diff -Nru sqlite3-3.42.0/autoconf/Makefile.am sqlite3-3.44.0-0/autoconf/Makefile.am --- sqlite3-3.42.0/autoconf/Makefile.am 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/autoconf/Makefile.am 2023-11-04 14:23:58.000000000 +0000 @@ -9,7 +9,7 @@ EXTRA_sqlite3_SOURCES = sqlite3.c sqlite3_LDADD = @EXTRA_SHELL_OBJ@ @READLINE_LIBS@ sqlite3_DEPENDENCIES = @EXTRA_SHELL_OBJ@ -sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS) +sqlite3_CFLAGS = $(AM_CFLAGS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS -DSQLITE_DQS=0 -DSQLITE_ENABLE_DBPAGE_VTAB -DSQLITE_ENABLE_STMTVTAB -DSQLITE_ENABLE_DBSTAT_VTAB $(SHELL_CFLAGS) include_HEADERS = sqlite3.h sqlite3ext.h diff -Nru sqlite3-3.42.0/autoconf/Makefile.msc sqlite3-3.44.0-0/autoconf/Makefile.msc --- sqlite3-3.42.0/autoconf/Makefile.msc 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/autoconf/Makefile.msc 2023-11-04 14:23:58.000000000 +0000 @@ -52,6 +52,13 @@ USE_STDCALL = 0 !ENDIF +# Use the USE_SEH=0 option on the nmake command line to omit structured +# exception handling (SEH) support. SEH is on by default. +# +!IFNDEF USE_SEH +USE_SEH = 1 +!ENDIF + # Set this non-0 to have the shell executable link against the core dynamic # link library. # @@ -180,6 +187,12 @@ OSTRACE = 0 !ENDIF +# enable address sanitizer using ASAN=1 on the command-line. +# +!IFNDEF ASAN +ASAN = 0 +!ENDIF + # Set this to one of the following values to enable various debugging # features. Each level includes the debugging options from the previous # levels. Currently, the recognized values for DEBUG are: @@ -283,6 +296,7 @@ !IFNDEF OPT_FEATURE_FLAGS !IF $(MINIMAL_AMALGAMATION)==0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 @@ -311,6 +325,14 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1 !ENDIF +# Should structured exception handling (SEH) be enabled for WAL mode in +# the core library? It is on by default. Only omit it if the +# USE_SEH=0 option is provided on the nmake command-line. +# +!IF $(USE_SEH)==0 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_OMIT_SEH=1 +!ENDIF + # These are the "extended" SQLite compilation options used when compiling for # the Windows 10 platform. # @@ -718,6 +740,13 @@ !ENDIF +# Address sanitizer if ASAN=1 +# +!IF $(ASAN)>0 +TCC = $(TCC) /fsanitize=address +!ENDIF + + # Compiler options needed for programs that use the readline() library. # !IFNDEF READLINE_FLAGS @@ -959,6 +988,8 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1 SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1 SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1 !ENDIF diff -Nru sqlite3-3.42.0/autoconf/tea/configure.ac sqlite3-3.44.0-0/autoconf/tea/configure.ac --- sqlite3-3.42.0/autoconf/tea/configure.ac 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/autoconf/tea/configure.ac 2023-11-04 14:23:58.000000000 +0000 @@ -19,7 +19,7 @@ # so that we create the export library with the dll. #----------------------------------------------------------------------- -AC_INIT([sqlite],[3.42.0]) +AC_INIT([sqlite],[3.44.1]) #-------------------------------------------------------------------- # Call TEA_INIT as the first TEA_ macro to set up initial vars. diff -Nru sqlite3-3.42.0/configure sqlite3-3.44.0-0/configure --- sqlite3-3.42.0/configure 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/configure 1970-01-01 00:00:00.000000000 +0000 @@ -1,14138 +0,0 @@ -#! /bin/sh -# Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.69 for sqlite 3.42.0. -# -# -# Copyright (C) 1992-1996, 1998-2012 Free Software Foundation, Inc. -# -# -# This configure script is free software; the Free Software Foundation -# gives unlimited permission to copy, distribute and modify it. -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -# Use a proper internal environment variable to ensure we don't fall - # into an infinite loop, continuously re-executing ourselves. - if test x"${_as_can_reexec}" != xno && test "x$CONFIG_SHELL" != x; then - _as_can_reexec=no; export _as_can_reexec; - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -as_fn_exit 255 - fi - # We don't want this to propagate to other subprocesses. - { _as_can_reexec=; unset _as_can_reexec;} -if test "x$CONFIG_SHELL" = x; then - as_bourne_compatible="if test -n \"\${ZSH_VERSION+set}\" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on \${1+\"\$@\"}, which - # is contrary to our usage. Disable this feature. - alias -g '\${1+\"\$@\"}'='\"\$@\"' - setopt NO_GLOB_SUBST -else - case \`(set -o) 2>/dev/null\` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi -" - as_required="as_fn_return () { (exit \$1); } -as_fn_success () { as_fn_return 0; } -as_fn_failure () { as_fn_return 1; } -as_fn_ret_success () { return 0; } -as_fn_ret_failure () { return 1; } - -exitcode=0 -as_fn_success || { exitcode=1; echo as_fn_success failed.; } -as_fn_failure && { exitcode=1; echo as_fn_failure succeeded.; } -as_fn_ret_success || { exitcode=1; echo as_fn_ret_success failed.; } -as_fn_ret_failure && { exitcode=1; echo as_fn_ret_failure succeeded.; } -if ( set x; as_fn_ret_success y && test x = \"\$1\" ); then : - -else - exitcode=1; echo positional parameters were not saved. -fi -test x\$exitcode = x0 || exit 1 -test -x / || exit 1" - as_suggested=" as_lineno_1=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_1a=\$LINENO - as_lineno_2=";as_suggested=$as_suggested$LINENO;as_suggested=$as_suggested" as_lineno_2a=\$LINENO - eval 'test \"x\$as_lineno_1'\$as_run'\" != \"x\$as_lineno_2'\$as_run'\" && - test \"x\`expr \$as_lineno_1'\$as_run' + 1\`\" = \"x\$as_lineno_2'\$as_run'\"' || exit 1 -test \$(( 1 + 1 )) = 2 || exit 1" - if (eval "$as_required") 2>/dev/null; then : - as_have_required=yes -else - as_have_required=no -fi - if test x$as_have_required = xyes && (eval "$as_suggested") 2>/dev/null; then : - -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -as_found=false -for as_dir in /bin$PATH_SEPARATOR/usr/bin$PATH_SEPARATOR$PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - as_found=: - case $as_dir in #( - /*) - for as_base in sh bash ksh sh5; do - # Try only shells that exist, to save several forks. - as_shell=$as_dir/$as_base - if { test -f "$as_shell" || test -f "$as_shell.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$as_shell"; } 2>/dev/null; then : - CONFIG_SHELL=$as_shell as_have_required=yes - if { $as_echo "$as_bourne_compatible""$as_suggested" | as_run=a "$as_shell"; } 2>/dev/null; then : - break 2 -fi -fi - done;; - esac - as_found=false -done -$as_found || { if { test -f "$SHELL" || test -f "$SHELL.exe"; } && - { $as_echo "$as_bourne_compatible""$as_required" | as_run=a "$SHELL"; } 2>/dev/null; then : - CONFIG_SHELL=$SHELL as_have_required=yes -fi; } -IFS=$as_save_IFS - - - if test "x$CONFIG_SHELL" != x; then : - export CONFIG_SHELL - # We cannot yet assume a decent shell, so we have to provide a -# neutralization value for shells without unset; and this also -# works around shells that cannot unset nonexistent variables. -# Preserve -v and -x to the replacement shell. -BASH_ENV=/dev/null -ENV=/dev/null -(unset BASH_ENV) >/dev/null 2>&1 && unset BASH_ENV ENV -case $- in # (((( - *v*x* | *x*v* ) as_opts=-vx ;; - *v* ) as_opts=-v ;; - *x* ) as_opts=-x ;; - * ) as_opts= ;; -esac -exec $CONFIG_SHELL $as_opts "$as_myself" ${1+"$@"} -# Admittedly, this is quite paranoid, since all the known shells bail -# out after a failed `exec'. -$as_echo "$0: could not re-execute with $CONFIG_SHELL" >&2 -exit 255 -fi - - if test x$as_have_required = xno; then : - $as_echo "$0: This script requires a shell more modern than all" - $as_echo "$0: the shells that I found on your system." - if test x${ZSH_VERSION+set} = xset ; then - $as_echo "$0: In particular, zsh $ZSH_VERSION has bugs and should" - $as_echo "$0: be upgraded to zsh 4.3.4 or later." - else - $as_echo "$0: Please tell bug-autoconf@gnu.org about your system, -$0: including any error possibly output before this -$0: message. Then install a modern shell, or manually run -$0: the script under such a shell if you do have one." - fi - exit 1 -fi -fi -fi -SHELL=${CONFIG_SHELL-/bin/sh} -export SHELL -# Unset more variables known to interfere with behavior of common tools. -CLICOLOR_FORCE= GREP_OPTIONS= -unset CLICOLOR_FORCE GREP_OPTIONS - -## --------------------- ## -## M4sh Shell Functions. ## -## --------------------- ## -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - - - as_lineno_1=$LINENO as_lineno_1a=$LINENO - as_lineno_2=$LINENO as_lineno_2a=$LINENO - eval 'test "x$as_lineno_1'$as_run'" != "x$as_lineno_2'$as_run'" && - test "x`expr $as_lineno_1'$as_run' + 1`" = "x$as_lineno_2'$as_run'"' || { - # Blame Lee E. McMahon (1931-1989) for sed's syntax. :-) - sed -n ' - p - /[$]LINENO/= - ' <$as_myself | - sed ' - s/[$]LINENO.*/&-/ - t lineno - b - :lineno - N - :loop - s/[$]LINENO\([^'$as_cr_alnum'_].*\n\)\(.*\)/\2\1\2/ - t loop - s/-\n.*// - ' >$as_me.lineno && - chmod +x "$as_me.lineno" || - { $as_echo "$as_me: error: cannot create $as_me.lineno; rerun with a POSIX shell" >&2; as_fn_exit 1; } - - # If we had to re-execute with $CONFIG_SHELL, we're ensured to have - # already done that, so ensure we don't try to do so again and fall - # in an infinite loop. This has already happened in practice. - _as_can_reexec=no; export _as_can_reexec - # Don't try to exec as it changes $[0], causing all sort of problems - # (the dirname of $[0] is not the place where we might find the - # original and so on. Autoconf is especially sensitive to this). - . "./$as_me.lineno" - # Exit status is that of the last command. - exit -} - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - - -# Check that we are running under the correct shell. -SHELL=${CONFIG_SHELL-/bin/sh} - -case X$lt_ECHO in -X*--fallback-echo) - # Remove one level of quotation (which was required for Make). - ECHO=`echo "$lt_ECHO" | sed 's,\\\\\$\\$0,'$0','` - ;; -esac - -ECHO=${lt_ECHO-echo} -if test "X$1" = X--no-reexec; then - # Discard the --no-reexec flag, and continue. - shift -elif test "X$1" = X--fallback-echo; then - # Avoid inline document here, it may be left over - : -elif test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' ; then - # Yippee, $ECHO works! - : -else - # Restart under the correct shell. - exec $SHELL "$0" --no-reexec ${1+"$@"} -fi - -if test "X$1" = X--fallback-echo; then - # used as fallback echo - shift - cat <<_LT_EOF -$* -_LT_EOF - exit 0 -fi - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -if test -z "$lt_ECHO"; then - if test "X${echo_test_string+set}" != Xset; then - # find a string as large as possible, as long as the shell can cope with it - for cmd in 'sed 50q "$0"' 'sed 20q "$0"' 'sed 10q "$0"' 'sed 2q "$0"' 'echo test'; do - # expected sizes: less than 2Kb, 1Kb, 512 bytes, 16 bytes, ... - if { echo_test_string=`eval $cmd`; } 2>/dev/null && - { test "X$echo_test_string" = "X$echo_test_string"; } 2>/dev/null - then - break - fi - done - fi - - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - : - else - # The Solaris, AIX, and Digital Unix default echo programs unquote - # backslashes. This makes it impossible to quote backslashes using - # echo "$something" | sed 's/\\/\\\\/g' - # - # So, first we look for a working echo in the user's PATH. - - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for dir in $PATH /usr/ucb; do - IFS="$lt_save_ifs" - if (test -f $dir/echo || test -f $dir/echo$ac_exeext) && - test "X`($dir/echo '\t') 2>/dev/null`" = 'X\t' && - echo_testing_string=`($dir/echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$dir/echo" - break - fi - done - IFS="$lt_save_ifs" - - if test "X$ECHO" = Xecho; then - # We didn't find a better echo, so look for alternatives. - if test "X`{ print -r '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ print -r "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # This shell has a builtin print -r that does the trick. - ECHO='print -r' - elif { test -f /bin/ksh || test -f /bin/ksh$ac_exeext; } && - test "X$CONFIG_SHELL" != X/bin/ksh; then - # If we have ksh, try running configure again with it. - ORIGINAL_CONFIG_SHELL=${CONFIG_SHELL-/bin/sh} - export ORIGINAL_CONFIG_SHELL - CONFIG_SHELL=/bin/ksh - export CONFIG_SHELL - exec $CONFIG_SHELL "$0" --no-reexec ${1+"$@"} - else - # Try using printf. - ECHO='printf %s\n' - if test "X`{ $ECHO '\t'; } 2>/dev/null`" = 'X\t' && - echo_testing_string=`{ $ECHO "$echo_test_string"; } 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - # Cool, printf works - : - elif echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($ORIGINAL_CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - CONFIG_SHELL=$ORIGINAL_CONFIG_SHELL - export CONFIG_SHELL - SHELL="$CONFIG_SHELL" - export SHELL - ECHO="$CONFIG_SHELL $0 --fallback-echo" - elif echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo '\t') 2>/dev/null` && - test "X$echo_testing_string" = 'X\t' && - echo_testing_string=`($CONFIG_SHELL "$0" --fallback-echo "$echo_test_string") 2>/dev/null` && - test "X$echo_testing_string" = "X$echo_test_string"; then - ECHO="$CONFIG_SHELL $0 --fallback-echo" - else - # maybe with a smaller string... - prev=: - - for cmd in 'echo test' 'sed 2q "$0"' 'sed 10q "$0"' 'sed 20q "$0"' 'sed 50q "$0"'; do - if { test "X$echo_test_string" = "X`eval $cmd`"; } 2>/dev/null - then - break - fi - prev="$cmd" - done - - if test "$prev" != 'sed 50q "$0"'; then - echo_test_string=`eval $prev` - export echo_test_string - exec ${ORIGINAL_CONFIG_SHELL-${CONFIG_SHELL-/bin/sh}} "$0" ${1+"$@"} - else - # Oops. We lost completely, so just stick with echo. - ECHO=echo - fi - fi - fi - fi - fi -fi - -# Copy echo and quote the copy suitably for passing to libtool from -# the Makefile, instead of quoting the original, which is used later. -lt_ECHO=$ECHO -if test "X$lt_ECHO" = "X$CONFIG_SHELL $0 --fallback-echo"; then - lt_ECHO="$CONFIG_SHELL \\\$\$0 --fallback-echo" -fi - - - - -test -n "$DJDIR" || exec 7<&0 &1 - -# Name of the host. -# hostname on some systems (SVR3.2, old GNU/Linux) returns a bogus exit status, -# so uname gets run too. -ac_hostname=`(hostname || uname -n) 2>/dev/null | sed 1q` - -# -# Initializations. -# -ac_default_prefix=/usr/local -ac_clean_files= -ac_config_libobj_dir=. -LIBOBJS= -cross_compiling=no -subdirs= -MFLAGS= -MAKEFLAGS= - -# Identity of this package. -PACKAGE_NAME='sqlite' -PACKAGE_TARNAME='sqlite' -PACKAGE_VERSION='3.42.0' -PACKAGE_STRING='sqlite 3.42.0' -PACKAGE_BUGREPORT='' -PACKAGE_URL='' - -# Factoring default headers for most tests. -ac_includes_default="\ -#include -#ifdef HAVE_SYS_TYPES_H -# include -#endif -#ifdef HAVE_SYS_STAT_H -# include -#endif -#ifdef STDC_HEADERS -# include -# include -#else -# ifdef HAVE_STDLIB_H -# include -# endif -#endif -#ifdef HAVE_STRING_H -# if !defined STDC_HEADERS && defined HAVE_MEMORY_H -# include -# endif -# include -#endif -#ifdef HAVE_STRINGS_H -# include -#endif -#ifdef HAVE_INTTYPES_H -# include -#endif -#ifdef HAVE_STDINT_H -# include -#endif -#ifdef HAVE_UNISTD_H -# include -#endif" - -ac_subst_vars='LTLIBOBJS -LIBOBJS -BUILD_CFLAGS -AMALGAMATION_LINE_MACROS -USE_GCOV -OPT_FEATURE_FLAGS -HAVE_ZLIB -USE_AMALGAMATION -TARGET_DEBUG -TARGET_HAVE_EDITLINE -TARGET_HAVE_READLINE -TARGET_READLINE_INC -TARGET_READLINE_LIBS -HAVE_TCL -TCL_SHLIB_SUFFIX -TCL_STUB_LIB_SPEC -TCL_STUB_LIB_FLAG -TCL_STUB_LIB_FILE -TCL_LIB_SPEC -TCL_LIB_FLAG -TCL_LIB_FILE -TCL_INCLUDE_SPEC -TCL_SRC_DIR -TCL_BIN_DIR -TCL_VERSION -TARGET_EXEEXT -SQLITE_OS_WIN -SQLITE_OS_UNIX -BUILD_EXEEXT -TEMP_STORE -ALLOWRELEASE -SQLITE_THREADSAFE -BUILD_CC -HAVE_WASI_SDK -RELEASE -VERSION -program_prefix -TCLLIBDIR -TCLSH_CMD -INSTALL_DATA -INSTALL_SCRIPT -INSTALL_PROGRAM -CPP -OTOOL64 -OTOOL -LIPO -NMEDIT -DSYMUTIL -lt_ECHO -RANLIB -STRIP -AR -OBJDUMP -LN_S -NM -ac_ct_DUMPBIN -DUMPBIN -LD -FGREP -EGREP -GREP -SED -OBJEXT -EXEEXT -ac_ct_CC -CPPFLAGS -LDFLAGS -CFLAGS -CC -host_os -host_vendor -host_cpu -host -build_os -build_vendor -build_cpu -build -LIBTOOL -target_alias -host_alias -build_alias -LIBS -ECHO_T -ECHO_N -ECHO_C -DEFS -mandir -localedir -libdir -psdir -pdfdir -dvidir -htmldir -infodir -docdir -oldincludedir -includedir -localstatedir -sharedstatedir -sysconfdir -datadir -datarootdir -libexecdir -sbindir -bindir -program_transform_name -prefix -exec_prefix -PACKAGE_URL -PACKAGE_BUGREPORT -PACKAGE_STRING -PACKAGE_VERSION -PACKAGE_TARNAME -PACKAGE_NAME -PATH_SEPARATOR -SHELL' -ac_subst_files='' -ac_user_opts=' -enable_option_checking -enable_shared -enable_static -with_pic -enable_fast_install -with_gnu_ld -enable_libtool_lock -enable_largefile -with_wasi_sdk -enable_threadsafe -enable_releasemode -enable_tempstore -enable_tcl -with_tcl -enable_editline -enable_readline -with_readline_lib -with_readline_inc -enable_debug -enable_amalgamation -enable_load_extension -enable_math -enable_json -enable_all -enable_memsys5 -enable_memsys3 -enable_fts3 -enable_fts4 -enable_fts5 -enable_update_limit -enable_geopoly -enable_rtree -enable_session -enable_gcov -' - ac_precious_vars='build_alias -host_alias -target_alias -CC -CFLAGS -LDFLAGS -LIBS -CPPFLAGS -CPP -TCLLIBDIR' - - -# Initialize some variables set by options. -ac_init_help= -ac_init_version=false -ac_unrecognized_opts= -ac_unrecognized_sep= -# The variables have the same names as the options, with -# dashes changed to underlines. -cache_file=/dev/null -exec_prefix=NONE -no_create= -no_recursion= -prefix=NONE -program_prefix=NONE -program_suffix=NONE -program_transform_name=s,x,x, -silent= -site= -srcdir= -verbose= -x_includes=NONE -x_libraries=NONE - -# Installation directory options. -# These are left unexpanded so users can "make install exec_prefix=/foo" -# and all the variables that are supposed to be based on exec_prefix -# by default will actually change. -# Use braces instead of parens because sh, perl, etc. also accept them. -# (The list follows the same order as the GNU Coding Standards.) -bindir='${exec_prefix}/bin' -sbindir='${exec_prefix}/sbin' -libexecdir='${exec_prefix}/libexec' -datarootdir='${prefix}/share' -datadir='${datarootdir}' -sysconfdir='${prefix}/etc' -sharedstatedir='${prefix}/com' -localstatedir='${prefix}/var' -includedir='${prefix}/include' -oldincludedir='/usr/include' -docdir='${datarootdir}/doc/${PACKAGE_TARNAME}' -infodir='${datarootdir}/info' -htmldir='${docdir}' -dvidir='${docdir}' -pdfdir='${docdir}' -psdir='${docdir}' -libdir='${exec_prefix}/lib' -localedir='${datarootdir}/locale' -mandir='${datarootdir}/man' - -ac_prev= -ac_dashdash= -for ac_option -do - # If the previous option needs an argument, assign it. - if test -n "$ac_prev"; then - eval $ac_prev=\$ac_option - ac_prev= - continue - fi - - case $ac_option in - *=?*) ac_optarg=`expr "X$ac_option" : '[^=]*=\(.*\)'` ;; - *=) ac_optarg= ;; - *) ac_optarg=yes ;; - esac - - # Accept the important Cygnus configure options, so we can diagnose typos. - - case $ac_dashdash$ac_option in - --) - ac_dashdash=yes ;; - - -bindir | --bindir | --bindi | --bind | --bin | --bi) - ac_prev=bindir ;; - -bindir=* | --bindir=* | --bindi=* | --bind=* | --bin=* | --bi=*) - bindir=$ac_optarg ;; - - -build | --build | --buil | --bui | --bu) - ac_prev=build_alias ;; - -build=* | --build=* | --buil=* | --bui=* | --bu=*) - build_alias=$ac_optarg ;; - - -cache-file | --cache-file | --cache-fil | --cache-fi \ - | --cache-f | --cache- | --cache | --cach | --cac | --ca | --c) - ac_prev=cache_file ;; - -cache-file=* | --cache-file=* | --cache-fil=* | --cache-fi=* \ - | --cache-f=* | --cache-=* | --cache=* | --cach=* | --cac=* | --ca=* | --c=*) - cache_file=$ac_optarg ;; - - --config-cache | -C) - cache_file=config.cache ;; - - -datadir | --datadir | --datadi | --datad) - ac_prev=datadir ;; - -datadir=* | --datadir=* | --datadi=* | --datad=*) - datadir=$ac_optarg ;; - - -datarootdir | --datarootdir | --datarootdi | --datarootd | --dataroot \ - | --dataroo | --dataro | --datar) - ac_prev=datarootdir ;; - -datarootdir=* | --datarootdir=* | --datarootdi=* | --datarootd=* \ - | --dataroot=* | --dataroo=* | --dataro=* | --datar=*) - datarootdir=$ac_optarg ;; - - -disable-* | --disable-*) - ac_useropt=`expr "x$ac_option" : 'x-*disable-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--disable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=no ;; - - -docdir | --docdir | --docdi | --doc | --do) - ac_prev=docdir ;; - -docdir=* | --docdir=* | --docdi=* | --doc=* | --do=*) - docdir=$ac_optarg ;; - - -dvidir | --dvidir | --dvidi | --dvid | --dvi | --dv) - ac_prev=dvidir ;; - -dvidir=* | --dvidir=* | --dvidi=* | --dvid=* | --dvi=* | --dv=*) - dvidir=$ac_optarg ;; - - -enable-* | --enable-*) - ac_useropt=`expr "x$ac_option" : 'x-*enable-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid feature name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"enable_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--enable-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval enable_$ac_useropt=\$ac_optarg ;; - - -exec-prefix | --exec_prefix | --exec-prefix | --exec-prefi \ - | --exec-pref | --exec-pre | --exec-pr | --exec-p | --exec- \ - | --exec | --exe | --ex) - ac_prev=exec_prefix ;; - -exec-prefix=* | --exec_prefix=* | --exec-prefix=* | --exec-prefi=* \ - | --exec-pref=* | --exec-pre=* | --exec-pr=* | --exec-p=* | --exec-=* \ - | --exec=* | --exe=* | --ex=*) - exec_prefix=$ac_optarg ;; - - -gas | --gas | --ga | --g) - # Obsolete; use --with-gas. - with_gas=yes ;; - - -help | --help | --hel | --he | -h) - ac_init_help=long ;; - -help=r* | --help=r* | --hel=r* | --he=r* | -hr*) - ac_init_help=recursive ;; - -help=s* | --help=s* | --hel=s* | --he=s* | -hs*) - ac_init_help=short ;; - - -host | --host | --hos | --ho) - ac_prev=host_alias ;; - -host=* | --host=* | --hos=* | --ho=*) - host_alias=$ac_optarg ;; - - -htmldir | --htmldir | --htmldi | --htmld | --html | --htm | --ht) - ac_prev=htmldir ;; - -htmldir=* | --htmldir=* | --htmldi=* | --htmld=* | --html=* | --htm=* \ - | --ht=*) - htmldir=$ac_optarg ;; - - -includedir | --includedir | --includedi | --included | --include \ - | --includ | --inclu | --incl | --inc) - ac_prev=includedir ;; - -includedir=* | --includedir=* | --includedi=* | --included=* | --include=* \ - | --includ=* | --inclu=* | --incl=* | --inc=*) - includedir=$ac_optarg ;; - - -infodir | --infodir | --infodi | --infod | --info | --inf) - ac_prev=infodir ;; - -infodir=* | --infodir=* | --infodi=* | --infod=* | --info=* | --inf=*) - infodir=$ac_optarg ;; - - -libdir | --libdir | --libdi | --libd) - ac_prev=libdir ;; - -libdir=* | --libdir=* | --libdi=* | --libd=*) - libdir=$ac_optarg ;; - - -libexecdir | --libexecdir | --libexecdi | --libexecd | --libexec \ - | --libexe | --libex | --libe) - ac_prev=libexecdir ;; - -libexecdir=* | --libexecdir=* | --libexecdi=* | --libexecd=* | --libexec=* \ - | --libexe=* | --libex=* | --libe=*) - libexecdir=$ac_optarg ;; - - -localedir | --localedir | --localedi | --localed | --locale) - ac_prev=localedir ;; - -localedir=* | --localedir=* | --localedi=* | --localed=* | --locale=*) - localedir=$ac_optarg ;; - - -localstatedir | --localstatedir | --localstatedi | --localstated \ - | --localstate | --localstat | --localsta | --localst | --locals) - ac_prev=localstatedir ;; - -localstatedir=* | --localstatedir=* | --localstatedi=* | --localstated=* \ - | --localstate=* | --localstat=* | --localsta=* | --localst=* | --locals=*) - localstatedir=$ac_optarg ;; - - -mandir | --mandir | --mandi | --mand | --man | --ma | --m) - ac_prev=mandir ;; - -mandir=* | --mandir=* | --mandi=* | --mand=* | --man=* | --ma=* | --m=*) - mandir=$ac_optarg ;; - - -nfp | --nfp | --nf) - # Obsolete; use --without-fp. - with_fp=no ;; - - -no-create | --no-create | --no-creat | --no-crea | --no-cre \ - | --no-cr | --no-c | -n) - no_create=yes ;; - - -no-recursion | --no-recursion | --no-recursio | --no-recursi \ - | --no-recurs | --no-recur | --no-recu | --no-rec | --no-re | --no-r) - no_recursion=yes ;; - - -oldincludedir | --oldincludedir | --oldincludedi | --oldincluded \ - | --oldinclude | --oldinclud | --oldinclu | --oldincl | --oldinc \ - | --oldin | --oldi | --old | --ol | --o) - ac_prev=oldincludedir ;; - -oldincludedir=* | --oldincludedir=* | --oldincludedi=* | --oldincluded=* \ - | --oldinclude=* | --oldinclud=* | --oldinclu=* | --oldincl=* | --oldinc=* \ - | --oldin=* | --oldi=* | --old=* | --ol=* | --o=*) - oldincludedir=$ac_optarg ;; - - -prefix | --prefix | --prefi | --pref | --pre | --pr | --p) - ac_prev=prefix ;; - -prefix=* | --prefix=* | --prefi=* | --pref=* | --pre=* | --pr=* | --p=*) - prefix=$ac_optarg ;; - - -program-prefix | --program-prefix | --program-prefi | --program-pref \ - | --program-pre | --program-pr | --program-p) - ac_prev=program_prefix ;; - -program-prefix=* | --program-prefix=* | --program-prefi=* \ - | --program-pref=* | --program-pre=* | --program-pr=* | --program-p=*) - program_prefix=$ac_optarg ;; - - -program-suffix | --program-suffix | --program-suffi | --program-suff \ - | --program-suf | --program-su | --program-s) - ac_prev=program_suffix ;; - -program-suffix=* | --program-suffix=* | --program-suffi=* \ - | --program-suff=* | --program-suf=* | --program-su=* | --program-s=*) - program_suffix=$ac_optarg ;; - - -program-transform-name | --program-transform-name \ - | --program-transform-nam | --program-transform-na \ - | --program-transform-n | --program-transform- \ - | --program-transform | --program-transfor \ - | --program-transfo | --program-transf \ - | --program-trans | --program-tran \ - | --progr-tra | --program-tr | --program-t) - ac_prev=program_transform_name ;; - -program-transform-name=* | --program-transform-name=* \ - | --program-transform-nam=* | --program-transform-na=* \ - | --program-transform-n=* | --program-transform-=* \ - | --program-transform=* | --program-transfor=* \ - | --program-transfo=* | --program-transf=* \ - | --program-trans=* | --program-tran=* \ - | --progr-tra=* | --program-tr=* | --program-t=*) - program_transform_name=$ac_optarg ;; - - -pdfdir | --pdfdir | --pdfdi | --pdfd | --pdf | --pd) - ac_prev=pdfdir ;; - -pdfdir=* | --pdfdir=* | --pdfdi=* | --pdfd=* | --pdf=* | --pd=*) - pdfdir=$ac_optarg ;; - - -psdir | --psdir | --psdi | --psd | --ps) - ac_prev=psdir ;; - -psdir=* | --psdir=* | --psdi=* | --psd=* | --ps=*) - psdir=$ac_optarg ;; - - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - silent=yes ;; - - -sbindir | --sbindir | --sbindi | --sbind | --sbin | --sbi | --sb) - ac_prev=sbindir ;; - -sbindir=* | --sbindir=* | --sbindi=* | --sbind=* | --sbin=* \ - | --sbi=* | --sb=*) - sbindir=$ac_optarg ;; - - -sharedstatedir | --sharedstatedir | --sharedstatedi \ - | --sharedstated | --sharedstate | --sharedstat | --sharedsta \ - | --sharedst | --shareds | --shared | --share | --shar \ - | --sha | --sh) - ac_prev=sharedstatedir ;; - -sharedstatedir=* | --sharedstatedir=* | --sharedstatedi=* \ - | --sharedstated=* | --sharedstate=* | --sharedstat=* | --sharedsta=* \ - | --sharedst=* | --shareds=* | --shared=* | --share=* | --shar=* \ - | --sha=* | --sh=*) - sharedstatedir=$ac_optarg ;; - - -site | --site | --sit) - ac_prev=site ;; - -site=* | --site=* | --sit=*) - site=$ac_optarg ;; - - -srcdir | --srcdir | --srcdi | --srcd | --src | --sr) - ac_prev=srcdir ;; - -srcdir=* | --srcdir=* | --srcdi=* | --srcd=* | --src=* | --sr=*) - srcdir=$ac_optarg ;; - - -sysconfdir | --sysconfdir | --sysconfdi | --sysconfd | --sysconf \ - | --syscon | --sysco | --sysc | --sys | --sy) - ac_prev=sysconfdir ;; - -sysconfdir=* | --sysconfdir=* | --sysconfdi=* | --sysconfd=* | --sysconf=* \ - | --syscon=* | --sysco=* | --sysc=* | --sys=* | --sy=*) - sysconfdir=$ac_optarg ;; - - -target | --target | --targe | --targ | --tar | --ta | --t) - ac_prev=target_alias ;; - -target=* | --target=* | --targe=* | --targ=* | --tar=* | --ta=* | --t=*) - target_alias=$ac_optarg ;; - - -v | -verbose | --verbose | --verbos | --verbo | --verb) - verbose=yes ;; - - -version | --version | --versio | --versi | --vers | -V) - ac_init_version=: ;; - - -with-* | --with-*) - ac_useropt=`expr "x$ac_option" : 'x-*with-\([^=]*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--with-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=\$ac_optarg ;; - - -without-* | --without-*) - ac_useropt=`expr "x$ac_option" : 'x-*without-\(.*\)'` - # Reject names that are not valid shell variable names. - expr "x$ac_useropt" : ".*[^-+._$as_cr_alnum]" >/dev/null && - as_fn_error $? "invalid package name: $ac_useropt" - ac_useropt_orig=$ac_useropt - ac_useropt=`$as_echo "$ac_useropt" | sed 's/[-+.]/_/g'` - case $ac_user_opts in - *" -"with_$ac_useropt" -"*) ;; - *) ac_unrecognized_opts="$ac_unrecognized_opts$ac_unrecognized_sep--without-$ac_useropt_orig" - ac_unrecognized_sep=', ';; - esac - eval with_$ac_useropt=no ;; - - --x) - # Obsolete; use --with-x. - with_x=yes ;; - - -x-includes | --x-includes | --x-include | --x-includ | --x-inclu \ - | --x-incl | --x-inc | --x-in | --x-i) - ac_prev=x_includes ;; - -x-includes=* | --x-includes=* | --x-include=* | --x-includ=* | --x-inclu=* \ - | --x-incl=* | --x-inc=* | --x-in=* | --x-i=*) - x_includes=$ac_optarg ;; - - -x-libraries | --x-libraries | --x-librarie | --x-librari \ - | --x-librar | --x-libra | --x-libr | --x-lib | --x-li | --x-l) - ac_prev=x_libraries ;; - -x-libraries=* | --x-libraries=* | --x-librarie=* | --x-librari=* \ - | --x-librar=* | --x-libra=* | --x-libr=* | --x-lib=* | --x-li=* | --x-l=*) - x_libraries=$ac_optarg ;; - - -*) as_fn_error $? "unrecognized option: \`$ac_option' -Try \`$0 --help' for more information" - ;; - - *=*) - ac_envvar=`expr "x$ac_option" : 'x\([^=]*\)='` - # Reject names that are not valid shell variable names. - case $ac_envvar in #( - '' | [0-9]* | *[!_$as_cr_alnum]* ) - as_fn_error $? "invalid variable name: \`$ac_envvar'" ;; - esac - eval $ac_envvar=\$ac_optarg - export $ac_envvar ;; - - *) - # FIXME: should be removed in autoconf 3.0. - $as_echo "$as_me: WARNING: you should use --build, --host, --target" >&2 - expr "x$ac_option" : ".*[^-._$as_cr_alnum]" >/dev/null && - $as_echo "$as_me: WARNING: invalid host type: $ac_option" >&2 - : "${build_alias=$ac_option} ${host_alias=$ac_option} ${target_alias=$ac_option}" - ;; - - esac -done - -if test -n "$ac_prev"; then - ac_option=--`echo $ac_prev | sed 's/_/-/g'` - as_fn_error $? "missing argument to $ac_option" -fi - -if test -n "$ac_unrecognized_opts"; then - case $enable_option_checking in - no) ;; - fatal) as_fn_error $? "unrecognized options: $ac_unrecognized_opts" ;; - *) $as_echo "$as_me: WARNING: unrecognized options: $ac_unrecognized_opts" >&2 ;; - esac -fi - -# Check all directory arguments for consistency. -for ac_var in exec_prefix prefix bindir sbindir libexecdir datarootdir \ - datadir sysconfdir sharedstatedir localstatedir includedir \ - oldincludedir docdir infodir htmldir dvidir pdfdir psdir \ - libdir localedir mandir -do - eval ac_val=\$$ac_var - # Remove trailing slashes. - case $ac_val in - */ ) - ac_val=`expr "X$ac_val" : 'X\(.*[^/]\)' \| "X$ac_val" : 'X\(.*\)'` - eval $ac_var=\$ac_val;; - esac - # Be sure to have absolute directory names. - case $ac_val in - [\\/$]* | ?:[\\/]* ) continue;; - NONE | '' ) case $ac_var in *prefix ) continue;; esac;; - esac - as_fn_error $? "expected an absolute directory name for --$ac_var: $ac_val" -done - -# There might be people who depend on the old broken behavior: `$host' -# used to hold the argument of --host etc. -# FIXME: To remove some day. -build=$build_alias -host=$host_alias -target=$target_alias - -# FIXME: To remove some day. -if test "x$host_alias" != x; then - if test "x$build_alias" = x; then - cross_compiling=maybe - elif test "x$build_alias" != "x$host_alias"; then - cross_compiling=yes - fi -fi - -ac_tool_prefix= -test -n "$host_alias" && ac_tool_prefix=$host_alias- - -test "$silent" = yes && exec 6>/dev/null - - -ac_pwd=`pwd` && test -n "$ac_pwd" && -ac_ls_di=`ls -di .` && -ac_pwd_ls_di=`cd "$ac_pwd" && ls -di .` || - as_fn_error $? "working directory cannot be determined" -test "X$ac_ls_di" = "X$ac_pwd_ls_di" || - as_fn_error $? "pwd does not report name of working directory" - - -# Find the source files, if location was not specified. -if test -z "$srcdir"; then - ac_srcdir_defaulted=yes - # Try the directory containing this script, then the parent directory. - ac_confdir=`$as_dirname -- "$as_myself" || -$as_expr X"$as_myself" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_myself" : 'X\(//\)[^/]' \| \ - X"$as_myself" : 'X\(//\)$' \| \ - X"$as_myself" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_myself" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - srcdir=$ac_confdir - if test ! -r "$srcdir/$ac_unique_file"; then - srcdir=.. - fi -else - ac_srcdir_defaulted=no -fi -if test ! -r "$srcdir/$ac_unique_file"; then - test "$ac_srcdir_defaulted" = yes && srcdir="$ac_confdir or .." - as_fn_error $? "cannot find sources ($ac_unique_file) in $srcdir" -fi -ac_msg="sources are in $srcdir, but \`cd $srcdir' does not work" -ac_abs_confdir=`( - cd "$srcdir" && test -r "./$ac_unique_file" || as_fn_error $? "$ac_msg" - pwd)` -# When building in place, set srcdir=. -if test "$ac_abs_confdir" = "$ac_pwd"; then - srcdir=. -fi -# Remove unnecessary trailing slashes from srcdir. -# Double slashes in file names in object file debugging info -# mess up M-x gdb in Emacs. -case $srcdir in -*/) srcdir=`expr "X$srcdir" : 'X\(.*[^/]\)' \| "X$srcdir" : 'X\(.*\)'`;; -esac -for ac_var in $ac_precious_vars; do - eval ac_env_${ac_var}_set=\${${ac_var}+set} - eval ac_env_${ac_var}_value=\$${ac_var} - eval ac_cv_env_${ac_var}_set=\${${ac_var}+set} - eval ac_cv_env_${ac_var}_value=\$${ac_var} -done - -# -# Report the --help message. -# -if test "$ac_init_help" = "long"; then - # Omit some internal or obsolete options to make the list less imposing. - # This message is too long to be a string in the A/UX 3.1 sh. - cat <<_ACEOF -\`configure' configures sqlite 3.42.0 to adapt to many kinds of systems. - -Usage: $0 [OPTION]... [VAR=VALUE]... - -To assign environment variables (e.g., CC, CFLAGS...), specify them as -VAR=VALUE. See below for descriptions of some of the useful variables. - -Defaults for the options are specified in brackets. - -Configuration: - -h, --help display this help and exit - --help=short display options specific to this package - --help=recursive display the short help of all the included packages - -V, --version display version information and exit - -q, --quiet, --silent do not print \`checking ...' messages - --cache-file=FILE cache test results in FILE [disabled] - -C, --config-cache alias for \`--cache-file=config.cache' - -n, --no-create do not create output files - --srcdir=DIR find the sources in DIR [configure dir or \`..'] - -Installation directories: - --prefix=PREFIX install architecture-independent files in PREFIX - [$ac_default_prefix] - --exec-prefix=EPREFIX install architecture-dependent files in EPREFIX - [PREFIX] - -By default, \`make install' will install all the files in -\`$ac_default_prefix/bin', \`$ac_default_prefix/lib' etc. You can specify -an installation prefix other than \`$ac_default_prefix' using \`--prefix', -for instance \`--prefix=\$HOME'. - -For better control, use the options below. - -Fine tuning of the installation directories: - --bindir=DIR user executables [EPREFIX/bin] - --sbindir=DIR system admin executables [EPREFIX/sbin] - --libexecdir=DIR program executables [EPREFIX/libexec] - --sysconfdir=DIR read-only single-machine data [PREFIX/etc] - --sharedstatedir=DIR modifiable architecture-independent data [PREFIX/com] - --localstatedir=DIR modifiable single-machine data [PREFIX/var] - --libdir=DIR object code libraries [EPREFIX/lib] - --includedir=DIR C header files [PREFIX/include] - --oldincludedir=DIR C header files for non-gcc [/usr/include] - --datarootdir=DIR read-only arch.-independent data root [PREFIX/share] - --datadir=DIR read-only architecture-independent data [DATAROOTDIR] - --infodir=DIR info documentation [DATAROOTDIR/info] - --localedir=DIR locale-dependent data [DATAROOTDIR/locale] - --mandir=DIR man documentation [DATAROOTDIR/man] - --docdir=DIR documentation root [DATAROOTDIR/doc/sqlite] - --htmldir=DIR html documentation [DOCDIR] - --dvidir=DIR dvi documentation [DOCDIR] - --pdfdir=DIR pdf documentation [DOCDIR] - --psdir=DIR ps documentation [DOCDIR] -_ACEOF - - cat <<\_ACEOF - -System types: - --build=BUILD configure for building on BUILD [guessed] - --host=HOST cross-compile to build programs to run on HOST [BUILD] -_ACEOF -fi - -if test -n "$ac_init_help"; then - case $ac_init_help in - short | recursive ) echo "Configuration of sqlite 3.42.0:";; - esac - cat <<\_ACEOF - -Optional Features: - --disable-option-checking ignore unrecognized --enable/--with options - --disable-FEATURE do not include FEATURE (same as --enable-FEATURE=no) - --enable-FEATURE[=ARG] include FEATURE [ARG=yes] - --enable-shared[=PKGS] build shared libraries [default=yes] - --enable-static[=PKGS] build static libraries [default=yes] - --enable-fast-install[=PKGS] - optimize for fast installation [default=yes] - --disable-libtool-lock avoid locking (might break parallel builds) - --disable-largefile omit support for large files - --disable-threadsafe Disable mutexing - --enable-releasemode Support libtool link to release mode - --enable-tempstore Use an in-ram database for temporary tables - (never,no,yes,always) - --disable-tcl do not build TCL extension - --enable-editline enable BSD editline support - --disable-readline disable readline support - --enable-debug enable debugging & verbose explain - --disable-amalgamation Disable the amalgamation and instead build all files - separately - --disable-load-extension - Disable loading of external extensions - --disable-math Disable math functions - --disable-json Disable JSON functions - --enable-all Enable FTS4, FTS5, Geopoly, RTree, Sessions - --enable-memsys5 Enable MEMSYS5 - --enable-memsys3 Enable MEMSYS3 - --enable-fts3 Enable the FTS3 extension - --enable-fts4 Enable the FTS4 extension - --enable-fts5 Enable the FTS5 extension - --enable-update-limit Enable the UPDATE/DELETE LIMIT clause - --enable-geopoly Enable the GEOPOLY extension - --enable-rtree Enable the RTREE extension - --enable-session Enable the SESSION extension - --enable-gcov Enable coverage testing using gcov - -Optional Packages: - --with-PACKAGE[=ARG] use PACKAGE [ARG=yes] - --without-PACKAGE do not use PACKAGE (same as --with-PACKAGE=no) - --with-pic try to use only PIC/non-PIC objects [default=use - both] - --with-gnu-ld assume the C compiler uses GNU ld [default=no] - --with-wasi-sdk=DIR directory containing the WASI SDK. Triggers - cross-compile to WASM. - --with-tcl=DIR directory containing tcl configuration - (tclConfig.sh) - --with-readline-lib specify readline library - --with-readline-inc specify readline include paths - -Some influential environment variables: - CC C compiler command - CFLAGS C compiler flags - LDFLAGS linker flags, e.g. -L if you have libraries in a - nonstandard directory - LIBS libraries to pass to the linker, e.g. -l - CPPFLAGS (Objective) C/C++ preprocessor flags, e.g. -I if - you have headers in a nonstandard directory - CPP C preprocessor - TCLLIBDIR Where to install tcl plugin - -Use these variables to override the choices made by `configure' or to help -it to find libraries and programs with nonstandard names/locations. - -Report bugs to the package provider. -_ACEOF -ac_status=$? -fi - -if test "$ac_init_help" = "recursive"; then - # If there are subdirs, report their specific --help. - for ac_dir in : $ac_subdirs_all; do test "x$ac_dir" = x: && continue - test -d "$ac_dir" || - { cd "$srcdir" && ac_pwd=`pwd` && srcdir=. && test -d "$ac_dir"; } || - continue - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - cd "$ac_dir" || { ac_status=$?; continue; } - # Check for guested configure. - if test -f "$ac_srcdir/configure.gnu"; then - echo && - $SHELL "$ac_srcdir/configure.gnu" --help=recursive - elif test -f "$ac_srcdir/configure"; then - echo && - $SHELL "$ac_srcdir/configure" --help=recursive - else - $as_echo "$as_me: WARNING: no configuration information is in $ac_dir" >&2 - fi || ac_status=$? - cd "$ac_pwd" || { ac_status=$?; break; } - done -fi - -test -n "$ac_init_help" && exit $ac_status -if $ac_init_version; then - cat <<\_ACEOF -sqlite configure 3.42.0 -generated by GNU Autoconf 2.69 - -Copyright (C) 2012 Free Software Foundation, Inc. -This configure script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it. -_ACEOF - exit -fi - -## ------------------------ ## -## Autoconf initialization. ## -## ------------------------ ## - -# ac_fn_c_try_compile LINENO -# -------------------------- -# Try to compile conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext - if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest.$ac_objext; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_compile - -# ac_fn_c_try_link LINENO -# ----------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_link () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - rm -f conftest.$ac_objext conftest$ac_exeext - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { - test -z "$ac_c_werror_flag" || - test ! -s conftest.err - } && test -s conftest$ac_exeext && { - test "$cross_compiling" = yes || - test -x conftest$ac_exeext - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - # Delete the IPA/IPO (Inter Procedural Analysis/Optimization) information - # created by the PGI compiler (conftest_ipa8_conftest.oo), as it would - # interfere with the next link command; also delete a directory that is - # left behind by Apple's compiler. We do this before executing the actions. - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_link - -# ac_fn_c_check_header_compile LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists and can be compiled using the include files in -# INCLUDES, setting the cache variable VAR accordingly. -ac_fn_c_check_header_compile () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_compile - -# ac_fn_c_try_cpp LINENO -# ---------------------- -# Try to preprocess conftest.$ac_ext, and return whether this succeeded. -ac_fn_c_try_cpp () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_cpp conftest.$ac_ext" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_cpp conftest.$ac_ext") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - grep -v '^ *+' conftest.err >conftest.er1 - cat conftest.er1 >&5 - mv -f conftest.er1 conftest.err - fi - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } > conftest.i && { - test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" || - test ! -s conftest.err - }; then : - ac_retval=0 -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=1 -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_cpp - -# ac_fn_c_try_run LINENO -# ---------------------- -# Try to link conftest.$ac_ext, and return whether this succeeded. Assumes -# that executables *can* be run. -ac_fn_c_try_run () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && { ac_try='./conftest$ac_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then : - ac_retval=0 -else - $as_echo "$as_me: program exited with status $ac_status" >&5 - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - - ac_retval=$ac_status -fi - rm -rf conftest.dSYM conftest_ipa8_conftest.oo - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - as_fn_set_status $ac_retval - -} # ac_fn_c_try_run - -# ac_fn_c_check_func LINENO FUNC VAR -# ---------------------------------- -# Tests whether FUNC exists, setting the cache variable VAR accordingly -ac_fn_c_check_func () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -/* Define $2 to an innocuous variant, in case declares $2. - For example, HP-UX 11i declares gettimeofday. */ -#define $2 innocuous_$2 - -/* System header to define __stub macros and hopefully few prototypes, - which can conflict with char $2 (); below. - Prefer to if __STDC__ is defined, since - exists even on freestanding compilers. */ - -#ifdef __STDC__ -# include -#else -# include -#endif - -#undef $2 - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char $2 (); -/* The GNU C library defines this for functions which it implements - to always fail with ENOSYS. Some functions are actually named - something starting with __ and the normal name is an alias. */ -#if defined __stub_$2 || defined __stub___$2 -choke me -#endif - -int -main () -{ -return $2 (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - eval "$3=yes" -else - eval "$3=no" -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_func - -# ac_fn_c_check_type LINENO TYPE VAR INCLUDES -# ------------------------------------------- -# Tests whether TYPE exists after having included INCLUDES, setting cache -# variable VAR accordingly. -ac_fn_c_check_type () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=no" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof ($2)) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -int -main () -{ -if (sizeof (($2))) - return 0; - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - eval "$3=yes" -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_type - -# ac_fn_c_check_header_mongrel LINENO HEADER VAR INCLUDES -# ------------------------------------------------------- -# Tests whether HEADER exists, giving a warning if it cannot be compiled using -# the include files in INCLUDES and setting the cache variable VAR -# accordingly. -ac_fn_c_check_header_mongrel () -{ - as_lineno=${as_lineno-"$1"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - if eval \${$3+:} false; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -else - # Is the header compilable? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 usability" >&5 -$as_echo_n "checking $2 usability... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -$4 -#include <$2> -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_header_compiler=yes -else - ac_header_compiler=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_compiler" >&5 -$as_echo "$ac_header_compiler" >&6; } - -# Is the header present? -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking $2 presence" >&5 -$as_echo_n "checking $2 presence... " >&6; } -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include <$2> -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - ac_header_preproc=yes -else - ac_header_preproc=no -fi -rm -f conftest.err conftest.i conftest.$ac_ext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_header_preproc" >&5 -$as_echo "$ac_header_preproc" >&6; } - -# So? What about this header? -case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in #(( - yes:no: ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&5 -$as_echo "$as_me: WARNING: $2: accepted by the compiler, rejected by the preprocessor!" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; - no:yes:* ) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: present but cannot be compiled" >&5 -$as_echo "$as_me: WARNING: $2: present but cannot be compiled" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: check for missing prerequisite headers?" >&5 -$as_echo "$as_me: WARNING: $2: check for missing prerequisite headers?" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: see the Autoconf documentation" >&5 -$as_echo "$as_me: WARNING: $2: see the Autoconf documentation" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&5 -$as_echo "$as_me: WARNING: $2: section \"Present But Cannot Be Compiled\"" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $2: proceeding with the compiler's result" >&5 -$as_echo "$as_me: WARNING: $2: proceeding with the compiler's result" >&2;} - ;; -esac - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for $2" >&5 -$as_echo_n "checking for $2... " >&6; } -if eval \${$3+:} false; then : - $as_echo_n "(cached) " >&6 -else - eval "$3=\$ac_header_compiler" -fi -eval ac_res=\$$3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -fi - eval $as_lineno_stack; ${as_lineno_stack:+:} unset as_lineno - -} # ac_fn_c_check_header_mongrel -cat >config.log <<_ACEOF -This file contains any messages produced by compilers while -running configure, to aid debugging if configure makes a mistake. - -It was created by sqlite $as_me 3.42.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - $ $0 $@ - -_ACEOF -exec 5>>config.log -{ -cat <<_ASUNAME -## --------- ## -## Platform. ## -## --------- ## - -hostname = `(hostname || uname -n) 2>/dev/null | sed 1q` -uname -m = `(uname -m) 2>/dev/null || echo unknown` -uname -r = `(uname -r) 2>/dev/null || echo unknown` -uname -s = `(uname -s) 2>/dev/null || echo unknown` -uname -v = `(uname -v) 2>/dev/null || echo unknown` - -/usr/bin/uname -p = `(/usr/bin/uname -p) 2>/dev/null || echo unknown` -/bin/uname -X = `(/bin/uname -X) 2>/dev/null || echo unknown` - -/bin/arch = `(/bin/arch) 2>/dev/null || echo unknown` -/usr/bin/arch -k = `(/usr/bin/arch -k) 2>/dev/null || echo unknown` -/usr/convex/getsysinfo = `(/usr/convex/getsysinfo) 2>/dev/null || echo unknown` -/usr/bin/hostinfo = `(/usr/bin/hostinfo) 2>/dev/null || echo unknown` -/bin/machine = `(/bin/machine) 2>/dev/null || echo unknown` -/usr/bin/oslevel = `(/usr/bin/oslevel) 2>/dev/null || echo unknown` -/bin/universe = `(/bin/universe) 2>/dev/null || echo unknown` - -_ASUNAME - -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - $as_echo "PATH: $as_dir" - done -IFS=$as_save_IFS - -} >&5 - -cat >&5 <<_ACEOF - - -## ----------- ## -## Core tests. ## -## ----------- ## - -_ACEOF - - -# Keep a trace of the command line. -# Strip out --no-create and --no-recursion so they do not pile up. -# Strip out --silent because we don't want to record it for future runs. -# Also quote any args containing shell meta-characters. -# Make two passes to allow for proper duplicate-argument suppression. -ac_configure_args= -ac_configure_args0= -ac_configure_args1= -ac_must_keep_next=false -for ac_pass in 1 2 -do - for ac_arg - do - case $ac_arg in - -no-create | --no-c* | -n | -no-recursion | --no-r*) continue ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil) - continue ;; - *\'*) - ac_arg=`$as_echo "$ac_arg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - case $ac_pass in - 1) as_fn_append ac_configure_args0 " '$ac_arg'" ;; - 2) - as_fn_append ac_configure_args1 " '$ac_arg'" - if test $ac_must_keep_next = true; then - ac_must_keep_next=false # Got value, back to normal. - else - case $ac_arg in - *=* | --config-cache | -C | -disable-* | --disable-* \ - | -enable-* | --enable-* | -gas | --g* | -nfp | --nf* \ - | -q | -quiet | --q* | -silent | --sil* | -v | -verb* \ - | -with-* | --with-* | -without-* | --without-* | --x) - case "$ac_configure_args0 " in - "$ac_configure_args1"*" '$ac_arg' "* ) continue ;; - esac - ;; - -* ) ac_must_keep_next=true ;; - esac - fi - as_fn_append ac_configure_args " '$ac_arg'" - ;; - esac - done -done -{ ac_configure_args0=; unset ac_configure_args0;} -{ ac_configure_args1=; unset ac_configure_args1;} - -# When interrupted or exit'd, cleanup temporary files, and complete -# config.log. We remove comments because anyway the quotes in there -# would cause problems or look ugly. -# WARNING: Use '\'' to represent an apostrophe within the trap. -# WARNING: Do not start the trap code with a newline, due to a FreeBSD 4.0 bug. -trap 'exit_status=$? - # Save into config.log some information that might help in debugging. - { - echo - - $as_echo "## ---------------- ## -## Cache variables. ## -## ---------------- ##" - echo - # The following way of writing the cache mishandles newlines in values, -( - for ac_var in `(set) 2>&1 | sed -n '\''s/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'\''`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - (set) 2>&1 | - case $as_nl`(ac_space='\'' '\''; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - sed -n \ - "s/'\''/'\''\\\\'\'''\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\''\\2'\''/p" - ;; #( - *) - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) - echo - - $as_echo "## ----------------- ## -## Output variables. ## -## ----------------- ##" - echo - for ac_var in $ac_subst_vars - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - - if test -n "$ac_subst_files"; then - $as_echo "## ------------------- ## -## File substitutions. ## -## ------------------- ##" - echo - for ac_var in $ac_subst_files - do - eval ac_val=\$$ac_var - case $ac_val in - *\'\''*) ac_val=`$as_echo "$ac_val" | sed "s/'\''/'\''\\\\\\\\'\'''\''/g"`;; - esac - $as_echo "$ac_var='\''$ac_val'\''" - done | sort - echo - fi - - if test -s confdefs.h; then - $as_echo "## ----------- ## -## confdefs.h. ## -## ----------- ##" - echo - cat confdefs.h - echo - fi - test "$ac_signal" != 0 && - $as_echo "$as_me: caught signal $ac_signal" - $as_echo "$as_me: exit $exit_status" - } >&5 - rm -f core *.core core.conftest.* && - rm -f -r conftest* confdefs* conf$$* $ac_clean_files && - exit $exit_status -' 0 -for ac_signal in 1 2 13 15; do - trap 'ac_signal='$ac_signal'; as_fn_exit 1' $ac_signal -done -ac_signal=0 - -# confdefs.h avoids OS command line length limits that DEFS can exceed. -rm -f -r conftest* confdefs.h - -$as_echo "/* confdefs.h */" > confdefs.h - -# Predefined preprocessor variables. - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_NAME "$PACKAGE_NAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_TARNAME "$PACKAGE_TARNAME" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_VERSION "$PACKAGE_VERSION" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_STRING "$PACKAGE_STRING" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_BUGREPORT "$PACKAGE_BUGREPORT" -_ACEOF - -cat >>confdefs.h <<_ACEOF -#define PACKAGE_URL "$PACKAGE_URL" -_ACEOF - - -# Let the site file select an alternate cache file if it wants to. -# Prefer an explicitly selected file to automatically selected ones. -ac_site_file1=NONE -ac_site_file2=NONE -if test -n "$CONFIG_SITE"; then - # We do not want a PATH search for config.site. - case $CONFIG_SITE in #(( - -*) ac_site_file1=./$CONFIG_SITE;; - */*) ac_site_file1=$CONFIG_SITE;; - *) ac_site_file1=./$CONFIG_SITE;; - esac -elif test "x$prefix" != xNONE; then - ac_site_file1=$prefix/share/config.site - ac_site_file2=$prefix/etc/config.site -else - ac_site_file1=$ac_default_prefix/share/config.site - ac_site_file2=$ac_default_prefix/etc/config.site -fi -for ac_site_file in "$ac_site_file1" "$ac_site_file2" -do - test "x$ac_site_file" = xNONE && continue - if test /dev/null != "$ac_site_file" && test -r "$ac_site_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading site script $ac_site_file" >&5 -$as_echo "$as_me: loading site script $ac_site_file" >&6;} - sed 's/^/| /' "$ac_site_file" >&5 - . "$ac_site_file" \ - || { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "failed to load site script $ac_site_file -See \`config.log' for more details" "$LINENO" 5; } - fi -done - -if test -r "$cache_file"; then - # Some versions of bash will fail to source /dev/null (special files - # actually), so we avoid doing that. DJGPP emulates it as a regular file. - if test /dev/null != "$cache_file" && test -f "$cache_file"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: loading cache $cache_file" >&5 -$as_echo "$as_me: loading cache $cache_file" >&6;} - case $cache_file in - [\\/]* | ?:[\\/]* ) . "$cache_file";; - *) . "./$cache_file";; - esac - fi -else - { $as_echo "$as_me:${as_lineno-$LINENO}: creating cache $cache_file" >&5 -$as_echo "$as_me: creating cache $cache_file" >&6;} - >$cache_file -fi - -# Check that the precious variables saved in the cache have kept the same -# value. -ac_cache_corrupted=false -for ac_var in $ac_precious_vars; do - eval ac_old_set=\$ac_cv_env_${ac_var}_set - eval ac_new_set=\$ac_env_${ac_var}_set - eval ac_old_val=\$ac_cv_env_${ac_var}_value - eval ac_new_val=\$ac_env_${ac_var}_value - case $ac_old_set,$ac_new_set in - set,) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was set to \`$ac_old_val' in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,set) - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' was not set in the previous run" >&5 -$as_echo "$as_me: error: \`$ac_var' was not set in the previous run" >&2;} - ac_cache_corrupted=: ;; - ,);; - *) - if test "x$ac_old_val" != "x$ac_new_val"; then - # differences in whitespace do not lead to failure. - ac_old_val_w=`echo x $ac_old_val` - ac_new_val_w=`echo x $ac_new_val` - if test "$ac_old_val_w" != "$ac_new_val_w"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: \`$ac_var' has changed since the previous run:" >&5 -$as_echo "$as_me: error: \`$ac_var' has changed since the previous run:" >&2;} - ac_cache_corrupted=: - else - { $as_echo "$as_me:${as_lineno-$LINENO}: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&5 -$as_echo "$as_me: warning: ignoring whitespace changes in \`$ac_var' since the previous run:" >&2;} - eval $ac_var=\$ac_old_val - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: former value: \`$ac_old_val'" >&5 -$as_echo "$as_me: former value: \`$ac_old_val'" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: current value: \`$ac_new_val'" >&5 -$as_echo "$as_me: current value: \`$ac_new_val'" >&2;} - fi;; - esac - # Pass precious variables to config.status. - if test "$ac_new_set" = set; then - case $ac_new_val in - *\'*) ac_arg=$ac_var=`$as_echo "$ac_new_val" | sed "s/'/'\\\\\\\\''/g"` ;; - *) ac_arg=$ac_var=$ac_new_val ;; - esac - case " $ac_configure_args " in - *" '$ac_arg' "*) ;; # Avoid dups. Use of quotes ensures accuracy. - *) as_fn_append ac_configure_args " '$ac_arg'" ;; - esac - fi -done -if $ac_cache_corrupted; then - { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: error: changes in the environment can compromise the build" >&5 -$as_echo "$as_me: error: changes in the environment can compromise the build" >&2;} - as_fn_error $? "run \`make distclean' and/or \`rm $cache_file' and start over" "$LINENO" 5 -fi -## -------------------- ## -## Main body of script. ## -## -------------------- ## - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - - -sqlite_version_sanity_check=`cat $srcdir/VERSION | tr -d '\n'` -if test "$PACKAGE_VERSION" != "$sqlite_version_sanity_check" ; then -as_fn_error $? "configure script is out of date: - configure \$PACKAGE_VERSION = $PACKAGE_VERSION - top level VERSION file = $sqlite_version_sanity_check -please regen with autoconf" "$LINENO" 5 -fi - -######### -# Programs needed -# -case `pwd` in - *\ * | *\ *) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&5 -$as_echo "$as_me: WARNING: Libtool does not cope well with whitespace in \`pwd\`" >&2;} ;; -esac - - - -macro_version='2.2.6' -macro_revision='1.3012' - - - - - - - - - - - - - -ltmain="$ac_aux_dir/ltmain.sh" - -ac_aux_dir= -for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do - if test -f "$ac_dir/install-sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install-sh -c" - break - elif test -f "$ac_dir/install.sh"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/install.sh -c" - break - elif test -f "$ac_dir/shtool"; then - ac_aux_dir=$ac_dir - ac_install_sh="$ac_aux_dir/shtool install -c" - break - fi -done -if test -z "$ac_aux_dir"; then - as_fn_error $? "cannot find install-sh, install.sh, or shtool in \"$srcdir\" \"$srcdir/..\" \"$srcdir/../..\"" "$LINENO" 5 -fi - -# These three variables are undocumented and unsupported, -# and are intended to be withdrawn in a future Autoconf release. -# They can cause serious problems if a builder's source tree is in a directory -# whose full name contains unusual characters. -ac_config_guess="$SHELL $ac_aux_dir/config.guess" # Please don't use this var. -ac_config_sub="$SHELL $ac_aux_dir/config.sub" # Please don't use this var. -ac_configure="$SHELL $ac_aux_dir/configure" # Please don't use this var. - - -# Make sure we can run config.sub. -$SHELL "$ac_aux_dir/config.sub" sun4 >/dev/null 2>&1 || - as_fn_error $? "cannot run $SHELL $ac_aux_dir/config.sub" "$LINENO" 5 - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build system type" >&5 -$as_echo_n "checking build system type... " >&6; } -if ${ac_cv_build+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_build_alias=$build_alias -test "x$ac_build_alias" = x && - ac_build_alias=`$SHELL "$ac_aux_dir/config.guess"` -test "x$ac_build_alias" = x && - as_fn_error $? "cannot guess build type; you must specify one" "$LINENO" 5 -ac_cv_build=`$SHELL "$ac_aux_dir/config.sub" $ac_build_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $ac_build_alias failed" "$LINENO" 5 - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_build" >&5 -$as_echo "$ac_cv_build" >&6; } -case $ac_cv_build in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical build" "$LINENO" 5;; -esac -build=$ac_cv_build -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_build -shift -build_cpu=$1 -build_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -build_os=$* -IFS=$ac_save_IFS -case $build_os in *\ *) build_os=`echo "$build_os" | sed 's/ /-/g'`;; esac - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking host system type" >&5 -$as_echo_n "checking host system type... " >&6; } -if ${ac_cv_host+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "x$host_alias" = x; then - ac_cv_host=$ac_cv_build -else - ac_cv_host=`$SHELL "$ac_aux_dir/config.sub" $host_alias` || - as_fn_error $? "$SHELL $ac_aux_dir/config.sub $host_alias failed" "$LINENO" 5 -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_host" >&5 -$as_echo "$ac_cv_host" >&6; } -case $ac_cv_host in -*-*-*) ;; -*) as_fn_error $? "invalid value of canonical host" "$LINENO" 5;; -esac -host=$ac_cv_host -ac_save_IFS=$IFS; IFS='-' -set x $ac_cv_host -shift -host_cpu=$1 -host_vendor=$2 -shift; shift -# Remember, the first character of IFS is used to create $*, -# except with old shells: -host_os=$* -IFS=$ac_save_IFS -case $host_os in *\ *) host_os=`echo "$host_os" | sed 's/ /-/g'`;; esac - - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}gcc", so it can be a program name with args. -set dummy ${ac_tool_prefix}gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_CC"; then - ac_ct_CC=$CC - # Extract the first word of "gcc", so it can be a program name with args. -set dummy gcc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="gcc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -else - CC="$ac_cv_prog_CC" -fi - -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}cc", so it can be a program name with args. -set dummy ${ac_tool_prefix}cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="${ac_tool_prefix}cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - fi -fi -if test -z "$CC"; then - # Extract the first word of "cc", so it can be a program name with args. -set dummy cc; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else - ac_prog_rejected=no -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - if test "$as_dir/$ac_word$ac_exec_ext" = "/usr/ucb/cc"; then - ac_prog_rejected=yes - continue - fi - ac_cv_prog_CC="cc" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -if test $ac_prog_rejected = yes; then - # We found a bogon in the path, so make sure we never use it. - set dummy $ac_cv_prog_CC - shift - if test $# != 0; then - # We chose a different compiler from the bogus one. - # However, it has the same basename, so the bogon will be chosen - # first if we set CC to just the basename; use the full file name. - shift - ac_cv_prog_CC="$as_dir/$ac_word${1+' '}$@" - fi -fi -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$CC"; then - if test -n "$ac_tool_prefix"; then - for ac_prog in cl.exe - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$CC"; then - ac_cv_prog_CC="$CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_CC="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -CC=$ac_cv_prog_CC -if test -n "$CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $CC" >&5 -$as_echo "$CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$CC" && break - done -fi -if test -z "$CC"; then - ac_ct_CC=$CC - for ac_prog in cl.exe -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_CC"; then - ac_cv_prog_ac_ct_CC="$ac_ct_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_CC=$ac_cv_prog_ac_ct_CC -if test -n "$ac_ct_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_CC" >&5 -$as_echo "$ac_ct_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_CC" && break -done - - if test "x$ac_ct_CC" = x; then - CC="" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - CC=$ac_ct_CC - fi -fi - -fi - - -test -z "$CC" && { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "no acceptable C compiler found in \$PATH -See \`config.log' for more details" "$LINENO" 5; } - -# Provide some information about the compiler. -$as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler version" >&5 -set X $ac_compile -ac_compiler=$2 -for ac_option in --version -v -V -qversion; do - { { ac_try="$ac_compiler $ac_option >&5" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compiler $ac_option >&5") 2>conftest.err - ac_status=$? - if test -s conftest.err; then - sed '10a\ -... rest of stderr output deleted ... - 10q' conftest.err >conftest.er1 - cat conftest.er1 >&5 - fi - rm -f conftest.er1 conftest.err - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } -done - -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files a.out a.out.dSYM a.exe b.out" -# Try to create an executable without -o first, disregard a.out. -# It will help us diagnose broken compilers, and finding out an intuition -# of exeext. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler works" >&5 -$as_echo_n "checking whether the C compiler works... " >&6; } -ac_link_default=`$as_echo "$ac_link" | sed 's/ -o *conftest[^ ]*//'` - -# The possible output files: -ac_files="a.out conftest.exe conftest a.exe a_out.exe b.out conftest.*" - -ac_rmfiles= -for ac_file in $ac_files -do - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - * ) ac_rmfiles="$ac_rmfiles $ac_file";; - esac -done -rm -f $ac_rmfiles - -if { { ac_try="$ac_link_default" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link_default") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # Autoconf-2.13 could set the ac_cv_exeext variable to `no'. -# So ignore a value of `no', otherwise this would lead to `EXEEXT = no' -# in a Makefile. We should not override ac_cv_exeext if it was cached, -# so that the user can short-circuit this test for compilers unknown to -# Autoconf. -for ac_file in $ac_files '' -do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) - ;; - [ab].out ) - # We found the default executable, but exeext='' is most - # certainly right. - break;; - *.* ) - if test "${ac_cv_exeext+set}" = set && test "$ac_cv_exeext" != no; - then :; else - ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - fi - # We set ac_cv_exeext here because the later test for it is not - # safe: cross compilers may not add the suffix if given an `-o' - # argument, so we may need to know it at that point already. - # Even if this section looks crufty: it has the advantage of - # actually working. - break;; - * ) - break;; - esac -done -test "$ac_cv_exeext" = no && ac_cv_exeext= - -else - ac_file='' -fi -if test -z "$ac_file"; then : - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -$as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error 77 "C compiler cannot create executables -See \`config.log' for more details" "$LINENO" 5; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for C compiler default output file name" >&5 -$as_echo_n "checking for C compiler default output file name... " >&6; } -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_file" >&5 -$as_echo "$ac_file" >&6; } -ac_exeext=$ac_cv_exeext - -rm -f -r a.out a.out.dSYM a.exe conftest$ac_cv_exeext b.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of executables" >&5 -$as_echo_n "checking for suffix of executables... " >&6; } -if { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - # If both `conftest.exe' and `conftest' are `present' (well, observable) -# catch `conftest.exe'. For instance with Cygwin, `ls conftest' will -# work properly (i.e., refer to `conftest.exe'), while it won't with -# `rm'. -for ac_file in conftest.exe conftest conftest.*; do - test -f "$ac_file" || continue - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM | *.o | *.obj ) ;; - *.* ) ac_cv_exeext=`expr "$ac_file" : '[^.]*\(\..*\)'` - break;; - * ) break;; - esac -done -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of executables: cannot compile and link -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest conftest$ac_cv_exeext -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_exeext" >&5 -$as_echo "$ac_cv_exeext" >&6; } - -rm -f conftest.$ac_ext -EXEEXT=$ac_cv_exeext -ac_exeext=$EXEEXT -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -int -main () -{ -FILE *f = fopen ("conftest.out", "w"); - return ferror (f) || fclose (f) != 0; - - ; - return 0; -} -_ACEOF -ac_clean_files="$ac_clean_files conftest.out" -# Check that the compiler produces executables we can run. If not, either -# the compiler is broken, or we cross compile. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are cross compiling" >&5 -$as_echo_n "checking whether we are cross compiling... " >&6; } -if test "$cross_compiling" != yes; then - { { ac_try="$ac_link" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_link") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - if { ac_try='./conftest$ac_cv_exeext' - { { case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_try") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; }; then - cross_compiling=no - else - if test "$cross_compiling" = maybe; then - cross_compiling=yes - else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot run C compiled programs. -If you meant to cross compile, use \`--host'. -See \`config.log' for more details" "$LINENO" 5; } - fi - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $cross_compiling" >&5 -$as_echo "$cross_compiling" >&6; } - -rm -f conftest.$ac_ext conftest$ac_cv_exeext conftest.out -ac_clean_files=$ac_clean_files_save -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for suffix of object files" >&5 -$as_echo_n "checking for suffix of object files... " >&6; } -if ${ac_cv_objext+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -rm -f conftest.o conftest.obj -if { { ac_try="$ac_compile" -case "(($ac_try" in - *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;; - *) ac_try_echo=$ac_try;; -esac -eval ac_try_echo="\"\$as_me:${as_lineno-$LINENO}: $ac_try_echo\"" -$as_echo "$ac_try_echo"; } >&5 - (eval "$ac_compile") 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then : - for ac_file in conftest.o conftest.obj conftest.*; do - test -f "$ac_file" || continue; - case $ac_file in - *.$ac_ext | *.xcoff | *.tds | *.d | *.pdb | *.xSYM | *.bb | *.bbg | *.map | *.inf | *.dSYM ) ;; - *) ac_cv_objext=`expr "$ac_file" : '.*\.\(.*\)'` - break;; - esac -done -else - $as_echo "$as_me: failed program was:" >&5 -sed 's/^/| /' conftest.$ac_ext >&5 - -{ { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "cannot compute suffix of object files: cannot compile -See \`config.log' for more details" "$LINENO" 5; } -fi -rm -f conftest.$ac_cv_objext conftest.$ac_ext -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_objext" >&5 -$as_echo "$ac_cv_objext" >&6; } -OBJEXT=$ac_cv_objext -ac_objext=$OBJEXT -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether we are using the GNU C compiler" >&5 -$as_echo_n "checking whether we are using the GNU C compiler... " >&6; } -if ${ac_cv_c_compiler_gnu+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ -#ifndef __GNUC__ - choke me -#endif - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_compiler_gnu=yes -else - ac_compiler_gnu=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -ac_cv_c_compiler_gnu=$ac_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_compiler_gnu" >&5 -$as_echo "$ac_cv_c_compiler_gnu" >&6; } -if test $ac_compiler_gnu = yes; then - GCC=yes -else - GCC= -fi -ac_test_CFLAGS=${CFLAGS+set} -ac_save_CFLAGS=$CFLAGS -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether $CC accepts -g" >&5 -$as_echo_n "checking whether $CC accepts -g... " >&6; } -if ${ac_cv_prog_cc_g+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_save_c_werror_flag=$ac_c_werror_flag - ac_c_werror_flag=yes - ac_cv_prog_cc_g=no - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -else - CFLAGS="" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - -else - ac_c_werror_flag=$ac_save_c_werror_flag - CFLAGS="-g" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_g=yes -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_c_werror_flag=$ac_save_c_werror_flag -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_g" >&5 -$as_echo "$ac_cv_prog_cc_g" >&6; } -if test "$ac_test_CFLAGS" = set; then - CFLAGS=$ac_save_CFLAGS -elif test $ac_cv_prog_cc_g = yes; then - if test "$GCC" = yes; then - CFLAGS="-g -O2" - else - CFLAGS="-g" - fi -else - if test "$GCC" = yes; then - CFLAGS="-O2" - else - CFLAGS= - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $CC option to accept ISO C89" >&5 -$as_echo_n "checking for $CC option to accept ISO C89... " >&6; } -if ${ac_cv_prog_cc_c89+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_prog_cc_c89=no -ac_save_CC=$CC -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -struct stat; -/* Most of the following tests are stolen from RCS 5.7's src/conf.sh. */ -struct buf { int x; }; -FILE * (*rcsopen) (struct buf *, struct stat *, int); -static char *e (p, i) - char **p; - int i; -{ - return p[i]; -} -static char *f (char * (*g) (char **, int), char **p, ...) -{ - char *s; - va_list v; - va_start (v,p); - s = g (p, va_arg (v,int)); - va_end (v); - return s; -} - -/* OSF 4.0 Compaq cc is some sort of almost-ANSI by default. It has - function prototypes and stuff, but not '\xHH' hex character constants. - These don't provoke an error unfortunately, instead are silently treated - as 'x'. The following induces an error, until -std is added to get - proper ANSI mode. Curiously '\x00'!='x' always comes out true, for an - array size at least. It's necessary to write '\x00'==0 to get something - that's true only with -std. */ -int osf4_cc_array ['\x00' == 0 ? 1 : -1]; - -/* IBM C 6 for AIX is almost-ANSI by default, but it replaces macro parameters - inside strings and character constants. */ -#define FOO(x) 'x' -int xlc6_cc_array[FOO(a) == 'x' ? 1 : -1]; - -int test (int i, double x); -struct s1 {int (*f) (int a);}; -struct s2 {int (*f) (double a);}; -int pairnames (int, char **, FILE *(*)(struct buf *, struct stat *, int), int, int); -int argc; -char **argv; -int -main () -{ -return f (e, argv, 0) != argv[0] || f (e, argv, 1) != argv[1]; - ; - return 0; -} -_ACEOF -for ac_arg in '' -qlanglvl=extc89 -qlanglvl=ansi -std \ - -Ae "-Aa -D_HPUX_SOURCE" "-Xc -D__EXTENSIONS__" -do - CC="$ac_save_CC $ac_arg" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_prog_cc_c89=$ac_arg -fi -rm -f core conftest.err conftest.$ac_objext - test "x$ac_cv_prog_cc_c89" != "xno" && break -done -rm -f conftest.$ac_ext -CC=$ac_save_CC - -fi -# AC_CACHE_VAL -case "x$ac_cv_prog_cc_c89" in - x) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none needed" >&5 -$as_echo "none needed" >&6; } ;; - xno) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unsupported" >&5 -$as_echo "unsupported" >&6; } ;; - *) - CC="$CC $ac_cv_prog_cc_c89" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_prog_cc_c89" >&5 -$as_echo "$ac_cv_prog_cc_c89" >&6; } ;; -esac -if test "x$ac_cv_prog_cc_c89" != xno; then : - -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a sed that does not truncate output" >&5 -$as_echo_n "checking for a sed that does not truncate output... " >&6; } -if ${ac_cv_path_SED+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_script=s/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa/bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb/ - for ac_i in 1 2 3 4 5 6 7; do - ac_script="$ac_script$as_nl$ac_script" - done - echo "$ac_script" 2>/dev/null | sed 99q >conftest.sed - { ac_script=; unset ac_script;} - if test -z "$SED"; then - ac_path_SED_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_SED="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_SED" || continue -# Check for GNU ac_path_SED and select it if it is found. - # Check for GNU $ac_path_SED -case `"$ac_path_SED" --version 2>&1` in -*GNU*) - ac_cv_path_SED="$ac_path_SED" ac_path_SED_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo '' >> "conftest.nl" - "$ac_path_SED" -f conftest.sed < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_SED_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_SED="$ac_path_SED" - ac_path_SED_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_SED_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_SED"; then - as_fn_error $? "no acceptable sed could be found in \$PATH" "$LINENO" 5 - fi -else - ac_cv_path_SED=$SED -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_SED" >&5 -$as_echo "$ac_cv_path_SED" >&6; } - SED="$ac_cv_path_SED" - rm -f conftest.sed - -test -z "$SED" && SED=sed -Xsed="$SED -e 1s/^X//" - - - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for grep that handles long lines and -e" >&5 -$as_echo_n "checking for grep that handles long lines and -e... " >&6; } -if ${ac_cv_path_GREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$GREP"; then - ac_path_GREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in grep ggrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_GREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_GREP" || continue -# Check for GNU ac_path_GREP and select it if it is found. - # Check for GNU $ac_path_GREP -case `"$ac_path_GREP" --version 2>&1` in -*GNU*) - ac_cv_path_GREP="$ac_path_GREP" ac_path_GREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'GREP' >> "conftest.nl" - "$ac_path_GREP" -e 'GREP$' -e '-(cannot match)-' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_GREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_GREP="$ac_path_GREP" - ac_path_GREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_GREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_GREP"; then - as_fn_error $? "no acceptable grep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_GREP=$GREP -fi - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_GREP" >&5 -$as_echo "$ac_cv_path_GREP" >&6; } - GREP="$ac_cv_path_GREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for egrep" >&5 -$as_echo_n "checking for egrep... " >&6; } -if ${ac_cv_path_EGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo a | $GREP -E '(a|b)' >/dev/null 2>&1 - then ac_cv_path_EGREP="$GREP -E" - else - if test -z "$EGREP"; then - ac_path_EGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in egrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_EGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_EGREP" || continue -# Check for GNU ac_path_EGREP and select it if it is found. - # Check for GNU $ac_path_EGREP -case `"$ac_path_EGREP" --version 2>&1` in -*GNU*) - ac_cv_path_EGREP="$ac_path_EGREP" ac_path_EGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'EGREP' >> "conftest.nl" - "$ac_path_EGREP" 'EGREP$' < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_EGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_EGREP="$ac_path_EGREP" - ac_path_EGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_EGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_EGREP"; then - as_fn_error $? "no acceptable egrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_EGREP=$EGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_EGREP" >&5 -$as_echo "$ac_cv_path_EGREP" >&6; } - EGREP="$ac_cv_path_EGREP" - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for fgrep" >&5 -$as_echo_n "checking for fgrep... " >&6; } -if ${ac_cv_path_FGREP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if echo 'ab*c' | $GREP -F 'ab*c' >/dev/null 2>&1 - then ac_cv_path_FGREP="$GREP -F" - else - if test -z "$FGREP"; then - ac_path_FGREP_found=false - # Loop through the user's path and test for each of PROGNAME-LIST - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH$PATH_SEPARATOR/usr/xpg4/bin -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_prog in fgrep; do - for ac_exec_ext in '' $ac_executable_extensions; do - ac_path_FGREP="$as_dir/$ac_prog$ac_exec_ext" - as_fn_executable_p "$ac_path_FGREP" || continue -# Check for GNU ac_path_FGREP and select it if it is found. - # Check for GNU $ac_path_FGREP -case `"$ac_path_FGREP" --version 2>&1` in -*GNU*) - ac_cv_path_FGREP="$ac_path_FGREP" ac_path_FGREP_found=:;; -*) - ac_count=0 - $as_echo_n 0123456789 >"conftest.in" - while : - do - cat "conftest.in" "conftest.in" >"conftest.tmp" - mv "conftest.tmp" "conftest.in" - cp "conftest.in" "conftest.nl" - $as_echo 'FGREP' >> "conftest.nl" - "$ac_path_FGREP" FGREP < "conftest.nl" >"conftest.out" 2>/dev/null || break - diff "conftest.out" "conftest.nl" >/dev/null 2>&1 || break - as_fn_arith $ac_count + 1 && ac_count=$as_val - if test $ac_count -gt ${ac_path_FGREP_max-0}; then - # Best one so far, save it but keep looking for a better one - ac_cv_path_FGREP="$ac_path_FGREP" - ac_path_FGREP_max=$ac_count - fi - # 10*(2^10) chars as input seems more than enough - test $ac_count -gt 10 && break - done - rm -f conftest.in conftest.tmp conftest.nl conftest.out;; -esac - - $ac_path_FGREP_found && break 3 - done - done - done -IFS=$as_save_IFS - if test -z "$ac_cv_path_FGREP"; then - as_fn_error $? "no acceptable fgrep could be found in $PATH$PATH_SEPARATOR/usr/xpg4/bin" "$LINENO" 5 - fi -else - ac_cv_path_FGREP=$FGREP -fi - - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_path_FGREP" >&5 -$as_echo "$ac_cv_path_FGREP" >&6; } - FGREP="$ac_cv_path_FGREP" - - -test -z "$GREP" && GREP=grep - - - - - - - - - - - - - - - - - - - -# Check whether --with-gnu-ld was given. -if test "${with_gnu_ld+set}" = set; then : - withval=$with_gnu_ld; test "$withval" = no || with_gnu_ld=yes -else - with_gnu_ld=no -fi - -ac_prog=ld -if test "$GCC" = yes; then - # Check if gcc -print-prog-name=ld gives a path. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 -$as_echo_n "checking for ld used by $CC... " >&6; } - case $host in - *-*-mingw*) - # gcc leaves a trailing carriage return which upsets mingw - ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; - *) - ac_prog=`($CC -print-prog-name=ld) 2>&5` ;; - esac - case $ac_prog in - # Accept absolute paths. - [\\/]* | ?:[\\/]*) - re_direlt='/[^/][^/]*/\.\./' - # Canonicalize the pathname of ld - ac_prog=`$ECHO "$ac_prog"| $SED 's%\\\\%/%g'` - while $ECHO "$ac_prog" | $GREP "$re_direlt" > /dev/null 2>&1; do - ac_prog=`$ECHO $ac_prog| $SED "s%$re_direlt%/%"` - done - test -z "$LD" && LD="$ac_prog" - ;; - "") - # If it fails, then pretend we aren't using GCC. - ac_prog=ld - ;; - *) - # If it is relative, then search for the first ld in PATH. - with_gnu_ld=unknown - ;; - esac -elif test "$with_gnu_ld" = yes; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for GNU ld" >&5 -$as_echo_n "checking for GNU ld... " >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for non-GNU ld" >&5 -$as_echo_n "checking for non-GNU ld... " >&6; } -fi -if ${lt_cv_path_LD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -z "$LD"; then - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f "$ac_dir/$ac_prog" || test -f "$ac_dir/$ac_prog$ac_exeext"; then - lt_cv_path_LD="$ac_dir/$ac_prog" - # Check to see if the program is GNU ld. I'd rather use --version, - # but apparently some variants of GNU ld only accept -v. - # Break only if it was the GNU/non-GNU ld that we prefer. - case `"$lt_cv_path_LD" -v 2>&1 &5 -$as_echo "$LD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -test -z "$LD" && as_fn_error $? "no acceptable ld found in \$PATH" "$LINENO" 5 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if the linker ($LD) is GNU ld" >&5 -$as_echo_n "checking if the linker ($LD) is GNU ld... " >&6; } -if ${lt_cv_prog_gnu_ld+:} false; then : - $as_echo_n "(cached) " >&6 -else - # I'd rather use --version here, but apparently some GNU lds only accept -v. -case `$LD -v 2>&1 &5 -$as_echo "$lt_cv_prog_gnu_ld" >&6; } -with_gnu_ld=$lt_cv_prog_gnu_ld - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for BSD- or MS-compatible name lister (nm)" >&5 -$as_echo_n "checking for BSD- or MS-compatible name lister (nm)... " >&6; } -if ${lt_cv_path_NM+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NM"; then - # Let the user override the test. - lt_cv_path_NM="$NM" -else - lt_nm_to_check="${ac_tool_prefix}nm" - if test -n "$ac_tool_prefix" && test "$build" = "$host"; then - lt_nm_to_check="$lt_nm_to_check nm" - fi - for lt_tmp_nm in $lt_nm_to_check; do - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - for ac_dir in $PATH /usr/ccs/bin/elf /usr/ccs/bin /usr/ucb /bin; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - tmp_nm="$ac_dir/$lt_tmp_nm" - if test -f "$tmp_nm" || test -f "$tmp_nm$ac_exeext" ; then - # Check to see if the nm accepts a BSD-compat flag. - # Adding the `sed 1q' prevents false positives on HP-UX, which says: - # nm: unknown option "B" ignored - # Tru64's nm complains that /dev/null is an invalid object file - case `"$tmp_nm" -B /dev/null 2>&1 | sed '1q'` in - */dev/null* | *'Invalid file or object type'*) - lt_cv_path_NM="$tmp_nm -B" - break - ;; - *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in - */dev/null*) - lt_cv_path_NM="$tmp_nm -p" - break - ;; - *) - lt_cv_path_NM=${lt_cv_path_NM="$tmp_nm"} # keep the first match, but - continue # so that we can try to find one that supports BSD flags - ;; - esac - ;; - esac - fi - done - IFS="$lt_save_ifs" - done - : ${lt_cv_path_NM=no} -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_NM" >&5 -$as_echo "$lt_cv_path_NM" >&6; } -if test "$lt_cv_path_NM" != "no"; then - NM="$lt_cv_path_NM" -else - # Didn't find any BSD compatible name lister, look for dumpbin. - if test -n "$ac_tool_prefix"; then - for ac_prog in "dumpbin -symbols" "link -dump -symbols" - do - # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. -set dummy $ac_tool_prefix$ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DUMPBIN"; then - ac_cv_prog_DUMPBIN="$DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DUMPBIN="$ac_tool_prefix$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DUMPBIN=$ac_cv_prog_DUMPBIN -if test -n "$DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DUMPBIN" >&5 -$as_echo "$DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$DUMPBIN" && break - done -fi -if test -z "$DUMPBIN"; then - ac_ct_DUMPBIN=$DUMPBIN - for ac_prog in "dumpbin -symbols" "link -dump -symbols" -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DUMPBIN+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DUMPBIN"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_ct_DUMPBIN" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DUMPBIN="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DUMPBIN=$ac_cv_prog_ac_ct_DUMPBIN -if test -n "$ac_ct_DUMPBIN"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DUMPBIN" >&5 -$as_echo "$ac_ct_DUMPBIN" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$ac_ct_DUMPBIN" && break -done - - if test "x$ac_ct_DUMPBIN" = x; then - DUMPBIN=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DUMPBIN=$ac_ct_DUMPBIN - fi -fi - - - if test "$DUMPBIN" != ":"; then - NM="$DUMPBIN" - fi -fi -test -z "$NM" && NM=nm - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the name lister ($NM) interface" >&5 -$as_echo_n "checking the name lister ($NM) interface... " >&6; } -if ${lt_cv_nm_interface+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_nm_interface="BSD nm" - echo "int some_variable = 0;" > conftest.$ac_ext - (eval echo "\"\$as_me:3945: $ac_compile\"" >&5) - (eval "$ac_compile" 2>conftest.err) - cat conftest.err >&5 - (eval echo "\"\$as_me:3948: $NM \\\"conftest.$ac_objext\\\"\"" >&5) - (eval "$NM \"conftest.$ac_objext\"" 2>conftest.err > conftest.out) - cat conftest.err >&5 - (eval echo "\"\$as_me:3951: output\"" >&5) - cat conftest.out >&5 - if $GREP 'External.*some_variable' conftest.out > /dev/null; then - lt_cv_nm_interface="MS dumpbin" - fi - rm -f conftest* -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_nm_interface" >&5 -$as_echo "$lt_cv_nm_interface" >&6; } - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ln -s works" >&5 -$as_echo_n "checking whether ln -s works... " >&6; } -LN_S=$as_ln_s -if test "$LN_S" = "ln -s"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no, using $LN_S" >&5 -$as_echo "no, using $LN_S" >&6; } -fi - -# find the maximum length of command line arguments -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking the maximum length of command line arguments" >&5 -$as_echo_n "checking the maximum length of command line arguments... " >&6; } -if ${lt_cv_sys_max_cmd_len+:} false; then : - $as_echo_n "(cached) " >&6 -else - i=0 - teststring="ABCD" - - case $build_os in - msdosdjgpp*) - # On DJGPP, this test can blow up pretty badly due to problems in libc - # (any single argument exceeding 2000 bytes causes a buffer overrun - # during glob expansion). Even if it were fixed, the result of this - # check would be larger than it should be. - lt_cv_sys_max_cmd_len=12288; # 12K is about right - ;; - - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. - # Libtool will interpret -1 as no limit whatsoever - lt_cv_sys_max_cmd_len=-1; - ;; - - cygwin* | mingw* | cegcc*) - # On Win9x/ME, this test blows up -- it succeeds, but takes - # about 5 minutes as the teststring grows exponentially. - # Worse, since 9x/ME are not pre-emptively multitasking, - # you end up with a "frozen" computer, even though with patience - # the test eventually succeeds (with a max line length of 256k). - # Instead, let's just punt: use the minimum linelength reported by - # all of the supported platforms: 8192 (on NT/2K/XP). - lt_cv_sys_max_cmd_len=8192; - ;; - - amigaos*) - # On AmigaOS with pdksh, this test takes hours, literally. - # So we just punt and use a minimum line length of 8192. - lt_cv_sys_max_cmd_len=8192; - ;; - - netbsd* | freebsd* | openbsd* | darwin* | dragonfly*) - # This has been around since 386BSD, at least. Likely further. - if test -x /sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` - elif test -x /usr/sbin/sysctl; then - lt_cv_sys_max_cmd_len=`/usr/sbin/sysctl -n kern.argmax` - else - lt_cv_sys_max_cmd_len=65536 # usable default for all BSDs - fi - # And add a safety zone - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - ;; - - interix*) - # We know the value 262144 and hardcode it with a safety zone (like BSD) - lt_cv_sys_max_cmd_len=196608 - ;; - - osf*) - # Dr. Hans Ekkehard Plesser reports seeing a kernel panic running configure - # due to this test when exec_disable_arg_limit is 1 on Tru64. It is not - # nice to cause kernel panics so lets avoid the loop below. - # First set a reasonable default. - lt_cv_sys_max_cmd_len=16384 - # - if test -x /sbin/sysconfig; then - case `/sbin/sysconfig -q proc exec_disable_arg_limit` in - *1*) lt_cv_sys_max_cmd_len=-1 ;; - esac - fi - ;; - sco3.2v5*) - lt_cv_sys_max_cmd_len=102400 - ;; - sysv5* | sco5v6* | sysv4.2uw2*) - kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` - if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` - else - lt_cv_sys_max_cmd_len=32768 - fi - ;; - *) - lt_cv_sys_max_cmd_len=`(getconf ARG_MAX) 2> /dev/null` - if test -n "$lt_cv_sys_max_cmd_len"; then - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 4` - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \* 3` - else - # Make teststring a little bigger before we do anything with it. - # a 1K string should be a reasonable start. - for i in 1 2 3 4 5 6 7 8 ; do - teststring=$teststring$teststring - done - SHELL=${SHELL-${CONFIG_SHELL-/bin/sh}} - # If test is not a shell built-in, we'll probably end up computing a - # maximum length that is only half of the actual maximum length, but - # we can't tell. - while { test "X"`$SHELL $0 --fallback-echo "X$teststring$teststring" 2>/dev/null` \ - = "XX$teststring$teststring"; } >/dev/null 2>&1 && - test $i != 17 # 1/2 MB should be enough - do - i=`expr $i + 1` - teststring=$teststring$teststring - done - # Only check the string length outside the loop. - lt_cv_sys_max_cmd_len=`expr "X$teststring" : ".*" 2>&1` - teststring= - # Add a significant safety factor because C++ compilers can tack on - # massive amounts of additional arguments before passing them to the - # linker. It appears as though 1/2 is a usable value. - lt_cv_sys_max_cmd_len=`expr $lt_cv_sys_max_cmd_len \/ 2` - fi - ;; - esac - -fi - -if test -n $lt_cv_sys_max_cmd_len ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_sys_max_cmd_len" >&5 -$as_echo "$lt_cv_sys_max_cmd_len" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: none" >&5 -$as_echo "none" >&6; } -fi -max_cmd_len=$lt_cv_sys_max_cmd_len - - - - - - -: ${CP="cp -f"} -: ${MV="mv -f"} -: ${RM="rm -f"} - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands some XSI constructs" >&5 -$as_echo_n "checking whether the shell understands some XSI constructs... " >&6; } -# Try some XSI features -xsi_shell=no -( _lt_dummy="a/b/c" - test "${_lt_dummy##*/},${_lt_dummy%/*},"${_lt_dummy%"$_lt_dummy"}, \ - = c,a/b,, \ - && eval 'test $(( 1 + 1 )) -eq 2 \ - && test "${#_lt_dummy}" -eq 5' ) >/dev/null 2>&1 \ - && xsi_shell=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $xsi_shell" >&5 -$as_echo "$xsi_shell" >&6; } - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the shell understands \"+=\"" >&5 -$as_echo_n "checking whether the shell understands \"+=\"... " >&6; } -lt_shell_append=no -( foo=bar; set foo baz; eval "$1+=\$2" && test "$foo" = barbaz ) \ - >/dev/null 2>&1 \ - && lt_shell_append=yes -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_shell_append" >&5 -$as_echo "$lt_shell_append" >&6; } - - -if ( (MAIL=60; unset MAIL) || exit) >/dev/null 2>&1; then - lt_unset=unset -else - lt_unset=false -fi - - - - - -# test EBCDIC or ASCII -case `echo X|tr X '\101'` in - A) # ASCII based system - # \n is not interpreted correctly by Solaris 8 /usr/ucb/tr - lt_SP2NL='tr \040 \012' - lt_NL2SP='tr \015\012 \040\040' - ;; - *) # EBCDIC based system - lt_SP2NL='tr \100 \n' - lt_NL2SP='tr \r\n \100\100' - ;; -esac - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $LD option to reload object files" >&5 -$as_echo_n "checking for $LD option to reload object files... " >&6; } -if ${lt_cv_ld_reload_flag+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_reload_flag='-r' -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_reload_flag" >&5 -$as_echo "$lt_cv_ld_reload_flag" >&6; } -reload_flag=$lt_cv_ld_reload_flag -case $reload_flag in -"" | " "*) ;; -*) reload_flag=" $reload_flag" ;; -esac -reload_cmds='$LD$reload_flag -o $output$reload_objs' -case $host_os in - darwin*) - if test "$GCC" = yes; then - reload_cmds='$LTCC $LTCFLAGS -nostdlib ${wl}-r -o $output$reload_objs' - else - reload_cmds='$LD$reload_flag -o $output$reload_objs' - fi - ;; -esac - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. -set dummy ${ac_tool_prefix}objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OBJDUMP"; then - ac_cv_prog_OBJDUMP="$OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OBJDUMP="${ac_tool_prefix}objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OBJDUMP=$ac_cv_prog_OBJDUMP -if test -n "$OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OBJDUMP" >&5 -$as_echo "$OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OBJDUMP"; then - ac_ct_OBJDUMP=$OBJDUMP - # Extract the first word of "objdump", so it can be a program name with args. -set dummy objdump; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OBJDUMP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OBJDUMP"; then - ac_cv_prog_ac_ct_OBJDUMP="$ac_ct_OBJDUMP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OBJDUMP="objdump" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OBJDUMP=$ac_cv_prog_ac_ct_OBJDUMP -if test -n "$ac_ct_OBJDUMP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OBJDUMP" >&5 -$as_echo "$ac_ct_OBJDUMP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OBJDUMP" = x; then - OBJDUMP="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OBJDUMP=$ac_ct_OBJDUMP - fi -else - OBJDUMP="$ac_cv_prog_OBJDUMP" -fi - -test -z "$OBJDUMP" && OBJDUMP=objdump - - - - - - - - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to recognize dependent libraries" >&5 -$as_echo_n "checking how to recognize dependent libraries... " >&6; } -if ${lt_cv_deplibs_check_method+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_file_magic_cmd='$MAGIC_CMD' -lt_cv_file_magic_test_file= -lt_cv_deplibs_check_method='unknown' -# Need to set the preceding variable on all platforms that support -# interlibrary dependencies. -# 'none' -- dependencies not supported. -# `unknown' -- same as none, but documents that we really don't know. -# 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. -# 'file_magic [[regex]]' -- check by looking for files in library path -# which responds to the $file_magic_cmd with a given extended regex. -# If you have `file' or equivalent on your system and you're not sure -# whether `pass_all' will *always* work, you probably want this one. - -case $host_os in -aix[4-9]*) - lt_cv_deplibs_check_method=pass_all - ;; - -beos*) - lt_cv_deplibs_check_method=pass_all - ;; - -bsdi[45]*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' - lt_cv_file_magic_test_file=/shlib/libc.so - ;; - -cygwin*) - # func_win32_libid is a shell function defined in ltmain.sh - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - ;; - -mingw* | pw32*) - # Base MSYS/MinGW do not provide the 'file' command needed by - # func_win32_libid shell function, so use a weaker test based on 'objdump', - # unless we find 'file', for example because we are cross-compiling. - if ( file / ) >/dev/null 2>&1; then - lt_cv_deplibs_check_method='file_magic ^x86 archive import|^x86 DLL' - lt_cv_file_magic_cmd='func_win32_libid' - else - lt_cv_deplibs_check_method='file_magic file format pei*-i386(.*architecture: i386)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - fi - ;; - -cegcc) - # use the weaker test based on 'objdump'. See mingw*. - lt_cv_deplibs_check_method='file_magic file format pe-arm-.*little(.*architecture: arm)?' - lt_cv_file_magic_cmd='$OBJDUMP -f' - ;; - -darwin* | rhapsody*) - lt_cv_deplibs_check_method=pass_all - ;; - -freebsd* | dragonfly*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - case $host_cpu in - i*86 ) - # Not sure whether the presence of OpenBSD here was a mistake. - # Let's accept both of them until this is cleared up. - lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` - ;; - esac - else - lt_cv_deplibs_check_method=pass_all - fi - ;; - -gnu*) - lt_cv_deplibs_check_method=pass_all - ;; - -hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file - case $host_cpu in - ia64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' - lt_cv_file_magic_test_file=/usr/lib/hpux32/libc.so - ;; - hppa*64*) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - PA-RISC [0-9].[0-9]' - lt_cv_file_magic_test_file=/usr/lib/pa20_64/libc.sl - ;; - *) - lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|PA-RISC[0-9].[0-9]) shared library' - lt_cv_file_magic_test_file=/usr/lib/libc.sl - ;; - esac - ;; - -interix[3-9]*) - # PIC code is broken on Interix 3.x, that's why |\.a not |_pic\.a here - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|\.a)$' - ;; - -irix5* | irix6* | nonstopux*) - case $LD in - *-32|*"-32 ") libmagic=32-bit;; - *-n32|*"-n32 ") libmagic=N32;; - *-64|*"-64 ") libmagic=64-bit;; - *) libmagic=never-match;; - esac - lt_cv_deplibs_check_method=pass_all - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - lt_cv_deplibs_check_method=pass_all - ;; - -netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so|_pic\.a)$' - fi - ;; - -newos6*) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file - lt_cv_file_magic_test_file=/usr/lib/libnls.so - ;; - -*nto* | *qnx*) - lt_cv_deplibs_check_method=pass_all - ;; - -openbsd*) - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' - else - lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' - fi - ;; - -osf3* | osf4* | osf5*) - lt_cv_deplibs_check_method=pass_all - ;; - -rdos*) - lt_cv_deplibs_check_method=pass_all - ;; - -solaris*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - lt_cv_deplibs_check_method=pass_all - ;; - -sysv4 | sysv4.3*) - case $host_vendor in - motorola) - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib) M[0-9][0-9]* Version [0-9]' - lt_cv_file_magic_test_file=`echo /usr/lib/libc.so*` - ;; - ncr) - lt_cv_deplibs_check_method=pass_all - ;; - sequent) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [LM]SB (shared object|dynamic lib )' - ;; - sni) - lt_cv_file_magic_cmd='/bin/file' - lt_cv_deplibs_check_method="file_magic ELF [0-9][0-9]*-bit [LM]SB dynamic lib" - lt_cv_file_magic_test_file=/lib/libc.so - ;; - siemens) - lt_cv_deplibs_check_method=pass_all - ;; - pc) - lt_cv_deplibs_check_method=pass_all - ;; - esac - ;; - -tpf*) - lt_cv_deplibs_check_method=pass_all - ;; -esac - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_deplibs_check_method" >&5 -$as_echo "$lt_cv_deplibs_check_method" >&6; } -file_magic_cmd=$lt_cv_file_magic_cmd -deplibs_check_method=$lt_cv_deplibs_check_method -test -z "$deplibs_check_method" && deplibs_check_method=unknown - - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ar", so it can be a program name with args. -set dummy ${ac_tool_prefix}ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$AR"; then - ac_cv_prog_AR="$AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_AR="${ac_tool_prefix}ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -AR=$ac_cv_prog_AR -if test -n "$AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $AR" >&5 -$as_echo "$AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_AR"; then - ac_ct_AR=$AR - # Extract the first word of "ar", so it can be a program name with args. -set dummy ar; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_AR+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_AR"; then - ac_cv_prog_ac_ct_AR="$ac_ct_AR" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_AR="ar" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_AR=$ac_cv_prog_ac_ct_AR -if test -n "$ac_ct_AR"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_AR" >&5 -$as_echo "$ac_ct_AR" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_AR" = x; then - AR="false" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - AR=$ac_ct_AR - fi -else - AR="$ac_cv_prog_AR" -fi - -test -z "$AR" && AR=ar -test -z "$AR_FLAGS" && AR_FLAGS=cru - - - - - - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}strip", so it can be a program name with args. -set dummy ${ac_tool_prefix}strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$STRIP"; then - ac_cv_prog_STRIP="$STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_STRIP="${ac_tool_prefix}strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -STRIP=$ac_cv_prog_STRIP -if test -n "$STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $STRIP" >&5 -$as_echo "$STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_STRIP"; then - ac_ct_STRIP=$STRIP - # Extract the first word of "strip", so it can be a program name with args. -set dummy strip; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_STRIP+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_STRIP"; then - ac_cv_prog_ac_ct_STRIP="$ac_ct_STRIP" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_STRIP="strip" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_STRIP=$ac_cv_prog_ac_ct_STRIP -if test -n "$ac_ct_STRIP"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_STRIP" >&5 -$as_echo "$ac_ct_STRIP" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_STRIP" = x; then - STRIP=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - STRIP=$ac_ct_STRIP - fi -else - STRIP="$ac_cv_prog_STRIP" -fi - -test -z "$STRIP" && STRIP=: - - - - - - -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -RANLIB=$ac_cv_prog_RANLIB -if test -n "$RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -$as_echo "$RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_RANLIB+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -$as_echo "$ac_ct_RANLIB" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$oldlib" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - - -# Check for command to grab the raw symbol name followed by C symbol from nm. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking command to parse $NM output from $compiler object" >&5 -$as_echo_n "checking command to parse $NM output from $compiler object... " >&6; } -if ${lt_cv_sys_global_symbol_pipe+:} false; then : - $as_echo_n "(cached) " >&6 -else - -# These are sane defaults that work on at least a few old systems. -# [They come from Ultrix. What could be older than Ultrix?!! ;)] - -# Character class describing NM global symbol codes. -symcode='[BCDEGRST]' - -# Regexp to match symbols that can be accessed directly from C. -sympat='\([_A-Za-z][_A-Za-z0-9]*\)' - -# Define system-specific variables. -case $host_os in -aix*) - symcode='[BCDT]' - ;; -cygwin* | mingw* | pw32* | cegcc*) - symcode='[ABCDGISTW]' - ;; -hpux*) - if test "$host_cpu" = ia64; then - symcode='[ABCDEGRST]' - fi - ;; -irix* | nonstopux*) - symcode='[BCDEGRST]' - ;; -osf*) - symcode='[BCDEGQRST]' - ;; -solaris*) - symcode='[BDRT]' - ;; -sco3.2v5*) - symcode='[DT]' - ;; -sysv4.2uw2*) - symcode='[DT]' - ;; -sysv5* | sco5v6* | unixware* | OpenUNIX*) - symcode='[ABDT]' - ;; -sysv4) - symcode='[DFNSTU]' - ;; -esac - -# If we're using GNU nm, then use its standard symbol codes. -case `$NM -V 2>&1` in -*GNU* | *'with BFD'*) - symcode='[ABCDGIRSTW]' ;; -esac - -# Transform an extracted symbol line into a proper C declaration. -# Some systems (esp. on ia64) link data and code symbols differently, -# so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n -e 's/^T .* \(.*\)$/extern int \1();/p' -e 's/^$symcode* .* \(.*\)$/extern char \1;/p'" - -# Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"\2\", (void *) \&\2},/p'" -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n -e 's/^: \([^ ]*\) $/ {\\\"\1\\\", (void *) 0},/p' -e 's/^$symcode* \([^ ]*\) \(lib[^ ]*\)$/ {\"\2\", (void *) \&\2},/p' -e 's/^$symcode* \([^ ]*\) \([^ ]*\)$/ {\"lib\2\", (void *) \&\2},/p'" - -# Handle CRLF in mingw tool chain -opt_cr= -case $build_os in -mingw*) - opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp - ;; -esac - -# Try without a prefix underscore, then with it. -for ac_symprfx in "" "_"; do - - # Transform symcode, sympat, and symprfx into a raw symbol and a C symbol. - symxfrm="\\1 $ac_symprfx\\2 \\2" - - # Write the raw and C identifiers. - if test "$lt_cv_nm_interface" = "MS dumpbin"; then - # Fake it for dumpbin and say T for any non-static function - # and D for any global variable. - # Also find C++ and __fastcall symbols from MSVC++, - # which start with @ or ?. - lt_cv_sys_global_symbol_pipe="$AWK '"\ -" {last_section=section; section=\$ 3};"\ -" /Section length .*#relocs.*(pick any)/{hide[last_section]=1};"\ -" \$ 0!~/External *\|/{next};"\ -" / 0+ UNDEF /{next}; / UNDEF \([^|]\)*()/{next};"\ -" {if(hide[section]) next};"\ -" {f=0}; \$ 0~/\(\).*\|/{f=1}; {printf f ? \"T \" : \"D \"};"\ -" {split(\$ 0, a, /\||\r/); split(a[2], s)};"\ -" s[1]~/^[@?]/{print s[1], s[1]; next};"\ -" s[1]~prfx {split(s[1],t,\"@\"); print t[1], substr(t[1],length(prfx))}"\ -" ' prfx=^$ac_symprfx" - else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" - fi - - # Check to see that the pipe works correctly. - pipe_works=no - - rm -f conftest* - cat > conftest.$ac_ext <<_LT_EOF -#ifdef __cplusplus -extern "C" { -#endif -char nm_test_var; -void nm_test_func(void); -void nm_test_func(void){} -#ifdef __cplusplus -} -#endif -int main(){nm_test_var='a';nm_test_func();return(0);} -_LT_EOF - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - # Now try to grab the symbols. - nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| $lt_cv_sys_global_symbol_pipe \> $nlist) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then - # Try sorting and uniquifying the output. - if sort "$nlist" | uniq > "$nlist"T; then - mv -f "$nlist"T "$nlist" - else - rm -f "$nlist"T - fi - - # Make sure that we snagged all the symbols we need. - if $GREP ' nm_test_var$' "$nlist" >/dev/null; then - if $GREP ' nm_test_func$' "$nlist" >/dev/null; then - cat <<_LT_EOF > conftest.$ac_ext -#ifdef __cplusplus -extern "C" { -#endif - -_LT_EOF - # Now generate the symbol file. - eval "$lt_cv_sys_global_symbol_to_cdecl"' < "$nlist" | $GREP -v main >> conftest.$ac_ext' - - cat <<_LT_EOF >> conftest.$ac_ext - -/* The mapping between symbol names and symbols. */ -const struct { - const char *name; - void *address; -} -lt__PROGRAM__LTX_preloaded_symbols[] = -{ - { "@PROGRAM@", (void *) 0 }, -_LT_EOF - $SED "s/^$symcode$symcode* \(.*\) \(.*\)$/ {\"\2\", (void *) \&\2},/" < "$nlist" | $GREP -v main >> conftest.$ac_ext - cat <<\_LT_EOF >> conftest.$ac_ext - {0, (void *) 0} -}; - -/* This works around a problem in FreeBSD linker */ -#ifdef FREEBSD_WORKAROUND -static const void *lt_preloaded_setup() { - return lt__PROGRAM__LTX_preloaded_symbols; -} -#endif - -#ifdef __cplusplus -} -#endif -_LT_EOF - # Now try linking the two files. - mv conftest.$ac_objext conftstm.$ac_objext - lt_save_LIBS="$LIBS" - lt_save_CFLAGS="$CFLAGS" - LIBS="conftstm.$ac_objext" - CFLAGS="$CFLAGS$lt_prog_compiler_no_builtin_flag" - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext}; then - pipe_works=yes - fi - LIBS="$lt_save_LIBS" - CFLAGS="$lt_save_CFLAGS" - else - echo "cannot find nm_test_func in $nlist" >&5 - fi - else - echo "cannot find nm_test_var in $nlist" >&5 - fi - else - echo "cannot run $lt_cv_sys_global_symbol_pipe" >&5 - fi - else - echo "$progname: failed program was:" >&5 - cat conftest.$ac_ext >&5 - fi - rm -rf conftest* conftst* - - # Do not use the global_symbol_pipe unless it works. - if test "$pipe_works" = yes; then - break - else - lt_cv_sys_global_symbol_pipe= - fi -done - -fi - -if test -z "$lt_cv_sys_global_symbol_pipe"; then - lt_cv_sys_global_symbol_to_cdecl= -fi -if test -z "$lt_cv_sys_global_symbol_pipe$lt_cv_sys_global_symbol_to_cdecl"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: failed" >&5 -$as_echo "failed" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ok" >&5 -$as_echo "ok" >&6; } -fi - - - - - - - - - - - - - - - - - - - - - - - -# Check whether --enable-libtool-lock was given. -if test "${enable_libtool_lock+set}" = set; then : - enableval=$enable_libtool_lock; -fi - -test "x$enable_libtool_lock" != xno && enable_libtool_lock=yes - -# Some flags need to be propagated to the compiler or linker for good -# libtool support. -case $host in -ia64-*-hpux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in - *ELF-32*) - HPUX_IA64_MODE="32" - ;; - *ELF-64*) - HPUX_IA64_MODE="64" - ;; - esac - fi - rm -rf conftest* - ;; -*-*-irix6*) - # Find out which ABI we are using. - echo '#line 5157 "configure"' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - if test "$lt_cv_prog_gnu_ld" = yes; then - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -melf32bsmip" - ;; - *N32*) - LD="${LD-ld} -melf32bmipn32" - ;; - *64-bit*) - LD="${LD-ld} -melf64bmip" - ;; - esac - else - case `/usr/bin/file conftest.$ac_objext` in - *32-bit*) - LD="${LD-ld} -32" - ;; - *N32*) - LD="${LD-ld} -n32" - ;; - *64-bit*) - LD="${LD-ld} -64" - ;; - esac - fi - fi - rm -rf conftest* - ;; - -x86_64-*kfreebsd*-gnu|x86_64-*linux*|ppc*-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *32-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_i386_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_i386" - ;; - ppc64-*linux*|powerpc64-*linux*) - LD="${LD-ld} -m elf32ppclinux" - ;; - s390x-*linux*) - LD="${LD-ld} -m elf_s390" - ;; - sparc64-*linux*) - LD="${LD-ld} -m elf32_sparc" - ;; - esac - ;; - *64-bit*) - case $host in - x86_64-*kfreebsd*-gnu) - LD="${LD-ld} -m elf_x86_64_fbsd" - ;; - x86_64-*linux*) - LD="${LD-ld} -m elf_x86_64" - ;; - ppc*-*linux*|powerpc*-*linux*) - LD="${LD-ld} -m elf64ppc" - ;; - s390*-*linux*|s390*-*tpf*) - LD="${LD-ld} -m elf64_s390" - ;; - sparc*-*linux*) - LD="${LD-ld} -m elf64_sparc" - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; - -*-*-sco3.2v5*) - # On SCO OpenServer 5, we need -belf to get full-featured binaries. - SAVE_CFLAGS="$CFLAGS" - CFLAGS="$CFLAGS -belf" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the C compiler needs -belf" >&5 -$as_echo_n "checking whether the C compiler needs -belf... " >&6; } -if ${lt_cv_cc_needs_belf+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_cc_needs_belf=yes -else - lt_cv_cc_needs_belf=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_cc_needs_belf" >&5 -$as_echo "$lt_cv_cc_needs_belf" >&6; } - if test x"$lt_cv_cc_needs_belf" != x"yes"; then - # this is probably gcc 2.8.0, egcs 1.0 or newer; no need for -belf - CFLAGS="$SAVE_CFLAGS" - fi - ;; -sparc*-*solaris*) - # Find out which ABI we are using. - echo 'int i;' > conftest.$ac_ext - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in - *64-bit*) - case $lt_cv_prog_gnu_ld in - yes*) LD="${LD-ld} -m elf64_sparc" ;; - *) - if ${LD-ld} -64 -r -o conftest2.o conftest.o >/dev/null 2>&1; then - LD="${LD-ld} -64" - fi - ;; - esac - ;; - esac - fi - rm -rf conftest* - ;; -esac - -need_locks="$enable_libtool_lock" - - - case $host_os in - rhapsody* | darwin*) - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}dsymutil", so it can be a program name with args. -set dummy ${ac_tool_prefix}dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$DSYMUTIL"; then - ac_cv_prog_DSYMUTIL="$DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_DSYMUTIL="${ac_tool_prefix}dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -DSYMUTIL=$ac_cv_prog_DSYMUTIL -if test -n "$DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $DSYMUTIL" >&5 -$as_echo "$DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_DSYMUTIL"; then - ac_ct_DSYMUTIL=$DSYMUTIL - # Extract the first word of "dsymutil", so it can be a program name with args. -set dummy dsymutil; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_DSYMUTIL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_DSYMUTIL"; then - ac_cv_prog_ac_ct_DSYMUTIL="$ac_ct_DSYMUTIL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_DSYMUTIL="dsymutil" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_DSYMUTIL=$ac_cv_prog_ac_ct_DSYMUTIL -if test -n "$ac_ct_DSYMUTIL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_DSYMUTIL" >&5 -$as_echo "$ac_ct_DSYMUTIL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_DSYMUTIL" = x; then - DSYMUTIL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - DSYMUTIL=$ac_ct_DSYMUTIL - fi -else - DSYMUTIL="$ac_cv_prog_DSYMUTIL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}nmedit", so it can be a program name with args. -set dummy ${ac_tool_prefix}nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$NMEDIT"; then - ac_cv_prog_NMEDIT="$NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_NMEDIT="${ac_tool_prefix}nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -NMEDIT=$ac_cv_prog_NMEDIT -if test -n "$NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $NMEDIT" >&5 -$as_echo "$NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_NMEDIT"; then - ac_ct_NMEDIT=$NMEDIT - # Extract the first word of "nmedit", so it can be a program name with args. -set dummy nmedit; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_NMEDIT+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_NMEDIT"; then - ac_cv_prog_ac_ct_NMEDIT="$ac_ct_NMEDIT" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_NMEDIT="nmedit" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_NMEDIT=$ac_cv_prog_ac_ct_NMEDIT -if test -n "$ac_ct_NMEDIT"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_NMEDIT" >&5 -$as_echo "$ac_ct_NMEDIT" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_NMEDIT" = x; then - NMEDIT=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - NMEDIT=$ac_ct_NMEDIT - fi -else - NMEDIT="$ac_cv_prog_NMEDIT" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}lipo", so it can be a program name with args. -set dummy ${ac_tool_prefix}lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$LIPO"; then - ac_cv_prog_LIPO="$LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_LIPO="${ac_tool_prefix}lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -LIPO=$ac_cv_prog_LIPO -if test -n "$LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $LIPO" >&5 -$as_echo "$LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_LIPO"; then - ac_ct_LIPO=$LIPO - # Extract the first word of "lipo", so it can be a program name with args. -set dummy lipo; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_LIPO+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_LIPO"; then - ac_cv_prog_ac_ct_LIPO="$ac_ct_LIPO" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_LIPO="lipo" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_LIPO=$ac_cv_prog_ac_ct_LIPO -if test -n "$ac_ct_LIPO"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_LIPO" >&5 -$as_echo "$ac_ct_LIPO" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_LIPO" = x; then - LIPO=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - LIPO=$ac_ct_LIPO - fi -else - LIPO="$ac_cv_prog_LIPO" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL"; then - ac_cv_prog_OTOOL="$OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL="${ac_tool_prefix}otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL=$ac_cv_prog_OTOOL -if test -n "$OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL" >&5 -$as_echo "$OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL"; then - ac_ct_OTOOL=$OTOOL - # Extract the first word of "otool", so it can be a program name with args. -set dummy otool; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL"; then - ac_cv_prog_ac_ct_OTOOL="$ac_ct_OTOOL" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL="otool" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL=$ac_cv_prog_ac_ct_OTOOL -if test -n "$ac_ct_OTOOL"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL" >&5 -$as_echo "$ac_ct_OTOOL" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL" = x; then - OTOOL=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL=$ac_ct_OTOOL - fi -else - OTOOL="$ac_cv_prog_OTOOL" -fi - - if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}otool64", so it can be a program name with args. -set dummy ${ac_tool_prefix}otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$OTOOL64"; then - ac_cv_prog_OTOOL64="$OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_OTOOL64="${ac_tool_prefix}otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -OTOOL64=$ac_cv_prog_OTOOL64 -if test -n "$OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $OTOOL64" >&5 -$as_echo "$OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_OTOOL64"; then - ac_ct_OTOOL64=$OTOOL64 - # Extract the first word of "otool64", so it can be a program name with args. -set dummy otool64; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_ac_ct_OTOOL64+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$ac_ct_OTOOL64"; then - ac_cv_prog_ac_ct_OTOOL64="$ac_ct_OTOOL64" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_OTOOL64="otool64" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_OTOOL64=$ac_cv_prog_ac_ct_OTOOL64 -if test -n "$ac_ct_OTOOL64"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_ct_OTOOL64" >&5 -$as_echo "$ac_ct_OTOOL64" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - if test "x$ac_ct_OTOOL64" = x; then - OTOOL64=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -$as_echo "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - OTOOL64=$ac_ct_OTOOL64 - fi -else - OTOOL64="$ac_cv_prog_OTOOL64" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -single_module linker flag" >&5 -$as_echo_n "checking for -single_module linker flag... " >&6; } -if ${lt_cv_apple_cc_single_mod+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_apple_cc_single_mod=no - if test -z "${LT_MULTI_MODULE}"; then - # By default we will add the -single_module flag. You can override - # by either setting the environment variable LT_MULTI_MODULE - # non-empty at configure time, or by adding -multi_module to the - # link flags. - rm -rf libconftest.dylib* - echo "int foo(void){return 1;}" > conftest.c - echo "$LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ --dynamiclib -Wl,-single_module conftest.c" >&5 - $LTCC $LTCFLAGS $LDFLAGS -o libconftest.dylib \ - -dynamiclib -Wl,-single_module conftest.c 2>conftest.err - _lt_result=$? - if test -f libconftest.dylib && test ! -s conftest.err && test $_lt_result = 0; then - lt_cv_apple_cc_single_mod=yes - else - cat conftest.err >&5 - fi - rm -rf libconftest.dylib* - rm -f conftest.* - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 -$as_echo "$lt_cv_apple_cc_single_mod" >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 -$as_echo_n "checking for -exported_symbols_list linker flag... " >&6; } -if ${lt_cv_ld_exported_symbols_list+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_ld_exported_symbols_list=no - save_LDFLAGS=$LDFLAGS - echo "_main" > conftest.sym - LDFLAGS="$LDFLAGS -Wl,-exported_symbols_list,conftest.sym" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - lt_cv_ld_exported_symbols_list=yes -else - lt_cv_ld_exported_symbols_list=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_ld_exported_symbols_list" >&5 -$as_echo "$lt_cv_ld_exported_symbols_list" >&6; } - case $host_os in - rhapsody* | darwin1.[012]) - _lt_dar_allow_undefined='${wl}-undefined ${wl}suppress' ;; - darwin1.*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - 10.[012]*) - _lt_dar_allow_undefined='${wl}-flat_namespace ${wl}-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='${wl}-undefined ${wl}dynamic_lookup' ;; - esac - ;; - esac - if test "$lt_cv_apple_cc_single_mod" = "yes"; then - _lt_dar_single_mod='$single_module' - fi - if test "$lt_cv_ld_exported_symbols_list" = "yes"; then - _lt_dar_export_syms=' ${wl}-exported_symbols_list,$output_objdir/${libname}-symbols.expsym' - else - _lt_dar_export_syms='~$NMEDIT -s $output_objdir/${libname}-symbols.expsym ${lib}' - fi - if test "$DSYMUTIL" != ":"; then - _lt_dsymutil='~$DSYMUTIL $lib || :' - else - _lt_dsymutil= - fi - ;; - esac - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking how to run the C preprocessor" >&5 -$as_echo_n "checking how to run the C preprocessor... " >&6; } -# On Suns, sometimes $CPP names a directory. -if test -n "$CPP" && test -d "$CPP"; then - CPP= -fi -if test -z "$CPP"; then - if ${ac_cv_prog_CPP+:} false; then : - $as_echo_n "(cached) " >&6 -else - # Double quotes because CPP needs to be expanded - for CPP in "$CC -E" "$CC -E -traditional-cpp" "/lib/cpp" - do - ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - break -fi - - done - ac_cv_prog_CPP=$CPP - -fi - CPP=$ac_cv_prog_CPP -else - ac_cv_prog_CPP=$CPP -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $CPP" >&5 -$as_echo "$CPP" >&6; } -ac_preproc_ok=false -for ac_c_preproc_warn_flag in '' yes -do - # Use a header file that comes with gcc, so configuring glibc - # with a fresh cross-compiler works. - # Prefer to if __STDC__ is defined, since - # exists even on freestanding compilers. - # On the NeXT, cc -E runs the code through the compiler's parser, - # not just through cpp. "Syntax error" is here to catch this case. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#ifdef __STDC__ -# include -#else -# include -#endif - Syntax error -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - -else - # Broken: fails on valid input. -continue -fi -rm -f conftest.err conftest.i conftest.$ac_ext - - # OK, works on sane cases. Now check whether nonexistent headers - # can be detected and how. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -_ACEOF -if ac_fn_c_try_cpp "$LINENO"; then : - # Broken: success on invalid input. -continue -else - # Passes both tests. -ac_preproc_ok=: -break -fi -rm -f conftest.err conftest.i conftest.$ac_ext - -done -# Because of `break', _AC_PREPROC_IFELSE's cleaning code was skipped. -rm -f conftest.i conftest.err conftest.$ac_ext -if $ac_preproc_ok; then : - -else - { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 -$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} -as_fn_error $? "C preprocessor \"$CPP\" fails sanity check -See \`config.log' for more details" "$LINENO" 5; } -fi - -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for ANSI C header files" >&5 -$as_echo_n "checking for ANSI C header files... " >&6; } -if ${ac_cv_header_stdc+:} false; then : - $as_echo_n "(cached) " >&6 -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#include -#include - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_header_stdc=yes -else - ac_cv_header_stdc=no -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - -if test $ac_cv_header_stdc = yes; then - # SunOS 4.x string.h does not declare mem*, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "memchr" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # ISC 2.0.2 stdlib.h does not declare free, contrary to ANSI. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - -_ACEOF -if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | - $EGREP "free" >/dev/null 2>&1; then : - -else - ac_cv_header_stdc=no -fi -rm -f conftest* - -fi - -if test $ac_cv_header_stdc = yes; then - # /bin/cc in Irix-4.0.5 gets non-ANSI ctype macros unless using -ansi. - if test "$cross_compiling" = yes; then : - : -else - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include -#include -#if ((' ' & 0x0FF) == 0x020) -# define ISLOWER(c) ('a' <= (c) && (c) <= 'z') -# define TOUPPER(c) (ISLOWER(c) ? 'A' + ((c) - 'a') : (c)) -#else -# define ISLOWER(c) \ - (('a' <= (c) && (c) <= 'i') \ - || ('j' <= (c) && (c) <= 'r') \ - || ('s' <= (c) && (c) <= 'z')) -# define TOUPPER(c) (ISLOWER(c) ? ((c) | 0x40) : (c)) -#endif - -#define XOR(e, f) (((e) && !(f)) || (!(e) && (f))) -int -main () -{ - int i; - for (i = 0; i < 256; i++) - if (XOR (islower (i), ISLOWER (i)) - || toupper (i) != TOUPPER (i)) - return 2; - return 0; -} -_ACEOF -if ac_fn_c_try_run "$LINENO"; then : - -else - ac_cv_header_stdc=no -fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - -fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_header_stdc" >&5 -$as_echo "$ac_cv_header_stdc" >&6; } -if test $ac_cv_header_stdc = yes; then - -$as_echo "#define STDC_HEADERS 1" >>confdefs.h - -fi - -# On IRIX 5.3, sys/types and inttypes.h are conflicting. -for ac_header in sys/types.h sys/stat.h stdlib.h string.h memory.h strings.h \ - inttypes.h stdint.h unistd.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_compile "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default -" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -for ac_header in dlfcn.h -do : - ac_fn_c_check_header_compile "$LINENO" "dlfcn.h" "ac_cv_header_dlfcn_h" "$ac_includes_default -" -if test "x$ac_cv_header_dlfcn_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_DLFCN_H 1 -_ACEOF - -fi - -done - - - -# Set options - - - - enable_dlopen=no - - - enable_win32_dll=no - - - # Check whether --enable-shared was given. -if test "${enable_shared+set}" = set; then : - enableval=$enable_shared; p=${PACKAGE-default} - case $enableval in - yes) enable_shared=yes ;; - no) enable_shared=no ;; - *) - enable_shared=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_shared=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_shared=yes -fi - - - - - - - - - - # Check whether --enable-static was given. -if test "${enable_static+set}" = set; then : - enableval=$enable_static; p=${PACKAGE-default} - case $enableval in - yes) enable_static=yes ;; - no) enable_static=no ;; - *) - enable_static=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_static=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_static=yes -fi - - - - - - - - - - -# Check whether --with-pic was given. -if test "${with_pic+set}" = set; then : - withval=$with_pic; pic_mode="$withval" -else - pic_mode=default -fi - - -test -z "$pic_mode" && pic_mode=default - - - - - - - - # Check whether --enable-fast-install was given. -if test "${enable_fast_install+set}" = set; then : - enableval=$enable_fast_install; p=${PACKAGE-default} - case $enableval in - yes) enable_fast_install=yes ;; - no) enable_fast_install=no ;; - *) - enable_fast_install=no - # Look at the argument we got. We use all the common list separators. - lt_save_ifs="$IFS"; IFS="${IFS}$PATH_SEPARATOR," - for pkg in $enableval; do - IFS="$lt_save_ifs" - if test "X$pkg" = "X$p"; then - enable_fast_install=yes - fi - done - IFS="$lt_save_ifs" - ;; - esac -else - enable_fast_install=yes -fi - - - - - - - - - - - -# This can be used to rebuild libtool when needed -LIBTOOL_DEPS="$ltmain" - -# Always use our own libtool. -LIBTOOL='$(SHELL) $(top_builddir)/libtool' - - - - - - - - - - - - - - - - - - - - - - - - - -test -z "$LN_S" && LN_S="ln -s" - - - - - - - - - - - - - - -if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for objdir" >&5 -$as_echo_n "checking for objdir... " >&6; } -if ${lt_cv_objdir+:} false; then : - $as_echo_n "(cached) " >&6 -else - rm -f .libs 2>/dev/null -mkdir .libs 2>/dev/null -if test -d .libs; then - lt_cv_objdir=.libs -else - # MS-DOS does not allow filenames that begin with a dot. - lt_cv_objdir=_libs -fi -rmdir .libs 2>/dev/null -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_objdir" >&5 -$as_echo "$lt_cv_objdir" >&6; } -objdir=$lt_cv_objdir - - - - - -cat >>confdefs.h <<_ACEOF -#define LT_OBJDIR "$lt_cv_objdir/" -_ACEOF - - - - - - - - - - - - - - - - - -case $host_os in -aix3*) - # AIX sometimes has problems with the GCC collect2 program. For some - # reason, if we set the COLLECT_NAMES environment variable, the problems - # vanish in a puff of smoke. - if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES - fi - ;; -esac - -# Sed substitution that helps us do robust quoting. It backslashifies -# metacharacters that are still active within double-quoted strings. -sed_quote_subst='s/\(["`$\\]\)/\\\1/g' - -# Same as above, but do not quote variable references. -double_quote_subst='s/\(["`\\]\)/\\\1/g' - -# Sed substitution to delay expansion of an escaped shell variable in a -# double_quote_subst'ed string. -delay_variable_subst='s/\\\\\\\\\\\$/\\\\\\$/g' - -# Sed substitution to delay expansion of an escaped single quote. -delay_single_quote_subst='s/'\''/'\'\\\\\\\'\''/g' - -# Sed substitution to avoid accidental globbing in evaled expressions -no_glob_subst='s/\*/\\\*/g' - -# Global variables: -ofile=libtool -can_build_shared=yes - -# All known linkers require a `.a' archive for static linking (except MSVC, -# which needs '.lib'). -libext=a - -with_gnu_ld="$lt_cv_prog_gnu_ld" - -old_CC="$CC" -old_CFLAGS="$CFLAGS" - -# Set sane defaults for various variables -test -z "$CC" && CC=cc -test -z "$LTCC" && LTCC=$CC -test -z "$LTCFLAGS" && LTCFLAGS=$CFLAGS -test -z "$LD" && LD=ld -test -z "$ac_objext" && ac_objext=o - -for cc_temp in $compiler""; do - case $cc_temp in - compile | *[\\/]compile | ccache | *[\\/]ccache ) ;; - distcc | *[\\/]distcc | purify | *[\\/]purify ) ;; - \-*) ;; - *) break;; - esac -done -cc_basename=`$ECHO "X$cc_temp" | $Xsed -e 's%.*/%%' -e "s%^$host_alias-%%"` - - -# Only perform the check for file, if the check method requires it -test -z "$MAGIC_CMD" && MAGIC_CMD=file -case $deplibs_check_method in -file_magic*) - if test "$file_magic_cmd" = '$MAGIC_CMD'; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for ${ac_tool_prefix}file" >&5 -$as_echo_n "checking for ${ac_tool_prefix}file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/${ac_tool_prefix}file; then - lt_cv_path_MAGIC_CMD="$ac_dir/${ac_tool_prefix}file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - - - -if test -z "$lt_cv_path_MAGIC_CMD"; then - if test -n "$ac_tool_prefix"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for file" >&5 -$as_echo_n "checking for file... " >&6; } -if ${lt_cv_path_MAGIC_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - case $MAGIC_CMD in -[\\/*] | ?:[\\/]*) - lt_cv_path_MAGIC_CMD="$MAGIC_CMD" # Let the user override the test with a path. - ;; -*) - lt_save_MAGIC_CMD="$MAGIC_CMD" - lt_save_ifs="$IFS"; IFS=$PATH_SEPARATOR - ac_dummy="/usr/bin$PATH_SEPARATOR$PATH" - for ac_dir in $ac_dummy; do - IFS="$lt_save_ifs" - test -z "$ac_dir" && ac_dir=. - if test -f $ac_dir/file; then - lt_cv_path_MAGIC_CMD="$ac_dir/file" - if test -n "$file_magic_test_file"; then - case $deplibs_check_method in - "file_magic "*) - file_magic_regex=`expr "$deplibs_check_method" : "file_magic \(.*\)"` - MAGIC_CMD="$lt_cv_path_MAGIC_CMD" - if eval $file_magic_cmd \$file_magic_test_file 2> /dev/null | - $EGREP "$file_magic_regex" > /dev/null; then - : - else - cat <<_LT_EOF 1>&2 - -*** Warning: the command libtool uses to detect shared libraries, -*** $file_magic_cmd, produces output that libtool cannot recognize. -*** The result is that libtool may fail to recognize shared libraries -*** as such. This will affect the creation of libtool libraries that -*** depend on shared libraries, but programs linked with such libtool -*** libraries will work regardless of this problem. Nevertheless, you -*** may want to report the problem to your system manager and/or to -*** bug-libtool@gnu.org - -_LT_EOF - fi ;; - esac - fi - break - fi - done - IFS="$lt_save_ifs" - MAGIC_CMD="$lt_save_MAGIC_CMD" - ;; -esac -fi - -MAGIC_CMD="$lt_cv_path_MAGIC_CMD" -if test -n "$MAGIC_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $MAGIC_CMD" >&5 -$as_echo "$MAGIC_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - else - MAGIC_CMD=: - fi -fi - - fi - ;; -esac - -# Use C for the default configuration in the libtool script - -lt_save_CC="$CC" -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - - -# Source file extension for C test sources. -ac_ext=c - -# Object file extension for compiled C test sources. -objext=o -objext=$objext - -# Code to be used in simple compile tests -lt_simple_compile_test_code="int some_variable = 0;" - -# Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' - - - - - - - -# If no C compiler was specified, use CC. -LTCC=${LTCC-"$CC"} - -# If no C compiler flags were specified, use CFLAGS. -LTCFLAGS=${LTCFLAGS-"$CFLAGS"} - -# Allow CC to be a program name with arguments. -compiler=$CC - -# Save the default compiler, since it gets overwritten when the other -# tags are being tested, and _LT_TAGVAR(compiler, []) is a NOP. -compiler_DEFAULT=$CC - -# save warnings/boilerplate of simple test code -ac_outfile=conftest.$ac_objext -echo "$lt_simple_compile_test_code" >conftest.$ac_ext -eval "$ac_compile" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_compiler_boilerplate=`cat conftest.err` -$RM conftest* - -ac_outfile=conftest.$ac_objext -echo "$lt_simple_link_test_code" >conftest.$ac_ext -eval "$ac_link" 2>&1 >/dev/null | $SED '/^$/d; /^ *+/d' >conftest.err -_lt_linker_boilerplate=`cat conftest.err` -$RM -r conftest* - - -if test -n "$compiler"; then - -lt_prog_compiler_no_builtin_flag= - -if test "$GCC" = yes; then - lt_prog_compiler_no_builtin_flag=' -fno-builtin' - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -fno-rtti -fno-exceptions" >&5 -$as_echo_n "checking if $compiler supports -fno-rtti -fno-exceptions... " >&6; } -if ${lt_cv_prog_compiler_rtti_exceptions+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_rtti_exceptions=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="-fno-rtti -fno-exceptions" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:6682: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:6686: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_rtti_exceptions=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_rtti_exceptions" >&5 -$as_echo "$lt_cv_prog_compiler_rtti_exceptions" >&6; } - -if test x"$lt_cv_prog_compiler_rtti_exceptions" = xyes; then - lt_prog_compiler_no_builtin_flag="$lt_prog_compiler_no_builtin_flag -fno-rtti -fno-exceptions" -else - : -fi - -fi - - - - - - - lt_prog_compiler_wl= -lt_prog_compiler_pic= -lt_prog_compiler_static= - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 -$as_echo_n "checking for $compiler option to produce PIC... " >&6; } - - if test "$GCC" = yes; then - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_static='-static' - - case $host_os in - aix*) - # All AIX code is PIC. - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - lt_prog_compiler_pic='-fPIC' - ;; - m68k) - # FIXME: we need at least 68020 code to build shared libraries, but - # adding the `-m68020' flag to GCC prevents building anything better, - # like `-m68040'. - lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' - ;; - esac - ;; - - beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) - # PIC is the default for these OSes. - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - # Although the cygwin gcc ignores -fPIC, still need this for old-style - # (--disable-auto-import) libraries - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - darwin* | rhapsody*) - # PIC is the default on this platform - # Common symbols not allowed in MH_DYLIB files - lt_prog_compiler_pic='-fno-common' - ;; - - hpux*) - # PIC is the default for 64-bit PA HP-UX, but not for 32-bit - # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag - # sets the default TLS model and affects inlining. - case $host_cpu in - hppa*64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - ;; - - interix[3-9]*) - # Interix 3.x gcc -fpic/-fPIC options generate broken code. - # Instead, we relocate shared libraries at runtime. - ;; - - msdosdjgpp*) - # Just because we use GCC doesn't mean we suddenly get shared libraries - # on systems that don't support them. - lt_prog_compiler_can_build_shared=no - enable_shared=no - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - lt_prog_compiler_pic=-Kconform_pic - fi - ;; - - *) - lt_prog_compiler_pic='-fPIC' - ;; - esac - else - # PORTME Check for flag to pass linker flags through the system compiler. - case $host_os in - aix*) - lt_prog_compiler_wl='-Wl,' - if test "$host_cpu" = ia64; then - # AIX 5 now supports IA64 processor - lt_prog_compiler_static='-Bstatic' - else - lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' - fi - ;; - - mingw* | cygwin* | pw32* | os2* | cegcc*) - # This hack is so that the source file can tell whether it is being - # built for inclusion in a dll (and should export symbols for example). - lt_prog_compiler_pic='-DDLL_EXPORT' - ;; - - hpux9* | hpux10* | hpux11*) - lt_prog_compiler_wl='-Wl,' - # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but - # not for PA HP-UX. - case $host_cpu in - hppa*64*|ia64*) - # +Z the default - ;; - *) - lt_prog_compiler_pic='+Z' - ;; - esac - # Is there a better lt_prog_compiler_static that works with the bundled CC? - lt_prog_compiler_static='${wl}-a ${wl}archive' - ;; - - irix5* | irix6* | nonstopux*) - lt_prog_compiler_wl='-Wl,' - # PIC (with -KPIC) is the default. - lt_prog_compiler_static='-non_shared' - ;; - - linux* | k*bsd*-gnu) - case $cc_basename in - # old Intel for x86_64 which still supported -KPIC. - ecc*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-static' - ;; - # icc used to be incompatible with GCC. - # ICC 10 doesn't accept -KPIC any more. - icc* | ifort*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fPIC' - lt_prog_compiler_static='-static' - ;; - # Lahey Fortran 8.1. - lf95*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='--shared' - lt_prog_compiler_static='--static' - ;; - pgcc* | pgf77* | pgf90* | pgf95*) - # Portland Group compilers (*not* the Pentium gcc compiler, - # which looks to be a dead project) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-fpic' - lt_prog_compiler_static='-Bstatic' - ;; - ccc*) - lt_prog_compiler_wl='-Wl,' - # All Alpha code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - xl*) - # IBM XL C 8.0/Fortran 10.1 on PPC - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-qpic' - lt_prog_compiler_static='-qstaticlink' - ;; - *) - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) - # Sun C 5.9 - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='-Wl,' - ;; - *Sun\ F*) - # Sun Fortran 8.3 passes all unrecognized flags to the linker - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - lt_prog_compiler_wl='' - ;; - esac - ;; - esac - ;; - - newsos6) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - *nto* | *qnx*) - # QNX uses GNU C++, but need to define -shared option too, otherwise - # it will coredump. - lt_prog_compiler_pic='-fPIC -shared' - ;; - - osf3* | osf4* | osf5*) - lt_prog_compiler_wl='-Wl,' - # All OSF/1 code is PIC. - lt_prog_compiler_static='-non_shared' - ;; - - rdos*) - lt_prog_compiler_static='-non_shared' - ;; - - solaris*) - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - case $cc_basename in - f77* | f90* | f95*) - lt_prog_compiler_wl='-Qoption ld ';; - *) - lt_prog_compiler_wl='-Wl,';; - esac - ;; - - sunos4*) - lt_prog_compiler_wl='-Qoption ld ' - lt_prog_compiler_pic='-PIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4 | sysv4.2uw2* | sysv4.3*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - sysv4*MP*) - if test -d /usr/nec ;then - lt_prog_compiler_pic='-Kconform_pic' - lt_prog_compiler_static='-Bstatic' - fi - ;; - - sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_pic='-KPIC' - lt_prog_compiler_static='-Bstatic' - ;; - - unicos*) - lt_prog_compiler_wl='-Wl,' - lt_prog_compiler_can_build_shared=no - ;; - - uts4*) - lt_prog_compiler_pic='-pic' - lt_prog_compiler_static='-Bstatic' - ;; - - *) - lt_prog_compiler_can_build_shared=no - ;; - esac - fi - -case $host_os in - # For platforms which do not support PIC, -DPIC is meaningless: - *djgpp*) - lt_prog_compiler_pic= - ;; - *) - lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_prog_compiler_pic" >&5 -$as_echo "$lt_prog_compiler_pic" >&6; } - - - - - - -# -# Check to make sure the PIC flag actually works. -# -if test -n "$lt_prog_compiler_pic"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 -$as_echo_n "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } -if ${lt_cv_prog_compiler_pic_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_pic_works=no - ac_outfile=conftest.$ac_objext - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - lt_compiler_flag="$lt_prog_compiler_pic -DPIC" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - # The option is referenced via a variable to avoid confusing sed. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7021: $lt_compile\"" >&5) - (eval "$lt_compile" 2>conftest.err) - ac_status=$? - cat conftest.err >&5 - echo "$as_me:7025: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s "$ac_outfile"; then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings other than the usual output. - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' >conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_pic_works=yes - fi - fi - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 -$as_echo "$lt_cv_prog_compiler_pic_works" >&6; } - -if test x"$lt_cv_prog_compiler_pic_works" = xyes; then - case $lt_prog_compiler_pic in - "" | " "*) ;; - *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; - esac -else - lt_prog_compiler_pic= - lt_prog_compiler_can_build_shared=no -fi - -fi - - - - - - -# -# Check to make sure the static flag actually works. -# -wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 -$as_echo_n "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } -if ${lt_cv_prog_compiler_static_works+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_static_works=no - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS $lt_tmp_static_flag" - echo "$lt_simple_link_test_code" > conftest.$ac_ext - if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then - # The linker can only warn and ignore the option if not recognized - # So say no if there are warnings - if test -s conftest.err; then - # Append any errors to the config.log. - cat conftest.err 1>&5 - $ECHO "X$_lt_linker_boilerplate" | $Xsed -e '/^$/d' > conftest.exp - $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 - if diff conftest.exp conftest.er2 >/dev/null; then - lt_cv_prog_compiler_static_works=yes - fi - else - lt_cv_prog_compiler_static_works=yes - fi - fi - $RM -r conftest* - LDFLAGS="$save_LDFLAGS" - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 -$as_echo "$lt_cv_prog_compiler_static_works" >&6; } - -if test x"$lt_cv_prog_compiler_static_works" = xyes; then - : -else - lt_prog_compiler_static= -fi - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7126: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:7130: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if $compiler supports -c -o file.$ac_objext" >&5 -$as_echo_n "checking if $compiler supports -c -o file.$ac_objext... " >&6; } -if ${lt_cv_prog_compiler_c_o+:} false; then : - $as_echo_n "(cached) " >&6 -else - lt_cv_prog_compiler_c_o=no - $RM -r conftest 2>/dev/null - mkdir conftest - cd conftest - mkdir out - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - lt_compiler_flag="-o out/conftest2.$ac_objext" - # Insert the option either (1) after the last *FLAGS variable, or - # (2) before a word containing "conftest.", or (3) at the end. - # Note that $ac_compile itself does not contain backslashes and begins - # with a dollar sign (not a hyphen), so the echo should work correctly. - lt_compile=`echo "$ac_compile" | $SED \ - -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ - -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ - -e 's:$: $lt_compiler_flag:'` - (eval echo "\"\$as_me:7181: $lt_compile\"" >&5) - (eval "$lt_compile" 2>out/conftest.err) - ac_status=$? - cat out/conftest.err >&5 - echo "$as_me:7185: \$? = $ac_status" >&5 - if (exit $ac_status) && test -s out/conftest2.$ac_objext - then - # The compiler can only warn and ignore the option if not recognized - # So say no if there are warnings - $ECHO "X$_lt_compiler_boilerplate" | $Xsed -e '/^$/d' > out/conftest.exp - $SED '/^$/d; /^ *+/d' out/conftest.err >out/conftest.er2 - if test ! -s out/conftest.er2 || diff out/conftest.exp out/conftest.er2 >/dev/null; then - lt_cv_prog_compiler_c_o=yes - fi - fi - chmod u+w . 2>&5 - $RM conftest* - # SGI C++ compiler will create directory out/ii_files/ for - # template instantiation - test -d out/ii_files && $RM out/ii_files/* && rmdir out/ii_files - $RM out/* && rmdir out - cd .. - $RM -r conftest - $RM conftest* - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_c_o" >&5 -$as_echo "$lt_cv_prog_compiler_c_o" >&6; } - - - - -hard_links="nottested" -if test "$lt_cv_prog_compiler_c_o" = no && test "$need_locks" != no; then - # do not overwrite the value of need_locks provided by the user - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if we can lock with hard links" >&5 -$as_echo_n "checking if we can lock with hard links... " >&6; } - hard_links=yes - $RM conftest* - ln conftest.a conftest.b 2>/dev/null && hard_links=no - touch conftest.a - ln conftest.a conftest.b 2>&5 || hard_links=no - ln conftest.a conftest.b 2>/dev/null && hard_links=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $hard_links" >&5 -$as_echo "$hard_links" >&6; } - if test "$hard_links" = no; then - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&5 -$as_echo "$as_me: WARNING: \`$CC' does not support \`-c -o', so \`make -j' may be unsafe" >&2;} - need_locks=warn - fi -else - need_locks=no -fi - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether the $compiler linker ($LD) supports shared libraries" >&5 -$as_echo_n "checking whether the $compiler linker ($LD) supports shared libraries... " >&6; } - - runpath_var= - allow_undefined_flag= - always_export_symbols=no - archive_cmds= - archive_expsym_cmds= - compiler_needs_object=no - enable_shared_with_static_runtimes=no - export_dynamic_flag_spec= - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED '\''s/.* //'\'' | sort | uniq > $export_symbols' - hardcode_automatic=no - hardcode_direct=no - hardcode_direct_absolute=no - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld= - hardcode_libdir_separator= - hardcode_minus_L=no - hardcode_shlibpath_var=unsupported - inherit_rpath=no - link_all_deplibs=unknown - module_cmds= - module_expsym_cmds= - old_archive_from_new_cmds= - old_archive_from_expsyms_cmds= - thread_safe_flag_spec= - whole_archive_flag_spec= - # include_expsyms should be a list of space-separated symbols to be *always* - # included in the symbol list - include_expsyms= - # exclude_expsyms can be an extended regexp of symbols to exclude - # it will be wrapped by ` (' and `)$', so one must not match beginning or - # end of line. Example: `a|bc|.*d.*' will exclude the symbols `a' and `bc', - # as well as any symbol that contains `d'. - exclude_expsyms='_GLOBAL_OFFSET_TABLE_|_GLOBAL__F[ID]_.*' - # Although _GLOBAL_OFFSET_TABLE_ is a valid symbol C name, most a.out - # platforms (ab)use it in PIC code, but their linkers get confused if - # the symbol is explicitly referenced. Since portable code cannot - # rely on this symbol name, it's probably fine to never include it in - # preloaded symbol tables. - # Exclude shared library initialization/finalization symbols. - extract_expsyms_cmds= - - case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - if test "$GCC" != yes; then - with_gnu_ld=no - fi - ;; - interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) - with_gnu_ld=yes - ;; - openbsd*) - with_gnu_ld=no - ;; - esac - - ld_shlibs=yes - if test "$with_gnu_ld" = yes; then - # If archive_cmds runs LD, not CC, wlarc should be empty - wlarc='${wl}' - - # Set some defaults for GNU ld with shared library support. These - # are reset later if shared libraries are not supported. Putting them - # here allows them to be overridden if necessary. - runpath_var=LD_RUN_PATH - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - export_dynamic_flag_spec='${wl}--export-dynamic' - # ancient GNU ld didn't support --whole-archive et. al. - if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then - whole_archive_flag_spec="$wlarc"'--whole-archive$convenience '"$wlarc"'--no-whole-archive' - else - whole_archive_flag_spec= - fi - supports_anon_versioning=no - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 - *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... - *\ 2.11.92.0.12\ *) supports_anon_versioning=yes ;; # Mandrake 8.2 ... - *\ 2.11.*) ;; # other 2.11 versions - *) supports_anon_versioning=yes ;; - esac - - # See if GNU ld supports shared libraries. - case $host_os in - aix[3-9]*) - # On AIX/PPC, the GNU linker is very broken - if test "$host_cpu" != ia64; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: the GNU linker, at least up to release 2.9.1, is reported -*** to be unable to reliably create shared libraries on AIX. -*** Therefore, libtool is disabling shared libraries support. If you -*** really care for shared libraries, you may want to modify your PATH -*** so that a non-GNU linker is found, and then restart. - -_LT_EOF - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - beos*) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - allow_undefined_flag=unsupported - # Joseph Beckenbach says some releases of gcc - # support --undefined. This deserves some investigation. FIXME - archive_cmds='$CC -nostart $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - else - ld_shlibs=no - fi - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, - # as there is no search path for DLLs. - hardcode_libdir_flag_spec='-L$libdir' - allow_undefined_flag=unsupported - always_export_symbols=no - enable_shared_with_static_runtimes=yes - export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/'\'' | $SED -e '\''/^[AITW][ ]/s/.*[ ]//'\'' | sort | uniq > $export_symbols' - - if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - # If the export-symbols file already is a .def file (1st line - # is EXPORTS), use it as is; otherwise, prepend... - archive_expsym_cmds='if test "x`$SED 1q $export_symbols`" = xEXPORTS; then - cp $export_symbols $output_objdir/$soname.def; - else - echo EXPORTS > $output_objdir/$soname.def; - cat $export_symbols >> $output_objdir/$soname.def; - fi~ - $CC -shared $output_objdir/$soname.def $libobjs $deplibs $compiler_flags -o $output_objdir/$soname ${wl}--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' - else - ld_shlibs=no - fi - ;; - - interix[3-9]*) - hardcode_direct=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - # Hack: On Interix 3.x, we cannot compile PIC because of a broken gcc. - # Instead, shared libraries are loaded at an image base (0x10000000 by - # default) and relocated if they conflict, which is a slow very memory - # consuming and fragmenting process. To avoid this, we pick a random, - # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link - # time. Moving up from 0x10000000 also allows more sbrk(2) space. - archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s,^,_," $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags ${wl}-h,$soname ${wl}--retain-symbols-file,$output_objdir/$soname.expsym ${wl}--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - ;; - - gnu* | linux* | tpf* | k*bsd*-gnu) - tmp_diet=no - if test "$host_os" = linux-dietlibc; then - case $cc_basename in - diet\ *) tmp_diet=yes;; # linux-dietlibc with static linking (!diet-dyn) - esac - fi - if $LD --help 2>&1 | $EGREP ': supported targets:.* elf' > /dev/null \ - && test "$tmp_diet" = no - then - tmp_addflag= - tmp_sharedflag='-shared' - case $cc_basename,$host_cpu in - pgcc*) # Portland Group C compiler - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag' - ;; - pgf77* | pgf90* | pgf95*) # Portland Group f77 and f90 compilers - whole_archive_flag_spec='${wl}--whole-archive`for conv in $convenience\"\"; do test -n \"$conv\" && new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - tmp_addflag=' $pic_flag -Mnomain' ;; - ecc*,ia64* | icc*,ia64*) # Intel C compiler on ia64 - tmp_addflag=' -i_dynamic' ;; - efc*,ia64* | ifort*,ia64*) # Intel Fortran compiler on ia64 - tmp_addflag=' -i_dynamic -nofor_main' ;; - ifc* | ifort*) # Intel Fortran compiler - tmp_addflag=' -nofor_main' ;; - lf95*) # Lahey Fortran 8.1 - whole_archive_flag_spec= - tmp_sharedflag='--shared' ;; - xl[cC]*) # IBM XL C 8.0 on PPC (deal with xlf below) - tmp_sharedflag='-qmkshrobj' - tmp_addflag= ;; - esac - case `$CC -V 2>&1 | sed 5q` in - *Sun\ C*) # Sun C 5.9 - whole_archive_flag_spec='${wl}--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; $ECHO \"$new_convenience\"` ${wl}--no-whole-archive' - compiler_needs_object=yes - tmp_sharedflag='-G' ;; - *Sun\ F*) # Sun Fortran 8.3 - tmp_sharedflag='-G' ;; - esac - archive_cmds='$CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-version-script ${wl}$output_objdir/$libname.ver -o $lib' - fi - - case $cc_basename in - xlf*) - # IBM XL Fortran 10.1 on PPC cannot create shared libs itself - whole_archive_flag_spec='--whole-archive$convenience --no-whole-archive' - hardcode_libdir_flag_spec= - hardcode_libdir_flag_spec_ld='-rpath $libdir' - archive_cmds='$LD -shared $libobjs $deplibs $compiler_flags -soname $soname -o $lib' - if test "x$supports_anon_versioning" = xyes; then - archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ - echo "local: *; };" >> $output_objdir/$libname.ver~ - $LD -shared $libobjs $deplibs $compiler_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' - fi - ;; - esac - else - ld_shlibs=no - fi - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' - wlarc= - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - fi - ;; - - solaris*) - if $LD -v 2>&1 | $GREP 'BFD 2\.8' > /dev/null; then - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: The releases 2.8.* of the GNU linker cannot reliably -*** create shared libraries on Solaris systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.9.1 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - elif $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - - sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX*) - case `$LD -v 2>&1` in - *\ [01].* | *\ 2.[0-9].* | *\ 2.1[0-5].*) - ld_shlibs=no - cat <<_LT_EOF 1>&2 - -*** Warning: Releases of the GNU linker prior to 2.16.91.0.3 can not -*** reliably create shared libraries on SCO systems. Therefore, libtool -*** is disabling shared libraries support. We urge you to upgrade GNU -*** binutils to release 2.16.91.0.3 or newer. Another option is to modify -*** your PATH or compiler configuration so that the native linker is -*** used, and then restart. - -_LT_EOF - ;; - *) - # For security reasons, it is highly recommended that you always - # use absolute paths for naming shared libraries, and exclude the - # DT_RUNPATH tag from executables and libraries. But doing so - # requires that you compile everything twice, which is a pain. - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - ;; - - sunos4*) - archive_cmds='$LD -assert pure-text -Bshareable -o $lib $libobjs $deplibs $linker_flags' - wlarc= - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - *) - if $LD --help 2>&1 | $GREP ': supported targets:.* elf' > /dev/null; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname ${wl}-retain-symbols-file $wl$export_symbols -o $lib' - else - ld_shlibs=no - fi - ;; - esac - - if test "$ld_shlibs" = no; then - runpath_var= - hardcode_libdir_flag_spec= - export_dynamic_flag_spec= - whole_archive_flag_spec= - fi - else - # PORTME fill in a description of your system's linker (not GNU ld) - case $host_os in - aix3*) - allow_undefined_flag=unsupported - always_export_symbols=yes - archive_expsym_cmds='$LD -o $output_objdir/$soname $libobjs $deplibs $linker_flags -bE:$export_symbols -T512 -H512 -bM:SRE~$AR $AR_FLAGS $lib $output_objdir/$soname' - # Note: this linker hardcodes the directories in LIBPATH if there - # are no directories specified by -L. - hardcode_minus_L=yes - if test "$GCC" = yes && test -z "$lt_prog_compiler_static"; then - # Neither direct hardcoding nor static linking is supported with a - # broken collect2. - hardcode_direct=unsupported - fi - ;; - - aix[4-9]*) - if test "$host_cpu" = ia64; then - # On IA64, the linker does run time linking by default, so we don't - # have to do anything special. - aix_use_runtimelinking=no - exp_sym_flag='-Bexport' - no_entry_flag="" - else - # If we're using GNU nm, then we don't want the "-C" option. - # -C means demangle to AIX nm, but means don't demangle with GNU nm - if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then - export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - else - export_symbols_cmds='$NM -BCpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B")) && (substr(\$ 3,1,1) != ".")) { print \$ 3 } }'\'' | sort -u > $export_symbols' - fi - aix_use_runtimelinking=no - - # Test if we are trying to use run time linking or normal - # AIX style linking. If -brtl is somewhere in LDFLAGS, we - # need to do runtime linking. - case $host_os in aix4.[23]|aix4.[23].*|aix[5-9]*) - for ld_flag in $LDFLAGS; do - if (test $ld_flag = "-brtl" || test $ld_flag = "-Wl,-brtl"); then - aix_use_runtimelinking=yes - break - fi - done - ;; - esac - - exp_sym_flag='-bexport' - no_entry_flag='-bnoentry' - fi - - # When large executables or shared objects are built, AIX ld can - # have problems creating the table of contents. If linking a library - # or program results in "error TOC overflow" add -mminimal-toc to - # CXXFLAGS/CFLAGS for g++/gcc. In the cases where that is not - # enough to fix the problem, add -Wl,-bbigtoc to LDFLAGS. - - archive_cmds='' - hardcode_direct=yes - hardcode_direct_absolute=yes - hardcode_libdir_separator=':' - link_all_deplibs=yes - file_list_spec='${wl}-f,' - - if test "$GCC" = yes; then - case $host_os in aix4.[012]|aix4.[012].*) - # We only want to do this on AIX 4.2 and lower, the check - # below for broken collect2 doesn't work under 4.3+ - collect2name=`${CC} -print-prog-name=collect2` - if test -f "$collect2name" && - strings "$collect2name" | $GREP resolve_lib_name >/dev/null - then - # We have reworked collect2 - : - else - # We have old collect2 - hardcode_direct=unsupported - # It fails to find uninstalled libraries when the uninstalled - # path is not listed in the libpath. Setting hardcode_minus_L - # to unsupported forces relinking - hardcode_minus_L=yes - hardcode_libdir_flag_spec='-L$libdir' - hardcode_libdir_separator= - fi - ;; - esac - shared_flag='-shared' - if test "$aix_use_runtimelinking" = yes; then - shared_flag="$shared_flag "'${wl}-G' - fi - else - # not using gcc - if test "$host_cpu" = ia64; then - # VisualAge C++, Version 5.5 for AIX 5L for IA-64, Beta 3 Release - # chokes on -Wl,-G. The following line is correct: - shared_flag='-G' - else - if test "$aix_use_runtimelinking" = yes; then - shared_flag='${wl}-G' - else - shared_flag='${wl}-bM:SRE' - fi - fi - fi - - export_dynamic_flag_spec='${wl}-bexpall' - # It seems that -bexpall does not export symbols beginning with - # underscore (_), so it is better to generate a list of symbols to export. - always_export_symbols=yes - if test "$aix_use_runtimelinking" = yes; then - # Warning - without using the other runtime loading flags (-brtl), - # -berok will link without error, but may produce a broken library. - allow_undefined_flag='-berok' - # Determine the default libpath from the value encoded in an - # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - archive_expsym_cmds='$CC -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags `if test "x${allow_undefined_flag}" != "x"; then $ECHO "X${wl}${allow_undefined_flag}" | $Xsed; else :; fi` '"\${wl}$exp_sym_flag:\$export_symbols $shared_flag" - else - if test "$host_cpu" = ia64; then - hardcode_libdir_flag_spec='${wl}-R $libdir:/usr/lib:/lib' - allow_undefined_flag="-z nodefs" - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs '"\${wl}$no_entry_flag"' $compiler_flags ${wl}${allow_undefined_flag} '"\${wl}$exp_sym_flag:\$export_symbols" - else - # Determine the default libpath from the value encoded in an - # empty executable. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - -lt_aix_libpath_sed=' - /Import File Strings/,/^$/ { - /^0/ { - s/^0 *\(.*\)$/\1/ - p - } - }' -aix_libpath=`dump -H conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -# Check for a 64-bit object if we didn't find anything. -if test -z "$aix_libpath"; then - aix_libpath=`dump -HX64 conftest$ac_exeext 2>/dev/null | $SED -n -e "$lt_aix_libpath_sed"` -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -if test -z "$aix_libpath"; then aix_libpath="/usr/lib:/lib"; fi - - hardcode_libdir_flag_spec='${wl}-blibpath:$libdir:'"$aix_libpath" - # Warning - without using the other run time loading flags, - # -berok will link without error, but may produce a broken library. - no_undefined_flag=' ${wl}-bernotok' - allow_undefined_flag=' ${wl}-berok' - # Exported symbols can be pulled into shared objects from archives - whole_archive_flag_spec='$convenience' - archive_cmds_need_lc=yes - # This is similar to how AIX traditionally builds its shared libraries. - archive_expsym_cmds="\$CC $shared_flag"' -o $output_objdir/$soname $libobjs $deplibs ${wl}-bnoentry $compiler_flags ${wl}-bE:$export_symbols${allow_undefined_flag}~$AR $AR_FLAGS $output_objdir/$libname$release.a $output_objdir/$soname' - fi - fi - ;; - - amigaos*) - case $host_cpu in - powerpc) - # see comment about AmigaOS4 .so support - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname $wl$soname -o $lib' - archive_expsym_cmds='' - ;; - m68k) - archive_cmds='$RM $output_objdir/a2ixlibrary.data~$ECHO "#define NAME $libname" > $output_objdir/a2ixlibrary.data~$ECHO "#define LIBRARY_ID 1" >> $output_objdir/a2ixlibrary.data~$ECHO "#define VERSION $major" >> $output_objdir/a2ixlibrary.data~$ECHO "#define REVISION $revision" >> $output_objdir/a2ixlibrary.data~$AR $AR_FLAGS $lib $libobjs~$RANLIB $lib~(cd $output_objdir && a2ixlibrary -32)' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - ;; - esac - ;; - - bsdi[45]*) - export_dynamic_flag_spec=-rdynamic - ;; - - cygwin* | mingw* | pw32* | cegcc*) - # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. - # hardcode_libdir_flag_spec is actually meaningless, as there is - # no search path for DLLs. - hardcode_libdir_flag_spec=' ' - allow_undefined_flag=unsupported - # Tell ltmain to make .lib files, not .a files. - libext=lib - # Tell ltmain to make .dll files, not .so files. - shrext_cmds=".dll" - # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $lib $libobjs $compiler_flags `$ECHO "X$deplibs" | $Xsed -e '\''s/ -lc$//'\''` -link -dll~linknames=' - # The linker will automatically build a .lib file if we build a DLL. - old_archive_from_new_cmds='true' - # FIXME: Should let the user specify the lib program. - old_archive_cmds='lib -OUT:$oldlib$oldobjs$old_deplibs' - fix_srcfile_path='`cygpath -w "$srcfile"`' - enable_shared_with_static_runtimes=yes - ;; - - darwin* | rhapsody*) - - - archive_cmds_need_lc=no - hardcode_direct=no - hardcode_automatic=yes - hardcode_shlibpath_var=unsupported - whole_archive_flag_spec='' - link_all_deplibs=yes - allow_undefined_flag="$_lt_dar_allow_undefined" - case $cc_basename in - ifort*) _lt_dar_can_shared=yes ;; - *) _lt_dar_can_shared=$GCC ;; - esac - if test "$_lt_dar_can_shared" = "yes"; then - output_verbose_link_cmd=echo - archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod${_lt_dsymutil}" - module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dsymutil}" - archive_expsym_cmds="sed 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring ${_lt_dar_single_mod}${_lt_dar_export_syms}${_lt_dsymutil}" - module_expsym_cmds="sed -e 's,^,_,' < \$export_symbols > \$output_objdir/\${libname}-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags${_lt_dar_export_syms}${_lt_dsymutil}" - - else - ld_shlibs=no - fi - - ;; - - dgux*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - freebsd1*) - ld_shlibs=no - ;; - - # FreeBSD 2.2.[012] allows us to include c++rt0.o to get C++ constructor - # support. Future versions do this automatically, but an explicit c++rt0.o - # does not break anything, and helps significantly (at the cost of a little - # extra space). - freebsd2.2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags /usr/lib/c++rt0.o' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - # Unfortunately, older versions of FreeBSD 2 do not have this feature. - freebsd2*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) - archive_cmds='$CC -shared -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - hpux9*) - if test "$GCC" = yes; then - archive_cmds='$RM $output_objdir/$soname~$CC -shared -fPIC ${wl}+b ${wl}$install_libdir -o $output_objdir/$soname $libobjs $deplibs $compiler_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - else - archive_cmds='$RM $output_objdir/$soname~$LD -b +b $install_libdir -o $output_objdir/$soname $libobjs $deplibs $linker_flags~test $output_objdir/$soname = $lib || mv $output_objdir/$soname $lib' - fi - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - export_dynamic_flag_spec='${wl}-E' - ;; - - hpux10*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -b +h $soname +b $install_libdir -o $lib $libobjs $deplibs $linker_flags' - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_flag_spec_ld='+b $libdir' - hardcode_libdir_separator=: - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - fi - ;; - - hpux11*) - if test "$GCC" = yes -a "$with_gnu_ld" = no; then - case $host_cpu in - hppa*64*) - archive_cmds='$CC -shared ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -shared -fPIC ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - else - case $host_cpu in - hppa*64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - ;; - ia64*) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+nodefaultrpath -o $lib $libobjs $deplibs $compiler_flags' - ;; - *) - archive_cmds='$CC -b ${wl}+h ${wl}$soname ${wl}+b ${wl}$install_libdir -o $lib $libobjs $deplibs $compiler_flags' - ;; - esac - fi - if test "$with_gnu_ld" = no; then - hardcode_libdir_flag_spec='${wl}+b ${wl}$libdir' - hardcode_libdir_separator=: - - case $host_cpu in - hppa*64*|ia64*) - hardcode_direct=no - hardcode_shlibpath_var=no - ;; - *) - hardcode_direct=yes - hardcode_direct_absolute=yes - export_dynamic_flag_spec='${wl}-E' - - # hardcode_minus_L: Not really in the search PATH, - # but as the default location of the library. - hardcode_minus_L=yes - ;; - esac - fi - ;; - - irix5* | irix6* | nonstopux*) - if test "$GCC" = yes; then - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - # Try to use the -exported_symbol ld option, if it does not - # work, assume that -exports_file does not work either and - # implicitly export all symbols. - save_LDFLAGS="$LDFLAGS" - LDFLAGS="$LDFLAGS -shared ${wl}-exported_symbol ${wl}foo ${wl}-update_registry ${wl}/dev/null" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -int foo(void) {} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations ${wl}-exports_file ${wl}$export_symbols -o $lib' - -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS="$save_LDFLAGS" - else - archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='$CC -shared $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -exports_file $export_symbols -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - inherit_rpath=yes - link_all_deplibs=yes - ;; - - netbsd*) - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out - else - archive_cmds='$LD -shared -o $lib $libobjs $deplibs $linker_flags' # ELF - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_direct=yes - hardcode_shlibpath_var=no - ;; - - newsos6) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - hardcode_shlibpath_var=no - ;; - - *nto* | *qnx*) - ;; - - openbsd*) - if test -f /usr/libexec/ld.so; then - hardcode_direct=yes - hardcode_shlibpath_var=no - hardcode_direct_absolute=yes - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags ${wl}-retain-symbols-file,$export_symbols' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - export_dynamic_flag_spec='${wl}-E' - else - case $host_os in - openbsd[01].* | openbsd2.[0-7] | openbsd2.[0-7].*) - archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-R$libdir' - ;; - *) - archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' - hardcode_libdir_flag_spec='${wl}-rpath,$libdir' - ;; - esac - fi - else - ld_shlibs=no - fi - ;; - - os2*) - hardcode_libdir_flag_spec='-L$libdir' - hardcode_minus_L=yes - allow_undefined_flag=unsupported - archive_cmds='$ECHO "LIBRARY $libname INITINSTANCE" > $output_objdir/$libname.def~$ECHO "DESCRIPTION \"$libname\"" >> $output_objdir/$libname.def~$ECHO DATA >> $output_objdir/$libname.def~$ECHO " SINGLE NONSHARED" >> $output_objdir/$libname.def~$ECHO EXPORTS >> $output_objdir/$libname.def~emxexp $libobjs >> $output_objdir/$libname.def~$CC -Zdll -Zcrtdll -o $lib $libobjs $deplibs $compiler_flags $output_objdir/$libname.def' - old_archive_from_new_cmds='emximp -o $output_objdir/$libname.a $output_objdir/$libname.def' - ;; - - osf3*) - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - fi - archive_cmds_need_lc='no' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - hardcode_libdir_separator=: - ;; - - osf4* | osf5*) # as osf3* with the addition of -msym flag - if test "$GCC" = yes; then - allow_undefined_flag=' ${wl}-expect_unresolved ${wl}\*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags ${wl}-msym ${wl}-soname ${wl}$soname `test -n "$verstring" && $ECHO "X${wl}-set_version ${wl}$verstring" | $Xsed` ${wl}-update_registry ${wl}${output_objdir}/so_locations -o $lib' - hardcode_libdir_flag_spec='${wl}-rpath ${wl}$libdir' - else - allow_undefined_flag=' -expect_unresolved \*' - archive_cmds='$CC -shared${allow_undefined_flag} $libobjs $deplibs $compiler_flags -msym -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib' - archive_expsym_cmds='for i in `cat $export_symbols`; do printf "%s %s\\n" -exported_symbol "\$i" >> $lib.exp; done; printf "%s\\n" "-hidden">> $lib.exp~ - $CC -shared${allow_undefined_flag} ${wl}-input ${wl}$lib.exp $compiler_flags $libobjs $deplibs -soname $soname `test -n "$verstring" && $ECHO "X-set_version $verstring" | $Xsed` -update_registry ${output_objdir}/so_locations -o $lib~$RM $lib.exp' - - # Both c and cxx compiler support -rpath directly - hardcode_libdir_flag_spec='-rpath $libdir' - fi - archive_cmds_need_lc='no' - hardcode_libdir_separator=: - ;; - - solaris*) - no_undefined_flag=' -z defs' - if test "$GCC" = yes; then - wlarc='${wl}' - archive_cmds='$CC -shared ${wl}-z ${wl}text ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -shared ${wl}-z ${wl}text ${wl}-M ${wl}$lib.exp ${wl}-h ${wl}$soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - else - case `$CC -V 2>&1` in - *"Compilers 5.0"*) - wlarc='' - archive_cmds='$LD -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $linker_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $LD -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $linker_flags~$RM $lib.exp' - ;; - *) - wlarc='${wl}' - archive_cmds='$CC -G${allow_undefined_flag} -h $soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='echo "{ global:" > $lib.exp~cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $lib.exp~echo "local: *; };" >> $lib.exp~ - $CC -G${allow_undefined_flag} -M $lib.exp -h $soname -o $lib $libobjs $deplibs $compiler_flags~$RM $lib.exp' - ;; - esac - fi - hardcode_libdir_flag_spec='-R$libdir' - hardcode_shlibpath_var=no - case $host_os in - solaris2.[0-5] | solaris2.[0-5].*) ;; - *) - # The compiler driver will combine and reorder linker options, - # but understands `-z linker_flag'. GCC discards it without `$wl', - # but is careful enough not to reorder. - # Supported since Solaris 2.6 (maybe 2.5.1?) - if test "$GCC" = yes; then - whole_archive_flag_spec='${wl}-z ${wl}allextract$convenience ${wl}-z ${wl}defaultextract' - else - whole_archive_flag_spec='-z allextract$convenience -z defaultextract' - fi - ;; - esac - link_all_deplibs=yes - ;; - - sunos4*) - if test "x$host_vendor" = xsequent; then - # Use $CC to link under sequent, because it throws in some extra .o - # files that make .init and .fini sections work. - archive_cmds='$CC -G ${wl}-h $soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$LD -assert pure-text -Bstatic -o $lib $libobjs $deplibs $linker_flags' - fi - hardcode_libdir_flag_spec='-L$libdir' - hardcode_direct=yes - hardcode_minus_L=yes - hardcode_shlibpath_var=no - ;; - - sysv4) - case $host_vendor in - sni) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=yes # is this really true??? - ;; - siemens) - ## LD is ld it makes a PLAMLIB - ## CC just makes a GrossModule. - archive_cmds='$LD -G -o $lib $libobjs $deplibs $linker_flags' - reload_cmds='$CC -r -o $output$reload_objs' - hardcode_direct=no - ;; - motorola) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_direct=no #Motorola manual says yes, but my tests say they lie - ;; - esac - runpath_var='LD_RUN_PATH' - hardcode_shlibpath_var=no - ;; - - sysv4.3*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - export_dynamic_flag_spec='-Bexport' - ;; - - sysv4*MP*) - if test -d /usr/nec; then - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_shlibpath_var=no - runpath_var=LD_RUN_PATH - hardcode_runpath_var=yes - ld_shlibs=yes - fi - ;; - - sysv4*uw2* | sysv5OpenUNIX* | sysv5UnixWare7.[01].[10]* | unixware7* | sco3.2v5.0.[024]*) - no_undefined_flag='${wl}-z,text' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - sysv5* | sco3.2v5* | sco5v6*) - # Note: We can NOT use -z defs as we might desire, because we do not - # link with -lc, and that would cause any symbols used from libc to - # always be unresolved, which means just about no library would - # ever link correctly. If we're not using GNU ld we use -z text - # though, which does catch some bad symbols but isn't as heavy-handed - # as -z defs. - no_undefined_flag='${wl}-z,text' - allow_undefined_flag='${wl}-z,nodefs' - archive_cmds_need_lc=no - hardcode_shlibpath_var=no - hardcode_libdir_flag_spec='${wl}-R,$libdir' - hardcode_libdir_separator=':' - link_all_deplibs=yes - export_dynamic_flag_spec='${wl}-Bexport' - runpath_var='LD_RUN_PATH' - - if test "$GCC" = yes; then - archive_cmds='$CC -shared ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -shared ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - else - archive_cmds='$CC -G ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - archive_expsym_cmds='$CC -G ${wl}-Bexport:$export_symbols ${wl}-h,$soname -o $lib $libobjs $deplibs $compiler_flags' - fi - ;; - - uts4*) - archive_cmds='$LD -G -h $soname -o $lib $libobjs $deplibs $linker_flags' - hardcode_libdir_flag_spec='-L$libdir' - hardcode_shlibpath_var=no - ;; - - *) - ld_shlibs=no - ;; - esac - - if test x$host_vendor = xsni; then - case $host in - sysv4 | sysv4.2uw2* | sysv4.3* | sysv5*) - export_dynamic_flag_spec='${wl}-Blargedynsym' - ;; - esac - fi - fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ld_shlibs" >&5 -$as_echo "$ld_shlibs" >&6; } -test "$ld_shlibs" = no && can_build_shared=no - -with_gnu_ld=$with_gnu_ld - - - - - - - - - - - - - - - -# -# Do we need to explicitly link libc? -# -case "x$archive_cmds_need_lc" in -x|xyes) - # Assume -lc should be added - archive_cmds_need_lc=yes - - if test "$enable_shared" = yes && test "$GCC" = yes; then - case $archive_cmds in - *'~'*) - # FIXME: we may have to deal with multi-command sequences. - ;; - '$CC '*) - # Test whether the compiler implicitly links with -lc since on some - # systems, -lgcc has to come before -lc. If gcc already passes -lc - # to ld, don't add -lc before -lgcc. - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether -lc should be explicitly linked in" >&5 -$as_echo_n "checking whether -lc should be explicitly linked in... " >&6; } - $RM conftest* - echo "$lt_simple_compile_test_code" > conftest.$ac_ext - - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 - (eval $ac_compile) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } 2>conftest.err; then - soname=conftest - lib=conftest - libobjs=conftest.$ac_objext - deplibs= - wl=$lt_prog_compiler_wl - pic_flag=$lt_prog_compiler_pic - compiler_flags=-v - linker_flags=-v - verstring= - output_objdir=. - libname=conftest - lt_save_allow_undefined_flag=$allow_undefined_flag - allow_undefined_flag= - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1\""; } >&5 - (eval $archive_cmds 2\>\&1 \| $GREP \" -lc \" \>/dev/null 2\>\&1) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } - then - archive_cmds_need_lc=no - else - archive_cmds_need_lc=yes - fi - allow_undefined_flag=$lt_save_allow_undefined_flag - else - cat conftest.err 1>&5 - fi - $RM conftest* - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $archive_cmds_need_lc" >&5 -$as_echo "$archive_cmds_need_lc" >&6; } - ;; - esac - fi - ;; -esac - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking dynamic linker characteristics" >&5 -$as_echo_n "checking dynamic linker characteristics... " >&6; } - -if test "$GCC" = yes; then - case $host_os in - darwin*) lt_awk_arg="/^libraries:/,/LR/" ;; - *) lt_awk_arg="/^libraries:/" ;; - esac - lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$lt_search_path_spec" | $GREP ';' >/dev/null ; then - # if the path contains ";" then we assume it to be the separator - # otherwise default to the standard path separator (i.e. ":") - it is - # assumed that no part of a normal pathname contains ";" but that should - # okay in the real world where ";" in dirpaths is itself problematic. - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e 's/;/ /g'` - else - lt_search_path_spec=`$ECHO "$lt_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - # Ok, now we have the path, separated by spaces, we can step through it - # and add multilib dir if necessary. - lt_tmp_lt_search_path_spec= - lt_multi_os_dir=`$CC $CPPFLAGS $CFLAGS $LDFLAGS -print-multi-os-directory 2>/dev/null` - for lt_sys_path in $lt_search_path_spec; do - if test -d "$lt_sys_path/$lt_multi_os_dir"; then - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path/$lt_multi_os_dir" - else - test -d "$lt_sys_path" && \ - lt_tmp_lt_search_path_spec="$lt_tmp_lt_search_path_spec $lt_sys_path" - fi - done - lt_search_path_spec=`$ECHO $lt_tmp_lt_search_path_spec | awk ' -BEGIN {RS=" "; FS="/|\n";} { - lt_foo=""; - lt_count=0; - for (lt_i = NF; lt_i > 0; lt_i--) { - if ($lt_i != "" && $lt_i != ".") { - if ($lt_i == "..") { - lt_count++; - } else { - if (lt_count == 0) { - lt_foo="/" $lt_i lt_foo; - } else { - lt_count--; - } - } - } - } - if (lt_foo != "") { lt_freq[lt_foo]++; } - if (lt_freq[lt_foo] == 1) { print lt_foo; } -}'` - sys_lib_search_path_spec=`$ECHO $lt_search_path_spec` -else - sys_lib_search_path_spec="/lib /usr/lib /usr/local/lib" -fi -library_names_spec= -libname_spec='lib$name' -soname_spec= -shrext_cmds=".so" -postinstall_cmds= -postuninstall_cmds= -finish_cmds= -finish_eval= -shlibpath_var= -shlibpath_overrides_runpath=unknown -version_type=none -dynamic_linker="$host_os ld.so" -sys_lib_dlsearch_path_spec="/lib /usr/lib" -need_lib_prefix=unknown -hardcode_into_libs=no - -# when you set need_version to no, make sure it does not cause -set_version -# flags to be left without arguments -need_version=unknown - -case $host_os in -aix3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname.a' - shlibpath_var=LIBPATH - - # AIX 3 has no versioning support, so we append a major version to the name. - soname_spec='${libname}${release}${shared_ext}$major' - ;; - -aix[4-9]*) - version_type=linux - need_lib_prefix=no - need_version=no - hardcode_into_libs=yes - if test "$host_cpu" = ia64; then - # AIX 5 supports IA64 - library_names_spec='${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext}$versuffix $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - else - # With GCC up to 2.95.x, collect2 would create an import file - # for dependence libraries. The import file would start with - # the line `#! .'. This would cause the generated library to - # depend on `.', always an invalid library. This was fixed in - # development snapshots of GCC prior to 3.0. - case $host_os in - aix4 | aix4.[01] | aix4.[01].*) - if { echo '#if __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 97)' - echo ' yes ' - echo '#endif'; } | ${CC} -E - | $GREP yes > /dev/null; then - : - else - can_build_shared=no - fi - ;; - esac - # AIX (on Power*) has no versioning support, so currently we can not hardcode correct - # soname into executable. Probably we can add versioning support to - # collect2, so additional links can be useful in future. - if test "$aix_use_runtimelinking" = yes; then - # If using run time linking (on AIX 4.2 or later) use lib.so - # instead of lib.a to let people know that these are not - # typical AIX shared libraries. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - else - # We preserve .a as extension for shared libraries through AIX4.2 - # and later when we are not doing run time linking. - library_names_spec='${libname}${release}.a $libname.a' - soname_spec='${libname}${release}${shared_ext}$major' - fi - shlibpath_var=LIBPATH - fi - ;; - -amigaos*) - case $host_cpu in - powerpc) - # Since July 2007 AmigaOS4 officially supports .so libraries. - # When compiling the executable, add -use-dynld -Lsobjs: to the compileline. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - ;; - m68k) - library_names_spec='$libname.ixlibrary $libname.a' - # Create ${libname}_ixlibrary.a entries in /sys/libs. - finish_eval='for lib in `ls $libdir/*.ixlibrary 2>/dev/null`; do libname=`$ECHO "X$lib" | $Xsed -e '\''s%^.*/\([^/]*\)\.ixlibrary$%\1%'\''`; test $RM /sys/libs/${libname}_ixlibrary.a; $show "cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a"; cd /sys/libs && $LN_S $lib ${libname}_ixlibrary.a || exit 1; done' - ;; - esac - ;; - -beos*) - library_names_spec='${libname}${shared_ext}' - dynamic_linker="$host_os ld.so" - shlibpath_var=LIBRARY_PATH - ;; - -bsdi[45]*) - version_type=linux - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/shlib /usr/lib /usr/X11/lib /usr/contrib/lib /lib /usr/local/lib" - sys_lib_dlsearch_path_spec="/shlib /usr/lib /usr/local/lib" - # the default ld.so.conf also contains /usr/contrib/lib and - # /usr/X11R6/lib (/usr/X11 is a link to /usr/X11R6), but let us allow - # libtool to hard-code these into programs - ;; - -cygwin* | mingw* | pw32* | cegcc*) - version_type=windows - shrext_cmds=".dll" - need_version=no - need_lib_prefix=no - - case $GCC,$host_os in - yes,cygwin* | yes,mingw* | yes,pw32* | yes,cegcc*) - library_names_spec='$libname.dll.a' - # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \${file}`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\${base_file}'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' - postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ - dlpath=$dir/\$dldll~ - $RM \$dlpath' - shlibpath_overrides_runpath=yes - - case $host_os in - cygwin*) - # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo ${libname} | sed -e 's/^lib/cyg/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec="/usr/lib /lib/w32api /lib /usr/local/lib" - ;; - mingw* | cegcc*) - # MinGW DLLs use traditional 'lib' prefix - soname_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - sys_lib_search_path_spec=`$CC -print-search-dirs | $GREP "^libraries:" | $SED -e "s/^libraries://" -e "s,=/,/,g"` - if $ECHO "$sys_lib_search_path_spec" | $GREP ';[c-zC-Z]:/' >/dev/null; then - # It is most probably a Windows format PATH printed by - # mingw gcc, but we are running on Cygwin. Gcc prints its search - # path with ; separators, and with drive letters. We can handle the - # drive letters (cygwin fileutils understands them), so leave them, - # especially as we might pass files found there to a mingw objdump, - # which wouldn't understand a cygwinified path. Ahh. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's/;/ /g'` - else - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e "s/$PATH_SEPARATOR/ /g"` - fi - ;; - pw32*) - # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo ${libname} | sed -e 's/^lib/pw/'``echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext}' - ;; - esac - ;; - - *) - library_names_spec='${libname}`echo ${release} | $SED -e 's/[.]/-/g'`${versuffix}${shared_ext} $libname.lib' - ;; - esac - dynamic_linker='Win32 ld.exe' - # FIXME: first we should search . and the directory the executable is in - shlibpath_var=PATH - ;; - -darwin* | rhapsody*) - dynamic_linker="$host_os dyld" - version_type=darwin - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${major}$shared_ext ${libname}$shared_ext' - soname_spec='${libname}${release}${major}$shared_ext' - shlibpath_overrides_runpath=yes - shlibpath_var=DYLD_LIBRARY_PATH - shrext_cmds='`test .$module = .yes && echo .so || echo .dylib`' - - sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/local/lib" - sys_lib_dlsearch_path_spec='/usr/local/lib /lib /usr/lib' - ;; - -dgux*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname$shared_ext' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -freebsd1*) - dynamic_linker=no - ;; - -freebsd* | dragonfly*) - # DragonFly does not have aout. When/if they implement a new - # versioning mechanism, adjust this. - if test -x /usr/bin/objformat; then - objformat=`/usr/bin/objformat` - else - case $host_os in - freebsd[123]*) objformat=aout ;; - *) objformat=elf ;; - esac - fi - # Handle Gentoo/FreeBSD as it was Linux - case $host_vendor in - gentoo) - version_type=linux ;; - *) - version_type=freebsd-$objformat ;; - esac - - case $version_type in - freebsd-elf*) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - need_version=no - need_lib_prefix=no - ;; - freebsd-*) - library_names_spec='${libname}${release}${shared_ext}$versuffix $libname${shared_ext}$versuffix' - need_version=yes - ;; - linux) - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - need_lib_prefix=no - need_version=no - ;; - esac - shlibpath_var=LD_LIBRARY_PATH - case $host_os in - freebsd2*) - shlibpath_overrides_runpath=yes - ;; - freebsd3.[01]* | freebsdelf3.[01]*) - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - freebsd3.[2-9]* | freebsdelf3.[2-9]* | \ - freebsd4.[0-5] | freebsdelf4.[0-5] | freebsd4.1.1 | freebsdelf4.1.1) - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - *) # from 4.6 on, and DragonFly - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - esac - ;; - -gnu*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}${major} ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - hardcode_into_libs=yes - ;; - -hpux9* | hpux10* | hpux11*) - # Give a soname corresponding to the major version so that dld.sl refuses to - # link against other versions. - version_type=sunos - need_lib_prefix=no - need_version=no - case $host_cpu in - ia64*) - shrext_cmds='.so' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.so" - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - if test "X$HPUX_IA64_MODE" = X32; then - sys_lib_search_path_spec="/usr/lib/hpux32 /usr/local/lib/hpux32 /usr/local/lib" - else - sys_lib_search_path_spec="/usr/lib/hpux64 /usr/local/lib/hpux64" - fi - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - hppa*64*) - shrext_cmds='.sl' - hardcode_into_libs=yes - dynamic_linker="$host_os dld.sl" - shlibpath_var=LD_LIBRARY_PATH # How should we handle SHLIB_PATH - shlibpath_overrides_runpath=yes # Unless +noenvvar is specified. - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - sys_lib_search_path_spec="/usr/lib/pa20_64 /usr/ccs/lib/pa20_64" - sys_lib_dlsearch_path_spec=$sys_lib_search_path_spec - ;; - *) - shrext_cmds='.sl' - dynamic_linker="$host_os dld.sl" - shlibpath_var=SHLIB_PATH - shlibpath_overrides_runpath=no # +s is required to enable SHLIB_PATH - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - ;; - esac - # HP-UX runs *really* slowly unless shared libraries are mode 555. - postinstall_cmds='chmod 555 $lib' - ;; - -interix[3-9]*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='Interix 3.x ld.so.1 (PE, like ELF)' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -irix5* | irix6* | nonstopux*) - case $host_os in - nonstopux*) version_type=nonstopux ;; - *) - if test "$lt_cv_prog_gnu_ld" = yes; then - version_type=linux - else - version_type=irix - fi ;; - esac - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${release}${shared_ext} $libname${shared_ext}' - case $host_os in - irix5* | nonstopux*) - libsuff= shlibsuff= - ;; - *) - case $LD in # libtool.m4 will add one of these switches to LD - *-32|*"-32 "|*-melf32bsmip|*"-melf32bsmip ") - libsuff= shlibsuff= libmagic=32-bit;; - *-n32|*"-n32 "|*-melf32bmipn32|*"-melf32bmipn32 ") - libsuff=32 shlibsuff=N32 libmagic=N32;; - *-64|*"-64 "|*-melf64bmip|*"-melf64bmip ") - libsuff=64 shlibsuff=64 libmagic=64-bit;; - *) libsuff= shlibsuff= libmagic=never-match;; - esac - ;; - esac - shlibpath_var=LD_LIBRARY${shlibsuff}_PATH - shlibpath_overrides_runpath=no - sys_lib_search_path_spec="/usr/lib${libsuff} /lib${libsuff} /usr/local/lib${libsuff}" - sys_lib_dlsearch_path_spec="/usr/lib${libsuff} /lib${libsuff}" - hardcode_into_libs=yes - ;; - -# No shared lib support for Linux oldld, aout, or coff. -linux*oldld* | linux*aout* | linux*coff*) - dynamic_linker=no - ;; - -# This must be Linux ELF. -linux* | k*bsd*-gnu) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -n $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - # Some binutils ld are patched to set DT_RUNPATH - save_LDFLAGS=$LDFLAGS - save_libdir=$libdir - eval "libdir=/foo; wl=\"$lt_prog_compiler_wl\"; \ - LDFLAGS=\"\$LDFLAGS $hardcode_libdir_flag_spec\"" - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - if ($OBJDUMP -p conftest$ac_exeext) 2>/dev/null | grep "RUNPATH.*$libdir" >/dev/null; then : - shlibpath_overrides_runpath=yes -fi -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext - LDFLAGS=$save_LDFLAGS - libdir=$save_libdir - - # This implies no fast_install, which is unacceptable. - # Some rework will be needed to allow for fast_install - # before this can be enabled. - hardcode_into_libs=yes - - # Append ld.so.conf contents to the search path - if test -f /etc/ld.so.conf; then - lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;/^[ ]*hwcap[ ]/d;s/[:, ]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '` - sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra" - fi - - # We used to test for /lib/ld.so.1 and disable shared libraries on - # powerpc, because MkLinux only supported shared libraries with the - # GNU dynamic linker. Since this was broken with cross compilers, - # most powerpc-linux boxes support dynamic linking these days and - # people can always --disable-shared, the test was removed, and we - # assume the GNU/Linux dynamic linker is in use. - dynamic_linker='GNU/Linux ld.so' - ;; - -netbsd*) - version_type=sunos - need_lib_prefix=no - need_version=no - if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - dynamic_linker='NetBSD (a.out) ld.so' - else - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major ${libname}${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - dynamic_linker='NetBSD ld.elf_so' - fi - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - ;; - -newsos6) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - ;; - -*nto* | *qnx*) - version_type=qnx - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - dynamic_linker='ldqnx.so' - ;; - -openbsd*) - version_type=sunos - sys_lib_dlsearch_path_spec="/usr/lib" - need_lib_prefix=no - # Some older versions of OpenBSD (3.3 at least) *do* need versioned libs. - case $host_os in - openbsd3.3 | openbsd3.3.*) need_version=yes ;; - *) need_version=no ;; - esac - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/sbin" ldconfig -m $libdir' - shlibpath_var=LD_LIBRARY_PATH - if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`" || test "$host_os-$host_cpu" = "openbsd2.8-powerpc"; then - case $host_os in - openbsd2.[89] | openbsd2.[89].*) - shlibpath_overrides_runpath=no - ;; - *) - shlibpath_overrides_runpath=yes - ;; - esac - else - shlibpath_overrides_runpath=yes - fi - ;; - -os2*) - libname_spec='$name' - shrext_cmds=".dll" - need_lib_prefix=no - library_names_spec='$libname${shared_ext} $libname.a' - dynamic_linker='OS/2 ld.exe' - shlibpath_var=LIBPATH - ;; - -osf3* | osf4* | osf5*) - version_type=osf - need_lib_prefix=no - need_version=no - soname_spec='${libname}${release}${shared_ext}$major' - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - sys_lib_search_path_spec="/usr/shlib /usr/ccs/lib /usr/lib/cmplrs/cc /usr/lib /usr/local/lib /var/shlib" - sys_lib_dlsearch_path_spec="$sys_lib_search_path_spec" - ;; - -rdos*) - dynamic_linker=no - ;; - -solaris*) - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - # ldd complains unless libraries are executable - postinstall_cmds='chmod +x $lib' - ;; - -sunos4*) - version_type=sunos - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${shared_ext}$versuffix' - finish_cmds='PATH="\$PATH:/usr/etc" ldconfig $libdir' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - if test "$with_gnu_ld" = yes; then - need_lib_prefix=no - fi - need_version=yes - ;; - -sysv4 | sysv4.3*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - case $host_vendor in - sni) - shlibpath_overrides_runpath=no - need_lib_prefix=no - runpath_var=LD_RUN_PATH - ;; - siemens) - need_lib_prefix=no - ;; - motorola) - need_lib_prefix=no - need_version=no - shlibpath_overrides_runpath=no - sys_lib_search_path_spec='/lib /usr/lib /usr/ccs/lib' - ;; - esac - ;; - -sysv4*MP*) - if test -d /usr/nec ;then - version_type=linux - library_names_spec='$libname${shared_ext}.$versuffix $libname${shared_ext}.$major $libname${shared_ext}' - soname_spec='$libname${shared_ext}.$major' - shlibpath_var=LD_LIBRARY_PATH - fi - ;; - -sysv5* | sco3.2v5* | sco5v6* | unixware* | OpenUNIX* | sysv4*uw2*) - version_type=freebsd-elf - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext} $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=yes - hardcode_into_libs=yes - if test "$with_gnu_ld" = yes; then - sys_lib_search_path_spec='/usr/local/lib /usr/gnu/lib /usr/ccs/lib /usr/lib /lib' - else - sys_lib_search_path_spec='/usr/ccs/lib /usr/lib' - case $host_os in - sco3.2v5*) - sys_lib_search_path_spec="$sys_lib_search_path_spec /lib" - ;; - esac - fi - sys_lib_dlsearch_path_spec='/usr/lib' - ;; - -tpf*) - # TPF is a cross-target only. Preferred cross-host = GNU/Linux. - version_type=linux - need_lib_prefix=no - need_version=no - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - shlibpath_var=LD_LIBRARY_PATH - shlibpath_overrides_runpath=no - hardcode_into_libs=yes - ;; - -uts4*) - version_type=linux - library_names_spec='${libname}${release}${shared_ext}$versuffix ${libname}${release}${shared_ext}$major $libname${shared_ext}' - soname_spec='${libname}${release}${shared_ext}$major' - shlibpath_var=LD_LIBRARY_PATH - ;; - -*) - dynamic_linker=no - ;; -esac -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -$as_echo "$dynamic_linker" >&6; } -test "$dynamic_linker" = no && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test "$GCC" = yes; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi - -if test "${lt_cv_sys_lib_search_path_spec+set}" = set; then - sys_lib_search_path_spec="$lt_cv_sys_lib_search_path_spec" -fi -if test "${lt_cv_sys_lib_dlsearch_path_spec+set}" = set; then - sys_lib_dlsearch_path_spec="$lt_cv_sys_lib_dlsearch_path_spec" -fi - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking how to hardcode library paths into programs" >&5 -$as_echo_n "checking how to hardcode library paths into programs... " >&6; } -hardcode_action= -if test -n "$hardcode_libdir_flag_spec" || - test -n "$runpath_var" || - test "X$hardcode_automatic" = "Xyes" ; then - - # We can hardcode non-existent directories. - if test "$hardcode_direct" != no && - # If the only mechanism to avoid hardcoding is shlibpath_var, we - # have to relink, otherwise we might link with an installed library - # when we should be linking with a yet-to-be-installed one - ## test "$_LT_TAGVAR(hardcode_shlibpath_var, )" != no && - test "$hardcode_minus_L" != no; then - # Linking always hardcodes the temporary library directory. - hardcode_action=relink - else - # We can link without hardcoding, and we can hardcode nonexisting dirs. - hardcode_action=immediate - fi -else - # We cannot hardcode anything, or else we can only hardcode existing - # directories. - hardcode_action=unsupported -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $hardcode_action" >&5 -$as_echo "$hardcode_action" >&6; } - -if test "$hardcode_action" = relink || - test "$inherit_rpath" = yes; then - # Fast installation is not supported - enable_fast_install=no -elif test "$shlibpath_overrides_runpath" = yes || - test "$enable_shared" = no; then - # Fast installation is not necessary - enable_fast_install=needless -fi - - - - - - - if test "x$enable_dlopen" != xyes; then - enable_dlopen=unknown - enable_dlopen_self=unknown - enable_dlopen_self_static=unknown -else - lt_cv_dlopen=no - lt_cv_dlopen_libs= - - case $host_os in - beos*) - lt_cv_dlopen="load_add_on" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - ;; - - mingw* | pw32* | cegcc*) - lt_cv_dlopen="LoadLibrary" - lt_cv_dlopen_libs= - ;; - - cygwin*) - lt_cv_dlopen="dlopen" - lt_cv_dlopen_libs= - ;; - - darwin*) - # if libdl is installed we need to link against it - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - - lt_cv_dlopen="dyld" - lt_cv_dlopen_libs= - lt_cv_dlopen_self=yes - -fi - - ;; - - *) - ac_fn_c_check_func "$LINENO" "shl_load" "ac_cv_func_shl_load" -if test "x$ac_cv_func_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for shl_load in -ldld" >&5 -$as_echo_n "checking for shl_load in -ldld... " >&6; } -if ${ac_cv_lib_dld_shl_load+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char shl_load (); -int -main () -{ -return shl_load (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_shl_load=yes -else - ac_cv_lib_dld_shl_load=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_shl_load" >&5 -$as_echo "$ac_cv_lib_dld_shl_load" >&6; } -if test "x$ac_cv_lib_dld_shl_load" = xyes; then : - lt_cv_dlopen="shl_load" lt_cv_dlopen_libs="-ldld" -else - ac_fn_c_check_func "$LINENO" "dlopen" "ac_cv_func_dlopen" -if test "x$ac_cv_func_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -ldl" >&5 -$as_echo_n "checking for dlopen in -ldl... " >&6; } -if ${ac_cv_lib_dl_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldl $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dl_dlopen=yes -else - ac_cv_lib_dl_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dl_dlopen" >&5 -$as_echo "$ac_cv_lib_dl_dlopen" >&6; } -if test "x$ac_cv_lib_dl_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-ldl" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dlopen in -lsvld" >&5 -$as_echo_n "checking for dlopen in -lsvld... " >&6; } -if ${ac_cv_lib_svld_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lsvld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_svld_dlopen=yes -else - ac_cv_lib_svld_dlopen=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_svld_dlopen" >&5 -$as_echo "$ac_cv_lib_svld_dlopen" >&6; } -if test "x$ac_cv_lib_svld_dlopen" = xyes; then : - lt_cv_dlopen="dlopen" lt_cv_dlopen_libs="-lsvld" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for dld_link in -ldld" >&5 -$as_echo_n "checking for dld_link in -ldld... " >&6; } -if ${ac_cv_lib_dld_dld_link+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-ldld $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dld_link (); -int -main () -{ -return dld_link (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_dld_dld_link=yes -else - ac_cv_lib_dld_dld_link=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_dld_dld_link" >&5 -$as_echo "$ac_cv_lib_dld_dld_link" >&6; } -if test "x$ac_cv_lib_dld_dld_link" = xyes; then : - lt_cv_dlopen="dld_link" lt_cv_dlopen_libs="-ldld" -fi - - -fi - - -fi - - -fi - - -fi - - -fi - - ;; - esac - - if test "x$lt_cv_dlopen" != xno; then - enable_dlopen=yes - else - enable_dlopen=no - fi - - case $lt_cv_dlopen in - dlopen) - save_CPPFLAGS="$CPPFLAGS" - test "x$ac_cv_header_dlfcn_h" = xyes && CPPFLAGS="$CPPFLAGS -DHAVE_DLFCN_H" - - save_LDFLAGS="$LDFLAGS" - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $export_dynamic_flag_spec\" - - save_LIBS="$LIBS" - LIBS="$lt_cv_dlopen_libs $LIBS" - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a program can dlopen itself" >&5 -$as_echo_n "checking whether a program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line 9561 "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self" >&5 -$as_echo "$lt_cv_dlopen_self" >&6; } - - if test "x$lt_cv_dlopen_self" = xyes; then - wl=$lt_prog_compiler_wl eval LDFLAGS=\"\$LDFLAGS $lt_prog_compiler_static\" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether a statically linked program can dlopen itself" >&5 -$as_echo_n "checking whether a statically linked program can dlopen itself... " >&6; } -if ${lt_cv_dlopen_self_static+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test "$cross_compiling" = yes; then : - lt_cv_dlopen_self_static=cross -else - lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2 - lt_status=$lt_dlunknown - cat > conftest.$ac_ext <<_LT_EOF -#line 9657 "configure" -#include "confdefs.h" - -#if HAVE_DLFCN_H -#include -#endif - -#include - -#ifdef RTLD_GLOBAL -# define LT_DLGLOBAL RTLD_GLOBAL -#else -# ifdef DL_GLOBAL -# define LT_DLGLOBAL DL_GLOBAL -# else -# define LT_DLGLOBAL 0 -# endif -#endif - -/* We may have to define LT_DLLAZY_OR_NOW in the command line if we - find out it does not work in some platform. */ -#ifndef LT_DLLAZY_OR_NOW -# ifdef RTLD_LAZY -# define LT_DLLAZY_OR_NOW RTLD_LAZY -# else -# ifdef DL_LAZY -# define LT_DLLAZY_OR_NOW DL_LAZY -# else -# ifdef RTLD_NOW -# define LT_DLLAZY_OR_NOW RTLD_NOW -# else -# ifdef DL_NOW -# define LT_DLLAZY_OR_NOW DL_NOW -# else -# define LT_DLLAZY_OR_NOW 0 -# endif -# endif -# endif -# endif -#endif - -void fnord() { int i=42;} -int main () -{ - void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); - int status = $lt_dlunknown; - - if (self) - { - if (dlsym (self,"fnord")) status = $lt_dlno_uscore; - else if (dlsym( self,"_fnord")) status = $lt_dlneed_uscore; - /* dlclose (self); */ - } - else - puts (dlerror ()); - - return status; -} -_LT_EOF - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_link\""; } >&5 - (eval $ac_link) 2>&5 - ac_status=$? - $as_echo "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s conftest${ac_exeext} 2>/dev/null; then - (./conftest; exit; ) >&5 2>/dev/null - lt_status=$? - case x$lt_status in - x$lt_dlno_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlneed_uscore) lt_cv_dlopen_self_static=yes ;; - x$lt_dlunknown|x*) lt_cv_dlopen_self_static=no ;; - esac - else : - # compilation failed - lt_cv_dlopen_self_static=no - fi -fi -rm -fr conftest* - - -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $lt_cv_dlopen_self_static" >&5 -$as_echo "$lt_cv_dlopen_self_static" >&6; } - fi - - CPPFLAGS="$save_CPPFLAGS" - LDFLAGS="$save_LDFLAGS" - LIBS="$save_LIBS" - ;; - esac - - case $lt_cv_dlopen_self in - yes|no) enable_dlopen_self=$lt_cv_dlopen_self ;; - *) enable_dlopen_self=unknown ;; - esac - - case $lt_cv_dlopen_self_static in - yes|no) enable_dlopen_self_static=$lt_cv_dlopen_self_static ;; - *) enable_dlopen_self_static=unknown ;; - esac -fi - - - - - - - - - - - - - - - - - -striplib= -old_striplib= -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 -$as_echo_n "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP" ; then - striplib="$STRIP -x" - old_striplib="$STRIP -S" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - fi - ;; - *) - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - esac -fi - - - - - - - - - - - - - # Report which library types will actually be built - { $as_echo "$as_me:${as_lineno-$LINENO}: checking if libtool supports shared libraries" >&5 -$as_echo_n "checking if libtool supports shared libraries... " >&6; } - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $can_build_shared" >&5 -$as_echo "$can_build_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build shared libraries" >&5 -$as_echo_n "checking whether to build shared libraries... " >&6; } - test "$can_build_shared" = "no" && enable_shared=no - - # On AIX, shared libraries and static libraries use the same namespace, and - # are all built from PIC. - case $host_os in - aix3*) - test "$enable_shared" = yes && enable_static=no - if test -n "$RANLIB"; then - archive_cmds="$archive_cmds~\$RANLIB \$lib" - postinstall_cmds='$RANLIB $lib' - fi - ;; - - aix[4-9]*) - if test "$host_cpu" != ia64 && test "$aix_use_runtimelinking" = no ; then - test "$enable_shared" = yes && enable_static=no - fi - ;; - esac - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_shared" >&5 -$as_echo "$enable_shared" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to build static libraries" >&5 -$as_echo_n "checking whether to build static libraries... " >&6; } - # Make sure either enable_shared or enable_static is yes. - test "$enable_shared" = yes || enable_static=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $enable_static" >&5 -$as_echo "$enable_static" >&6; } - - - - -fi -ac_ext=c -ac_cpp='$CPP $CPPFLAGS' -ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5' -ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5' -ac_compiler_gnu=$ac_cv_c_compiler_gnu - -CC="$lt_save_CC" - - - - - - - - - - - - - - ac_config_commands="$ac_config_commands libtool" - - - - -# Only expand once: - - -# Find a good install program. We prefer a C program (faster), -# so one script is as good as another. But avoid the broken or -# incompatible versions: -# SysV /etc/install, /usr/sbin/install -# SunOS /usr/etc/install -# IRIX /sbin/install -# AIX /bin/install -# AmigaOS /C/install, which installs bootblocks on floppy discs -# AIX 4 /usr/bin/installbsd, which doesn't work without a -g flag -# AFS /usr/afsws/bin/install, which mishandles nonexistent args -# SVR4 /usr/ucb/install, which tries to use the nonexistent group "staff" -# OS/2's system install, which has a completely different semantic -# ./install, which can be erroneously created by make from ./install.sh. -# Reject install programs that cannot install multiple files. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for a BSD-compatible install" >&5 -$as_echo_n "checking for a BSD-compatible install... " >&6; } -if test -z "$INSTALL"; then -if ${ac_cv_path_install+:} false; then : - $as_echo_n "(cached) " >&6 -else - as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - # Account for people who put trailing slashes in PATH elements. -case $as_dir/ in #(( - ./ | .// | /[cC]/* | \ - /etc/* | /usr/sbin/* | /usr/etc/* | /sbin/* | /usr/afsws/bin/* | \ - ?:[\\/]os2[\\/]install[\\/]* | ?:[\\/]OS2[\\/]INSTALL[\\/]* | \ - /usr/ucb/* ) ;; - *) - # OSF1 and SCO ODT 3.0 have their own names for install. - # Don't use installbsd from OSF since it installs stuff as root - # by default. - for ac_prog in ginstall scoinst install; do - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_prog$ac_exec_ext"; then - if test $ac_prog = install && - grep dspmsg "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # AIX install. It has an incompatible calling convention. - : - elif test $ac_prog = install && - grep pwplus "$as_dir/$ac_prog$ac_exec_ext" >/dev/null 2>&1; then - # program-specific install script used by HP pwplus--don't use. - : - else - rm -rf conftest.one conftest.two conftest.dir - echo one > conftest.one - echo two > conftest.two - mkdir conftest.dir - if "$as_dir/$ac_prog$ac_exec_ext" -c conftest.one conftest.two "`pwd`/conftest.dir" && - test -s conftest.one && test -s conftest.two && - test -s conftest.dir/conftest.one && - test -s conftest.dir/conftest.two - then - ac_cv_path_install="$as_dir/$ac_prog$ac_exec_ext -c" - break 3 - fi - fi - fi - done - done - ;; -esac - - done -IFS=$as_save_IFS - -rm -rf conftest.one conftest.two conftest.dir - -fi - if test "${ac_cv_path_install+set}" = set; then - INSTALL=$ac_cv_path_install - else - # As a last resort, use the slow shell script. Don't cache a - # value for INSTALL within a source directory, because that will - # break other packages using the cache if that directory is - # removed, or if the value is a relative name. - INSTALL=$ac_install_sh - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $INSTALL" >&5 -$as_echo "$INSTALL" >&6; } - -# Use test -z because SunOS4 sh mishandles braces in ${var-val}. -# It thinks the first close brace ends the variable substitution. -test -z "$INSTALL_PROGRAM" && INSTALL_PROGRAM='${INSTALL}' - -test -z "$INSTALL_SCRIPT" && INSTALL_SCRIPT='${INSTALL}' - -test -z "$INSTALL_DATA" && INSTALL_DATA='${INSTALL} -m 644' - - -######### -# Enable large file support (if special flags are necessary) -# -# Check whether --enable-largefile was given. -if test "${enable_largefile+set}" = set; then : - enableval=$enable_largefile; -fi - -if test "$enable_largefile" != no; then - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for special C compiler options needed for large files" >&5 -$as_echo_n "checking for special C compiler options needed for large files... " >&6; } -if ${ac_cv_sys_largefile_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_cv_sys_largefile_CC=no - if test "$GCC" != yes; then - ac_save_CC=$CC - while :; do - # IRIX 6.2 and later do not support large files by default, - # so use the C compiler's -n32 option if that helps. - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF - if ac_fn_c_try_compile "$LINENO"; then : - break -fi -rm -f core conftest.err conftest.$ac_objext - CC="$CC -n32" - if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_largefile_CC=' -n32'; break -fi -rm -f core conftest.err conftest.$ac_objext - break - done - CC=$ac_save_CC - rm -f conftest.$ac_ext - fi -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_largefile_CC" >&5 -$as_echo "$ac_cv_sys_largefile_CC" >&6; } - if test "$ac_cv_sys_largefile_CC" != no; then - CC=$CC$ac_cv_sys_largefile_CC - fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _FILE_OFFSET_BITS value needed for large files" >&5 -$as_echo_n "checking for _FILE_OFFSET_BITS value needed for large files... " >&6; } -if ${ac_cv_sys_file_offset_bits+:} false; then : - $as_echo_n "(cached) " >&6 -else - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_file_offset_bits=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _FILE_OFFSET_BITS 64 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_file_offset_bits=64; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cv_sys_file_offset_bits=unknown - break -done -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_file_offset_bits" >&5 -$as_echo "$ac_cv_sys_file_offset_bits" >&6; } -case $ac_cv_sys_file_offset_bits in #( - no | unknown) ;; - *) -cat >>confdefs.h <<_ACEOF -#define _FILE_OFFSET_BITS $ac_cv_sys_file_offset_bits -_ACEOF -;; -esac -rm -rf conftest* - if test $ac_cv_sys_file_offset_bits = unknown; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for _LARGE_FILES value needed for large files" >&5 -$as_echo_n "checking for _LARGE_FILES value needed for large files... " >&6; } -if ${ac_cv_sys_large_files+:} false; then : - $as_echo_n "(cached) " >&6 -else - while :; do - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_large_files=no; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ -#define _LARGE_FILES 1 -#include - /* Check that off_t can represent 2**63 - 1 correctly. - We can't simply define LARGE_OFF_T to be 9223372036854775807, - since some C++ compilers masquerading as C compilers - incorrectly reject 9223372036854775807. */ -#define LARGE_OFF_T (((off_t) 1 << 62) - 1 + ((off_t) 1 << 62)) - int off_t_is_large[(LARGE_OFF_T % 2147483629 == 721 - && LARGE_OFF_T % 2147483647 == 1) - ? 1 : -1]; -int -main () -{ - - ; - return 0; -} -_ACEOF -if ac_fn_c_try_compile "$LINENO"; then : - ac_cv_sys_large_files=1; break -fi -rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext - ac_cv_sys_large_files=unknown - break -done -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_sys_large_files" >&5 -$as_echo "$ac_cv_sys_large_files" >&6; } -case $ac_cv_sys_large_files in #( - no | unknown) ;; - *) -cat >>confdefs.h <<_ACEOF -#define _LARGE_FILES $ac_cv_sys_large_files -_ACEOF -;; -esac -rm -rf conftest* - fi - - -fi - - -######### -# Check for needed/wanted data types -ac_fn_c_check_type "$LINENO" "int8_t" "ac_cv_type_int8_t" "$ac_includes_default" -if test "x$ac_cv_type_int8_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT8_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "int16_t" "ac_cv_type_int16_t" "$ac_includes_default" -if test "x$ac_cv_type_int16_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT16_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "int32_t" "ac_cv_type_int32_t" "$ac_includes_default" -if test "x$ac_cv_type_int32_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT32_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "int64_t" "ac_cv_type_int64_t" "$ac_includes_default" -if test "x$ac_cv_type_int64_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INT64_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "intptr_t" "ac_cv_type_intptr_t" "$ac_includes_default" -if test "x$ac_cv_type_intptr_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_INTPTR_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint8_t" "ac_cv_type_uint8_t" "$ac_includes_default" -if test "x$ac_cv_type_uint8_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT8_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint16_t" "ac_cv_type_uint16_t" "$ac_includes_default" -if test "x$ac_cv_type_uint16_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT16_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint32_t" "ac_cv_type_uint32_t" "$ac_includes_default" -if test "x$ac_cv_type_uint32_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT32_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uint64_t" "ac_cv_type_uint64_t" "$ac_includes_default" -if test "x$ac_cv_type_uint64_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINT64_T 1 -_ACEOF - - -fi -ac_fn_c_check_type "$LINENO" "uintptr_t" "ac_cv_type_uintptr_t" "$ac_includes_default" -if test "x$ac_cv_type_uintptr_t" = xyes; then : - -cat >>confdefs.h <<_ACEOF -#define HAVE_UINTPTR_T 1 -_ACEOF - - -fi - - -######### -# Check for needed/wanted headers -for ac_header in sys/types.h stdlib.h stdint.h inttypes.h malloc.h -do : - as_ac_Header=`$as_echo "ac_cv_header_$ac_header" | $as_tr_sh` -ac_fn_c_check_header_mongrel "$LINENO" "$ac_header" "$as_ac_Header" "$ac_includes_default" -if eval test \"x\$"$as_ac_Header"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_header" | $as_tr_cpp` 1 -_ACEOF - -fi - -done - - -######### -# Figure out whether or not we have these functions -# -for ac_func in fdatasync gmtime_r isnan localtime_r localtime_s malloc_usable_size strchrnul usleep utime pread pread64 pwrite pwrite64 -do : - as_ac_var=`$as_echo "ac_cv_func_$ac_func" | $as_tr_sh` -ac_fn_c_check_func "$LINENO" "$ac_func" "$as_ac_var" -if eval test \"x\$"$as_ac_var"\" = x"yes"; then : - cat >>confdefs.h <<_ACEOF -#define `$as_echo "HAVE_$ac_func" | $as_tr_cpp` 1 -_ACEOF - -fi -done - - -######### -# By default, we use the amalgamation (this may be changed below...) -# -USE_AMALGAMATION=1 - -######### -# See whether we can run specific tclsh versions known to work well; -# if not, then we fall back to plain tclsh. -# TODO: try other versions before falling back? -# -for ac_prog in tclsh8.7 tclsh8.6 tclsh8.5 tclsh -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_TCLSH_CMD+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$TCLSH_CMD"; then - ac_cv_prog_TCLSH_CMD="$TCLSH_CMD" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_TCLSH_CMD="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -TCLSH_CMD=$ac_cv_prog_TCLSH_CMD -if test -n "$TCLSH_CMD"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $TCLSH_CMD" >&5 -$as_echo "$TCLSH_CMD" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$TCLSH_CMD" && break -done -test -n "$TCLSH_CMD" || TCLSH_CMD="none" - -if test "$TCLSH_CMD" = "none"; then - # If we can't find a local tclsh, then building the amalgamation will fail. - # We act as though --disable-amalgamation has been used. - echo "Warning: can't find tclsh - defaulting to non-amalgamation build." - USE_AMALGAMATION=0 - TCLSH_CMD="tclsh" -fi - - - -if test "x${TCLLIBDIR+set}" != "xset" ; then - TCLLIBDIR='$(libdir)' - for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` ; do - if test -d $i ; then - TCLLIBDIR=$i - break - fi - done - TCLLIBDIR="${TCLLIBDIR}/sqlite3" -fi - - -######### -# Set up an appropriate program prefix -# -if test "$program_prefix" = "NONE"; then - program_prefix="" -fi - - -VERSION=`cat $srcdir/VERSION | sed 's/^\([0-9]*\.*[0-9]*\).*/\1/'` -{ $as_echo "$as_me:${as_lineno-$LINENO}: Version set to $VERSION" >&5 -$as_echo "$as_me: Version set to $VERSION" >&6;} - -RELEASE=`cat $srcdir/VERSION` -{ $as_echo "$as_me:${as_lineno-$LINENO}: Release set to $RELEASE" >&5 -$as_echo "$as_me: Release set to $RELEASE" >&6;} - - -########## -# Handle --with-wasi-sdk=DIR -# -# This must be early because it changes the toolchain. -# - -# Check whether --with-wasi-sdk was given. -if test "${with_wasi_sdk+set}" = set; then : - withval=$with_wasi_sdk; with_wasisdk=${withval} -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for WASI SDK directory" >&5 -$as_echo_n "checking for WASI SDK directory... " >&6; } -if ${ac_cv_c_wasi_sdk+:} false; then : - $as_echo_n "(cached) " >&6 -else - - # First check to see if --with-tcl was specified. - if test x"${with_wasi_sdk}" != x ; then - if ! test -d "${with_wasi_sdk}" ; then - as_fn_error $? "${with_wasi_sdk} directory doesn't exist" "$LINENO" 5 - fi - { $as_echo "$as_me:${as_lineno-$LINENO}: result: ${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL" >&5 -$as_echo "${with_wasi_sdk}: using wasi-sdk clang, disabling: tcl, CLI shell, DLL" >&6; } - use_wasi_sdk=yes - else - use_wasi_sdk=no - fi - -fi - -if test "${use_wasi_sdk}" = "no" ; then - HAVE_WASI_SDK="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - HAVE_WASI_SDK=1 -# Changing --host and --target have no effect here except to possibly -# cause confusion. autoconf has finished processing them by this -# point. -# -# host_alias=wasm32-wasi -# target=wasm32-wasi -# -# Merely changing CC and LD to the wasi-sdk's is enough to get -# sqlite3.o building in WASM format. - CC="${with_wasi_sdk}/bin/clang" - LD="${with_wasi_sdk}/bin/wasm-ld" - RANLIB="${with_wasi_sdk}/bin/llvm-ranlib" - cross_compiling=yes - enable_threadsafe=no - use_tcl=no - enable_tcl=no - # libtool is apparently hard-coded to use gcc for linking DLLs, so - # we disable the DLL build... - enable_shared=no - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - - - -######### -# Locate a compiler for the build machine. This compiler should -# generate command-line programs that run on the build machine. -# -if test x"$cross_compiling" = xno; then - BUILD_CC=$CC - BUILD_CFLAGS=$CFLAGS -else - if test "${BUILD_CC+set}" != set; then - for ac_prog in gcc cc cl -do - # Extract the first word of "$ac_prog", so it can be a program name with args. -set dummy $ac_prog; ac_word=$2 -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -$as_echo_n "checking for $ac_word... " >&6; } -if ${ac_cv_prog_BUILD_CC+:} false; then : - $as_echo_n "(cached) " >&6 -else - if test -n "$BUILD_CC"; then - ac_cv_prog_BUILD_CC="$BUILD_CC" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir/$ac_word$ac_exec_ext"; then - ac_cv_prog_BUILD_CC="$ac_prog" - $as_echo "$as_me:${as_lineno-$LINENO}: found $as_dir/$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -BUILD_CC=$ac_cv_prog_BUILD_CC -if test -n "$BUILD_CC"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $BUILD_CC" >&5 -$as_echo "$BUILD_CC" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - - - test -n "$BUILD_CC" && break -done - - fi - if test "${BUILD_CFLAGS+set}" != set; then - BUILD_CFLAGS="-g" - fi -fi - - -########## -# Do we want to support multithreaded use of sqlite -# -# Check whether --enable-threadsafe was given. -if test "${enable_threadsafe+set}" = set; then : - enableval=$enable_threadsafe; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support threadsafe operation" >&5 -$as_echo_n "checking whether to support threadsafe operation... " >&6; } -if test "$enable_threadsafe" = "no"; then - SQLITE_THREADSAFE=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - SQLITE_THREADSAFE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - - -if test "$SQLITE_THREADSAFE" = "1"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5 -$as_echo_n "checking for library containing pthread_create... " >&6; } -if ${ac_cv_search_pthread_create+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_create (); -int -main () -{ -return pthread_create (); - ; - return 0; -} -_ACEOF -for ac_lib in '' pthread; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_pthread_create=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_pthread_create+:} false; then : - break -fi -done -if ${ac_cv_search_pthread_create+:} false; then : - -else - ac_cv_search_pthread_create=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_create" >&5 -$as_echo "$ac_cv_search_pthread_create" >&6; } -ac_res=$ac_cv_search_pthread_create -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_mutexattr_init" >&5 -$as_echo_n "checking for library containing pthread_mutexattr_init... " >&6; } -if ${ac_cv_search_pthread_mutexattr_init+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char pthread_mutexattr_init (); -int -main () -{ -return pthread_mutexattr_init (); - ; - return 0; -} -_ACEOF -for ac_lib in '' pthread; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_pthread_mutexattr_init=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_pthread_mutexattr_init+:} false; then : - break -fi -done -if ${ac_cv_search_pthread_mutexattr_init+:} false; then : - -else - ac_cv_search_pthread_mutexattr_init=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_pthread_mutexattr_init" >&5 -$as_echo "$ac_cv_search_pthread_mutexattr_init" >&6; } -ac_res=$ac_cv_search_pthread_mutexattr_init -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -########## -# Do we want to support release -# -# Check whether --enable-releasemode was given. -if test "${enable_releasemode+set}" = set; then : - enableval=$enable_releasemode; -else - enable_releasemode=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support shared library linked as release mode or not" >&5 -$as_echo_n "checking whether to support shared library linked as release mode or not... " >&6; } -if test "$enable_releasemode" = "no"; then - ALLOWRELEASE="" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - ALLOWRELEASE="-release `cat $srcdir/VERSION`" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - - -########## -# Do we want temporary databases in memory -# -# Check whether --enable-tempstore was given. -if test "${enable_tempstore+set}" = set; then : - enableval=$enable_tempstore; -else - enable_tempstore=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to use an in-ram database for temporary tables" >&5 -$as_echo_n "checking whether to use an in-ram database for temporary tables... " >&6; } -case "$enable_tempstore" in - never ) - TEMP_STORE=0 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: never" >&5 -$as_echo "never" >&6; } - ;; - no ) - TEMP_STORE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; - yes ) - TEMP_STORE=2 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - ;; - always ) - TEMP_STORE=3 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: always" >&5 -$as_echo "always" >&6; } - ;; - * ) - TEMP_STORE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - ;; -esac - - - -########### -# Lots of things are different if we are compiling for Windows using -# the CYGWIN environment. So check for that special case and handle -# things accordingly. -# -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking if executables have the .exe suffix" >&5 -$as_echo_n "checking if executables have the .exe suffix... " >&6; } -if test "$config_BUILD_EXEEXT" = ".exe"; then - CYGWIN=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: unknown" >&5 -$as_echo "unknown" >&6; } -fi -if test "$CYGWIN" != "yes"; then - -case $host_os in - *cygwin* ) CYGWIN=yes;; - * ) CYGWIN=no;; -esac - -fi -if test "$CYGWIN" = "yes"; then - BUILD_EXEEXT=.exe -else - BUILD_EXEEXT=$EXEEXT -fi -if test x"$cross_compiling" = xno; then - TARGET_EXEEXT=$BUILD_EXEEXT -else - TARGET_EXEEXT=$config_TARGET_EXEEXT -fi -if test "$TARGET_EXEEXT" = ".exe"; then - SQLITE_OS_UNIX=0 - SQLITE_OS_WIN=1 - CFLAGS="$CFLAGS -DSQLITE_OS_WIN=1" -else - SQLITE_OS_UNIX=1 - SQLITE_OS_WIN=0 - CFLAGS="$CFLAGS -DSQLITE_OS_UNIX=1" -fi - - - - - - -########## -# Figure out all the parameters needed to compile against Tcl. -# -# This code is derived from the SC_PATH_TCLCONFIG and SC_LOAD_TCLCONFIG -# macros in the in the tcl.m4 file of the standard TCL distribution. -# Those macros could not be used directly since we have to make some -# minor changes to accomodate systems that do not have TCL installed. -# -# Check whether --enable-tcl was given. -if test "${enable_tcl+set}" = set; then : - enableval=$enable_tcl; use_tcl=$enableval -else - use_tcl=yes -fi - -if test "${use_tcl}" = "yes" ; then - -# Check whether --with-tcl was given. -if test "${with_tcl+set}" = set; then : - withval=$with_tcl; with_tclconfig=${withval} -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for Tcl configuration" >&5 -$as_echo_n "checking for Tcl configuration... " >&6; } - if ${ac_cv_c_tclconfig+:} false; then : - $as_echo_n "(cached) " >&6 -else - - # First check to see if --with-tcl was specified. - if test x"${with_tclconfig}" != x ; then - if test -f "${with_tclconfig}/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd ${with_tclconfig}; pwd)` - else - as_fn_error $? "${with_tclconfig} directory doesn't contain tclConfig.sh" "$LINENO" 5 - fi - fi - - # Start autosearch by asking tclsh - if test x"${ac_cv_c_tclconfig}" = x ; then - if test x"$cross_compiling" = xno; then - for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD}` - do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig="$i" - break - fi - done - fi - fi - - # On ubuntu 14.10, $auto_path on tclsh is not quite correct. - # So try again after applying corrections. - if test x"${ac_cv_c_tclconfig}" = x ; then - if test x"$cross_compiling" = xno; then - for i in `echo 'puts stdout $auto_path' | ${TCLSH_CMD} | sed 's,/tcltk/tcl,/tcl,g'` - do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig="$i" - break - fi - done - fi - fi - - # Recent versions of Xcode on Macs hid the tclConfig.sh file - # in a strange place. - if test x"${ac_cv_c_tclconfig}" = x ; then - if test x"$cross_compiling" = xno; then - for i in /Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX*.sdk/usr/lib - do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig="$i" - break - fi - done - fi - fi - - # then check for a private Tcl installation - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ../tcl \ - `ls -dr ../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../tcl \ - `ls -dr ../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../tcl[8-9].[0-9]* 2>/dev/null` \ - ../../../tcl \ - `ls -dr ../../../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ../../../tcl[8-9].[0-9]* 2>/dev/null` - do - if test -f "$i/unix/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/unix; pwd)` - break - fi - done - fi - - # check in a few common install locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - `ls -d ${libdir} 2>/dev/null` \ - `ls -d /usr/local/lib 2>/dev/null` \ - `ls -d /usr/contrib/lib 2>/dev/null` \ - `ls -d /usr/lib 2>/dev/null` - do - if test -f "$i/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i; pwd)` - break - fi - done - fi - - # check in a few other private locations - if test x"${ac_cv_c_tclconfig}" = x ; then - for i in \ - ${srcdir}/../tcl \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9].[0-9]* 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9] 2>/dev/null` \ - `ls -dr ${srcdir}/../tcl[8-9].[0-9]* 2>/dev/null` - do - if test -f "$i/unix/tclConfig.sh" ; then - ac_cv_c_tclconfig=`(cd $i/unix; pwd)` - break - fi - done - fi - -fi - - - if test x"${ac_cv_c_tclconfig}" = x ; then - use_tcl=no - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: Can't find Tcl configuration definitions" >&5 -$as_echo "$as_me: WARNING: Can't find Tcl configuration definitions" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&5 -$as_echo "$as_me: WARNING: *** Without Tcl the regression tests cannot be executed ***" >&2;} - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&5 -$as_echo "$as_me: WARNING: *** Consider using --with-tcl=... to define location of Tcl ***" >&2;} - else - TCL_BIN_DIR=${ac_cv_c_tclconfig} - { $as_echo "$as_me:${as_lineno-$LINENO}: result: found $TCL_BIN_DIR/tclConfig.sh" >&5 -$as_echo "found $TCL_BIN_DIR/tclConfig.sh" >&6; } - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for existence of $TCL_BIN_DIR/tclConfig.sh" >&5 -$as_echo_n "checking for existence of $TCL_BIN_DIR/tclConfig.sh... " >&6; } - if test -f "$TCL_BIN_DIR/tclConfig.sh" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: loading" >&5 -$as_echo "loading" >&6; } - . $TCL_BIN_DIR/tclConfig.sh - else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: file not found" >&5 -$as_echo "file not found" >&6; } - fi - - # - # If the TCL_BIN_DIR is the build directory (not the install directory), - # then set the common variable name to the value of the build variables. - # For example, the variable TCL_LIB_SPEC will be set to the value - # of TCL_BUILD_LIB_SPEC. An extension should make use of TCL_LIB_SPEC - # instead of TCL_BUILD_LIB_SPEC since it will work with both an - # installed and uninstalled version of Tcl. - # - - if test -f $TCL_BIN_DIR/Makefile ; then - TCL_LIB_SPEC=${TCL_BUILD_LIB_SPEC} - TCL_STUB_LIB_SPEC=${TCL_BUILD_STUB_LIB_SPEC} - TCL_STUB_LIB_PATH=${TCL_BUILD_STUB_LIB_PATH} - fi - - # - # eval is required to do the TCL_DBGX substitution - # - - eval "TCL_LIB_FILE=\"${TCL_LIB_FILE}\"" - eval "TCL_LIB_FLAG=\"${TCL_LIB_FLAG}\"" - eval "TCL_LIB_SPEC=\"${TCL_LIB_SPEC}\"" - - eval "TCL_STUB_LIB_FILE=\"${TCL_STUB_LIB_FILE}\"" - eval "TCL_STUB_LIB_FLAG=\"${TCL_STUB_LIB_FLAG}\"" - eval "TCL_STUB_LIB_SPEC=\"${TCL_STUB_LIB_SPEC}\"" - - - - - - - - - - - - - - - fi -fi -if test "${use_tcl}" = "no" ; then - HAVE_TCL="" -else - HAVE_TCL=1 -fi - - -########## -# Figure out what C libraries are required to compile programs -# that use "readline()" library. -# -TARGET_READLINE_LIBS="" -TARGET_READLINE_INC="" -TARGET_HAVE_READLINE=0 -TARGET_HAVE_EDITLINE=0 -# Check whether --enable-editline was given. -if test "${enable_editline+set}" = set; then : - enableval=$enable_editline; with_editline=$enableval -else - with_editline=auto -fi - -# Check whether --enable-readline was given. -if test "${enable_readline+set}" = set; then : - enableval=$enable_readline; with_readline=$enableval -else - with_readline=auto -fi - - -if test x"$with_editline" != xno; then - sLIBS=$LIBS - LIBS="" - TARGET_HAVE_EDITLINE=1 - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing readline" >&5 -$as_echo_n "checking for library containing readline... " >&6; } -if ${ac_cv_search_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -for ac_lib in '' edit; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_readline=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_readline+:} false; then : - break -fi -done -if ${ac_cv_search_readline+:} false; then : - -else - ac_cv_search_readline=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_readline" >&5 -$as_echo "$ac_cv_search_readline" >&6; } -ac_res=$ac_cv_search_readline -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - with_readline=no -else - TARGET_HAVE_EDITLINE=0 -fi - - TARGET_READLINE_LIBS=$LIBS - LIBS=$sLIBS -fi -if test x"$with_readline" != xno; then - found="yes" - - -# Check whether --with-readline-lib was given. -if test "${with_readline_lib+set}" = set; then : - withval=$with_readline_lib; with_readline_lib=$withval -else - with_readline_lib="auto" -fi - - if test "x$with_readline_lib" = xauto; then - save_LIBS="$LIBS" - LIBS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing tgetent" >&5 -$as_echo_n "checking for library containing tgetent... " >&6; } -if ${ac_cv_search_tgetent+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char tgetent (); -int -main () -{ -return tgetent (); - ; - return 0; -} -_ACEOF -for ac_lib in '' readline ncurses curses termcap; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_tgetent=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_tgetent+:} false; then : - break -fi -done -if ${ac_cv_search_tgetent+:} false; then : - -else - ac_cv_search_tgetent=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_tgetent" >&5 -$as_echo "$ac_cv_search_tgetent" >&6; } -ac_res=$ac_cv_search_tgetent -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - term_LIBS="$LIBS" -else - term_LIBS="" -fi - - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for readline in -lreadline" >&5 -$as_echo_n "checking for readline in -lreadline... " >&6; } -if ${ac_cv_lib_readline_readline+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_check_lib_save_LIBS=$LIBS -LIBS="-lreadline $LIBS" -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char readline (); -int -main () -{ -return readline (); - ; - return 0; -} -_ACEOF -if ac_fn_c_try_link "$LINENO"; then : - ac_cv_lib_readline_readline=yes -else - ac_cv_lib_readline_readline=no -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext conftest.$ac_ext -LIBS=$ac_check_lib_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_lib_readline_readline" >&5 -$as_echo "$ac_cv_lib_readline_readline" >&6; } -if test "x$ac_cv_lib_readline_readline" = xyes; then : - TARGET_READLINE_LIBS="-lreadline" -else - found="no" -fi - - TARGET_READLINE_LIBS="$TARGET_READLINE_LIBS $term_LIBS" - LIBS="$save_LIBS" - else - TARGET_READLINE_LIBS="$with_readline_lib" - fi - - -# Check whether --with-readline-inc was given. -if test "${with_readline_inc+set}" = set; then : - withval=$with_readline_inc; with_readline_inc=$withval -else - with_readline_inc="auto" -fi - - if test "x$with_readline_inc" = xauto; then - ac_fn_c_check_header_mongrel "$LINENO" "readline.h" "ac_cv_header_readline_h" "$ac_includes_default" -if test "x$ac_cv_header_readline_h" = xyes; then : - found="yes" -else - - found="no" - if test "$cross_compiling" != yes; then - for dir in /usr /usr/local /usr/local/readline /usr/contrib /mingw; do - for subdir in include include/readline; do - as_ac_File=`$as_echo "ac_cv_file_$dir/$subdir/readline.h" | $as_tr_sh` -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for $dir/$subdir/readline.h" >&5 -$as_echo_n "checking for $dir/$subdir/readline.h... " >&6; } -if eval \${$as_ac_File+:} false; then : - $as_echo_n "(cached) " >&6 -else - test "$cross_compiling" = yes && - as_fn_error $? "cannot check for file existence when cross compiling" "$LINENO" 5 -if test -r "$dir/$subdir/readline.h"; then - eval "$as_ac_File=yes" -else - eval "$as_ac_File=no" -fi -fi -eval ac_res=\$$as_ac_File - { $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_res" >&5 -$as_echo "$ac_res" >&6; } -if eval test \"x\$"$as_ac_File"\" = x"yes"; then : - found=yes -fi - - if test "$found" = "yes"; then - TARGET_READLINE_INC="-I$dir/$subdir" - break - fi - done - test "$found" = "yes" && break - done - fi - -fi - - - else - TARGET_READLINE_INC="$with_readline_inc" - fi - - if test x"$found" = xno; then - TARGET_READLINE_LIBS="" - TARGET_READLINE_INC="" - TARGET_HAVE_READLINE=0 - else - TARGET_HAVE_READLINE=1 - fi -fi - - - - - - -########## -# Figure out what C libraries are required to compile programs -# that use "fdatasync()" function. -# -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing fdatasync" >&5 -$as_echo_n "checking for library containing fdatasync... " >&6; } -if ${ac_cv_search_fdatasync+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char fdatasync (); -int -main () -{ -return fdatasync (); - ; - return 0; -} -_ACEOF -for ac_lib in '' rt; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_fdatasync=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_fdatasync+:} false; then : - break -fi -done -if ${ac_cv_search_fdatasync+:} false; then : - -else - ac_cv_search_fdatasync=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_fdatasync" >&5 -$as_echo "$ac_cv_search_fdatasync" >&6; } -ac_res=$ac_cv_search_fdatasync -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - - -######### -# check for debug enabled -# Check whether --enable-debug was given. -if test "${enable_debug+set}" = set; then : - enableval=$enable_debug; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking build type" >&5 -$as_echo_n "checking build type... " >&6; } -if test "${enable_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5 -$as_echo "debug" >&6; } -else - TARGET_DEBUG="-DNDEBUG" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: release" >&5 -$as_echo "release" >&6; } -fi - - -######### -# See whether we should use the amalgamation to build - -# Check whether --enable-amalgamation was given. -if test "${enable_amalgamation+set}" = set; then : - enableval=$enable_amalgamation; -fi - -if test "${enable_amalgamation}" = "no" ; then - USE_AMALGAMATION=0 -fi - - -######### -# Look for zlib. Only needed by extensions and by the sqlite3.exe shell -for ac_header in zlib.h -do : - ac_fn_c_check_header_mongrel "$LINENO" "zlib.h" "ac_cv_header_zlib_h" "$ac_includes_default" -if test "x$ac_cv_header_zlib_h" = xyes; then : - cat >>confdefs.h <<_ACEOF -#define HAVE_ZLIB_H 1 -_ACEOF - -fi - -done - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing deflate" >&5 -$as_echo_n "checking for library containing deflate... " >&6; } -if ${ac_cv_search_deflate+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char deflate (); -int -main () -{ -return deflate (); - ; - return 0; -} -_ACEOF -for ac_lib in '' z; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_deflate=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_deflate+:} false; then : - break -fi -done -if ${ac_cv_search_deflate+:} false; then : - -else - ac_cv_search_deflate=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_deflate" >&5 -$as_echo "$ac_cv_search_deflate" >&6; } -ac_res=$ac_cv_search_deflate -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - HAVE_ZLIB="-DSQLITE_HAVE_ZLIB=1" -else - HAVE_ZLIB="" -fi - - - -######### -# See whether we should allow loadable extensions -# Check whether --enable-load-extension was given. -if test "${enable_load_extension+set}" = set; then : - enableval=$enable_load_extension; -else - enable_load_extension=yes -fi - -if test "${enable_load_extension}" = "yes" ; then - OPT_FEATURE_FLAGS="" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing dlopen" >&5 -$as_echo_n "checking for library containing dlopen... " >&6; } -if ${ac_cv_search_dlopen+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char dlopen (); -int -main () -{ -return dlopen (); - ; - return 0; -} -_ACEOF -for ac_lib in '' dl; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_dlopen=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_dlopen+:} false; then : - break -fi -done -if ${ac_cv_search_dlopen+:} false; then : - -else - ac_cv_search_dlopen=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_dlopen" >&5 -$as_echo "$ac_cv_search_dlopen" >&6; } -ac_res=$ac_cv_search_dlopen -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - OPT_FEATURE_FLAGS="-DSQLITE_OMIT_LOAD_EXTENSION=1" -fi - -########## -# Do we want to support math functions -# -# Check whether --enable-math was given. -if test "${enable_math+set}" = set; then : - enableval=$enable_math; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support math functions" >&5 -$as_echo_n "checking whether to support math functions... " >&6; } -if test "$enable_math" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MATH_FUNCTIONS" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing ceil" >&5 -$as_echo_n "checking for library containing ceil... " >&6; } -if ${ac_cv_search_ceil+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char ceil (); -int -main () -{ -return ceil (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_ceil=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_ceil+:} false; then : - break -fi -done -if ${ac_cv_search_ceil+:} false; then : - -else - ac_cv_search_ceil=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_ceil" >&5 -$as_echo "$ac_cv_search_ceil" >&6; } -ac_res=$ac_cv_search_ceil -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -fi - -########## -# Do we want to support JSON functions -# -# Check whether --enable-json was given. -if test "${enable_json+set}" = set; then : - enableval=$enable_json; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support JSON functions" >&5 -$as_echo_n "checking whether to support JSON functions... " >&6; } -if test "$enable_json" = "no"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_OMIT_JSON" -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -fi - -######## -# The --enable-all argument is short-hand to enable -# multiple extensions. -# Check whether --enable-all was given. -if test "${enable_all+set}" = set; then : - enableval=$enable_all; -fi - - -########## -# Do we want to support memsys3 and/or memsys5 -# -# Check whether --enable-memsys5 was given. -if test "${enable_memsys5+set}" = set; then : - enableval=$enable_memsys5; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS5" >&5 -$as_echo_n "checking whether to support MEMSYS5... " >&6; } -if test "${enable_memsys5}" = "yes"; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS5" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -# Check whether --enable-memsys3 was given. -if test "${enable_memsys3+set}" = set; then : - enableval=$enable_memsys3; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support MEMSYS3" >&5 -$as_echo_n "checking whether to support MEMSYS3... " >&6; } -if test "${enable_memsys3}" = "yes" -a "${enable_memsys5}" = "no"; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_MEMSYS3" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable Full Text Search extensions -# Check whether --enable-fts3 was given. -if test "${enable_fts3+set}" = set; then : - enableval=$enable_fts3; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS3" >&5 -$as_echo_n "checking whether to support FTS3... " >&6; } -if test "${enable_fts3}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS3" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -# Check whether --enable-fts4 was given. -if test "${enable_fts4+set}" = set; then : - enableval=$enable_fts4; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS4" >&5 -$as_echo_n "checking whether to support FTS4... " >&6; } -if test "${enable_fts4}" = "yes" -o "${enable_all}" = "yes" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS4" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 -$as_echo_n "checking for library containing log... " >&6; } -if ${ac_cv_search_log+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char log (); -int -main () -{ -return log (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_log=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_log+:} false; then : - break -fi -done -if ${ac_cv_search_log+:} false; then : - -else - ac_cv_search_log=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5 -$as_echo "$ac_cv_search_log" >&6; } -ac_res=$ac_cv_search_log -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi -# Check whether --enable-fts5 was given. -if test "${enable_fts5+set}" = set; then : - enableval=$enable_fts5; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support FTS5" >&5 -$as_echo_n "checking whether to support FTS5... " >&6; } -if test "${enable_fts5}" = "yes" -o "${enable_all}" = "yes" ; then - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_FTS5" - { $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing log" >&5 -$as_echo_n "checking for library containing log... " >&6; } -if ${ac_cv_search_log+:} false; then : - $as_echo_n "(cached) " >&6 -else - ac_func_search_save_LIBS=$LIBS -cat confdefs.h - <<_ACEOF >conftest.$ac_ext -/* end confdefs.h. */ - -/* Override any GCC internal prototype to avoid an error. - Use char because int might match the return type of a GCC - builtin and then its argument prototype would still apply. */ -#ifdef __cplusplus -extern "C" -#endif -char log (); -int -main () -{ -return log (); - ; - return 0; -} -_ACEOF -for ac_lib in '' m; do - if test -z "$ac_lib"; then - ac_res="none required" - else - ac_res=-l$ac_lib - LIBS="-l$ac_lib $ac_func_search_save_LIBS" - fi - if ac_fn_c_try_link "$LINENO"; then : - ac_cv_search_log=$ac_res -fi -rm -f core conftest.err conftest.$ac_objext \ - conftest$ac_exeext - if ${ac_cv_search_log+:} false; then : - break -fi -done -if ${ac_cv_search_log+:} false; then : - -else - ac_cv_search_log=no -fi -rm conftest.$ac_ext -LIBS=$ac_func_search_save_LIBS -fi -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $ac_cv_search_log" >&5 -$as_echo "$ac_cv_search_log" >&6; } -ac_res=$ac_cv_search_log -if test "$ac_res" != no; then : - test "$ac_res" = "none required" || LIBS="$ac_res $LIBS" - -fi - -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable the LIMIT clause on UPDATE and DELETE -# statements. -# Check whether --enable-update-limit was given. -if test "${enable_update_limit+set}" = set; then : - enableval=$enable_update_limit; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support LIMIT on UPDATE and DELETE statements" >&5 -$as_echo_n "checking whether to support LIMIT on UPDATE and DELETE statements... " >&6; } -if test "${enable_update_limit}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable GEOPOLY -# Check whether --enable-geopoly was given. -if test "${enable_geopoly+set}" = set; then : - enableval=$enable_geopoly; enable_geopoly=yes -else - enable_geopoly=no -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support GEOPOLY" >&5 -$as_echo_n "checking whether to support GEOPOLY... " >&6; } -if test "${enable_geopoly}" = "yes" -o "${enable_all}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_GEOPOLY" - enable_rtree=yes - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable RTREE -# Check whether --enable-rtree was given. -if test "${enable_rtree+set}" = set; then : - enableval=$enable_rtree; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support RTREE" >&5 -$as_echo_n "checking whether to support RTREE... " >&6; } -if test "${enable_rtree}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_RTREE" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# See whether we should enable the SESSION extension -# Check whether --enable-session was given. -if test "${enable_session+set}" = set; then : - enableval=$enable_session; -fi - -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether to support SESSION" >&5 -$as_echo_n "checking whether to support SESSION... " >&6; } -if test "${enable_session}" = "yes" -o "${enable_all}" = "yes" ; then - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_SESSION" - OPT_FEATURE_FLAGS="${OPT_FEATURE_FLAGS} -DSQLITE_ENABLE_PREUPDATE_HOOK" - { $as_echo "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -$as_echo "yes" >&6; } -else - { $as_echo "$as_me:${as_lineno-$LINENO}: result: no" >&5 -$as_echo "no" >&6; } -fi - -######### -# attempt to duplicate any OMITS and ENABLES into the ${OPT_FEATURE_FLAGS} parameter -for option in $CFLAGS $CPPFLAGS -do - case $option in - -DSQLITE_OMIT*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - -DSQLITE_ENABLE*) OPT_FEATURE_FLAGS="$OPT_FEATURE_FLAGS $option";; - esac -done - - - -# attempt to remove any OMITS and ENABLES from the $(CFLAGS) parameter -ac_temp_CFLAGS="" -for option in $CFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_CFLAGS="$ac_temp_CFLAGS $option";; - esac -done -CFLAGS=$ac_temp_CFLAGS - - -# attempt to remove any OMITS and ENABLES from the $(CPPFLAGS) parameter -ac_temp_CPPFLAGS="" -for option in $CPPFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_CPPFLAGS="$ac_temp_CPPFLAGS $option";; - esac -done -CPPFLAGS=$ac_temp_CPPFLAGS - - -# attempt to remove any OMITS and ENABLES from the $(BUILD_CFLAGS) parameter -ac_temp_BUILD_CFLAGS="" -for option in $BUILD_CFLAGS -do - case $option in - -DSQLITE_OMIT*) ;; - -DSQLITE_ENABLE*) ;; - *) ac_temp_BUILD_CFLAGS="$ac_temp_BUILD_CFLAGS $option";; - esac -done -BUILD_CFLAGS=$ac_temp_BUILD_CFLAGS - - -######### -# See whether we should use GCOV -# Check whether --enable-gcov was given. -if test "${enable_gcov+set}" = set; then : - enableval=$enable_gcov; -fi - -if test "${use_gcov}" = "yes" ; then - USE_GCOV=1 -else - USE_GCOV=0 -fi - - -######### -# Enable/disabled amalagamation line macros -######## -AMALGAMATION_LINE_MACROS=--linemacros=0 -if test "${amalgamation_line_macros}" = "yes" ; then - AMALGAMATION_LINE_MACROS=--linemacros=1 -fi -if test "${amalgamation_line_macros}" = "no" ; then - AMALGAMATION_LINE_MACROS=--linemacros=0 -fi - - -######### -# Output the config header -ac_config_headers="$ac_config_headers sqlite_cfg.h" - - -######### -# Generate the output files. -# - -ac_config_files="$ac_config_files Makefile sqlite3.pc" - -cat >confcache <<\_ACEOF -# This file is a shell script that caches the results of configure -# tests run on this system so they can be shared between configure -# scripts and configure runs, see configure's option --config-cache. -# It is not useful on other systems. If it contains results you don't -# want to keep, you may remove or edit it. -# -# config.status only pays attention to the cache file if you give it -# the --recheck option to rerun configure. -# -# `ac_cv_env_foo' variables (set or unset) will be overridden when -# loading this file, other *unset* `ac_cv_foo' will be assigned the -# following values. - -_ACEOF - -# The following way of writing the cache mishandles newlines in values, -# but we know of no workaround that is simple, portable, and efficient. -# So, we kill variables containing newlines. -# Ultrix sh set writes to stderr and can't be redirected directly, -# and sets the high bit in the cache file unless we assign to the vars. -( - for ac_var in `(set) 2>&1 | sed -n 's/^\([a-zA-Z_][a-zA-Z0-9_]*\)=.*/\1/p'`; do - eval ac_val=\$$ac_var - case $ac_val in #( - *${as_nl}*) - case $ac_var in #( - *_cv_*) { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: cache variable $ac_var contains a newline" >&5 -$as_echo "$as_me: WARNING: cache variable $ac_var contains a newline" >&2;} ;; - esac - case $ac_var in #( - _ | IFS | as_nl) ;; #( - BASH_ARGV | BASH_SOURCE) eval $ac_var= ;; #( - *) { eval $ac_var=; unset $ac_var;} ;; - esac ;; - esac - done - - (set) 2>&1 | - case $as_nl`(ac_space=' '; set) 2>&1` in #( - *${as_nl}ac_space=\ *) - # `set' does not quote correctly, so add quotes: double-quote - # substitution turns \\\\ into \\, and sed turns \\ into \. - sed -n \ - "s/'/'\\\\''/g; - s/^\\([_$as_cr_alnum]*_cv_[_$as_cr_alnum]*\\)=\\(.*\\)/\\1='\\2'/p" - ;; #( - *) - # `set' quotes correctly as required by POSIX, so do not add quotes. - sed -n "/^[_$as_cr_alnum]*_cv_[_$as_cr_alnum]*=/p" - ;; - esac | - sort -) | - sed ' - /^ac_cv_env_/b end - t clear - :clear - s/^\([^=]*\)=\(.*[{}].*\)$/test "${\1+set}" = set || &/ - t end - s/^\([^=]*\)=\(.*\)$/\1=${\1=\2}/ - :end' >>confcache -if diff "$cache_file" confcache >/dev/null 2>&1; then :; else - if test -w "$cache_file"; then - if test "x$cache_file" != "x/dev/null"; then - { $as_echo "$as_me:${as_lineno-$LINENO}: updating cache $cache_file" >&5 -$as_echo "$as_me: updating cache $cache_file" >&6;} - if test ! -f "$cache_file" || test -h "$cache_file"; then - cat confcache >"$cache_file" - else - case $cache_file in #( - */* | ?:*) - mv -f confcache "$cache_file"$$ && - mv -f "$cache_file"$$ "$cache_file" ;; #( - *) - mv -f confcache "$cache_file" ;; - esac - fi - fi - else - { $as_echo "$as_me:${as_lineno-$LINENO}: not updating unwritable cache $cache_file" >&5 -$as_echo "$as_me: not updating unwritable cache $cache_file" >&6;} - fi -fi -rm -f confcache - -test "x$prefix" = xNONE && prefix=$ac_default_prefix -# Let make expand exec_prefix. -test "x$exec_prefix" = xNONE && exec_prefix='${prefix}' - -DEFS=-DHAVE_CONFIG_H - -ac_libobjs= -ac_ltlibobjs= -U= -for ac_i in : $LIBOBJS; do test "x$ac_i" = x: && continue - # 1. Remove the extension, and $U if already installed. - ac_script='s/\$U\././;s/\.o$//;s/\.obj$//' - ac_i=`$as_echo "$ac_i" | sed "$ac_script"` - # 2. Prepend LIBOBJDIR. When used with automake>=1.10 LIBOBJDIR - # will be set to the directory where LIBOBJS objects are built. - as_fn_append ac_libobjs " \${LIBOBJDIR}$ac_i\$U.$ac_objext" - as_fn_append ac_ltlibobjs " \${LIBOBJDIR}$ac_i"'$U.lo' -done -LIBOBJS=$ac_libobjs - -LTLIBOBJS=$ac_ltlibobjs - - - -: "${CONFIG_STATUS=./config.status}" -ac_write_fail=0 -ac_clean_files_save=$ac_clean_files -ac_clean_files="$ac_clean_files $CONFIG_STATUS" -{ $as_echo "$as_me:${as_lineno-$LINENO}: creating $CONFIG_STATUS" >&5 -$as_echo "$as_me: creating $CONFIG_STATUS" >&6;} -as_write_fail=0 -cat >$CONFIG_STATUS <<_ASEOF || as_write_fail=1 -#! $SHELL -# Generated by $as_me. -# Run this file to recreate the current configuration. -# Compiler output produced by configure, useful for debugging -# configure, is in config.log if it exists. - -debug=false -ac_cs_recheck=false -ac_cs_silent=false - -SHELL=\${CONFIG_SHELL-$SHELL} -export SHELL -_ASEOF -cat >>$CONFIG_STATUS <<\_ASEOF || as_write_fail=1 -## -------------------- ## -## M4sh Initialization. ## -## -------------------- ## - -# Be more Bourne compatible -DUALCASE=1; export DUALCASE # for MKS sh -if test -n "${ZSH_VERSION+set}" && (emulate sh) >/dev/null 2>&1; then : - emulate sh - NULLCMD=: - # Pre-4.2 versions of Zsh do word splitting on ${1+"$@"}, which - # is contrary to our usage. Disable this feature. - alias -g '${1+"$@"}'='"$@"' - setopt NO_GLOB_SUBST -else - case `(set -o) 2>/dev/null` in #( - *posix*) : - set -o posix ;; #( - *) : - ;; -esac -fi - - -as_nl=' -' -export as_nl -# Printing a long string crashes Solaris 7 /usr/bin/printf. -as_echo='\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\\' -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo -as_echo=$as_echo$as_echo$as_echo$as_echo$as_echo$as_echo -# Prefer a ksh shell builtin over an external printf program on Solaris, -# but without wasting forks for bash or zsh. -if test -z "$BASH_VERSION$ZSH_VERSION" \ - && (test "X`print -r -- $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='print -r --' - as_echo_n='print -rn --' -elif (test "X`printf %s $as_echo`" = "X$as_echo") 2>/dev/null; then - as_echo='printf %s\n' - as_echo_n='printf %s' -else - if test "X`(/usr/ucb/echo -n -n $as_echo) 2>/dev/null`" = "X-n $as_echo"; then - as_echo_body='eval /usr/ucb/echo -n "$1$as_nl"' - as_echo_n='/usr/ucb/echo -n' - else - as_echo_body='eval expr "X$1" : "X\\(.*\\)"' - as_echo_n_body='eval - arg=$1; - case $arg in #( - *"$as_nl"*) - expr "X$arg" : "X\\(.*\\)$as_nl"; - arg=`expr "X$arg" : ".*$as_nl\\(.*\\)"`;; - esac; - expr "X$arg" : "X\\(.*\\)" | tr -d "$as_nl" - ' - export as_echo_n_body - as_echo_n='sh -c $as_echo_n_body as_echo' - fi - export as_echo_body - as_echo='sh -c $as_echo_body as_echo' -fi - -# The user is always right. -if test "${PATH_SEPARATOR+set}" != set; then - PATH_SEPARATOR=: - (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { - (PATH='/bin:/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 || - PATH_SEPARATOR=';' - } -fi - - -# IFS -# We need space, tab and new line, in precisely that order. Quoting is -# there to prevent editors from complaining about space-tab. -# (If _AS_PATH_WALK were called with IFS unset, it would disable word -# splitting by setting IFS to empty value.) -IFS=" "" $as_nl" - -# Find who we are. Look in the path if we contain no directory separator. -as_myself= -case $0 in #(( - *[\\/]* ) as_myself=$0 ;; - *) as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - test -r "$as_dir/$0" && as_myself=$as_dir/$0 && break - done -IFS=$as_save_IFS - - ;; -esac -# We did not find ourselves, most probably we were run as `sh COMMAND' -# in which case we are not to be found in the path. -if test "x$as_myself" = x; then - as_myself=$0 -fi -if test ! -f "$as_myself"; then - $as_echo "$as_myself: error: cannot find myself; rerun with an absolute file name" >&2 - exit 1 -fi - -# Unset variables that we do not need and which cause bugs (e.g. in -# pre-3.0 UWIN ksh). But do not cause bugs in bash 2.01; the "|| exit 1" -# suppresses any "Segmentation fault" message there. '((' could -# trigger a bug in pdksh 5.2.14. -for as_var in BASH_ENV ENV MAIL MAILPATH -do eval test x\${$as_var+set} = xset \ - && ( (unset $as_var) || exit 1) >/dev/null 2>&1 && unset $as_var || : -done -PS1='$ ' -PS2='> ' -PS4='+ ' - -# NLS nuisances. -LC_ALL=C -export LC_ALL -LANGUAGE=C -export LANGUAGE - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - - -# as_fn_error STATUS ERROR [LINENO LOG_FD] -# ---------------------------------------- -# Output "`basename $0`: error: ERROR" to stderr. If LINENO and LOG_FD are -# provided, also output the error to LOG_FD, referencing LINENO. Then exit the -# script with STATUS, using 1 if that was 0. -as_fn_error () -{ - as_status=$1; test $as_status -eq 0 && as_status=1 - if test "$4"; then - as_lineno=${as_lineno-"$3"} as_lineno_stack=as_lineno_stack=$as_lineno_stack - $as_echo "$as_me:${as_lineno-$LINENO}: error: $2" >&$4 - fi - $as_echo "$as_me: error: $2" >&2 - as_fn_exit $as_status -} # as_fn_error - - -# as_fn_set_status STATUS -# ----------------------- -# Set $? to STATUS, without forking. -as_fn_set_status () -{ - return $1 -} # as_fn_set_status - -# as_fn_exit STATUS -# ----------------- -# Exit the shell with STATUS, even in a "trap 0" or "set -e" context. -as_fn_exit () -{ - set +e - as_fn_set_status $1 - exit $1 -} # as_fn_exit - -# as_fn_unset VAR -# --------------- -# Portably unset VAR. -as_fn_unset () -{ - { eval $1=; unset $1;} -} -as_unset=as_fn_unset -# as_fn_append VAR VALUE -# ---------------------- -# Append the text in VALUE to the end of the definition contained in VAR. Take -# advantage of any shell optimizations that allow amortized linear growth over -# repeated appends, instead of the typical quadratic growth present in naive -# implementations. -if (eval "as_var=1; as_var+=2; test x\$as_var = x12") 2>/dev/null; then : - eval 'as_fn_append () - { - eval $1+=\$2 - }' -else - as_fn_append () - { - eval $1=\$$1\$2 - } -fi # as_fn_append - -# as_fn_arith ARG... -# ------------------ -# Perform arithmetic evaluation on the ARGs, and store the result in the -# global $as_val. Take advantage of shells that can avoid forks. The arguments -# must be portable across $(()) and expr. -if (eval "test \$(( 1 + 1 )) = 2") 2>/dev/null; then : - eval 'as_fn_arith () - { - as_val=$(( $* )) - }' -else - as_fn_arith () - { - as_val=`expr "$@" || test $? -eq 1` - } -fi # as_fn_arith - - -if expr a : '\(a\)' >/dev/null 2>&1 && - test "X`expr 00001 : '.*\(...\)'`" = X001; then - as_expr=expr -else - as_expr=false -fi - -if (basename -- /) >/dev/null 2>&1 && test "X`basename -- / 2>&1`" = "X/"; then - as_basename=basename -else - as_basename=false -fi - -if (as_dir=`dirname -- /` && test "X$as_dir" = X/) >/dev/null 2>&1; then - as_dirname=dirname -else - as_dirname=false -fi - -as_me=`$as_basename -- "$0" || -$as_expr X/"$0" : '.*/\([^/][^/]*\)/*$' \| \ - X"$0" : 'X\(//\)$' \| \ - X"$0" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X/"$0" | - sed '/^.*\/\([^/][^/]*\)\/*$/{ - s//\1/ - q - } - /^X\/\(\/\/\)$/{ - s//\1/ - q - } - /^X\/\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - -# Avoid depending upon Character Ranges. -as_cr_letters='abcdefghijklmnopqrstuvwxyz' -as_cr_LETTERS='ABCDEFGHIJKLMNOPQRSTUVWXYZ' -as_cr_Letters=$as_cr_letters$as_cr_LETTERS -as_cr_digits='0123456789' -as_cr_alnum=$as_cr_Letters$as_cr_digits - -ECHO_C= ECHO_N= ECHO_T= -case `echo -n x` in #((((( --n*) - case `echo 'xy\c'` in - *c*) ECHO_T=' ';; # ECHO_T is single tab character. - xy) ECHO_C='\c';; - *) echo `echo ksh88 bug on AIX 6.1` > /dev/null - ECHO_T=' ';; - esac;; -*) - ECHO_N='-n';; -esac - -rm -f conf$$ conf$$.exe conf$$.file -if test -d conf$$.dir; then - rm -f conf$$.dir/conf$$.file -else - rm -f conf$$.dir - mkdir conf$$.dir 2>/dev/null -fi -if (echo >conf$$.file) 2>/dev/null; then - if ln -s conf$$.file conf$$ 2>/dev/null; then - as_ln_s='ln -s' - # ... but there are two gotchas: - # 1) On MSYS, both `ln -s file dir' and `ln file dir' fail. - # 2) DJGPP < 2.04 has no symlinks; `ln -s' creates a wrapper executable. - # In both cases, we have to default to `cp -pR'. - ln -s conf$$.file conf$$.dir 2>/dev/null && test ! -f conf$$.exe || - as_ln_s='cp -pR' - elif ln conf$$.file conf$$ 2>/dev/null; then - as_ln_s=ln - else - as_ln_s='cp -pR' - fi -else - as_ln_s='cp -pR' -fi -rm -f conf$$ conf$$.exe conf$$.dir/conf$$.file conf$$.file -rmdir conf$$.dir 2>/dev/null - - -# as_fn_mkdir_p -# ------------- -# Create "$as_dir" as a directory, including parents if necessary. -as_fn_mkdir_p () -{ - - case $as_dir in #( - -*) as_dir=./$as_dir;; - esac - test -d "$as_dir" || eval $as_mkdir_p || { - as_dirs= - while :; do - case $as_dir in #( - *\'*) as_qdir=`$as_echo "$as_dir" | sed "s/'/'\\\\\\\\''/g"`;; #'( - *) as_qdir=$as_dir;; - esac - as_dirs="'$as_qdir' $as_dirs" - as_dir=`$as_dirname -- "$as_dir" || -$as_expr X"$as_dir" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$as_dir" : 'X\(//\)[^/]' \| \ - X"$as_dir" : 'X\(//\)$' \| \ - X"$as_dir" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$as_dir" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - test -d "$as_dir" && break - done - test -z "$as_dirs" || eval "mkdir $as_dirs" - } || test -d "$as_dir" || as_fn_error $? "cannot create directory $as_dir" - - -} # as_fn_mkdir_p -if mkdir -p . 2>/dev/null; then - as_mkdir_p='mkdir -p "$as_dir"' -else - test -d ./-p && rmdir ./-p - as_mkdir_p=false -fi - - -# as_fn_executable_p FILE -# ----------------------- -# Test if FILE is an executable regular file. -as_fn_executable_p () -{ - test -f "$1" && test -x "$1" -} # as_fn_executable_p -as_test_x='test -x' -as_executable_p=as_fn_executable_p - -# Sed expression to map a string onto a valid CPP name. -as_tr_cpp="eval sed 'y%*$as_cr_letters%P$as_cr_LETTERS%;s%[^_$as_cr_alnum]%_%g'" - -# Sed expression to map a string onto a valid variable name. -as_tr_sh="eval sed 'y%*+%pp%;s%[^_$as_cr_alnum]%_%g'" - - -exec 6>&1 -## ----------------------------------- ## -## Main body of $CONFIG_STATUS script. ## -## ----------------------------------- ## -_ASEOF -test $as_write_fail = 0 && chmod +x $CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# Save the log message, to keep $0 and so on meaningful, and to -# report actual input values of CONFIG_FILES etc. instead of their -# values after options handling. -ac_log=" -This file was extended by sqlite $as_me 3.42.0, which was -generated by GNU Autoconf 2.69. Invocation command line was - - CONFIG_FILES = $CONFIG_FILES - CONFIG_HEADERS = $CONFIG_HEADERS - CONFIG_LINKS = $CONFIG_LINKS - CONFIG_COMMANDS = $CONFIG_COMMANDS - $ $0 $@ - -on `(hostname || uname -n) 2>/dev/null | sed 1q` -" - -_ACEOF - -case $ac_config_files in *" -"*) set x $ac_config_files; shift; ac_config_files=$*;; -esac - -case $ac_config_headers in *" -"*) set x $ac_config_headers; shift; ac_config_headers=$*;; -esac - - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# Files that config.status was made for. -config_files="$ac_config_files" -config_headers="$ac_config_headers" -config_commands="$ac_config_commands" - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -ac_cs_usage="\ -\`$as_me' instantiates files and other configuration actions -from templates according to the current configuration. Unless the files -and actions are specified as TAGs, all are instantiated by default. - -Usage: $0 [OPTION]... [TAG]... - - -h, --help print this help, then exit - -V, --version print version number and configuration settings, then exit - --config print configuration, then exit - -q, --quiet, --silent - do not print progress messages - -d, --debug don't remove temporary files - --recheck update $as_me by reconfiguring in the same conditions - --file=FILE[:TEMPLATE] - instantiate the configuration file FILE - --header=FILE[:TEMPLATE] - instantiate the configuration header FILE - -Configuration files: -$config_files - -Configuration headers: -$config_headers - -Configuration commands: -$config_commands - -Report bugs to the package provider." - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`" -ac_cs_version="\\ -sqlite config.status 3.42.0 -configured by $0, generated by GNU Autoconf 2.69, - with options \\"\$ac_cs_config\\" - -Copyright (C) 2012 Free Software Foundation, Inc. -This config.status script is free software; the Free Software Foundation -gives unlimited permission to copy, distribute and modify it." - -ac_pwd='$ac_pwd' -srcdir='$srcdir' -INSTALL='$INSTALL' -test -n "\$AWK" || AWK=awk -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# The default lists apply if the user does not specify any file. -ac_need_defaults=: -while test $# != 0 -do - case $1 in - --*=?*) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg=`expr "X$1" : 'X[^=]*=\(.*\)'` - ac_shift=: - ;; - --*=) - ac_option=`expr "X$1" : 'X\([^=]*\)='` - ac_optarg= - ac_shift=: - ;; - *) - ac_option=$1 - ac_optarg=$2 - ac_shift=shift - ;; - esac - - case $ac_option in - # Handling of the options. - -recheck | --recheck | --rechec | --reche | --rech | --rec | --re | --r) - ac_cs_recheck=: ;; - --version | --versio | --versi | --vers | --ver | --ve | --v | -V ) - $as_echo "$ac_cs_version"; exit ;; - --config | --confi | --conf | --con | --co | --c ) - $as_echo "$ac_cs_config"; exit ;; - --debug | --debu | --deb | --de | --d | -d ) - debug=: ;; - --file | --fil | --fi | --f ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - '') as_fn_error $? "missing file argument" ;; - esac - as_fn_append CONFIG_FILES " '$ac_optarg'" - ac_need_defaults=false;; - --header | --heade | --head | --hea ) - $ac_shift - case $ac_optarg in - *\'*) ac_optarg=`$as_echo "$ac_optarg" | sed "s/'/'\\\\\\\\''/g"` ;; - esac - as_fn_append CONFIG_HEADERS " '$ac_optarg'" - ac_need_defaults=false;; - --he | --h) - # Conflict between --help and --header - as_fn_error $? "ambiguous option: \`$1' -Try \`$0 --help' for more information.";; - --help | --hel | -h ) - $as_echo "$ac_cs_usage"; exit ;; - -q | -quiet | --quiet | --quie | --qui | --qu | --q \ - | -silent | --silent | --silen | --sile | --sil | --si | --s) - ac_cs_silent=: ;; - - # This is an error. - -*) as_fn_error $? "unrecognized option: \`$1' -Try \`$0 --help' for more information." ;; - - *) as_fn_append ac_config_targets " $1" - ac_need_defaults=false ;; - - esac - shift -done - -ac_configure_extra_args= - -if $ac_cs_silent; then - exec 6>/dev/null - ac_configure_extra_args="$ac_configure_extra_args --silent" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -if \$ac_cs_recheck; then - set X $SHELL '$0' $ac_configure_args \$ac_configure_extra_args --no-create --no-recursion - shift - \$as_echo "running CONFIG_SHELL=$SHELL \$*" >&6 - CONFIG_SHELL='$SHELL' - export CONFIG_SHELL - exec "\$@" -fi - -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -exec 5>>config.log -{ - echo - sed 'h;s/./-/g;s/^.../## /;s/...$/ ##/;p;x;p;x' <<_ASBOX -## Running $as_me. ## -_ASBOX - $as_echo "$ac_log" -} >&5 - -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -# -# INIT-COMMANDS -# - - -# The HP-UX ksh and POSIX shell print the target directory to stdout -# if CDPATH is set. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH - -sed_quote_subst='$sed_quote_subst' -double_quote_subst='$double_quote_subst' -delay_variable_subst='$delay_variable_subst' -macro_version='`$ECHO "X$macro_version" | $Xsed -e "$delay_single_quote_subst"`' -macro_revision='`$ECHO "X$macro_revision" | $Xsed -e "$delay_single_quote_subst"`' -enable_shared='`$ECHO "X$enable_shared" | $Xsed -e "$delay_single_quote_subst"`' -enable_static='`$ECHO "X$enable_static" | $Xsed -e "$delay_single_quote_subst"`' -pic_mode='`$ECHO "X$pic_mode" | $Xsed -e "$delay_single_quote_subst"`' -enable_fast_install='`$ECHO "X$enable_fast_install" | $Xsed -e "$delay_single_quote_subst"`' -host_alias='`$ECHO "X$host_alias" | $Xsed -e "$delay_single_quote_subst"`' -host='`$ECHO "X$host" | $Xsed -e "$delay_single_quote_subst"`' -host_os='`$ECHO "X$host_os" | $Xsed -e "$delay_single_quote_subst"`' -build_alias='`$ECHO "X$build_alias" | $Xsed -e "$delay_single_quote_subst"`' -build='`$ECHO "X$build" | $Xsed -e "$delay_single_quote_subst"`' -build_os='`$ECHO "X$build_os" | $Xsed -e "$delay_single_quote_subst"`' -SED='`$ECHO "X$SED" | $Xsed -e "$delay_single_quote_subst"`' -Xsed='`$ECHO "X$Xsed" | $Xsed -e "$delay_single_quote_subst"`' -GREP='`$ECHO "X$GREP" | $Xsed -e "$delay_single_quote_subst"`' -EGREP='`$ECHO "X$EGREP" | $Xsed -e "$delay_single_quote_subst"`' -FGREP='`$ECHO "X$FGREP" | $Xsed -e "$delay_single_quote_subst"`' -LD='`$ECHO "X$LD" | $Xsed -e "$delay_single_quote_subst"`' -NM='`$ECHO "X$NM" | $Xsed -e "$delay_single_quote_subst"`' -LN_S='`$ECHO "X$LN_S" | $Xsed -e "$delay_single_quote_subst"`' -max_cmd_len='`$ECHO "X$max_cmd_len" | $Xsed -e "$delay_single_quote_subst"`' -ac_objext='`$ECHO "X$ac_objext" | $Xsed -e "$delay_single_quote_subst"`' -exeext='`$ECHO "X$exeext" | $Xsed -e "$delay_single_quote_subst"`' -lt_unset='`$ECHO "X$lt_unset" | $Xsed -e "$delay_single_quote_subst"`' -lt_SP2NL='`$ECHO "X$lt_SP2NL" | $Xsed -e "$delay_single_quote_subst"`' -lt_NL2SP='`$ECHO "X$lt_NL2SP" | $Xsed -e "$delay_single_quote_subst"`' -reload_flag='`$ECHO "X$reload_flag" | $Xsed -e "$delay_single_quote_subst"`' -reload_cmds='`$ECHO "X$reload_cmds" | $Xsed -e "$delay_single_quote_subst"`' -OBJDUMP='`$ECHO "X$OBJDUMP" | $Xsed -e "$delay_single_quote_subst"`' -deplibs_check_method='`$ECHO "X$deplibs_check_method" | $Xsed -e "$delay_single_quote_subst"`' -file_magic_cmd='`$ECHO "X$file_magic_cmd" | $Xsed -e "$delay_single_quote_subst"`' -AR='`$ECHO "X$AR" | $Xsed -e "$delay_single_quote_subst"`' -AR_FLAGS='`$ECHO "X$AR_FLAGS" | $Xsed -e "$delay_single_quote_subst"`' -STRIP='`$ECHO "X$STRIP" | $Xsed -e "$delay_single_quote_subst"`' -RANLIB='`$ECHO "X$RANLIB" | $Xsed -e "$delay_single_quote_subst"`' -old_postinstall_cmds='`$ECHO "X$old_postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -old_postuninstall_cmds='`$ECHO "X$old_postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -old_archive_cmds='`$ECHO "X$old_archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' -CC='`$ECHO "X$CC" | $Xsed -e "$delay_single_quote_subst"`' -CFLAGS='`$ECHO "X$CFLAGS" | $Xsed -e "$delay_single_quote_subst"`' -compiler='`$ECHO "X$compiler" | $Xsed -e "$delay_single_quote_subst"`' -GCC='`$ECHO "X$GCC" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_pipe='`$ECHO "X$lt_cv_sys_global_symbol_pipe" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_cdecl='`$ECHO "X$lt_cv_sys_global_symbol_to_cdecl" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix='`$ECHO "X$lt_cv_sys_global_symbol_to_c_name_address_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' -objdir='`$ECHO "X$objdir" | $Xsed -e "$delay_single_quote_subst"`' -SHELL='`$ECHO "X$SHELL" | $Xsed -e "$delay_single_quote_subst"`' -ECHO='`$ECHO "X$ECHO" | $Xsed -e "$delay_single_quote_subst"`' -MAGIC_CMD='`$ECHO "X$MAGIC_CMD" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_no_builtin_flag='`$ECHO "X$lt_prog_compiler_no_builtin_flag" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_wl='`$ECHO "X$lt_prog_compiler_wl" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_pic='`$ECHO "X$lt_prog_compiler_pic" | $Xsed -e "$delay_single_quote_subst"`' -lt_prog_compiler_static='`$ECHO "X$lt_prog_compiler_static" | $Xsed -e "$delay_single_quote_subst"`' -lt_cv_prog_compiler_c_o='`$ECHO "X$lt_cv_prog_compiler_c_o" | $Xsed -e "$delay_single_quote_subst"`' -need_locks='`$ECHO "X$need_locks" | $Xsed -e "$delay_single_quote_subst"`' -DSYMUTIL='`$ECHO "X$DSYMUTIL" | $Xsed -e "$delay_single_quote_subst"`' -NMEDIT='`$ECHO "X$NMEDIT" | $Xsed -e "$delay_single_quote_subst"`' -LIPO='`$ECHO "X$LIPO" | $Xsed -e "$delay_single_quote_subst"`' -OTOOL='`$ECHO "X$OTOOL" | $Xsed -e "$delay_single_quote_subst"`' -OTOOL64='`$ECHO "X$OTOOL64" | $Xsed -e "$delay_single_quote_subst"`' -libext='`$ECHO "X$libext" | $Xsed -e "$delay_single_quote_subst"`' -shrext_cmds='`$ECHO "X$shrext_cmds" | $Xsed -e "$delay_single_quote_subst"`' -extract_expsyms_cmds='`$ECHO "X$extract_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' -archive_cmds_need_lc='`$ECHO "X$archive_cmds_need_lc" | $Xsed -e "$delay_single_quote_subst"`' -enable_shared_with_static_runtimes='`$ECHO "X$enable_shared_with_static_runtimes" | $Xsed -e "$delay_single_quote_subst"`' -export_dynamic_flag_spec='`$ECHO "X$export_dynamic_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' -whole_archive_flag_spec='`$ECHO "X$whole_archive_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' -compiler_needs_object='`$ECHO "X$compiler_needs_object" | $Xsed -e "$delay_single_quote_subst"`' -old_archive_from_new_cmds='`$ECHO "X$old_archive_from_new_cmds" | $Xsed -e "$delay_single_quote_subst"`' -old_archive_from_expsyms_cmds='`$ECHO "X$old_archive_from_expsyms_cmds" | $Xsed -e "$delay_single_quote_subst"`' -archive_cmds='`$ECHO "X$archive_cmds" | $Xsed -e "$delay_single_quote_subst"`' -archive_expsym_cmds='`$ECHO "X$archive_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' -module_cmds='`$ECHO "X$module_cmds" | $Xsed -e "$delay_single_quote_subst"`' -module_expsym_cmds='`$ECHO "X$module_expsym_cmds" | $Xsed -e "$delay_single_quote_subst"`' -with_gnu_ld='`$ECHO "X$with_gnu_ld" | $Xsed -e "$delay_single_quote_subst"`' -allow_undefined_flag='`$ECHO "X$allow_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' -no_undefined_flag='`$ECHO "X$no_undefined_flag" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec='`$ECHO "X$hardcode_libdir_flag_spec" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_libdir_flag_spec_ld='`$ECHO "X$hardcode_libdir_flag_spec_ld" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_libdir_separator='`$ECHO "X$hardcode_libdir_separator" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_direct='`$ECHO "X$hardcode_direct" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_direct_absolute='`$ECHO "X$hardcode_direct_absolute" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_minus_L='`$ECHO "X$hardcode_minus_L" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_shlibpath_var='`$ECHO "X$hardcode_shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_automatic='`$ECHO "X$hardcode_automatic" | $Xsed -e "$delay_single_quote_subst"`' -inherit_rpath='`$ECHO "X$inherit_rpath" | $Xsed -e "$delay_single_quote_subst"`' -link_all_deplibs='`$ECHO "X$link_all_deplibs" | $Xsed -e "$delay_single_quote_subst"`' -fix_srcfile_path='`$ECHO "X$fix_srcfile_path" | $Xsed -e "$delay_single_quote_subst"`' -always_export_symbols='`$ECHO "X$always_export_symbols" | $Xsed -e "$delay_single_quote_subst"`' -export_symbols_cmds='`$ECHO "X$export_symbols_cmds" | $Xsed -e "$delay_single_quote_subst"`' -exclude_expsyms='`$ECHO "X$exclude_expsyms" | $Xsed -e "$delay_single_quote_subst"`' -include_expsyms='`$ECHO "X$include_expsyms" | $Xsed -e "$delay_single_quote_subst"`' -prelink_cmds='`$ECHO "X$prelink_cmds" | $Xsed -e "$delay_single_quote_subst"`' -file_list_spec='`$ECHO "X$file_list_spec" | $Xsed -e "$delay_single_quote_subst"`' -variables_saved_for_relink='`$ECHO "X$variables_saved_for_relink" | $Xsed -e "$delay_single_quote_subst"`' -need_lib_prefix='`$ECHO "X$need_lib_prefix" | $Xsed -e "$delay_single_quote_subst"`' -need_version='`$ECHO "X$need_version" | $Xsed -e "$delay_single_quote_subst"`' -version_type='`$ECHO "X$version_type" | $Xsed -e "$delay_single_quote_subst"`' -runpath_var='`$ECHO "X$runpath_var" | $Xsed -e "$delay_single_quote_subst"`' -shlibpath_var='`$ECHO "X$shlibpath_var" | $Xsed -e "$delay_single_quote_subst"`' -shlibpath_overrides_runpath='`$ECHO "X$shlibpath_overrides_runpath" | $Xsed -e "$delay_single_quote_subst"`' -libname_spec='`$ECHO "X$libname_spec" | $Xsed -e "$delay_single_quote_subst"`' -library_names_spec='`$ECHO "X$library_names_spec" | $Xsed -e "$delay_single_quote_subst"`' -soname_spec='`$ECHO "X$soname_spec" | $Xsed -e "$delay_single_quote_subst"`' -postinstall_cmds='`$ECHO "X$postinstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -postuninstall_cmds='`$ECHO "X$postuninstall_cmds" | $Xsed -e "$delay_single_quote_subst"`' -finish_cmds='`$ECHO "X$finish_cmds" | $Xsed -e "$delay_single_quote_subst"`' -finish_eval='`$ECHO "X$finish_eval" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_into_libs='`$ECHO "X$hardcode_into_libs" | $Xsed -e "$delay_single_quote_subst"`' -sys_lib_search_path_spec='`$ECHO "X$sys_lib_search_path_spec" | $Xsed -e "$delay_single_quote_subst"`' -sys_lib_dlsearch_path_spec='`$ECHO "X$sys_lib_dlsearch_path_spec" | $Xsed -e "$delay_single_quote_subst"`' -hardcode_action='`$ECHO "X$hardcode_action" | $Xsed -e "$delay_single_quote_subst"`' -enable_dlopen='`$ECHO "X$enable_dlopen" | $Xsed -e "$delay_single_quote_subst"`' -enable_dlopen_self='`$ECHO "X$enable_dlopen_self" | $Xsed -e "$delay_single_quote_subst"`' -enable_dlopen_self_static='`$ECHO "X$enable_dlopen_self_static" | $Xsed -e "$delay_single_quote_subst"`' -old_striplib='`$ECHO "X$old_striplib" | $Xsed -e "$delay_single_quote_subst"`' -striplib='`$ECHO "X$striplib" | $Xsed -e "$delay_single_quote_subst"`' - -LTCC='$LTCC' -LTCFLAGS='$LTCFLAGS' -compiler='$compiler_DEFAULT' - -# Quote evaled strings. -for var in SED \ -GREP \ -EGREP \ -FGREP \ -LD \ -NM \ -LN_S \ -lt_SP2NL \ -lt_NL2SP \ -reload_flag \ -OBJDUMP \ -deplibs_check_method \ -file_magic_cmd \ -AR \ -AR_FLAGS \ -STRIP \ -RANLIB \ -CC \ -CFLAGS \ -compiler \ -lt_cv_sys_global_symbol_pipe \ -lt_cv_sys_global_symbol_to_cdecl \ -lt_cv_sys_global_symbol_to_c_name_address \ -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix \ -SHELL \ -ECHO \ -lt_prog_compiler_no_builtin_flag \ -lt_prog_compiler_wl \ -lt_prog_compiler_pic \ -lt_prog_compiler_static \ -lt_cv_prog_compiler_c_o \ -need_locks \ -DSYMUTIL \ -NMEDIT \ -LIPO \ -OTOOL \ -OTOOL64 \ -shrext_cmds \ -export_dynamic_flag_spec \ -whole_archive_flag_spec \ -compiler_needs_object \ -with_gnu_ld \ -allow_undefined_flag \ -no_undefined_flag \ -hardcode_libdir_flag_spec \ -hardcode_libdir_flag_spec_ld \ -hardcode_libdir_separator \ -fix_srcfile_path \ -exclude_expsyms \ -include_expsyms \ -file_list_spec \ -variables_saved_for_relink \ -libname_spec \ -library_names_spec \ -soname_spec \ -finish_eval \ -old_striplib \ -striplib; do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$sed_quote_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Double-quote double-evaled strings. -for var in reload_cmds \ -old_postinstall_cmds \ -old_postuninstall_cmds \ -old_archive_cmds \ -extract_expsyms_cmds \ -old_archive_from_new_cmds \ -old_archive_from_expsyms_cmds \ -archive_cmds \ -archive_expsym_cmds \ -module_cmds \ -module_expsym_cmds \ -export_symbols_cmds \ -prelink_cmds \ -postinstall_cmds \ -postuninstall_cmds \ -finish_cmds \ -sys_lib_search_path_spec \ -sys_lib_dlsearch_path_spec; do - case \`eval \\\\\$ECHO "X\\\\\$\$var"\` in - *[\\\\\\\`\\"\\\$]*) - eval "lt_\$var=\\\\\\"\\\`\\\$ECHO \\"X\\\$\$var\\" | \\\$Xsed -e \\"\\\$double_quote_subst\\" -e \\"\\\$sed_quote_subst\\" -e \\"\\\$delay_variable_subst\\"\\\`\\\\\\"" - ;; - *) - eval "lt_\$var=\\\\\\"\\\$\$var\\\\\\"" - ;; - esac -done - -# Fix-up fallback echo if it was mangled by the above quoting rules. -case \$lt_ECHO in -*'\\\$0 --fallback-echo"') lt_ECHO=\`\$ECHO "X\$lt_ECHO" | \$Xsed -e 's/\\\\\\\\\\\\\\\$0 --fallback-echo"\$/\$0 --fallback-echo"/'\` - ;; -esac - -ac_aux_dir='$ac_aux_dir' -xsi_shell='$xsi_shell' -lt_shell_append='$lt_shell_append' - -# See if we are running on zsh, and set the options which allow our -# commands through without removal of \ escapes INIT. -if test -n "\${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST -fi - - - PACKAGE='$PACKAGE' - VERSION='$VERSION' - TIMESTAMP='$TIMESTAMP' - RM='$RM' - ofile='$ofile' - - - - -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - -# Handling of arguments. -for ac_config_target in $ac_config_targets -do - case $ac_config_target in - "libtool") CONFIG_COMMANDS="$CONFIG_COMMANDS libtool" ;; - "sqlite_cfg.h") CONFIG_HEADERS="$CONFIG_HEADERS sqlite_cfg.h" ;; - "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;; - "sqlite3.pc") CONFIG_FILES="$CONFIG_FILES sqlite3.pc" ;; - - *) as_fn_error $? "invalid argument: \`$ac_config_target'" "$LINENO" 5;; - esac -done - - -# If the user did not use the arguments to specify the items to instantiate, -# then the envvar interface is used. Set only those that are not. -# We use the long form for the default assignment because of an extremely -# bizarre bug on SunOS 4.1.3. -if $ac_need_defaults; then - test "${CONFIG_FILES+set}" = set || CONFIG_FILES=$config_files - test "${CONFIG_HEADERS+set}" = set || CONFIG_HEADERS=$config_headers - test "${CONFIG_COMMANDS+set}" = set || CONFIG_COMMANDS=$config_commands -fi - -# Have a temporary directory for convenience. Make it in the build tree -# simply because there is no reason against having it here, and in addition, -# creating and moving files from /tmp can sometimes cause problems. -# Hook for its removal unless debugging. -# Note that there is a small window in which the directory will not be cleaned: -# after its creation but before its name has been assigned to `$tmp'. -$debug || -{ - tmp= ac_tmp= - trap 'exit_status=$? - : "${ac_tmp:=$tmp}" - { test ! -d "$ac_tmp" || rm -fr "$ac_tmp"; } && exit $exit_status -' 0 - trap 'as_fn_exit 1' 1 2 13 15 -} -# Create a (secure) tmp directory for tmp files. - -{ - tmp=`(umask 077 && mktemp -d "./confXXXXXX") 2>/dev/null` && - test -d "$tmp" -} || -{ - tmp=./conf$$-$RANDOM - (umask 077 && mkdir "$tmp") -} || as_fn_error $? "cannot create a temporary directory in ." "$LINENO" 5 -ac_tmp=$tmp - -# Set up the scripts for CONFIG_FILES section. -# No need to generate them if there are no CONFIG_FILES. -# This happens for instance with `./config.status config.h'. -if test -n "$CONFIG_FILES"; then - - -ac_cr=`echo X | tr X '\015'` -# On cygwin, bash can eat \r inside `` if the user requested igncr. -# But we know of no other shell where ac_cr would be empty at this -# point, so we can use a bashism as a fallback. -if test "x$ac_cr" = x; then - eval ac_cr=\$\'\\r\' -fi -ac_cs_awk_cr=`$AWK 'BEGIN { print "a\rb" }' /dev/null` -if test "$ac_cs_awk_cr" = "a${ac_cr}b"; then - ac_cs_awk_cr='\\r' -else - ac_cs_awk_cr=$ac_cr -fi - -echo 'BEGIN {' >"$ac_tmp/subs1.awk" && -_ACEOF - - -{ - echo "cat >conf$$subs.awk <<_ACEOF" && - echo "$ac_subst_vars" | sed 's/.*/&!$&$ac_delim/' && - echo "_ACEOF" -} >conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 -ac_delim_num=`echo "$ac_subst_vars" | grep -c '^'` -ac_delim='%!_!# ' -for ac_last_try in false false false false false :; do - . ./conf$$subs.sh || - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - - ac_delim_n=`sed -n "s/.*$ac_delim\$/X/p" conf$$subs.awk | grep -c X` - if test $ac_delim_n = $ac_delim_num; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_STATUS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done -rm -f conf$$subs.sh - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -cat >>"\$ac_tmp/subs1.awk" <<\\_ACAWK && -_ACEOF -sed -n ' -h -s/^/S["/; s/!.*/"]=/ -p -g -s/^[^!]*!// -:repl -t repl -s/'"$ac_delim"'$// -t delim -:nl -h -s/\(.\{148\}\)..*/\1/ -t more1 -s/["\\]/\\&/g; s/^/"/; s/$/\\n"\\/ -p -n -b repl -:more1 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t nl -:delim -h -s/\(.\{148\}\)..*/\1/ -t more2 -s/["\\]/\\&/g; s/^/"/; s/$/"/ -p -b -:more2 -s/["\\]/\\&/g; s/^/"/; s/$/"\\/ -p -g -s/.\{148\}// -t delim -' >$CONFIG_STATUS || ac_write_fail=1 -rm -f conf$$subs.awk -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -_ACAWK -cat >>"\$ac_tmp/subs1.awk" <<_ACAWK && - for (key in S) S_is_set[key] = 1 - FS = "" - -} -{ - line = $ 0 - nfields = split(line, field, "@") - substed = 0 - len = length(field[1]) - for (i = 2; i < nfields; i++) { - key = field[i] - keylen = length(key) - if (S_is_set[key]) { - value = S[key] - line = substr(line, 1, len) "" value "" substr(line, len + keylen + 3) - len += length(value) + length(field[++i]) - substed = 1 - } else - len += 1 + keylen - } - - print line -} - -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -if sed "s/$ac_cr//" < /dev/null > /dev/null 2>&1; then - sed "s/$ac_cr\$//; s/$ac_cr/$ac_cs_awk_cr/g" -else - cat -fi < "$ac_tmp/subs1.awk" > "$ac_tmp/subs.awk" \ - || as_fn_error $? "could not setup config files machinery" "$LINENO" 5 -_ACEOF - -# VPATH may cause trouble with some makes, so we remove sole $(srcdir), -# ${srcdir} and @srcdir@ entries from VPATH if srcdir is ".", strip leading and -# trailing colons and then remove the whole line if VPATH becomes empty -# (actually we leave an empty line to preserve line numbers). -if test "x$srcdir" = x.; then - ac_vpsub='/^[ ]*VPATH[ ]*=[ ]*/{ -h -s/// -s/^/:/ -s/[ ]*$/:/ -s/:\$(srcdir):/:/g -s/:\${srcdir}:/:/g -s/:@srcdir@:/:/g -s/^:*// -s/:*$// -x -s/\(=[ ]*\).*/\1/ -G -s/\n// -s/^[^=]*=[ ]*$// -}' -fi - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -fi # test -n "$CONFIG_FILES" - -# Set up the scripts for CONFIG_HEADERS section. -# No need to generate them if there are no CONFIG_HEADERS. -# This happens for instance with `./config.status Makefile'. -if test -n "$CONFIG_HEADERS"; then -cat >"$ac_tmp/defines.awk" <<\_ACAWK || -BEGIN { -_ACEOF - -# Transform confdefs.h into an awk script `defines.awk', embedded as -# here-document in config.status, that substitutes the proper values into -# config.h.in to produce config.h. - -# Create a delimiter string that does not exist in confdefs.h, to ease -# handling of long lines. -ac_delim='%!_!# ' -for ac_last_try in false false :; do - ac_tt=`sed -n "/$ac_delim/p" confdefs.h` - if test -z "$ac_tt"; then - break - elif $ac_last_try; then - as_fn_error $? "could not make $CONFIG_HEADERS" "$LINENO" 5 - else - ac_delim="$ac_delim!$ac_delim _$ac_delim!! " - fi -done - -# For the awk script, D is an array of macro values keyed by name, -# likewise P contains macro parameters if any. Preserve backslash -# newline sequences. - -ac_word_re=[_$as_cr_Letters][_$as_cr_alnum]* -sed -n ' -s/.\{148\}/&'"$ac_delim"'/g -t rset -:rset -s/^[ ]*#[ ]*define[ ][ ]*/ / -t def -d -:def -s/\\$// -t bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3"/p -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2"/p -d -:bsnl -s/["\\]/\\&/g -s/^ \('"$ac_word_re"'\)\(([^()]*)\)[ ]*\(.*\)/P["\1"]="\2"\ -D["\1"]=" \3\\\\\\n"\\/p -t cont -s/^ \('"$ac_word_re"'\)[ ]*\(.*\)/D["\1"]=" \2\\\\\\n"\\/p -t cont -d -:cont -n -s/.\{148\}/&'"$ac_delim"'/g -t clear -:clear -s/\\$// -t bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/"/p -d -:bsnlc -s/["\\]/\\&/g; s/^/"/; s/$/\\\\\\n"\\/p -b cont -' >$CONFIG_STATUS || ac_write_fail=1 - -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - for (key in D) D_is_set[key] = 1 - FS = "" -} -/^[\t ]*#[\t ]*(define|undef)[\t ]+$ac_word_re([\t (]|\$)/ { - line = \$ 0 - split(line, arg, " ") - if (arg[1] == "#") { - defundef = arg[2] - mac1 = arg[3] - } else { - defundef = substr(arg[1], 2) - mac1 = arg[2] - } - split(mac1, mac2, "(") #) - macro = mac2[1] - prefix = substr(line, 1, index(line, defundef) - 1) - if (D_is_set[macro]) { - # Preserve the white space surrounding the "#". - print prefix "define", macro P[macro] D[macro] - next - } else { - # Replace #undef with comments. This is necessary, for example, - # in the case of _POSIX_SOURCE, which is predefined and required - # on some systems where configure will not decide to define it. - if (defundef == "undef") { - print "/*", prefix defundef, macro, "*/" - next - } - } -} -{ print } -_ACAWK -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 - as_fn_error $? "could not setup config headers machinery" "$LINENO" 5 -fi # test -n "$CONFIG_HEADERS" - - -eval set X " :F $CONFIG_FILES :H $CONFIG_HEADERS :C $CONFIG_COMMANDS" -shift -for ac_tag -do - case $ac_tag in - :[FHLC]) ac_mode=$ac_tag; continue;; - esac - case $ac_mode$ac_tag in - :[FHL]*:*);; - :L* | :C*:*) as_fn_error $? "invalid tag \`$ac_tag'" "$LINENO" 5;; - :[FH]-) ac_tag=-:-;; - :[FH]*) ac_tag=$ac_tag:$ac_tag.in;; - esac - ac_save_IFS=$IFS - IFS=: - set x $ac_tag - IFS=$ac_save_IFS - shift - ac_file=$1 - shift - - case $ac_mode in - :L) ac_source=$1;; - :[FH]) - ac_file_inputs= - for ac_f - do - case $ac_f in - -) ac_f="$ac_tmp/stdin";; - *) # Look for the file first in the build tree, then in the source tree - # (if the path is not absolute). The absolute path cannot be DOS-style, - # because $ac_f cannot contain `:'. - test -f "$ac_f" || - case $ac_f in - [\\/$]*) false;; - *) test -f "$srcdir/$ac_f" && ac_f="$srcdir/$ac_f";; - esac || - as_fn_error 1 "cannot find input file: \`$ac_f'" "$LINENO" 5;; - esac - case $ac_f in *\'*) ac_f=`$as_echo "$ac_f" | sed "s/'/'\\\\\\\\''/g"`;; esac - as_fn_append ac_file_inputs " '$ac_f'" - done - - # Let's still pretend it is `configure' which instantiates (i.e., don't - # use $as_me), people would be surprised to read: - # /* config.h. Generated by config.status. */ - configure_input='Generated from '` - $as_echo "$*" | sed 's|^[^:]*/||;s|:[^:]*/|, |g' - `' by configure.' - if test x"$ac_file" != x-; then - configure_input="$ac_file. $configure_input" - { $as_echo "$as_me:${as_lineno-$LINENO}: creating $ac_file" >&5 -$as_echo "$as_me: creating $ac_file" >&6;} - fi - # Neutralize special characters interpreted by sed in replacement strings. - case $configure_input in #( - *\&* | *\|* | *\\* ) - ac_sed_conf_input=`$as_echo "$configure_input" | - sed 's/[\\\\&|]/\\\\&/g'`;; #( - *) ac_sed_conf_input=$configure_input;; - esac - - case $ac_tag in - *:-:* | *:-) cat >"$ac_tmp/stdin" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 ;; - esac - ;; - esac - - ac_dir=`$as_dirname -- "$ac_file" || -$as_expr X"$ac_file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$ac_file" : 'X\(//\)[^/]' \| \ - X"$ac_file" : 'X\(//\)$' \| \ - X"$ac_file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$ac_file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ - s//\1/ - q - } - /^X\(\/\/\)$/{ - s//\1/ - q - } - /^X\(\/\).*/{ - s//\1/ - q - } - s/.*/./; q'` - as_dir="$ac_dir"; as_fn_mkdir_p - ac_builddir=. - -case "$ac_dir" in -.) ac_dir_suffix= ac_top_builddir_sub=. ac_top_build_prefix= ;; -*) - ac_dir_suffix=/`$as_echo "$ac_dir" | sed 's|^\.[\\/]||'` - # A ".." for each directory in $ac_dir_suffix. - ac_top_builddir_sub=`$as_echo "$ac_dir_suffix" | sed 's|/[^\\/]*|/..|g;s|/||'` - case $ac_top_builddir_sub in - "") ac_top_builddir_sub=. ac_top_build_prefix= ;; - *) ac_top_build_prefix=$ac_top_builddir_sub/ ;; - esac ;; -esac -ac_abs_top_builddir=$ac_pwd -ac_abs_builddir=$ac_pwd$ac_dir_suffix -# for backward compatibility: -ac_top_builddir=$ac_top_build_prefix - -case $srcdir in - .) # We are building in place. - ac_srcdir=. - ac_top_srcdir=$ac_top_builddir_sub - ac_abs_top_srcdir=$ac_pwd ;; - [\\/]* | ?:[\\/]* ) # Absolute name. - ac_srcdir=$srcdir$ac_dir_suffix; - ac_top_srcdir=$srcdir - ac_abs_top_srcdir=$srcdir ;; - *) # Relative name. - ac_srcdir=$ac_top_build_prefix$srcdir$ac_dir_suffix - ac_top_srcdir=$ac_top_build_prefix$srcdir - ac_abs_top_srcdir=$ac_pwd/$srcdir ;; -esac -ac_abs_srcdir=$ac_abs_top_srcdir$ac_dir_suffix - - - case $ac_mode in - :F) - # - # CONFIG_FILE - # - - case $INSTALL in - [\\/$]* | ?:[\\/]* ) ac_INSTALL=$INSTALL ;; - *) ac_INSTALL=$ac_top_build_prefix$INSTALL ;; - esac -_ACEOF - -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -# If the template does not know about datarootdir, expand it. -# FIXME: This hack should be removed a few years after 2.60. -ac_datarootdir_hack=; ac_datarootdir_seen= -ac_sed_dataroot=' -/datarootdir/ { - p - q -} -/@datadir@/p -/@docdir@/p -/@infodir@/p -/@localedir@/p -/@mandir@/p' -case `eval "sed -n \"\$ac_sed_dataroot\" $ac_file_inputs"` in -*datarootdir*) ac_datarootdir_seen=yes;; -*@datadir@*|*@docdir@*|*@infodir@*|*@localedir@*|*@mandir@*) - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&5 -$as_echo "$as_me: WARNING: $ac_file_inputs seems to ignore the --datarootdir setting" >&2;} -_ACEOF -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 - ac_datarootdir_hack=' - s&@datadir@&$datadir&g - s&@docdir@&$docdir&g - s&@infodir@&$infodir&g - s&@localedir@&$localedir&g - s&@mandir@&$mandir&g - s&\\\${datarootdir}&$datarootdir&g' ;; -esac -_ACEOF - -# Neutralize VPATH when `$srcdir' = `.'. -# Shell code in configure.ac might set extrasub. -# FIXME: do we really want to maintain this feature? -cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 -ac_sed_extra="$ac_vpsub -$extrasub -_ACEOF -cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 -:t -/@[a-zA-Z_][a-zA-Z_0-9]*@/!b -s|@configure_input@|$ac_sed_conf_input|;t t -s&@top_builddir@&$ac_top_builddir_sub&;t t -s&@top_build_prefix@&$ac_top_build_prefix&;t t -s&@srcdir@&$ac_srcdir&;t t -s&@abs_srcdir@&$ac_abs_srcdir&;t t -s&@top_srcdir@&$ac_top_srcdir&;t t -s&@abs_top_srcdir@&$ac_abs_top_srcdir&;t t -s&@builddir@&$ac_builddir&;t t -s&@abs_builddir@&$ac_abs_builddir&;t t -s&@abs_top_builddir@&$ac_abs_top_builddir&;t t -s&@INSTALL@&$ac_INSTALL&;t t -$ac_datarootdir_hack -" -eval sed \"\$ac_sed_extra\" "$ac_file_inputs" | $AWK -f "$ac_tmp/subs.awk" \ - >$ac_tmp/out || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - -test -z "$ac_datarootdir_hack$ac_datarootdir_seen" && - { ac_out=`sed -n '/\${datarootdir}/p' "$ac_tmp/out"`; test -n "$ac_out"; } && - { ac_out=`sed -n '/^[ ]*datarootdir[ ]*:*=/p' \ - "$ac_tmp/out"`; test -z "$ac_out"; } && - { $as_echo "$as_me:${as_lineno-$LINENO}: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&5 -$as_echo "$as_me: WARNING: $ac_file contains a reference to the variable \`datarootdir' -which seems to be undefined. Please make sure it is defined" >&2;} - - rm -f "$ac_tmp/stdin" - case $ac_file in - -) cat "$ac_tmp/out" && rm -f "$ac_tmp/out";; - *) rm -f "$ac_file" && mv "$ac_tmp/out" "$ac_file";; - esac \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - ;; - :H) - # - # CONFIG_HEADER - # - if test x"$ac_file" != x-; then - { - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" - } >"$ac_tmp/config.h" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - if diff "$ac_file" "$ac_tmp/config.h" >/dev/null 2>&1; then - { $as_echo "$as_me:${as_lineno-$LINENO}: $ac_file is unchanged" >&5 -$as_echo "$as_me: $ac_file is unchanged" >&6;} - else - rm -f "$ac_file" - mv "$ac_tmp/config.h" "$ac_file" \ - || as_fn_error $? "could not create $ac_file" "$LINENO" 5 - fi - else - $as_echo "/* $configure_input */" \ - && eval '$AWK -f "$ac_tmp/defines.awk"' "$ac_file_inputs" \ - || as_fn_error $? "could not create -" "$LINENO" 5 - fi - ;; - - :C) { $as_echo "$as_me:${as_lineno-$LINENO}: executing $ac_file commands" >&5 -$as_echo "$as_me: executing $ac_file commands" >&6;} - ;; - esac - - - case $ac_file$ac_mode in - "libtool":C) - - # See if we are running on zsh, and set the options which allow our - # commands through without removal of \ escapes. - if test -n "${ZSH_VERSION+set}" ; then - setopt NO_GLOB_SUBST - fi - - cfgfile="${ofile}T" - trap "$RM \"$cfgfile\"; exit 1" 1 2 15 - $RM "$cfgfile" - - cat <<_LT_EOF >> "$cfgfile" -#! $SHELL - -# `$ECHO "$ofile" | sed 's%^.*/%%'` - Provide generalized library-building support services. -# Generated automatically by $as_me ($PACKAGE$TIMESTAMP) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: -# NOTE: Changes made to this file will be lost: look at ltmain.sh. -# -# Copyright (C) 1996, 1997, 1998, 1999, 2000, 2001, 2003, 2004, 2005, -# 2006, 2007, 2008 Free Software Foundation, Inc. -# Written by Gordon Matzigkeit, 1996 -# -# This file is part of GNU Libtool. -# -# GNU Libtool is free software; you can redistribute it and/or -# modify it under the terms of the GNU General Public License as -# published by the Free Software Foundation; either version 2 of -# the License, or (at your option) any later version. -# -# As a special exception to the GNU General Public License, -# if you distribute this file as part of a program or library that -# is built using GNU Libtool, you may include this file under the -# same distribution terms that you use for the rest of that program. -# -# GNU Libtool is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# -# You should have received a copy of the GNU General Public License -# along with GNU Libtool; see the file COPYING. If not, a copy -# can be downloaded from http://www.gnu.org/licenses/gpl.html, or -# obtained by writing to the Free Software Foundation, Inc., -# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. - - -# The names of the tagged configurations supported by this script. -available_tags="" - -# ### BEGIN LIBTOOL CONFIG - -# Which release of libtool.m4 was used? -macro_version=$macro_version -macro_revision=$macro_revision - -# Whether or not to build shared libraries. -build_libtool_libs=$enable_shared - -# Whether or not to build static libraries. -build_old_libs=$enable_static - -# What type of objects to build. -pic_mode=$pic_mode - -# Whether or not to optimize for fast installation. -fast_install=$enable_fast_install - -# The host system. -host_alias=$host_alias -host=$host -host_os=$host_os - -# The build system. -build_alias=$build_alias -build=$build -build_os=$build_os - -# A sed program that does not truncate output. -SED=$lt_SED - -# Sed that helps us avoid accidentally triggering echo(1) options like -n. -Xsed="\$SED -e 1s/^X//" - -# A grep program that handles long lines. -GREP=$lt_GREP - -# An ERE matcher. -EGREP=$lt_EGREP - -# A literal string matcher. -FGREP=$lt_FGREP - -# A BSD- or MS-compatible name lister. -NM=$lt_NM - -# Whether we need soft or hard links. -LN_S=$lt_LN_S - -# What is the maximum length of a command? -max_cmd_len=$max_cmd_len - -# Object file suffix (normally "o"). -objext=$ac_objext - -# Executable file suffix (normally ""). -exeext=$exeext - -# whether the shell understands "unset". -lt_unset=$lt_unset - -# turn spaces into newlines. -SP2NL=$lt_lt_SP2NL - -# turn newlines into spaces. -NL2SP=$lt_lt_NL2SP - -# How to create reloadable object files. -reload_flag=$lt_reload_flag -reload_cmds=$lt_reload_cmds - -# An object symbol dumper. -OBJDUMP=$lt_OBJDUMP - -# Method to check whether dependent libraries are shared objects. -deplibs_check_method=$lt_deplibs_check_method - -# Command to use when deplibs_check_method == "file_magic". -file_magic_cmd=$lt_file_magic_cmd - -# The archiver. -AR=$lt_AR -AR_FLAGS=$lt_AR_FLAGS - -# A symbol stripping program. -STRIP=$lt_STRIP - -# Commands used to install an old-style archive. -RANLIB=$lt_RANLIB -old_postinstall_cmds=$lt_old_postinstall_cmds -old_postuninstall_cmds=$lt_old_postuninstall_cmds - -# A C compiler. -LTCC=$lt_CC - -# LTCC compiler flags. -LTCFLAGS=$lt_CFLAGS - -# Take the output of nm and produce a listing of raw symbols and C names. -global_symbol_pipe=$lt_lt_cv_sys_global_symbol_pipe - -# Transform the output of nm in a proper C declaration. -global_symbol_to_cdecl=$lt_lt_cv_sys_global_symbol_to_cdecl - -# Transform the output of nm in a C name address pair. -global_symbol_to_c_name_address=$lt_lt_cv_sys_global_symbol_to_c_name_address - -# Transform the output of nm in a C name address pair when lib prefix is needed. -global_symbol_to_c_name_address_lib_prefix=$lt_lt_cv_sys_global_symbol_to_c_name_address_lib_prefix - -# The name of the directory that contains temporary libtool files. -objdir=$objdir - -# Shell to use when invoking shell scripts. -SHELL=$lt_SHELL - -# An echo program that does not interpret backslashes. -ECHO=$lt_ECHO - -# Used to examine libraries when file_magic_cmd begins with "file". -MAGIC_CMD=$MAGIC_CMD - -# Must we lock files when doing compilation? -need_locks=$lt_need_locks - -# Tool to manipulate archived DWARF debug symbol files on Mac OS X. -DSYMUTIL=$lt_DSYMUTIL - -# Tool to change global to local symbols on Mac OS X. -NMEDIT=$lt_NMEDIT - -# Tool to manipulate fat objects and archives on Mac OS X. -LIPO=$lt_LIPO - -# ldd/readelf like tool for Mach-O binaries on Mac OS X. -OTOOL=$lt_OTOOL - -# ldd/readelf like tool for 64 bit Mach-O binaries on Mac OS X 10.4. -OTOOL64=$lt_OTOOL64 - -# Old archive suffix (normally "a"). -libext=$libext - -# Shared library suffix (normally ".so"). -shrext_cmds=$lt_shrext_cmds - -# The commands to extract the exported symbol list from a shared archive. -extract_expsyms_cmds=$lt_extract_expsyms_cmds - -# Variables whose values should be saved in libtool wrapper scripts and -# restored at link time. -variables_saved_for_relink=$lt_variables_saved_for_relink - -# Do we need the "lib" prefix for modules? -need_lib_prefix=$need_lib_prefix - -# Do we need a version for libraries? -need_version=$need_version - -# Library versioning type. -version_type=$version_type - -# Shared library runtime path variable. -runpath_var=$runpath_var - -# Shared library path variable. -shlibpath_var=$shlibpath_var - -# Is shlibpath searched before the hard-coded library search path? -shlibpath_overrides_runpath=$shlibpath_overrides_runpath - -# Format of library name prefix. -libname_spec=$lt_libname_spec - -# List of archive names. First name is the real one, the rest are links. -# The last name is the one that the linker finds with -lNAME -library_names_spec=$lt_library_names_spec - -# The coded name of the library, if different from the real name. -soname_spec=$lt_soname_spec - -# Command to use after installation of a shared archive. -postinstall_cmds=$lt_postinstall_cmds - -# Command to use after uninstallation of a shared archive. -postuninstall_cmds=$lt_postuninstall_cmds - -# Commands used to finish a libtool library installation in a directory. -finish_cmds=$lt_finish_cmds - -# As "finish_cmds", except a single script fragment to be evaled but -# not shown. -finish_eval=$lt_finish_eval - -# Whether we should hardcode library paths into libraries. -hardcode_into_libs=$hardcode_into_libs - -# Compile-time system search path for libraries. -sys_lib_search_path_spec=$lt_sys_lib_search_path_spec - -# Run-time system search path for libraries. -sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec - -# Whether dlopen is supported. -dlopen_support=$enable_dlopen - -# Whether dlopen of programs is supported. -dlopen_self=$enable_dlopen_self - -# Whether dlopen of statically linked programs is supported. -dlopen_self_static=$enable_dlopen_self_static - -# Commands to strip libraries. -old_striplib=$lt_old_striplib -striplib=$lt_striplib - - -# The linker used to build libraries. -LD=$lt_LD - -# Commands used to build an old-style archive. -old_archive_cmds=$lt_old_archive_cmds - -# A language specific compiler. -CC=$lt_compiler - -# Is the compiler the GNU compiler? -with_gcc=$GCC - -# Compiler flag to turn off builtin functions. -no_builtin_flag=$lt_lt_prog_compiler_no_builtin_flag - -# How to pass a linker flag through the compiler. -wl=$lt_lt_prog_compiler_wl - -# Additional compiler flags for building library objects. -pic_flag=$lt_lt_prog_compiler_pic - -# Compiler flag to prevent dynamic linking. -link_static_flag=$lt_lt_prog_compiler_static - -# Does compiler simultaneously support -c and -o options? -compiler_c_o=$lt_lt_cv_prog_compiler_c_o - -# Whether or not to add -lc for building shared libraries. -build_libtool_need_lc=$archive_cmds_need_lc - -# Whether or not to disallow shared libs when runtime libs are static. -allow_libtool_libs_with_static_runtimes=$enable_shared_with_static_runtimes - -# Compiler flag to allow reflexive dlopens. -export_dynamic_flag_spec=$lt_export_dynamic_flag_spec - -# Compiler flag to generate shared objects directly from archives. -whole_archive_flag_spec=$lt_whole_archive_flag_spec - -# Whether the compiler copes with passing no objects directly. -compiler_needs_object=$lt_compiler_needs_object - -# Create an old-style archive from a shared archive. -old_archive_from_new_cmds=$lt_old_archive_from_new_cmds - -# Create a temporary old-style archive to link instead of a shared archive. -old_archive_from_expsyms_cmds=$lt_old_archive_from_expsyms_cmds - -# Commands used to build a shared archive. -archive_cmds=$lt_archive_cmds -archive_expsym_cmds=$lt_archive_expsym_cmds - -# Commands used to build a loadable module if different from building -# a shared archive. -module_cmds=$lt_module_cmds -module_expsym_cmds=$lt_module_expsym_cmds - -# Whether we are building with GNU ld or not. -with_gnu_ld=$lt_with_gnu_ld - -# Flag that allows shared libraries with undefined symbols to be built. -allow_undefined_flag=$lt_allow_undefined_flag - -# Flag that enforces no undefined symbols. -no_undefined_flag=$lt_no_undefined_flag - -# Flag to hardcode \$libdir into a binary during linking. -# This must work even if \$libdir does not exist -hardcode_libdir_flag_spec=$lt_hardcode_libdir_flag_spec - -# If ld is used when linking, flag to hardcode \$libdir into a binary -# during linking. This must work even if \$libdir does not exist. -hardcode_libdir_flag_spec_ld=$lt_hardcode_libdir_flag_spec_ld - -# Whether we need a single "-rpath" flag with a separated argument. -hardcode_libdir_separator=$lt_hardcode_libdir_separator - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary. -hardcode_direct=$hardcode_direct - -# Set to "yes" if using DIR/libNAME\${shared_ext} during linking hardcodes -# DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \${shlibpath_var} if the -# library is relocated. -hardcode_direct_absolute=$hardcode_direct_absolute - -# Set to "yes" if using the -LDIR flag during linking hardcodes DIR -# into the resulting binary. -hardcode_minus_L=$hardcode_minus_L - -# Set to "yes" if using SHLIBPATH_VAR=DIR during linking hardcodes DIR -# into the resulting binary. -hardcode_shlibpath_var=$hardcode_shlibpath_var - -# Set to "yes" if building a shared library automatically hardcodes DIR -# into the library and all subsequent libraries and executables linked -# against it. -hardcode_automatic=$hardcode_automatic - -# Set to yes if linker adds runtime paths of dependent libraries -# to runtime path list. -inherit_rpath=$inherit_rpath - -# Whether libtool must link a program against all its dependency libraries. -link_all_deplibs=$link_all_deplibs - -# Fix the shell variable \$srcfile for the compiler. -fix_srcfile_path=$lt_fix_srcfile_path - -# Set to "yes" if exported symbols are required. -always_export_symbols=$always_export_symbols - -# The commands to list exported symbols. -export_symbols_cmds=$lt_export_symbols_cmds - -# Symbols that should not be listed in the preloaded symbols. -exclude_expsyms=$lt_exclude_expsyms - -# Symbols that must always be exported. -include_expsyms=$lt_include_expsyms - -# Commands necessary for linking programs (against libraries) with templates. -prelink_cmds=$lt_prelink_cmds - -# Specify filename containing input files. -file_list_spec=$lt_file_list_spec - -# How to hardcode a shared library path into an executable. -hardcode_action=$hardcode_action - -# ### END LIBTOOL CONFIG - -_LT_EOF - - case $host_os in - aix3*) - cat <<\_LT_EOF >> "$cfgfile" -# AIX sometimes has problems with the GCC collect2 program. For some -# reason, if we set the COLLECT_NAMES environment variable, the problems -# vanish in a puff of smoke. -if test "X${COLLECT_NAMES+set}" != Xset; then - COLLECT_NAMES= - export COLLECT_NAMES -fi -_LT_EOF - ;; - esac - - -ltmain="$ac_aux_dir/ltmain.sh" - - - # We use sed instead of cat because bash on DJGPP gets confused if - # if finds mixed CR/LF and LF-only lines. Since sed operates in - # text mode, it properly converts lines to CR/LF. This bash problem - # is reportedly fixed, but why not run on old versions too? - sed '/^# Generated shell functions inserted here/q' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - case $xsi_shell in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac -} - -# func_basename file -func_basename () -{ - func_basename_result="${1##*/}" -} - -# func_dirname_and_basename file append nondir_replacement -# perform func_basename and func_dirname in a single function -# call: -# dirname: Compute the dirname of FILE. If nonempty, -# add APPEND to the result, otherwise set result -# to NONDIR_REPLACEMENT. -# value returned in "$func_dirname_result" -# basename: Compute filename of FILE. -# value retuned in "$func_basename_result" -# Implementation must be kept synchronized with func_dirname -# and func_basename. For efficiency, we do not delegate to -# those functions but instead duplicate the functionality here. -func_dirname_and_basename () -{ - case ${1} in - */*) func_dirname_result="${1%/*}${2}" ;; - * ) func_dirname_result="${3}" ;; - esac - func_basename_result="${1##*/}" -} - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -func_stripname () -{ - # pdksh 5.2.14 does not do ${X%$Y} correctly if both X and Y are - # positional parameters, so assign one to ordinary parameter first. - func_stripname_result=${3} - func_stripname_result=${func_stripname_result#"${1}"} - func_stripname_result=${func_stripname_result%"${2}"} -} - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=${1%%=*} - func_opt_split_arg=${1#*=} -} - -# func_lo2o object -func_lo2o () -{ - case ${1} in - *.lo) func_lo2o_result=${1%.lo}.${objext} ;; - *) func_lo2o_result=${1} ;; - esac -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=${1%.*}.lo -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=$(( $* )) -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=${#1} -} - -_LT_EOF - ;; - *) # Bourne compatible functions. - cat << \_LT_EOF >> "$cfgfile" - -# func_dirname file append nondir_replacement -# Compute the dirname of FILE. If nonempty, add APPEND to the result, -# otherwise set result to NONDIR_REPLACEMENT. -func_dirname () -{ - # Extract subdirectory from the argument. - func_dirname_result=`$ECHO "X${1}" | $Xsed -e "$dirname"` - if test "X$func_dirname_result" = "X${1}"; then - func_dirname_result="${3}" - else - func_dirname_result="$func_dirname_result${2}" - fi -} - -# func_basename file -func_basename () -{ - func_basename_result=`$ECHO "X${1}" | $Xsed -e "$basename"` -} - - -# func_stripname prefix suffix name -# strip PREFIX and SUFFIX off of NAME. -# PREFIX and SUFFIX must not contain globbing or regex special -# characters, hashes, percent signs, but SUFFIX may contain a leading -# dot (in which case that matches only a dot). -# func_strip_suffix prefix name -func_stripname () -{ - case ${2} in - .*) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%\\\\${2}\$%%"`;; - *) func_stripname_result=`$ECHO "X${3}" \ - | $Xsed -e "s%^${1}%%" -e "s%${2}\$%%"`;; - esac -} - -# sed scripts: -my_sed_long_opt='1s/^\(-[^=]*\)=.*/\1/;q' -my_sed_long_arg='1s/^-[^=]*=//' - -# func_opt_split -func_opt_split () -{ - func_opt_split_opt=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_opt"` - func_opt_split_arg=`$ECHO "X${1}" | $Xsed -e "$my_sed_long_arg"` -} - -# func_lo2o object -func_lo2o () -{ - func_lo2o_result=`$ECHO "X${1}" | $Xsed -e "$lo2o"` -} - -# func_xform libobj-or-source -func_xform () -{ - func_xform_result=`$ECHO "X${1}" | $Xsed -e 's/\.[^.]*$/.lo/'` -} - -# func_arith arithmetic-term... -func_arith () -{ - func_arith_result=`expr "$@"` -} - -# func_len string -# STRING may not start with a hyphen. -func_len () -{ - func_len_result=`expr "$1" : ".*" 2>/dev/null || echo $max_cmd_len` -} - -_LT_EOF -esac - -case $lt_shell_append in - yes) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$1+=\$2" -} -_LT_EOF - ;; - *) - cat << \_LT_EOF >> "$cfgfile" - -# func_append var value -# Append VALUE to the end of shell variable VAR. -func_append () -{ - eval "$1=\$$1\$2" -} - -_LT_EOF - ;; - esac - - - sed -n '/^# Generated shell functions inserted here/,$p' "$ltmain" >> "$cfgfile" \ - || (rm -f "$cfgfile"; exit 1) - - mv -f "$cfgfile" "$ofile" || - (rm -f "$ofile" && cp "$cfgfile" "$ofile" && rm -f "$cfgfile") - chmod +x "$ofile" - - ;; - - esac -done # for ac_tag - - -as_fn_exit 0 -_ACEOF -ac_clean_files=$ac_clean_files_save - -test $ac_write_fail = 0 || - as_fn_error $? "write failure creating $CONFIG_STATUS" "$LINENO" 5 - - -# configure is writing to config.log, and then calls config.status. -# config.status does its own redirection, appending to config.log. -# Unfortunately, on DOS this fails, as config.log is still kept open -# by configure, so config.status won't be able to write to it; its -# output is simply discarded. So we exec the FD to /dev/null, -# effectively closing config.log, so it can be properly (re)opened and -# appended to by config.status. When coming back to configure, we -# need to make the FD available again. -if test "$no_create" != yes; then - ac_cs_success=: - ac_config_status_args= - test "$silent" = yes && - ac_config_status_args="$ac_config_status_args --quiet" - exec 5>/dev/null - $SHELL $CONFIG_STATUS $ac_config_status_args || ac_cs_success=false - exec 5>>config.log - # Use ||, not &&, to avoid exiting from the if with $? = 1, which - # 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 - diff -Nru sqlite3-3.42.0/configure.ac sqlite3-3.44.0-0/configure.ac --- sqlite3-3.42.0/configure.ac 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/configure.ac 2023-11-04 14:23:58.000000000 +0000 @@ -598,11 +598,28 @@ TARGET_HAVE_READLINE=1 fi fi +AC_ARG_WITH([linenoise], + [AS_HELP_STRING([--with-linenoise=DIR],[source directory for linenoise library])], + [with_linenoise=$withval], + [with_linenoise="no"]) +if test "x$with_linenoise" != "xno"; then + TARGET_HAVE_READLINE=0 + TARGET_HAVE_EDITLINE=0 + TARGET_HAVE_LINENOISE=1 + TARGET_READLINE_INC="-I${with_linenoise}" + TARGET_READLINE_LIBS="${with_linenoise}/linenoise.c" + echo "using linenoise source code at ${with_linenoise}" +else + TARGET_HAVE_LINENOISE=0 + echo "not using linenoise" +fi AC_SUBST(TARGET_READLINE_LIBS) AC_SUBST(TARGET_READLINE_INC) AC_SUBST(TARGET_HAVE_READLINE) AC_SUBST(TARGET_HAVE_EDITLINE) +AC_SUBST(TARGET_HAVE_LINENOISE) + ########## # Figure out what C libraries are required to compile programs @@ -615,7 +632,7 @@ AC_ARG_ENABLE(debug, AS_HELP_STRING([--enable-debug],[enable debugging & verbose explain])) AC_MSG_CHECKING([build type]) if test "${enable_debug}" = "yes" ; then - TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0" + TARGET_DEBUG="-DSQLITE_DEBUG=1 -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE -O0 -Wall" AC_MSG_RESULT([debug]) else TARGET_DEBUG="-DNDEBUG" diff -Nru sqlite3-3.42.0/debian/changelog sqlite3-3.44.0-0/debian/changelog --- sqlite3-3.42.0/debian/changelog 2023-06-24 14:16:47.000000000 +0000 +++ sqlite3-3.44.0-0/debian/changelog 2023-11-04 14:24:20.000000000 +0000 @@ -1,174 +1,14 @@ -sqlite3 (3.42.0-1) unstable; urgency=medium +sqlite3 (3.44.0-0-20359~202311021114~202311041424~ubuntu23.10.1) mantic; urgency=low - * New upstream release. - * Remove sqlite3ExprIsTableConstraint@Base and - sqlite3SelectAddColumnTypeAndCollation@Base symbols as no longer part - of the library. - * Update symbols file. + * Auto build. - [ Samuel Thibault ] - Add hurd-amd64 support (closes: #1035646). + -- Gajj GNDU Sat, 04 Nov 2023 14:24:20 +0000 - -- Laszlo Boszormenyi (GCS) Sat, 24 Jun 2023 16:16:47 +0200 +sqlite3 (3.36.0-3) UNRELEASED; urgency=high -sqlite3 (3.40.1-2) unstable; urgency=medium + * nightly release - [ Cyril Brulebois ] - * Add Breaks against crowdsec as found in bullseye, as it relies on a - particular table_info format, which changes between 3.36.0 and 3.37.0 - (closes: #1033029). - - -- Laszlo Boszormenyi (GCS) Thu, 16 Mar 2023 19:54:28 +0100 - -sqlite3 (3.40.1-1) unstable; urgency=medium - - * New upstream release. - * Update symbols file. - * Update Standards-Version to 4.6.2 . - - -- Laszlo Boszormenyi (GCS) Sat, 31 Dec 2022 09:41:40 +0100 - -sqlite3 (3.40.0-2) unstable; urgency=high - - * Backport upstream security fix for CVE-2022-46908: when relying on --safe - for execution of an untrusted CLI script, does not properly implement the - azProhibitedFunctions protection mechanism (closes: #1026293). - - [ Helge Deller ] - * Enable large file support (closes: #1026171). - - -- Laszlo Boszormenyi (GCS) Sun, 18 Dec 2022 10:03:56 +0100 - -sqlite3 (3.40.0-1) unstable; urgency=medium - - * New upstream release. - * Remove sqlite3StdTypeMap@Base symbol as no longer part of the library. - * Update symbols file. - * Update patches to apply clean. - - -- Laszlo Boszormenyi (GCS) Wed, 16 Nov 2022 18:21:56 +0100 - -sqlite3 (3.39.4-1) unstable; urgency=high - - * New upstream release: - - fix a possible integer overflow in the size computation for a memory - allocation in FTS3. - - -- Laszlo Boszormenyi (GCS) Sun, 02 Oct 2022 18:17:34 +0200 - -sqlite3 (3.39.3-1) unstable; urgency=medium - - * New upstream release. - - -- Laszlo Boszormenyi (GCS) Mon, 05 Sep 2022 17:38:52 +0200 - -sqlite3 (3.39.2-1) unstable; urgency=high - - * New upstream release: - - apply fixes for CVE-2022-35737. - - -- Laszlo Boszormenyi (GCS) Fri, 22 Jul 2022 12:10:48 +0000 - -sqlite3 (3.39.1-1) unstable; urgency=medium - - * New upstream release. - - -- Laszlo Boszormenyi (GCS) Thu, 14 Jul 2022 17:51:49 +0200 - -sqlite3 (3.39.0-3) unstable; urgency=medium - - [ Helmut Grohne ] - * libsqlite3-dev: Generalize libc6-dev dependency to libc-dev - (closes: #1014893). - - -- Laszlo Boszormenyi (GCS) Thu, 14 Jul 2022 06:23:16 +0200 - -sqlite3 (3.39.0-2) unstable; urgency=medium - - * Compile with -DSQLITE_ALLOW_ROWID_IN_VIEW to re-enable rowid for views - (closes: #1014495). - - -- Laszlo Boszormenyi (GCS) Thu, 07 Jul 2022 00:04:47 +0200 - -sqlite3 (3.39.0-1) unstable; urgency=medium - - * New upstream release. - * Update symbols file. - - -- Laszlo Boszormenyi (GCS) Wed, 29 Jun 2022 23:27:17 +0200 - -sqlite3 (3.38.5-1) unstable; urgency=high - - * New upstream release: - - fix a byte-code problem in the Bloom filter pull-down optimization that - enters an infinite loop. - - [ Helmut Grohne ] - * Link sqlite3 dynamically with its library (closes: #1010516). - - -- Laszlo Boszormenyi (GCS) Sat, 07 May 2022 13:18:57 +0200 - -sqlite3 (3.38.3-1) unstable; urgency=medium - - * New upstream release. - * Update symbols file. - - -- Laszlo Boszormenyi (GCS) Sat, 30 Apr 2022 07:13:56 +0200 - -sqlite3 (3.38.2-1) unstable; urgency=medium - - * New upstream release. - - -- Laszlo Boszormenyi (GCS) Mon, 28 Mar 2022 17:35:33 +0200 - -sqlite3 (3.38.1-1) unstable; urgency=medium - - * New upstream release. - - -- Laszlo Boszormenyi (GCS) Sun, 13 Mar 2022 19:02:54 +0100 - -sqlite3 (3.38.0-1) unstable; urgency=medium - - * New upstream release. - * Remove sqlite3ParserReset@Base symbol as no longer part of the library. - - -- Laszlo Boszormenyi (GCS) Sun, 27 Feb 2022 19:52:50 +0100 - -sqlite3 (3.37.2-2) unstable; urgency=medium - - * Fix non-Linux installation. - - -- Laszlo Boszormenyi (GCS) Sun, 16 Jan 2022 11:59:39 +0100 - -sqlite3 (3.37.2-1) unstable; urgency=medium - - * New upstream release. - * Don't try to build sqlite3-tools on kfreebsd-any. - * Update symbols file. - - -- Laszlo Boszormenyi (GCS) Thu, 06 Jan 2022 19:16:04 +0100 - -sqlite3 (3.37.1-1) unstable; urgency=medium - - * New upstream release. - - -- Laszlo Boszormenyi (GCS) Sun, 02 Jan 2022 13:15:04 +0100 - -sqlite3 (3.37.0-2) experimental; urgency=medium - - * Fix Breaks + Replaces for sqlite3-tools (closes: #1002551). - * Declare conflicts with emboss on sqlite3-tools (closes: #1002549). - - -- Laszlo Boszormenyi (GCS) Fri, 24 Dec 2021 12:20:47 +0100 - -sqlite3 (3.37.0-1) experimental; urgency=medium - - * New upstream release. - * Update symbols file. - * Distinct license of the patches (closes: #858756). - * Package sqlite3 tools separately. - - -- Laszlo Boszormenyi (GCS) Sun, 12 Dec 2021 23:34:48 +0100 + -- Navdeep Fri, 10 Dec 2021 20:50:05 -0600 sqlite3 (3.36.0-2) unstable; urgency=high diff -Nru sqlite3-3.42.0/debian/clean sqlite3-3.44.0-0/debian/clean --- sqlite3-3.42.0/debian/clean 2023-06-24 14:16:47.000000000 +0000 +++ sqlite3-3.44.0-0/debian/clean 1970-01-01 00:00:00.000000000 +0000 @@ -1,2 +0,0 @@ -config.guess -config.sub diff -Nru sqlite3-3.42.0/debian/clean-www.sh sqlite3-3.44.0-0/debian/clean-www.sh --- sqlite3-3.42.0/debian/clean-www.sh 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/debian/clean-www.sh 2023-11-04 14:24:19.000000000 +0000 @@ -0,0 +1,6 @@ +#!/bin/sh + +rm -f www/images/fileformat/._filesystem1.gif +rm -f www/images/fileformat/._master_journal_ptr.gif +rm -f www/images/fileformat/.~lock.indexpage.odg# + diff -Nru sqlite3-3.42.0/debian/control sqlite3-3.44.0-0/debian/control --- sqlite3-3.42.0/debian/control 2023-06-24 14:16:47.000000000 +0000 +++ sqlite3-3.44.0-0/debian/control 2023-11-04 14:24:19.000000000 +0000 @@ -2,9 +2,9 @@ Section: devel Priority: optional Maintainer: Laszlo Boszormenyi (GCS) -Build-Depends: debhelper-compat (= 13), autoconf (>= 2.59), libtool (>= 1.5.2), automake, chrpath, lynx, libreadline-dev, tcl8.6-dev +Build-Depends: debhelper-compat (= 11), autoconf (>= 2.59), libtool (>= 1.5.2), automake, chrpath, lynx, libreadline-dev, tcl8.6-dev Build-Conflicts: tcl8.4, tcl8.4-dev, tcl8.5, tcl8.5-dev -Standards-Version: 4.6.2 +Standards-Version: 4.5.1 Rules-Requires-Root: no Homepage: https://www.sqlite.org/ @@ -39,7 +39,6 @@ Architecture: all Depends: ${misc:Depends} Recommends: sqlite3 -Multi-Arch: foreign Description: SQLite 3 documentation SQLite is a C library that implements an SQL database engine. Programs that link with the SQLite library can have SQL database @@ -52,7 +51,7 @@ Section: libs Architecture: any Depends: ${shlibs:Depends}, ${misc:Depends} -Breaks: python-migrate (<< 0.11.0-4~), python3-migrate (<< 0.11.0-4~), crowdsec (<< 1.4) +Breaks: python-migrate (<< 0.11.0-4~), python3-migrate (<< 0.11.0-4~) Multi-Arch: same Pre-Depends: ${misc:Pre-Depends} Description: SQLite 3 shared library @@ -64,7 +63,7 @@ Suggests: sqlite3-doc Section: libdevel Architecture: any -Depends: libsqlite3-0 (= ${binary:Version}), ${misc:Depends}, libc-dev +Depends: libsqlite3-0 (= ${binary:Version}), ${misc:Depends}, libc6-dev Multi-Arch: same Description: SQLite 3 development files SQLite is a C library that implements an SQL database engine. @@ -84,21 +83,3 @@ access without running a separate RDBMS process. . This package contains the Tcl bindings. - -Package: sqlite3-tools -Suggests: sqlite3-doc -Section: database -Architecture: linux-any hurd-any -Depends: ${shlibs:Depends}, ${misc:Depends} -Breaks: sqlite3 (<< 3.37.0) -Replaces: sqlite3 (<< 3.37.0) -Conflicts: emboss -Multi-Arch: foreign -Description: Command line interface for SQLite 3 (tools) - This package contains various tools such as: - - showdb - - showjournal - - showstat4 - - showwal - - sqldiff - - sqlite3_analyzer diff -Nru sqlite3-3.42.0/debian/copyright sqlite3-3.44.0-0/debian/copyright --- sqlite3-3.42.0/debian/copyright 2021-12-12 22:34:48.000000000 +0000 +++ sqlite3-3.44.0-0/debian/copyright 2023-11-04 14:24:19.000000000 +0000 @@ -5,6 +5,8 @@ Files: * Copyright: D. Richard Hipp License: public-domain + The files listed have been put on the public domain by the sqlite3 + contributors. Files: debian/* Copyright: 2006- Laszlo Boszormenyi (GCS) , @@ -26,25 +28,3 @@ . On Debian systems, the full text of the GNU General Public License version 2 can be found in the file `/usr/share/common-licenses/GPL-2'. - -Files: debian/sqlite3_analyzer.1 -Copyright: 2018 Yuriy M. Kaminskiy Aq yumkam+debian@gmail.com -License: public-domain - - -Files: debian/patches/* -Copyright: D. Richard Hipp -License: public-domain - -Files: debian/patches/02-use-packaged-lempar.c.patch - debian/patches/31-increase_SQLITE_MAX_DEFAULT_PAGE_SIZE_to_32k.patch -Copyright: 2006- Laszlo Boszormenyi (GCS) -License: public-domain - -Files: debian/patches/40-amalgamation_configure.patch -Copyright: Jan Palus -License: public-domain - -License: public-domain - The files listed have been put on the public domain by the sqlite3 - contributors. diff -Nru sqlite3-3.42.0/debian/git-build-recipe.manifest sqlite3-3.44.0-0/debian/git-build-recipe.manifest --- sqlite3-3.42.0/debian/git-build-recipe.manifest 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/debian/git-build-recipe.manifest 2023-11-04 14:24:20.000000000 +0000 @@ -0,0 +1,4 @@ +# git-build-recipe format 0.4 deb-version 3.44.0-0-20359~202311021114~202311041424 +lp:~linuxgndu/sqlite-recipe/+git/sqlite-recipe git-commit:11379c080966df5c39db7a606c2cb33032819e00 +nest-part packaging lp:sqlite-recipe debian debian git-commit:827d8530756db3776fd03e0573bcbfd2b5a75539 +nest-part www lp:sqlite-recipe www www git-commit:827d8530756db3776fd03e0573bcbfd2b5a75539 diff -Nru sqlite3-3.42.0/debian/libsqlite3-0.symbols sqlite3-3.44.0-0/debian/libsqlite3-0.symbols --- sqlite3-3.42.0/debian/libsqlite3-0.symbols 2023-06-24 14:16:47.000000000 +0000 +++ sqlite3-3.44.0-0/debian/libsqlite3-0.symbols 2023-11-04 14:24:19.000000000 +0000 @@ -1,1070 +1,7 @@ libsqlite3.so.0 libsqlite3-0 #MINVER# - sqlite3AbsInt32@Base 3.37.0 - sqlite3AddCheckConstraint@Base 3.37.0 - sqlite3AddCollateType@Base 3.37.0 - sqlite3AddColumn@Base 3.37.0 - sqlite3AddDefaultValue@Base 3.37.0 - sqlite3AddGenerated@Base 3.37.0 - sqlite3AddInt64@Base 3.37.0 - sqlite3AddNotNull@Base 3.37.0 - sqlite3AddPrimaryKey@Base 3.37.0 - sqlite3AddReturning@Base 3.37.0 - sqlite3AffinityType@Base 3.37.0 - sqlite3AggInfoPersistWalkerInit@Base 3.37.0 - sqlite3AllocateIndexObject@Base 3.37.0 - sqlite3AlterBeginAddColumn@Base 3.37.0 - sqlite3AlterDropColumn@Base 3.37.0 - sqlite3AlterFinishAddColumn@Base 3.37.0 - sqlite3AlterFunctions@Base 3.37.0 - sqlite3AlterRenameColumn@Base 3.37.0 - sqlite3AlterRenameTable@Base 3.37.0 - sqlite3AnalysisLoad@Base 3.37.0 - sqlite3Analyze@Base 3.37.0 - sqlite3ApiExit@Base 3.37.0 - sqlite3ArrayAllocate@Base 3.37.0 - sqlite3AtoF@Base 3.37.0 - sqlite3Atoi64@Base 3.37.0 - sqlite3Atoi@Base 3.37.0 - sqlite3Attach@Base 3.37.0 - sqlite3AuthCheck@Base 3.37.0 - sqlite3AuthContextPop@Base 3.37.0 - sqlite3AuthContextPush@Base 3.37.0 - sqlite3AuthRead@Base 3.37.0 - sqlite3AuthReadCol@Base 3.37.0 - sqlite3AutoLoadExtensions@Base 3.37.0 - sqlite3AutoincrementBegin@Base 3.37.0 - sqlite3AutoincrementEnd@Base 3.37.0 - sqlite3BackupRestart@Base 3.37.0 - sqlite3BackupUpdate@Base 3.37.0 - sqlite3BeginBenignMalloc@Base 3.37.0 - sqlite3BeginTransaction@Base 3.37.0 - sqlite3BeginTrigger@Base 3.37.0 - sqlite3BeginWriteOperation@Base 3.37.0 - sqlite3BenignMallocHooks@Base 3.37.0 - sqlite3BinaryCompareCollSeq@Base 3.37.0 - sqlite3BitvecBuiltinTest@Base 3.37.0 - sqlite3BitvecClear@Base 3.37.0 - sqlite3BitvecCreate@Base 3.37.0 - sqlite3BitvecDestroy@Base 3.37.0 - sqlite3BitvecSet@Base 3.37.0 - sqlite3BitvecSize@Base 3.37.0 - sqlite3BitvecTest@Base 3.37.0 - sqlite3BitvecTestNotNull@Base 3.37.0 - sqlite3BlobCompare@Base 3.37.0 - sqlite3BtreeBeginStmt@Base 3.37.0 - sqlite3BtreeBeginTrans@Base 3.37.0 - sqlite3BtreeCheckpoint@Base 3.37.0 - sqlite3BtreeClearCache@Base 3.40.1 - sqlite3BtreeClearCursor@Base 3.37.0 - sqlite3BtreeClearTable@Base 3.37.0 - sqlite3BtreeClearTableOfCursor@Base 3.37.0 - sqlite3BtreeClose@Base 3.37.0 - sqlite3BtreeCloseCursor@Base 3.37.0 - sqlite3BtreeCommit@Base 3.37.0 - sqlite3BtreeCommitPhaseOne@Base 3.37.0 - sqlite3BtreeCommitPhaseTwo@Base 3.37.0 - sqlite3BtreeConnectionCount@Base 3.37.0 - sqlite3BtreeCopyFile@Base 3.37.0 - sqlite3BtreeCount@Base 3.37.0 - sqlite3BtreeCreateTable@Base 3.37.0 - sqlite3BtreeCursor@Base 3.37.0 - sqlite3BtreeCursorHasHint@Base 3.37.0 - sqlite3BtreeCursorHasMoved@Base 3.37.0 - sqlite3BtreeCursorHintFlags@Base 3.37.0 - sqlite3BtreeCursorIsValidNN@Base 3.37.0 - sqlite3BtreeCursorPin@Base 3.37.0 - sqlite3BtreeCursorRestore@Base 3.37.0 - sqlite3BtreeCursorSize@Base 3.37.0 - sqlite3BtreeCursorUnpin@Base 3.37.0 - sqlite3BtreeCursorZero@Base 3.37.0 - sqlite3BtreeDelete@Base 3.37.0 - sqlite3BtreeDropTable@Base 3.37.0 - sqlite3BtreeEnter@Base 3.37.0 - sqlite3BtreeEnterAll@Base 3.37.0 - sqlite3BtreeEnterCursor@Base 3.37.0 - sqlite3BtreeEof@Base 3.37.0 - sqlite3BtreeFakeValidCursor@Base 3.37.0 - sqlite3BtreeFirst@Base 3.37.0 - sqlite3BtreeGetAutoVacuum@Base 3.37.0 - sqlite3BtreeGetFilename@Base 3.37.0 - sqlite3BtreeGetJournalname@Base 3.37.0 - sqlite3BtreeGetMeta@Base 3.37.0 - sqlite3BtreeGetPageSize@Base 3.37.0 - sqlite3BtreeGetRequestedReserve@Base 3.37.0 - sqlite3BtreeGetReserveNoMutex@Base 3.37.0 - sqlite3BtreeIncrVacuum@Base 3.37.0 - sqlite3BtreeIncrblobCursor@Base 3.37.0 - sqlite3BtreeIndexMoveto@Base 3.37.0 - sqlite3BtreeInsert@Base 3.37.0 - sqlite3BtreeIntegerKey@Base 3.37.0 - sqlite3BtreeIntegrityCheck@Base 3.37.0 - sqlite3BtreeIsInBackup@Base 3.37.0 - sqlite3BtreeIsReadonly@Base 3.37.0 - sqlite3BtreeLast@Base 3.37.0 - sqlite3BtreeLastPage@Base 3.37.0 - sqlite3BtreeLeave@Base 3.37.0 - sqlite3BtreeLeaveAll@Base 3.37.0 - sqlite3BtreeLeaveCursor@Base 3.37.0 - sqlite3BtreeLockTable@Base 3.37.0 - sqlite3BtreeMaxPageCount@Base 3.37.0 - sqlite3BtreeMaxRecordSize@Base 3.37.0 - sqlite3BtreeNewDb@Base 3.37.0 - sqlite3BtreeNext@Base 3.37.0 - sqlite3BtreeOpen@Base 3.37.0 - sqlite3BtreePager@Base 3.37.0 - sqlite3BtreePayload@Base 3.37.0 - sqlite3BtreePayloadChecked@Base 3.37.0 - sqlite3BtreePayloadFetch@Base 3.37.0 - sqlite3BtreePayloadSize@Base 3.37.0 - sqlite3BtreePrevious@Base 3.37.0 - sqlite3BtreePutData@Base 3.37.0 - sqlite3BtreeRollback@Base 3.37.0 - sqlite3BtreeRowCountEst@Base 3.37.0 - sqlite3BtreeSavepoint@Base 3.37.0 - sqlite3BtreeSchema@Base 3.37.0 - sqlite3BtreeSchemaLocked@Base 3.37.0 - sqlite3BtreeSecureDelete@Base 3.37.0 - sqlite3BtreeSetAutoVacuum@Base 3.37.0 - sqlite3BtreeSetCacheSize@Base 3.37.0 - (arch=!hurd-any !kfreebsd-any)sqlite3BtreeSetMmapLimit@Base 3.37.0 - sqlite3BtreeSetPageSize@Base 3.37.0 - sqlite3BtreeSetPagerFlags@Base 3.37.0 - sqlite3BtreeSetSpillSize@Base 3.37.0 - sqlite3BtreeSetVersion@Base 3.37.0 - sqlite3BtreeSharable@Base 3.37.0 - sqlite3BtreeTableMoveto@Base 3.37.0 - sqlite3BtreeTransferRow@Base 3.37.0 - sqlite3BtreeTripAllCursors@Base 3.37.0 - sqlite3BtreeTxnState@Base 3.37.0 - sqlite3BtreeUpdateMeta@Base 3.37.0 - sqlite3BuiltinFunctions@Base 3.37.0 - sqlite3CantopenError@Base 3.37.0 - sqlite3ChangeCookie@Base 3.37.0 - sqlite3CheckCollSeq@Base 3.37.0 - sqlite3CheckObjectName@Base 3.37.0 - sqlite3Checkpoint@Base 3.37.0 - sqlite3ClearOnOrUsing@Base 3.39.0 - sqlite3ClearTempRegCache@Base 3.37.0 - sqlite3CloseExtensions@Base 3.37.0 - sqlite3CloseSavepoints@Base 3.37.0 - sqlite3CodeChangeCount@Base 3.38.0 - sqlite3CodeDropTable@Base 3.37.0 - sqlite3CodeRhsOfIN@Base 3.37.0 - sqlite3CodeRowTrigger@Base 3.37.0 - sqlite3CodeRowTriggerDirect@Base 3.37.0 - sqlite3CodeSubselect@Base 3.37.0 - sqlite3CodeVerifyNamedSchema@Base 3.37.0 - sqlite3CodeVerifySchema@Base 3.37.0 - sqlite3CollapseDatabaseArray@Base 3.37.0 - sqlite3ColumnColl@Base 3.37.0 - sqlite3ColumnDefault@Base 3.37.0 - sqlite3ColumnExpr@Base 3.37.0 - sqlite3ColumnIndex@Base 3.37.0 - sqlite3ColumnSetColl@Base 3.37.0 - sqlite3ColumnSetExpr@Base 3.37.0 - sqlite3ColumnType@Base 3.37.0 - sqlite3ColumnsFromExprList@Base 3.37.0 - sqlite3CommitInternalChanges@Base 3.37.0 - sqlite3CompareAffinity@Base 3.37.0 - sqlite3CompileOptions@Base 3.37.0 - sqlite3CompleteInsertion@Base 3.37.0 - sqlite3ComputeGeneratedColumns@Base 3.37.0 - sqlite3Config@Base 3.37.0 - sqlite3ConnectionBlocked@Base 3.37.0 - sqlite3ConnectionClosed@Base 3.37.0 - sqlite3ConnectionUnlocked@Base 3.37.0 - sqlite3CorruptError@Base 3.37.0 - sqlite3CreateColumnExpr@Base 3.37.0 - sqlite3CreateForeignKey@Base 3.37.0 - sqlite3CreateFunc@Base 3.37.0 - sqlite3CreateIndex@Base 3.37.0 - sqlite3CreateView@Base 3.37.0 - sqlite3CteDelete@Base 3.37.0 - sqlite3CteNew@Base 3.37.0 - sqlite3CtypeMap@Base 3.37.0 - sqlite3DbFree@Base 3.37.0 - sqlite3DbFreeNN@Base 3.37.0 - sqlite3DbIsNamed@Base 3.37.0 - sqlite3DbMallocRaw@Base 3.37.0 - sqlite3DbMallocRawNN@Base 3.37.0 - sqlite3DbMallocSize@Base 3.37.0 - sqlite3DbMallocZero@Base 3.37.0 - sqlite3DbNNFreeNN@Base 3.40.0 - sqlite3DbNameToBtree@Base 3.37.0 - sqlite3DbRealloc@Base 3.37.0 - sqlite3DbReallocOrFree@Base 3.37.0 - sqlite3DbSpanDup@Base 3.37.0 - sqlite3DbStrDup@Base 3.37.0 - sqlite3DbStrNDup@Base 3.37.0 - sqlite3DbstatRegister@Base 3.37.0 - sqlite3DecOrHexToI64@Base 3.37.0 - sqlite3DefaultMutex@Base 3.37.0 - sqlite3DefaultRowEst@Base 3.37.0 - sqlite3DeferForeignKey@Base 3.37.0 - sqlite3DeleteColumnNames@Base 3.37.0 - sqlite3DeleteFrom@Base 3.37.0 - sqlite3DeleteIndexSamples@Base 3.37.0 - sqlite3DeleteTable@Base 3.37.0 - sqlite3DeleteTrigger@Base 3.37.0 - sqlite3DeleteTriggerStep@Base 3.37.0 - sqlite3Dequote@Base 3.37.0 - sqlite3DequoteExpr@Base 3.37.0 - sqlite3DequoteToken@Base 3.37.0 - sqlite3Detach@Base 3.37.0 - sqlite3DropIndex@Base 3.37.0 - sqlite3DropTable@Base 3.37.0 - sqlite3DropTrigger@Base 3.37.0 - sqlite3DropTriggerPtr@Base 3.37.0 - sqlite3EndBenignMalloc@Base 3.37.0 - sqlite3EndTable@Base 3.37.0 - sqlite3EndTransaction@Base 3.37.0 - sqlite3ErrStr@Base 3.37.0 - sqlite3Error@Base 3.37.0 - sqlite3ErrorClear@Base 3.37.0 - sqlite3ErrorMsg@Base 3.37.0 - sqlite3ErrorToParser@Base 3.37.0 - sqlite3ErrorWithMsg@Base 3.37.0 - sqlite3ExpandSubquery@Base 3.37.0 - sqlite3ExpirePreparedStatements@Base 3.37.0 - sqlite3Expr@Base 3.37.0 - sqlite3ExprAddCollateString@Base 3.37.0 - sqlite3ExprAddCollateToken@Base 3.37.0 - sqlite3ExprAffinity@Base 3.37.0 - sqlite3ExprAlloc@Base 3.37.0 - sqlite3ExprAnalyzeAggList@Base 3.37.0 - sqlite3ExprAnalyzeAggregates@Base 3.37.0 - sqlite3ExprAnd@Base 3.37.0 - sqlite3ExprAssignVarNumber@Base 3.37.0 - sqlite3ExprAttachSubtrees@Base 3.37.0 - sqlite3ExprCanBeNull@Base 3.37.0 - sqlite3ExprCheckHeight@Base 3.37.0 - sqlite3ExprCheckIN@Base 3.37.0 - sqlite3ExprCode@Base 3.37.0 - sqlite3ExprCodeCopy@Base 3.37.0 - sqlite3ExprCodeExprList@Base 3.37.0 - sqlite3ExprCodeFactorable@Base 3.37.0 - sqlite3ExprCodeGeneratedColumn@Base 3.37.0 - sqlite3ExprCodeGetColumn@Base 3.37.0 - sqlite3ExprCodeGetColumnOfTable@Base 3.37.0 - sqlite3ExprCodeLoadIndexColumn@Base 3.37.0 - sqlite3ExprCodeMove@Base 3.37.0 - sqlite3ExprCodeRunJustOnce@Base 3.37.0 - sqlite3ExprCodeTarget@Base 3.37.0 - sqlite3ExprCodeTemp@Base 3.37.0 - sqlite3ExprColUsed@Base 3.37.0 - sqlite3ExprCollSeq@Base 3.37.0 - sqlite3ExprCollSeqMatch@Base 3.37.0 - sqlite3ExprCompare@Base 3.37.0 - sqlite3ExprCompareCollSeq@Base 3.37.0 - sqlite3ExprCompareSkip@Base 3.37.0 - sqlite3ExprCoveredByIndex@Base 3.37.0 - sqlite3ExprDataType@Base 3.42.0 - sqlite3ExprDeferredDelete@Base 3.37.0 - sqlite3ExprDelete@Base 3.37.0 - sqlite3ExprDup@Base 3.37.0 - sqlite3ExprForVectorField@Base 3.37.0 - sqlite3ExprFunction@Base 3.37.0 - sqlite3ExprFunctionUsable@Base 3.37.0 - sqlite3ExprIdToTrueFalse@Base 3.37.0 - sqlite3ExprIfFalse@Base 3.37.0 - sqlite3ExprIfFalseDup@Base 3.37.0 - sqlite3ExprIfTrue@Base 3.37.0 - sqlite3ExprImpliesExpr@Base 3.37.0 - sqlite3ExprImpliesNonNullRow@Base 3.37.0 - sqlite3ExprIsConstant@Base 3.37.0 - sqlite3ExprIsConstantNotJoin@Base 3.37.0 - sqlite3ExprIsConstantOrFunction@Base 3.37.0 - sqlite3ExprIsConstantOrGroupBy@Base 3.37.0 - sqlite3ExprIsInteger@Base 3.37.0 - sqlite3ExprIsSingleTableConstraint@Base 3.42.0 - sqlite3ExprIsTableConstant@Base 3.37.0 - sqlite3ExprIsVector@Base 3.37.0 - sqlite3ExprListAppend@Base 3.37.0 - sqlite3ExprListAppendGrow@Base 3.37.0 - sqlite3ExprListAppendNew@Base 3.37.0 - sqlite3ExprListAppendVector@Base 3.37.0 - sqlite3ExprListCheckLength@Base 3.37.0 - sqlite3ExprListCompare@Base 3.37.0 - sqlite3ExprListDelete@Base 3.37.0 - sqlite3ExprListDup@Base 3.37.0 - sqlite3ExprListFlags@Base 3.37.0 - sqlite3ExprListSetName@Base 3.37.0 - sqlite3ExprListSetSortOrder@Base 3.37.0 - sqlite3ExprListSetSpan@Base 3.37.0 - sqlite3ExprListToValues@Base 3.37.0 - sqlite3ExprNNCollSeq@Base 3.37.0 - sqlite3ExprNeedsNoAffinityChange@Base 3.37.0 - sqlite3ExprReferencesUpdatedColumn@Base 3.37.0 - sqlite3ExprSetHeightAndFlags@Base 3.37.0 - sqlite3ExprSimplifiedAndOr@Base 3.37.0 - sqlite3ExprSkipCollate@Base 3.37.0 - sqlite3ExprSkipCollateAndLikely@Base 3.37.0 - sqlite3ExprTruthValue@Base 3.37.0 - sqlite3ExprUnmapAndDelete@Base 3.37.0 - sqlite3ExprVectorSize@Base 3.37.0 - sqlite3ExprWalkNoop@Base 3.37.0 - sqlite3FaultSim@Base 3.37.0 - sqlite3FindCollSeq@Base 3.37.0 - sqlite3FindDb@Base 3.37.0 - sqlite3FindDbName@Base 3.37.0 - sqlite3FindFunction@Base 3.37.0 - sqlite3FindInIndex@Base 3.37.0 - sqlite3FindIndex@Base 3.37.0 - sqlite3FindTable@Base 3.37.0 - sqlite3FinishCoding@Base 3.37.0 - sqlite3FinishTrigger@Base 3.37.0 - sqlite3FixExpr@Base 3.37.0 - sqlite3FixInit@Base 3.37.0 - sqlite3FixSelect@Base 3.37.0 - sqlite3FixSrcList@Base 3.37.0 - sqlite3FixTriggerStep@Base 3.37.0 - sqlite3FkActions@Base 3.37.0 - sqlite3FkCheck@Base 3.37.0 - sqlite3FkClearTriggerCache@Base 3.37.2 - sqlite3FkDelete@Base 3.37.0 - sqlite3FkDropTable@Base 3.37.0 - sqlite3FkLocateIndex@Base 3.37.0 - sqlite3FkOldmask@Base 3.37.0 - sqlite3FkReferences@Base 3.37.0 - sqlite3FkRequired@Base 3.37.0 - sqlite3FreeIndex@Base 3.37.0 - sqlite3Fts3AllSegdirs@Base 3.37.0 - sqlite3Fts3CacheDeferredDoclists@Base 3.37.0 - sqlite3Fts3CreateStatTable@Base 3.37.0 - sqlite3Fts3DeferToken@Base 3.37.0 - sqlite3Fts3DeferredTokenList@Base 3.37.0 - sqlite3Fts3Dequote@Base 3.37.0 - sqlite3Fts3DoclistNext@Base 3.37.0 - sqlite3Fts3DoclistPrev@Base 3.37.0 - sqlite3Fts3ErrMsg@Base 3.37.0 - sqlite3Fts3EvalPhraseCleanup@Base 3.37.0 - sqlite3Fts3EvalPhrasePoslist@Base 3.37.0 - sqlite3Fts3EvalPhraseStats@Base 3.37.0 - sqlite3Fts3EvalTestDeferred@Base 3.37.0 - sqlite3Fts3ExprFree@Base 3.37.0 - sqlite3Fts3ExprIterate@Base 3.42.0 - sqlite3Fts3ExprParse@Base 3.37.0 - sqlite3Fts3FirstFilter@Base 3.37.0 - sqlite3Fts3FreeDeferredDoclists@Base 3.37.0 - sqlite3Fts3FreeDeferredTokens@Base 3.37.0 - sqlite3Fts3GetVarint32@Base 3.37.0 - sqlite3Fts3GetVarint@Base 3.37.0 - sqlite3Fts3GetVarintBounded@Base 3.37.0 - sqlite3Fts3GetVarintU@Base 3.37.0 - sqlite3Fts3HashClear@Base 3.37.0 - sqlite3Fts3HashFind@Base 3.37.0 - sqlite3Fts3HashFindElem@Base 3.37.0 - sqlite3Fts3HashInit@Base 3.37.0 - sqlite3Fts3HashInsert@Base 3.37.0 - sqlite3Fts3Incrmerge@Base 3.37.0 - sqlite3Fts3Init@Base 3.37.0 - sqlite3Fts3InitAux@Base 3.37.0 - sqlite3Fts3InitHashTable@Base 3.37.0 - sqlite3Fts3InitTok@Base 3.37.0 - sqlite3Fts3InitTokenizer@Base 3.37.0 - sqlite3Fts3IsIdChar@Base 3.37.0 - sqlite3Fts3MIBufferFree@Base 3.37.0 - sqlite3Fts3MallocZero@Base 3.37.0 - sqlite3Fts3Matchinfo@Base 3.37.0 - sqlite3Fts3MaxLevel@Base 3.37.0 - sqlite3Fts3MsrIncrNext@Base 3.37.0 - sqlite3Fts3MsrIncrRestart@Base 3.37.0 - sqlite3Fts3MsrIncrStart@Base 3.37.0 - sqlite3Fts3MsrOvfl@Base 3.37.0 - sqlite3Fts3NextToken@Base 3.37.0 - sqlite3Fts3Offsets@Base 3.37.0 - sqlite3Fts3OpenTokenizer@Base 3.37.0 - sqlite3Fts3Optimize@Base 3.37.0 - sqlite3Fts3PendingTermsClear@Base 3.37.0 - sqlite3Fts3PendingTermsFlush@Base 3.37.0 - sqlite3Fts3PorterTokenizerModule@Base 3.37.0 - sqlite3Fts3PutVarint@Base 3.37.0 - sqlite3Fts3ReadBlock@Base 3.37.0 - sqlite3Fts3ReadInt@Base 3.37.0 - sqlite3Fts3SegReaderCursor@Base 3.37.0 - sqlite3Fts3SegReaderFinish@Base 3.37.0 - sqlite3Fts3SegReaderFree@Base 3.37.0 - sqlite3Fts3SegReaderNew@Base 3.37.0 - sqlite3Fts3SegReaderPending@Base 3.37.0 - sqlite3Fts3SegReaderStart@Base 3.37.0 - sqlite3Fts3SegReaderStep@Base 3.37.0 - sqlite3Fts3SegmentsClose@Base 3.37.0 - sqlite3Fts3SelectDocsize@Base 3.37.0 - sqlite3Fts3SelectDoctotal@Base 3.37.0 - sqlite3Fts3SimpleTokenizerModule@Base 3.37.0 - sqlite3Fts3Snippet@Base 3.37.0 - sqlite3Fts3UnicodeTokenizer@Base 3.37.0 - sqlite3Fts3UpdateMethod@Base 3.37.0 - sqlite3Fts3VarintLen@Base 3.37.0 - sqlite3Fts5Init@Base 3.37.0 - sqlite3FtsUnicodeFold@Base 3.37.0 - sqlite3FtsUnicodeIsalnum@Base 3.37.0 - sqlite3FtsUnicodeIsdiacritic@Base 3.37.0 - sqlite3FunctionSearch@Base 3.37.0 - sqlite3GenerateColumnNames@Base 3.37.0 - sqlite3GenerateConstraintChecks@Base 3.37.0 - sqlite3GenerateIndexKey@Base 3.37.0 - sqlite3GenerateRowDelete@Base 3.37.0 - sqlite3GenerateRowIndexDelete@Base 3.37.0 - sqlite3Get4byte@Base 3.37.0 - sqlite3GetBoolean@Base 3.37.0 - sqlite3GetCollSeq@Base 3.37.0 - sqlite3GetInt32@Base 3.37.0 - sqlite3GetTempRange@Base 3.37.0 - sqlite3GetTempReg@Base 3.37.0 - sqlite3GetToken@Base 3.37.0 - sqlite3GetUInt32@Base 3.37.0 - sqlite3GetVTable@Base 3.37.0 - sqlite3GetVarint32@Base 3.37.0 - sqlite3GetVarint@Base 3.37.0 - sqlite3GetVdbe@Base 3.37.0 - sqlite3HaltConstraint@Base 3.37.0 - sqlite3HasExplicitNulls@Base 3.37.0 - sqlite3HashClear@Base 3.37.0 - sqlite3HashFind@Base 3.37.0 - sqlite3HashInit@Base 3.37.0 - sqlite3HashInsert@Base 3.37.0 - sqlite3HeaderSizeBtree@Base 3.37.0 - sqlite3HeaderSizePcache1@Base 3.37.0 - sqlite3HeaderSizePcache@Base 3.37.0 - sqlite3HeapNearlyFull@Base 3.37.0 - sqlite3HexToBlob@Base 3.37.0 - sqlite3HexToInt@Base 3.37.0 - sqlite3IdListAppend@Base 3.37.0 - sqlite3IdListDelete@Base 3.37.0 - sqlite3IdListDup@Base 3.37.0 - sqlite3IdListIndex@Base 3.37.0 - sqlite3IndexAffinityOk@Base 3.37.0 - sqlite3IndexAffinityStr@Base 3.37.0 - sqlite3IndexHasDuplicateRootPage@Base 3.37.0 - sqlite3IndexedByLookup@Base 3.37.0 - sqlite3Init@Base 3.37.0 - sqlite3InitCallback@Base 3.37.0 - sqlite3InitOne@Base 3.37.0 - sqlite3Insert@Base 3.37.0 - sqlite3InsertBuiltinFuncs@Base 3.37.0 - sqlite3Int64ToText@Base 3.37.0 - sqlite3IntFloatCompare@Base 3.37.0 - sqlite3InvokeBusyHandler@Base 3.37.0 - sqlite3IsBinary@Base 3.37.0 - sqlite3IsIdChar@Base 3.37.0 - sqlite3IsLikeFunction@Base 3.37.0 - sqlite3IsMemdb@Base 3.40.1 - sqlite3IsNaN@Base 3.37.0 - sqlite3IsReadOnly@Base 3.37.0 - sqlite3IsRowid@Base 3.37.0 - sqlite3IsShadowTableOf@Base 3.37.0 - sqlite3IsTrueOrFalse@Base 3.37.0 - sqlite3JoinType@Base 3.37.0 - sqlite3JournalIsInMemory@Base 3.37.0 - sqlite3JournalModename@Base 3.37.0 - sqlite3JournalOpen@Base 3.37.0 - sqlite3JournalSize@Base 3.37.0 - sqlite3JsonTableFunctions@Base 3.38.0 - sqlite3KeyInfoAlloc@Base 3.37.0 - sqlite3KeyInfoFromExprList@Base 3.37.0 - sqlite3KeyInfoOfIndex@Base 3.37.0 - sqlite3KeyInfoRef@Base 3.37.0 - sqlite3KeyInfoUnref@Base 3.37.0 - sqlite3KeywordCode@Base 3.37.0 - sqlite3LeaveMutexAndCloseZombie@Base 3.37.0 - sqlite3LimitWhere@Base 3.37.0 - sqlite3LocateCollSeq@Base 3.37.0 - sqlite3LocateTable@Base 3.37.0 - sqlite3LocateTableItem@Base 3.37.0 - sqlite3LogEst@Base 3.37.0 - sqlite3LogEstAdd@Base 3.37.0 - sqlite3LogEstFromDouble@Base 3.37.0 - sqlite3LogEstToInt@Base 3.38.0 - sqlite3LookasideUsed@Base 3.37.0 - sqlite3MPrintf@Base 3.37.0 - sqlite3Malloc@Base 3.37.0 - sqlite3MallocEnd@Base 3.37.0 - sqlite3MallocInit@Base 3.37.0 - sqlite3MallocMutex@Base 3.37.0 - sqlite3MallocSize@Base 3.37.0 - sqlite3MallocZero@Base 3.37.0 - sqlite3MarkAllShadowTablesOf@Base 3.37.0 - sqlite3MatchEName@Base 3.37.0 - sqlite3MaterializeView@Base 3.37.0 - sqlite3MayAbort@Base 3.37.0 - sqlite3MemCompare@Base 3.37.0 - sqlite3MemJournalOpen@Base 3.37.0 - sqlite3MemSetDefault@Base 3.37.0 - sqlite3MemdbInit@Base 3.37.0 - sqlite3MemoryBarrier@Base 3.37.0 - sqlite3MisuseError@Base 3.37.0 - sqlite3MulInt64@Base 3.37.0 - sqlite3MultiWrite@Base 3.37.0 - sqlite3MutexAlloc@Base 3.37.0 - sqlite3MutexEnd@Base 3.37.0 - sqlite3MutexInit@Base 3.37.0 - sqlite3NameFromToken@Base 3.37.0 - sqlite3NestedParse@Base 3.37.0 - sqlite3NoopDestructor@Base 3.37.0 - sqlite3NoopMutex@Base 3.37.0 - sqlite3NotPureFunc@Base 3.37.0 - sqlite3OomClear@Base 3.37.0 - sqlite3OomFault@Base 3.37.0 - sqlite3OpcodeName@Base 3.37.0 - sqlite3OpcodeProperty@Base 3.37.0 - sqlite3OpenSchemaTable@Base 3.37.0 - sqlite3OpenTable@Base 3.37.0 - sqlite3OpenTableAndIndices@Base 3.37.0 - sqlite3OpenTempDatabase@Base 3.37.0 - sqlite3OsAccess@Base 3.37.0 - sqlite3OsCheckReservedLock@Base 3.37.0 - sqlite3OsClose@Base 3.37.0 - sqlite3OsCloseFree@Base 3.37.0 - sqlite3OsCurrentTimeInt64@Base 3.37.0 - sqlite3OsDelete@Base 3.37.0 - sqlite3OsDeviceCharacteristics@Base 3.37.0 - sqlite3OsDlClose@Base 3.37.0 - sqlite3OsDlError@Base 3.37.0 - sqlite3OsDlOpen@Base 3.37.0 - sqlite3OsDlSym@Base 3.37.0 - sqlite3OsFetch@Base 3.37.0 - sqlite3OsFileControl@Base 3.37.0 - sqlite3OsFileControlHint@Base 3.37.0 - sqlite3OsFileSize@Base 3.37.0 - sqlite3OsFullPathname@Base 3.37.0 - sqlite3OsGetLastError@Base 3.37.0 - sqlite3OsInit@Base 3.37.0 - sqlite3OsLock@Base 3.37.0 - sqlite3OsOpen@Base 3.37.0 - sqlite3OsOpenMalloc@Base 3.37.0 - sqlite3OsRandomness@Base 3.37.0 - sqlite3OsRead@Base 3.37.0 - sqlite3OsSectorSize@Base 3.37.0 - sqlite3OsShmBarrier@Base 3.37.0 - sqlite3OsShmLock@Base 3.37.0 - sqlite3OsShmMap@Base 3.37.0 - sqlite3OsShmUnmap@Base 3.37.0 - sqlite3OsSleep@Base 3.37.0 - sqlite3OsSync@Base 3.37.0 - sqlite3OsTruncate@Base 3.37.0 - sqlite3OsUnfetch@Base 3.37.0 - sqlite3OsUnlock@Base 3.37.0 - sqlite3OsWrite@Base 3.37.0 - sqlite3PCacheBufferSetup@Base 3.37.0 - sqlite3PCachePercentDirty@Base 3.37.0 - sqlite3PCacheSetDefault@Base 3.37.0 - sqlite3PExpr@Base 3.37.0 - sqlite3PExprAddSelect@Base 3.37.0 - sqlite3PageFree@Base 3.37.0 - sqlite3PageMalloc@Base 3.37.0 - sqlite3PagerBackupPtr@Base 3.37.0 - sqlite3PagerBegin@Base 3.37.0 - sqlite3PagerCacheStat@Base 3.37.0 - sqlite3PagerCheckpoint@Base 3.37.0 - sqlite3PagerClearCache@Base 3.37.0 - sqlite3PagerClose@Base 3.37.0 - sqlite3PagerCloseWal@Base 3.37.0 - sqlite3PagerCommitPhaseOne@Base 3.37.0 - sqlite3PagerCommitPhaseTwo@Base 3.37.0 - sqlite3PagerDataVersion@Base 3.37.0 - sqlite3PagerDontWrite@Base 3.37.0 - sqlite3PagerExclusiveLock@Base 3.37.0 - sqlite3PagerFile@Base 3.37.0 - sqlite3PagerFilename@Base 3.37.0 - sqlite3PagerFlush@Base 3.37.0 - sqlite3PagerGet@Base 3.37.0 - sqlite3PagerGetData@Base 3.37.0 - sqlite3PagerGetExtra@Base 3.37.0 - sqlite3PagerGetJournalMode@Base 3.37.0 - sqlite3PagerIsMemdb@Base 3.37.0 - sqlite3PagerIsreadonly@Base 3.37.0 - sqlite3PagerJournalSizeLimit@Base 3.37.0 - sqlite3PagerJournalname@Base 3.37.0 - sqlite3PagerJrnlFile@Base 3.37.0 - sqlite3PagerLockingMode@Base 3.37.0 - sqlite3PagerLookup@Base 3.37.0 - sqlite3PagerMaxPageCount@Base 3.37.0 - sqlite3PagerMemUsed@Base 3.37.0 - sqlite3PagerMovepage@Base 3.37.0 - sqlite3PagerOkToChangeJournalMode@Base 3.37.0 - sqlite3PagerOpen@Base 3.37.0 - sqlite3PagerOpenSavepoint@Base 3.37.0 - sqlite3PagerOpenWal@Base 3.37.0 - sqlite3PagerPageRefcount@Base 3.37.0 - sqlite3PagerPagecount@Base 3.37.0 - sqlite3PagerReadFileheader@Base 3.37.0 - sqlite3PagerRef@Base 3.37.0 - sqlite3PagerRekey@Base 3.37.0 - sqlite3PagerRollback@Base 3.37.0 - sqlite3PagerSavepoint@Base 3.37.0 - sqlite3PagerSetBusyHandler@Base 3.37.0 - sqlite3PagerSetCachesize@Base 3.37.0 - sqlite3PagerSetFlags@Base 3.37.0 - sqlite3PagerSetJournalMode@Base 3.37.0 - sqlite3PagerSetMmapLimit@Base 3.37.0 - sqlite3PagerSetPagesize@Base 3.37.0 - sqlite3PagerSetSpillsize@Base 3.37.0 - sqlite3PagerSharedLock@Base 3.37.0 - sqlite3PagerShrink@Base 3.37.0 - sqlite3PagerSync@Base 3.37.0 - sqlite3PagerTempSpace@Base 3.37.0 - sqlite3PagerTruncateImage@Base 3.37.0 - sqlite3PagerUnref@Base 3.37.0 - sqlite3PagerUnrefNotNull@Base 3.37.0 - sqlite3PagerUnrefPageOne@Base 3.37.0 - sqlite3PagerVfs@Base 3.37.0 - sqlite3PagerWalCallback@Base 3.37.0 - sqlite3PagerWalSupported@Base 3.37.0 - sqlite3PagerWrite@Base 3.37.0 - sqlite3ParseObjectInit@Base 3.38.0 - sqlite3ParseObjectReset@Base 3.38.0 - sqlite3ParseUri@Base 3.37.0 - sqlite3Parser@Base 3.37.0 - sqlite3ParserAddCleanup@Base 3.37.0 - sqlite3ParserAlloc@Base 3.37.0 - sqlite3ParserFallback@Base 3.37.0 - sqlite3ParserFinalize@Base 3.37.0 - sqlite3ParserFree@Base 3.37.0 - sqlite3ParserInit@Base 3.37.0 - sqlite3Pcache1Mutex@Base 3.37.0 - sqlite3PcacheCleanAll@Base 3.37.0 - sqlite3PcacheClear@Base 3.37.0 - sqlite3PcacheClearSyncFlags@Base 3.37.0 - sqlite3PcacheClearWritable@Base 3.37.0 - sqlite3PcacheClose@Base 3.37.0 - sqlite3PcacheDirtyList@Base 3.37.0 - sqlite3PcacheDrop@Base 3.37.0 - sqlite3PcacheFetch@Base 3.37.0 - sqlite3PcacheFetchFinish@Base 3.37.0 - sqlite3PcacheFetchStress@Base 3.37.0 - sqlite3PcacheInitialize@Base 3.37.0 - sqlite3PcacheMakeClean@Base 3.37.0 - sqlite3PcacheMakeDirty@Base 3.37.0 - sqlite3PcacheMove@Base 3.37.0 - sqlite3PcacheOpen@Base 3.37.0 - sqlite3PcachePageRefcount@Base 3.37.0 - sqlite3PcachePagecount@Base 3.37.0 - sqlite3PcacheRef@Base 3.37.0 - sqlite3PcacheRefCount@Base 3.37.0 - sqlite3PcacheRelease@Base 3.37.0 - sqlite3PcacheSetCachesize@Base 3.37.0 - sqlite3PcacheSetPageSize@Base 3.37.0 - sqlite3PcacheSetSpillsize@Base 3.37.0 - sqlite3PcacheShrink@Base 3.37.0 - sqlite3PcacheShutdown@Base 3.37.0 - sqlite3PcacheSize@Base 3.37.0 - sqlite3PcacheTruncate@Base 3.37.0 - sqlite3PendingByte@Base 3.37.0 - sqlite3Pragma@Base 3.37.0 - sqlite3PragmaVtabRegister@Base 3.37.0 - sqlite3PreferredTableName@Base 3.37.0 - sqlite3PrimaryKeyIndex@Base 3.37.0 - sqlite3PrngRestoreState@Base 3.37.0 - sqlite3PrngSaveState@Base 3.37.0 - sqlite3ProgressCheck@Base 3.42.0 - sqlite3Put4byte@Base 3.37.0 - sqlite3PutVarint@Base 3.37.0 - sqlite3QuoteValue@Base 3.38.0 - sqlite3ReadOnlyShadowTables@Base 3.37.0 - sqlite3ReadSchema@Base 3.37.0 - sqlite3RealSameAsInt@Base 3.37.0 - sqlite3RealToI64@Base 3.40.0 - sqlite3Realloc@Base 3.37.0 - sqlite3RecordErrorByteOffset@Base 3.38.0 - sqlite3RecordErrorOffsetOfExpr@Base 3.38.0 - sqlite3ReferencesSrcList@Base 3.37.0 - sqlite3RegisterBuiltinFunctions@Base 3.37.0 - sqlite3RegisterDateTimeFunctions@Base 3.37.0 - sqlite3RegisterJsonFunctions@Base 3.38.0 - sqlite3RegisterLikeFunctions@Base 3.37.0 - sqlite3RegisterPerConnectionBuiltinFunctions@Base 3.37.0 - sqlite3Reindex@Base 3.37.0 - sqlite3ReleaseTempRange@Base 3.37.0 - sqlite3ReleaseTempReg@Base 3.37.0 - sqlite3RenameExprUnmap@Base 3.37.0 - sqlite3RenameExprlistUnmap@Base 3.37.0 - sqlite3RenameTokenMap@Base 3.37.0 - sqlite3RenameTokenRemap@Base 3.37.0 - sqlite3ReportError@Base 3.37.0 - sqlite3Reprepare@Base 3.37.0 - sqlite3ResetAllSchemasOfConnection@Base 3.37.0 - sqlite3ResetOneSchema@Base 3.37.0 - sqlite3ResolveExprListNames@Base 3.37.0 - sqlite3ResolveExprNames@Base 3.37.0 - sqlite3ResolveOrderGroupBy@Base 3.37.0 - sqlite3ResolvePartIdxLabel@Base 3.37.0 - sqlite3ResolveSelectNames@Base 3.37.0 - sqlite3ResolveSelfReference@Base 3.37.0 - sqlite3ResultIntReal@Base 3.37.0 - sqlite3ResultSetOfSelect@Base 3.37.0 - sqlite3ResultStrAccum@Base 3.37.0 - sqlite3RollbackAll@Base 3.37.0 - sqlite3RootPageMoved@Base 3.37.0 - sqlite3RowSetClear@Base 3.37.0 - sqlite3RowSetDelete@Base 3.37.0 - sqlite3RowSetInit@Base 3.37.0 - sqlite3RowSetInsert@Base 3.37.0 - sqlite3RowSetNext@Base 3.37.0 - sqlite3RowSetTest@Base 3.37.0 - sqlite3RowidConstraint@Base 3.37.0 - sqlite3RtreeInit@Base 3.37.0 - sqlite3RunParser@Base 3.37.0 - sqlite3RunVacuum@Base 3.37.0 - sqlite3SafetyCheckOk@Base 3.37.0 - sqlite3SafetyCheckSickOrOk@Base 3.37.0 - sqlite3Savepoint@Base 3.37.0 - sqlite3SchemaClear@Base 3.37.0 - sqlite3SchemaGet@Base 3.37.0 - sqlite3SchemaToIndex@Base 3.37.0 - sqlite3SectorSize@Base 3.37.0 - sqlite3Select@Base 3.37.0 - sqlite3SelectDelete@Base 3.37.0 - sqlite3SelectDestInit@Base 3.37.0 - sqlite3SelectDup@Base 3.37.0 - sqlite3SelectExprHeight@Base 3.37.0 - sqlite3SelectNew@Base 3.37.0 - sqlite3SelectOpName@Base 3.37.0 - sqlite3SelectPopWith@Base 3.37.0 - sqlite3SelectPrep@Base 3.37.0 - sqlite3SelectWalkFail@Base 3.37.0 - sqlite3SelectWalkNoop@Base 3.37.0 - sqlite3SelectWrongNumTermsError@Base 3.37.0 - sqlite3SetJoinExpr@Base 3.37.0 - sqlite3SetString@Base 3.37.0 - sqlite3SetTextEncoding@Base 3.37.0 - sqlite3ShadowTableName@Base 3.37.0 - sqlite3SmallTypeSizes@Base 3.39.0 - sqlite3SrcItemColumnUsed@Base 3.39.0 - sqlite3SrcListAppend@Base 3.37.0 - sqlite3SrcListAppendFromTerm@Base 3.37.0 - sqlite3SrcListAppendList@Base 3.37.0 - sqlite3SrcListAssignCursors@Base 3.37.0 - sqlite3SrcListDelete@Base 3.37.0 - sqlite3SrcListDup@Base 3.37.0 - sqlite3SrcListEnlarge@Base 3.37.0 - sqlite3SrcListFuncArgs@Base 3.37.0 - sqlite3SrcListIndexedBy@Base 3.37.0 - sqlite3SrcListLookup@Base 3.37.0 - sqlite3SrcListShiftJoinType@Base 3.37.0 - sqlite3StartTable@Base 3.37.0 - sqlite3StatusDown@Base 3.37.0 - sqlite3StatusHighwater@Base 3.37.0 - sqlite3StatusUp@Base 3.37.0 - sqlite3StatusValue@Base 3.37.0 - sqlite3StdType@Base 3.37.0 - sqlite3StdTypeAffinity@Base 3.37.0 - sqlite3StdTypeLen@Base 3.37.0 - sqlite3StmtCurrentTime@Base 3.37.0 - sqlite3StmtVtabInit@Base 3.37.0 - sqlite3StorageColumnToTable@Base 3.37.0 - sqlite3StrAccumEnlarge@Base 3.38.0 - sqlite3StrAccumFinish@Base 3.37.0 - sqlite3StrAccumInit@Base 3.37.0 - sqlite3StrAccumSetError@Base 3.37.0 - sqlite3StrBINARY@Base 3.37.0 - sqlite3StrICmp@Base 3.37.0 - sqlite3StrIHash@Base 3.37.0 - sqlite3Strlen30@Base 3.37.0 - sqlite3SubInt64@Base 3.37.0 - sqlite3SubqueryColumnTypes@Base 3.42.0 - sqlite3SubselectError@Base 3.37.0 - sqlite3SystemError@Base 3.37.0 - sqlite3TableAffinity@Base 3.37.0 - sqlite3TableAffinityStr@Base 3.40.0 - sqlite3TableColumnAffinity@Base 3.37.0 - sqlite3TableColumnToIndex@Base 3.37.0 - sqlite3TableColumnToStorage@Base 3.37.0 - sqlite3TableLock@Base 3.37.0 - sqlite3TempInMemory@Base 3.37.0 - sqlite3ThreadCreate@Base 3.37.0 - sqlite3ThreadJoin@Base 3.37.0 - sqlite3TokenInit@Base 3.37.0 - sqlite3TouchRegister@Base 3.42.0 - sqlite3TransferBindings@Base 3.37.0 - sqlite3TreeTrace@Base 3.39.0 - sqlite3TriggerColmask@Base 3.37.0 - sqlite3TriggerDeleteStep@Base 3.37.0 - sqlite3TriggerInsertStep@Base 3.37.0 - sqlite3TriggerList@Base 3.37.0 - sqlite3TriggerSelectStep@Base 3.37.0 - sqlite3TriggerStepSrc@Base 3.37.0 - sqlite3TriggerUpdateStep@Base 3.37.0 - sqlite3TriggersExist@Base 3.37.0 - sqlite3TwoPartName@Base 3.37.0 - sqlite3UniqueConstraint@Base 3.37.0 - sqlite3UnlinkAndDeleteIndex@Base 3.37.0 - sqlite3UnlinkAndDeleteTable@Base 3.37.0 - sqlite3UnlinkAndDeleteTrigger@Base 3.37.0 - sqlite3Update@Base 3.37.0 - sqlite3UpperToLower@Base 3.37.0 - sqlite3UpsertAnalyzeTarget@Base 3.37.0 - sqlite3UpsertDelete@Base 3.37.0 - sqlite3UpsertDoUpdate@Base 3.37.0 - sqlite3UpsertDup@Base 3.37.0 - sqlite3UpsertNew@Base 3.37.0 - sqlite3UpsertNextIsIPK@Base 3.37.0 - sqlite3UpsertOfIndex@Base 3.37.0 - sqlite3Utf16ByteLen@Base 3.37.0 - sqlite3Utf16to8@Base 3.37.0 - sqlite3Utf8CharLen@Base 3.37.0 - sqlite3Utf8Read@Base 3.37.0 - sqlite3VListAdd@Base 3.37.0 - sqlite3VListNameToNum@Base 3.37.0 - sqlite3VListNumToName@Base 3.37.0 - sqlite3VMPrintf@Base 3.37.0 - sqlite3Vacuum@Base 3.37.0 - sqlite3ValueApplyAffinity@Base 3.37.0 - sqlite3ValueBytes@Base 3.37.0 - sqlite3ValueFree@Base 3.37.0 - sqlite3ValueFromExpr@Base 3.37.0 - sqlite3ValueNew@Base 3.37.0 - sqlite3ValueSetNull@Base 3.37.0 - sqlite3ValueSetStr@Base 3.37.0 - sqlite3ValueText@Base 3.37.0 - sqlite3VarintLen@Base 3.37.0 - sqlite3VdbeAddFunctionCall@Base 3.37.0 - sqlite3VdbeAddOp0@Base 3.37.0 - sqlite3VdbeAddOp1@Base 3.37.0 - sqlite3VdbeAddOp2@Base 3.37.0 - sqlite3VdbeAddOp3@Base 3.37.0 - sqlite3VdbeAddOp4@Base 3.37.0 - sqlite3VdbeAddOp4Dup8@Base 3.37.0 - sqlite3VdbeAddOp4Int@Base 3.37.0 - sqlite3VdbeAddOpList@Base 3.37.0 - sqlite3VdbeAddParseSchemaOp@Base 3.37.0 - sqlite3VdbeAllocUnpackedRecord@Base 3.37.0 - sqlite3VdbeAppendP4@Base 3.37.0 - sqlite3VdbeBooleanValue@Base 3.37.0 - sqlite3VdbeChangeEncoding@Base 3.37.0 - sqlite3VdbeChangeOpcode@Base 3.37.0 - sqlite3VdbeChangeP1@Base 3.37.0 - sqlite3VdbeChangeP2@Base 3.37.0 - sqlite3VdbeChangeP3@Base 3.37.0 - sqlite3VdbeChangeP4@Base 3.37.0 - sqlite3VdbeChangeP5@Base 3.37.0 - sqlite3VdbeChangeToNoop@Base 3.37.0 - sqlite3VdbeCheckFk@Base 3.37.0 - sqlite3VdbeCloseStatement@Base 3.37.0 - sqlite3VdbeCountChanges@Base 3.37.0 - sqlite3VdbeCreate@Base 3.37.0 - sqlite3VdbeCurrentAddr@Base 3.37.0 - sqlite3VdbeCursorRestore@Base 3.37.0 - sqlite3VdbeDb@Base 3.37.0 - sqlite3VdbeDelete@Base 3.37.0 - sqlite3VdbeDeleteAuxData@Base 3.37.0 - sqlite3VdbeDeletePriorOpcode@Base 3.37.0 - sqlite3VdbeDisplayP4@Base 3.37.0 - sqlite3VdbeEndCoroutine@Base 3.37.0 - sqlite3VdbeEnter@Base 3.37.0 - sqlite3VdbeError@Base 3.37.0 - sqlite3VdbeExec@Base 3.37.0 - sqlite3VdbeExpandSql@Base 3.37.0 - sqlite3VdbeExplain@Base 3.37.0 - sqlite3VdbeExplainParent@Base 3.37.0 - sqlite3VdbeExplainPop@Base 3.37.0 - sqlite3VdbeFinalize@Base 3.37.0 - sqlite3VdbeFindCompare@Base 3.37.0 - sqlite3VdbeFinishMoveto@Base 3.37.0 - sqlite3VdbeFrameDelete@Base 3.37.0 - sqlite3VdbeFrameMemDel@Base 3.37.0 - sqlite3VdbeFrameRestore@Base 3.37.0 - sqlite3VdbeFreeCursor@Base 3.37.0 - sqlite3VdbeFreeCursorNN@Base 3.39.0 - sqlite3VdbeGetBoundValue@Base 3.37.0 - sqlite3VdbeGetLastOp@Base 3.40.0 - sqlite3VdbeGetOp@Base 3.37.0 - sqlite3VdbeGoto@Base 3.37.0 - sqlite3VdbeHalt@Base 3.37.0 - sqlite3VdbeHandleMovedCursor@Base 3.39.0 - sqlite3VdbeHasSubProgram@Base 3.37.0 - sqlite3VdbeIdxKeyCompare@Base 3.37.0 - sqlite3VdbeIdxRowid@Base 3.37.0 - sqlite3VdbeIntValue@Base 3.37.0 - sqlite3VdbeIntegerAffinity@Base 3.37.0 - sqlite3VdbeJumpHere@Base 3.37.0 - sqlite3VdbeJumpHereOrPopInst@Base 3.37.0 - sqlite3VdbeLeave@Base 3.37.0 - sqlite3VdbeLinkSubProgram@Base 3.37.0 - sqlite3VdbeList@Base 3.37.0 - sqlite3VdbeLoadString@Base 3.37.0 - sqlite3VdbeMakeLabel@Base 3.37.0 - sqlite3VdbeMakeReady@Base 3.37.0 - sqlite3VdbeMemAggValue@Base 3.37.0 - sqlite3VdbeMemCast@Base 3.37.0 - sqlite3VdbeMemClearAndResize@Base 3.37.0 - sqlite3VdbeMemCopy@Base 3.37.0 - sqlite3VdbeMemExpandBlob@Base 3.37.0 - sqlite3VdbeMemFinalize@Base 3.37.0 - sqlite3VdbeMemFromBtree@Base 3.37.0 - sqlite3VdbeMemFromBtreeZeroOffset@Base 3.37.0 - sqlite3VdbeMemGrow@Base 3.37.0 - sqlite3VdbeMemHandleBom@Base 3.37.0 - sqlite3VdbeMemInit@Base 3.37.0 - sqlite3VdbeMemIntegerify@Base 3.37.0 - sqlite3VdbeMemMakeWriteable@Base 3.37.0 - sqlite3VdbeMemMove@Base 3.37.0 - sqlite3VdbeMemNulTerminate@Base 3.37.0 - sqlite3VdbeMemNumerify@Base 3.37.0 - sqlite3VdbeMemRealify@Base 3.37.0 - sqlite3VdbeMemRelease@Base 3.37.0 - sqlite3VdbeMemReleaseMalloc@Base 3.39.0 - sqlite3VdbeMemSetDouble@Base 3.37.0 - sqlite3VdbeMemSetInt64@Base 3.37.0 - sqlite3VdbeMemSetNull@Base 3.37.0 - sqlite3VdbeMemSetPointer@Base 3.37.0 - sqlite3VdbeMemSetRowSet@Base 3.37.0 - sqlite3VdbeMemSetStr@Base 3.37.0 - sqlite3VdbeMemSetZeroBlob@Base 3.37.0 - sqlite3VdbeMemShallowCopy@Base 3.37.0 - sqlite3VdbeMemStringify@Base 3.37.0 - sqlite3VdbeMemTooBig@Base 3.37.0 - sqlite3VdbeMemTranslate@Base 3.37.0 - sqlite3VdbeMultiLoad@Base 3.37.0 - sqlite3VdbeNextOpcode@Base 3.37.0 - sqlite3VdbeOneByteSerialTypeLen@Base 3.37.0 - sqlite3VdbeParameterIndex@Base 3.37.0 - sqlite3VdbeParser@Base 3.37.0 - sqlite3VdbePreUpdateHook@Base 3.37.0 - sqlite3VdbePrepareFlags@Base 3.37.0 - sqlite3VdbeRealValue@Base 3.37.0 - sqlite3VdbeRecordCompare@Base 3.37.0 - sqlite3VdbeRecordCompareWithSkip@Base 3.37.0 - sqlite3VdbeRecordUnpack@Base 3.37.0 - sqlite3VdbeReset@Base 3.37.0 - sqlite3VdbeResetStepResult@Base 3.37.0 - sqlite3VdbeResolveLabel@Base 3.37.0 - sqlite3VdbeReusable@Base 3.37.0 - sqlite3VdbeRewind@Base 3.37.0 - sqlite3VdbeRunOnlyOnce@Base 3.37.0 - sqlite3VdbeSerialGet@Base 3.37.0 - sqlite3VdbeSerialTypeLen@Base 3.37.0 - sqlite3VdbeSetChanges@Base 3.37.0 - sqlite3VdbeSetColName@Base 3.37.0 - sqlite3VdbeSetNumCols@Base 3.37.0 - sqlite3VdbeSetP4KeyInfo@Base 3.37.0 - sqlite3VdbeSetSql@Base 3.37.0 - sqlite3VdbeSetVarmask@Base 3.37.0 - sqlite3VdbeSorterClose@Base 3.37.0 - sqlite3VdbeSorterCompare@Base 3.37.0 - sqlite3VdbeSorterInit@Base 3.37.0 - sqlite3VdbeSorterNext@Base 3.37.0 - sqlite3VdbeSorterReset@Base 3.37.0 - sqlite3VdbeSorterRewind@Base 3.37.0 - sqlite3VdbeSorterRowkey@Base 3.37.0 - sqlite3VdbeSorterWrite@Base 3.37.0 - sqlite3VdbeSwap@Base 3.37.0 - sqlite3VdbeTakeOpArray@Base 3.37.0 - sqlite3VdbeTransferError@Base 3.37.0 - sqlite3VdbeTypeofColumn@Base 3.40.0 - sqlite3VdbeUsesBtree@Base 3.37.0 - sqlite3VdbeValueListFree@Base 3.42.0 - sqlite3VectorErrorMsg@Base 3.37.0 - sqlite3VectorFieldSubexpr@Base 3.37.0 - sqlite3ViewGetColumnNames@Base 3.37.0 - sqlite3VtabArgExtend@Base 3.37.0 - sqlite3VtabArgInit@Base 3.37.0 - sqlite3VtabBegin@Base 3.37.0 - sqlite3VtabBeginParse@Base 3.37.0 - sqlite3VtabCallConnect@Base 3.37.0 - sqlite3VtabCallCreate@Base 3.37.0 - sqlite3VtabCallDestroy@Base 3.37.0 - sqlite3VtabClear@Base 3.37.0 - sqlite3VtabCommit@Base 3.37.0 - sqlite3VtabCreateModule@Base 3.37.0 - sqlite3VtabDisconnect@Base 3.37.0 - sqlite3VtabEponymousTableClear@Base 3.37.0 - sqlite3VtabEponymousTableInit@Base 3.37.0 - sqlite3VtabFinishParse@Base 3.37.0 - sqlite3VtabImportErrmsg@Base 3.37.0 - sqlite3VtabLock@Base 3.37.0 - sqlite3VtabMakeWritable@Base 3.37.0 - sqlite3VtabModuleUnref@Base 3.37.0 - sqlite3VtabOverloadFunction@Base 3.37.0 - sqlite3VtabRollback@Base 3.37.0 - sqlite3VtabSavepoint@Base 3.37.0 - sqlite3VtabSync@Base 3.37.0 - sqlite3VtabUnlock@Base 3.37.0 - sqlite3VtabUnlockList@Base 3.37.0 - sqlite3VtabUsesAllSchemas@Base 3.42.0 - sqlite3WalBeginReadTransaction@Base 3.37.0 - sqlite3WalBeginWriteTransaction@Base 3.37.0 - sqlite3WalCallback@Base 3.37.0 - sqlite3WalCheckpoint@Base 3.37.0 - sqlite3WalClose@Base 3.37.0 - sqlite3WalDbsize@Base 3.37.0 - sqlite3WalDefaultHook@Base 3.37.0 - sqlite3WalEndReadTransaction@Base 3.37.0 - sqlite3WalEndWriteTransaction@Base 3.37.0 - sqlite3WalExclusiveMode@Base 3.37.0 - sqlite3WalFile@Base 3.37.0 - sqlite3WalFindFrame@Base 3.37.0 - sqlite3WalFrames@Base 3.37.0 - sqlite3WalHeapMemory@Base 3.37.0 - sqlite3WalLimit@Base 3.37.0 - sqlite3WalOpen@Base 3.37.0 - sqlite3WalReadFrame@Base 3.37.0 - sqlite3WalSavepoint@Base 3.37.0 - sqlite3WalSavepointUndo@Base 3.37.0 - sqlite3WalUndo@Base 3.37.0 - sqlite3WalkExpr@Base 3.37.0 - sqlite3WalkExprList@Base 3.37.0 - sqlite3WalkSelect@Base 3.37.0 - sqlite3WalkSelectExpr@Base 3.37.0 - sqlite3WalkSelectFrom@Base 3.37.0 - sqlite3WalkWinDefnDummyCallback@Base 3.37.0 - sqlite3WalkerDepthDecrease@Base 3.37.0 - sqlite3WalkerDepthIncrease@Base 3.37.0 - sqlite3WhereAddLimit@Base 3.38.0 - sqlite3WhereBegin@Base 3.37.0 - sqlite3WhereBreakLabel@Base 3.37.0 - sqlite3WhereClauseClear@Base 3.37.0 - sqlite3WhereClauseInit@Base 3.37.0 - sqlite3WhereCodeOneLoopStart@Base 3.37.0 - sqlite3WhereContinueLabel@Base 3.37.0 - sqlite3WhereEnd@Base 3.37.0 - sqlite3WhereExplainBloomFilter@Base 3.38.0 - sqlite3WhereExplainOneScan@Base 3.37.0 - sqlite3WhereExprAnalyze@Base 3.37.0 - sqlite3WhereExprListUsage@Base 3.37.0 - sqlite3WhereExprUsage@Base 3.37.0 - sqlite3WhereExprUsageNN@Base 3.37.0 - sqlite3WhereFindTerm@Base 3.37.0 - sqlite3WhereGetMask@Base 3.37.0 - sqlite3WhereIsDistinct@Base 3.37.0 - sqlite3WhereIsOrdered@Base 3.37.0 - sqlite3WhereIsSorted@Base 3.37.0 - sqlite3WhereMalloc@Base 3.39.0 - sqlite3WhereMinMaxOptEarlyOut@Base 3.37.0 - sqlite3WhereOkOnePass@Base 3.37.0 - sqlite3WhereOrderByLimitOptLabel@Base 3.37.0 - sqlite3WhereOutputRowCount@Base 3.37.0 - sqlite3WhereRealloc@Base 3.39.0 - sqlite3WhereRightJoinLoop@Base 3.39.0 - sqlite3WhereSplit@Base 3.37.0 - sqlite3WhereTabFuncArgs@Base 3.37.0 - sqlite3WhereTrace@Base 3.37.0 - sqlite3WhereUsesDeferredSeek@Base 3.37.0 - sqlite3WindowAlloc@Base 3.37.0 - sqlite3WindowAssemble@Base 3.37.0 - sqlite3WindowAttach@Base 3.37.0 - sqlite3WindowChain@Base 3.37.0 - sqlite3WindowCodeInit@Base 3.37.0 - sqlite3WindowCodeStep@Base 3.37.0 - sqlite3WindowCompare@Base 3.37.0 - sqlite3WindowDelete@Base 3.37.0 - sqlite3WindowDup@Base 3.37.0 - sqlite3WindowFunctions@Base 3.37.0 - sqlite3WindowLink@Base 3.37.0 - sqlite3WindowListDelete@Base 3.37.0 - sqlite3WindowListDup@Base 3.37.0 - sqlite3WindowRewrite@Base 3.37.0 - sqlite3WindowUnlinkFromSelect@Base 3.37.0 - sqlite3WindowUpdate@Base 3.37.0 - sqlite3WithAdd@Base 3.37.0 - sqlite3WithDelete@Base 3.37.0 - sqlite3WithDup@Base 3.37.0 - sqlite3WithPush@Base 3.37.0 - sqlite3WritableSchema@Base 3.37.0 sqlite3_aggregate_context@Base 3.5.9 sqlite3_aggregate_count@Base 3.5.9 sqlite3_auto_extension@Base 3.5.9 - sqlite3_autovacuum_pages@Base 3.37.0 sqlite3_backup_finish@Base 3.6.11 sqlite3_backup_init@Base 3.6.11 sqlite3_backup_pagecount@Base 3.6.11 @@ -1095,7 +32,6 @@ sqlite3_busy_handler@Base 3.5.9 sqlite3_busy_timeout@Base 3.5.9 sqlite3_cancel_auto_extension@Base 3.8.0.1 - sqlite3_changes64@Base 3.37.0 sqlite3_changes@Base 3.5.9 sqlite3_clear_bindings@Base 3.5.9 sqlite3_close@Base 3.5.9 @@ -1148,7 +84,6 @@ sqlite3_db_filename@Base 3.7.10 sqlite3_db_handle@Base 3.5.9 sqlite3_db_mutex@Base 3.6.5 - sqlite3_db_name@Base 3.39.0 sqlite3_db_readonly@Base 3.7.11 sqlite3_db_release_memory@Base 3.7.10 sqlite3_db_status@Base 3.6.1 @@ -1160,7 +95,6 @@ sqlite3_errcode@Base 3.5.9 sqlite3_errmsg16@Base 3.5.9 sqlite3_errmsg@Base 3.5.9 - sqlite3_error_offset@Base 3.38.0 sqlite3_errstr@Base 3.7.15 sqlite3_exec@Base 3.5.9 sqlite3_expanded_sql@Base 3.14.0 @@ -1182,7 +116,6 @@ sqlite3_hard_heap_limit64@Base 3.30.1+fossil191229 sqlite3_initialize@Base 3.6.0 sqlite3_interrupt@Base 3.5.9 - sqlite3_is_interrupted@Base 3.42.0 sqlite3_keyword_check@Base 3.24.0 sqlite3_keyword_count@Base 3.24.0 sqlite3_keyword_name@Base 3.24.0 @@ -1294,7 +227,6 @@ sqlite3_test_control@Base 3.5.9 sqlite3_thread_cleanup@Base 3.5.9 sqlite3_threadsafe@Base 3.5.9 - sqlite3_total_changes64@Base 3.37.0 sqlite3_total_changes@Base 3.5.9 sqlite3_trace@Base 3.5.9 sqlite3_trace_v2@Base 3.14.0 @@ -1312,7 +244,6 @@ sqlite3_value_bytes@Base 3.5.9 sqlite3_value_double@Base 3.5.9 sqlite3_value_dup@Base 3.8.11 - sqlite3_value_encoding@Base 3.40.0 sqlite3_value_free@Base 3.8.11 sqlite3_value_frombind@Base 3.29.0 sqlite3_value_int64@Base 3.5.9 @@ -1334,20 +265,12 @@ sqlite3_vsnprintf@Base 3.7.5 sqlite3_vtab_collation@Base 3.22.0 sqlite3_vtab_config@Base 3.7.7 - sqlite3_vtab_distinct@Base 3.38.0 - sqlite3_vtab_in@Base 3.38.0 - sqlite3_vtab_in_first@Base 3.38.0 - sqlite3_vtab_in_next@Base 3.38.0 sqlite3_vtab_nochange@Base 3.22.0 sqlite3_vtab_on_conflict@Base 3.7.7 - sqlite3_vtab_rhs_value@Base 3.38.0 sqlite3_wal_autocheckpoint@Base 3.7.0 sqlite3_wal_checkpoint@Base 3.7.0 sqlite3_wal_checkpoint_v2@Base 3.7.6.1 sqlite3_wal_hook@Base 3.7.0 - sqlite3aEQb@Base 3.37.0 - sqlite3aGTb@Base 3.37.0 - sqlite3aLTb@Base 3.37.0 sqlite3changegroup_add@Base 3.13.0 sqlite3changegroup_add_strm@Base 3.13.0 sqlite3changegroup_delete@Base 3.13.0 diff -Nru sqlite3-3.42.0/debian/patches/02-use-packaged-lempar.c.patch sqlite3-3.44.0-0/debian/patches/02-use-packaged-lempar.c.patch --- sqlite3-3.42.0/debian/patches/02-use-packaged-lempar.c.patch 2022-11-16 17:21:56.000000000 +0000 +++ sqlite3-3.44.0-0/debian/patches/02-use-packaged-lempar.c.patch 2023-11-04 14:24:19.000000000 +0000 @@ -7,7 +7,7 @@ --- a/tool/lemon.c +++ b/tool/lemon.c -@@ -3673,6 +3673,8 @@ PRIVATE FILE *tplt_open(struct lemon *le +@@ -3668,6 +3668,8 @@ PRIVATE FILE *tplt_open(struct lemon *le tpltname = buf; }else if( access(templatename,004)==0 ){ tpltname = templatename; diff -Nru sqlite3-3.42.0/debian/patches/30-cross.patch sqlite3-3.44.0-0/debian/patches/30-cross.patch --- sqlite3-3.42.0/debian/patches/30-cross.patch 2022-11-16 17:21:56.000000000 +0000 +++ sqlite3-3.44.0-0/debian/patches/30-cross.patch 2023-11-04 14:24:19.000000000 +0000 @@ -1,8 +1,8 @@ -Index: sqlite3/Makefile.in +Index: sqlite3-3.13.0/Makefile.in =================================================================== ---- sqlite3.orig/Makefile.in -+++ sqlite3/Makefile.in -@@ -799,10 +799,20 @@ sqlite3.lo: sqlite3.c +--- sqlite3-3.13.0.orig/Makefile.in ++++ sqlite3-3.13.0/Makefile.in +@@ -773,10 +773,20 @@ sqlite3.lo: sqlite3.c # Rules to build the LEMON compiler generator # @@ -24,7 +24,7 @@ # Rules to build the program that generates the source-id # mksourceid$(BEXE): $(TOP)/tool/mksourceid.c -@@ -1087,9 +1087,9 @@ opcodes.h: parse.h $(TOP)/src/vdbe.c $(T +@@ -1052,9 +1052,9 @@ opcodes.h: parse.h $(TOP)/src/vdbe.c $(T # parse.h: parse.c @@ -36,7 +36,7 @@ sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h -@@ -1225,10 +1225,10 @@ FTS5_SRC = \ +@@ -1179,10 +1179,10 @@ FTS5_SRC = \ $(TOP)/ext/fts5/fts5_varint.c \ $(TOP)/ext/fts5/fts5_vocab.c \ @@ -49,7 +49,7 @@ fts5parse.h: fts5parse.c -@@ -1496,7 +1496,10 @@ clean: +@@ -1431,7 +1441,10 @@ rm -f *.lo *.la *.o sqlite3$(TEXE) libsqlite3.la rm -f sqlite3.h opcodes.* rm -rf .libs .deps @@ -59,5 +59,5 @@ + rm -f lemon$(TEXE) +endif rm -f mkkeywordhash$(BEXE) keywordhash.h - rm -f mksourceid$(BEXE) rm -f *.da *.bb *.bbg gmon.out + rm -rf tsrc .target_source diff -Nru sqlite3-3.42.0/debian/patches/31-increase_SQLITE_MAX_DEFAULT_PAGE_SIZE_to_32k.patch sqlite3-3.44.0-0/debian/patches/31-increase_SQLITE_MAX_DEFAULT_PAGE_SIZE_to_32k.patch --- sqlite3-3.42.0/debian/patches/31-increase_SQLITE_MAX_DEFAULT_PAGE_SIZE_to_32k.patch 2023-06-24 14:16:47.000000000 +0000 +++ sqlite3-3.44.0-0/debian/patches/31-increase_SQLITE_MAX_DEFAULT_PAGE_SIZE_to_32k.patch 2023-11-04 14:24:19.000000000 +0000 @@ -2,16 +2,17 @@ Firefox/Iceweasel uses a page size of 32k, but sqlite won't allow it because the maximum it allows by default is 8k (through the SQLITE_MAX_DEFAULT_PAGE_SIZE define). This patch increases this limit. + . Author: Laszlo Boszormenyi (GCS) Bug-Debian: http://bugs.debian.org/672573 -Forwarded: not-needed +Forwarded: Last-Update: 2019-12-29 --- --- sqlite3-3.7.12.orig/src/sqliteLimit.h +++ sqlite3-3.7.12/src/sqliteLimit.h -@@ -171,7 +171,7 @@ +@@ -172,7 +172,7 @@ ** SQLite will choose on its own. */ #ifndef SQLITE_MAX_DEFAULT_PAGE_SIZE diff -Nru sqlite3-3.42.0/debian/patches/32-dynamic_link.patch sqlite3-3.44.0-0/debian/patches/32-dynamic_link.patch --- sqlite3-3.42.0/debian/patches/32-dynamic_link.patch 2022-11-16 17:21:56.000000000 +0000 +++ sqlite3-3.44.0-0/debian/patches/32-dynamic_link.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,14 +0,0 @@ ---- sqlite3-3.38.3.orig/Makefile.in -+++ sqlite3-3.38.3/Makefile.in -@@ -672,9 +672,9 @@ - -avoid-version - sed -i "/dependency_libs/s/'.*'/''/" $@ - --sqlite3$(TEXE): shell.c sqlite3.c -+sqlite3$(TEXE): shell.c libsqlite3.la - $(LTLINK) $(READLINE_FLAGS) $(SHELL_OPT) -o $@ \ -- shell.c sqlite3.c \ -+ shell.c libsqlite3.la \ - $(LIBREADLINE) $(TLIBS) -rpath "$(libdir)" - - sqldiff$(TEXE): $(TOP)/tool/sqldiff.c sqlite3.lo sqlite3.h diff -Nru sqlite3-3.42.0/debian/patches/40-amalgamation_configure.patch sqlite3-3.44.0-0/debian/patches/40-amalgamation_configure.patch --- sqlite3-3.42.0/debian/patches/40-amalgamation_configure.patch 2021-12-12 22:34:48.000000000 +0000 +++ sqlite3-3.44.0-0/debian/patches/40-amalgamation_configure.patch 1970-01-01 00:00:00.000000000 +0000 @@ -1,37 +0,0 @@ ---- sqlite-src-3370000/configure.ac.orig 2021-11-27 16:05:17.000000000 +0100 -+++ sqlite-src-3370000/configure.ac 2021-12-03 21:21:47.506868981 +0100 -@@ -116,6 +116,13 @@ - USE_AMALGAMATION=1 - - ######### -+# By default, amalgamation sqlite3.c will have #line directives. -+# This is a build option not shown by ./configure --help -+# To control it, use configure option: amalgamation_line_macros=? -+# where ? is no to suppress #line directives or yes to create them. -+AMALGAMATION_LINE_MACROS=--linemacros=0 -+ -+######### - # See whether we can run specific tclsh versions known to work well; - # if not, then we fall back to plain tclsh. - # TODO: try other versions before falling back? -@@ -606,6 +613,20 @@ - fi - AC_SUBST(USE_AMALGAMATION) - -+######## -+# See whether --disable -+if test "${amalgamation_line_macros+set}" = set; then : -+ enableval=$amalgamation_line_macros; -+fi -+ -+if test "${amalgamation_line_macros}" = "yes" ; then -+ AMALGAMATION_LINE_MACROS=--linemacros=1 -+fi -+if test "${amalgamation_line_macros}" = "no" ; then -+ AMALGAMATION_LINE_MACROS=--linemacros=0 -+fi -+AC_SUBST(AMALGAMATION_LINE_MACROS) -+ - ######### - # Look for zlib. Only needed by extensions and by the sqlite3.exe shell - AC_CHECK_HEADERS(zlib.h) diff -Nru sqlite3-3.42.0/debian/patches/40-fix_CVE-2021-36690.patch sqlite3-3.44.0-0/debian/patches/40-fix_CVE-2021-36690.patch --- sqlite3-3.42.0/debian/patches/40-fix_CVE-2021-36690.patch 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/debian/patches/40-fix_CVE-2021-36690.patch 2023-11-04 14:24:19.000000000 +0000 @@ -0,0 +1,54 @@ +Index: sqlite3/ext/expert/sqlite3expert.c +================================================================== +--- a/ext/expert/sqlite3expert.c ++++ b/ext/expert/sqlite3expert.c +@@ -688,15 +688,17 @@ + int nPk = 0; + + rc = idxPrintfPrepareStmt(db, &p1, pzErrmsg, "PRAGMA table_xinfo=%Q", zTab); + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ + const char *zCol = (const char*)sqlite3_column_text(p1, 1); ++ const char *zColSeq = 0; + nByte += 1 + STRLEN(zCol); + rc = sqlite3_table_column_metadata( +- db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 ++ db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0 + ); +- nByte += 1 + STRLEN(zCol); ++ if( zColSeq==0 ) zColSeq = "binary"; ++ nByte += 1 + STRLEN(zColSeq); + nCol++; + nPk += (sqlite3_column_int(p1, 5)>0); + } + rc2 = sqlite3_reset(p1); + if( rc==SQLITE_OK ) rc = rc2; +@@ -712,23 +714,25 @@ + } + + nCol = 0; + while( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(p1) ){ + const char *zCol = (const char*)sqlite3_column_text(p1, 1); ++ const char *zColSeq = 0; + int nCopy = STRLEN(zCol) + 1; + pNew->aCol[nCol].zName = pCsr; + pNew->aCol[nCol].iPk = (sqlite3_column_int(p1, 5)==1 && nPk==1); + memcpy(pCsr, zCol, nCopy); + pCsr += nCopy; + + rc = sqlite3_table_column_metadata( +- db, "main", zTab, zCol, 0, &zCol, 0, 0, 0 ++ db, "main", zTab, zCol, 0, &zColSeq, 0, 0, 0 + ); + if( rc==SQLITE_OK ){ +- nCopy = STRLEN(zCol) + 1; ++ if( zColSeq==0 ) zColSeq = "binary"; ++ nCopy = STRLEN(zColSeq) + 1; + pNew->aCol[nCol].zColl = pCsr; +- memcpy(pCsr, zCol, nCopy); ++ memcpy(pCsr, zColSeq, nCopy); + pCsr += nCopy; + } + + nCol++; + } + diff -Nru sqlite3-3.42.0/debian/patches/series sqlite3-3.44.0-0/debian/patches/series --- sqlite3-3.42.0/debian/patches/series 2022-12-31 08:41:40.000000000 +0000 +++ sqlite3-3.44.0-0/debian/patches/series 2023-11-04 14:24:19.000000000 +0000 @@ -4,6 +4,5 @@ 30-cross.patch 10-665363-disable-malloc-usable-size.patch 31-increase_SQLITE_MAX_DEFAULT_PAGE_SIZE_to_32k.patch -32-dynamic_link.patch 02-use-packaged-lempar.c.patch -40-amalgamation_configure.patch +40-fix_CVE-2021-36690.patch diff -Nru sqlite3-3.42.0/debian/rules sqlite3-3.44.0-0/debian/rules --- sqlite3-3.42.0/debian/rules 2022-12-18 09:03:56.000000000 +0000 +++ sqlite3-3.44.0-0/debian/rules 2023-11-04 14:24:19.000000000 +0000 @@ -4,11 +4,9 @@ # Uncomment this to turn on verbose mode. #export DH_VERBOSE=1 -export DEB_BUILD_ARCH_OS ?= $(shell dpkg-architecture -qDEB_BUILD_ARCH_OS) - export LC_ALL:=C.UTF-8 -export DEB_BUILD_MAINT_OPTIONS = hardening=+all future=+lfs +export DEB_BUILD_MAINT_OPTIONS = hardening=+all DPKG_EXPORT_BUILDFLAGS = 1 include /usr/share/dpkg/buildflags.mk @@ -46,10 +44,9 @@ -DSQLITE_ENABLE_RTREE=1 -DSQLITE_SOUNDEX=1 \ -DSQLITE_ENABLE_UNLOCK_NOTIFY \ -DSQLITE_OMIT_LOOKASIDE=1 -DSQLITE_ENABLE_DBSTAT_VTAB \ - -DSQLITE_ALLOW_ROWID_IN_VIEW \ -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 \ -DSQLITE_ENABLE_LOAD_EXTENSION \ - -DSQLITE_ENABLE_JSON1 \ + -DSQLITE_ENABLE_JSON1 -DSQLITE_ENABLE_MATH_FUNCTIONS\ -DSQLITE_LIKE_DOESNT_MATCH_BLOBS \ -DSQLITE_THREADSAFE=1 \ -DSQLITE_ENABLE_FTS3_TOKENIZER=1 \ @@ -68,10 +65,9 @@ ./configure --prefix=/usr --mandir="/usr/share/man" \ $(confflags) --enable-threadsafe \ --enable-load-extension \ - --enable-json \ + --enable-json1 \ --enable-fts4 \ --enable-fts5 \ - --disable-amalgamation \ --libdir=\$${prefix}/lib/$(DEB_HOST_MULTIARCH) \ --libexecdir=\$${libdir}/sqlite3 \ TCLLIBDIR=/usr/lib/tcltk/sqlite3 \ @@ -90,10 +86,7 @@ build-stamp: configure dh_testdir $(MAKE) -ifeq (,$(findstring $(DEB_BUILD_ARCH_OS),kfreebsd)) - # build tools - $(MAKE) showdb showjournal showstat4 showwal sqldiff sqlite3_analyzer -endif + $(MAKE) sqldiff ifneq ($(DEB_BUILD_GNU_TYPE), $(DEB_HOST_GNU_TYPE)) $(MAKE) lemon endif @@ -122,18 +115,14 @@ install -m 0664 libtclsqlite3.la $(DESTDIR)/usr/lib/tcltk/sqlite3/ install -d $(DESTDIR)/usr/share/lemon install -m 0664 tool/lempar.c $(DESTDIR)/usr/share/lemon/ -ifeq (,$(findstring $(DEB_BUILD_ARCH_OS),kfreebsd)) - install -m 0775 showdb showjournal showstat4 showwal \ - sqldiff sqlite3_analyzer \ - $(DESTDIR)/usr/bin/ -endif + install -m 0775 sqldiff $(DESTDIR)/usr/bin/ install -m 0775 lemon $(DESTDIR)/usr/bin/ install -d $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/sqlite/ install -m 0775 ext/misc/csv.so \ $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/sqlite/ # Remove *.la files per policy 3.9.1.0 - rm $(DESTDIR)/usr/lib/$(DEB_HOST_MULTIARCH)/libsqlite3.la + rm $(DESTDIR)/usr/lib/*/libsqlite3.la # Create the pkgIndex.tcl file for the Tcl module. This generated file # actually turns out to be relocatable. @@ -154,9 +143,9 @@ dh_install -i --sourcedir=$(DESTDIR) dh_installdocs -i - lynx -dump -nolist www/changes.html >changelog - dh_installchangelogs -i www/changes.html changelog - rm changelog + #lynx -dump -nolist www/www/changes.html >changelog + #dh_installchangelogs -i www/www/changes.html changelog + #rm changelog dh_compress -i dh_fixperms -i dh_installdeb -i @@ -171,9 +160,9 @@ dh_install -a --sourcedir=$(DESTDIR) dh_installman -a dh_installdocs -a - lynx -dump -nolist www/changes.html >changelog - dh_installchangelogs -a www/changes.html changelog - rm changelog + #lynx -dump -nolist www/www/changes.html >changelog + #dh_installchangelogs -a www/www/changes.html changelog + #rm changelog dh_strip -a dh_compress -a dh_fixperms -a diff -Nru sqlite3-3.42.0/debian/source/format sqlite3-3.44.0-0/debian/source/format --- sqlite3-3.42.0/debian/source/format 2010-05-05 18:58:30.000000000 +0000 +++ sqlite3-3.44.0-0/debian/source/format 2023-11-04 14:24:19.000000000 +0000 @@ -1 +1 @@ -3.0 (quilt) +3.0 (native) diff -Nru sqlite3-3.42.0/debian/source/lintian-overrides sqlite3-3.44.0-0/debian/source/lintian-overrides --- sqlite3-3.42.0/debian/source/lintian-overrides 2022-09-05 15:38:52.000000000 +0000 +++ sqlite3-3.44.0-0/debian/source/lintian-overrides 1970-01-01 00:00:00.000000000 +0000 @@ -1,33 +0,0 @@ -# long lines -source-is-missing [www/c3ref/c_abort_rollback.html] -source-is-missing [www/c3ref/c_alter_table.html] -source-is-missing [www/c3ref/c_config_covering_index_scan.html] -source-is-missing [www/c3ref/c_dbconfig_defensive.html] -source-is-missing [www/c3ref/c_fcntl_begin_atomic_write.html] -source-is-missing [www/c3ref/c_index_constraint_eq.html] -source-is-missing [www/c3ref/c_testctrl_always.html] -source-is-missing [www/doc_keyword_crossref.html] -source-is-missing [www/doc_pagelink_crossref.html] -source-is-missing [www/doc_target_crossref.html] -source-is-missing [www/faq.html] -source-is-missing [www/syntax/common-table-expression.html] -source-is-missing [www/syntax/compound-operator.html] -source-is-missing [www/syntax/expr.html] -source-is-missing [www/syntax/filter-clause.html] -source-is-missing [www/syntax/frame-spec.html] -source-is-missing [www/syntax/join-clause.html] -source-is-missing [www/syntax/join-constraint.html] -source-is-missing [www/syntax/join-operator.html] -source-is-missing [www/syntax/literal-value.html] -source-is-missing [www/syntax/ordering-term.html] -source-is-missing [www/syntax/over-clause.html] -source-is-missing [www/syntax/raise-function.html] -source-is-missing [www/syntax/result-column.html] -source-is-missing [www/syntax/select-stmt.html] -source-is-missing [www/syntax/signed-number.html] -source-is-missing [www/syntax/sql-stmt.html] -source-is-missing [www/syntax/table-or-subquery.html] -source-is-missing [www/syntax/type-name.html] -source-is-missing [www/syntax/update-stmt-limited.html] -source-is-missing [www/syntax/window-defn.html] -source-is-missing [www/syntaxdiagrams.html] diff -Nru sqlite3-3.42.0/debian/sqlite3_analyzer.1 sqlite3-3.44.0-0/debian/sqlite3_analyzer.1 --- sqlite3-3.42.0/debian/sqlite3_analyzer.1 2021-12-12 22:34:48.000000000 +0000 +++ sqlite3-3.44.0-0/debian/sqlite3_analyzer.1 1970-01-01 00:00:00.000000000 +0000 @@ -1,39 +0,0 @@ -.Dd 2018-07-22 -.Dt SQLITE3_ANALYZER 1 -.Os "Debian GNU/Linux" -.Sh NAME -.Nm sqlite3_analyzer -.Nd SQLite3 database space usage analyzis tool -.Sh SYNOPSIS -.Nm -.Op Fl -pageinfo -.Op Fl -stats -.Op Fl -tclsh -.Op Fl -version -.Ar database.sqlite -.Sh DESCRIPTION -.Nm -program analyze an SQLite database file and -output a report detailing size and storage efficiency -information for the database and its constituent tables and indexes. -.Pp -.Sh OPTIONS -.Bl -tag -width indent -.It Fl -pageinfo -Show how each page of the database-file is used -.It Fl -stats -Output SQL text that creates a new database containing -statistics about the database that was analyzed -.It Fl -tclsh -Run the built-in TCL interpreter interactively (for debugging) -.It Fl -version -Show the version number of SQLite -.El -.Sh AUTHOR -.Nm -has been written by -.An D. Richard Hipp Aq drh@hwaci.com . -.Pp -This manual page was written by -.An Yuriy M. Kaminskiy Aq yumkam+debian@gmail.com -for the Debian GNU/Linux system. diff -Nru sqlite3-3.42.0/debian/sqlite3.install sqlite3-3.44.0-0/debian/sqlite3.install --- sqlite3-3.42.0/debian/sqlite3.install 2021-12-12 22:34:48.000000000 +0000 +++ sqlite3-3.44.0-0/debian/sqlite3.install 2023-11-04 14:24:19.000000000 +0000 @@ -1 +1,2 @@ usr/bin/sqlite3 +usr/bin/sqldiff diff -Nru sqlite3-3.42.0/debian/sqlite3-tools.install sqlite3-3.44.0-0/debian/sqlite3-tools.install --- sqlite3-3.42.0/debian/sqlite3-tools.install 2021-12-12 22:34:48.000000000 +0000 +++ sqlite3-3.44.0-0/debian/sqlite3-tools.install 1970-01-01 00:00:00.000000000 +0000 @@ -1,6 +0,0 @@ -usr/bin/showdb -usr/bin/showjournal -usr/bin/showstat4 -usr/bin/showwal -usr/bin/sqldiff -usr/bin/sqlite3_analyzer diff -Nru sqlite3-3.42.0/debian/sqlite3-tools.manpages sqlite3-3.44.0-0/debian/sqlite3-tools.manpages --- sqlite3-3.42.0/debian/sqlite3-tools.manpages 2021-12-12 22:34:48.000000000 +0000 +++ sqlite3-3.44.0-0/debian/sqlite3-tools.manpages 1970-01-01 00:00:00.000000000 +0000 @@ -1 +0,0 @@ -debian/sqlite3_analyzer.1 diff -Nru sqlite3-3.42.0/doc/compile-for-windows.md sqlite3-3.44.0-0/doc/compile-for-windows.md --- sqlite3-3.42.0/doc/compile-for-windows.md 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/doc/compile-for-windows.md 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,136 @@ +# Notes On Compiling SQLite On Windows 11 + +Here are step-by-step instructions on how to build SQLite from +canonical source on a new Windows 11 PC, as of 2023-08-16: + + 1. Install Microsoft Visual Studio. The free "community edition" + will work fine. Do a standard install for C++ development. + SQLite only needs the + "cl" compiler and the "nmake" build tool. + + 2. Under the "Start" menu, find "All Apps" then go to "Visual Studio 20XX" + and find "x64 Native Tools Command Prompt for VS 20XX". Pin that + application to your task bar, as you will use it a lot. Bring up + an instance of this command prompt and do all of the subsequent steps + in that "x64 Native Tools" command prompt. (Or use "x86" if you want + a 32-bit build.) The subsequent steps will not work in a vanilla + DOS prompt. Nor will they work in PowerShell. + + 3. Install TCL development libraries. This note assumes that you will + install the TCL development libraries in the "`c:\Tcl`" directory. + Make adjustments + if you want TCL installed somewhere else. SQLite needs both the + "tclsh.exe" command-line tool as part of the build process, and + the "tcl86.lib" library in order to run tests. You will need + TCL version 8.6 or later. +
    +
  1. Get the TCL source archive, perhaps from + [https://www.tcl.tk/software/tcltk/download.html](https://www.tcl.tk/software/tcltk/download.html). +
  2. Untar or unzip the source archive. CD into the "win/" subfolder + of the source tree. +
  3. Run: `nmake /f makefile.vc release` +
  4. Run: `nmake /f makefile.vc INSTALLDIR=c:\Tcl install` +
  5. CD to `c:\Tcl\lib`. In that subfolder make a copy of the + "`tcl86t.lib`" file to the alternative name "`tcl86.lib`" + (omitting the second 't'). Leave the copy in the same directory + as the original. +
  6. CD to `c:\Tcl\bin`. Make a copy of the "`tclsh86t.exe`" + file into "`tclsh.exe`" (without the "86t") in the same directory. +
  7. Add `c:\Tcl\bin` to your %PATH%. To do this, go to Settings + and search for "path". Select "edit environment variables for + your account" and modify your default PATH accordingly. + You will need to close and reopen your command prompts after + making this change. +
+ + 4. Download the SQLite source tree and unpack it. CD into the + toplevel directory of the source tree. + + 5. Set the TCLDIR environment variable to point to your TCL installation. + Like this: +
    +
  • `set TCLDIR=c:\Tcl` +
+ + 6. Run the "`Makefile.msc`" makefile with an appropriate target. + Examples: +
    +
  • `nmake /f makefile.msc` +
  • `nmake /f makefile.msc sqlite3.c` +
  • `nmake /f makefile.msc devtest` +
  • `nmake /f makefile.msc releasetest` +
+ +## 32-bit Builds + +Doing a 32-bit build is just like doing a 64-bit build with the +following minor changes: + + 1. Use the "x86 Native Tools Command Prompt" instead of + "x64 Native Tools Command Prompt". "**x86**" instead of "**x64**". + + 2. Use a different installation directory for TCL. + The recommended directory is `c:\tcl32`. Thus you end up + with two TCL builds: +
    +
  • `c:\tcl` ← 64-bit (the default) +
  • `c:\tcl32` ← 32-bit +
+ + 3. Ensure that `c:\tcl32\bin` comes before `c:\tcl\bin` on + your PATH environment variable. You can achieve this using + a command like: +
    +
  • `set PATH=c:\tcl32\bin;%PATH%` +
+ +## Statically Linking The TCL Library + +Some utility programs associated with SQLite need to be linked +with TCL in order to function. The [sqlite3_analyzer.exe program](https://sqlite.org/sqlanalyze.html) +is an example. You can build as described above, and then +enter: + +> ~~~~ +nmake /f Makefile.msc sqlite3_analyzer.exe +~~~~ + +And you will end up with a working executable. However, that executable +will depend on having the "tcl86.dll" library somewhere on your %PATH%. +Use the following steps to build an executable that has the TCL library +statically linked so that it does not depend on separate DLL: + + 1. Use the appropriate "Command Prompt" window - either x86 or + x64, depending on whether you want a 32-bit or 64-bit executable. + + 2. Untar the TCL source tarball into a fresh directory. CD into + the "win/" subfolder. + + 3. Run: `nmake /f makefile.vc OPTS=nothreads,static shell` + + + 4. CD into the "Release*" subfolder that is created (note the + wildcard - the full name of the directory might vary). There + you will find the "tcl86s.lib" file. Copy this file into the + same directory that you put the "tcl86.lib" on your initial + installation. (In this document, that directory is + "`C:\Tcl32\lib`" for 32-bit builds and + "`C:\Tcl\lib`" for 64-bit builds.) + + 5. CD into your SQLite source code directory and build the desired + utility program, but add the following extra arguments to the + nmake command line: +
+      CCOPTS="-DSTATIC_BUILD" LIBTCL="tcl86s.lib netapi32.lib user32.lib"
+      
+

So, for example, to build a statically linked version of + sqlite3_analyzer.exe, you might type: +

+      nmake /f Makefile.msc CCOPTS="-DSTATIC_BUILD" LIBTCL="tcl86s.lib netapi32.lib user32.lib" sqlite3_analyzer.exe
+      
+ + 6. After your executable is built, you can verify that it does not + depend on the TCL DLL by running: +
+      dumpbin /dependents sqlite3_analyzer.exe
+      
diff -Nru sqlite3-3.42.0/doc/lemon.html sqlite3-3.44.0-0/doc/lemon.html --- sqlite3-3.42.0/doc/lemon.html 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/doc/lemon.html 2023-11-04 14:23:58.000000000 +0000 @@ -1229,8 +1229,8 @@

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

+There was a companion LL(1) parser generator program named "Lime". +The Lime source code has been lost.

The lemon.c source file was originally many separate files that were compiled together to generate the "lemon" executable. Sometime in the diff -Nru sqlite3-3.42.0/doc/testrunner.md sqlite3-3.44.0-0/doc/testrunner.md --- sqlite3-3.42.0/doc/testrunner.md 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/doc/testrunner.md 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,284 @@ + + +# The testrunner.tcl Script + +# 1. Overview + +testrunner.tcl is a Tcl script used to run multiple SQLite tests using +multiple jobs. It supports the following types of tests: + + * Tcl test scripts. + + * Tests run with [make] commands. Specifically, at time of writing, + [make fuzztest], [make mptest], [make sourcetest] and [make threadtest]. + +testrunner.tcl pipes the output of all tests and builds run into log file +**testrunner.log**, created in the cwd directory. Searching this file for +"failed" is a good way to find the output of a failed test. + +testrunner.tcl also populates SQLite database **testrunner.db**. This database +contains details of all tests run, running and to be run. A useful query +might be: + +``` + SELECT * FROM script WHERE state='failed' +``` + +Running the command: + +``` + ./testfixture $(TESTDIR)/testrunner.tcl status +``` + +in the directory containing the testrunner.db database runs various queries +to produce a succinct report on the state of a running testrunner.tcl script. +Running: + +``` + watch ./testfixture $(TESTDIR)/testrunner.tcl status +``` + +in another terminal is a good way to keep an eye on a long running test. + +Sometimes testrunner.tcl uses the [testfixture] binary that it is run with +to run tests (see "Binary Tests" below). Sometimes it builds testfixture and +other binaries in specific configurations to test (see "Source Tests"). + +# 2. Binary Tests + +The commands described in this section all run various combinations of the Tcl +test scripts using the [testfixture] binary used to run the testrunner.tcl +script (i.e. they do not invoke the compiler to build new binaries, or the +[make] command to run tests that are not Tcl scripts). The procedure to run +these tests is therefore: + + 1. Build the "testfixture" (or "testfixture.exe" for windows) binary using + whatever method seems convenient. + + 2. Test the binary built in step 1 by running testrunner.tcl with it, + perhaps with various options. + +The following sub-sections describe the various options that can be +passed to testrunner.tcl to test binary testfixture builds. + +## 2.1. Organization of Tcl Tests + +Tcl tests are stored in files that match the pattern *\*.test*. They are +found in both the $TOP/test/ directory, and in the various sub-directories +of the $TOP/ext/ directory of the source tree. Not all *\*.test* files +contain Tcl tests - a handful are Tcl scripts designed to invoke other +*\*.test* files. + +The **veryquick** set of tests is a subset of all Tcl test scripts in the +source tree. In includes most tests, but excludes some that are very slow. +Almost all fault-injection tests (those that test the response of the library +to OOM or IO errors) are excluded. It is defined in source file +*test/permutations.test*. + +The **full** set of tests includes all Tcl test scripts in the source tree. +To run a "full" test is to run all Tcl test scripts that can be found in the +source tree. + +File *permutations.test* defines various test "permutations". A permutation +consists of: + + * A subset of Tcl test scripts, and + + * Runtime configuration to apply before running each test script + (e.g. enabling auto-vacuum, or disable lookaside). + +Running **all** tests is to run all tests in the full test set, plus a dozen +or so permutations. The specific permutations that are run as part of "all" +are defined in file *testrunner_data.tcl*. + +## 2.2. Commands to Run Tests + +To run the "veryquick" test set, use either of the following: + +``` + ./testfixture $TESTDIR/testrunner.tcl + ./testfixture $TESTDIR/testrunner.tcl veryquick +``` + +To run the "full" test suite: + +``` + ./testfixture $TESTDIR/testrunner.tcl full +``` + +To run the subset of the "full" test suite for which the test file name matches +a specified pattern (e.g. all tests that start with "fts5"), either of: + +``` + ./testfixture $TESTDIR/testrunner.tcl fts5% + ./testfixture $TESTDIR/testrunner.tcl 'fts5*' +``` + +To run "all" tests (full + permutations): + +``` + ./testfixture $TESTDIR/testrunner.tcl all +``` + + +## 2.3. Investigating Binary Test Failures + +If a test fails, testrunner.tcl reports name of the Tcl test script and, if +applicable, the name of the permutation, to stdout. This information can also +be retrieved from either *testrunner.log* or *testrunner.db*. + +If there is no permutation, the individual test script may be run with: + +``` + ./testfixture $PATH_TO_SCRIPT +``` + +Or, if the failure occured as part of a permutation: + +``` + ./testfixture $TESTDIR/testrunner.tcl $PERMUTATION $PATH_TO_SCRIPT +``` + +TODO: An example instead of "$PERMUTATION" and $PATH\_TO\_SCRIPT? + +# 3. Source Code Tests + +The commands described in this section invoke the C compiler to build +binaries from the source tree, then use those binaries to run Tcl and +other tests. The advantages of this are that: + + * it is possible to test multiple build configurations with a single + command, and + + * it ensures that tests are always run using binaries created with the + same set of compiler options. + +The testrunner.tcl commands described in this section may be run using +either a *testfixture* (or testfixture.exe) build, or with any other Tcl +shell that supports SQLite 3.31.1 or newer via "package require sqlite3". + +TODO: ./configure + Makefile.msc build systems. + +## Commands to Run SQLite Tests + +The **mdevtest** command is equivalent to running the veryquick tests and +the [make fuzztest] target once for each of two --enable-all builds - one +with debugging enabled and one without: + +``` + tclsh $TESTDIR/testrunner.tcl mdevtest +``` + +In other words, it is equivalent to running: + +``` + $TOP/configure --enable-all --enable-debug + make fuzztest + make testfixture + ./testfixture $TOP/test/testrunner.tcl veryquick + + # Then, after removing files created by the tests above: + $TOP/configure --enable-all OPTS="-O0" + make fuzztest + make testfixture + ./testfixture $TOP/test/testrunner.tcl veryquick +``` + +The **sdevtest** command is identical to the mdevtest command, except that the +second of the two builds is a sanitizer build. Specifically, this means that +OPTS="-fsanitize=address,undefined" is specified instead of OPTS="-O0": + +``` + tclsh $TESTDIR/testrunner.tcl sdevtest +``` + +The **release** command runs lots of tests under lots of builds. It runs +different combinations of builds and tests depending on whether it is run +on Linux, Windows or OSX. Refer to *testrunner\_data.tcl* for the details +of the specific tests run. + +``` + tclsh $TESTDIR/testrunner.tcl release +``` + +## Running ZipVFS Tests + +testrunner.tcl can build a zipvfs-enabled testfixture and use it to run +tests from the Zipvfs project with the following command: + +``` + tclsh $TESTDIR/testrunner.tcl --zipvfs $PATH_TO_ZIPVFS +``` + +This can be combined with any of "mdevtest", "sdevtest" or "release" to +test both SQLite and Zipvfs with a single command: + +``` + tclsh $TESTDIR/testrunner.tcl --zipvfs $PATH_TO_ZIPVFS mdevtest +``` + +## Investigating Source Code Test Failures + +Investigating a test failure that occurs during source code testing is a +two step process: + + 1. Recreating the build configuration in which the test failed, and + + 2. Re-running the actual test. + +To recreate a build configuration, use the testrunner.tcl **script** command +to create a build script. A build script is a bash script on Linux or OSX, or +a dos \*.bat file on windows. For example: + +``` + # Create a script that recreates build configuration "Device-One" on + # Linux or OSX: + tclsh $TESTDIR/testrunner.tcl script Device-One > make.sh + + # Create a script that recreates build configuration "Have-Not" on Windows: + tclsh $TESTDIR/testrunner.tcl script Have-Not > make.bat +``` + +The generated bash or \*.bat file script accepts a single argument - a makefile +target to build. This may be used either to run a [make] command test directly, +or else to build a testfixture (or testfixture.exe) binary with which to +run a Tcl test script, as described above. + + + +# 4. Controlling CPU Core Utilization + +When running either binary or source code tests, testrunner.tcl reports the +number of jobs it intends to use to stdout. e.g. + +``` + $ ./testfixture $TESTDIR/testrunner.tcl + splitting work across 16 jobs + ... more output ... +``` + +By default, testfixture.tcl attempts to set the number of jobs to the number +of real cores on the machine. This can be overridden using the "--jobs" (or -j) +switch: + +``` + $ ./testfixture $TESTDIR/testrunner.tcl --jobs 8 + splitting work across 8 jobs + ... more output ... +``` + +The number of jobs may also be changed while an instance of testrunner.tcl is +running by exucuting the following command from the directory containing the +testrunner.log and testrunner.db files: + +``` + $ ./testfixture $TESTDIR/testrunner.tcl njob $NEW_NUMBER_OF_JOBS +``` + + + + + + + + diff -Nru sqlite3-3.42.0/ext/expert/expert1.test sqlite3-3.44.0-0/ext/expert/expert1.test --- sqlite3-3.42.0/ext/expert/expert1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/expert/expert1.test 2023-11-04 14:23:58.000000000 +0000 @@ -464,4 +464,23 @@ t2 t2_idx_0001295b {100 20 5} } +if 0 { +do_test expert1-6.0 { + catchcmd :memory: { +.expert +select base64(''); +.expert +select name from pragma_collation_list order by name collate uint; +} +} {0 {(no new indexes) + +SCAN CONSTANT ROW + +(no new indexes) + +SCAN pragma_collation_list VIRTUAL TABLE INDEX 0: +USE TEMP B-TREE FOR ORDER BY +}} +} + finish_test diff -Nru sqlite3-3.42.0/ext/expert/sqlite3expert.c sqlite3-3.44.0-0/ext/expert/sqlite3expert.c --- sqlite3-3.42.0/ext/expert/sqlite3expert.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/expert/sqlite3expert.c 2023-11-04 14:23:58.000000000 +0000 @@ -32,7 +32,7 @@ #endif /* !defined(SQLITE_AMALGAMATION) */ -#ifndef SQLITE_OMIT_VIRTUALTABLE +#ifndef SQLITE_OMIT_VIRTUALTABLE typedef sqlite3_int64 i64; typedef sqlite3_uint64 u64; @@ -662,6 +662,7 @@ 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0, /* xIntegrity */ }; return sqlite3_create_module(p->dbv, "expert", &expertModule, (void*)p); @@ -1819,6 +1820,88 @@ } /* +** Define and possibly pretend to use a useless collation sequence. +** This pretense allows expert to accept SQL using custom collations. +*/ +int dummyCompare(void *up1, int up2, const void *up3, int up4, const void *up5){ + (void)up1; + (void)up2; + (void)up3; + (void)up4; + (void)up5; + assert(0); /* VDBE should never be run. */ + return 0; +} +/* And a callback to register above upon actual need */ +void useDummyCS(void *up1, sqlite3 *db, int etr, const char *zName){ + (void)up1; + sqlite3_create_collation_v2(db, zName, etr, 0, dummyCompare, 0); +} + +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) \ + && !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) +/* +** dummy functions for no-op implementation of UDFs during expert's work +*/ +void dummyUDF(sqlite3_context *up1, int up2, sqlite3_value **up3){ + (void)up1; + (void)up2; + (void)up3; + assert(0); /* VDBE should never be run. */ +} +void dummyUDFvalue(sqlite3_context *up1){ + (void)up1; + assert(0); /* VDBE should never be run. */ +} + +/* +** Register UDFs from user database with another. +*/ +int registerUDFs(sqlite3 *dbSrc, sqlite3 *dbDst){ + sqlite3_stmt *pStmt; + int rc = sqlite3_prepare_v2(dbSrc, + "SELECT name,type,enc,narg,flags " + "FROM pragma_function_list() " + "WHERE builtin==0", -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + while( SQLITE_ROW==(rc = sqlite3_step(pStmt)) ){ + int nargs = sqlite3_column_int(pStmt,3); + int flags = sqlite3_column_int(pStmt,4); + const char *name = (char*)sqlite3_column_text(pStmt,0); + const char *type = (char*)sqlite3_column_text(pStmt,1); + const char *enc = (char*)sqlite3_column_text(pStmt,2); + if( name==0 || type==0 || enc==0 ){ + /* no-op. Only happens on OOM */ + }else{ + int ienc = SQLITE_UTF8; + int rcf = SQLITE_ERROR; + if( strcmp(enc,"utf16le")==0 ) ienc = SQLITE_UTF16LE; + else if( strcmp(enc,"utf16be")==0 ) ienc = SQLITE_UTF16BE; + ienc |= (flags & (SQLITE_DETERMINISTIC|SQLITE_DIRECTONLY)); + if( strcmp(type,"w")==0 ){ + rcf = sqlite3_create_window_function(dbDst,name,nargs,ienc,0, + dummyUDF,dummyUDFvalue,0,0,0); + }else if( strcmp(type,"a")==0 ){ + rcf = sqlite3_create_function(dbDst,name,nargs,ienc,0, + 0,dummyUDF,dummyUDFvalue); + }else if( strcmp(type,"s")==0 ){ + rcf = sqlite3_create_function(dbDst,name,nargs,ienc,0, + dummyUDF,0,0); + } + if( rcf!=SQLITE_OK ){ + rc = rcf; + break; + } + } + } + sqlite3_finalize(pStmt); + if( rc==SQLITE_DONE ) rc = SQLITE_OK; + } + return rc; +} +#endif + +/* ** Allocate a new sqlite3expert object. */ sqlite3expert *sqlite3_expert_new(sqlite3 *db, char **pzErrmsg){ @@ -1844,7 +1927,21 @@ sqlite3_db_config(pNew->dbm, SQLITE_DBCONFIG_TRIGGER_EQP, 1, (int*)0); } } - + + /* Allow custom collations to be dealt with through prepare. */ + if( rc==SQLITE_OK ) rc = sqlite3_collation_needed(pNew->dbm,0,useDummyCS); + if( rc==SQLITE_OK ) rc = sqlite3_collation_needed(pNew->dbv,0,useDummyCS); + +#if !defined(SQLITE_OMIT_SCHEMA_PRAGMAS) \ + && !defined(SQLITE_OMIT_INTROSPECTION_PRAGMAS) + /* Register UDFs from database [db] with [dbm] and [dbv]. */ + if( rc==SQLITE_OK ){ + rc = registerUDFs(pNew->db, pNew->dbm); + } + if( rc==SQLITE_OK ){ + rc = registerUDFs(pNew->db, pNew->dbv); + } +#endif /* Copy the entire schema of database [db] into [dbm]. */ if( rc==SQLITE_OK ){ @@ -1920,6 +2017,10 @@ while( rc==SQLITE_OK && zStmt && zStmt[0] ){ sqlite3_stmt *pStmt = 0; + /* Ensure that the provided statement compiles against user's DB. */ + rc = idxPrepareStmt(p->db, &pStmt, pzErr, zStmt); + if( rc!=SQLITE_OK ) break; + sqlite3_finalize(pStmt); rc = sqlite3_prepare_v2(p->dbv, zStmt, -1, &pStmt, &zStmt); if( rc==SQLITE_OK ){ if( pStmt ){ diff -Nru sqlite3-3.42.0/ext/fts3/fts3_aux.c sqlite3-3.44.0-0/ext/fts3/fts3_aux.c --- sqlite3-3.42.0/ext/fts3/fts3_aux.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts3/fts3_aux.c 2023-11-04 14:23:58.000000000 +0000 @@ -545,7 +545,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff -Nru sqlite3-3.42.0/ext/fts3/fts3.c sqlite3-3.44.0-0/ext/fts3/fts3.c --- sqlite3-3.42.0/ext/fts3/fts3.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts3/fts3.c 2023-11-04 14:23:58.000000000 +0000 @@ -640,6 +640,7 @@ zLanguageid = (p->zLanguageid ? p->zLanguageid : "__langid"); sqlite3_vtab_config(p->db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(p->db, SQLITE_VTAB_INNOCUOUS); /* Create a list of user columns for the virtual table */ zCols = sqlite3_mprintf("%Q, ", p->azColumn[0]); @@ -3889,6 +3890,8 @@ rc = sqlite3Fts3PendingTermsFlush(p); } + p->bIgnoreSavepoint = 1; + if( p->zContentTbl==0 ){ fts3DbExec(&rc, db, "ALTER TABLE %Q.'%q_content' RENAME TO '%q_content';", @@ -3916,6 +3919,8 @@ "ALTER TABLE %Q.'%q_segdir' RENAME TO '%q_segdir';", p->zDb, p->zName, zName ); + + p->bIgnoreSavepoint = 0; return rc; } @@ -3926,12 +3931,28 @@ */ static int fts3SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ int rc = SQLITE_OK; - UNUSED_PARAMETER(iSavepoint); - assert( ((Fts3Table *)pVtab)->inTransaction ); - assert( ((Fts3Table *)pVtab)->mxSavepoint <= iSavepoint ); - TESTONLY( ((Fts3Table *)pVtab)->mxSavepoint = iSavepoint ); - if( ((Fts3Table *)pVtab)->bIgnoreSavepoint==0 ){ - rc = fts3SyncMethod(pVtab); + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint<=iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + + if( pTab->bIgnoreSavepoint==0 ){ + if( fts3HashCount(&pTab->aIndex[0].hPending)>0 ){ + char *zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->zDb, pTab->zName, pTab->zName + ); + if( zSql ){ + pTab->bIgnoreSavepoint = 1; + rc = sqlite3_exec(pTab->db, zSql, 0, 0, 0); + pTab->bIgnoreSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } } return rc; } @@ -3942,12 +3963,11 @@ ** This is a no-op. */ static int fts3ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - TESTONLY( Fts3Table *p = (Fts3Table*)pVtab ); - UNUSED_PARAMETER(iSavepoint); - UNUSED_PARAMETER(pVtab); - assert( p->inTransaction ); - assert( p->mxSavepoint >= iSavepoint ); - TESTONLY( p->mxSavepoint = iSavepoint-1 ); + Fts3Table *pTab = (Fts3Table*)pVtab; + assert( pTab->inTransaction ); + assert( pTab->mxSavepoint >= iSavepoint ); + TESTONLY( pTab->mxSavepoint = iSavepoint-1 ); + pTab->iSavepoint = iSavepoint; return SQLITE_OK; } @@ -3957,11 +3977,13 @@ ** Discard the contents of the pending terms table. */ static int fts3RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ - Fts3Table *p = (Fts3Table*)pVtab; + Fts3Table *pTab = (Fts3Table*)pVtab; UNUSED_PARAMETER(iSavepoint); - assert( p->inTransaction ); - TESTONLY( p->mxSavepoint = iSavepoint ); - sqlite3Fts3PendingTermsClear(p); + assert( pTab->inTransaction ); + TESTONLY( pTab->mxSavepoint = iSavepoint ); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + sqlite3Fts3PendingTermsClear(pTab); + } return SQLITE_OK; } @@ -3980,8 +4002,49 @@ return 0; } +/* +** Implementation of the xIntegrity() method on the FTS3/FTS4 virtual +** table. +*/ +static int fts3Integrity( + sqlite3_vtab *pVtab, /* The virtual table to be checked */ + const char *zSchema, /* Name of schema in which pVtab lives */ + const char *zTabname, /* Name of the pVTab table */ + int isQuick, /* True if this is a quick_check */ + char **pzErr /* Write error message here */ +){ + Fts3Table *p = (Fts3Table*)pVtab; + char *zSql; + int rc; + char *zErr = 0; + + assert( pzErr!=0 ); + assert( *pzErr==0 ); + UNUSED_PARAMETER(isQuick); + zSql = sqlite3_mprintf( + "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", + zSchema, zTabname, zTabname); + if( zSql==0 ){ + return SQLITE_NOMEM; + } + rc = sqlite3_exec(p->db, zSql, 0, 0, &zErr); + sqlite3_free(zSql); + if( (rc&0xff)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS%d table %s.%s", + p->bFts4 ? 4 : 3, zSchema, zTabname); + }else if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" + " FTS%d table %s.%s: %s", + p->bFts4 ? 4 : 3, zSchema, zTabname, zErr); + } + sqlite3_free(zErr); + return SQLITE_OK; +} + + + static const sqlite3_module fts3Module = { - /* iVersion */ 3, + /* iVersion */ 4, /* xCreate */ fts3CreateMethod, /* xConnect */ fts3ConnectMethod, /* xBestIndex */ fts3BestIndexMethod, @@ -4005,6 +4068,7 @@ /* xRelease */ fts3ReleaseMethod, /* xRollbackTo */ fts3RollbackToMethod, /* xShadowName */ fts3ShadowName, + /* xIntegrity */ fts3Integrity, }; /* diff -Nru sqlite3-3.42.0/ext/fts3/fts3Int.h sqlite3-3.44.0-0/ext/fts3/fts3Int.h --- sqlite3-3.42.0/ext/fts3/fts3Int.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts3/fts3Int.h 2023-11-04 14:23:58.000000000 +0000 @@ -265,6 +265,7 @@ int nPgsz; /* Page size for host database */ char *zSegmentsTbl; /* Name of %_segments table */ sqlite3_blob *pSegments; /* Blob handle open on %_segments table */ + int iSavepoint; /* ** The following array of hash tables is used to buffer pending index diff -Nru sqlite3-3.42.0/ext/fts3/fts3_term.c sqlite3-3.44.0-0/ext/fts3/fts3_term.c --- sqlite3-3.42.0/ext/fts3/fts3_term.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts3/fts3_term.c 2023-11-04 14:23:58.000000000 +0000 @@ -362,7 +362,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff -Nru sqlite3-3.42.0/ext/fts3/fts3_tokenize_vtab.c sqlite3-3.44.0-0/ext/fts3/fts3_tokenize_vtab.c --- sqlite3-3.42.0/ext/fts3/fts3_tokenize_vtab.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts3/fts3_tokenize_vtab.c 2023-11-04 14:23:58.000000000 +0000 @@ -445,7 +445,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff -Nru sqlite3-3.42.0/ext/fts3/fts3_write.c sqlite3-3.44.0-0/ext/fts3/fts3_write.c --- sqlite3-3.42.0/ext/fts3/fts3_write.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts3/fts3_write.c 2023-11-04 14:23:58.000000000 +0000 @@ -3325,7 +3325,6 @@ rc = fts3SegmentMerge(p, p->iPrevLangid, i, FTS3_SEGCURSOR_PENDING); if( rc==SQLITE_DONE ) rc = SQLITE_OK; } - sqlite3Fts3PendingTermsClear(p); /* Determine the auto-incr-merge setting if unknown. If enabled, ** estimate the number of leaf blocks of content to be written @@ -3347,6 +3346,10 @@ rc = sqlite3_reset(pStmt); } } + + if( rc==SQLITE_OK ){ + sqlite3Fts3PendingTermsClear(p); + } return rc; } @@ -3978,6 +3981,8 @@ blobGrowBuffer(pPrev, nTerm, &rc); if( rc!=SQLITE_OK ) return rc; + assert( pPrev!=0 ); + assert( pPrev->a!=0 ); nPrefix = fts3PrefixCompress(pPrev->a, pPrev->n, zTerm, nTerm); nSuffix = nTerm - nPrefix; @@ -4034,9 +4039,13 @@ nSpace += sqlite3Fts3VarintLen(nDoclist) + nDoclist; /* If the current block is not empty, and if adding this term/doclist - ** to the current block would make it larger than Fts3Table.nNodeSize - ** bytes, write this block out to the database. */ - if( pLeaf->block.n>0 && (pLeaf->block.n + nSpace)>p->nNodeSize ){ + ** to the current block would make it larger than Fts3Table.nNodeSize bytes, + ** and if there is still room for another leaf page, write this block out to + ** the database. */ + if( pLeaf->block.n>0 + && (pLeaf->block.n + nSpace)>p->nNodeSize + && pLeaf->iBlock < (pWriter->iStart + pWriter->nLeafEst) + ){ rc = fts3WriteSegment(p, pLeaf->iBlock, pLeaf->block.a, pLeaf->block.n); pWriter->nWork++; @@ -4347,6 +4356,7 @@ for(i=nHeight; i>=0 && rc==SQLITE_OK; i--){ NodeReader reader; + memset(&reader, 0, sizeof(reader)); pNode = &pWriter->aNodeWriter[i]; if( pNode->block.a){ @@ -4367,7 +4377,7 @@ rc = sqlite3Fts3ReadBlock(p, reader.iChild, &aBlock, &nBlock,0); blobGrowBuffer(&pNode->block, MAX(nBlock, p->nNodeSize)+FTS3_NODE_PADDING, &rc - ); + ); if( rc==SQLITE_OK ){ memcpy(pNode->block.a, aBlock, nBlock); pNode->block.n = nBlock; @@ -5217,7 +5227,7 @@ int rc; u64 cksum = 0; - assert( *pRc==SQLITE_OK ); + if( *pRc ) return 0; memset(&filter, 0, sizeof(filter)); memset(&csr, 0, sizeof(csr)); @@ -5432,8 +5442,11 @@ rc = fts3DoIncrmerge(p, &zVal[6]); }else if( nVal>10 && 0==sqlite3_strnicmp(zVal, "automerge=", 10) ){ rc = fts3DoAutoincrmerge(p, &zVal[10]); + }else if( nVal==5 && 0==sqlite3_strnicmp(zVal, "flush", 5) ){ + rc = sqlite3Fts3PendingTermsFlush(p); + } #if defined(SQLITE_DEBUG) || defined(SQLITE_TEST) - }else{ + else{ int v; if( nVal>9 && 0==sqlite3_strnicmp(zVal, "nodesize=", 9) ){ v = atoi(&zVal[9]); @@ -5451,8 +5464,8 @@ if( v>=4 && v<=FTS3_MERGE_COUNT && (v&1)==0 ) p->nMergeCount = v; rc = SQLITE_OK; } -#endif } +#endif return rc; } diff -Nru sqlite3-3.42.0/ext/fts5/fts5_aux.c sqlite3-3.44.0-0/ext/fts5/fts5_aux.c --- sqlite3-3.42.0/ext/fts5/fts5_aux.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_aux.c 2023-11-04 14:23:58.000000000 +0000 @@ -110,15 +110,19 @@ */ typedef struct HighlightContext HighlightContext; struct HighlightContext { - CInstIter iter; /* Coalesced Instance Iterator */ - int iPos; /* Current token offset in zIn[] */ + /* Constant parameters to fts5HighlightCb() */ int iRangeStart; /* First token to include */ int iRangeEnd; /* If non-zero, last token to include */ const char *zOpen; /* Opening highlight */ const char *zClose; /* Closing highlight */ const char *zIn; /* Input text */ int nIn; /* Size of input text in bytes */ - int iOff; /* Current offset within zIn[] */ + + /* Variables modified by fts5HighlightCb() */ + CInstIter iter; /* Coalesced Instance Iterator */ + int iPos; /* Current token offset in zIn[] */ + int iOff; /* Have copied up to this offset in zIn[] */ + int bOpen; /* True if highlight is open */ char *zOut; /* Output value */ }; @@ -151,8 +155,8 @@ int tflags, /* Mask of FTS5_TOKEN_* flags */ const char *pToken, /* Buffer containing token */ int nToken, /* Size of token in bytes */ - int iStartOff, /* Start offset of token */ - int iEndOff /* End offset of token */ + int iStartOff, /* Start byte offset of token */ + int iEndOff /* End byte offset of token */ ){ HighlightContext *p = (HighlightContext*)pContext; int rc = SQLITE_OK; @@ -168,30 +172,47 @@ if( p->iRangeStart && iPos==p->iRangeStart ) p->iOff = iStartOff; } - if( iPos==p->iter.iStart ){ + /* If the parenthesis is open, and this token is not part of the current + ** phrase, and the starting byte offset of this token is past the point + ** that has currently been copied into the output buffer, close the + ** parenthesis. */ + if( p->bOpen + && (iPos<=p->iter.iStart || p->iter.iStart<0) + && iStartOff>p->iOff + ){ + fts5HighlightAppend(&rc, p, p->zClose, -1); + p->bOpen = 0; + } + + /* If this is the start of a new phrase, and the highlight is not open: + ** + ** * copy text from the input up to the start of the phrase, and + ** * open the highlight. + */ + if( iPos==p->iter.iStart && p->bOpen==0 ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iStartOff - p->iOff); fts5HighlightAppend(&rc, p, p->zOpen, -1); p->iOff = iStartOff; + p->bOpen = 1; } if( iPos==p->iter.iEnd ){ - if( p->iRangeEnd>=0 && p->iter.iStartiRangeStart ){ + if( p->bOpen==0 ){ + assert( p->iRangeEnd>=0 ); fts5HighlightAppend(&rc, p, p->zOpen, -1); + p->bOpen = 1; } fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); - fts5HighlightAppend(&rc, p, p->zClose, -1); p->iOff = iEndOff; + if( rc==SQLITE_OK ){ rc = fts5CInstIterNext(&p->iter); } } - if( p->iRangeEnd>=0 && iPos==p->iRangeEnd ){ + if( iPos==p->iRangeEnd ){ fts5HighlightAppend(&rc, p, &p->zIn[p->iOff], iEndOff - p->iOff); p->iOff = iEndOff; - if( iPos>=p->iter.iStart && iPositer.iEnd ){ - fts5HighlightAppend(&rc, p, p->zClose, -1); - } } return rc; @@ -232,6 +253,9 @@ if( rc==SQLITE_OK ){ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); } + if( ctx.bOpen ){ + fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); + } fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); if( rc==SQLITE_OK ){ @@ -510,6 +534,9 @@ if( rc==SQLITE_OK ){ rc = pApi->xTokenize(pFts, ctx.zIn, ctx.nIn, (void*)&ctx,fts5HighlightCb); } + if( ctx.bOpen ){ + fts5HighlightAppend(&rc, &ctx, ctx.zClose, -1); + } if( ctx.iRangeEnd>=(nColSize-1) ){ fts5HighlightAppend(&rc, &ctx, &ctx.zIn[ctx.iOff], ctx.nIn - ctx.iOff); }else{ diff -Nru sqlite3-3.42.0/ext/fts5/fts5_config.c sqlite3-3.44.0-0/ext/fts5/fts5_config.c --- sqlite3-3.42.0/ext/fts5/fts5_config.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_config.c 2023-11-04 14:23:58.000000000 +0000 @@ -22,6 +22,8 @@ #define FTS5_DEFAULT_CRISISMERGE 16 #define FTS5_DEFAULT_HASHSIZE (1024*1024) +#define FTS5_DEFAULT_DELETE_AUTOMERGE 10 /* default 10% */ + /* Maximum allowed page size */ #define FTS5_MAX_PAGE_SIZE (64*1024) @@ -352,6 +354,16 @@ return rc; } + if( sqlite3_strnicmp("contentless_delete", zCmd, nCmd)==0 ){ + if( (zArg[0]!='0' && zArg[0]!='1') || zArg[1]!='\0' ){ + *pzErr = sqlite3_mprintf("malformed contentless_delete=... directive"); + rc = SQLITE_ERROR; + }else{ + pConfig->bContentlessDelete = (zArg[0]=='1'); + } + return rc; + } + if( sqlite3_strnicmp("content_rowid", zCmd, nCmd)==0 ){ if( pConfig->zContentRowid ){ *pzErr = sqlite3_mprintf("multiple content_rowid=... directives"); @@ -596,6 +608,28 @@ sqlite3_free(zTwo); } + /* We only allow contentless_delete=1 if the table is indeed contentless. */ + if( rc==SQLITE_OK + && pRet->bContentlessDelete + && pRet->eContent!=FTS5_CONTENT_NONE + ){ + *pzErr = sqlite3_mprintf( + "contentless_delete=1 requires a contentless table" + ); + rc = SQLITE_ERROR; + } + + /* We only allow contentless_delete=1 if columnsize=0 is not present. + ** + ** This restriction may be removed at some point. + */ + if( rc==SQLITE_OK && pRet->bContentlessDelete && pRet->bColumnsize==0 ){ + *pzErr = sqlite3_mprintf( + "contentless_delete=1 is incompatible with columnsize=0" + ); + rc = SQLITE_ERROR; + } + /* If a tokenizer= option was successfully parsed, the tokenizer has ** already been allocated. Otherwise, allocate an instance of the default ** tokenizer (unicode61) now. */ @@ -890,6 +924,18 @@ } } + else if( 0==sqlite3_stricmp(zKey, "deletemerge") ){ + int nVal = -1; + if( SQLITE_INTEGER==sqlite3_value_numeric_type(pVal) ){ + nVal = sqlite3_value_int(pVal); + }else{ + *pbBadkey = 1; + } + if( nVal<0 ) nVal = FTS5_DEFAULT_DELETE_AUTOMERGE; + if( nVal>100 ) nVal = 0; + pConfig->nDeleteMerge = nVal; + } + else if( 0==sqlite3_stricmp(zKey, "rank") ){ const char *zIn = (const char*)sqlite3_value_text(pVal); char *zRank; @@ -938,6 +984,7 @@ pConfig->nUsermerge = FTS5_DEFAULT_USERMERGE; pConfig->nCrisisMerge = FTS5_DEFAULT_CRISISMERGE; pConfig->nHashSize = FTS5_DEFAULT_HASHSIZE; + pConfig->nDeleteMerge = FTS5_DEFAULT_DELETE_AUTOMERGE; zSql = sqlite3Fts5Mprintf(&rc, zSelect, pConfig->zDb, pConfig->zName); if( zSql ){ diff -Nru sqlite3-3.42.0/ext/fts5/fts5_expr.c sqlite3-3.44.0-0/ext/fts5/fts5_expr.c --- sqlite3-3.42.0/ext/fts5/fts5_expr.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_expr.c 2023-11-04 14:23:58.000000000 +0000 @@ -2477,7 +2477,7 @@ return pRet; } -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) static char *fts5ExprTermPrint(Fts5ExprTerm *pTerm){ sqlite3_int64 nByte = 0; Fts5ExprTerm *p; @@ -2583,6 +2583,8 @@ if( zRet==0 ) return 0; } + }else if( pExpr->eType==0 ){ + zRet = sqlite3_mprintf("{}"); }else{ char const *zOp = 0; int i; @@ -2844,14 +2846,14 @@ sqlite3_result_int(pCtx, sqlite3Fts5UnicodeFold(iCode, bRemoveDiacritics)); } } -#endif /* ifdef SQLITE_TEST */ +#endif /* if SQLITE_TEST || SQLITE_FTS5_DEBUG */ /* ** This is called during initialization to register the fts5_expr() scalar ** UDF with the SQLite handle passed as the only argument. */ int sqlite3Fts5ExprInit(Fts5Global *pGlobal, sqlite3 *db){ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) struct Fts5ExprFunc { const char *z; void (*x)(sqlite3_context*,int,sqlite3_value**); diff -Nru sqlite3-3.42.0/ext/fts5/fts5.h sqlite3-3.44.0-0/ext/fts5/fts5.h --- sqlite3-3.42.0/ext/fts5/fts5.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5.h 2023-11-04 14:23:58.000000000 +0000 @@ -263,7 +263,7 @@ ** See xPhraseFirstColumn above. */ struct Fts5ExtensionApi { - int iVersion; /* Currently always set to 3 */ + int iVersion; /* Currently always set to 2 */ void *(*xUserData)(Fts5Context*); @@ -492,8 +492,8 @@ ** as separate queries of the FTS index are required for each synonym. ** ** When using methods (2) or (3), it is important that the tokenizer only -** provide synonyms when tokenizing document text (method (2)) or query -** text (method (3)), not both. Doing so will not cause any errors, but is +** provide synonyms when tokenizing document text (method (3)) or query +** text (method (2)), not both. Doing so will not cause any errors, but is ** inefficient. */ typedef struct Fts5Tokenizer Fts5Tokenizer; @@ -541,7 +541,7 @@ int (*xCreateTokenizer)( fts5_api *pApi, const char *zName, - void *pContext, + void *pUserData, fts5_tokenizer *pTokenizer, void (*xDestroy)(void*) ); @@ -550,7 +550,7 @@ int (*xFindTokenizer)( fts5_api *pApi, const char *zName, - void **ppContext, + void **ppUserData, fts5_tokenizer *pTokenizer ); @@ -558,7 +558,7 @@ int (*xCreateFunction)( fts5_api *pApi, const char *zName, - void *pContext, + void *pUserData, fts5_extension_function xFunction, void (*xDestroy)(void*) ); diff -Nru sqlite3-3.42.0/ext/fts5/fts5_hash.c sqlite3-3.44.0-0/ext/fts5/fts5_hash.c --- sqlite3-3.42.0/ext/fts5/fts5_hash.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_hash.c 2023-11-04 14:23:58.000000000 +0000 @@ -475,7 +475,6 @@ pList = fts5HashEntryMerge(pList, ap[i]); } - pHash->nEntry = 0; sqlite3_free(ap); *ppSorted = pList; return SQLITE_OK; @@ -529,6 +528,28 @@ return fts5HashEntrySort(p, pTerm, nTerm, &p->pScan); } +#ifdef SQLITE_DEBUG +static int fts5HashCount(Fts5Hash *pHash){ + int nEntry = 0; + int ii; + for(ii=0; iinSlot; ii++){ + Fts5HashEntry *p = 0; + for(p=pHash->aSlot[ii]; p; p=p->pHashNext){ + nEntry++; + } + } + return nEntry; +} +#endif + +/* +** Return true if the hash table is empty, false otherwise. +*/ +int sqlite3Fts5HashIsEmpty(Fts5Hash *pHash){ + assert( pHash->nEntry==fts5HashCount(pHash) ); + return pHash->nEntry==0; +} + void sqlite3Fts5HashScanNext(Fts5Hash *p){ assert( !sqlite3Fts5HashScanEof(p) ); p->pScan = p->pScan->pScanNext; diff -Nru sqlite3-3.42.0/ext/fts5/fts5_index.c sqlite3-3.44.0-0/ext/fts5/fts5_index.c --- sqlite3-3.42.0/ext/fts5/fts5_index.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_index.c 2023-11-04 14:23:58.000000000 +0000 @@ -57,13 +57,31 @@ #define FTS5_MAX_LEVEL 64 /* +** There are two versions of the format used for the structure record: +** +** 1. the legacy format, that may be read by all fts5 versions, and +** +** 2. the V2 format, which is used by contentless_delete=1 databases. +** +** Both begin with a 4-byte "configuration cookie" value. Then, a legacy +** format structure record contains a varint - the number of levels in +** the structure. Whereas a V2 structure record contains the constant +** 4 bytes [0xff 0x00 0x00 0x01]. This is unambiguous as the value of a +** varint has to be at least 16256 to begin with "0xFF". And the default +** maximum number of levels is 64. +** +** See below for more on structure record formats. +*/ +#define FTS5_STRUCTURE_V2 "\xFF\x00\x00\x01" + +/* ** Details: ** ** The %_data table managed by this module, ** ** CREATE TABLE %_data(id INTEGER PRIMARY KEY, block BLOB); ** -** , contains the following 5 types of records. See the comments surrounding +** , contains the following 6 types of records. See the comments surrounding ** the FTS5_*_ROWID macros below for a description of how %_data rowids are ** assigned to each fo them. ** @@ -71,13 +89,13 @@ ** ** The set of segments that make up an index - the index structure - are ** recorded in a single record within the %_data table. The record consists -** of a single 32-bit configuration cookie value followed by a list of -** SQLite varints. If the FTS table features more than one index (because -** there are one or more prefix indexes), it is guaranteed that all share -** the same cookie value. +** of a single 32-bit configuration cookie value followed by a list of +** SQLite varints. ** -** Immediately following the configuration cookie, the record begins with -** three varints: +** If the structure record is a V2 record, the configuration cookie is +** followed by the following 4 bytes: [0xFF 0x00 0x00 0x01]. +** +** Next, the record continues with three varints: ** ** + number of levels, ** + total number of segments on all levels, @@ -92,6 +110,12 @@ ** + first leaf page number (often 1, always greater than 0) ** + final leaf page number ** +** Then, for V2 structures only: +** +** + lower origin counter value, +** + upper origin counter value, +** + the number of tombstone hash pages. +** ** 2. The Averages Record: ** ** A single record within the %_data table. The data is a list of varints. @@ -207,6 +231,38 @@ ** * A list of delta-encoded varints - the first rowid on each subsequent ** child page. ** +** 6. Tombstone Hash Page +** +** These records are only ever present in contentless_delete=1 tables. +** There are zero or more of these associated with each segment. They +** are used to store the tombstone rowids for rows contained in the +** associated segments. +** +** The set of nHashPg tombstone hash pages associated with a single +** segment together form a single hash table containing tombstone rowids. +** To find the page of the hash on which a key might be stored: +** +** iPg = (rowid % nHashPg) +** +** Then, within page iPg, which has nSlot slots: +** +** iSlot = (rowid / nHashPg) % nSlot +** +** Each tombstone hash page begins with an 8 byte header: +** +** 1-byte: Key-size (the size in bytes of each slot). Either 4 or 8. +** 1-byte: rowid-0-tombstone flag. This flag is only valid on the +** first tombstone hash page for each segment (iPg=0). If set, +** the hash table contains rowid 0. If clear, it does not. +** Rowid 0 is handled specially. +** 2-bytes: unused. +** 4-bytes: Big-endian integer containing number of entries on page. +** +** Following this are nSlot 4 or 8 byte slots (depending on the key-size +** in the first byte of the page header). The number of slots may be +** determined based on the size of the page record and the key-size: +** +** nSlot = (nByte - 8) / key-size */ /* @@ -240,6 +296,7 @@ #define FTS5_SEGMENT_ROWID(segid, pgno) fts5_dri(segid, 0, 0, pgno) #define FTS5_DLIDX_ROWID(segid, height, pgno) fts5_dri(segid, 1, height, pgno) +#define FTS5_TOMBSTONE_ROWID(segid,ipg) fts5_dri(segid+(1<<16), 0, 0, ipg) #ifdef SQLITE_DEBUG int sqlite3Fts5Corrupt() { return SQLITE_CORRUPT_VTAB; } @@ -275,6 +332,12 @@ /* ** One object per %_data table. +** +** nContentlessDelete: +** The number of contentless delete operations since the most recent +** call to fts5IndexFlush() or fts5IndexDiscardData(). This is tracked +** so that extra auto-merge work can be done by fts5IndexFlush() to +** account for the delete operations. */ struct Fts5Index { Fts5Config *pConfig; /* Virtual table configuration */ @@ -289,6 +352,8 @@ int nPendingData; /* Current bytes of pending data */ i64 iWriteRowid; /* Rowid for current doc being written */ int bDelete; /* Current write is a delete */ + int nContentlessDelete; /* Number of contentless delete ops */ + int nPendingRow; /* Number of INSERT in hash table */ /* Error state. */ int rc; /* Current error code */ @@ -323,11 +388,23 @@ ** The contents of the "structure" record for each index are represented ** using an Fts5Structure record in memory. Which uses instances of the ** other Fts5StructureXXX types as components. +** +** nOriginCntr: +** This value is set to non-zero for structure records created for +** contentlessdelete=1 tables only. In that case it represents the +** origin value to apply to the next top-level segment created. */ struct Fts5StructureSegment { int iSegid; /* Segment id */ int pgnoFirst; /* First leaf page number in segment */ int pgnoLast; /* Last leaf page number in segment */ + + /* contentlessdelete=1 tables only: */ + u64 iOrigin1; + u64 iOrigin2; + int nPgTombstone; /* Number of tombstone hash table pages */ + u64 nEntryTombstone; /* Number of tombstone entries that "count" */ + u64 nEntry; /* Number of rows in this segment */ }; struct Fts5StructureLevel { int nMerge; /* Number of segments in incr-merge */ @@ -337,6 +414,7 @@ struct Fts5Structure { int nRef; /* Object reference count */ u64 nWriteCounter; /* Total leaves written to level 0 */ + u64 nOriginCntr; /* Origin value for next top-level segment */ int nSegment; /* Total segments in this structure */ int nLevel; /* Number of levels in this index */ Fts5StructureLevel aLevel[1]; /* Array of nLevel level objects */ @@ -425,6 +503,13 @@ ** ** iTermIdx: ** Index of current term on iTermLeafPgno. +** +** apTombstone/nTombstone: +** These are used for contentless_delete=1 tables only. When the cursor +** is first allocated, the apTombstone[] array is allocated so that it +** is large enough for all tombstones hash pages associated with the +** segment. The pages themselves are loaded lazily from the database as +** they are required. */ struct Fts5SegIter { Fts5StructureSegment *pSeg; /* Segment to iterate through */ @@ -433,6 +518,8 @@ Fts5Data *pLeaf; /* Current leaf data */ Fts5Data *pNextLeaf; /* Leaf page (iLeafPgno+1) */ i64 iLeafOffset; /* Byte offset within current leaf */ + Fts5Data **apTombstone; /* Array of tombstone pages */ + int nTombstone; /* Next method */ void (*xNext)(Fts5Index*, Fts5SegIter*, int*); @@ -563,6 +650,60 @@ } /* +** The only argument points to a buffer at least 8 bytes in size. This +** function interprets the first 8 bytes of the buffer as a 64-bit big-endian +** unsigned integer and returns the result. +*/ +static u64 fts5GetU64(u8 *a){ + return ((u64)a[0] << 56) + + ((u64)a[1] << 48) + + ((u64)a[2] << 40) + + ((u64)a[3] << 32) + + ((u64)a[4] << 24) + + ((u64)a[5] << 16) + + ((u64)a[6] << 8) + + ((u64)a[7] << 0); +} + +/* +** The only argument points to a buffer at least 4 bytes in size. This +** function interprets the first 4 bytes of the buffer as a 32-bit big-endian +** unsigned integer and returns the result. +*/ +static u32 fts5GetU32(const u8 *a){ + return ((u32)a[0] << 24) + + ((u32)a[1] << 16) + + ((u32)a[2] << 8) + + ((u32)a[3] << 0); +} + +/* +** Write iVal, formated as a 64-bit big-endian unsigned integer, to the +** buffer indicated by the first argument. +*/ +static void fts5PutU64(u8 *a, u64 iVal){ + a[0] = ((iVal >> 56) & 0xFF); + a[1] = ((iVal >> 48) & 0xFF); + a[2] = ((iVal >> 40) & 0xFF); + a[3] = ((iVal >> 32) & 0xFF); + a[4] = ((iVal >> 24) & 0xFF); + a[5] = ((iVal >> 16) & 0xFF); + a[6] = ((iVal >> 8) & 0xFF); + a[7] = ((iVal >> 0) & 0xFF); +} + +/* +** Write iVal, formated as a 32-bit big-endian unsigned integer, to the +** buffer indicated by the first argument. +*/ +static void fts5PutU32(u8 *a, u32 iVal){ + a[0] = ((iVal >> 24) & 0xFF); + a[1] = ((iVal >> 16) & 0xFF); + a[2] = ((iVal >> 8) & 0xFF); + a[3] = ((iVal >> 0) & 0xFF); +} + +/* ** Allocate and return a buffer at least nByte bytes in size. ** ** If an OOM error is encountered, return NULL and set the error code in @@ -789,10 +930,17 @@ /* ** Remove all records associated with segment iSegid. */ -static void fts5DataRemoveSegment(Fts5Index *p, int iSegid){ +static void fts5DataRemoveSegment(Fts5Index *p, Fts5StructureSegment *pSeg){ + int iSegid = pSeg->iSegid; i64 iFirst = FTS5_SEGMENT_ROWID(iSegid, 0); i64 iLast = FTS5_SEGMENT_ROWID(iSegid+1, 0)-1; fts5DataDelete(p, iFirst, iLast); + + if( pSeg->nPgTombstone ){ + i64 iTomb1 = FTS5_TOMBSTONE_ROWID(iSegid, 0); + i64 iTomb2 = FTS5_TOMBSTONE_ROWID(iSegid, pSeg->nPgTombstone-1); + fts5DataDelete(p, iTomb1, iTomb2); + } if( p->pIdxDeleter==0 ){ Fts5Config *pConfig = p->pConfig; fts5IndexPrepareStmt(p, &p->pIdxDeleter, sqlite3_mprintf( @@ -903,11 +1051,19 @@ int nSegment = 0; sqlite3_int64 nByte; /* Bytes of space to allocate at pRet */ Fts5Structure *pRet = 0; /* Structure object to return */ + int bStructureV2 = 0; /* True for FTS5_STRUCTURE_V2 */ + u64 nOriginCntr = 0; /* Largest origin value seen so far */ /* Grab the cookie value */ if( piCookie ) *piCookie = sqlite3Fts5Get32(pData); i = 4; + /* Check if this is a V2 structure record. Set bStructureV2 if it is. */ + if( 0==memcmp(&pData[i], FTS5_STRUCTURE_V2, 4) ){ + i += 4; + bStructureV2 = 1; + } + /* Read the total number of levels and segments from the start of the ** structure record. */ i += fts5GetVarint32(&pData[i], nLevel); @@ -958,6 +1114,14 @@ i += fts5GetVarint32(&pData[i], pSeg->iSegid); i += fts5GetVarint32(&pData[i], pSeg->pgnoFirst); i += fts5GetVarint32(&pData[i], pSeg->pgnoLast); + if( bStructureV2 ){ + i += fts5GetVarint(&pData[i], &pSeg->iOrigin1); + i += fts5GetVarint(&pData[i], &pSeg->iOrigin2); + i += fts5GetVarint32(&pData[i], pSeg->nPgTombstone); + i += fts5GetVarint(&pData[i], &pSeg->nEntryTombstone); + i += fts5GetVarint(&pData[i], &pSeg->nEntry); + nOriginCntr = MAX(nOriginCntr, pSeg->iOrigin2); + } if( pSeg->pgnoLastpgnoFirst ){ rc = FTS5_CORRUPT; break; @@ -968,6 +1132,9 @@ } } if( nSegment!=0 && rc==SQLITE_OK ) rc = FTS5_CORRUPT; + if( bStructureV2 ){ + pRet->nOriginCntr = nOriginCntr+1; + } if( rc!=SQLITE_OK ){ fts5StructureRelease(pRet); @@ -1180,6 +1347,7 @@ Fts5Buffer buf; /* Buffer to serialize record into */ int iLvl; /* Used to iterate through levels */ int iCookie; /* Cookie value to store */ + int nHdr = (pStruct->nOriginCntr>0 ? (4+4+9+9+9) : (4+9+9)); assert( pStruct->nSegment==fts5StructureCountSegments(pStruct) ); memset(&buf, 0, sizeof(Fts5Buffer)); @@ -1188,9 +1356,12 @@ iCookie = p->pConfig->iCookie; if( iCookie<0 ) iCookie = 0; - if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, 4+9+9+9) ){ + if( 0==sqlite3Fts5BufferSize(&p->rc, &buf, nHdr) ){ sqlite3Fts5Put32(buf.p, iCookie); buf.n = 4; + if( pStruct->nOriginCntr>0 ){ + fts5BufferSafeAppendBlob(&buf, FTS5_STRUCTURE_V2, 4); + } fts5BufferSafeAppendVarint(&buf, pStruct->nLevel); fts5BufferSafeAppendVarint(&buf, pStruct->nSegment); fts5BufferSafeAppendVarint(&buf, (i64)pStruct->nWriteCounter); @@ -1204,9 +1375,17 @@ assert( pLvl->nMerge<=pLvl->nSeg ); for(iSeg=0; iSegnSeg; iSeg++){ - fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].iSegid); - fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoFirst); - fts5BufferAppendVarint(&p->rc, &buf, pLvl->aSeg[iSeg].pgnoLast); + Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; + fts5BufferAppendVarint(&p->rc, &buf, pSeg->iSegid); + fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoFirst); + fts5BufferAppendVarint(&p->rc, &buf, pSeg->pgnoLast); + if( pStruct->nOriginCntr>0 ){ + fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin1); + fts5BufferAppendVarint(&p->rc, &buf, pSeg->iOrigin2); + fts5BufferAppendVarint(&p->rc, &buf, pSeg->nPgTombstone); + fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntryTombstone); + fts5BufferAppendVarint(&p->rc, &buf, pSeg->nEntry); + } } } @@ -1730,6 +1909,23 @@ } /* +** Allocate a tombstone hash page array (pIter->apTombstone) for the +** iterator passed as the second argument. If an OOM error occurs, leave +** an error in the Fts5Index object. +*/ +static void fts5SegIterAllocTombstone(Fts5Index *p, Fts5SegIter *pIter){ + const int nTomb = pIter->pSeg->nPgTombstone; + if( nTomb>0 ){ + Fts5Data **apTomb = 0; + apTomb = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data)*nTomb); + if( apTomb ){ + pIter->apTombstone = apTomb; + pIter->nTombstone = nTomb; + } + } +} + +/* ** Initialize the iterator object pIter to iterate through the entries in ** segment pSeg. The iterator is left pointing to the first entry when ** this function returns. @@ -1770,6 +1966,7 @@ pIter->iPgidxOff = pIter->pLeaf->szLeaf+1; fts5SegIterLoadTerm(p, pIter, 0); fts5SegIterLoadNPos(p, pIter); + fts5SegIterAllocTombstone(p, pIter); } } @@ -2471,6 +2668,7 @@ } fts5SegIterSetNext(p, pIter); + fts5SegIterAllocTombstone(p, pIter); /* Either: ** @@ -2552,12 +2750,27 @@ } /* +** Array ap[] contains n elements. Release each of these elements using +** fts5DataRelease(). Then free the array itself using sqlite3_free(). +*/ +static void fts5IndexFreeArray(Fts5Data **ap, int n){ + if( ap ){ + int ii; + for(ii=0; iiterm); fts5DataRelease(pIter->pLeaf); fts5DataRelease(pIter->pNextLeaf); + fts5IndexFreeArray(pIter->apTombstone, pIter->nTombstone); fts5DlidxIterFree(pIter->pDlidx); sqlite3_free(pIter->aRowidOffset); memset(pIter, 0, sizeof(Fts5SegIter)); @@ -2691,7 +2904,6 @@ assert_nc( i2!=0 ); pRes->bTermEq = 1; if( p1->iRowid==p2->iRowid ){ - p1->bDel = p2->bDel; return i2; } res = ((p1->iRowid > p2->iRowid)==pIter->bRev) ? -1 : +1; @@ -2896,6 +3108,84 @@ } /* +** The argument to this macro must be an Fts5Data structure containing a +** tombstone hash page. This macro returns the key-size of the hash-page. +*/ +#define TOMBSTONE_KEYSIZE(pPg) (pPg->p[0]==4 ? 4 : 8) + +#define TOMBSTONE_NSLOT(pPg) \ + ((pPg->nn > 16) ? ((pPg->nn-8) / TOMBSTONE_KEYSIZE(pPg)) : 1) + +/* +** Query a single tombstone hash table for rowid iRowid. Return true if +** it is found or false otherwise. The tombstone hash table is one of +** nHashTable tables. +*/ +static int fts5IndexTombstoneQuery( + Fts5Data *pHash, /* Hash table page to query */ + int nHashTable, /* Number of pages attached to segment */ + u64 iRowid /* Rowid to query hash for */ +){ + const int szKey = TOMBSTONE_KEYSIZE(pHash); + const int nSlot = TOMBSTONE_NSLOT(pHash); + int iSlot = (iRowid / nHashTable) % nSlot; + int nCollide = nSlot; + + if( iRowid==0 ){ + return pHash->p[1]; + }else if( szKey==4 ){ + u32 *aSlot = (u32*)&pHash->p[8]; + while( aSlot[iSlot] ){ + if( fts5GetU32((u8*)&aSlot[iSlot])==iRowid ) return 1; + if( nCollide--==0 ) break; + iSlot = (iSlot+1)%nSlot; + } + }else{ + u64 *aSlot = (u64*)&pHash->p[8]; + while( aSlot[iSlot] ){ + if( fts5GetU64((u8*)&aSlot[iSlot])==iRowid ) return 1; + if( nCollide--==0 ) break; + iSlot = (iSlot+1)%nSlot; + } + } + + return 0; +} + +/* +** Return true if the iterator passed as the only argument points +** to an segment entry for which there is a tombstone. Return false +** if there is no tombstone or if the iterator is already at EOF. +*/ +static int fts5MultiIterIsDeleted(Fts5Iter *pIter){ + int iFirst = pIter->aFirst[1].iFirst; + Fts5SegIter *pSeg = &pIter->aSeg[iFirst]; + + if( pSeg->pLeaf && pSeg->nTombstone ){ + /* Figure out which page the rowid might be present on. */ + int iPg = ((u64)pSeg->iRowid) % pSeg->nTombstone; + assert( iPg>=0 ); + + /* If tombstone hash page iPg has not yet been loaded from the + ** database, load it now. */ + if( pSeg->apTombstone[iPg]==0 ){ + pSeg->apTombstone[iPg] = fts5DataRead(pIter->pIndex, + FTS5_TOMBSTONE_ROWID(pSeg->pSeg->iSegid, iPg) + ); + if( pSeg->apTombstone[iPg]==0 ) return 0; + } + + return fts5IndexTombstoneQuery( + pSeg->apTombstone[iPg], + pSeg->nTombstone, + pSeg->iRowid + ); + } + + return 0; +} + +/* ** Move the iterator to the next entry. ** ** If an error occurs, an error code is left in Fts5Index.rc. It is not @@ -2932,7 +3222,9 @@ fts5AssertMultiIterSetup(p, pIter); assert( pSeg==&pIter->aSeg[pIter->aFirst[1].iFirst] && pSeg->pLeaf ); - if( pIter->bSkipEmpty==0 || pSeg->nPos ){ + if( (pIter->bSkipEmpty==0 || pSeg->nPos) + && 0==fts5MultiIterIsDeleted(pIter) + ){ pIter->xSetOutputs(pIter, pSeg); return; } @@ -2964,7 +3256,9 @@ } fts5AssertMultiIterSetup(p, pIter); - }while( fts5MultiIterIsEmpty(p, pIter) ); + }while( (fts5MultiIterIsEmpty(p, pIter) || fts5MultiIterIsDeleted(pIter)) + && (p->rc==SQLITE_OK) + ); } } @@ -2977,7 +3271,7 @@ int nSeg ){ Fts5Iter *pNew; - int nSlot; /* Power of two >= nSeg */ + i64 nSlot; /* Power of two >= nSeg */ for(nSlot=2; nSlotbSkipEmpty && fts5MultiIterIsEmpty(p, pNew) ){ + if( (pNew->bSkipEmpty && fts5MultiIterIsEmpty(p, pNew)) + || fts5MultiIterIsDeleted(pNew) + ){ fts5MultiIterNext(p, pNew, 0, 0); }else if( pNew->base.bEof==0 ){ Fts5SegIter *pSeg = &pNew->aSeg[pNew->aFirst[1].iFirst]; @@ -3697,7 +3993,9 @@ if( p->pHash ){ sqlite3Fts5HashClear(p->pHash); p->nPendingData = 0; + p->nPendingRow = 0; } + p->nContentlessDelete = 0; } /* @@ -4334,6 +4632,12 @@ /* Read input from all segments in the input level */ nInput = pLvl->nSeg; + + /* Set the range of origins that will go into the output segment. */ + if( pStruct->nOriginCntr>0 ){ + pSeg->iOrigin1 = pLvl->aSeg[0].iOrigin1; + pSeg->iOrigin2 = pLvl->aSeg[pLvl->nSeg-1].iOrigin2; + } } bOldest = (pLvlOut->nSeg==1 && pStruct->nLevel==iLvl+2); @@ -4393,8 +4697,11 @@ int i; /* Remove the redundant segments from the %_data table */ + assert( pSeg->nEntry==0 ); for(i=0; iaSeg[i].iSegid); + Fts5StructureSegment *pOld = &pLvl->aSeg[i]; + pSeg->nEntry += (pOld->nEntry - pOld->nEntryTombstone); + fts5DataRemoveSegment(p, pOld); } /* Remove the redundant segments from the input level */ @@ -4421,6 +4728,43 @@ } /* +** If this is not a contentless_delete=1 table, or if the 'deletemerge' +** configuration option is set to 0, then this function always returns -1. +** Otherwise, it searches the structure object passed as the second argument +** for a level suitable for merging due to having a large number of +** tombstones in the tombstone hash. If one is found, its index is returned. +** Otherwise, if there is no suitable level, -1. +*/ +static int fts5IndexFindDeleteMerge(Fts5Index *p, Fts5Structure *pStruct){ + Fts5Config *pConfig = p->pConfig; + int iRet = -1; + if( pConfig->bContentlessDelete && pConfig->nDeleteMerge>0 ){ + int ii; + int nBest = 0; + + for(ii=0; iinLevel; ii++){ + Fts5StructureLevel *pLvl = &pStruct->aLevel[ii]; + i64 nEntry = 0; + i64 nTomb = 0; + int iSeg; + for(iSeg=0; iSegnSeg; iSeg++){ + nEntry += pLvl->aSeg[iSeg].nEntry; + nTomb += pLvl->aSeg[iSeg].nEntryTombstone; + } + assert_nc( nEntry>0 || pLvl->nSeg==0 ); + if( nEntry>0 ){ + int nPercent = (nTomb * 100) / nEntry; + if( nPercent>=pConfig->nDeleteMerge && nPercent>nBest ){ + iRet = ii; + nBest = nPercent; + } + } + } + } + return iRet; +} + +/* ** Do up to nPg pages of automerge work on the index. ** ** Return true if any changes were actually made, or false otherwise. @@ -4439,14 +4783,15 @@ int iBestLvl = 0; /* Level offering the most input segments */ int nBest = 0; /* Number of input segments on best level */ - /* Set iBestLvl to the level to read input segments from. */ + /* Set iBestLvl to the level to read input segments from. Or to -1 if + ** there is no level suitable to merge segments from. */ assert( pStruct->nLevel>0 ); for(iLvl=0; iLvlnLevel; iLvl++){ Fts5StructureLevel *pLvl = &pStruct->aLevel[iLvl]; if( pLvl->nMerge ){ if( pLvl->nMerge>nBest ){ iBestLvl = iLvl; - nBest = pLvl->nMerge; + nBest = nMin; } break; } @@ -4455,22 +4800,18 @@ iBestLvl = iLvl; } } - - /* If nBest is still 0, then the index must be empty. */ -#ifdef SQLITE_DEBUG - for(iLvl=0; nBest==0 && iLvlnLevel; iLvl++){ - assert( pStruct->aLevel[iLvl].nSeg==0 ); + if( nBestaLevel[iBestLvl].nMerge==0 ){ - break; - } + if( iBestLvl<0 ) break; bRet = 1; fts5IndexMergeLevel(p, &pStruct, iBestLvl, &nRem); if( p->rc==SQLITE_OK && pStruct->aLevel[iBestLvl].nMerge==0 ){ fts5StructurePromote(p, iBestLvl+1, pStruct); } + + if( nMin==1 ) nMin = 2; } *ppStruct = pStruct; return bRet; @@ -4636,7 +4977,7 @@ pLeaf = 0; }else if( bDetailNone ){ break; - }else if( iNext>=pLeaf->szLeaf || iNext<4 ){ + }else if( iNext>=pLeaf->szLeaf || pLeaf->nnszLeaf || iNext<4 ){ p->rc = FTS5_CORRUPT; break; }else{ @@ -4655,9 +4996,13 @@ int i1 = pLeaf->szLeaf; int i2 = 0; + i1 += fts5GetVarint32(&aPg[i1], iFirst); + if( iFirstrc = FTS5_CORRUPT; + break; + } aIdx = sqlite3Fts5MallocZero(&p->rc, (pLeaf->nn-pLeaf->szLeaf)+2); if( aIdx==0 ) break; - i1 += fts5GetVarint32(&aPg[i1], iFirst); i2 = sqlite3Fts5PutVarint(aIdx, iFirst-nShift); if( i1nn ){ memcpy(&aIdx[i2], &aPg[i1], pLeaf->nn-i1); @@ -4702,7 +5047,6 @@ int iPgIdx = pSeg->pLeaf->szLeaf; u64 iDelta = 0; - u64 iNextDelta = 0; int iNextOff = 0; int iOff = 0; int nIdx = 0; @@ -4710,8 +5054,6 @@ int bLastInDoclist = 0; int iIdx = 0; int iStart = 0; - int iKeyOff = 0; - int iPrevKeyOff = 0; int iDelKeyOff = 0; /* Offset of deleted key, if any */ nIdx = nPg-iPgIdx; @@ -4736,10 +5078,21 @@ ** This block sets the following variables: ** ** iStart: + ** The offset of the first byte of the rowid or delta-rowid + ** value for the doclist entry being removed. + ** ** iDelta: + ** The value of the rowid or delta-rowid value for the doclist + ** entry being removed. + ** + ** iNextOff: + ** The offset of the next entry following the position list + ** for the one being removed. If the position list for this + ** entry overflows onto the next leaf page, this value will be + ** greater than pLeaf->szLeaf. */ { - int iSOP; + int iSOP; /* Start-Of-Position-list */ if( pSeg->iLeafPgno==pSeg->iTermLeafPgno ){ iStart = pSeg->iTermLeafOffset; }else{ @@ -4775,47 +5128,75 @@ } iOff = iStart; - if( iNextOff>=iPgIdx ){ - int pgno = pSeg->iLeafPgno+1; - fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); - iNextOff = iPgIdx; - }else{ - /* Set bLastInDoclist to true if the entry being removed is the last - ** in its doclist. */ - for(iIdx=0, iKeyOff=0; iIdxbDel==0 ){ + if( iNextOff>=iPgIdx ){ + int pgno = pSeg->iLeafPgno+1; + fts5SecureDeleteOverflow(p, pSeg->pSeg, pgno, &bLastInDoclist); + iNextOff = iPgIdx; + }else{ + /* Loop through the page-footer. If iNextOff (offset of the + ** entry following the one we are removing) is equal to the + ** offset of a key on this page, then the entry is the last + ** in its doclist. */ + int iKeyOff = 0; + for(iIdx=0; iIdxbDel ){ + iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta); + aPg[iOff++] = 0x01; + }else if( bLastInDoclist==0 ){ if( iNextOff!=iPgIdx ){ + u64 iNextDelta = 0; iNextOff += fts5GetVarint(&aPg[iNextOff], &iNextDelta); iOff += sqlite3Fts5PutVarint(&aPg[iOff], iDelta + iNextDelta); } }else if( - iStart==pSeg->iTermLeafOffset && pSeg->iLeafPgno==pSeg->iTermLeafPgno + pSeg->iLeafPgno==pSeg->iTermLeafPgno + && iStart==pSeg->iTermLeafOffset ){ /* The entry being removed was the only position list in its ** doclist. Therefore the term needs to be removed as well. */ int iKey = 0; - for(iIdx=0, iKeyOff=0; iIdx(u32)iStart ) break; iKeyOff += iVal; } + assert_nc( iKey>=1 ); + /* Set iDelKeyOff to the value of the footer entry to remove from + ** the page. */ iDelKeyOff = iOff = iKeyOff; + if( iNextOff!=iPgIdx ){ + /* This is the only position-list associated with the term, and there + ** is another term following it on this page. So the subsequent term + ** needs to be moved to replace the term associated with the entry + ** being removed. */ int nPrefix = 0; int nSuffix = 0; int nPrefix2 = 0; @@ -4840,7 +5221,9 @@ iOff += sqlite3Fts5PutVarint(&aPg[iOff], nPrefix); } iOff += sqlite3Fts5PutVarint(&aPg[iOff], nSuffix); - if( nPrefix2>nPrefix ){ + if( nPrefix2>pSeg->term.n ){ + p->rc = FTS5_CORRUPT; + }else if( nPrefix2>nPrefix ){ memcpy(&aPg[iOff], &pSeg->term.p[nPrefix], nPrefix2-nPrefix); iOff += (nPrefix2-nPrefix); } @@ -4850,80 +5233,88 @@ } } }else if( iStart==4 ){ - int iPgno; + int iPgno; - assert_nc( pSeg->iLeafPgno>pSeg->iTermLeafPgno ); - /* The entry being removed may be the only position list in - ** its doclist. */ - for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){ - Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); - int bEmpty = (pPg && pPg->nn==4); - fts5DataRelease(pPg); - if( bEmpty==0 ) break; - } - - if( iPgno==pSeg->iTermLeafPgno ){ - i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno); - Fts5Data *pTerm = fts5DataRead(p, iId); - if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){ - u8 *aTermIdx = &pTerm->p[pTerm->szLeaf]; - int nTermIdx = pTerm->nn - pTerm->szLeaf; - int iTermIdx = 0; - int iTermOff = 0; - - while( 1 ){ - u32 iVal = 0; - int nByte = fts5GetVarint32(&aTermIdx[iTermIdx], iVal); - iTermOff += iVal; - if( (iTermIdx+nByte)>=nTermIdx ) break; - iTermIdx += nByte; - } - nTermIdx = iTermIdx; + assert_nc( pSeg->iLeafPgno>pSeg->iTermLeafPgno ); + /* The entry being removed may be the only position list in + ** its doclist. */ + for(iPgno=pSeg->iLeafPgno-1; iPgno>pSeg->iTermLeafPgno; iPgno-- ){ + Fts5Data *pPg = fts5DataRead(p, FTS5_SEGMENT_ROWID(iSegid, iPgno)); + int bEmpty = (pPg && pPg->nn==4); + fts5DataRelease(pPg); + if( bEmpty==0 ) break; + } + + if( iPgno==pSeg->iTermLeafPgno ){ + i64 iId = FTS5_SEGMENT_ROWID(iSegid, pSeg->iTermLeafPgno); + Fts5Data *pTerm = fts5DataRead(p, iId); + if( pTerm && pTerm->szLeaf==pSeg->iTermLeafOffset ){ + u8 *aTermIdx = &pTerm->p[pTerm->szLeaf]; + int nTermIdx = pTerm->nn - pTerm->szLeaf; + int iTermIdx = 0; + int iTermOff = 0; + + while( 1 ){ + u32 iVal = 0; + int nByte = fts5GetVarint32(&aTermIdx[iTermIdx], iVal); + iTermOff += iVal; + if( (iTermIdx+nByte)>=nTermIdx ) break; + iTermIdx += nByte; + } + nTermIdx = iTermIdx; - memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); - fts5PutU16(&pTerm->p[2], iTermOff); + memmove(&pTerm->p[iTermOff], &pTerm->p[pTerm->szLeaf], nTermIdx); + fts5PutU16(&pTerm->p[2], iTermOff); - fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); - if( nTermIdx==0 ){ - fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); - } + fts5DataWrite(p, iId, pTerm->p, iTermOff+nTermIdx); + if( nTermIdx==0 ){ + fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iTermLeafPgno); } - fts5DataRelease(pTerm); } + fts5DataRelease(pTerm); } + } - if( p->rc==SQLITE_OK ){ - const int nMove = nPg - iNextOff; - int nShift = 0; + /* Assuming no error has occurred, this block does final edits to the + ** leaf page before writing it back to disk. Input variables are: + ** + ** nPg: Total initial size of leaf page. + ** iPgIdx: Initial offset of page footer. + ** + ** iOff: Offset to move data to + ** iNextOff: Offset to move data from + */ + if( p->rc==SQLITE_OK ){ + const int nMove = nPg - iNextOff; /* Number of bytes to move */ + int nShift = iNextOff - iOff; /* Distance to move them */ - memmove(&aPg[iOff], &aPg[iNextOff], nMove); - iPgIdx -= (iNextOff - iOff); - nPg = iPgIdx; - fts5PutU16(&aPg[2], iPgIdx); + int iPrevKeyOut = 0; + int iKeyIn = 0; - nShift = iNextOff - iOff; - for(iIdx=0, iKeyOff=0, iPrevKeyOff=0; iIdxiOff ){ - iKeyOff -= nShift; - nShift = 0; - } - nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOff - iPrevKeyOff); - iPrevKeyOff = iKeyOff; - } - } + memmove(&aPg[iOff], &aPg[iNextOff], nMove); + iPgIdx -= nShift; + nPg = iPgIdx; + fts5PutU16(&aPg[2], iPgIdx); - if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ - fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno); + for(iIdx=0; iIdxiOff ? nShift : 0)); + nPg += sqlite3Fts5PutVarint(&aPg[nPg], iKeyOut - iPrevKeyOut); + iPrevKeyOut = iKeyOut; } + } - assert_nc( nPg>4 || fts5GetU16(aPg)==0 ); - fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg,nPg); + if( iPgIdx==nPg && nIdx>0 && pSeg->iLeafPgno!=1 ){ + fts5SecureDeleteIdxEntry(p, iSegid, pSeg->iLeafPgno); } - sqlite3_free(aIdx); + + assert_nc( nPg>4 || fts5GetU16(aPg)==0 ); + fts5DataWrite(p, FTS5_SEGMENT_ROWID(iSegid,pSeg->iLeafPgno), aPg, nPg); + } + sqlite3_free(aIdx); } /* @@ -4977,184 +5368,198 @@ /* Obtain a reference to the index structure and allocate a new segment-id ** for the new level-0 segment. */ pStruct = fts5StructureRead(p); - iSegid = fts5AllocateSegid(p, pStruct); fts5StructureInvalidate(p); - if( iSegid ){ - const int pgsz = p->pConfig->pgsz; - int eDetail = p->pConfig->eDetail; - int bSecureDelete = p->pConfig->bSecureDelete; - Fts5StructureSegment *pSeg; /* New segment within pStruct */ - Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ - Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ - - Fts5SegWriter writer; - fts5WriteInit(p, &writer, iSegid); - - pBuf = &writer.writer.buf; - pPgidx = &writer.writer.pgidx; - - /* fts5WriteInit() should have initialized the buffers to (most likely) - ** the maximum space required. */ - assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) ); - assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) ); - - /* Begin scanning through hash table entries. This loop runs once for each - ** term/doclist currently stored within the hash table. */ - if( p->rc==SQLITE_OK ){ - p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); - } - while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ - const char *zTerm; /* Buffer containing term */ - int nTerm; /* Size of zTerm in bytes */ - const u8 *pDoclist; /* Pointer to doclist for this term */ - int nDoclist; /* Size of doclist in bytes */ - - /* Get the term and doclist for this entry. */ - sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); - nTerm = (int)strlen(zTerm); - if( bSecureDelete==0 ){ - fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); - if( p->rc!=SQLITE_OK ) break; - assert( writer.bFirstRowidInPage==0 ); - } - - if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ - /* The entire doclist will fit on the current leaf. */ - fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); - }else{ - int bTermWritten = !bSecureDelete; - i64 iRowid = 0; - i64 iPrev = 0; - int iOff = 0; - - /* The entire doclist will not fit on this leaf. The following - ** loop iterates through the poslists that make up the current - ** doclist. */ - while( p->rc==SQLITE_OK && iOffpConfig->pgsz; + int eDetail = p->pConfig->eDetail; + int bSecureDelete = p->pConfig->bSecureDelete; + Fts5StructureSegment *pSeg; /* New segment within pStruct */ + Fts5Buffer *pBuf; /* Buffer in which to assemble leaf page */ + Fts5Buffer *pPgidx; /* Buffer in which to assemble pgidx */ + + Fts5SegWriter writer; + fts5WriteInit(p, &writer, iSegid); + + pBuf = &writer.writer.buf; + pPgidx = &writer.writer.pgidx; + + /* fts5WriteInit() should have initialized the buffers to (most likely) + ** the maximum space required. */ + assert( p->rc || pBuf->nSpace>=(pgsz + FTS5_DATA_PADDING) ); + assert( p->rc || pPgidx->nSpace>=(pgsz + FTS5_DATA_PADDING) ); + + /* Begin scanning through hash table entries. This loop runs once for each + ** term/doclist currently stored within the hash table. */ + if( p->rc==SQLITE_OK ){ + p->rc = sqlite3Fts5HashScanInit(pHash, 0, 0); + } + while( p->rc==SQLITE_OK && 0==sqlite3Fts5HashScanEof(pHash) ){ + const char *zTerm; /* Buffer containing term */ + int nTerm; /* Size of zTerm in bytes */ + const u8 *pDoclist; /* Pointer to doclist for this term */ + int nDoclist; /* Size of doclist in bytes */ + + /* Get the term and doclist for this entry. */ + sqlite3Fts5HashScanEntry(pHash, &zTerm, &pDoclist, &nDoclist); + nTerm = (int)strlen(zTerm); + if( bSecureDelete==0 ){ + fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); + if( p->rc!=SQLITE_OK ) break; + assert( writer.bFirstRowidInPage==0 ); + } + + if( !bSecureDelete && pgsz>=(pBuf->n + pPgidx->n + nDoclist + 1) ){ + /* The entire doclist will fit on the current leaf. */ + fts5BufferSafeAppendBlob(pBuf, pDoclist, nDoclist); + }else{ + int bTermWritten = !bSecureDelete; + i64 iRowid = 0; + i64 iPrev = 0; + int iOff = 0; + + /* The entire doclist will not fit on this leaf. The following + ** loop iterates through the poslists that make up the current + ** doclist. */ + while( p->rc==SQLITE_OK && iOffrc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ iOff++; - nDoclist = 0; - }else{ continue; } } - }else if( (pDoclist[iOff] & 0x01) ){ - fts5FlushSecureDelete(p, pStruct, zTerm, iRowid); - if( p->rc!=SQLITE_OK || pDoclist[iOff]==0x01 ){ - iOff++; - continue; - } } - } - - if( p->rc==SQLITE_OK && bTermWritten==0 ){ - fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); - bTermWritten = 1; - assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 ); - } - - if( writer.bFirstRowidInPage ){ - fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */ - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); - writer.bFirstRowidInPage = 0; - fts5WriteDlidxAppend(p, &writer, iRowid); - }else{ - pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid-iPrev); - } - if( p->rc!=SQLITE_OK ) break; - assert( pBuf->n<=pBuf->nSpace ); - iPrev = iRowid; - - if( eDetail==FTS5_DETAIL_NONE ){ - if( iOffp[pBuf->n++] = 0; - iOff++; + + if( p->rc==SQLITE_OK && bTermWritten==0 ){ + fts5WriteAppendTerm(p, &writer, nTerm, (const u8*)zTerm); + bTermWritten = 1; + assert( p->rc!=SQLITE_OK || writer.bFirstRowidInPage==0 ); + } + + if( writer.bFirstRowidInPage ){ + fts5PutU16(&pBuf->p[0], (u16)pBuf->n); /* first rowid on page */ + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowid); + writer.bFirstRowidInPage = 0; + fts5WriteDlidxAppend(p, &writer, iRowid); + }else{ + u64 iRowidDelta = (u64)iRowid - (u64)iPrev; + pBuf->n += sqlite3Fts5PutVarint(&pBuf->p[pBuf->n], iRowidDelta); + } + if( p->rc!=SQLITE_OK ) break; + assert( pBuf->n<=pBuf->nSpace ); + iPrev = iRowid; + + if( eDetail==FTS5_DETAIL_NONE ){ if( iOffp[pBuf->n++] = 0; iOff++; + if( iOffp[pBuf->n++] = 0; + iOff++; + } + } + if( (pBuf->n + pPgidx->n)>=pgsz ){ + fts5WriteFlushLeaf(p, &writer); } - } - if( (pBuf->n + pPgidx->n)>=pgsz ){ - fts5WriteFlushLeaf(p, &writer); - } - }else{ - int bDummy; - int nPos; - int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDummy); - nCopy += nPos; - if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ - /* The entire poslist will fit on the current leaf. So copy - ** it in one go. */ - fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy); }else{ - /* The entire poslist will not fit on this leaf. So it needs - ** to be broken into sections. The only qualification being - ** that each varint must be stored contiguously. */ - const u8 *pPoslist = &pDoclist[iOff]; - int iPos = 0; - while( p->rc==SQLITE_OK ){ - int nSpace = pgsz - pBuf->n - pPgidx->n; - int n = 0; - if( (nCopy - iPos)<=nSpace ){ - n = nCopy - iPos; - }else{ - n = fts5PoslistPrefix(&pPoslist[iPos], nSpace); - } - assert( n>0 ); - fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n); - iPos += n; - if( (pBuf->n + pPgidx->n)>=pgsz ){ - fts5WriteFlushLeaf(p, &writer); + int bDel = 0; + int nPos = 0; + int nCopy = fts5GetPoslistSize(&pDoclist[iOff], &nPos, &bDel); + if( bDel && bSecureDelete ){ + fts5BufferAppendVarint(&p->rc, pBuf, nPos*2); + iOff += nCopy; + nCopy = nPos; + }else{ + nCopy += nPos; + } + if( (pBuf->n + pPgidx->n + nCopy) <= pgsz ){ + /* The entire poslist will fit on the current leaf. So copy + ** it in one go. */ + fts5BufferSafeAppendBlob(pBuf, &pDoclist[iOff], nCopy); + }else{ + /* The entire poslist will not fit on this leaf. So it needs + ** to be broken into sections. The only qualification being + ** that each varint must be stored contiguously. */ + const u8 *pPoslist = &pDoclist[iOff]; + int iPos = 0; + while( p->rc==SQLITE_OK ){ + int nSpace = pgsz - pBuf->n - pPgidx->n; + int n = 0; + if( (nCopy - iPos)<=nSpace ){ + n = nCopy - iPos; + }else{ + n = fts5PoslistPrefix(&pPoslist[iPos], nSpace); + } + assert( n>0 ); + fts5BufferSafeAppendBlob(pBuf, &pPoslist[iPos], n); + iPos += n; + if( (pBuf->n + pPgidx->n)>=pgsz ){ + fts5WriteFlushLeaf(p, &writer); + } + if( iPos>=nCopy ) break; } - if( iPos>=nCopy ) break; } + iOff += nCopy; } - iOff += nCopy; } } + + /* TODO2: Doclist terminator written here. */ + /* pBuf->p[pBuf->n++] = '\0'; */ + assert( pBuf->n<=pBuf->nSpace ); + if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); } - - /* TODO2: Doclist terminator written here. */ - /* pBuf->p[pBuf->n++] = '\0'; */ - assert( pBuf->n<=pBuf->nSpace ); - if( p->rc==SQLITE_OK ) sqlite3Fts5HashScanNext(pHash); - } - sqlite3Fts5HashClear(pHash); - fts5WriteFinish(p, &writer, &pgnoLast); - - assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 ); - if( pgnoLast>0 ){ - /* Update the Fts5Structure. It is written back to the database by the - ** fts5StructureRelease() call below. */ - if( pStruct->nLevel==0 ){ - fts5StructureAddLevel(&p->rc, &pStruct); - } - fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); - if( p->rc==SQLITE_OK ){ - pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; - pSeg->iSegid = iSegid; - pSeg->pgnoFirst = 1; - pSeg->pgnoLast = pgnoLast; - pStruct->nSegment++; + fts5WriteFinish(p, &writer, &pgnoLast); + + assert( p->rc!=SQLITE_OK || bSecureDelete || pgnoLast>0 ); + if( pgnoLast>0 ){ + /* Update the Fts5Structure. It is written back to the database by the + ** fts5StructureRelease() call below. */ + if( pStruct->nLevel==0 ){ + fts5StructureAddLevel(&p->rc, &pStruct); + } + fts5StructureExtendLevel(&p->rc, pStruct, 0, 1, 0); + if( p->rc==SQLITE_OK ){ + pSeg = &pStruct->aLevel[0].aSeg[ pStruct->aLevel[0].nSeg++ ]; + pSeg->iSegid = iSegid; + pSeg->pgnoFirst = 1; + pSeg->pgnoLast = pgnoLast; + if( pStruct->nOriginCntr>0 ){ + pSeg->iOrigin1 = pStruct->nOriginCntr; + pSeg->iOrigin2 = pStruct->nOriginCntr; + pSeg->nEntry = p->nPendingRow; + pStruct->nOriginCntr++; + } + pStruct->nSegment++; + } + fts5StructurePromote(p, 0, pStruct); } - fts5StructurePromote(p, 0, pStruct); } } - fts5IndexAutomerge(p, &pStruct, pgnoLast); + fts5IndexAutomerge(p, &pStruct, pgnoLast + p->nContentlessDelete); fts5IndexCrisismerge(p, &pStruct); fts5StructureWrite(p, pStruct); fts5StructureRelease(pStruct); @@ -5165,10 +5570,15 @@ */ static void fts5IndexFlush(Fts5Index *p){ /* Unless it is empty, flush the hash table to disk */ - if( p->nPendingData ){ + if( p->nPendingData || p->nContentlessDelete ){ assert( p->pHash ); - p->nPendingData = 0; fts5FlushOneHash(p); + if( p->rc==SQLITE_OK ){ + sqlite3Fts5HashClear(p->pHash); + p->nPendingData = 0; + p->nPendingRow = 0; + p->nContentlessDelete = 0; + } } } @@ -5184,17 +5594,22 @@ /* Figure out if this structure requires optimization. A structure does ** not require optimization if either: ** - ** + it consists of fewer than two segments, or - ** + all segments are on the same level, or - ** + all segments except one are currently inputs to a merge operation. + ** 1. it consists of fewer than two segments, or + ** 2. all segments are on the same level, or + ** 3. all segments except one are currently inputs to a merge operation. ** - ** In the first case, return NULL. In the second, increment the ref-count - ** on *pStruct and return a copy of the pointer to it. + ** In the first case, if there are no tombstone hash pages, return NULL. In + ** the second, increment the ref-count on *pStruct and return a copy of the + ** pointer to it. */ - if( nSeg<2 ) return 0; + if( nSeg==0 ) return 0; for(i=0; inLevel; i++){ int nThis = pStruct->aLevel[i].nSeg; - if( nThis==nSeg || (nThis==nSeg-1 && pStruct->aLevel[i].nMerge==nThis) ){ + int nMerge = pStruct->aLevel[i].nMerge; + if( nThis>0 && (nThis==nSeg || (nThis==nSeg-1 && nMerge==nThis)) ){ + if( nSeg==1 && nThis==1 && pStruct->aLevel[i].aSeg[0].nPgTombstone==0 ){ + return 0; + } fts5StructureRef(pStruct); return pStruct; } @@ -5210,6 +5625,7 @@ pNew->nLevel = MIN(pStruct->nLevel+1, FTS5_MAX_LEVEL); pNew->nRef = 1; pNew->nWriteCounter = pStruct->nWriteCounter; + pNew->nOriginCntr = pStruct->nOriginCntr; pLvl = &pNew->aLevel[pNew->nLevel-1]; pLvl->aSeg = (Fts5StructureSegment*)sqlite3Fts5MallocZero(&p->rc, nByte); if( pLvl->aSeg ){ @@ -5240,6 +5656,7 @@ assert( p->rc==SQLITE_OK ); fts5IndexFlush(p); + assert( p->nContentlessDelete==0 ); pStruct = fts5StructureRead(p); fts5StructureInvalidate(p); @@ -5269,7 +5686,10 @@ ** INSERT command. */ int sqlite3Fts5IndexMerge(Fts5Index *p, int nMerge){ - Fts5Structure *pStruct = fts5StructureRead(p); + Fts5Structure *pStruct = 0; + + fts5IndexFlush(p); + pStruct = fts5StructureRead(p); if( pStruct ){ int nMin = p->pConfig->nUsermerge; fts5StructureInvalidate(p); @@ -5277,7 +5697,7 @@ Fts5Structure *pNew = fts5IndexOptimizeStruct(p, pStruct); fts5StructureRelease(pStruct); pStruct = pNew; - nMin = 2; + nMin = 1; nMerge = nMerge*-1; } if( pStruct && pStruct->nLevel ){ @@ -5791,6 +6211,9 @@ p->iWriteRowid = iRowid; p->bDelete = bDelete; + if( bDelete==0 ){ + p->nPendingRow++; + } return fts5IndexReturn(p); } @@ -5828,6 +6251,9 @@ fts5StructureInvalidate(p); fts5IndexDiscardData(p); memset(&s, 0, sizeof(Fts5Structure)); + if( p->pConfig->bContentlessDelete ){ + s.nOriginCntr = 1; + } fts5DataWrite(p, FTS5_AVERAGES_ROWID, (const u8*)"", 0); fts5StructureWrite(p, &s); return fts5IndexReturn(p); @@ -6219,6 +6645,347 @@ return fts5IndexReturn(p); } +/* +** Retrieve the origin value that will be used for the segment currently +** being accumulated in the in-memory hash table when it is flushed to +** disk. If successful, SQLITE_OK is returned and (*piOrigin) set to +** the queried value. Or, if an error occurs, an error code is returned +** and the final value of (*piOrigin) is undefined. +*/ +int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin){ + Fts5Structure *pStruct; + pStruct = fts5StructureRead(p); + if( pStruct ){ + *piOrigin = pStruct->nOriginCntr; + fts5StructureRelease(pStruct); + } + return fts5IndexReturn(p); +} + +/* +** Buffer pPg contains a page of a tombstone hash table - one of nPg pages +** associated with the same segment. This function adds rowid iRowid to +** the hash table. The caller is required to guarantee that there is at +** least one free slot on the page. +** +** If parameter bForce is false and the hash table is deemed to be full +** (more than half of the slots are occupied), then non-zero is returned +** and iRowid not inserted. Or, if bForce is true or if the hash table page +** is not full, iRowid is inserted and zero returned. +*/ +static int fts5IndexTombstoneAddToPage( + Fts5Data *pPg, + int bForce, + int nPg, + u64 iRowid +){ + const int szKey = TOMBSTONE_KEYSIZE(pPg); + const int nSlot = TOMBSTONE_NSLOT(pPg); + const int nElem = fts5GetU32(&pPg->p[4]); + int iSlot = (iRowid / nPg) % nSlot; + int nCollide = nSlot; + + if( szKey==4 && iRowid>0xFFFFFFFF ) return 2; + if( iRowid==0 ){ + pPg->p[1] = 0x01; + return 0; + } + + if( bForce==0 && nElem>=(nSlot/2) ){ + return 1; + } + + fts5PutU32(&pPg->p[4], nElem+1); + if( szKey==4 ){ + u32 *aSlot = (u32*)&pPg->p[8]; + while( aSlot[iSlot] ){ + iSlot = (iSlot + 1) % nSlot; + if( nCollide--==0 ) return 0; + } + fts5PutU32((u8*)&aSlot[iSlot], (u32)iRowid); + }else{ + u64 *aSlot = (u64*)&pPg->p[8]; + while( aSlot[iSlot] ){ + iSlot = (iSlot + 1) % nSlot; + if( nCollide--==0 ) return 0; + } + fts5PutU64((u8*)&aSlot[iSlot], iRowid); + } + + return 0; +} + +/* +** This function attempts to build a new hash containing all the keys +** currently in the tombstone hash table for segment pSeg. The new +** hash will be stored in the nOut buffers passed in array apOut[]. +** All pages of the new hash use key-size szKey (4 or 8). +** +** Return 0 if the hash is successfully rebuilt into the nOut pages. +** Or non-zero if it is not (because one page became overfull). In this +** case the caller should retry with a larger nOut parameter. +** +** Parameter pData1 is page iPg1 of the hash table being rebuilt. +*/ +static int fts5IndexTombstoneRehash( + Fts5Index *p, + Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */ + Fts5Data *pData1, /* One page of current hash - or NULL */ + int iPg1, /* Which page of the current hash is pData1 */ + int szKey, /* 4 or 8, the keysize */ + int nOut, /* Number of output pages */ + Fts5Data **apOut /* Array of output hash pages */ +){ + int ii; + int res = 0; + + /* Initialize the headers of all the output pages */ + for(ii=0; iip[0] = szKey; + fts5PutU32(&apOut[ii]->p[4], 0); + } + + /* Loop through the current pages of the hash table. */ + for(ii=0; res==0 && iinPgTombstone; ii++){ + Fts5Data *pData = 0; /* Page ii of the current hash table */ + Fts5Data *pFree = 0; /* Free this at the end of the loop */ + + if( iPg1==ii ){ + pData = pData1; + }else{ + pFree = pData = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid, ii)); + } + + if( pData ){ + int szKeyIn = TOMBSTONE_KEYSIZE(pData); + int nSlotIn = (pData->nn - 8) / szKeyIn; + int iIn; + for(iIn=0; iInp[8]; + if( aSlot[iIn] ) iVal = fts5GetU32((u8*)&aSlot[iIn]); + }else{ + u64 *aSlot = (u64*)&pData->p[8]; + if( aSlot[iIn] ) iVal = fts5GetU64((u8*)&aSlot[iIn]); + } + + /* If iVal is not 0 at this point, insert it into the new hash table */ + if( iVal ){ + Fts5Data *pPg = apOut[(iVal % nOut)]; + res = fts5IndexTombstoneAddToPage(pPg, 0, nOut, iVal); + if( res ) break; + } + } + + /* If this is page 0 of the old hash, copy the rowid-0-flag from the + ** old hash to the new. */ + if( ii==0 ){ + apOut[0]->p[1] = pData->p[1]; + } + } + fts5DataRelease(pFree); + } + + return res; +} + +/* +** This is called to rebuild the hash table belonging to segment pSeg. +** If parameter pData1 is not NULL, then one page of the existing hash table +** has already been loaded - pData1, which is page iPg1. The key-size for +** the new hash table is szKey (4 or 8). +** +** If successful, the new hash table is not written to disk. Instead, +** output parameter (*pnOut) is set to the number of pages in the new +** hash table, and (*papOut) to point to an array of buffers containing +** the new page data. +** +** If an error occurs, an error code is left in the Fts5Index object and +** both output parameters set to 0 before returning. +*/ +static void fts5IndexTombstoneRebuild( + Fts5Index *p, + Fts5StructureSegment *pSeg, /* Segment to rebuild hash of */ + Fts5Data *pData1, /* One page of current hash - or NULL */ + int iPg1, /* Which page of the current hash is pData1 */ + int szKey, /* 4 or 8, the keysize */ + int *pnOut, /* OUT: Number of output pages */ + Fts5Data ***papOut /* OUT: Output hash pages */ +){ + const int MINSLOT = 32; + int nSlotPerPage = MAX(MINSLOT, (p->pConfig->pgsz - 8) / szKey); + int nSlot = 0; /* Number of slots in each output page */ + int nOut = 0; + + /* Figure out how many output pages (nOut) and how many slots per + ** page (nSlot). There are three possibilities: + ** + ** 1. The hash table does not yet exist. In this case the new hash + ** table will consist of a single page with MINSLOT slots. + ** + ** 2. The hash table exists but is currently a single page. In this + ** case an attempt is made to grow the page to accommodate the new + ** entry. The page is allowed to grow up to nSlotPerPage (see above) + ** slots. + ** + ** 3. The hash table already consists of more than one page, or of + ** a single page already so large that it cannot be grown. In this + ** case the new hash consists of (nPg*2+1) pages of nSlotPerPage + ** slots each, where nPg is the current number of pages in the + ** hash table. + */ + if( pSeg->nPgTombstone==0 ){ + /* Case 1. */ + nOut = 1; + nSlot = MINSLOT; + }else if( pSeg->nPgTombstone==1 ){ + /* Case 2. */ + int nElem = (int)fts5GetU32(&pData1->p[4]); + assert( pData1 && iPg1==0 ); + nOut = 1; + nSlot = MAX(nElem*4, MINSLOT); + if( nSlot>nSlotPerPage ) nOut = 0; + } + if( nOut==0 ){ + /* Case 3. */ + nOut = (pSeg->nPgTombstone * 2 + 1); + nSlot = nSlotPerPage; + } + + /* Allocate the required array and output pages */ + while( 1 ){ + int res = 0; + int ii = 0; + int szPage = 0; + Fts5Data **apOut = 0; + + /* Allocate space for the new hash table */ + assert( nSlot>=MINSLOT ); + apOut = (Fts5Data**)sqlite3Fts5MallocZero(&p->rc, sizeof(Fts5Data*) * nOut); + szPage = 8 + nSlot*szKey; + for(ii=0; iirc, + sizeof(Fts5Data)+szPage + ); + if( pNew ){ + pNew->nn = szPage; + pNew->p = (u8*)&pNew[1]; + apOut[ii] = pNew; + } + } + + /* Rebuild the hash table. */ + if( p->rc==SQLITE_OK ){ + res = fts5IndexTombstoneRehash(p, pSeg, pData1, iPg1, szKey, nOut, apOut); + } + if( res==0 ){ + if( p->rc ){ + fts5IndexFreeArray(apOut, nOut); + apOut = 0; + nOut = 0; + } + *pnOut = nOut; + *papOut = apOut; + break; + } + + /* If control flows to here, it was not possible to rebuild the hash + ** table. Free all buffers and then try again with more pages. */ + assert( p->rc==SQLITE_OK ); + fts5IndexFreeArray(apOut, nOut); + nSlot = nSlotPerPage; + nOut = nOut*2 + 1; + } +} + + +/* +** Add a tombstone for rowid iRowid to segment pSeg. +*/ +static void fts5IndexTombstoneAdd( + Fts5Index *p, + Fts5StructureSegment *pSeg, + u64 iRowid +){ + Fts5Data *pPg = 0; + int iPg = -1; + int szKey = 0; + int nHash = 0; + Fts5Data **apHash = 0; + + p->nContentlessDelete++; + + if( pSeg->nPgTombstone>0 ){ + iPg = iRowid % pSeg->nPgTombstone; + pPg = fts5DataRead(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg)); + if( pPg==0 ){ + assert( p->rc!=SQLITE_OK ); + return; + } + + if( 0==fts5IndexTombstoneAddToPage(pPg, 0, pSeg->nPgTombstone, iRowid) ){ + fts5DataWrite(p, FTS5_TOMBSTONE_ROWID(pSeg->iSegid,iPg), pPg->p, pPg->nn); + fts5DataRelease(pPg); + return; + } + } + + /* Have to rebuild the hash table. First figure out the key-size (4 or 8). */ + szKey = pPg ? TOMBSTONE_KEYSIZE(pPg) : 4; + if( iRowid>0xFFFFFFFF ) szKey = 8; + + /* Rebuild the hash table */ + fts5IndexTombstoneRebuild(p, pSeg, pPg, iPg, szKey, &nHash, &apHash); + assert( p->rc==SQLITE_OK || (nHash==0 && apHash==0) ); + + /* If all has succeeded, write the new rowid into one of the new hash + ** table pages, then write them all out to disk. */ + if( nHash ){ + int ii = 0; + fts5IndexTombstoneAddToPage(apHash[iRowid % nHash], 1, nHash, iRowid); + for(ii=0; iiiSegid, ii); + fts5DataWrite(p, iTombstoneRowid, apHash[ii]->p, apHash[ii]->nn); + } + pSeg->nPgTombstone = nHash; + fts5StructureWrite(p, p->pStruct); + } + + fts5DataRelease(pPg); + fts5IndexFreeArray(apHash, nHash); +} + +/* +** Add iRowid to the tombstone list of the segment or segments that contain +** rows from origin iOrigin. Return SQLITE_OK if successful, or an SQLite +** error code otherwise. +*/ +int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid){ + Fts5Structure *pStruct; + pStruct = fts5StructureRead(p); + if( pStruct ){ + int bFound = 0; /* True after pSeg->nEntryTombstone incr. */ + int iLvl; + for(iLvl=pStruct->nLevel-1; iLvl>=0; iLvl--){ + int iSeg; + for(iSeg=pStruct->aLevel[iLvl].nSeg-1; iSeg>=0; iSeg--){ + Fts5StructureSegment *pSeg = &pStruct->aLevel[iLvl].aSeg[iSeg]; + if( pSeg->iOrigin1<=(u64)iOrigin && pSeg->iOrigin2>=(u64)iOrigin ){ + if( bFound==0 ){ + pSeg->nEntryTombstone++; + bFound = 1; + } + fts5IndexTombstoneAdd(p, pSeg, iRowid); + } + } + } + fts5StructureRelease(pStruct); + } + return fts5IndexReturn(p); +} /************************************************************************* ************************************************************************** @@ -6770,13 +7537,14 @@ ** function only. */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** Decode a segment-data rowid from the %_data table. This function is ** the opposite of macro FTS5_SEGMENT_ROWID(). */ static void fts5DecodeRowid( i64 iRowid, /* Rowid from %_data table */ + int *pbTombstone, /* OUT: Tombstone hash flag */ int *piSegid, /* OUT: Segment id */ int *pbDlidx, /* OUT: Dlidx flag */ int *piHeight, /* OUT: Height */ @@ -6792,13 +7560,16 @@ iRowid >>= FTS5_DATA_DLI_B; *piSegid = (int)(iRowid & (((i64)1 << FTS5_DATA_ID_B) - 1)); + iRowid >>= FTS5_DATA_ID_B; + + *pbTombstone = (int)(iRowid & 0x0001); } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) static void fts5DebugRowid(int *pRc, Fts5Buffer *pBuf, i64 iKey){ - int iSegid, iHeight, iPgno, bDlidx; /* Rowid compenents */ - fts5DecodeRowid(iKey, &iSegid, &bDlidx, &iHeight, &iPgno); + int iSegid, iHeight, iPgno, bDlidx, bTomb; /* Rowid compenents */ + fts5DecodeRowid(iKey, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); if( iSegid==0 ){ if( iKey==FTS5_AVERAGES_ROWID ){ @@ -6808,14 +7579,16 @@ } } else{ - sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%ssegid=%d h=%d pgno=%d}", - bDlidx ? "dlidx " : "", iSegid, iHeight, iPgno + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "{%s%ssegid=%d h=%d pgno=%d}", + bDlidx ? "dlidx " : "", + bTomb ? "tombstone " : "", + iSegid, iHeight, iPgno ); } } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) static void fts5DebugStructure( int *pRc, /* IN/OUT: error code */ Fts5Buffer *pBuf, @@ -6830,16 +7603,22 @@ ); for(iSeg=0; iSegnSeg; iSeg++){ Fts5StructureSegment *pSeg = &pLvl->aSeg[iSeg]; - sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d}", + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " {id=%d leaves=%d..%d", pSeg->iSegid, pSeg->pgnoFirst, pSeg->pgnoLast ); + if( pSeg->iOrigin1>0 ){ + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " origin=%lld..%lld", + pSeg->iOrigin1, pSeg->iOrigin2 + ); + } + sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); } sqlite3Fts5BufferAppendPrintf(pRc, pBuf, "}"); } } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** This is part of the fts5_decode() debugging aid. ** @@ -6864,9 +7643,9 @@ fts5DebugStructure(pRc, pBuf, p); fts5StructureRelease(p); } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** This is part of the fts5_decode() debugging aid. ** @@ -6889,9 +7668,9 @@ zSpace = " "; } } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** Buffer (a/n) is assumed to contain a list of serialized varints. Read ** each varint and append its string representation to buffer pBuf. Return @@ -6908,9 +7687,9 @@ } return iOff; } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** The start of buffer (a/n) contains the start of a doclist. The doclist ** may or may not finish within the buffer. This function appends a text @@ -6943,9 +7722,9 @@ return iOff; } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** This function is part of the fts5_decode() debugging function. It is ** only ever used with detail=none tables. @@ -6986,9 +7765,9 @@ sqlite3Fts5BufferAppendPrintf(pRc, pBuf, " %lld%s", iRowid, zApp); } } -#endif /* SQLITE_TEST */ +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) /* ** The implementation of user-defined scalar function fts5_decode(). */ @@ -6999,6 +7778,7 @@ ){ i64 iRowid; /* Rowid for record being decoded */ int iSegid,iHeight,iPgno,bDlidx;/* Rowid components */ + int bTomb; const u8 *aBlob; int n; /* Record to decode */ u8 *a = 0; Fts5Buffer s; /* Build up text to return here */ @@ -7021,7 +7801,7 @@ if( a==0 ) goto decode_out; if( n>0 ) memcpy(a, aBlob, n); - fts5DecodeRowid(iRowid, &iSegid, &bDlidx, &iHeight, &iPgno); + fts5DecodeRowid(iRowid, &bTomb, &iSegid, &bDlidx, &iHeight, &iPgno); fts5DebugRowid(&rc, &s, iRowid); if( bDlidx ){ @@ -7040,6 +7820,28 @@ " %d(%lld)", lvl.iLeafPgno, lvl.iRowid ); } + }else if( bTomb ){ + u32 nElem = fts5GetU32(&a[4]); + int szKey = (aBlob[0]==4 || aBlob[0]==8) ? aBlob[0] : 8; + int nSlot = (n - 8) / szKey; + int ii; + sqlite3Fts5BufferAppendPrintf(&rc, &s, " nElem=%d", (int)nElem); + if( aBlob[1] ){ + sqlite3Fts5BufferAppendPrintf(&rc, &s, " 0"); + } + for(ii=0; iiszLeaf ){ + rc = FTS5_CORRUPT; + }else{ + fts5DecodeRowidList(&rc, &s, &a[iOff], iTermOff-iOff); + } iOff = iTermOff; if( iOffestimatedCost = (double)100; + pIdxInfo->estimatedRows = 100; + pIdxInfo->idxNum = 0; + for(i=0, p=pIdxInfo->aConstraint; inConstraint; i++, p++){ + if( p->usable==0 ) continue; + if( p->op==SQLITE_INDEX_CONSTRAINT_EQ && p->iColumn==11 ){ + rc = SQLITE_OK; + pIdxInfo->aConstraintUsage[i].omit = 1; + pIdxInfo->aConstraintUsage[i].argvIndex = 1; + break; + } + } + return rc; +} + +/* +** This method is the destructor for bytecodevtab objects. +*/ +static int fts5structDisconnectMethod(sqlite3_vtab *pVtab){ + Fts5StructVtab *p = (Fts5StructVtab*)pVtab; + sqlite3_free(p); + return SQLITE_OK; +} + +/* +** Constructor for a new bytecodevtab_cursor object. +*/ +static int fts5structOpenMethod(sqlite3_vtab *p, sqlite3_vtab_cursor **ppCsr){ + int rc = SQLITE_OK; + Fts5StructVcsr *pNew = 0; + + pNew = sqlite3Fts5MallocZero(&rc, sizeof(*pNew)); + *ppCsr = (sqlite3_vtab_cursor*)pNew; + + return SQLITE_OK; +} + +/* +** Destructor for a bytecodevtab_cursor. +*/ +static int fts5structCloseMethod(sqlite3_vtab_cursor *cur){ + Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; + fts5StructureRelease(pCsr->pStruct); + sqlite3_free(pCsr); + return SQLITE_OK; +} + + +/* +** Advance a bytecodevtab_cursor to its next row of output. +*/ +static int fts5structNextMethod(sqlite3_vtab_cursor *cur){ + Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; + Fts5Structure *p = pCsr->pStruct; + + assert( pCsr->pStruct ); + pCsr->iSeg++; + pCsr->iRowid++; + while( pCsr->iLevelnLevel && pCsr->iSeg>=p->aLevel[pCsr->iLevel].nSeg ){ + pCsr->iLevel++; + pCsr->iSeg = 0; + } + if( pCsr->iLevel>=p->nLevel ){ + fts5StructureRelease(pCsr->pStruct); + pCsr->pStruct = 0; + } + return SQLITE_OK; +} + +/* +** Return TRUE if the cursor has been moved off of the last +** row of output. +*/ +static int fts5structEofMethod(sqlite3_vtab_cursor *cur){ + Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; + return pCsr->pStruct==0; +} + +static int fts5structRowidMethod( + sqlite3_vtab_cursor *cur, + sqlite_int64 *piRowid +){ + Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; + *piRowid = pCsr->iRowid; + return SQLITE_OK; +} + +/* +** Return values of columns for the row at which the bytecodevtab_cursor +** is currently pointing. +*/ +static int fts5structColumnMethod( + sqlite3_vtab_cursor *cur, /* The cursor */ + sqlite3_context *ctx, /* First argument to sqlite3_result_...() */ + int i /* Which column to return */ +){ + Fts5StructVcsr *pCsr = (Fts5StructVcsr*)cur; + Fts5Structure *p = pCsr->pStruct; + Fts5StructureSegment *pSeg = &p->aLevel[pCsr->iLevel].aSeg[pCsr->iSeg]; + + switch( i ){ + case 0: /* level */ + sqlite3_result_int(ctx, pCsr->iLevel); + break; + case 1: /* segment */ + sqlite3_result_int(ctx, pCsr->iSeg); + break; + case 2: /* merge */ + sqlite3_result_int(ctx, pCsr->iSeg < p->aLevel[pCsr->iLevel].nMerge); + break; + case 3: /* segid */ + sqlite3_result_int(ctx, pSeg->iSegid); + break; + case 4: /* leaf1 */ + sqlite3_result_int(ctx, pSeg->pgnoFirst); + break; + case 5: /* leaf2 */ + sqlite3_result_int(ctx, pSeg->pgnoLast); + break; + case 6: /* origin1 */ + sqlite3_result_int64(ctx, pSeg->iOrigin1); + break; + case 7: /* origin2 */ + sqlite3_result_int64(ctx, pSeg->iOrigin2); + break; + case 8: /* npgtombstone */ + sqlite3_result_int(ctx, pSeg->nPgTombstone); + break; + case 9: /* nentrytombstone */ + sqlite3_result_int64(ctx, pSeg->nEntryTombstone); + break; + case 10: /* nentry */ + sqlite3_result_int64(ctx, pSeg->nEntry); + break; + } + return SQLITE_OK; +} + +/* +** Initialize a cursor. +** +** idxNum==0 means show all subprograms +** idxNum==1 means show only the main bytecode and omit subprograms. +*/ +static int fts5structFilterMethod( + sqlite3_vtab_cursor *pVtabCursor, + int idxNum, const char *idxStr, + int argc, sqlite3_value **argv +){ + Fts5StructVcsr *pCsr = (Fts5StructVcsr *)pVtabCursor; + int rc = SQLITE_OK; + + const u8 *aBlob = 0; + int nBlob = 0; + + assert( argc==1 ); + fts5StructureRelease(pCsr->pStruct); + pCsr->pStruct = 0; + + nBlob = sqlite3_value_bytes(argv[0]); + aBlob = (const u8*)sqlite3_value_blob(argv[0]); + rc = fts5StructureDecode(aBlob, nBlob, 0, &pCsr->pStruct); + if( rc==SQLITE_OK ){ + pCsr->iLevel = 0; + pCsr->iRowid = 0; + pCsr->iSeg = -1; + rc = fts5structNextMethod(pVtabCursor); + } + + return rc; +} + +#endif /* SQLITE_TEST || SQLITE_FTS5_DEBUG */ /* ** This is called as part of registering the FTS5 module with database @@ -7244,7 +8277,7 @@ ** SQLite error code is returned instead. */ int sqlite3Fts5IndexInit(sqlite3 *db){ -#ifdef SQLITE_TEST +#if defined(SQLITE_TEST) || defined(SQLITE_FTS5_DEBUG) int rc = sqlite3_create_function( db, "fts5_decode", 2, SQLITE_UTF8, 0, fts5DecodeFunction, 0, 0 ); @@ -7261,6 +8294,37 @@ db, "fts5_rowid", -1, SQLITE_UTF8, 0, fts5RowidFunction, 0, 0 ); } + + if( rc==SQLITE_OK ){ + static const sqlite3_module fts5structure_module = { + 0, /* iVersion */ + 0, /* xCreate */ + fts5structConnectMethod, /* xConnect */ + fts5structBestIndexMethod, /* xBestIndex */ + fts5structDisconnectMethod, /* xDisconnect */ + 0, /* xDestroy */ + fts5structOpenMethod, /* xOpen */ + fts5structCloseMethod, /* xClose */ + fts5structFilterMethod, /* xFilter */ + fts5structNextMethod, /* xNext */ + fts5structEofMethod, /* xEof */ + fts5structColumnMethod, /* xColumn */ + fts5structRowidMethod, /* xRowid */ + 0, /* xUpdate */ + 0, /* xBegin */ + 0, /* xSync */ + 0, /* xCommit */ + 0, /* xRollback */ + 0, /* xFindFunction */ + 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ + }; + rc = sqlite3_create_module(db, "fts5_structure", &fts5structure_module, 0); + } return rc; #else return SQLITE_OK; diff -Nru sqlite3-3.42.0/ext/fts5/fts5Int.h sqlite3-3.44.0-0/ext/fts5/fts5Int.h --- sqlite3-3.42.0/ext/fts5/fts5Int.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5Int.h 2023-11-04 14:23:58.000000000 +0000 @@ -154,6 +154,10 @@ ** attempt to merge together. A value of 1 sets the object to use the ** compile time default. Zero disables auto-merge altogether. ** +** bContentlessDelete: +** True if the contentless_delete option was present in the CREATE +** VIRTUAL TABLE statement. +** ** zContent: ** ** zContentRowid: @@ -188,6 +192,7 @@ int nPrefix; /* Number of prefix indexes */ int *aPrefix; /* Sizes in bytes of nPrefix prefix indexes */ int eContent; /* An FTS5_CONTENT value */ + int bContentlessDelete; /* "contentless_delete=" option (dflt==0) */ char *zContent; /* content table */ char *zContentRowid; /* "content_rowid=" option value */ int bColumnsize; /* "columnsize=" option value (dflt==1) */ @@ -209,6 +214,7 @@ char *zRank; /* Name of rank function */ char *zRankArgs; /* Arguments to rank function */ int bSecureDelete; /* 'secure-delete' */ + int nDeleteMerge; /* 'deletemerge' */ /* If non-NULL, points to sqlite3_vtab.base.zErrmsg. Often NULL. */ char **pzErrmsg; @@ -531,6 +537,9 @@ int sqlite3Fts5IndexLoadConfig(Fts5Index *p); +int sqlite3Fts5IndexGetOrigin(Fts5Index *p, i64 *piOrigin); +int sqlite3Fts5IndexContentlessDelete(Fts5Index *p, i64 iOrigin, i64 iRowid); + /* ** End of interface to code in fts5_index.c. **************************************************************************/ @@ -615,6 +624,11 @@ */ void sqlite3Fts5HashClear(Fts5Hash*); +/* +** Return true if the hash is empty, false otherwise. +*/ +int sqlite3Fts5HashIsEmpty(Fts5Hash*); + int sqlite3Fts5HashQuery( Fts5Hash*, /* Hash table to query */ int nPre, @@ -636,6 +650,7 @@ ); + /* ** End of interface to code in fts5_hash.c. **************************************************************************/ diff -Nru sqlite3-3.42.0/ext/fts5/fts5_main.c sqlite3-3.44.0-0/ext/fts5/fts5_main.c --- sqlite3-3.42.0/ext/fts5/fts5_main.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_main.c 2023-11-04 14:23:58.000000000 +0000 @@ -117,6 +117,8 @@ Fts5Storage *pStorage; /* Document store */ Fts5Global *pGlobal; /* Global (connection wide) data */ Fts5Cursor *pSortCsr; /* Sort data from this cursor */ + int iSavepoint; /* Successful xSavepoint()+1 */ + int bInSavepoint; #ifdef SQLITE_DEBUG struct Fts5TransactionState ts; #endif @@ -405,6 +407,13 @@ pConfig->pzErrmsg = 0; } + if( rc==SQLITE_OK && pConfig->eContent==FTS5_CONTENT_NORMAL ){ + rc = sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, (int)1); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + } + if( rc!=SQLITE_OK ){ fts5FreeVtab(pTab); pTab = 0; @@ -1329,6 +1338,9 @@ pCsr->iFirstRowid = fts5GetRowidLimit(pRowidGe, SMALLEST_INT64); } + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + if( rc!=SQLITE_OK ) goto filter_out; + if( pTab->pSortCsr ){ /* If pSortCsr is non-NULL, then this call is being made as part of ** processing for a "... MATCH ORDER BY rank" query (ePlan is @@ -1351,6 +1363,7 @@ pCsr->pExpr = pTab->pSortCsr->pExpr; rc = fts5CursorFirst(pTab, pCsr, bDesc); }else if( pCsr->pExpr ){ + assert( rc==SQLITE_OK ); rc = fts5CursorParseRank(pConfig, pCsr, pRank); if( rc==SQLITE_OK ){ if( bOrderByRank ){ @@ -1522,6 +1535,7 @@ Fts5Config *pConfig = pTab->p.pConfig; int rc = SQLITE_OK; int bError = 0; + int bLoadConfig = 0; if( 0==sqlite3_stricmp("delete-all", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ @@ -1533,6 +1547,7 @@ }else{ rc = sqlite3Fts5StorageDeleteAll(pTab->pStorage); } + bLoadConfig = 1; }else if( 0==sqlite3_stricmp("rebuild", zCmd) ){ if( pConfig->eContent==FTS5_CONTENT_NONE ){ fts5SetVtabError(pTab, @@ -1542,6 +1557,7 @@ }else{ rc = sqlite3Fts5StorageRebuild(pTab->pStorage); } + bLoadConfig = 1; }else if( 0==sqlite3_stricmp("optimize", zCmd) ){ rc = sqlite3Fts5StorageOptimize(pTab->pStorage); }else if( 0==sqlite3_stricmp("merge", zCmd) ){ @@ -1554,6 +1570,8 @@ }else if( 0==sqlite3_stricmp("prefix-index", zCmd) ){ pConfig->bPrefixIndex = sqlite3_value_int(pVal); #endif + }else if( 0==sqlite3_stricmp("flush", zCmd) ){ + rc = sqlite3Fts5FlushToDisk(&pTab->p); }else{ rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); if( rc==SQLITE_OK ){ @@ -1567,6 +1585,12 @@ } } } + + if( rc==SQLITE_OK && bLoadConfig ){ + pTab->p.pConfig->iCookie--; + rc = sqlite3Fts5IndexLoadConfig(pTab->p.pIndex); + } + return rc; } @@ -1624,7 +1648,6 @@ int eType0; /* value_type() of apVal[0] */ int rc = SQLITE_OK; /* Return code */ int bUpdateOrDelete = 0; - /* A transaction must be open when this is called. */ assert( pTab->ts.eState==1 || pTab->ts.eState==2 ); @@ -1654,7 +1677,14 @@ if( pConfig->eContent!=FTS5_CONTENT_NORMAL && 0==sqlite3_stricmp("delete", z) ){ - rc = fts5SpecialDelete(pTab, apVal); + if( pConfig->bContentlessDelete ){ + fts5SetVtabError(pTab, + "'delete' may not be used with a contentless_delete=1 table" + ); + rc = SQLITE_ERROR; + }else{ + rc = fts5SpecialDelete(pTab, apVal); + } }else{ rc = fts5SpecialInsert(pTab, z, apVal[2 + pConfig->nCol + 1]); } @@ -1671,7 +1701,7 @@ ** Cases 3 and 4 may violate the rowid constraint. */ int eConflict = SQLITE_ABORT; - if( pConfig->eContent==FTS5_CONTENT_NORMAL ){ + if( pConfig->eContent==FTS5_CONTENT_NORMAL || pConfig->bContentlessDelete ){ eConflict = sqlite3_vtab_on_conflict(pConfig->db); } @@ -1679,8 +1709,12 @@ assert( nArg!=1 || eType0==SQLITE_INTEGER ); /* Filter out attempts to run UPDATE or DELETE on contentless tables. - ** This is not suported. */ - if( eType0==SQLITE_INTEGER && fts5IsContentless(pTab) ){ + ** This is not suported. Except - they are both supported if the CREATE + ** VIRTUAL TABLE statement contained "contentless_delete=1". */ + if( eType0==SQLITE_INTEGER + && pConfig->eContent==FTS5_CONTENT_NONE + && pConfig->bContentlessDelete==0 + ){ pTab->p.base.zErrMsg = sqlite3_mprintf( "cannot %s contentless fts5 table: %s", (nArg>1 ? "UPDATE" : "DELETE from"), pConfig->zName @@ -1704,7 +1738,8 @@ } else if( eType0!=SQLITE_INTEGER ){ - /* If this is a REPLACE, first remove the current entry (if any) */ + /* An INSERT statement. If the conflict-mode is REPLACE, first remove + ** the current entry (if any). */ if( eConflict==SQLITE_REPLACE && eType1==SQLITE_INTEGER ){ i64 iNew = sqlite3_value_int64(apVal[1]); /* Rowid to delete */ rc = sqlite3Fts5StorageDelete(pTab->pStorage, iNew, 0); @@ -1767,8 +1802,7 @@ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; fts5CheckTransactionState(pTab, FTS5_SYNC, 0); pTab->p.pConfig->pzErrmsg = &pTab->p.base.zErrMsg; - fts5TripCursors(pTab); - rc = sqlite3Fts5StorageSync(pTab->pStorage); + rc = sqlite3Fts5FlushToDisk(&pTab->p); pTab->p.pConfig->pzErrmsg = 0; return rc; } @@ -2535,6 +2569,12 @@ sqlite3_result_value(pCtx, sqlite3_column_value(pCsr->pStmt, iCol+1)); } pConfig->pzErrmsg = 0; + }else if( pConfig->bContentlessDelete && sqlite3_vtab_nochange(pCtx) ){ + char *zErr = sqlite3_mprintf("cannot UPDATE a subset of " + "columns on fts5 contentless-delete table: %s", pConfig->zName + ); + sqlite3_result_error(pCtx, zErr, -1); + sqlite3_free(zErr); } return rc; } @@ -2573,8 +2613,12 @@ sqlite3_vtab *pVtab, /* Virtual table handle */ const char *zName /* New name of table */ ){ + int rc; Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - return sqlite3Fts5StorageRename(pTab->pStorage, zName); + pTab->bInSavepoint = 1; + rc = sqlite3Fts5StorageRename(pTab->pStorage, zName); + pTab->bInSavepoint = 0; + return rc; } int sqlite3Fts5FlushToDisk(Fts5Table *pTab){ @@ -2588,9 +2632,29 @@ ** Flush the contents of the pending-terms table to disk. */ static int fts5SavepointMethod(sqlite3_vtab *pVtab, int iSavepoint){ - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_SAVEPOINT, iSavepoint); - return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + int rc = SQLITE_OK; + char *zSql = 0; + fts5CheckTransactionState(pTab, FTS5_SAVEPOINT, iSavepoint); + + if( pTab->bInSavepoint==0 ){ + zSql = sqlite3_mprintf("INSERT INTO %Q.%Q(%Q) VALUES('flush')", + pTab->p.pConfig->zDb, pTab->p.pConfig->zName, pTab->p.pConfig->zName + ); + if( zSql ){ + pTab->bInSavepoint = 1; + rc = sqlite3_exec(pTab->p.pConfig->db, zSql, 0, 0, 0); + pTab->bInSavepoint = 0; + sqlite3_free(zSql); + }else{ + rc = SQLITE_NOMEM; + } + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint+1; + } + } + + return rc; } /* @@ -2599,9 +2663,16 @@ ** This is a no-op. */ static int fts5ReleaseMethod(sqlite3_vtab *pVtab, int iSavepoint){ - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ - fts5CheckTransactionState((Fts5FullTable*)pVtab, FTS5_RELEASE, iSavepoint); - return sqlite3Fts5FlushToDisk((Fts5Table*)pVtab); + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + int rc = SQLITE_OK; + fts5CheckTransactionState(pTab, FTS5_RELEASE, iSavepoint); + if( (iSavepoint+1)iSavepoint ){ + rc = sqlite3Fts5FlushToDisk(&pTab->p); + if( rc==SQLITE_OK ){ + pTab->iSavepoint = iSavepoint; + } + } + return rc; } /* @@ -2611,11 +2682,14 @@ */ static int fts5RollbackToMethod(sqlite3_vtab *pVtab, int iSavepoint){ Fts5FullTable *pTab = (Fts5FullTable*)pVtab; - UNUSED_PARAM(iSavepoint); /* Call below is a no-op for NDEBUG builds */ + int rc = SQLITE_OK; fts5CheckTransactionState(pTab, FTS5_ROLLBACKTO, iSavepoint); fts5TripCursors(pTab); pTab->p.pConfig->pgsz = 0; - return sqlite3Fts5StorageRollback(pTab->pStorage); + if( (iSavepoint+1)<=pTab->iSavepoint ){ + rc = sqlite3Fts5StorageRollback(pTab->pStorage); + } + return rc; } /* @@ -2835,9 +2909,46 @@ return 0; } +/* +** Run an integrity check on the FTS5 data structures. Return a string +** if anything is found amiss. Return a NULL pointer if everything is +** OK. +*/ +static int fts5Integrity( + sqlite3_vtab *pVtab, /* the FTS5 virtual table to check */ + const char *zSchema, /* Name of schema in which this table lives */ + const char *zTabname, /* Name of the table itself */ + int isQuick, /* True if this is a quick-check */ + char **pzErr /* Write error message here */ +){ + Fts5FullTable *pTab = (Fts5FullTable*)pVtab; + Fts5Config *pConfig = pTab->p.pConfig; + char *zSql; + char *zErr = 0; + int rc; + assert( pzErr!=0 && *pzErr==0 ); + UNUSED_PARAM(isQuick); + zSql = sqlite3_mprintf( + "INSERT INTO \"%w\".\"%w\"(\"%w\") VALUES('integrity-check');", + zSchema, zTabname, pConfig->zName); + if( zSql==0 ) return SQLITE_NOMEM; + rc = sqlite3_exec(pConfig->db, zSql, 0, 0, &zErr); + sqlite3_free(zSql); + if( (rc&0xff)==SQLITE_CORRUPT ){ + *pzErr = sqlite3_mprintf("malformed inverted index for FTS5 table %s.%s", + zSchema, zTabname); + }else if( rc!=SQLITE_OK ){ + *pzErr = sqlite3_mprintf("unable to validate the inverted index for" + " FTS5 table %s.%s: %s", + zSchema, zTabname, zErr); + } + sqlite3_free(zErr); + return SQLITE_OK; +} + static int fts5Init(sqlite3 *db){ static const sqlite3_module fts5Mod = { - /* iVersion */ 3, + /* iVersion */ 4, /* xCreate */ fts5CreateMethod, /* xConnect */ fts5ConnectMethod, /* xBestIndex */ fts5BestIndexMethod, @@ -2860,7 +2971,8 @@ /* xSavepoint */ fts5SavepointMethod, /* xRelease */ fts5ReleaseMethod, /* xRollbackTo */ fts5RollbackToMethod, - /* xShadowName */ fts5ShadowName + /* xShadowName */ fts5ShadowName, + /* xIntegrity */ fts5Integrity }; int rc; diff -Nru sqlite3-3.42.0/ext/fts5/fts5_storage.c sqlite3-3.44.0-0/ext/fts5/fts5_storage.c --- sqlite3-3.42.0/ext/fts5/fts5_storage.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_storage.c 2023-11-04 14:23:58.000000000 +0000 @@ -77,10 +77,10 @@ "INSERT INTO %Q.'%q_content' VALUES(%s)", /* INSERT_CONTENT */ "REPLACE INTO %Q.'%q_content' VALUES(%s)", /* REPLACE_CONTENT */ "DELETE FROM %Q.'%q_content' WHERE id=?", /* DELETE_CONTENT */ - "REPLACE INTO %Q.'%q_docsize' VALUES(?,?)", /* REPLACE_DOCSIZE */ + "REPLACE INTO %Q.'%q_docsize' VALUES(?,?%s)", /* REPLACE_DOCSIZE */ "DELETE FROM %Q.'%q_docsize' WHERE id=?", /* DELETE_DOCSIZE */ - "SELECT sz FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ + "SELECT sz%s FROM %Q.'%q_docsize' WHERE id=?", /* LOOKUP_DOCSIZE */ "REPLACE INTO %Q.'%q_config' VALUES(?,?)", /* REPLACE_CONFIG */ "SELECT %s FROM %s AS T", /* SCAN */ @@ -128,6 +128,19 @@ break; } + case FTS5_STMT_REPLACE_DOCSIZE: + zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName, + (pC->bContentlessDelete ? ",?" : "") + ); + break; + + case FTS5_STMT_LOOKUP_DOCSIZE: + zSql = sqlite3_mprintf(azStmt[eStmt], + (pC->bContentlessDelete ? ",origin" : ""), + pC->zDb, pC->zName + ); + break; + default: zSql = sqlite3_mprintf(azStmt[eStmt], pC->zDb, pC->zName); break; @@ -317,9 +330,11 @@ } if( rc==SQLITE_OK && pConfig->bColumnsize ){ - rc = sqlite3Fts5CreateTable( - pConfig, "docsize", "id INTEGER PRIMARY KEY, sz BLOB", 0, pzErr - ); + const char *zCols = "id INTEGER PRIMARY KEY, sz BLOB"; + if( pConfig->bContentlessDelete ){ + zCols = "id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER"; + } + rc = sqlite3Fts5CreateTable(pConfig, "docsize", zCols, 0, pzErr); } if( rc==SQLITE_OK ){ rc = sqlite3Fts5CreateTable( @@ -396,7 +411,7 @@ ){ Fts5Config *pConfig = p->pConfig; sqlite3_stmt *pSeek = 0; /* SELECT to read row iDel from %_data */ - int rc; /* Return code */ + int rc = SQLITE_OK; /* Return code */ int rc2; /* sqlite3_reset() return code */ int iCol; Fts5InsertCtx ctx; @@ -412,7 +427,6 @@ ctx.pStorage = p; ctx.iCol = -1; - rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); for(iCol=1; rc==SQLITE_OK && iCol<=pConfig->nCol; iCol++){ if( pConfig->abUnindexed[iCol-1]==0 ){ const char *zText; @@ -449,6 +463,37 @@ return rc; } +/* +** This function is called to process a DELETE on a contentless_delete=1 +** table. It adds the tombstone required to delete the entry with rowid +** iDel. If successful, SQLITE_OK is returned. Or, if an error occurs, +** an SQLite error code. +*/ +static int fts5StorageContentlessDelete(Fts5Storage *p, i64 iDel){ + i64 iOrigin = 0; + sqlite3_stmt *pLookup = 0; + int rc = SQLITE_OK; + + assert( p->pConfig->bContentlessDelete ); + assert( p->pConfig->eContent==FTS5_CONTENT_NONE ); + + /* Look up the origin of the document in the %_docsize table. Store + ** this in stack variable iOrigin. */ + rc = fts5StorageGetStmt(p, FTS5_STMT_LOOKUP_DOCSIZE, &pLookup, 0); + if( rc==SQLITE_OK ){ + sqlite3_bind_int64(pLookup, 1, iDel); + if( SQLITE_ROW==sqlite3_step(pLookup) ){ + iOrigin = sqlite3_column_int64(pLookup, 1); + } + rc = sqlite3_reset(pLookup); + } + + if( rc==SQLITE_OK && iOrigin!=0 ){ + rc = sqlite3Fts5IndexContentlessDelete(p->pIndex, iOrigin, iDel); + } + + return rc; +} /* ** Insert a record into the %_docsize table. Specifically, do: @@ -469,10 +514,17 @@ rc = fts5StorageGetStmt(p, FTS5_STMT_REPLACE_DOCSIZE, &pReplace, 0); if( rc==SQLITE_OK ){ sqlite3_bind_int64(pReplace, 1, iRowid); - sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); - sqlite3_step(pReplace); - rc = sqlite3_reset(pReplace); - sqlite3_bind_null(pReplace, 2); + if( p->pConfig->bContentlessDelete ){ + i64 iOrigin = 0; + rc = sqlite3Fts5IndexGetOrigin(p->pIndex, &iOrigin); + sqlite3_bind_int64(pReplace, 3, iOrigin); + } + if( rc==SQLITE_OK ){ + sqlite3_bind_blob(pReplace, 2, pBuf->p, pBuf->n, SQLITE_STATIC); + sqlite3_step(pReplace); + rc = sqlite3_reset(pReplace); + sqlite3_bind_null(pReplace, 2); + } } } return rc; @@ -536,7 +588,15 @@ /* Delete the index records */ if( rc==SQLITE_OK ){ - rc = fts5StorageDeleteFromIndex(p, iDel, apVal); + rc = sqlite3Fts5IndexBeginWrite(p->pIndex, 1, iDel); + } + + if( rc==SQLITE_OK ){ + if( p->pConfig->bContentlessDelete ){ + rc = fts5StorageContentlessDelete(p, iDel); + }else{ + rc = fts5StorageDeleteFromIndex(p, iDel, apVal); + } } /* Delete the %_docsize record */ @@ -1124,7 +1184,9 @@ i64 iLastRowid = sqlite3_last_insert_rowid(p->pConfig->db); if( p->bTotalsValid ){ rc = fts5StorageSaveTotals(p); - p->bTotalsValid = 0; + if( rc==SQLITE_OK ){ + p->bTotalsValid = 0; + } } if( rc==SQLITE_OK ){ rc = sqlite3Fts5IndexSync(p->pIndex); diff -Nru sqlite3-3.42.0/ext/fts5/fts5_test_tok.c sqlite3-3.44.0-0/ext/fts5/fts5_test_tok.c --- sqlite3-3.42.0/ext/fts5/fts5_test_tok.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_test_tok.c 2023-11-04 14:23:58.000000000 +0000 @@ -472,7 +472,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc; /* Return code */ diff -Nru sqlite3-3.42.0/ext/fts5/fts5_vocab.c sqlite3-3.44.0-0/ext/fts5/fts5_vocab.c --- sqlite3-3.42.0/ext/fts5/fts5_vocab.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/fts5_vocab.c 2023-11-04 14:23:58.000000000 +0000 @@ -783,7 +783,8 @@ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; void *p = (void*)pGlobal; diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5aa.test sqlite3-3.44.0-0/ext/fts5/test/fts5aa.test --- sqlite3-3.42.0/ext/fts5/test/fts5aa.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5aa.test 2023-11-04 14:23:58.000000000 +0000 @@ -65,7 +65,9 @@ do_execsql_test 2.4 { INSERT INTO t1(t1) VALUES('integrity-check'); -} + PRAGMA integrity_check; + PRAGMA integrity_check(t1); +} {ok ok} #------------------------------------------------------------------------- @@ -88,6 +90,7 @@ } { do_execsql_test 3.$i.1 { INSERT INTO t1 VALUES($x, $y) } do_execsql_test 3.$i.2 { INSERT INTO t1(t1) VALUES('integrity-check') } + do_execsql_test 3.$i.3 { PRAGMA integrity_check(t1) } ok if {[set_test_counter errors]} break } @@ -135,7 +138,7 @@ 10 {ddd abcde dddd dd c} {dddd c c d abcde} } { do_execsql_test 5.$i.1 { INSERT INTO t1 VALUES($x, $y) } - do_execsql_test 5.$i.2 { INSERT INTO t1(t1) VALUES('integrity-check') } + do_execsql_test 5.$i.2 { PRAGMA integrity_check(t1) } ok if {[set_test_counter errors]} break } diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5aux.test sqlite3-3.44.0-0/ext/fts5/test/fts5aux.test --- sqlite3-3.42.0/ext/fts5/test/fts5aux.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5aux.test 2023-11-04 14:23:58.000000000 +0000 @@ -307,5 +307,31 @@ SELECT group_concat(firstcol(t1), '.') FROM t1 GROUP BY rowid } {1 {unable to use function firstcol in the requested context}} -finish_test +#------------------------------------------------------------------------- +# Test that xInstCount() works from within an xPhraseQuery() callback. +# +reset_db + +proc xCallback {cmd} { + incr ::hitcount [$cmd xInstCount] + return SQLITE_OK +} +proc fts5_hitcount {cmd} { + set ::hitcount 0 + $cmd xQueryPhrase 0 xCallback + return $::hitcount +} +sqlite3_fts5_create_function db fts5_hitcount fts5_hitcount + +do_execsql_test 11.1 { + CREATE VIRTUAL TABLE x1 USING fts5(z); + INSERT INTO x1 VALUES('one two three'); + INSERT INTO x1 VALUES('one two one three one'); + INSERT INTO x1 VALUES('one two three'); +} +do_execsql_test 11.2 { + SELECT fts5_hitcount(x1) FROM x1('one') LIMIT 1; +} {5} + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5bigid.test sqlite3-3.44.0-0/ext/fts5/test/fts5bigid.test --- sqlite3-3.42.0/ext/fts5/test/fts5bigid.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5bigid.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,62 @@ +# 2023 May 28 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5bigid + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +set nRow 20000 + +proc do_ascdesc_test {tn query} { + set ::lAsc [db eval { SELECT rowid FROM x1($query) }] + set ::lDesc [db eval { SELECT rowid FROM x1($query) ORDER BY rowid DESC }] + do_test $tn.1 { lsort -integer $::lAsc } $::lAsc + do_test $tn.2 { lsort -integer -decr $::lDesc } $::lDesc + do_test $tn.3 { lsort -integer $::lDesc } $::lAsc +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE x1 USING fts5(a); +} + +do_test 1.1 { + for {set ii 0} {$ii < $nRow} {incr ii} { + db eval { + REPLACE INTO x1(rowid, a) VALUES(random(), 'movement at the station'); + } + } +} {} + +do_ascdesc_test 1.2 "the" + +do_execsql_test 1.3 { + DELETE FROM x1 +} + +do_test 1.4 { + for {set ii 0} {$ii < $nRow} {incr ii} { + db eval { + INSERT INTO x1(rowid, a) VALUES( + $ii + 0x6FFFFFFFFFFFFFFF, 'movement at the station' + ); + } + } +} {} + +do_ascdesc_test 1.5 "movement" + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5conflict.test sqlite3-3.44.0-0/ext/fts5/test/fts5conflict.test --- sqlite3-3.42.0/ext/fts5/test/fts5conflict.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5conflict.test 2023-11-04 14:23:58.000000000 +0000 @@ -65,4 +65,44 @@ INSERT INTO fts_idx(fts_idx) VALUES('integrity-check'); } +#------------------------------------------------------------------------- +# Tests for OR IGNORE conflict handling. +# +reset_db +foreach_detail_mode $::testprefix { + + do_execsql_test 3.0 { + CREATE VIRTUAL TABLE t1 USING fts5(xyz, detail=%DETAIL%); + + BEGIN; + INSERT INTO t1(rowid, xyz) VALUES(13, 'thirteen documents'); + INSERT INTO t1(rowid, xyz) VALUES(14, 'fourteen documents'); + INSERT INTO t1(rowid, xyz) VALUES(15, 'fifteen documents'); + COMMIT; + } + + set db_cksum [cksum] + foreach {tn sql} { + 1 { + INSERT OR IGNORE INTO t1(rowid, xyz) VALUES(14, 'new text'); + } + 2 { + UPDATE OR IGNORE t1 SET rowid=13 WHERE rowid=15; + } + 3 { + INSERT OR IGNORE INTO t1(rowid, xyz) + SELECT 13, 'some text' + UNION ALL + SELECT 14, 'some text' + UNION ALL + SELECT 15, 'some text' + } + } { + do_execsql_test 3.1.$tn.1 $sql + do_test 3.1.$tn.2 { cksum } $db_cksum + } + +} + + finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5contentless2.test sqlite3-3.44.0-0/ext/fts5/test/fts5contentless2.test --- sqlite3-3.42.0/ext/fts5/test/fts5contentless2.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5contentless2.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,207 @@ +# 2023 July 19 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for the content= and content_rowid= options. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5contentless2 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +proc vocab {} { + list aaa bbb ccc ddd eee fff ggg hhh iii jjj kkk lll mmm nnn ooo ppp +} + +proc document {nToken} { + set doc [list] + set vocab [vocab] + for {set ii 0} {$ii < $nToken} {incr ii} { + lappend doc [lindex $vocab [expr int(rand()*[llength $vocab])]] + } + set doc +} +db func document document + +proc contains {doc token} { + expr {[lsearch $doc $token]>=0} +} +db func contains contains + +proc do_compare_tables_test {tn} { + uplevel [list do_test $tn { + foreach v [vocab] { + set l1 [execsql { SELECT rowid FROM t1 WHERE contains(doc, $v) }] + set l2 [execsql { SELECT rowid FROM t2($v) }] + if {$l1!=$l2} { error "1: query mismatch ($l1) ($l2)" } + + set w "[string range $v 0 1]*" + set l1 [execsql { SELECT rowid FROM t1 WHERE contains(doc, $w) }] + set l2 [execsql { SELECT rowid FROM t2($w) }] + if {$l1!=$l2} { error "2: query mismatch ($l1) ($l2)" } + + set w "[string range $v 0 0]*" + set l1 [execsql { SELECT rowid FROM t1 WHERE contains(doc, $w) }] + set l2 [execsql { SELECT rowid FROM t2($w) }] + if {$l1!=$l2} { error "2: query mismatch ($l1) ($l2)" } + + set l1 [execsql { + SELECT rowid FROM t1 WHERE contains(doc, $v) ORDER BY rowid DESC + }] + set l2 [execsql { SELECT rowid FROM t2($v) ORDER BY rowid DESC }] + if {$l1!=$l2} { error "1: query mismatch ($l1) ($l2)" } + } + set {} {} + } {}] +} + +proc lshuffle {in} { + set L [list] + set ret [list] + foreach elem $in { lappend L [list [expr rand()] $elem] } + foreach pair [lsort -index 0 $L] { lappend ret [lindex $pair 1] } + set ret +} + +expr srand(0) + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t2 USING fts5( + doc, prefix=2, content=, contentless_delete=1 + ); + + CREATE TABLE t1(doc); + CREATE TRIGGER tr1 AFTER DELETE ON t1 BEGIN + DELETE FROM t2 WHERE rowid = old.rowid; + END; +} + +set SMALLEST64 -9223372036854775808 +set LARGEST64 9223372036854775807 + +foreach {tn r1 r2} { + 1 0 50 + 2 $SMALLEST64 $SMALLEST64+50 + 3 $LARGEST64-50 $LARGEST64 + 4 -50 -1 +} { + set r1 [expr $r1] + set r2 [expr $r2] + + do_test 1.1.$tn { + execsql BEGIN + for {set ii $r1} {$ii <= $r2} {incr ii} { + execsql { INSERT INTO t1(rowid, doc) VALUES ($ii, document(8)); } + } + execsql COMMIT + } {} +} +do_test 1.2 { + db eval { SELECT rowid, doc FROM t1 } { + execsql { INSERT INTO t2(rowid, doc) VALUES($rowid, $doc) } + } +} {} + +foreach {tn rowid} { + 1 $SMALLEST64 + 2 0 + 3 -5 + 4 -30 + 5 $LARGEST64 + 6 $LARGEST64-1 +} { + set rowid [expr $rowid] + do_execsql_test 1.3.$tn.1 { + DELETE FROM t1 WHERE rowid=$rowid + } + do_compare_tables_test 1.3.$tn.2 +} + +set iTest 1 +foreach r [lshuffle [execsql {SELECT rowid FROM t1}]] { + if {($iTest % 50)==0} { + execsql { INSERT INTO t2(t2) VALUES('optimize') } + } + if {($iTest % 5)==0} { + execsql { INSERT INTO t2(t2, rank) VALUES('merge', 5) } + } + do_execsql_test 1.4.$iTest.1($r) { + DELETE FROM t1 WHERE rowid=$r + } + do_compare_tables_test 1.4.$iTest.2 + incr iTest +} + +do_execsql_test 1.5 { + SELECT * FROM t1 +} {} + +#------------------------------------------------------------------------- +reset_db +db func document document + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t2 USING fts5(doc, content=, contentless_delete=1); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO t2(rowid, doc) SELECT i, i || ' ' || i FROM s; +} + +do_execsql_test 2.1 { + BEGIN; + DELETE FROM t2 WHERE rowid=32; + DELETE FROM t2 WHERE rowid=64; + DELETE FROM t2 WHERE rowid=96; + DELETE FROM t2 WHERE rowid=128; + DELETE FROM t2 WHERE rowid=160; + DELETE FROM t2 WHERE rowid=192; + COMMIT; +} + +do_execsql_test 2.2 { + SELECT * FROM t2('128'); +} {} + +#------------------------------------------------------------------------- + +foreach {tn step} { + 1 3 + 2 7 + 3 15 +} { + set step [expr $step] + + reset_db + db func document document + do_execsql_test 3.$tn.0 { + CREATE VIRTUAL TABLE t2 USING fts5(doc, content=, contentless_delete=1); + INSERT INTO t2(t2, rank) VALUES('pgsz', 100); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO t2(rowid, doc) SELECT i, i || ' ' || i FROM s; + } + do_execsql_test 3.$tn.1 { + DELETE FROM t2 WHERE (rowid % $step)==0 + } + do_execsql_test 3.$tn.2 { + SELECT * FROM t2( $step * 5 ) + } {} +} + + + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5contentless3.test sqlite3-3.44.0-0/ext/fts5/test/fts5contentless3.test --- sqlite3-3.42.0/ext/fts5/test/fts5contentless3.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5contentless3.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,195 @@ +# 2023 July 21 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for the content= and content_rowid= options. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5contentless3 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content=, contentless_delete=1); + BEGIN; + INSERT INTO ft VALUES('one one one'); + INSERT INTO ft VALUES('two two two'); + INSERT INTO ft VALUES('three three three'); + INSERT INTO ft VALUES('four four four'); + INSERT INTO ft VALUES('five five five'); + INSERT INTO ft VALUES('six six six'); + INSERT INTO ft VALUES('seven seven seven'); + INSERT INTO ft VALUES('eight eight eight'); + INSERT INTO ft VALUES('nine nine nine'); + COMMIT; + + DELETE FROM ft WHERE rowid=3; +} + +proc myhex {hex} { binary decode hex $hex } +db func myhex myhex + +do_execsql_test 1.1 { + UPDATE ft_data SET block = + myhex('04000000 00000001' || + '01020304 01020304 01020304 01020304' || + '01020304 01020304 01020304 01020304' + ) + WHERE id = (SELECT max(id) FROM ft_data); +} + +do_execsql_test 1.2 { + DELETE FROM ft WHERE rowid=1 +} + +do_execsql_test 1.3 { + SELECT rowid FROM ft('two'); +} {2} + +do_execsql_test 1.3 { + UPDATE ft_data SET block = + myhex('08000000 00000001' || + '0000000001020304 0000000001020304 0000000001020304 0000000001020304' || + '0000000001020304 0000000001020304 0000000001020304 0000000001020304' + ) + WHERE id = (SELECT max(id) FROM ft_data); +} + +do_execsql_test 1.4 { + SELECT rowid FROM ft('two'); +} {2} + +do_execsql_test 1.5 { + DELETE FROM ft WHERE rowid=4 +} + +do_execsql_test 1.6 { + UPDATE ft_data SET block = myhex('04000000 00000000') + WHERE id = (SELECT max(id) FROM ft_data); +} +do_execsql_test 1.7 { + SELECT rowid FROM ft('two'); +} {2} + +do_execsql_test 1.8 { + UPDATE ft_data SET block = myhex('04000000 00000000') + WHERE id = (SELECT max(id) FROM ft_data); +} +do_execsql_test 1.9 { + DELETE FROM ft WHERE rowid=8 +} {} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content=, contentless_delete=1); + INSERT INTO ft VALUES('one one one'); + INSERT INTO ft VALUES('two two two'); + INSERT INTO ft VALUES('three three three'); + INSERT INTO ft VALUES('four four four'); + INSERT INTO ft VALUES('five five five'); + INSERT INTO ft VALUES('six six six'); + INSERT INTO ft VALUES('seven seven seven'); + INSERT INTO ft VALUES('eight eight eight'); + INSERT INTO ft VALUES('nine nine nine'); +} + +do_execsql_test 2.1 { + INSERT INTO ft(ft) VALUES('optimize'); +} +do_execsql_test 2.2 { + SELECT count(*) FROM ft_data +} {3} +do_execsql_test 2.3 { + DELETE FROM ft WHERE rowid=5 +} +do_execsql_test 2.4 { + SELECT count(*) FROM ft_data +} {4} + +# Check that an 'optimize' works (rewrites the index) if there is a single +# segment with one or more tombstone hash pages. +do_execsql_test 2.5 { + INSERT INTO ft(ft) VALUES('optimize'); +} +do_execsql_test 2.6 { + SELECT count(*) FROM ft_data +} {3} + +# Check that an 'optimize' is a no-op if there is a single segment +# and no tombstone hash pages. +do_execsql_test 2.7 { + INSERT INTO ft(ft) VALUES('optimize'); + SELECT rowid FROM ft_data; +} [db eval {SELECT rowid FROM ft_data}] + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content=, contentless_delete=1); + INSERT INTO ft(ft, rank) VALUES('pgsz', 64); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO ft(rowid, x) SELECT i, i||' '||i||' '||i||' '||i FROM s; + INSERT INTO ft(ft) VALUES('optimize'); +} + +do_execsql_test 3.1 { + SELECT count(*) FROM ft_data +} {200} + +do_execsql_test 3.2 { + DELETE FROM ft WHERE (rowid % 50)==0; + SELECT count(*) FROM ft_data; +} {203} + +do_execsql_test 3.3 { + INSERT INTO ft(ft, rank) VALUES('merge', 500); + SELECT rowid FROM ft_data; +} [db eval {SELECT rowid FROM ft_data}] + +do_execsql_test 3.4 { + INSERT INTO ft(ft, rank) VALUES('merge', -1000); + SELECT count(*) FROM ft_data; +} {197} + +do_execsql_test 3.5 { + DELETE FROM ft WHERE (rowid % 50)==1; + SELECT count(*) FROM ft_data; +} {200} + +do_execsql_test 3.6 { + SELECT level, segment, npgtombstone FROM fts5_structure( + (SELECT block FROM ft_data WHERE id=10) + ) +} {1 0 3} + +do_test 3.6 { + while 1 { + set nChange [db total_changes] + execsql { INSERT INTO ft(ft, rank) VALUES('merge', -5) } + if {([db total_changes] - $nChange)<2} break + } +} {} + +do_execsql_test 3.7 { + SELECT level, segment, npgtombstone FROM fts5_structure( + (SELECT block FROM ft_data WHERE id=10) + ) +} {2 0 0} + + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5contentless4.test sqlite3-3.44.0-0/ext/fts5/test/fts5contentless4.test --- sqlite3-3.42.0/ext/fts5/test/fts5contentless4.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5contentless4.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,247 @@ +# 2023 July 21 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for the content= and content_rowid= options. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5contentless4 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +proc document {n} { + set vocab [list A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + set ret [list] + for {set ii 0} {$ii < $n} {incr ii} { + lappend ret [lindex $vocab [expr int(rand()*[llength $vocab])]] + } + set ret +} +db func document document + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); + INSERT INTO ft(ft, rank) VALUES('pgsz', 240); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO ft SELECT document(12) FROM s; +} + +do_execsql_test 1.1 { + INSERT INTO ft(ft) VALUES('optimize'); +} + +do_execsql_test 1.2 { + SELECT level, segment, nentry, nentrytombstone FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} {0 0 1000 0} + +do_execsql_test 1.3 { + DELETE FROM ft WHERE rowid < 50 +} + +do_execsql_test 1.4 { + SELECT level, segment, nentry, nentrytombstone FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} {0 0 1000 49} + +do_execsql_test 1.5 { + DELETE FROM ft WHERE rowid < 1000 +} + +do_execsql_test 1.6 { + SELECT level, segment, nentry, nentrytombstone FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} {1 0 1 0} + +#-------------------------------------------------------------------------- +reset_db +db func document document + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); +} + +do_test 2.1 { + for {set ii 0} {$ii < 5000} {incr ii} { + execsql { INSERT INTO ft VALUES( document(12) ) } + } +} {} + +do_execsql_test 2.2 { + SELECT sum(nentry) - sum(nentrytombstone) FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} {5000} + +for {set ii 5000} {$ii >= 0} {incr ii -100} { + do_execsql_test 2.3.$ii { + DELETE FROM ft WHERE rowid > $ii + } + do_execsql_test 2.3.$ii.2 { + SELECT + CAST((total(nentry) - total(nentrytombstone)) AS integer) + FROM + fts5_structure( (SELECT block FROM ft_data WHERE id=10) ) + } $ii +} + +execsql_pp { + SELECT * FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} + +do_test 2.4 { + for {set ii 0} {$ii < 5000} {incr ii} { + execsql { INSERT INTO ft VALUES( document(12) ) } + } +} {} + +for {set ii 1} {$ii <= 5000} {incr ii 10} { + do_execsql_test 2.3.$ii { + DELETE FROM ft WHERE rowid = $ii; + INSERT INTO ft VALUES( document(12) ); + INSERT INTO ft(ft, rank) VALUES('merge', -10); + } + + do_execsql_test 2.3.$ii.2 { + SELECT + CAST((total(nentry) - total(nentrytombstone)) AS integer) + FROM + fts5_structure( (SELECT block FROM ft_data WHERE id=10) ) + } 5000 +} + +#------------------------------------------------------------------------- +reset_db +db func document document +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO ft SELECT document(12) FROM s; +} + +do_catchsql_test 3.1 { + INSERT INTO ft(ft, rank) VALUES('deletemerge', 'text'); +} {1 {SQL logic error}} +do_catchsql_test 3.2 { + INSERT INTO ft(ft, rank) VALUES('deletemerge', 50); +} {0 {}} +do_execsql_test 3.3 { + SELECT * FROM ft_config WHERE k='deletemerge' +} {deletemerge 50} +do_catchsql_test 3.4 { + INSERT INTO ft(ft, rank) VALUES('deletemerge', 101); +} {0 {}} +do_execsql_test 3.5 { + SELECT * FROM ft_config WHERE k='deletemerge' +} {deletemerge 101} + +do_execsql_test 3.6 { + DELETE FROM ft WHERE rowid<95 +} + +do_execsql_test 3.7 { + SELECT nentrytombstone, nentry FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} {94 100} + +do_execsql_test 3.8 { + DELETE FROM ft WHERE rowid=95 +} + +do_execsql_test 3.9 { + SELECT nentrytombstone, nentry FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} {95 100} + +do_execsql_test 3.10 { + DELETE FROM ft; + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<100 + ) + INSERT INTO ft SELECT document(12) FROM s; + INSERT INTO ft(ft, rank) VALUES('deletemerge', 50); +} + +do_execsql_test 3.11 { + DELETE FROM ft WHERE rowid<95 +} + +do_execsql_test 3.12 { + SELECT nentrytombstone, nentry FROM fts5_structure(( + SELECT block FROM ft_data WHERE id=10 + )) +} {0 6} + +#------------------------------------------------------------------------- +reset_db +db func document document +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE x1 USING fts5(x, content='', contentless_delete=1); + INSERT INTO x1(x1, rank) VALUES('usermerge', 16); + INSERT INTO x1(x1, rank) VALUES('deletemerge', 40); + INSERT INTO x1 VALUES('one'); + INSERT INTO x1 VALUES('two'); + INSERT INTO x1 VALUES('three'); + INSERT INTO x1 VALUES('four'); + INSERT INTO x1 VALUES('five'); + INSERT INTO x1 VALUES('six'); + INSERT INTO x1 VALUES('seven'); + INSERT INTO x1 VALUES('eight'); + INSERT INTO x1 VALUES('nine'); + INSERT INTO x1 VALUES('ten'); +} + +do_execsql_test 4.1 { + SELECT level, segment FROM fts5_structure(( + SELECT block FROM x1_data WHERE id=10 + )) +} { + 0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 +} + +for {set ii 1} {$ii < 4} {incr ii} { + do_execsql_test 4.2.$ii { + DELETE FROM x1 WHERE rowid = $ii; + INSERT INTO x1(x1, rank) VALUES('merge', 5); + SELECT level, segment FROM fts5_structure(( + SELECT block FROM x1_data WHERE id=10 + )) + } { + 0 0 0 1 0 2 0 3 0 4 0 5 0 6 0 7 0 8 0 9 + } +} + +do_execsql_test 4.3 { + DELETE FROM x1 WHERE rowid = $ii; + INSERT INTO x1(x1, rank) VALUES('merge', 5); + SELECT level, segment, nentry FROM fts5_structure(( + SELECT block FROM x1_data WHERE id=10 + )) +} { + 1 0 6 +} + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5contentless5.test sqlite3-3.44.0-0/ext/fts5/test/fts5contentless5.test --- sqlite3-3.42.0/ext/fts5/test/fts5contentless5.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5contentless5.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,58 @@ +# 2023 August 7 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for the content= and content_rowid= options. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5contentless5 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a, b, c, content='', contentless_delete=1); + INSERT INTO t1 VALUES('A', 'B', 'C'); + INSERT INTO t1 VALUES('D', 'E', 'F'); + INSERT INTO t1 VALUES('G', 'H', 'I'); +} + +do_execsql_test 1.01 { + CREATE TABLE t2(x, y); + INSERT INTO t2 VALUES('x', 'y'); +} + +# explain_i "UPDATE t1 SET a='a' WHERE t1.rowid=1" +breakpoint +explain_i "UPDATE t1 SET a='a' FROM t2 WHERE t1.rowid=1 AND b IS NULL" + +#breakpoint +#explain_i "UPDATE t1 SET a='a' WHERE b IS NULL AND rowid=?" + +foreach {tn up err} { + 1 "UPDATE t1 SET a='a', b='b', c='c' WHERE rowid=1" 0 + 2 "UPDATE t1 SET a='a', b='b' WHERE rowid=1" 1 + 3 "UPDATE t1 SET b='b', c='c' WHERE rowid=1" 1 + 4 "UPDATE t1 SET a='a', c='c' WHERE rowid=1" 1 + 5 "UPDATE t1 SET a='a', c='c' WHERE t1.rowid=1 AND b IS NULL" 1 + 6 "UPDATE t1 SET a='a' FROM t2 WHERE t1.rowid=1" 1 + 7 "UPDATE t1 SET a='a', b='b', c='c' FROM t2 WHERE t1.rowid=1" 0 +} { + + set res(0) {0 {}} + set res(1) {1 {cannot UPDATE a subset of columns on fts5 contentless-delete table: t1}} + do_catchsql_test 1.$tn $up $res($err) +} + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5contentless.test sqlite3-3.44.0-0/ext/fts5/test/fts5contentless.test --- sqlite3-3.42.0/ext/fts5/test/fts5contentless.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5contentless.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,270 @@ +# 2014 Dec 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains tests for the content= and content_rowid= options. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5contentless + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +# Check that it is not possible to specify "contentless_delete=1" for +# anything other than a contentless table. +# +set res(0) {0 {}} +set res(1) {1 {contentless_delete=1 requires a contentless table}} +foreach {tn sql bError} { + 1 "(a, b, contentless_delete=1)" 1 + 2 "(a, b, contentless_delete=1, content=abc)" 1 + 3 "(a, b, contentless_delete=1, content=)" 0 + 4 "(content=, contentless_delete=1, a)" 0 + 5 "(content='', contentless_delete=1, hello)" 0 +} { + execsql { BEGIN } + do_catchsql_test 1.$tn "CREATE VIRTUAL TABLE t1 USING fts5 $sql" $res($bError) + execsql { ROLLBACK } +} + +# Check that it is not possible to specify "contentless_delete=1" +# along with columnsize=1. +# +set res(0) {0 {}} +set res(1) {1 {contentless_delete=1 is incompatible with columnsize=0}} +foreach {tn sql bError} { + 2 "(a, b, content='', contentless_delete=1, columnsize=0)" 1 +} { + execsql { BEGIN } + do_catchsql_test 1.$tn "CREATE VIRTUAL TABLE t1 USING fts5 $sql" $res($bError) + execsql { ROLLBACK } +} + +# Check that if contentless_delete=1 is specified, then the "origin" +# column is added to the %_docsize table. +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE x1 USING fts5(c, content=''); + CREATE VIRTUAL TABLE x2 USING fts5(c, content='', contentless_delete=1); +} +do_execsql_test 3.1 { + SELECT sql FROM sqlite_schema WHERE name IN ('x1_docsize', 'x2_docsize'); +} { + {CREATE TABLE 'x1_docsize'(id INTEGER PRIMARY KEY, sz BLOB)} + {CREATE TABLE 'x2_docsize'(id INTEGER PRIMARY KEY, sz BLOB, origin INTEGER)} +} + +do_execsql_test 3.2.1 { + SELECT hex(block) FROM x1_data WHERE id=10 +} {00000000000000} +do_execsql_test 3.2.2 { + SELECT hex(block) FROM x2_data WHERE id=10 +} {00000000FF000001000000} + +do_execsql_test 3.3 { + INSERT INTO x2 VALUES('first text'); + INSERT INTO x2 VALUES('second text'); +} +do_execsql_test 3.4 { + SELECT id, origin FROM x2_docsize +} {1 1 2 2} +do_execsql_test 3.5 { + SELECT level, segment, loc1, loc2 FROM fts5_structure( + (SELECT block FROM x2_data WHERE id=10) + ) +} { + 0 0 1 1 + 0 1 2 2 +} +do_execsql_test 3.6 { + INSERT INTO x2(x2) VALUES('optimize'); +} +do_execsql_test 3.7 { + SELECT level, segment, loc1, loc2 FROM fts5_structure( + (SELECT block FROM x2_data WHERE id=10) + ) +} { + 1 0 1 2 +} + +do_execsql_test 3.8 { + DELETE FROM x2 WHERE rowid=2; +} + +do_execsql_test 3.9 { + SELECT rowid FROM x2('text') +} {1} + +#-------------------------------------------------------------------------- +reset_db +proc document {n} { + set vocab [list A B C D E F G H I J K L M N O P Q R S T U V W X Y Z] + set ret [list] + for {set ii 0} {$ii < $n} {incr ii} { + lappend ret [lindex $vocab [expr int(rand()*[llength $vocab])]] + } + set ret +} + +set nRow 1000 + +do_execsql_test 4.0 { + CREATE TABLE t1(x); + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); + INSERT INTO ft(ft, rank) VALUES('pgsz', 100); +} +do_test 4.1 { + for {set ii 0} {$ii < $nRow} {incr ii} { + set doc [document 6] + execsql { + INSERT INTO t1 VALUES($doc); + INSERT INTO ft VALUES($doc); + } + } +} {} + +foreach v {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} { + set L1 [execsql {SELECT rowid FROM t1 WHERE x LIKE '%'||$v||'%'}] + set L2 [execsql {SELECT rowid FROM ft($v)}] + do_test 4.2.$v { set L1 } $L2 +} + +do_test 4.3 { + for {set ii 1} {$ii < $nRow} {incr ii 2} { + execsql { + DELETE FROM ft WHERE rowid=$ii; + DELETE FROM t1 WHERE rowid=$ii; + } + } +} {} + +foreach v {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} { + set L1 [execsql {SELECT rowid FROM t1 WHERE x LIKE '%'||$v||'%'}] + set L2 [execsql {SELECT rowid FROM ft($v)}] + do_test 4.4.$v { set L1 } $L2 +} + +do_execsql_test 4.5 { + INSERT INTO ft(ft) VALUES('optimize'); +} {} + +foreach v {A B C D E F G H I J K L M N O P Q R S T U V W X Y Z} { + set L1 [execsql {SELECT rowid FROM t1 WHERE x LIKE '%'||$v||'%'}] + set L2 [execsql {SELECT rowid FROM ft($v)}] + do_test 4.6.$v { set L1 } $L2 +} + +#execsql_pp { SELECT fts5_decode(id, block) FROM ft_data } + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); + INSERT INTO ft(rowid, x) VALUES(1, 'one two three'); + INSERT INTO ft(rowid, x) VALUES(2, 'one two four'); + INSERT INTO ft(rowid, x) VALUES(3, 'one two five'); + INSERT INTO ft(rowid, x) VALUES(4, 'one two seven'); + INSERT INTO ft(rowid, x) VALUES(5, 'one two eight'); +} + +do_execsql_test 5.1 { + DELETE FROM ft WHERE rowid=2 +} + +do_execsql_test 5.2 { + SELECT rowid FROM ft +} {1 3 4 5} + +do_catchsql_test 5.3 { + UPDATE ft SET x='four six' WHERE rowid=3 +} {0 {}} + +do_execsql_test 5.4 { + SELECT rowid FROM ft('one'); +} {1 4 5} + +do_execsql_test 5.5 { + REPLACE INTO ft(rowid, x) VALUES(3, 'four six'); + SELECT rowid FROM ft('one'); +} {1 4 5} + +do_execsql_test 5.6 { + REPLACE INTO ft(rowid, x) VALUES(6, 'one two eleven'); + SELECT rowid FROM ft('one'); +} {1 4 5 6} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); + INSERT INTO ft(rowid, x) VALUES(1, 'one two three'); + INSERT INTO ft(rowid, x) VALUES(2, 'one two four'); +} + +do_test 6.1 { + db eval { SELECT rowid FROM ft('one two') } { + if {$rowid==1} { + db eval { INSERT INTO ft(rowid, x) VALUES(3, 'one two four') } + } + } +} {} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 7.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); +} + +set lRowid [list -450 0 1 2 42] + +do_test 7.1 { + execsql BEGIN + foreach r $lRowid { + execsql { INSERT INTO ft(rowid, x) VALUES($r, 'one one one'); } + } + execsql COMMIT +} {} + +do_test 7.2 { + execsql BEGIN + foreach r $lRowid { + execsql { REPLACE INTO ft(rowid, x) VALUES($r, 'two two two'); } + } + execsql COMMIT +} {} + +do_execsql_test 7.3 { SELECT rowid FROM ft('one'); } {} +do_execsql_test 7.4 { SELECT rowid FROM ft('two'); } $lRowid + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 8.0 { + CREATE VIRTUAL TABLE ft USING fts5(x, content='', contentless_delete=1); + INSERT INTO ft VALUES('hello world'); + INSERT INTO ft VALUES('one two three'); +} + +do_catchsql_test 8.1 { + INSERT INTO ft(ft, rowid, x) VALUES('delete', 1, 'hello world'); +} {1 {'delete' may not be used with a contentless_delete=1 table}} + +do_execsql_test 8.2 { + BEGIN; + INSERT INTO ft(rowid, x) VALUES(3, 'four four four'); + DELETE FROM ft WHERE rowid=3; + COMMIT; + SELECT rowid FROM ft('four'); +} {} + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5content.test sqlite3-3.44.0-0/ext/fts5/test/fts5content.test --- sqlite3-3.42.0/ext/fts5/test/fts5content.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5content.test 2023-11-04 14:23:58.000000000 +0000 @@ -294,4 +294,3 @@ } {1 {recursively defined fts5 content table}} finish_test - diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5corrupt2.test sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt2.test --- sqlite3-3.42.0/ext/fts5/test/fts5corrupt2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt2.test 2023-11-04 14:23:58.000000000 +0000 @@ -167,6 +167,9 @@ do_test 3.$tn.$tn2.2 { catchsql { INSERT INTO x3(x3) VALUES('integrity-check') } } {1 {database disk image is malformed}} + do_execsql_test 3.$tn.$tn2.3 { + PRAGMA integrity_check(x3); + } {{malformed inverted index for FTS5 table main.x3}} } execsql ROLLBACK diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5corrupt5.test sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt5.test --- sqlite3-3.42.0/ext/fts5/test/fts5corrupt5.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt5.test 2023-11-04 14:23:58.000000000 +0000 @@ -15,7 +15,7 @@ # source [file join [file dirname [info script]] fts5_common.tcl] -set testprefix fts5corrupt3 +set testprefix fts5corrupt5 # If SQLITE_ENABLE_FTS5 is defined, omit this file. ifcapable !fts5 { @@ -793,6 +793,94 @@ REPLACE INTO t1(rowid,a,b,rowid) VALUES(200,1,2,3); } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_test 5.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +.open --hexdb +| size 28672 pagesize 4096 filename crash-0c6d3451d11597.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 00 00 00 00 07 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 07 00 00 00 04 ................ +| 96: 00 00 00 00 0d 00 00 00 07 0d d2 00 0f c4 0f 6d ...............m +| 112: 0f 02 0e ab 0e 4e 0d f6 0d d2 00 00 00 00 00 00 .....N.......... +| 3536: 00 00 22 07 06 17 11 11 01 31 74 61 62 6c 65 74 .........1tablet +| 3552: 32 74 32 07 43 52 45 41 54 45 20 54 41 42 4c 45 2t2.CREATE TABLE +| 3568: 20 74 32 28 78 29 56 06 06 17 1f 1f 01 7d 74 61 t2(x)V.......ta +| 3584: 62 6c 65 74 31 5f 63 6f 6e 66 69 67 74 31 5f 63 blet1_configt1_c +| 3600: 6f 6e 66 69 67 06 43 52 45 41 54 45 20 54 41 42 onfig.CREATE TAB +| 3616: 4c 45 20 27 74 31 5f 63 6f 6e 66 69 67 27 28 6b LE 't1_config'(k +| 3632: 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 76 29 PRIMARY KEY, v) +| 3648: 20 57 49 54 48 4f 55 54 20 52 4f 57 49 44 5b 05 WITHOUT ROWID[. +| 3664: 07 17 21 21 01 81 01 74 61 62 6c 65 74 31 5f 64 ..!!...tablet1_d +| 3680: 6f 63 73 69 7a 65 74 31 5f 64 6f 63 73 69 7a 65 ocsizet1_docsize +| 3696: 05 43 52 45 41 54 45 20 54 41 42 4c 45 20 27 74 .CREATE TABLE 't +| 3712: 31 5f 64 6f 63 73 69 7a 65 27 28 69 64 20 49 4e 1_docsize'(id IN +| 3728: 54 45 47 45 52 20 50 52 49 4d 41 52 59 20 4b 45 TEGER PRIMARY KE +| 3744: 59 2c 20 73 7a 20 42 4c 4f 42 29 55 04 06 17 21 Y, sz BLOB)U...! +| 3760: 21 01 77 74 61 62 6c 65 74 31 5f 63 6f 6e 74 65 !.wtablet1_conte +| 3776: 6e 74 74 31 5f 63 6f 6e 74 65 6e 74 04 43 52 45 ntt1_content.CRE +| 3792: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 63 6f ATE TABLE 't1_co +| 3808: 6e 74 65 6e 74 27 28 69 64 20 49 4e 54 45 47 45 ntent'(id INTEGE +| 3824: 52 20 50 52 49 4d 41 52 59 20 4b 45 59 2c 20 63 R PRIMARY KEY, c +| 3840: 30 29 69 03 07 17 19 19 01 81 2d 74 61 62 6c 65 0)i.......-table +| 3856: 74 31 5f 69 64 78 74 31 5f 69 64 78 03 43 52 45 t1_idxt1_idx.CRE +| 3872: 41 54 45 20 54 41 42 4c 45 20 27 74 31 5f 69 64 ATE TABLE 't1_id +| 3888: 78 27 28 73 65 67 69 64 2c 20 74 65 72 6d 2c 20 x'(segid, term, +| 3904: 70 67 6e 6f 2c 20 50 52 49 4d 41 52 59 20 4b 45 pgno, PRIMARY KE +| 3920: 59 28 73 65 67 69 64 2c 20 74 65 72 6d 29 29 20 Y(segid, term)) +| 3936: 57 49 54 48 4f 55 54 20 52 4f 57 49 44 55 02 07 WITHOUT ROWIDU.. +| 3952: 17 1b 1b 01 81 01 74 61 62 6c 65 74 31 5f 64 61 ......tablet1_da +| 3968: 74 61 74 31 5f 64 61 74 61 02 43 52 45 41 54 45 tat1_data.CREATE +| 3984: 20 54 41 42 4c 45 20 27 74 31 5f 64 61 74 61 27 TABLE 't1_data' +| 4000: 28 69 64 20 49 4e 54 45 47 45 52 20 50 52 49 4d (id INTEGER PRIM +| 4016: 41 52 b9 20 4b 45 59 2c 20 62 6c 6f 63 6b 20 42 AR. KEY, block B +| 4032: 4c 4f 42 29 3a 01 06 17 11 11 08 63 74 61 62 6c LOB):......ctabl +| 4048: 65 74 31 74 31 43 52 45 41 54 45 20 56 49 52 54 et1t1CREATE VIRT +| 4064: 55 41 4c 20 54 41 42 4c 45 20 74 31 20 55 53 49 UAL TABLE t1 USI +| 4080: 4e 47 20 66 74 73 35 28 63 6f 6e 74 65 6e 74 29 NG fts5(content) +| page 2 offset 4096 +| 0: 0d 00 00 00 03 0f bd 00 0f e8 0f ef 0f bd 00 00 ................ +| 16: 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4016: 00 00 00 00 00 00 00 00 00 00 00 00 00 24 84 80 .............$.. +| 4032: 80 80 80 01 03 00 4e 00 00 00 1e 06 30 61 62 61 ......N.....0aba +| 4048: 63 6b 01 02 02 04 02 66 74 02 02 02 04 04 6e 64 ck.....ft.....nd +| 4064: 6f 6e 03 02 02 04 0a 07 05 01 03 00 10 03 03 0f on.............. +| 4080: 0a 03 00 24 00 00 00 00 01 01 01 00 01 01 01 11 ...$............ +| page 3 offset 8192 +| 0: 0a 00 00 00 01 0f 00 00 00 00 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 00 00 00 00 00 00 05 04 09 0c 01 02 ................ +| page 4 offset 12288 +| 0: 0d 00 00 00 03 0f e0 00 0f f6 0f ec 0f e0 00 00 ................ +| 4064: 0a 03 03 00 1b 61 62 61 6e 64 6f 6e 08 02 03 00 .....abandon.... +| 4080: 17 61 62 61 66 74 08 01 03 00 17 61 62 61 63 6b .abaft.....aback +| page 5 offset 16384 +| 0: 0d 00 00 00 03 0f ee 00 0f fa 0f f4 0f ee 00 00 ................ +| 16: 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4064: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 04 03 ................ +| 4080: 03 00 0e 01 04 02 03 00 0e 01 04 01 03 00 0e 01 ................ +| page 6 offset 20480 +| 0: 0a 00 00 00 01 0f f4 00 0f f4 00 00 00 00 00 00 ................ +| 4080: 00 00 00 00 0b 03 1b 01 76 65 72 73 69 6f 6e 04 ........version. +| page 7 offset 24576 +| 0: 0d 00 00 10 03 0f d6 00 0f f4 10 e1 0f d6 00 00 ................ +| 16: 00 00 00 01 00 00 00 00 00 00 00 00 00 00 00 00 ................ +| 4048: 00 00 00 00 00 00 09 03 02 1b 72 65 62 75 69 6c ..........rebuil +| 4064: 64 11 02 02 2b 69 6e 74 65 67 72 69 74 79 2d 63 d...+integrity-c +| 4080: 68 65 63 6b 0a 01 02 1d 6f 70 74 69 6d 00 00 00 heck....optim... +| end crash-0c6d3451d11597.db +}]} {} + +do_execsql_test 5.1 { + INSERT INTO t1(t1,rank) VALUES('secure-delete',1); +} +do_catchsql_test 5.4 { + UPDATE t1 SET content=randomblob(500); +} {1 {database disk image is malformed}} + + sqlite3_fts5_may_be_corrupt 0 finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5corrupt7.test sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt7.test --- sqlite3-3.42.0/ext/fts5/test/fts5corrupt7.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt7.test 2023-11-04 14:23:58.000000000 +0000 @@ -96,4 +96,33 @@ db close } +#------------------------------------------------------------------------- +reset_db +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x); + BEGIN; + INSERT INTO t1 VALUES('abc'); + INSERT INTO t1 VALUES('b d d d'); + COMMIT; + INSERT INTO t1(t1, rank) VALUES('secure-delete', 1); +} + +execsql_pp { + SELECT id, quote(block) FROM t1_data +} + +do_execsql_test 2.1 { + SELECT quote(block) FROM t1_data WHERE id > 10; +} {X'0000001A04306162630102020101620202020101640206030303040806'} + +do_execsql_test 2.2 { + UPDATE t1_data SET + block=X'0000001A04306162630102025501620202020101640206030303040806' + WHERE id>10 +} + +do_catchsql_test 2.3 { + DELETE FROM t1 WHERE rowid = 1 +} {1 {database disk image is malformed}} + finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5corrupt.test sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt.test --- sqlite3-3.42.0/ext/fts5/test/fts5corrupt.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5corrupt.test 2023-11-04 14:23:58.000000000 +0000 @@ -48,6 +48,10 @@ } catchsql { INSERT INTO t1(t1) VALUES('integrity-check') } } {1 {database disk image is malformed}} +do_execsql_test 1.3b { + PRAGMA integrity_check(t1); +} {{malformed inverted index for FTS5 table main.t1}} + do_test 1.4 { db_restore_and_reopen diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5eb.test sqlite3-3.44.0-0/ext/fts5/test/fts5eb.test --- sqlite3-3.42.0/ext/fts5/test/fts5eb.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5eb.test 2023-11-04 14:23:58.000000000 +0000 @@ -95,6 +95,9 @@ SELECT rowid, bm25(e1) FROM e1 WHERE e1 MATCH '"/" OR "just"' ORDER BY rank; } {1 -1e-06} +do_execsql_test 3.4 " + SELECT fts5_expr_tcl('e AND \" \"'); +" {{AND [nearset -- {e}] [{}]}} finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5faultF.test sqlite3-3.44.0-0/ext/fts5/test/fts5faultF.test --- sqlite3-3.42.0/ext/fts5/test/fts5faultF.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5faultF.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,111 @@ +# 2023 July 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# +# This file is focused on OOM errors. Particularly those that may occur +# when using contentless_delete=1 databases. +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/malloc_common.tcl +set testprefix fts5faultF + +# If SQLITE_ENABLE_FTS5 is not defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +faultsim_save_and_close +do_faultsim_test 1 -prep { + faultsim_restore_and_reopen +} -body { + execsql { + CREATE VIRTUAL TABLE t1 USING fts5(x, y, content=, contentless_delete=1) + } +} -test { + faultsim_test_result {0 {}} {1 {vtable constructor failed: t1}} +} + +reset_db +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t1 USING fts5(doc, content=, contentless_delete=1); + BEGIN; + INSERT INTO t1(rowid, doc) VALUES(1, 'a b c d'); + INSERT INTO t1(rowid, doc) VALUES(2, 'a b c d'); + INSERT INTO t1(rowid, doc) VALUES(3, 'a b c d'); + INSERT INTO t1(rowid, doc) VALUES(4, 'a b c d'); + COMMIT; + DELETE FROM t1 WHERE rowid IN (2, 4); +} + +do_faultsim_test 2 -prep { + sqlite3 db test.db + execsql { SELECT rowid FROM t1 } +} -body { + execsql { + SELECT rowid FROM t1('b c'); + } +} -test { + faultsim_test_result {0 {1 3}} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE t1 USING fts5(doc, content=, contentless_delete=1); + BEGIN; + INSERT INTO t1(rowid, doc) VALUES(1, 'a b c d'); + INSERT INTO t1(rowid, doc) VALUES(2, 'a b c d'); + INSERT INTO t1(rowid, doc) VALUES(3, 'a b c d'); + INSERT INTO t1(rowid, doc) VALUES(4, 'a b c d'); + COMMIT; +} + +faultsim_save_and_close +do_faultsim_test 3 -prep { + faultsim_restore_and_reopen + execsql { SELECT rowid FROM t1 } +} -body { + execsql { + INSERT INTO t1(rowid, doc) VALUES(5, 'a b c d'); + } +} -test { + faultsim_test_result {0 {}} +} + +#------------------------------------------------------------------------- +reset_db +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE t1 USING fts5(doc, content=, contentless_delete=1); + INSERT INTO t1(t1, rank) VALUES('pgsz', 64); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<1000 + ) + INSERT INTO t1(rowid, doc) SELECT i, 'a b c d' FROM s; +} + +do_execsql_test 4.1 { DELETE FROM t1 WHERE rowid <= 25 } + +faultsim_save_and_close +do_faultsim_test 4 -faults oom-t* -prep { + faultsim_restore_and_reopen + execsql { SELECT rowid FROM t1 } +} -body { + execsql { + DELETE FROM t1 WHERE rowid < 100 + } +} -test { + faultsim_test_result {0 {}} +} + + +finish_test + diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5faultG.test sqlite3-3.44.0-0/ext/fts5/test/fts5faultG.test --- sqlite3-3.42.0/ext/fts5/test/fts5faultG.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5faultG.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,50 @@ +# 2010 June 15 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +source [file join [file dirname [info script]] fts5_common.tcl] +source $testdir/malloc_common.tcl +set testprefix fts5faultG + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +set ::testprefix fts5faultG + + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(a); + INSERT INTO t1 VALUES('test renaming the table'); + INSERT INTO t1 VALUES(' after it has been written'); + INSERT INTO t1 VALUES(' actually other stuff instead'); +} +faultsim_save_and_close +do_faultsim_test 1 -faults oom* -prep { + faultsim_restore_and_reopen + execsql { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + } +} -body { + execsql { + DELETE FROM t1; + } +} -test { + catchsql { COMMIT } + faultsim_integrity_check + faultsim_test_result {0 {}} +} + + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5integrity.test sqlite3-3.44.0-0/ext/fts5/test/fts5integrity.test --- sqlite3-3.42.0/ext/fts5/test/fts5integrity.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5integrity.test 2023-11-04 14:23:58.000000000 +0000 @@ -77,6 +77,9 @@ UPDATE aa_docsize SET sz = X'44' WHERE rowid = 3; INSERT INTO aa(aa) VALUES('integrity-check'); } {1 {database disk image is malformed}} +do_execsql_test 4.2.1 { + PRAGMA integrity_check(aa); +} {{malformed inverted index for FTS5 table main.aa}} do_catchsql_test 4.3 { ROLLBACK; @@ -317,4 +320,39 @@ INSERT INTO vt0(vt0) VALUES('integrity-check'); } {0 {}} +reset_db +proc slang {in} {return [string map {th d e eh} $in]} +db function slang -deterministic -innocuous slang +do_execsql_test 11.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT AS (slang(b))); + INSERT INTO t1(b) VALUES('the quick fox jumps over the lazy brown dog'); + SELECT c FROM t1; +} {{deh quick fox jumps ovehr deh lazy brown dog}} + +do_execsql_test 11.1 { + CREATE VIRTUAL TABLE t2 USING fts5(content="t1", c); + INSERT INTO t2(t2) VALUES('rebuild'); + SELECT rowid FROM t2 WHERE t2 MATCH 'deh'; +} {1} + +do_execsql_test 11.2 { + PRAGMA integrity_check(t2); +} {ok} +db close +sqlite3 db test.db + +# FIX ME? +# +# FTS5 integrity-check does not care if the content table is unreadable or +# does not exist. It only looks for internal inconsistencies in the +# inverted index. +# +do_execsql_test 11.3 { + PRAGMA integrity_check(t2); +} {ok} +do_execsql_test 11.4 { + DROP TABLE t1; + PRAGMA integrity_check(t2); +} {ok} + finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5misc.test sqlite3-3.44.0-0/ext/fts5/test/fts5misc.test --- sqlite3-3.42.0/ext/fts5/test/fts5misc.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5misc.test 2023-11-04 14:23:58.000000000 +0000 @@ -44,12 +44,12 @@ do_catchsql_test 1.3.1 { SELECT highlight(t1, 4, '', '') FROM t1('*reads'); -} {1 {no such cursor: 1}} +} {1 {no such cursor: 2}} do_catchsql_test 1.3.2 { SELECT a FROM t1 WHERE rank = (SELECT highlight(t1, 4, '', '') FROM t1('*reads')); -} {1 {no such cursor: 1}} +} {1 {no such cursor: 2}} db close sqlite3 db test.db @@ -424,10 +424,12 @@ SAVEPOINT one; } {} do_execsql_test 15.4 END -do_test 15.4 { +do_test 15.5 { list [catch { db2 eval COMMIT } msg] $msg } {0 {}} +db2 close + #------------------------------------------------------------------------- reset_db forcedelete test.db2 @@ -469,6 +471,8 @@ SELECT * FROM x1 } {abc def} +db2 close + #------------------------------------------------------------------------- reset_db do_execsql_test 17.1 { diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5optimize2.test sqlite3-3.44.0-0/ext/fts5/test/fts5optimize2.test --- sqlite3-3.42.0/ext/fts5/test/fts5optimize2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5optimize2.test 2023-11-04 14:23:58.000000000 +0000 @@ -9,7 +9,7 @@ # #*********************************************************************** # -# TESTRUNNER: slow +# TESTRUNNER: superslow # source [file join [file dirname [info script]] fts5_common.tcl] @@ -42,23 +42,4 @@ SELECT count(*) FROM t1('mno') } $nLoop -do_execsql_test 2.0 { - CREATE VIRTUAL TABLE t2 USING fts5(x); - INSERT INTO t2(t2, rank) VALUES('pgsz', 32); -} - -do_test 2.1 { - for {set ii 0} {$ii < $nLoop} {incr ii} { - execsql { - INSERT INTO t2 VALUES('abc def ghi'); - INSERT INTO t2 VALUES('jkl mno pqr'); - INSERT INTO t2(t2, rank) VALUES('merge', -1); - } - } -} {} - -do_execsql_test 2.2 { - SELECT count(*) FROM t2('mno') -} $nLoop - finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5optimize3.test sqlite3-3.44.0-0/ext/fts5/test/fts5optimize3.test --- sqlite3-3.42.0/ext/fts5/test/fts5optimize3.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5optimize3.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,45 @@ +# 2023 Aug 27 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# TESTRUNNER: superslow +# + +source [file join [file dirname [info script]] fts5_common.tcl] +set testprefix fts5optimize2 + +# If SQLITE_ENABLE_FTS5 is defined, omit this file. +ifcapable !fts5 { + finish_test + return +} + +set nLoop 2500 + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t2 USING fts5(x); + INSERT INTO t2(t2, rank) VALUES('pgsz', 32); +} + +do_test 1.1 { + for {set ii 0} {$ii < $nLoop} {incr ii} { + execsql { + INSERT INTO t2 VALUES('abc def ghi'); + INSERT INTO t2 VALUES('jkl mno pqr'); + INSERT INTO t2(t2, rank) VALUES('merge', -1); + } + } +} {} + +do_execsql_test 1.2 { + SELECT count(*) FROM t2('mno') +} $nLoop + +finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5rank.test sqlite3-3.44.0-0/ext/fts5/test/fts5rank.test --- sqlite3-3.42.0/ext/fts5/test/fts5rank.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5rank.test 2023-11-04 14:23:58.000000000 +0000 @@ -180,4 +180,28 @@ {table table table} {the table names.} {rank on an fts5 table} } + +#------------------------------------------------------------------------- +# forum post: https://sqlite.org/forum/forumpost/a2dd636330 +# +reset_db +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t USING fts5 (a, b); + INSERT INTO t (a, b) VALUES ('data1', 'sentence1'), ('data2', 'sentence2'); + INSERT INTO t(t, rank) VALUES ('rank', 'bm25(10.0,1.0)'); +} + +sqlite3 db2 test.db +do_execsql_test -db db2 1.1 { + SELECT *, rank<0.0 FROM t('data*') ORDER BY RANK; +} {data1 sentence1 1 data2 sentence2 1} + +do_execsql_test 1.2 { + INSERT INTO t(t, rank) VALUES ('rank', 'bm25(10.0,1.0)'); +} +do_execsql_test -db db2 1.3 { + SELECT *, rank<0.0 FROM t('data*') ORDER BY RANK; +} {data1 sentence1 1 data2 sentence2 1} +db2 close + finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5savepoint.test sqlite3-3.44.0-0/ext/fts5/test/fts5savepoint.test --- sqlite3-3.42.0/ext/fts5/test/fts5savepoint.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5savepoint.test 2023-11-04 14:23:58.000000000 +0000 @@ -71,7 +71,7 @@ do_catchsql_test 3.2 { DROP TABLE vt1; - } {1 {SQL logic error}} + } {0 {}} do_execsql_test 3.3 { SAVEPOINT x; diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5secure6.test sqlite3-3.44.0-0/ext/fts5/test/fts5secure6.test --- sqlite3-3.42.0/ext/fts5/test/fts5secure6.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5secure6.test 2023-11-04 14:23:58.000000000 +0000 @@ -18,7 +18,7 @@ set ::PHC 0 proc progress_handler {args} { incr ::PHC - if {($::PHC % 100000)==0} breakpoint + # if {($::PHC % 100000)==0} breakpoint return 0 } @@ -50,6 +50,92 @@ expr $phc(1)*5 < $phc(2) } {1} +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x); + INSERT INTO t1(t1, rank) VALUES('secure-delete', $sd) +} + +do_execsql_test 2.1 { + BEGIN; + INSERT INTO t1(rowid, x) VALUES(-100000, 'abc def ghi'); + INSERT INTO t1(rowid, x) VALUES(-99999, 'abc def ghi'); + INSERT INTO t1(rowid, x) VALUES(9223372036854775800, 'abc def ghi'); + COMMIT; +} + +do_execsql_test 2.2 { + SELECT rowid FROM t1('def') +} {-100000 -99999 9223372036854775800} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 3.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x); + INSERT INTO t1(t1, rank) VALUES('secure-delete', $sd) +} + +do_execsql_test 3.1 { + BEGIN; + INSERT INTO t1(rowid, x) + VALUES(51869, 'when whenever where weress what turn'), + (51871, 'to were'); + COMMIT; +} + +do_execsql_test 3.2 { + DELETE FROM t1 WHERE rowid=51871; + INSERT INTO t1(t1) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 4.0 { + CREATE VIRTUAL TABLE t1 USING fts5(x); + INSERT INTO t1(rowid, x) VALUES(10, 'one two'); +} +do_execsql_test 4.1 { + UPDATE t1 SET x = 'one three' WHERE rowid=10; + INSERT INTO t1(t1, rank) VALUES('secure-delete', 1); +} +do_execsql_test 4.2 { + DELETE FROM t1 WHERE rowid=10; +} +do_execsql_test 4.3 { + INSERT INTO t1(t1) VALUES('integrity-check'); +} + +#------------------------------------------------------------------------- +reset_db + +do_execsql_test 5.0 { + CREATE VIRTUAL TABLE t1 USING fts5(content); + + INSERT INTO t1(t1,rank) VALUES('secure-delete',1); + INSERT INTO t1 VALUES('active'),('boomer'),('atom'),('atomic'), + ('alpha channel backup abandon test aback boomer atom alpha active'); + DELETE FROM t1 WHERE t1 MATCH 'abandon'; +} + +do_execsql_test 5.1 { + INSERT INTO t1(t1) VALUES('rebuild'); +} + +do_execsql_test 5.2 { + DELETE FROM t1 WHERE rowid NOTNULL<5; +} + +db close +sqlite3 db test.db + +do_execsql_test 5.3 { + PRAGMA integrity_check; +} {ok} + finish_test diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5secure7.test sqlite3-3.44.0-0/ext/fts5/test/fts5secure7.test --- sqlite3-3.42.0/ext/fts5/test/fts5secure7.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5secure7.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,116 @@ +# 2023 Feb 17 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#************************************************************************* +# +# TESTRUNNER: slow +# + +source [file join [file dirname [info script]] fts5_common.tcl] +ifcapable !fts5 { finish_test ; return } +set ::testprefix fts5secure7 + + +set NVOCAB 500 +set NDOC [expr 1000] + +set NREP 100 +set nDeletePerRep [expr 5] + +set VOCAB [list] + +proc select_one {list} { + set n [llength $list] + lindex $list [expr {abs(int(rand()*$n))}] +} + +proc init_vocab {} { + set L [split "abcdefghijklmnopqrstuvwxyz" {}] + set nL [llength $L] + for {set i 0} {$i < $::NVOCAB} {incr i} { + set n [expr {6 + int(rand()*8)}] + set word "" + for {set j 0} {$j < $n} {incr j} { + append word [select_one $L] + } + lappend ::VOCAB $word + } +} + +proc get_word {} { + select_one $::VOCAB +} + +proc get_document {nWord} { + set ret [list] + for {set i 0} {$i < $nWord} {incr i} { + lappend ret [get_word] + } + return $ret +} + +init_vocab + +db func document [list get_document 12] + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts5(body); + INSERT INTO t1(t1, rank) VALUES('secure-delete', 1); +} +do_execsql_test 1.1 { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<$NDOC + ) + INSERT INTO t1 SELECT document() FROM s; +} + +for {set iRep 0} {$iRep < $NREP} {incr iRep} { + set lRowid [db eval {SELECT rowid FROM t1}] + for {set iDel 0} {$iDel < $nDeletePerRep} {incr iDel} { + set idx [select_one $lRowid] + db eval { + DELETE FROM t1 WHERE rowid=$idx + } + } + db eval { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<$nDeletePerRep + ) + INSERT INTO t1 SELECT document() FROM s; + } + do_execsql_test 1.2.$iRep { + INSERT INTO t1(t1) VALUES('integrity-check'); + } +} + +reset_db +db func document [list get_document 12] +do_execsql_test 2.0 { + CREATE VIRTUAL TABLE t1 USING fts5(body); + INSERT INTO t1(t1, rank) VALUES('secure-delete', 1); + INSERT INTO t1(t1, rank) VALUES('pgsz', 128); +} +do_execsql_test 2.1 { + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<$NDOC + ) + INSERT INTO t1 SELECT document() FROM s; +} +for {set ii 0} {$ii < $NDOC} {incr ii} { + set lRowid [db eval {SELECT rowid FROM t1}] + set idx [select_one $lRowid] + db eval { DELETE FROM t1 WHERE rowid=$idx } + do_execsql_test 2.2.$ii { + INSERT INTO t1(t1) VALUES('integrity-check'); + } +} + +finish_test + + diff -Nru sqlite3-3.42.0/ext/fts5/test/fts5secure.test sqlite3-3.44.0-0/ext/fts5/test/fts5secure.test --- sqlite3-3.42.0/ext/fts5/test/fts5secure.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/fts5/test/fts5secure.test 2023-11-04 14:23:58.000000000 +0000 @@ -273,6 +273,76 @@ do_execsql_test 5.4 { SELECT rowid FROM t1('abc'); } 2 do_execsql_test 5.5 { SELECT rowid FROM t1('aa'); } 2 +#------------------------------------------------------------------------- +# Tests for the bug fixed by https://sqlite.org/src/info/4b60a1c3 +# +reset_db +do_execsql_test 6.0 { + CREATE VIRTUAL TABLE fts USING fts5(content); + INSERT INTO fts(fts, rank) VALUES ('secure-delete', 1); + INSERT INTO fts(rowid, content) VALUES + (3407, 'profile profile profile profile profile profile profile profile pull pulling pulling really'); + DELETE FROM fts WHERE rowid IS 3407; + INSERT INTO fts(fts) VALUES ('integrity-check'); +} + +foreach {tn detail} { + 1 full + 2 column + 3 none +} { + do_execsql_test 6.1.$detail " + DROP TABLE IF EXISTS t1; + CREATE VIRTUAL TABLE t1 USING fts5(x, detail=$detail); + " + + do_execsql_test 6.2.$detail { + INSERT INTO t1(t1, rank) VALUES('secure-delete', 1); + } + + for {set ii 1} {$ii < 100} {incr ii} { + do_execsql_test 6.3.$detail.$ii.1 { + BEGIN; + INSERT INTO t1(rowid, x) VALUES(10, 'word1'); + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i/dev/null)) +# SQLITE_C_IS_SEE := 0 +#else +# SQLITE_C_IS_SEE := 1 +# $(info This is an SEE build.) +#endif + +.NOTPARALLEL: $(sqlite3.h) +$(sqlite3.h): + $(MAKE) -C $(dir.top) sqlite3.c +$(sqlite3.c): $(sqlite3.h) + +opt.threadsafe ?= 1 +opt.fatal-oom ?= 1 +opt.debug ?= 1 +opt.metrics ?= 1 +SQLITE_OPT = \ + -DSQLITE_THREADSAFE=$(opt.threadsafe) \ + -DSQLITE_TEMP_STORE=2 \ + -DSQLITE_USE_URI=1 \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_OMIT_DEPRECATED \ + -DSQLITE_OMIT_SHARED_CACHE \ + -DSQLITE_C=$(sqlite3.c) \ + -DSQLITE_JNI_FATAL_OOM=$(opt.fatal-oom) \ + -DSQLITE_JNI_ENABLE_METRICS=$(opt.metrics) + +opt.extras ?= 1 +ifeq (1,$(opt.extras)) +SQLITE_OPT += -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ + -DSQLITE_ENABLE_STMTVTAB \ + -DSQLITE_ENABLE_DBPAGE_VTAB \ + -DSQLITE_ENABLE_DBSTAT_VTAB \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ + -DSQLITE_ENABLE_PREUPDATE_HOOK \ + -DSQLITE_ENABLE_NORMALIZE \ + -DSQLITE_ENABLE_SQLLOG +endif + +ifeq (1,$(opt.debug)) + SQLITE_OPT += -DSQLITE_DEBUG -g -DDEBUG -UNDEBUG +else + SQLITE_OPT += -Os +endif + +ifeq (1,$(enable.fts5)) + SQLITE_OPT += -DSQLITE_ENABLE_FTS5 +endif + +sqlite3-jni.c := $(dir.src.c)/sqlite3-jni.c +sqlite3-jni.o := $(dir.bld.c)/sqlite3-jni.o +sqlite3-jni.h := $(dir.src.c)/sqlite3-jni.h +package.dll := $(dir.bld.c)/libsqlite3-jni.so +# All javac-generated .h files must be listed in $(sqlite3-jni.h.in): +sqlite3-jni.h.in := +# $(java.with.jni) lists all Java files which contain JNI decls: +java.with.jni := +define ADD_JNI_H +sqlite3-jni.h.in += $$(dir.bld.c)/org_sqlite_jni$(3)_$(2).h +java.with.jni += $(1)/$(2).java +$$(dir.bld.c)/org_sqlite_jni$(3)_$(2).h: $(1)/$(2).java +endef +# Invoke ADD_JNI_H once for each Java file which includes JNI +# declarations: +$(eval $(call ADD_JNI_H,$(dir.src.capi),CApi,_capi)) +$(eval $(call ADD_JNI_H,$(dir.src.capi),SQLTester,_capi)) +ifeq (1,$(enable.fts5)) + $(eval $(call ADD_JNI_H,$(dir.src.fts5),Fts5ExtensionApi,_fts5)) + $(eval $(call ADD_JNI_H,$(dir.src.fts5),fts5_api,_fts5)) + $(eval $(call ADD_JNI_H,$(dir.src.fts5),fts5_tokenizer,_fts5)) +endif +$(sqlite3-jni.h.in): $(dir.bld.c) + +#package.dll.cfiles := +package.dll.cflags = \ + -std=c99 \ + -fPIC \ + -I. \ + -I$(dir $(sqlite3.h)) \ + -I$(dir.src.c) \ + -I$(JDK_HOME)/include \ + $(patsubst %,-I%,$(patsubst %.h,,$(wildcard $(JDK_HOME)/include/*))) \ + -Wall +# The gross $(patsubst...) above is to include the platform-specific +# subdir which lives under $(JDK_HOME)/include and is a required +# include path for client-level code. +# +# Using (-Wall -Wextra) triggers an untennable number of +# gcc warnings from sqlite3.c for mundane things like +# unused parameters. +######################################################################## +ifeq (1,$(enable.tester)) + package.dll.cflags += -DSQLITE_JNI_ENABLE_SQLTester +endif + +$(sqlite3-jni.h): $(sqlite3-jni.h.in) $(MAKEFILE) + @cat $(sqlite3-jni.h.in) > $@.tmp + @if cmp $@ $@.tmp >/dev/null; then \ + rm -f $@.tmp; \ + echo "$@ not modified"; \ + else \ + mv $@.tmp $@; \ + echo "Updated $@"; \ + fi + @if [ x1 != x$(enable.fts5) ]; then \ + echo "*** REMINDER:"; \ + echo "*** enable.fts5=0, so please do not check in changes to $@."; \ + fi + +$(package.dll): $(sqlite3-jni.h) $(sqlite3.c) $(sqlite3.h) +$(package.dll): $(sqlite3-jni.c) $(MAKEFILE) + $(CC) $(package.dll.cflags) $(SQLITE_OPT) \ + $(sqlite3-jni.c) -shared -o $@ +all: $(package.dll) + +.PHONY: test test-one +Tester1.flags ?= +Tester2.flags ?= +test.flags.jvm = -ea -Djava.library.path=$(dir.bld.c) \ + $(java.flags) -cp $(classpath) +test.deps := $(CLASS_FILES) $(package.dll) +test-one: $(test.deps) + $(bin.java) $(test.flags.jvm) org.sqlite.jni.capi.Tester1 $(Tester1.flags) + $(bin.java) $(test.flags.jvm) org.sqlite.jni.wrapper1.Tester2 $(Tester2.flags) +test-sqllog: $(test.deps) + @echo "Testing with -sqllog..." + $(bin.java) $(test.flags.jvm) -sqllog +test-mt: $(test.deps) + @echo "Testing in multi-threaded mode:"; + $(bin.java) $(test.flags.jvm) org.sqlite.jni.capi.Tester1 \ + -t 7 -r 50 -shuffle $(Tester1.flags) + $(bin.java) $(test.flags.jvm) org.sqlite.jni.wrapper1.Tester2 \ + -t 7 -r 50 -shuffle $(Tester2.flags) + +test: test-one test-mt +tests: test test-sqllog + +tester.scripts := $(sort $(wildcard $(dir.src)/tests/*.test)) +tester.flags ?= # --verbose +.PHONY: tester tester-local tester-ext +ifeq (1,$(enable.tester)) +tester-local: $(CLASS_FILES.tester) $(package.dll) + $(bin.java) -ea -Djava.library.path=$(dir.bld.c) \ + $(java.flags) -cp $(classpath) \ + org.sqlite.jni.capi.SQLTester $(tester.flags) $(tester.scripts) +tester: tester-local +else +tester: + @echo "SQLTester support is disabled." +endif + +tester.extdir.default := $(dir.tests)/ext +tester.extdir ?= $(tester.extdir.default) +tester.extern-scripts := $(wildcard $(tester.extdir)/*.test) +ifneq (,$(tester.extern-scripts)) +tester-ext: + $(bin.java) -ea -Djava.library.path=$(dir.bld.c) \ + $(java.flags) -cp $(classpath) \ + org.sqlite.jni.capi.SQLTester $(tester.flags) $(tester.extern-scripts) +else +tester-ext: + @echo "******************************************************"; \ + echo "*** Include the out-of-tree test suite in the 'tester'"; \ + echo "*** target by either symlinking its directory to"; \ + echo "*** $(tester.extdir.default) or passing it to make"; \ + echo "*** as tester.extdir=/path/to/that/dir."; \ + echo "******************************************************"; +endif + +tester-ext: tester-local +tester: tester-ext +tests: tester +######################################################################## +# Build each SQLITE_THREADMODE variant and run all tests against them. +multitest: clean +define MULTIOPT +multitest: multitest-$(1) +multitest-$(1): + $$(MAKE) opt.debug=$$(opt.debug) $(patsubst %,opt.%,$(2)) \ + tests clean enable.fts5=1 +endef + +$(eval $(call MULTIOPT,01,threadsafe=0 oom=1)) +$(eval $(call MULTIOPT,00,threadsafe=0 oom=0)) +$(eval $(call MULTIOPT,11,threadsafe=1 oom=1)) +$(eval $(call MULTIOPT,10,threadsafe=1 oom=0)) +$(eval $(call MULTIOPT,21,threadsafe=2 oom=1)) +$(eval $(call MULTIOPT,20,threadsafe=2 oom=0)) + + +######################################################################## +# jar bundle... +package.jar.in := $(abspath $(dir.src)/jar.in) +CLEAN_FILES += $(package.jar.in) +JAVA_FILES.jar := $(JAVA_FILES.main) $(JAVA_FILES.unittest) $(JAVA_FILES.package.info) +CLASS_FILES.jar := $(filter-out %/package-info.class,$(JAVA_FILES.jar:.java=.class)) +$(package.jar.in): $(package.dll) $(MAKEFILE) + ls -1 \ + $(dir.src.jni)/*/*.java $(dir.src.jni)/*/*.class \ + | sed -e 's,^$(dir.src)/,,' | sort > $@ + +$(package.jar): $(CLASS_FILES.jar) $(MAKEFILE) $(package.jar.in) + @rm -f $(dir.src)/c/*~ $(dir.src.jni)/*~ + cd $(dir.src); $(bin.jar) -cfe ../$@ org.sqlite.jni.capi.Tester1 @$(package.jar.in) + @ls -la $@ + @echo "To use this jar you will need the -Djava.library.path=DIR/CONTAINING/libsqlite3-jni.so flag." + @echo "e.g. java -Djava.library.path=bld -jar $@" + +jar: $(package.jar) +run-jar: $(package.jar) $(package.dll) + $(bin.java) -Djava.library.path=$(dir.bld) -jar $(package.jar) $(run-jar.flags) + +######################################################################## +# javadoc... +dir.doc := $(dir.jni)/javadoc +doc.index := $(dir.doc)/index.html +javadoc.exclude := -exclude org.sqlite.jni.fts5 +# ^^^^ 2023-09-13: elide the fts5 parts from the public docs for +# the time being, as it's not clear where the Java bindings for +# those bits are going. +# javadoc.exclude += -exclude org.sqlite.jni.capi +# ^^^^ exclude the capi API only for certain builds (TBD) +$(doc.index): $(JAVA_FILES.main) $(MAKEFILE) + @if [ -d $(dir.doc) ]; then rm -fr $(dir.doc)/*; fi + $(bin.javadoc) -cp $(classpath) -d $(dir.doc) -quiet \ + -subpackages org.sqlite.jni $(javadoc.exclude) + @echo "javadoc output is in $@" + +.PHONY: doc javadoc docserve +.FORCE: doc +doc: $(doc.index) +javadoc: $(doc.index) +# Force rebild of docs +redoc: + @rm -f $(doc.index) + @$(MAKE) doc +docserve: $(doc.index) + cd $(dir.doc) && althttpd -max-age 1 -page index.html +######################################################################## +# Clean up... +CLEAN_FILES += $(dir.bld.c)/* \ + $(dir.src.jni)/*.class \ + $(dir.src.jni)/*/*.class \ + $(package.dll) \ + hs_err_pid*.log + +.PHONY: clean distclean +clean: + -rm -f $(CLEAN_FILES) +distclean: clean + -rm -f $(DISTCLEAN_FILES) + -rm -fr $(dir.bld.c) $(dir.doc) + +######################################################################## +# disttribution bundle rules... + +ifeq (,$(filter snapshot,$(MAKECMDGOALS))) +dist-name-prefix := sqlite-jni +else +dist-name-prefix := sqlite-jni-snapshot-$(shell /usr/bin/date +%Y%m%d) +endif +dist-name := $(dist-name-prefix)-TEMP + + +dist-dir.top := $(dist-name) +dist-dir.src := $(dist-dir.top)/src +dist.top.extras := \ + README.md + +.PHONY: dist snapshot + +dist: \ + $(bin.version-info) $(sqlite3.canonical.c) \ + $(package.jar) $(MAKEFILE) + @echo "Making end-user deliverables..." + @echo "****************************************************************************"; \ + echo "*** WARNING: be sure to build this with JDK8 (javac 1.8) for compatibility."; \ + echo "*** reasons!"; $$($(bin.javac) -version); \ + echo "****************************************************************************" + @rm -fr $(dist-dir.top) + @mkdir -p $(dist-dir.src) + @cp -p $(dist.top.extras) $(dist-dir.top)/. + @cp -p jar-dist.make $(dist-dir.top)/Makefile + @cp -p $(dir.src.c)/*.[ch] $(dist-dir.src)/. + @cp -p $(sqlite3.canonical.c) $(sqlite3.canonical.h) $(dist-dir.src)/. + @set -e; \ + vnum=$$($(bin.version-info) --download-version); \ + vjar=$$($(bin.version-info) --version); \ + vdir=$(dist-name-prefix)-$$vnum; \ + arczip=$$vdir.zip; \ + cp -p $(package.jar) $(dist-dir.top)/sqlite3-jni-$${vjar}.jar; \ + echo "Making $$arczip ..."; \ + rm -fr $$arczip $$vdir; \ + mv $(dist-dir.top) $$vdir; \ + zip -qr $$arczip $$vdir; \ + rm -fr $$vdir; \ + ls -la $$arczip; \ + set +e; \ + unzip -lv $$arczip || echo "Missing unzip app? Not fatal." + +snapshot: dist + +.PHONY: dist-clean +clean: dist-clean +dist-clean: + rm -fr $(dist-name) $(wildcard sqlite-jni-*.zip) diff -Nru sqlite3-3.42.0/ext/jni/jar-dist.make sqlite3-3.44.0-0/ext/jni/jar-dist.make --- sqlite3-3.42.0/ext/jni/jar-dist.make 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/jar-dist.make 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,60 @@ +#!/this/is/make +#^^^^ help emacs out +# +# This is a POSIX-make-compatible makefile for building the sqlite3 +# JNI library from "dist" zip file. It must be edited to set the +# proper top-level JDK directory and, depending on the platform, add a +# platform-specific -I directory. It should build as-is with any +# 2020s-era version of gcc or clang. It requires JDK version 8 or +# higher and that JAVA_HOME points to the top-most installation +# directory of that JDK. On Ubuntu-style systems the JDK is typically +# installed under /usr/lib/jvm/java-VERSION-PLATFORM. + +default: all + +JAVA_HOME = /usr/lib/jvm/java-1.8.0-openjdk-amd64 +CFLAGS = \ + -fPIC \ + -Isrc \ + -I$(JAVA_HOME)/include \ + -I$(JAVA_HOME)/include/linux \ + -I$(JAVA_HOME)/include/apple \ + -I$(JAVA_HOME)/include/bsd \ + -Wall + +SQLITE_OPT = \ + -DSQLITE_ENABLE_RTREE \ + -DSQLITE_ENABLE_EXPLAIN_COMMENTS \ + -DSQLITE_ENABLE_STMTVTAB \ + -DSQLITE_ENABLE_DBPAGE_VTAB \ + -DSQLITE_ENABLE_DBSTAT_VTAB \ + -DSQLITE_ENABLE_BYTECODE_VTAB \ + -DSQLITE_ENABLE_OFFSET_SQL_FUNC \ + -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_OMIT_DEPRECATED \ + -DSQLITE_OMIT_SHARED_CACHE \ + -DSQLITE_THREADSAFE=1 \ + -DSQLITE_TEMP_STORE=2 \ + -DSQLITE_USE_URI=1 \ + -DSQLITE_ENABLE_FTS5 \ + -DSQLITE_DEBUG + +sqlite3-jni.dll = libsqlite3-jni.so +$(sqlite3-jni.dll): + @echo "************************************************************************"; \ + echo "*** If this fails to build, be sure to edit this makefile ***"; \ + echo "*** to configure it for your system. ***"; \ + echo "************************************************************************" + $(CC) $(CFLAGS) $(SQLITE_OPT) \ + src/sqlite3-jni.c -shared -o $@ + @echo "Now try running it with: make test" + +test.flags = -Djava.library.path=. sqlite3-jni-*.jar +test: $(sqlite3-jni.dll) + java -jar $(test.flags) + java -jar $(test.flags) -t 7 -r 10 -shuffle + +clean: + -rm -f $(sqlite3-jni.dll) + +all: $(sqlite3-jni.dll) diff -Nru sqlite3-3.42.0/ext/jni/README.md sqlite3-3.44.0-0/ext/jni/README.md --- sqlite3-3.42.0/ext/jni/README.md 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/README.md 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,313 @@ +SQLite3 via JNI +======================================================================== + +This directory houses a Java Native Interface (JNI) binding for the +sqlite3 API. If you are reading this from the distribution ZIP file, +links to resources in the canonical source tree will note work. The +canonical copy of this file can be browsed at: + + + +Technical support is available in the forum: + + + + +> **FOREWARNING:** this subproject is very much in development and + subject to any number of changes. Please do not rely on any + information about its API until this disclaimer is removed. The JNI + bindings released with version 3.43 are a "tech preview" and 3.44 + will be "final," at which point strong backward compatibility + guarantees will apply. + +Project goals/requirements: + +- A [1-to-1(-ish) mapping of the C API](#1to1ish) to Java via JNI, + insofar as cross-language semantics allow for. A closely-related + goal is that [the C documentation](https://sqlite.org/c3ref/intro.html) + should be usable as-is, insofar as possible, for the JNI binding. + +- Support Java as far back as version 8 (2014). + +- Environment-independent. Should work everywhere both Java + and SQLite3 do. + +- No 3rd-party dependencies beyond the JDK. That includes no + build-level dependencies for specific IDEs and toolchains. We + welcome the addition of build files for arbitrary environments + insofar as they neither interfere with each other nor become + a maintenance burden for the sqlite developers. + +Non-goals: + +- Creation of high-level OO wrapper APIs. Clients are free to create + them off of the C-style API. + +- Support for mixed-mode operation, where client code accesses SQLite + both via the Java-side API and the C API via their own native + code. In such cases, proxy functionalities (primarily callback + handler wrappers of all sorts) may fail because the C-side use of + the SQLite APIs will bypass those proxies. + + +Hello World +----------------------------------------------------------------------- + +```java +import org.sqlite.jni.*; +import static org.sqlite.jni.CApi.*; + +... + +final sqlite3 db = sqlite3_open(":memory:"); +try { + final int rc = sqlite3_errcode(db); + if( 0 != rc ){ + if( null != db ){ + System.out.print("Error opening db: "+sqlite3_errmsg(db)); + }else{ + System.out.print("Error opening db: rc="+rc); + } + ... handle error ... + } + // ... else use the db ... +}finally{ + // ALWAYS close databases using sqlite3_close() or sqlite3_close_v2() + // when done with them. All of their active statement handles must + // first have been passed to sqlite3_finalize(). + sqlite3_close_v2(db); +} +``` + + +Building +======================================================================== + +The canonical builds assumes a Linux-like environment and requires: + +- GNU Make +- A JDK supporting Java 8 or higher +- A modern C compiler. gcc and clang should both work. + +Put simply: + +```console +$ export JAVA_HOME=/path/to/jdk/root +$ make +$ make test +$ make clean +``` + +The jar distribution can be created with `make jar`, but note that it +does not contain the binary DLL file. A different DLL is needed for +each target platform. + + + +One-to-One(-ish) Mapping to C +======================================================================== + +This JNI binding aims to provide as close to a 1-to-1 experience with +the C API as cross-language semantics allow. Interface changes are +necessarily made where cross-language semantics do not allow a 1-to-1, +and judiciously made where a 1-to-1 mapping would be unduly cumbersome +to use in Java. In all cases, this binding makes every effort to +provide semantics compatible with the C API documentation even if the +interface to those semantics is slightly different. Any cases which +deviate from those semantics (either removing or adding semantics) are +clearly documented. + +Where it makes sense to do so for usability, Java-side overloads are +provided which accept or return data in alternative forms or provide +sensible default argument values. In all such cases they are thin +proxies around the corresponding C APIs and do not introduce new +semantics. + +In some very few cases, Java-specific capabilities have been added in +new APIs, all of which have "_java" somewhere in their names. +Examples include: + +- `sqlite3_result_java_object()` +- `sqlite3_column_java_object()` +- `sqlite3_column_java_casted()` +- `sqlite3_value_java_object()` +- `sqlite3_value_java_casted()` + +which, as one might surmise, collectively enable the passing of +arbitrary Java objects from user-defined SQL functions through to the +caller. + + +Golden Rule: Garbage Collection Cannot Free SQLite Resources +------------------------------------------------------------------------ + +It is important that all databases and prepared statement handles get +cleaned up by client code. A database cannot be closed if it has open +statement handles. `sqlite3_close()` fails if the db cannot be closed +whereas `sqlite3_close_v2()` recognizes that case and marks the db as +a "zombie," pending finalization when the library detects that all +pending statements have been closed. Be aware that Java garbage +collection _cannot_ close a database or finalize a prepared statement. +Those things require explicit API calls. + + +Golden Rule #2: _Never_ Throw from Callbacks (Unless...) +------------------------------------------------------------------------ + +All routines in this API, barring explicitly documented exceptions, +retain C-like semantics. For example, they are not permitted to throw +or propagate exceptions and must return error information (if any) via +result codes or `null`. The only cases where the C-style APIs may +throw is through client-side misuse, e.g. passing in a null where it +shouldn't be used. The APIs clearly mark function parameters which +should not be null, but does not actively defend itself against such +misuse. Some C-style APIs explicitly accept `null` as a no-op for +usability's sake, and some of the JNI APIs deliberately return an +error code, instead of segfaulting, when passed a `null`. + +Client-defined callbacks _must never throw exceptions_ unless _very +explicitly documented_ as being throw-safe. Exceptions are generally +reserved for higher-level bindings which are constructed to +specifically deal with them and ensure that they do not leak C-level +resources. In some cases, callback handlers are permitted to throw, in +which cases they get translated to C-level result codes and/or +messages. If a callback which is not permitted to throw throws, its +exception may trigger debug output but will otherwise be suppressed. + +The reason some callbacks are permitted to throw and others not is +because all such callbacks act as proxies for C function callback +interfaces and some of those interfaces have no error-reporting +mechanism. Those which are capable of propagating errors back through +the library convert exceptions from callbacks into corresponding +C-level error information. Those which cannot propagate errors +necessarily suppress any exceptions in order to maintain the C-style +semantics of the APIs. + + +Unwieldy Constructs are Re-mapped +------------------------------------------------------------------------ + +Some constructs, when modelled 1-to-1 from C to Java, are unduly +clumsy to work with in Java because they try to shoehorn C's way of +doing certain things into Java's wildly different ways. The following +subsections cover those, starting with a verbose explanation and +demonstration of where such changes are "really necessary"... + +### Custom Collations + +A prime example of where interface changes for Java are necessary for +usability is [registration of a custom +collation](https://sqlite.org/c3ref/create_collation.html): + +```c +// C: +int sqlite3_create_collation(sqlite3 * db, const char * name, int eTextRep, + void *pUserData, + int (*xCompare)(void*,int,void const *,int,void const *)); + +int sqlite3_create_collation_v2(sqlite3 * db, const char * name, int eTextRep, + void *pUserData, + int (*xCompare)(void*,int,void const *,int,void const *), + void (*xDestroy)(void*)); +``` + +The `pUserData` object is optional client-defined state for the +`xCompare()` and/or `xDestroy()` callback functions, both of which are +passed that object as their first argument. That data is passed around +"externally" in C because that's how C models the world. If we were to +bind that part as-is to Java, the result would be awkward to use (^Yes, +we tried this.): + +```java +// Java: +int sqlite3_create_collation(sqlite3 db, String name, int eTextRep, + Object pUserData, xCompareType xCompare); + +int sqlite3_create_collation_v2(sqlite3 db, String name, int eTextRep, + Object pUserData, + xCompareType xCompare, xDestroyType xDestroy); +``` + +The awkwardness comes from (A) having two distinctly different objects +for callbacks and (B) having their internal state provided separately, +which is ill-fitting in Java. For the sake of usability, C APIs which +follow that pattern use a slightly different Java interface: + +```java +int sqlite3_create_collation(sqlite3 db, String name, int eTextRep, + SomeCallbackType collation); +``` + +Where the `Collation` class has an abstract `call()` method and +no-op `xDestroy()` method which can be overridden if needed, leading to +a much more Java-esque usage: + +```java +int rc = sqlite3_create_collation(db, "mycollation", SQLITE_UTF8, new SomeCallbackType(){ + + // Required comparison function: + @Override public int call(byte[] lhs, byte[] rhs){ ... } + + // Optional finalizer function: + @Override public void xDestroy(){ ... } + + // Optional local state: + private String localState1 = + "This is local state. There are many like it, but this one is mine."; + private MyStateType localState2 = new MyStateType(); + ... +}); +``` + +Noting that: + +- It is possible to bind in call-scope-local state via closures, if + desired, as opposed to packing it into the Collation object. + +- No capabilities of the C API are lost or unduly obscured via the + above API reshaping, so power users need not make any compromises. + +- In the specific example above, `sqlite3_create_collation_v2()` + becomes superfluous because the provided interface effectively + provides both the v1 and v2 interfaces, the difference being that + overriding the `xDestroy()` method effectively gives it v2 + semantics. + + +### User-defined SQL Functions (a.k.a. UDFs) + +The [`sqlite3_create_function()`](https://sqlite.org/c3ref/create_function.html) +family of APIs make heavy use of function pointers to provide +client-defined callbacks, necessitating interface changes in the JNI +binding. The Java API has only one core function-registration function: + +```java +int sqlite3_create_function(sqlite3 db, String funcName, int nArgs, + int encoding, SQLFunction func); +``` + +> Design question: does the encoding argument serve any purpose in + Java? That's as-yet undetermined. If not, it will be removed. + +`SQLFunction` is not used directly, but is instead instantiated via +one of its three subclasses: + +- `SQLFunction.Scalar` implements simple scalar functions using but a + single callback. +- `SQLFunction.Aggregate` implements aggregate functions using two + callbacks. +- `SQLFunction.Window` implements window functions using four + callbacks. + +Search [`Tester1.java`](/file/ext/jni/src/org/sqlite/jni/Tester1.java) for +`SQLFunction` for how it's used. + +Reminder: see the disclaimer at the top of this document regarding the +in-flux nature of this API. + +### And so on... + +Various APIs which accept callbacks, e.g. `sqlite3_trace_v2()` and +`sqlite3_update_hook()`, use interfaces similar to those shown above. +Despite the changes in signature, the JNI layer makes every effort to +provide the same semantics as the C API documentation suggests. diff -Nru sqlite3-3.42.0/ext/jni/src/c/sqlite3-jni.c sqlite3-3.44.0-0/ext/jni/src/c/sqlite3-jni.c --- sqlite3-3.42.0/ext/jni/src/c/sqlite3-jni.c 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/c/sqlite3-jni.c 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,5899 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file implements the JNI bindings declared in +** org.sqlite.jni.capi.CApi (from which sqlite3-jni.h is generated). +*/ + +/* +** If you found this comment by searching the code for +** CallStaticObjectMethod then you're the victim of an OpenJDK bug: +** +** https://bugs.openjdk.org/browse/JDK-8130659 +** +** It's known to happen with OpenJDK v8 but not with v19. +** +** This code does not use JNI's CallStaticObjectMethod(). +*/ + +/* +** Define any SQLITE_... config defaults we want if they aren't +** overridden by the builder. Please keep these alphabetized. +*/ + +/**********************************************************************/ +/* SQLITE_D... */ +#ifndef SQLITE_DEFAULT_CACHE_SIZE +# define SQLITE_DEFAULT_CACHE_SIZE -16384 +#endif +#if !defined(SQLITE_DEFAULT_PAGE_SIZE) +# define SQLITE_DEFAULT_PAGE_SIZE 8192 +#endif +#ifndef SQLITE_DQS +# define SQLITE_DQS 0 +#endif + +/**********************************************************************/ +/* SQLITE_ENABLE_... */ +/* +** Unconditionally enable API_ARMOR in the JNI build. It ensures that +** public APIs behave predictable in the face of passing illegal NULLs +** or ranges which might otherwise invoke undefined behavior. +*/ +#undef SQLITE_ENABLE_API_ARMOR +#define SQLITE_ENABLE_API_ARMOR 1 + +#ifndef SQLITE_ENABLE_BYTECODE_VTAB +# define SQLITE_ENABLE_BYTECODE_VTAB 1 +#endif +#ifndef SQLITE_ENABLE_DBPAGE_VTAB +# define SQLITE_ENABLE_DBPAGE_VTAB 1 +#endif +#ifndef SQLITE_ENABLE_DBSTAT_VTAB +# define SQLITE_ENABLE_DBSTAT_VTAB 1 +#endif +#ifndef SQLITE_ENABLE_EXPLAIN_COMMENTS +# define SQLITE_ENABLE_EXPLAIN_COMMENTS 1 +#endif +#ifndef SQLITE_ENABLE_MATH_FUNCTIONS +# define SQLITE_ENABLE_MATH_FUNCTIONS 1 +#endif +#ifndef SQLITE_ENABLE_OFFSET_SQL_FUNC +# define SQLITE_ENABLE_OFFSET_SQL_FUNC 1 +#endif +#ifndef SQLITE_ENABLE_RTREE +# define SQLITE_ENABLE_RTREE 1 +#endif +//#ifndef SQLITE_ENABLE_SESSION +//# define SQLITE_ENABLE_SESSION 1 +//#endif +#ifndef SQLITE_ENABLE_STMTVTAB +# define SQLITE_ENABLE_STMTVTAB 1 +#endif +//#ifndef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +//# define SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION +//#endif + +/**********************************************************************/ +/* SQLITE_J... */ +#ifdef SQLITE_JNI_FATAL_OOM +#if !SQLITE_JNI_FATAL_OOM +#undef SQLITE_JNI_FATAL_OOM +#endif +#endif + +/**********************************************************************/ +/* SQLITE_M... */ +#ifndef SQLITE_MAX_ALLOCATION_SIZE +# define SQLITE_MAX_ALLOCATION_SIZE 0x1fffffff +#endif + +/**********************************************************************/ +/* SQLITE_O... */ +#ifndef SQLITE_OMIT_DEPRECATED +# define SQLITE_OMIT_DEPRECATED 1 +#endif +#ifndef SQLITE_OMIT_LOAD_EXTENSION +# define SQLITE_OMIT_LOAD_EXTENSION 1 +#endif +#ifndef SQLITE_OMIT_SHARED_CACHE +# define SQLITE_OMIT_SHARED_CACHE 1 +#endif +#ifdef SQLITE_OMIT_UTF16 +/* UTF16 is required for java */ +# undef SQLITE_OMIT_UTF16 1 +#endif + +/**********************************************************************/ +/* SQLITE_T... */ +#ifndef SQLITE_TEMP_STORE +# define SQLITE_TEMP_STORE 2 +#endif +#ifndef SQLITE_THREADSAFE +# define SQLITE_THREADSAFE 1 +#endif + +/**********************************************************************/ +/* SQLITE_USE_... */ +#ifndef SQLITE_USE_URI +# define SQLITE_USE_URI 1 +#endif + + +/* +** Which sqlite3.c we're using needs to be configurable to enable +** building against a custom copy, e.g. the SEE variant. We have to +** include sqlite3.c, as opposed to sqlite3.h, in order to get access +** to some interal details like SQLITE_MAX_... and friends. This +** increases the rebuild time considerably but we need this in order +** to access some internal functionality and keep the to-Java-exported +** values of SQLITE_MAX_... and SQLITE_LIMIT_... in sync with the C +** build. +*/ +#ifndef SQLITE_C +# define SQLITE_C sqlite3.c +#endif +#define INC__STRINGIFY_(f) #f +#define INC__STRINGIFY(f) INC__STRINGIFY_(f) +#include INC__STRINGIFY(SQLITE_C) +#undef INC__STRINGIFY_ +#undef INC__STRINGIFY +#undef SQLITE_C + +/* +** End of the sqlite3 lib setup. What follows is JNI-specific. +*/ + +#include "sqlite3-jni.h" +#include +#include /* only for testing/debugging */ +#include /* intptr_t for 32-bit builds */ + +/* Only for debugging */ +#define MARKER(pfexp) \ + do{ printf("MARKER: %s:%d:%s():\t",__FILE__,__LINE__,__func__); \ + printf pfexp; \ + } while(0) + +/* +** Creates a verbose JNI function name. Suffix must be +** the JNI-mangled form of the function's name, minus the +** prefix seen in this macro. +*/ +#define JniFuncName(Suffix) \ + Java_org_sqlite_jni_capi_CApi_sqlite3_ ## Suffix + +/* Prologue for JNI function declarations and definitions. */ +#define JniDecl(ReturnType,Suffix) \ + JNIEXPORT ReturnType JNICALL JniFuncName(Suffix) + +/* +** S3JniApi's intent is that CFunc be the C API func(s) the +** being-declared JNI function is wrapping, making it easier to find +** that function's JNI-side entry point. The other args are for JniDecl. +** See the many examples in this file. +*/ +#define S3JniApi(CFunc,ReturnType,Suffix) JniDecl(ReturnType,Suffix) + +/* +** S3JniCast_L2P and P2L cast jlong (64-bit) to/from pointers. This is +** required for casting warning-free on 32-bit builds, where we +** otherwise get complaints that we're casting between different-sized +** int types. +** +** This use of intptr_t is the _only_ reason we require +** which, in turn, requires building with -std=c99 (or later). +*/ +#define S3JniCast_L2P(JLongAsPtr) (void*)((intptr_t)(JLongAsPtr)) +#define S3JniCast_P2L(PTR) (jlong)((intptr_t)(PTR)) + +/* +** Shortcuts for the first 2 parameters to all JNI bindings. +** +** The type of the jSelf arg differs, but no docs seem to mention +** this: for static methods it's of type jclass and for non-static +** it's jobject. jobject actually works for all funcs, in the sense +** that it compiles and runs so long as we don't use jSelf (which is +** only rarely needed in this code), but to be pedantically correct we +** need the proper type in the signature. +** +** https://docs.oracle.com/javase/8/docs/technotes/guides/jni/spec/design.html#jni_interface_functions_and_pointers +*/ +#define JniArgsEnvObj JNIEnv * const env, jobject jSelf +#define JniArgsEnvClass JNIEnv * const env, jclass jKlazz +/* +** Helpers to account for -Xcheck:jni warnings about not having +** checked for exceptions. +*/ +#define S3JniIfThrew if( (*env)->ExceptionCheck(env) ) +#define S3JniExceptionClear (*env)->ExceptionClear(env) +#define S3JniExceptionReport (*env)->ExceptionDescribe(env) +#define S3JniExceptionIgnore S3JniIfThrew S3JniExceptionClear +#define S3JniExceptionWarnIgnore \ + S3JniIfThrew {S3JniExceptionReport; S3JniExceptionClear;}(void)0 +#define S3JniExceptionWarnCallbackThrew(STR) \ + MARKER(("WARNING: " STR " MUST NOT THROW.\n")); \ + (*env)->ExceptionDescribe(env) + +/** To be used for cases where we're _really_ not expecting an + exception, e.g. looking up well-defined Java class members. */ +#define S3JniExceptionIsFatal(MSG) S3JniIfThrew {\ + S3JniExceptionReport; S3JniExceptionClear; \ + (*env)->FatalError(env, MSG); \ + } + +/* +** Declares local var env = s3jni_env(). All JNI calls involve a +** JNIEnv somewhere, always named env, and many of our macros assume +** env is in scope. Where it's not, but should be, use this to make it +** so. +*/ +#define S3JniDeclLocal_env JNIEnv * const env = s3jni_env() + +/* Fail fatally with an OOM message. */ +static inline void s3jni_oom(JNIEnv * const env){ + (*env)->FatalError(env, "SQLite3 JNI is out of memory.") /* does not return */; +} + +/* +** sqlite3_malloc() proxy which fails fatally on OOM. This should +** only be used for routines which manage global state and have no +** recovery strategy for OOM. For sqlite3 API which can reasonably +** return SQLITE_NOMEM, s3jni_malloc() should be used instead. +*/ +static void * s3jni_malloc_or_die(JNIEnv * const env, size_t n){ + void * const rv = sqlite3_malloc(n); + if( n && !rv ) s3jni_oom(env); + return rv; +} + +/* +** Works like sqlite3_malloc() unless built with SQLITE_JNI_FATAL_OOM, +** in which case it calls s3jni_oom() on OOM. +*/ +#ifdef SQLITE_JNI_FATAL_OOM +#define s3jni_malloc(SIZE) s3jni_malloc_or_die(env, SIZE) +#else +#define s3jni_malloc(SIZE) sqlite3_malloc(((void)env,(SIZE))) +/* the ((void)env) trickery here is to avoid ^^^^^^ an otherwise + unused arg in at least one place. */ +#endif + +/* +** Works like sqlite3_realloc() unless built with SQLITE_JNI_FATAL_OOM, +** in which case it calls s3jni_oom() on OOM. +*/ +#ifdef SQLITE_JNI_FATAL_OOM +static void * s3jni_realloc_or_die(JNIEnv * const env, void * p, size_t n){ + void * const rv = sqlite3_realloc(p, (int)n); + if( n && !rv ) s3jni_oom(env); + return rv; +} +#define s3jni_realloc(MEM,SIZE) s3jni_realloc_or_die(env, (MEM), (SIZE)) +#else +#define s3jni_realloc(MEM,SIZE) sqlite3_realloc((MEM), ((void)env, (SIZE))) +#endif + +/* Fail fatally if !EXPR. */ +#define s3jni_oom_fatal(EXPR) if( !(EXPR) ) s3jni_oom(env) +/* Maybe fail fatally if !EXPR. */ +#ifdef SQLITE_JNI_FATAL_OOM +#define s3jni_oom_check s3jni_oom_fatal +#else +#define s3jni_oom_check(EXPR) +#endif +//#define S3JniDb_oom(pDb,EXPR) ((EXPR) ? sqlite3OomFault(pDb) : 0) + +#define s3jni_db_oom(pDb) (void)((pDb) ? ((pDb)->mallocFailed=1) : 0) + +/* Helpers for Java value reference management. */ +static jobject s3jni_ref_global(JNIEnv * const env, jobject const v){ + jobject const rv = v ? (*env)->NewGlobalRef(env, v) : NULL; + s3jni_oom_fatal( v ? !!rv : 1 ); + return rv; +} +static jobject s3jni_ref_local(JNIEnv * const env, jobject const v){ + jobject const rv = v ? (*env)->NewLocalRef(env, v) : NULL; + s3jni_oom_fatal( v ? !!rv : 1 ); + return rv; +} +static inline void s3jni_unref_global(JNIEnv * const env, jobject const v){ + if( v ) (*env)->DeleteGlobalRef(env, v); +} +static inline void s3jni_unref_local(JNIEnv * const env, jobject const v){ + if( v ) (*env)->DeleteLocalRef(env, v); +} +#define S3JniRefGlobal(VAR) s3jni_ref_global(env, (VAR)) +#define S3JniRefLocal(VAR) s3jni_ref_local(env, (VAR)) +#define S3JniUnrefGlobal(VAR) s3jni_unref_global(env, (VAR)) +#define S3JniUnrefLocal(VAR) s3jni_unref_local(env, (VAR)) + +/* +** Lookup key type for use with s3jni_nphop() and a cache of a +** frequently-needed Java-side class reference and one or two Java +** class member IDs. +*/ +typedef struct S3JniNphOp S3JniNphOp; +struct S3JniNphOp { + const int index /* index into S3JniGlobal.nph[] */; + const char * const zName /* Full Java name of the class */; + const char * const zMember /* Name of member property */; + const char * const zTypeSig /* JNI type signature of zMember */; + /* + ** klazz is a global ref to the class represented by pRef. + ** + ** According to: + ** + ** https://developer.ibm.com/articles/j-jni/ + ** + ** > ... the IDs returned for a given class don't change for the + ** lifetime of the JVM process. But the call to get the field or + ** method can require significant work in the JVM, because fields + ** and methods might have been inherited from superclasses, making + ** the JVM walk up the class hierarchy to find them. Because the + ** IDs are the same for a given class, you should look them up + ** once and then reuse them. Similarly, looking up class objects + ** can be expensive, so they should be cached as well. + */ + jclass klazz; + volatile jfieldID fidValue /* NativePointerHolder.nativePointer or + ** OutputPointer.T.value */; + volatile jmethodID midCtor /* klazz's no-arg constructor. Used by + ** NativePointerHolder_new(). */; +}; + +/* +** Cache keys for each concrete NativePointerHolder subclasses and +** OutputPointer.T types. The members are to be used with s3jni_nphop() +** and friends, and each one's member->index corresponds to its index +** in the S3JniGlobal.nph[] array. +*/ +static const struct { + const S3JniNphOp sqlite3; + const S3JniNphOp sqlite3_backup; + const S3JniNphOp sqlite3_blob; + const S3JniNphOp sqlite3_context; + const S3JniNphOp sqlite3_stmt; + const S3JniNphOp sqlite3_value; + const S3JniNphOp OutputPointer_Bool; + const S3JniNphOp OutputPointer_Int32; + const S3JniNphOp OutputPointer_Int64; + const S3JniNphOp OutputPointer_sqlite3; + const S3JniNphOp OutputPointer_sqlite3_blob; + const S3JniNphOp OutputPointer_sqlite3_stmt; + const S3JniNphOp OutputPointer_sqlite3_value; + const S3JniNphOp OutputPointer_String; +#ifdef SQLITE_ENABLE_FTS5 + const S3JniNphOp OutputPointer_ByteArray; + const S3JniNphOp Fts5Context; + const S3JniNphOp Fts5ExtensionApi; + const S3JniNphOp fts5_api; + const S3JniNphOp fts5_tokenizer; + const S3JniNphOp Fts5Tokenizer; +#endif +} S3JniNphOps = { +#define MkRef(INDEX, KLAZZ, MEMBER, SIG) \ + { INDEX, "org/sqlite/jni/" KLAZZ, MEMBER, SIG } +/* NativePointerHolder ref */ +#define RefN(INDEX, KLAZZ) MkRef(INDEX, KLAZZ, "nativePointer", "J") +/* OutputPointer.T ref */ +#define RefO(INDEX, KLAZZ, SIG) MkRef(INDEX, KLAZZ, "value", SIG) + RefN(0, "capi/sqlite3"), + RefN(1, "capi/sqlite3_backup"), + RefN(2, "capi/sqlite3_blob"), + RefN(3, "capi/sqlite3_context"), + RefN(4, "capi/sqlite3_stmt"), + RefN(5, "capi/sqlite3_value"), + RefO(6, "capi/OutputPointer$Bool", "Z"), + RefO(7, "capi/OutputPointer$Int32", "I"), + RefO(8, "capi/OutputPointer$Int64", "J"), + RefO(9, "capi/OutputPointer$sqlite3", + "Lorg/sqlite/jni/capi/sqlite3;"), + RefO(10, "capi/OutputPointer$sqlite3_blob", + "Lorg/sqlite/jni/capi/sqlite3_blob;"), + RefO(11, "capi/OutputPointer$sqlite3_stmt", + "Lorg/sqlite/jni/capi/sqlite3_stmt;"), + RefO(12, "capi/OutputPointer$sqlite3_value", + "Lorg/sqlite/jni/capi/sqlite3_value;"), + RefO(13, "capi/OutputPointer$String", "Ljava/lang/String;"), +#ifdef SQLITE_ENABLE_FTS5 + RefO(14, "capi/OutputPointer$ByteArray", "[B"), + RefN(15, "fts5/Fts5Context"), + RefN(16, "fts5/Fts5ExtensionApi"), + RefN(17, "fts5/fts5_api"), + RefN(18, "fts5/fts5_tokenizer"), + RefN(19, "fts5/Fts5Tokenizer") +#endif +#undef MkRef +#undef RefN +#undef RefO +}; + +#define S3JniNph(T) &S3JniNphOps.T + +enum { + /* + ** Size of the NativePointerHolder cache. Need enough space for + ** (only) the library's NativePointerHolder and OutputPointer types, + ** a fixed count known at build-time. This value needs to be + ** exactly the number of S3JniNphOp entries in the S3JniNphOps + ** object. + */ + S3Jni_NphCache_size = sizeof(S3JniNphOps) / sizeof(S3JniNphOp) +}; + +/* +** State for binding C callbacks to Java methods. +*/ +typedef struct S3JniHook S3JniHook; +struct S3JniHook{ + jobject jObj /* global ref to Java instance */; + jmethodID midCallback /* callback method. Signature depends on + ** jObj's type */; + /* We lookup the jObj.xDestroy() method as-needed for contexts which + ** support custom finalizers. Fundamentally we can support them for + ** any Java type, but we only want to expose support for them where + ** the C API does. */ + jobject jExtra /* Global ref to a per-hook-type value */; + int doXDestroy /* If true then S3JniHook_unref() will call + jObj->xDestroy() if it's available. */; + S3JniHook * pNext /* Next entry in S3Global.hooks.aFree */; +}; +/* For clean bitwise-copy init of local instances. */ +static const S3JniHook S3JniHook_empty = {0,0,0,0,0}; + +/* +** Per-(sqlite3*) state for various JNI bindings. This state is +** allocated as needed, cleaned up in sqlite3_close(_v2)(), and +** recycled when possible. +** +** Trivia: vars and parameters of this type are often named "ps" +** because this class used to have a name for which that abbreviation +** made sense. +*/ +typedef struct S3JniDb S3JniDb; +struct S3JniDb { + sqlite3 *pDb /* The associated db handle */; + jobject jDb /* A global ref of the output object which gets + returned from sqlite3_open(_v2)(). We need this in + order to have an object to pass to routines like + sqlite3_collation_needed()'s callback, or else we + have to dynamically create one for that purpose, + which would be fine except that it would be a + different instance (and maybe even a different + class) than the one the user may expect to + receive. */; + char * zMainDbName /* Holds the string allocated on behalf of + SQLITE_DBCONFIG_MAINDBNAME. */; + struct { + S3JniHook busyHandler; + S3JniHook collationNeeded; + S3JniHook commit; + S3JniHook progress; + S3JniHook rollback; + S3JniHook trace; + S3JniHook update; + S3JniHook auth; +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + S3JniHook preUpdate; +#endif + } hooks; +#ifdef SQLITE_ENABLE_FTS5 + /* FTS5-specific state */ + struct { + jobject jApi /* global ref to s3jni_fts5_api_from_db() */; + } fts; +#endif + S3JniDb * pNext /* Next entry in SJG.perDb.aFree */; +}; + +static const char * const S3JniDb_clientdata_key = "S3JniDb"; +#define S3JniDb_from_clientdata(pDb) \ + (pDb ? sqlite3_get_clientdata(pDb, S3JniDb_clientdata_key) : 0) + +/* +** Cache for per-JNIEnv (i.e. per-thread) data. +** +** Trivia: vars and parameters of this type are often named "jc" +** because this class used to have a name for which that abbreviation +** made sense. +*/ +typedef struct S3JniEnv S3JniEnv; +struct S3JniEnv { + JNIEnv *env /* JNIEnv in which this cache entry was created */; + /* + ** pdbOpening is used to coordinate the Java/DB connection of a + ** being-open()'d db in the face of auto-extensions. + ** Auto-extensions run before we can bind the C db to its Java + ** representation, but auto-extensions require that binding to pass + ** on to their Java-side callbacks. We handle this as follows: + ** + ** - In the JNI side of sqlite3_open(), allocate the Java side of + ** that connection and set pdbOpening to point to that + ** object. + ** + ** - Call sqlite3_open(), which triggers the auto-extension + ** handler. That handler uses pdbOpening to connect the native + ** db handle which it receives with pdbOpening. + ** + ** - When sqlite3_open() returns, check whether pdbOpening->pDb is + ** NULL. If it isn't, auto-extension handling set it up. If it + ** is, complete the Java/C binding unless sqlite3_open() returns + ** a NULL db, in which case free pdbOpening. + */ + S3JniDb * pdbOpening; + S3JniEnv * pNext /* Next entry in SJG.envCache.aHead or + SJG.envCache.aFree */; +}; + +/* +** State for proxying sqlite3_auto_extension() in Java. This was +** initially a separate class from S3JniHook and now the older name is +** retained for readability in the APIs which use this, as well as for +** its better code-searchability. +*/ +typedef S3JniHook S3JniAutoExtension; + +/* +** Type IDs for SQL function categories. +*/ +enum UDFType { + UDF_UNKNOWN_TYPE = 0/*for error propagation*/, + UDF_SCALAR, + UDF_AGGREGATE, + UDF_WINDOW +}; + +/* +** State for binding Java-side UDFs. +*/ +typedef struct S3JniUdf S3JniUdf; +struct S3JniUdf { + jobject jObj /* SQLFunction instance */; + char * zFuncName /* Only for error reporting and debug logging */; + enum UDFType type /* UDF type */; + /** Method IDs for the various UDF methods. */ + jmethodID jmidxFunc /* xFunc method (scalar) */; + jmethodID jmidxStep /* xStep method (aggregate/window) */; + jmethodID jmidxFinal /* xFinal method (aggregate/window) */; + jmethodID jmidxValue /* xValue method (window) */; + jmethodID jmidxInverse /* xInverse method (window) */; + S3JniUdf * pNext /* Next entry in SJG.udf.aFree. */; +}; + +#if defined(SQLITE_JNI_ENABLE_METRICS) && 0==SQLITE_JNI_ENABLE_METRICS +# undef SQLITE_JNI_ENABLE_METRICS +#endif + +/* +** If true, modifying S3JniGlobal.metrics is protected by a mutex, +** else it isn't. +*/ +#ifdef SQLITE_DEBUG +# define S3JNI_METRICS_MUTEX SQLITE_THREADSAFE +#else +# define S3JNI_METRICS_MUTEX 0 +#endif +#ifndef SQLITE_JNI_ENABLE_METRICS +# undef S3JNI_METRICS_MUTEX +# define S3JNI_METRICS_MUTEX 0 +#endif + +/* +** Global state, e.g. caches and metrics. +*/ +typedef struct S3JniGlobalType S3JniGlobalType; +struct S3JniGlobalType { + /* + ** According to: https://developer.ibm.com/articles/j-jni/ + ** + ** > A thread can get a JNIEnv by calling GetEnv() using the JNI + ** invocation interface through a JavaVM object. The JavaVM object + ** itself can be obtained by calling the JNI GetJavaVM() method + ** using a JNIEnv object and can be cached and shared across + ** threads. Caching a copy of the JavaVM object enables any thread + ** with access to the cached object to get access to its own + ** JNIEnv when necessary. + */ + JavaVM * jvm; + /* + ** Global mutex. It must not be used for anything which might call + ** back into the JNI layer. + */ + sqlite3_mutex * mutex; + /* + ** Cache of references to Java classes and method IDs for + ** NativePointerHolder subclasses and OutputPointer.T types. + */ + struct { + S3JniNphOp list[S3Jni_NphCache_size]; + sqlite3_mutex * mutex; /* mutex for this->list */ + volatile void const * locker; /* sanity-checking-only context object + for this->mutex */ + } nph; + /* + ** Cache of per-thread state. + */ + struct { + S3JniEnv * aHead /* Linked list of in-use instances */; + S3JniEnv * aFree /* Linked list of free instances */; + sqlite3_mutex * mutex /* mutex for aHead and aFree. */; + volatile void const * locker /* env mutex is held on this + object's behalf. Used only for + sanity checking. */; + } envCache; + /* + ** Per-db state. This can move into the core library once we can tie + ** client-defined state to db handles there. + */ + struct { + S3JniDb * aFree /* Linked list of free instances */; + sqlite3_mutex * mutex /* mutex for aHead and aFree */; + volatile void const * locker + /* perDb mutex is held on this object's behalf. Used only for + sanity checking. Note that the mutex is at the class level, not + instance level. */; + } perDb; + struct { + S3JniUdf * aFree /* Head of the free-item list. Guarded by global + mutex. */; + } udf; + /* + ** Refs to global classes and methods. Obtained during static init + ** and never released. + */ + struct { + jclass cLong /* global ref to java.lang.Long */; + jclass cString /* global ref to java.lang.String */; + jobject oCharsetUtf8 /* global ref to StandardCharset.UTF_8 */; + jmethodID ctorLong1 /* the Long(long) constructor */; + jmethodID ctorStringBA /* the String(byte[],Charset) constructor */; + jmethodID stringGetBytes /* the String.getBytes(Charset) method */; + } g; + /* + ** The list of Java-side auto-extensions + ** (org.sqlite.jni.capi.AutoExtensionCallback objects). + */ + struct { + S3JniAutoExtension *aExt /* The auto-extension list. It is + maintained such that all active + entries are in the first contiguous + nExt array elements. */; + int nAlloc /* number of entries allocated for aExt, + as distinct from the number of active + entries. */; + int nExt /* number of active entries in aExt, all in the + first nExt'th array elements. */; + sqlite3_mutex * mutex /* mutex for manipulation/traversal of aExt */; + volatile const void * locker /* object on whose behalf the mutex + is held. Only for sanity checking + in debug builds. */; + } autoExt; +#ifdef SQLITE_ENABLE_FTS5 + struct { + volatile jobject jExt /* Global ref to Java singleton for the + Fts5ExtensionApi instance. */; + struct { + jfieldID fidA /* Fts5Phrase::a member */; + jfieldID fidB /* Fts5Phrase::b member */; + } jPhraseIter; + } fts5; +#endif + struct { +#ifdef SQLITE_ENABLE_SQLLOG + S3JniHook sqllog /* sqlite3_config(SQLITE_CONFIG_SQLLOG) callback */; +#endif + S3JniHook configlog /* sqlite3_config(SQLITE_CONFIG_LOG) callback */; + S3JniHook * aFree /* free-item list, for recycling. */; + sqlite3_mutex * mutex /* mutex for aFree */; + volatile const void * locker /* object on whose behalf the mutex + is held. Only for sanity checking + in debug builds. */; + } hook; +#ifdef SQLITE_JNI_ENABLE_METRICS + /* Internal metrics. */ + struct { + volatile unsigned nEnvHit; + volatile unsigned nEnvMiss; + volatile unsigned nEnvAlloc; + volatile unsigned nMutexEnv /* number of times envCache.mutex was entered for + a S3JniEnv operation. */; + volatile unsigned nMutexNph /* number of times SJG.mutex was entered */; + volatile unsigned nMutexHook /* number of times SJG.mutex hooks.was entered */; + volatile unsigned nMutexPerDb /* number of times perDb.mutex was entered */; + volatile unsigned nMutexAutoExt /* number of times autoExt.mutex was entered */; + volatile unsigned nMutexGlobal /* number of times global mutex was entered. */; + volatile unsigned nMutexUdf /* number of times global mutex was entered + for UDFs. */; + volatile unsigned nDestroy /* xDestroy() calls across all types */; + volatile unsigned nPdbAlloc /* Number of S3JniDb alloced. */; + volatile unsigned nPdbRecycled /* Number of S3JniDb reused. */; + volatile unsigned nUdfAlloc /* Number of S3JniUdf alloced. */; + volatile unsigned nUdfRecycled /* Number of S3JniUdf reused. */; + volatile unsigned nHookAlloc /* Number of S3JniHook alloced. */; + volatile unsigned nHookRecycled /* Number of S3JniHook reused. */; + struct { + /* Number of calls for each type of UDF callback. */ + volatile unsigned nFunc; + volatile unsigned nStep; + volatile unsigned nFinal; + volatile unsigned nValue; + volatile unsigned nInverse; + } udf; + unsigned nMetrics /* Total number of mutex-locked + metrics increments. */; +#if S3JNI_METRICS_MUTEX + sqlite3_mutex * mutex; +#endif + } metrics; +#endif /* SQLITE_JNI_ENABLE_METRICS */ +}; +static S3JniGlobalType S3JniGlobal = {}; +#define SJG S3JniGlobal + +/* Increments *p, possibly protected by a mutex. */ +#ifndef SQLITE_JNI_ENABLE_METRICS +#define s3jni_incr(PTR) +#elif S3JNI_METRICS_MUTEX +static void s3jni_incr( volatile unsigned int * const p ){ + sqlite3_mutex_enter(SJG.metrics.mutex); + ++SJG.metrics.nMetrics; + ++(*p); + sqlite3_mutex_leave(SJG.metrics.mutex); +} +#else +#define s3jni_incr(PTR) ++(*(PTR)) +#endif + +/* Helpers for working with specific mutexes. */ +#if SQLITE_THREADSAFE +#define s3jni_mutex_enter2(M, Metric) \ + sqlite3_mutex_enter( M ); \ + s3jni_incr( &SJG.metrics.Metric ) +#define s3jni_mutex_leave2(M) \ + sqlite3_mutex_leave( M ) + +#define s3jni_mutex_enter(M, L, Metric) \ + assert( (void*)env != (void*)L && "Invalid use of " #L); \ + s3jni_mutex_enter2( M, Metric ); \ + L = env +#define s3jni_mutex_leave(M, L) \ + assert( (void*)env == (void*)L && "Invalid use of " #L); \ + L = 0; \ + s3jni_mutex_leave2( M ) + +#define S3JniEnv_mutex_assertLocked \ + assert( 0 != SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" ) +#define S3JniEnv_mutex_assertLocker \ + assert( (env) == SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" ) +#define S3JniEnv_mutex_assertNotLocker \ + assert( (env) != SJG.envCache.locker && "Misuse of S3JniGlobal.envCache.mutex" ) + +#define S3JniEnv_mutex_enter \ + s3jni_mutex_enter( SJG.envCache.mutex, SJG.envCache.locker, nMutexEnv ) +#define S3JniEnv_mutex_leave \ + s3jni_mutex_leave( SJG.envCache.mutex, SJG.envCache.locker ) + +#define S3JniAutoExt_mutex_enter \ + s3jni_mutex_enter( SJG.autoExt.mutex, SJG.autoExt.locker, nMutexAutoExt ) +#define S3JniAutoExt_mutex_leave \ + s3jni_mutex_leave( SJG.autoExt.mutex, SJG.autoExt.locker ) +#define S3JniAutoExt_mutex_assertLocker \ + assert( env == SJG.autoExt.locker && "Misuse of S3JniGlobal.autoExt.mutex" ) + +#define S3JniGlobal_mutex_enter \ + s3jni_mutex_enter2( SJG.mutex, nMutexGlobal ) +#define S3JniGlobal_mutex_leave \ + s3jni_mutex_leave2( SJG.mutex ) + +#define S3JniHook_mutex_enter \ + s3jni_mutex_enter( SJG.hook.mutex, SJG.hook.locker, nMutexHook ) +#define S3JniHook_mutex_leave \ + s3jni_mutex_leave( SJG.hook.mutex, SJG.hook.locker ) + +#define S3JniNph_mutex_enter \ + s3jni_mutex_enter( SJG.nph.mutex, SJG.nph.locker, nMutexNph ) +#define S3JniNph_mutex_leave \ + s3jni_mutex_leave( SJG.nph.mutex, SJG.nph.locker ) + +#define S3JniDb_mutex_assertLocker \ + assert( (env) == SJG.perDb.locker && "Misuse of S3JniGlobal.perDb.mutex" ) +#define S3JniDb_mutex_enter \ + s3jni_mutex_enter( SJG.perDb.mutex, SJG.perDb.locker, nMutexPerDb ) +#define S3JniDb_mutex_leave \ + s3jni_mutex_leave( SJG.perDb.mutex, SJG.perDb.locker ) + +#else /* SQLITE_THREADSAFE==0 */ +#define S3JniAutoExt_mutex_assertLocker +#define S3JniAutoExt_mutex_enter +#define S3JniAutoExt_mutex_leave +#define S3JniDb_mutex_assertLocker +#define S3JniDb_mutex_enter +#define S3JniDb_mutex_leave +#define S3JniEnv_mutex_assertLocked +#define S3JniEnv_mutex_assertLocker +#define S3JniEnv_mutex_assertNotLocker +#define S3JniEnv_mutex_enter +#define S3JniEnv_mutex_leave +#define S3JniGlobal_mutex_enter +#define S3JniGlobal_mutex_leave +#define S3JniHook_mutex_enter +#define S3JniHook_mutex_leave +#define S3JniNph_mutex_enter +#define S3JniNph_mutex_leave +#endif + +/* Helpers for jstring and jbyteArray. */ +static const char * s3jni__jstring_to_mutf8(JNIEnv * const env, jstring v ){ + const char *z = v ? (*env)->GetStringUTFChars(env, v, NULL) : 0; + s3jni_oom_check( v ? !!z : !z ); + return z; +} + +#define s3jni_jstring_to_mutf8(ARG) s3jni__jstring_to_mutf8(env, (ARG)) +#define s3jni_mutf8_release(ARG,VAR) if( VAR ) (*env)->ReleaseStringUTFChars(env, ARG, VAR) + +/* +** If jBA is not NULL then its GetByteArrayElements() value is +** returned. If jBA is not NULL and nBA is not NULL then *nBA is set +** to the GetArrayLength() of jBA. If GetByteArrayElements() requires +** an allocation and that allocation fails then this function either +** fails fatally or returns 0, depending on build-time options. + */ +static jbyte * s3jni__jbyteArray_bytes2(JNIEnv * const env, jbyteArray jBA, jsize * nBA ){ + jbyte * const rv = jBA ? (*env)->GetByteArrayElements(env, jBA, NULL) : 0; + s3jni_oom_check( jBA ? !!rv : 1 ); + if( jBA && nBA ) *nBA = (*env)->GetArrayLength(env, jBA); + return rv; +} + +#define s3jni_jbyteArray_bytes2(jByteArray,ptrToSz) \ + s3jni__jbyteArray_bytes2(env, (jByteArray), (ptrToSz)) +#define s3jni_jbyteArray_bytes(jByteArray) s3jni__jbyteArray_bytes2(env, (jByteArray), 0) +#define s3jni_jbyteArray_release(jByteArray,jBytes) \ + if( jBytes ) (*env)->ReleaseByteArrayElements(env, jByteArray, jBytes, JNI_ABORT) +#define s3jni_jbyteArray_commit(jByteArray,jBytes) \ + if( jBytes ) (*env)->ReleaseByteArrayElements(env, jByteArray, jBytes, JNI_COMMIT) + +/* +** Returns the current JNIEnv object. Fails fatally if it cannot find +** the object. +*/ +static JNIEnv * s3jni_env(void){ + JNIEnv * env = 0; + if( (*SJG.jvm)->GetEnv(SJG.jvm, (void **)&env, + JNI_VERSION_1_8) ){ + fprintf(stderr, "Fatal error: cannot get current JNIEnv.\n"); + abort(); + } + return env; +} + +/* +** Fetches the S3JniGlobal.envCache row for the given env, allocing a +** row if needed. When a row is allocated, its state is initialized +** insofar as possible. Calls (*env)->FatalError() if allocation of an +** entry fails. That's hypothetically possible but "shouldn't happen." +*/ +static S3JniEnv * S3JniEnv__get(JNIEnv * const env){ + struct S3JniEnv * row; + S3JniEnv_mutex_enter; + row = SJG.envCache.aHead; + for( ; row; row = row->pNext ){ + if( row->env == env ){ + s3jni_incr( &SJG.metrics.nEnvHit ); + S3JniEnv_mutex_leave; + return row; + } + } + s3jni_incr( &SJG.metrics.nEnvMiss ); + row = SJG.envCache.aFree; + if( row ){ + SJG.envCache.aFree = row->pNext; + }else{ + row = s3jni_malloc_or_die(env, sizeof(*row)); + s3jni_incr( &SJG.metrics.nEnvAlloc ); + } + memset(row, 0, sizeof(*row)); + row->pNext = SJG.envCache.aHead; + SJG.envCache.aHead = row; + row->env = env; + + S3JniEnv_mutex_leave; + return row; +} + +#define S3JniEnv_get() S3JniEnv__get(env) + +/* +** This function is NOT part of the sqlite3 public API. It is strictly +** for use by the sqlite project's own Java/JNI bindings. +** +** For purposes of certain hand-crafted JNI function bindings, we +** need a way of reporting errors which is consistent with the rest of +** the C API, as opposed to throwing Java exceptions. To that end, this +** internal-use-only function is a thin proxy around +** sqlite3ErrorWithMessage(). The intent is that it only be used from +** JNI bindings such as sqlite3_prepare_v2/v3(), and definitely not +** from client code. +** +** Returns err_code. +*/ +static int s3jni_db_error(sqlite3* const db, int err_code, + const char * const zMsg){ + if( db!=0 ){ + if( 0==zMsg ){ + sqlite3Error(db, err_code); + }else{ + const int nMsg = sqlite3Strlen30(zMsg); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); + sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); + } + } + return err_code; +} + +/* +** Creates a new jByteArray of length nP, copies p's contents into it, +** and returns that byte array (NULL on OOM unless fail-fast alloc +** errors are enabled). p may be NULL, in which case the array is +** created but no bytes are filled. +*/ +static jbyteArray s3jni__new_jbyteArray(JNIEnv * const env, + const void * const p, int nP){ + jbyteArray jba = (*env)->NewByteArray(env, (jint)nP); + + s3jni_oom_check( jba ); + if( jba && p ){ + (*env)->SetByteArrayRegion(env, jba, 0, (jint)nP, (const jbyte*)p); + } + return jba; +} + +#define s3jni_new_jbyteArray(P,n) s3jni__new_jbyteArray(env, P, n) + + +/* +** Uses the java.lang.String(byte[],Charset) constructor to create a +** new String from UTF-8 string z. n is the number of bytes to +** copy. If n<0 then sqlite3Strlen30() is used to calculate it. +** +** Returns NULL if z is NULL or on OOM, else returns a new jstring +** owned by the caller. +** +** Sidebar: this is a painfully inefficient way to convert from +** standard UTF-8 to a Java string, but JNI offers only algorithms for +** working with MUTF-8, not UTF-8. +*/ +static jstring s3jni__utf8_to_jstring(JNIEnv * const env, + const char * const z, int n){ + jstring rv = NULL; + if( 0==n || (n<0 && z && !z[0]) ){ + /* Fast-track the empty-string case via the MUTF-8 API. We could + hypothetically do this for any strings where n<4 and z is + NUL-terminated and none of z[0..3] are NUL bytes. */ + rv = (*env)->NewStringUTF(env, ""); + s3jni_oom_check( rv ); + }else if( z ){ + jbyteArray jba; + if( n<0 ) n = sqlite3Strlen30(z); + jba = s3jni_new_jbyteArray((unsigned const char *)z, n); + if( jba ){ + rv = (*env)->NewObject(env, SJG.g.cString, SJG.g.ctorStringBA, + jba, SJG.g.oCharsetUtf8); + S3JniIfThrew{ + S3JniExceptionReport; + S3JniExceptionClear; + } + S3JniUnrefLocal(jba); + } + s3jni_oom_check( rv ); + } + return rv; +} +#define s3jni_utf8_to_jstring(CStr,n) s3jni__utf8_to_jstring(env, CStr, n) + +/* +** Converts the given java.lang.String object into a NUL-terminated +** UTF-8 C-string by calling jstr.getBytes(StandardCharset.UTF_8). +** Returns NULL if jstr is NULL or on allocation error. If jstr is not +** NULL and nLen is not NULL then nLen is set to the length of the +** returned string, not including the terminating NUL. If jstr is not +** NULL and it returns NULL, this indicates an allocation error. In +** that case, if nLen is not NULL then it is either set to 0 (if +** fetching of jstr's bytes fails to allocate) or set to what would +** have been the length of the string had C-string allocation +** succeeded. +** +** The returned memory is allocated from sqlite3_malloc() and +** ownership is transferred to the caller. +*/ +static char * s3jni__jstring_to_utf8(JNIEnv * const env, + jstring jstr, int *nLen){ + jbyteArray jba; + jsize nBA; + char *rv; + + if( !jstr ) return 0; + jba = (*env)->CallObjectMethod(env, jstr, SJG.g.stringGetBytes, + SJG.g.oCharsetUtf8); + + if( (*env)->ExceptionCheck(env) || !jba + /* order of these checks is significant for -Xlint:jni */ ) { + S3JniExceptionReport; + s3jni_oom_check( jba ); + if( nLen ) *nLen = 0; + return 0; + } + nBA = (*env)->GetArrayLength(env, jba); + if( nLen ) *nLen = (int)nBA; + rv = s3jni_malloc( nBA + 1 ); + if( rv ){ + (*env)->GetByteArrayRegion(env, jba, 0, nBA, (jbyte*)rv); + rv[nBA] = 0; + } + S3JniUnrefLocal(jba); + return rv; +} +#define s3jni_jstring_to_utf8(JStr,n) s3jni__jstring_to_utf8(env, JStr, n) + +/* +** Expects to be passed a pointer from sqlite3_column_text16() or +** sqlite3_value_text16() and a byte-length value from +** sqlite3_column_bytes16() or sqlite3_value_bytes16(). It creates a +** Java String of exactly half that character length, returning NULL +** if !p or (*env)->NewString() fails. +*/ +static jstring s3jni_text16_to_jstring(JNIEnv * const env, const void * const p, int nP){ + jstring const rv = p + ? (*env)->NewString(env, (const jchar *)p, (jsize)(nP/2)) + : NULL; + s3jni_oom_check( p ? !!rv : 1 ); + return rv; +} + +/* +** Requires jx to be a Throwable. Calls its toString() method and +** returns its value converted to a UTF-8 string. The caller owns the +** returned string and must eventually sqlite3_free() it. Returns 0 +** if there is a problem fetching the info or on OOM. +** +** Design note: we use toString() instead of getMessage() because the +** former includes the exception type's name: +** +** Exception e = new RuntimeException("Hi"); +** System.out.println(e.toString()); // java.lang.RuntimeException: Hi +** System.out.println(e.getMessage()); // Hi +*/ +static char * s3jni_exception_error_msg(JNIEnv * const env, jthrowable jx){ + jmethodID mid; + jstring msg; + char * zMsg; + jclass const klazz = (*env)->GetObjectClass(env, jx); + mid = (*env)->GetMethodID(env, klazz, "toString", "()Ljava/lang/String;"); + S3JniUnrefLocal(klazz); + S3JniIfThrew{ + S3JniExceptionReport; + S3JniExceptionClear; + return 0; + } + msg = (*env)->CallObjectMethod(env, jx, mid); + S3JniIfThrew{ + S3JniExceptionReport; + S3JniExceptionClear; + return 0; + } + zMsg = s3jni_jstring_to_utf8( msg, 0); + S3JniUnrefLocal(msg); + return zMsg; +} + +/* +** Extracts env's current exception, sets ps->pDb's error message to +** its message string, and clears the exception. If errCode is non-0, +** it is used as-is, else SQLITE_ERROR is assumed. If there's a +** problem extracting the exception's message, it's treated as +** non-fatal and zDfltMsg is used in its place. +** +** Locks the global S3JniDb mutex. +** +** This must only be called if a JNI exception is pending. +** +** Returns errCode unless it is 0, in which case SQLITE_ERROR is +** returned. +*/ +static int s3jni__db_exception(JNIEnv * const env, sqlite3 * const pDb, + int errCode, const char *zDfltMsg){ + jthrowable const ex = (*env)->ExceptionOccurred(env); + + if( 0==errCode ) errCode = SQLITE_ERROR; + if( ex ){ + char * zMsg; + S3JniExceptionClear; + zMsg = s3jni_exception_error_msg(env, ex); + s3jni_db_error(pDb, errCode, zMsg ? zMsg : zDfltMsg); + sqlite3_free(zMsg); + S3JniUnrefLocal(ex); + }else if( zDfltMsg ){ + s3jni_db_error(pDb, errCode, zDfltMsg); + } + return errCode; +} +#define s3jni_db_exception(pDb,ERRCODE,DFLTMSG) \ + s3jni__db_exception(env, (pDb), (ERRCODE), (DFLTMSG) ) + +/* +** Extracts the (void xDestroy()) method from jObj and applies it to +** jObj. If jObj is NULL, this is a no-op. The lack of an xDestroy() +** method is silently ignored. Any exceptions thrown by xDestroy() +** trigger a warning to stdout or stderr and then the exception is +** suppressed. +*/ +static void s3jni__call_xDestroy(JNIEnv * const env, jobject jObj){ + if( jObj ){ + jclass const klazz = (*env)->GetObjectClass(env, jObj); + jmethodID method = (*env)->GetMethodID(env, klazz, "xDestroy", "()V"); + + S3JniUnrefLocal(klazz); + if( method ){ + s3jni_incr( &SJG.metrics.nDestroy ); + (*env)->CallVoidMethod(env, jObj, method); + S3JniIfThrew{ + S3JniExceptionWarnCallbackThrew("xDestroy() callback"); + S3JniExceptionClear; + } + }else{ + /* Non-fatal. */ + S3JniExceptionClear; + } + } +} +#define s3jni_call_xDestroy(JOBJ) s3jni__call_xDestroy(env, (JOBJ)) + +/* +** Internal helper for many hook callback impls. Locks the S3JniDb +** mutex, makes a copy of src into dest, with a some differences: (1) +** if src->jObj or src->jExtra are not NULL then dest will be a new +** LOCAL ref to it instead of a copy of the prior GLOBAL ref. (2) +** dest->doXDestroy is always false. +** +** If dest->jObj is not NULL when this returns then the caller is +** obligated to eventually free the new ref by passing *dest to +** S3JniHook_localundup(). The dest pointer must NOT be passed to +** S3JniHook_unref(), as that routine assumes that dest->jObj/jExtra +** are GLOBAL refs (it's illegal to try to unref the wrong ref type). +** +** Background: when running a hook we need a call-local copy lest +** another thread modify the hook while we're running it. That copy +** has to have its own Java reference, but it need only be call-local. +*/ +static void S3JniHook__localdup( JNIEnv * const env, S3JniHook const * const src, + S3JniHook * const dest ){ + S3JniHook_mutex_enter; + *dest = *src; + if(src->jObj) dest->jObj = S3JniRefLocal(src->jObj); + if(src->jExtra) dest->jExtra = S3JniRefLocal(src->jExtra); + dest->doXDestroy = 0; + S3JniHook_mutex_leave; +} +#define S3JniHook_localdup(src,dest) S3JniHook__localdup(env,src,dest) + +static void S3JniHook__localundup( JNIEnv * const env, S3JniHook * const h ){ + S3JniUnrefLocal(h->jObj); + S3JniUnrefLocal(h->jExtra); + *h = S3JniHook_empty; +} +#define S3JniHook_localundup(HOOK) S3JniHook__localundup(env, &(HOOK)) + +/* +** Removes any Java references from s and clears its state. If +** doXDestroy is true and s->jObj is not NULL, s->jObj +** is passed to s3jni_call_xDestroy() before any references are +** cleared. It is legal to call this when the object has no Java +** references. s must not be NULL. +*/ +static void S3JniHook__unref(JNIEnv * const env, S3JniHook * const s){ + if( s->jObj ){ + if( s->doXDestroy ){ + s3jni_call_xDestroy(s->jObj); + } + S3JniUnrefGlobal(s->jObj); + S3JniUnrefGlobal(s->jExtra); + }else{ + assert( !s->jExtra ); + } + *s = S3JniHook_empty; +} +#define S3JniHook_unref(hook) S3JniHook__unref(env, (hook)) + +/* +** Allocates one blank S3JniHook object from the recycling bin, if +** available, else from the heap. Returns NULL or dies on OOM, +** depending on build options. Locks on SJG.hooks.mutex. +*/ +static S3JniHook *S3JniHook__alloc(JNIEnv * const env){ + S3JniHook * p = 0; + S3JniHook_mutex_enter; + if( SJG.hook.aFree ){ + p = SJG.hook.aFree; + SJG.hook.aFree = p->pNext; + p->pNext = 0; + s3jni_incr(&SJG.metrics.nHookRecycled); + } + S3JniHook_mutex_leave; + if( 0==p ){ + p = s3jni_malloc(sizeof(S3JniHook)); + if( p ){ + s3jni_incr(&SJG.metrics.nHookAlloc); + } + } + if( p ){ + *p = S3JniHook_empty; + } + return p; +} +#define S3JniHook_alloc() S3JniHook__alloc(env) + +/* +** The rightful fate of all results from S3JniHook_alloc(). Locks on +** SJG.hook.mutex. +*/ +static void S3JniHook__free(JNIEnv * const env, S3JniHook * const p){ + if(p){ + assert( !p->pNext ); + S3JniHook_unref(p); + S3JniHook_mutex_enter; + p->pNext = SJG.hook.aFree; + SJG.hook.aFree = p; + S3JniHook_mutex_leave; + } +} +#define S3JniHook_free(hook) S3JniHook__free(env, hook) + +#if 0 +/* S3JniHook__free() without the lock: caller must hold the global mutex */ +static void S3JniHook__free_unlocked(JNIEnv * const env, S3JniHook * const p){ + if(p){ + assert( !p->pNext ); + assert( p->pNext != SJG.hook.aFree ); + S3JniHook_unref(p); + p->pNext = SJG.hook.aFree; + SJG.hook.aFree = p; + } +} +#define S3JniHook_free_unlocked(hook) S3JniHook__free_unlocked(env, hook) +#endif + +/* +** Clears all of s's state. Requires that that the caller has locked +** S3JniGlobal.perDb.mutex. Make sure to do anything needed with +** s->pNext and s->pPrev before calling this, as this clears them. +*/ +static void S3JniDb_clear(JNIEnv * const env, S3JniDb * const s){ + S3JniDb_mutex_assertLocker; + sqlite3_free( s->zMainDbName ); +#define UNHOOK(MEMBER) \ + S3JniHook_unref(&s->hooks.MEMBER) + UNHOOK(auth); + UNHOOK(busyHandler); + UNHOOK(collationNeeded); + UNHOOK(commit); + UNHOOK(progress); + UNHOOK(rollback); + UNHOOK(trace); + UNHOOK(update); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + UNHOOK(preUpdate); +#endif +#undef UNHOOK + S3JniUnrefGlobal(s->jDb); + memset(s, 0, sizeof(S3JniDb)); +} + +/* +** Clears s's state and moves it to the free-list. Requires that +** S3JniGlobal.perDb.mutex is locked. +*/ +static void S3JniDb__set_aside_unlocked(JNIEnv * const env, S3JniDb * const s){ + assert( s ); + S3JniDb_mutex_assertLocker; + if( s ){ + S3JniDb_clear(env, s); + s->pNext = SJG.perDb.aFree; + SJG.perDb.aFree = s; + } +} +#define S3JniDb_set_aside_unlocked(JniDb) S3JniDb__set_aside_unlocked(env, JniDb) + +static void S3JniDb__set_aside(JNIEnv * const env, S3JniDb * const s){ + S3JniDb_mutex_enter; + S3JniDb_set_aside_unlocked(s); + S3JniDb_mutex_leave; +} +#define S3JniDb_set_aside(JNIDB) S3JniDb__set_aside(env, JNIDB) + +/* +** Uncache any state for the given JNIEnv, clearing all Java +** references the cache owns. Returns true if env was cached and false +** if it was not found in the cache. Ownership of the S3JniEnv object +** associated with the given argument is transferred to this function, +** which makes it free for re-use. +** +** Requires that the env mutex be locked. +*/ +static int S3JniEnv_uncache(JNIEnv * const env){ + struct S3JniEnv * row; + struct S3JniEnv * pPrev = 0; + + S3JniEnv_mutex_assertLocked; + row = SJG.envCache.aHead; + for( ; row; pPrev = row, row = row->pNext ){ + if( row->env == env ){ + break; + } + } + if( !row ){ + return 0; + } + if( pPrev) pPrev->pNext = row->pNext; + else{ + assert( SJG.envCache.aHead == row ); + SJG.envCache.aHead = row->pNext; + } + memset(row, 0, sizeof(S3JniEnv)); + row->pNext = SJG.envCache.aFree; + SJG.envCache.aFree = row; + return 1; +} + +/* +** Fetches the given nph-ref from cache the cache and returns the +** object with its klazz member set. This is an O(1) operation except +** on the first call for a given pRef, during which pRef->klazz and +** pRef->pRef are initialized thread-safely. In the latter case it's +** still effectively O(1), but with a much longer 1. +** +** It is up to the caller to populate the other members of the +** returned object if needed, taking care to lock the modification +** with S3JniNph_mutex_enter/leave. +** +** This simple cache catches >99% of searches in the current +** (2023-07-31) tests. +*/ +static S3JniNphOp * s3jni__nphop(JNIEnv * const env, S3JniNphOp const* pRef){ + S3JniNphOp * const pNC = &SJG.nph.list[pRef->index]; + + assert( (void*)pRef>=(void*)&S3JniNphOps && (void*)pRef<(void*)(&S3JniNphOps + 1) + && "pRef is out of range" ); + assert( pRef->index>=0 + && (pRef->index < (sizeof(S3JniNphOps) / sizeof(S3JniNphOp))) + && "pRef->index is out of range" ); + if( !pNC->klazz ){ + S3JniNph_mutex_enter; + if( !pNC->klazz ){ + jclass const klazz = (*env)->FindClass(env, pRef->zName); + //printf("FindClass %s\n", pRef->zName); + S3JniExceptionIsFatal("FindClass() unexpectedly threw"); + pNC->klazz = S3JniRefGlobal(klazz); + } + S3JniNph_mutex_leave; + } + assert( pNC->klazz ); + return pNC; +} + +#define s3jni_nphop(PRef) s3jni__nphop(env, PRef) + +/* +** Common code for accessor functions for NativePointerHolder and +** OutputPointer types. pRef must be a pointer from S3JniNphOps. jOut +** must be an instance of that class (Java's type safety takes care of +** that requirement). If necessary, this fetches the jfieldID for +** jOut's pRef->zMember, which must be of the type represented by the +** JNI type signature pRef->zTypeSig, and stores it in +** S3JniGlobal.nph.list[pRef->index]. Fails fatally if the pRef->zMember +** property is not found, as that presents a serious internal misuse. +** +** Property lookups are cached on a per-pRef basis. +*/ +static jfieldID s3jni_nphop_field(JNIEnv * const env, S3JniNphOp const* pRef){ + S3JniNphOp * const pNC = s3jni_nphop(pRef); + + if( !pNC->fidValue ){ + S3JniNph_mutex_enter; + if( !pNC->fidValue ){ + pNC->fidValue = (*env)->GetFieldID(env, pNC->klazz, + pRef->zMember, pRef->zTypeSig); + S3JniExceptionIsFatal("Code maintenance required: missing " + "required S3JniNphOp::fidValue."); + } + S3JniNph_mutex_leave; + } + assert( pNC->fidValue ); + return pNC->fidValue; +} + +/* +** Sets a native ptr value in NativePointerHolder object jNph, +** which must be of the native type described by pRef. jNph +** may not be NULL. +*/ +static void NativePointerHolder__set(JNIEnv * const env, S3JniNphOp const* pRef, + jobject jNph, const void * p){ + assert( jNph ); + (*env)->SetLongField(env, jNph, s3jni_nphop_field(env, pRef), + S3JniCast_P2L(p)); + S3JniExceptionIsFatal("Could not set NativePointerHolder.nativePointer."); +} + +#define NativePointerHolder_set(PREF,JNPH,P) \ + NativePointerHolder__set(env, PREF, JNPH, P) + +/* +** Fetches a native ptr value from NativePointerHolder object jNph, +** which must be of the native type described by pRef. This is a +** no-op if jNph is NULL. +*/ +static void * NativePointerHolder__get(JNIEnv * env, jobject jNph, + S3JniNphOp const* pRef){ + void * rv = 0; + if( jNph ){ + rv = S3JniCast_L2P( + (*env)->GetLongField(env, jNph, s3jni_nphop_field(env, pRef)) + ); + S3JniExceptionIsFatal("Cannot fetch NativePointerHolder.nativePointer."); + } + return rv; +} + +#define NativePointerHolder_get(JOBJ,NPHREF) \ + NativePointerHolder__get(env, (JOBJ), (NPHREF)) + +/* +** Helpers for extracting pointers from jobjects, noting that we rely +** on the corresponding Java interfaces having already done the +** type-checking. OBJ must be a jobject referring to a +** NativePointerHolder, where T matches PtrGet_T. Don't use these +** in contexts where that's not the case. Note that these aren't +** type-safe in the strictest sense: +** +** sqlite3 * s = PtrGet_sqlite3_stmt(...) +** +** will work, despite the incorrect macro name, so long as the +** argument is a Java sqlite3 object, as this operation only has void +** pointers to work with. +*/ +#define PtrGet_T(T,OBJ) (T*)NativePointerHolder_get(OBJ, S3JniNph(T)) +#define PtrGet_sqlite3(OBJ) PtrGet_T(sqlite3, OBJ) +#define PtrGet_sqlite3_backup(OBJ) PtrGet_T(sqlite3_backup, OBJ) +#define PtrGet_sqlite3_blob(OBJ) PtrGet_T(sqlite3_blob, OBJ) +#define PtrGet_sqlite3_context(OBJ) PtrGet_T(sqlite3_context, OBJ) +#define PtrGet_sqlite3_stmt(OBJ) PtrGet_T(sqlite3_stmt, OBJ) +#define PtrGet_sqlite3_value(OBJ) PtrGet_T(sqlite3_value, OBJ) +/* +** S3JniLongPtr_T(X,Y) expects X to be an unqualified sqlite3 struct +** type name and Y to be a native pointer to such an object in the +** form of a jlong value. The jlong is simply cast to (X*). This +** approach is, as of 2023-09-27, supplanting the former approach. We +** now do the native pointer extraction in the Java side, rather than +** the C side, because it's reportedly significantly faster. The +** intptr_t part here is necessary for compatibility with (at least) +** ARM32. +*/ +#define S3JniLongPtr_T(T,JLongAsPtr) (T*)((intptr_t)(JLongAsPtr)) +#define S3JniLongPtr_sqlite3(JLongAsPtr) S3JniLongPtr_T(sqlite3,JLongAsPtr) +#define S3JniLongPtr_sqlite3_backup(JLongAsPtr) S3JniLongPtr_T(sqlite3_backup,JLongAsPtr) +#define S3JniLongPtr_sqlite3_blob(JLongAsPtr) S3JniLongPtr_T(sqlite3_blob,JLongAsPtr) +#define S3JniLongPtr_sqlite3_stmt(JLongAsPtr) S3JniLongPtr_T(sqlite3_stmt,JLongAsPtr) +#define S3JniLongPtr_sqlite3_value(JLongAsPtr) S3JniLongPtr_T(sqlite3_value,JLongAsPtr) +/* +** Extracts the new S3JniDb instance from the free-list, or allocates +** one if needed, associates it with pDb, and returns. Returns NULL +** on OOM. The returned object MUST, on success of the calling +** operation, subsequently be associated with jDb via +** NativePointerHolder_set() or freed using S3JniDb_set_aside(). +*/ +static S3JniDb * S3JniDb_alloc(JNIEnv * const env, jobject jDb){ + S3JniDb * rv = 0; + S3JniDb_mutex_enter; + if( SJG.perDb.aFree ){ + rv = SJG.perDb.aFree; + SJG.perDb.aFree = rv->pNext; + rv->pNext = 0; + s3jni_incr( &SJG.metrics.nPdbRecycled ); + } + S3JniDb_mutex_leave; + if( 0==rv ){ + rv = s3jni_malloc(sizeof(S3JniDb)); + if( rv ){ + s3jni_incr( &SJG.metrics.nPdbAlloc ); + } + } + if( rv ){ + memset(rv, 0, sizeof(S3JniDb)); + rv->jDb = S3JniRefGlobal(jDb); + } + return rv; +} + +/* +** Returns the S3JniDb object for the given org.sqlite.jni.capi.sqlite3 +** object, or NULL if jDb is NULL, no pointer can be extracted +** from it, or no matching entry can be found. +*/ +static S3JniDb * S3JniDb__from_java(JNIEnv * const env, jobject jDb){ + sqlite3 * const pDb = jDb ? PtrGet_sqlite3(jDb) : 0; + return pDb ? S3JniDb_from_clientdata(pDb) : 0; +} +#define S3JniDb_from_java(jObject) S3JniDb__from_java(env,(jObject)) + +/* +** S3JniDb finalizer for use with sqlite3_set_clientdata(). +*/ +static void S3JniDb_xDestroy(void *p){ + S3JniDeclLocal_env; + S3JniDb * const ps = p; + assert( !ps->pNext && "Else ps is already in the free-list."); + S3JniDb_set_aside(ps); +} + +/* +** Evaluates to the S3JniDb object for the given sqlite3 object, or +** NULL if pDb is NULL or was not initialized via the JNI interfaces. +*/ +#define S3JniDb_from_c(sqlite3Ptr) \ + ((sqlite3Ptr) ? S3JniDb_from_clientdata(sqlite3Ptr) : 0) +#define S3JniDb_from_jlong(sqlite3PtrAsLong) \ + S3JniDb_from_c(S3JniLongPtr_T(sqlite3,sqlite3PtrAsLong)) + +/* +** Unref any Java-side state in (S3JniAutoExtension*) AX and zero out +** AX. +*/ +#define S3JniAutoExtension_clear(AX) S3JniHook_unref(AX); + +/* +** Initializes a pre-allocated S3JniAutoExtension object. Returns +** non-0 if there is an error collecting the required state from +** jAutoExt (which must be an AutoExtensionCallback object). On error, +** it passes ax to S3JniAutoExtension_clear(). +*/ +static int S3JniAutoExtension_init(JNIEnv *const env, + S3JniAutoExtension * const ax, + jobject const jAutoExt){ + jclass const klazz = (*env)->GetObjectClass(env, jAutoExt); + + S3JniAutoExt_mutex_assertLocker; + *ax = S3JniHook_empty; + ax->midCallback = (*env)->GetMethodID(env, klazz, "call", + "(Lorg/sqlite/jni/capi/sqlite3;)I"); + S3JniUnrefLocal(klazz); + S3JniExceptionWarnIgnore; + if( !ax->midCallback ){ + S3JniAutoExtension_clear(ax); + return SQLITE_ERROR; + } + ax->jObj = S3JniRefGlobal(jAutoExt); + return 0; +} + +/* +** Sets the value property of the OutputPointer.Bool jOut object to +** v. +*/ +static void OutputPointer_set_Bool(JNIEnv * const env, jobject const jOut, + int v){ + (*env)->SetBooleanField(env, jOut, s3jni_nphop_field( + env, S3JniNph(OutputPointer_Bool) + ), v ? JNI_TRUE : JNI_FALSE ); + S3JniExceptionIsFatal("Cannot set OutputPointer.Bool.value"); +} + +/* +** Sets the value property of the OutputPointer.Int32 jOut object to +** v. +*/ +static void OutputPointer_set_Int32(JNIEnv * const env, jobject const jOut, + int v){ + (*env)->SetIntField(env, jOut, s3jni_nphop_field( + env, S3JniNph(OutputPointer_Int32) + ), (jint)v); + S3JniExceptionIsFatal("Cannot set OutputPointer.Int32.value"); +} + +/* +** Sets the value property of the OutputPointer.Int64 jOut object to +** v. +*/ +static void OutputPointer_set_Int64(JNIEnv * const env, jobject const jOut, + jlong v){ + (*env)->SetLongField(env, jOut, s3jni_nphop_field( + env, S3JniNph(OutputPointer_Int64) + ), v); + S3JniExceptionIsFatal("Cannot set OutputPointer.Int64.value"); +} + +/* +** Internal helper for OutputPointer_set_TYPE() where TYPE is an +** Object type. +*/ +static void OutputPointer_set_obj(JNIEnv * const env, + S3JniNphOp const * const pRef, + jobject const jOut, + jobject v){ + (*env)->SetObjectField(env, jOut, s3jni_nphop_field(env, pRef), v); + S3JniExceptionIsFatal("Cannot set OutputPointer.T.value"); +} + +#ifdef SQLITE_ENABLE_FTS5 +#if 0 +/* +** Sets the value property of the OutputPointer.ByteArray jOut object +** to v. +*/ +static void OutputPointer_set_ByteArray(JNIEnv * const env, jobject const jOut, + jbyteArray const v){ + OutputPointer_set_obj(env, S3JniNph(OutputPointer_ByteArray), jOut, v); +} +#endif +#endif /* SQLITE_ENABLE_FTS5 */ + +/* +** Sets the value property of the OutputPointer.String jOut object to +** v. +*/ +static void OutputPointer_set_String(JNIEnv * const env, jobject const jOut, + jstring const v){ + OutputPointer_set_obj(env, S3JniNph(OutputPointer_String), jOut, v); +} + +/* +** Returns true if eTextRep is a valid sqlite3 encoding constant, else +** returns false. +*/ +static int encodingTypeIsValid(int eTextRep){ + switch( eTextRep ){ + case SQLITE_UTF8: case SQLITE_UTF16: + case SQLITE_UTF16LE: case SQLITE_UTF16BE: + return 1; + default: + return 0; + } +} + +/* For use with sqlite3_result/value_pointer() */ +static const char * const ResultJavaValuePtrStr = "org.sqlite.jni.capi.ResultJavaVal"; + +/* +** If v is not NULL, it must be a jobject global reference. Its +** reference is relinquished. +*/ +static void S3Jni_jobject_finalizer(void *v){ + if( v ){ + S3JniDeclLocal_env; + S3JniUnrefGlobal((jobject)v); + } +} + +/* +** Returns a new Java instance of the class referred to by pRef, which +** MUST be interface-compatible with NativePointerHolder and MUST have +** a no-arg constructor. The NativePointerHolder_set() method is +** passed the new Java object (which must not be NULL) and pNative +** (which may be NULL). Hypothetically returns NULL if Java fails to +** allocate, but the JNI docs are not entirely clear on that detail. +** +** Always use a static pointer from the S3JniNphOps struct for the +** 2nd argument. +*/ +static jobject NativePointerHolder_new(JNIEnv * const env, + S3JniNphOp const * pRef, + const void * pNative){ + jobject rv = 0; + S3JniNphOp * const pNC = s3jni_nphop(pRef); + if( !pNC->midCtor ){ + S3JniNph_mutex_enter; + if( !pNC->midCtor ){ + pNC->midCtor = (*env)->GetMethodID(env, pNC->klazz, "", "()V"); + S3JniExceptionIsFatal("Cannot find constructor for class."); + } + S3JniNph_mutex_leave; + } + rv = (*env)->NewObject(env, pNC->klazz, pNC->midCtor); + S3JniExceptionIsFatal("No-arg constructor threw."); + s3jni_oom_check(rv); + if( rv ) NativePointerHolder_set(pRef, rv, pNative); + return rv; +} + +static inline jobject new_java_sqlite3(JNIEnv * const env, sqlite3 *sv){ + return NativePointerHolder_new(env, S3JniNph(sqlite3), sv); +} +static inline jobject new_java_sqlite3_backup(JNIEnv * const env, sqlite3_backup *sv){ + return NativePointerHolder_new(env, S3JniNph(sqlite3_backup), sv); +} +static inline jobject new_java_sqlite3_blob(JNIEnv * const env, sqlite3_blob *sv){ + return NativePointerHolder_new(env, S3JniNph(sqlite3_blob), sv); +} +static inline jobject new_java_sqlite3_context(JNIEnv * const env, sqlite3_context *sv){ + return NativePointerHolder_new(env, S3JniNph(sqlite3_context), sv); +} +static inline jobject new_java_sqlite3_stmt(JNIEnv * const env, sqlite3_stmt *sv){ + return NativePointerHolder_new(env, S3JniNph(sqlite3_stmt), sv); +} +static inline jobject new_java_sqlite3_value(JNIEnv * const env, sqlite3_value *sv){ + return NativePointerHolder_new(env, S3JniNph(sqlite3_value), sv); +} + +/* Helper typedefs for UDF callback types. */ +typedef void (*udf_xFunc_f)(sqlite3_context*,int,sqlite3_value**); +typedef void (*udf_xStep_f)(sqlite3_context*,int,sqlite3_value**); +typedef void (*udf_xFinal_f)(sqlite3_context*); +/*typedef void (*udf_xValue_f)(sqlite3_context*);*/ +/*typedef void (*udf_xInverse_f)(sqlite3_context*,int,sqlite3_value**);*/ + +/* +** Allocate a new S3JniUdf (User-defined Function) and associate it +** with the SQLFunction-type jObj. Returns NULL on OOM. If the +** returned object's type==UDF_UNKNOWN_TYPE then the type of UDF was +** not unambiguously detected based on which callback members it has, +** which falls into the category of user error. +** +** The caller must arrange for the returned object to eventually be +** passed to S3JniUdf_free(). +*/ +static S3JniUdf * S3JniUdf_alloc(JNIEnv * const env, jobject jObj){ + S3JniUdf * s = 0; + + S3JniGlobal_mutex_enter; + s3jni_incr(&SJG.metrics.nMutexUdf); + if( SJG.udf.aFree ){ + s = SJG.udf.aFree; + SJG.udf.aFree = s->pNext; + s->pNext = 0; + s3jni_incr(&SJG.metrics.nUdfRecycled); + } + S3JniGlobal_mutex_leave; + if( !s ){ + s = s3jni_malloc( sizeof(*s)); + s3jni_incr(&SJG.metrics.nUdfAlloc); + } + if( s ){ + const char * zFSI = /* signature for xFunc, xStep, xInverse */ + "(Lorg/sqlite/jni/capi/sqlite3_context;[Lorg/sqlite/jni/capi/sqlite3_value;)V"; + const char * zFV = /* signature for xFinal, xValue */ + "(Lorg/sqlite/jni/capi/sqlite3_context;)V"; + jclass const klazz = (*env)->GetObjectClass(env, jObj); + + memset(s, 0, sizeof(*s)); + s->jObj = S3JniRefGlobal(jObj); + +#define FGET(FuncName,FuncSig,Field) \ + s->Field = (*env)->GetMethodID(env, klazz, FuncName, FuncSig); \ + if( !s->Field ) (*env)->ExceptionClear(env) + + FGET("xFunc", zFSI, jmidxFunc); + FGET("xStep", zFSI, jmidxStep); + FGET("xFinal", zFV, jmidxFinal); + FGET("xValue", zFV, jmidxValue); + FGET("xInverse", zFSI, jmidxInverse); +#undef FGET + + S3JniUnrefLocal(klazz); + if( s->jmidxFunc ) s->type = UDF_SCALAR; + else if( s->jmidxStep && s->jmidxFinal ){ + s->type = (s->jmidxValue && s->jmidxInverse) + ? UDF_WINDOW : UDF_AGGREGATE; + }else{ + s->type = UDF_UNKNOWN_TYPE; + } + } + return s; +} + +/* +** Frees up all resources owned by s, clears its state, then either +** caches it for reuse (if cacheIt is true) or frees it. The former +** requires locking the global mutex, so it must not be held when this +** is called. +*/ +static void S3JniUdf_free(JNIEnv * const env, S3JniUdf * const s, + int cacheIt){ + assert( !s->pNext ); + if( s->jObj ){ + s3jni_call_xDestroy(s->jObj); + S3JniUnrefGlobal(s->jObj); + sqlite3_free(s->zFuncName); + assert( !s->pNext ); + memset(s, 0, sizeof(*s)); + } + if( cacheIt ){ + S3JniGlobal_mutex_enter; + s->pNext = S3JniGlobal.udf.aFree; + S3JniGlobal.udf.aFree = s; + S3JniGlobal_mutex_leave; + }else{ + sqlite3_free( s ); + } +} + +/* Finalizer for sqlite3_create_function() and friends. */ +static void S3JniUdf_finalizer(void * s){ + S3JniUdf_free(s3jni_env(), (S3JniUdf*)s, 1); +} + +/* +** Helper for processing args to UDF handlers with signature +** (sqlite3_context*,int,sqlite3_value**). +*/ +typedef struct { + jobject jcx /* sqlite3_context */; + jobjectArray jargv /* sqlite3_value[] */; +} udf_jargs; + +/* +** Converts the given (cx, argc, argv) into arguments for the given +** UDF, writing the result (Java wrappers for cx and argv) in the +** final 2 arguments. Returns 0 on success, SQLITE_NOMEM on allocation +** error. On error *jCx and *jArgv will be set to 0. The output +** objects are of type org.sqlite.jni.capi.sqlite3_context and +** array-of-org.sqlite.jni.capi.sqlite3_value, respectively. +*/ +static int udf_args(JNIEnv *env, + sqlite3_context * const cx, + int argc, sqlite3_value**argv, + jobject * jCx, jobjectArray *jArgv){ + jobjectArray ja = 0; + jobject jcx = new_java_sqlite3_context(env, cx); + jint i; + *jCx = 0; + *jArgv = 0; + if( !jcx ) goto error_oom; + ja = (*env)->NewObjectArray( + env, argc, s3jni_nphop(S3JniNph(sqlite3_value))->klazz, + NULL); + s3jni_oom_check( ja ); + if( !ja ) goto error_oom; + for(i = 0; i < argc; ++i){ + jobject jsv = new_java_sqlite3_value(env, argv[i]); + if( !jsv ) goto error_oom; + (*env)->SetObjectArrayElement(env, ja, i, jsv); + S3JniUnrefLocal(jsv)/*ja has a ref*/; + } + *jCx = jcx; + *jArgv = ja; + return 0; +error_oom: + S3JniUnrefLocal(jcx); + S3JniUnrefLocal(ja); + return SQLITE_NOMEM; +} + +/* +** Requires that jCx and jArgv are sqlite3_context +** resp. array-of-sqlite3_value values initialized by udf_args(). This +** function zeroes out the nativePointer member of jCx and each entry +** in jArgv. This is a safety-net precaution to avoid undefined +** behavior if a Java-side UDF holds a reference to one of its +** arguments. This MUST be called from any function which successfully +** calls udf_args(), after calling the corresponding UDF and checking +** its exception status. It MUST NOT be called in any other case. +*/ +static void udf_unargs(JNIEnv *env, jobject jCx, int argc, jobjectArray jArgv){ + int i = 0; + assert(jCx); + NativePointerHolder_set(S3JniNph(sqlite3_context), jCx, 0); + for( ; i < argc; ++i ){ + jobject jsv = (*env)->GetObjectArrayElement(env, jArgv, i); + assert(jsv); + NativePointerHolder_set(S3JniNph(sqlite3_value), jsv, 0); + } +} + + +/* +** Must be called immediately after a Java-side UDF callback throws. +** If translateToErr is true then it sets the exception's message in +** the result error using sqlite3_result_error(). If translateToErr is +** false then it emits a warning that the function threw but should +** not do so. In either case, it clears the exception state. +** +** Returns SQLITE_NOMEM if an allocation fails, else SQLITE_ERROR. In +** the former case it calls sqlite3_result_error_nomem(). +*/ +static int udf_report_exception(JNIEnv * const env, int translateToErr, + sqlite3_context * cx, + const char *zFuncName, const char *zFuncType ){ + jthrowable const ex = (*env)->ExceptionOccurred(env); + int rc = SQLITE_ERROR; + + assert(ex && "This must only be called when a Java exception is pending."); + if( translateToErr ){ + char * zMsg; + char * z; + + S3JniExceptionClear; + zMsg = s3jni_exception_error_msg(env, ex); + z = sqlite3_mprintf("Client-defined SQL function %s.%s() threw: %s", + zFuncName ? zFuncName : "", zFuncType, + zMsg ? zMsg : "Unknown exception" ); + sqlite3_free(zMsg); + if( z ){ + sqlite3_result_error(cx, z, -1); + sqlite3_free(z); + }else{ + sqlite3_result_error_nomem(cx); + rc = SQLITE_NOMEM; + } + }else{ + S3JniExceptionWarnCallbackThrew("client-defined SQL function"); + S3JniExceptionClear; + } + S3JniUnrefLocal(ex); + return rc; +} + +/* +** Sets up the state for calling a Java-side xFunc/xStep/xInverse() +** UDF, calls it, and returns 0 on success. +*/ +static int udf_xFSI(sqlite3_context* const pCx, int argc, + sqlite3_value** const argv, S3JniUdf * const s, + jmethodID xMethodID, const char * const zFuncType){ + S3JniDeclLocal_env; + udf_jargs args = {0,0}; + int rc = udf_args(env, pCx, argc, argv, &args.jcx, &args.jargv); + + if( 0 == rc ){ + (*env)->CallVoidMethod(env, s->jObj, xMethodID, args.jcx, args.jargv); + S3JniIfThrew{ + rc = udf_report_exception(env, 'F'==zFuncType[1]/*xFunc*/, pCx, + s->zFuncName, zFuncType); + } + udf_unargs(env, args.jcx, argc, args.jargv); + } + S3JniUnrefLocal(args.jcx); + S3JniUnrefLocal(args.jargv); + return rc; +} + +/* +** Sets up the state for calling a Java-side xFinal/xValue() UDF, +** calls it, and returns 0 on success. +*/ +static int udf_xFV(sqlite3_context* cx, S3JniUdf * s, + jmethodID xMethodID, + const char *zFuncType){ + S3JniDeclLocal_env; + jobject jcx = new_java_sqlite3_context(env, cx); + int rc = 0; + int const isFinal = 'F'==zFuncType[1]/*xFinal*/; + + if( jcx ){ + (*env)->CallVoidMethod(env, s->jObj, xMethodID, jcx); + S3JniIfThrew{ + rc = udf_report_exception(env, isFinal, cx, s->zFuncName, + zFuncType); + } + S3JniUnrefLocal(jcx); + }else{ + if( isFinal ) sqlite3_result_error_nomem(cx); + rc = SQLITE_NOMEM; + } + return rc; +} + +/* Proxy for C-to-Java xFunc. */ +static void udf_xFunc(sqlite3_context* cx, int argc, + sqlite3_value** argv){ + S3JniUdf * const s = (S3JniUdf*)sqlite3_user_data(cx); + s3jni_incr( &SJG.metrics.udf.nFunc ); + udf_xFSI(cx, argc, argv, s, s->jmidxFunc, "xFunc"); +} +/* Proxy for C-to-Java xStep. */ +static void udf_xStep(sqlite3_context* cx, int argc, + sqlite3_value** argv){ + S3JniUdf * const s = (S3JniUdf*)sqlite3_user_data(cx); + s3jni_incr( &SJG.metrics.udf.nStep ); + udf_xFSI(cx, argc, argv, s, s->jmidxStep, "xStep"); +} +/* Proxy for C-to-Java xFinal. */ +static void udf_xFinal(sqlite3_context* cx){ + S3JniUdf * const s = (S3JniUdf*)sqlite3_user_data(cx); + s3jni_incr( &SJG.metrics.udf.nFinal ); + udf_xFV(cx, s, s->jmidxFinal, "xFinal"); +} +/* Proxy for C-to-Java xValue. */ +static void udf_xValue(sqlite3_context* cx){ + S3JniUdf * const s = (S3JniUdf*)sqlite3_user_data(cx); + s3jni_incr( &SJG.metrics.udf.nValue ); + udf_xFV(cx, s, s->jmidxValue, "xValue"); +} +/* Proxy for C-to-Java xInverse. */ +static void udf_xInverse(sqlite3_context* cx, int argc, + sqlite3_value** argv){ + S3JniUdf * const s = (S3JniUdf*)sqlite3_user_data(cx); + s3jni_incr( &SJG.metrics.udf.nInverse ); + udf_xFSI(cx, argc, argv, s, s->jmidxInverse, "xInverse"); +} + + +//////////////////////////////////////////////////////////////////////// +// What follows is the JNI/C bindings. They are in alphabetical order +// except for this macro-generated subset which are kept together +// (alphabetized) here at the front... +//////////////////////////////////////////////////////////////////////// + +/** Create a trivial JNI wrapper for (int CName(void)). */ +#define WRAP_INT_VOID(JniNameSuffix,CName) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass){ \ + return (jint)CName(); \ + } +/** Create a trivial JNI wrapper for (int CName(int)). */ +#define WRAP_INT_INT(JniNameSuffix,CName) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jint arg){ \ + return (jint)CName((int)arg); \ + } +/* +** Create a trivial JNI wrapper for (const mutf8_string * +** CName(void)). This is only valid for functions which are known to +** return ASCII or text which is equivalent in UTF-8 and MUTF-8. +*/ +#define WRAP_MUTF8_VOID(JniNameSuffix,CName) \ + JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass){ \ + jstring const rv = (*env)->NewStringUTF( env, CName() ); \ + s3jni_oom_check(rv); \ + return rv; \ + } +/** Create a trivial JNI wrapper for (int CName(sqlite3_stmt*)). */ +#define WRAP_INT_STMT(JniNameSuffix,CName) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpStmt){ \ + return (jint)CName(S3JniLongPtr_sqlite3_stmt(jpStmt)); \ + } +/** Create a trivial JNI wrapper for (int CName(sqlite3_stmt*,int)). */ +#define WRAP_INT_STMT_INT(JniNameSuffix,CName) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpStmt, jint n){ \ + return (jint)CName(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)n); \ + } +/** Create a trivial JNI wrapper for (boolean CName(sqlite3_stmt*)). */ +#define WRAP_BOOL_STMT(JniNameSuffix,CName) \ + JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jobject jStmt){ \ + return CName(PtrGet_sqlite3_stmt(jStmt)) ? JNI_TRUE : JNI_FALSE; \ + } +/** Create a trivial JNI wrapper for (jstring CName(sqlite3_stmt*,int)). */ +#define WRAP_STR_STMT_INT(JniNameSuffix,CName) \ + JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jlong jpStmt, jint ndx){ \ + return s3jni_utf8_to_jstring( \ + CName(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx), \ + -1); \ + } +/** Create a trivial JNI wrapper for (boolean CName(sqlite3*)). */ +#define WRAP_BOOL_DB(JniNameSuffix,CName) \ + JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \ + return CName(S3JniLongPtr_sqlite3(jpDb)) ? JNI_TRUE : JNI_FALSE; \ + } +/** Create a trivial JNI wrapper for (int CName(sqlite3*)). */ +#define WRAP_INT_DB(JniNameSuffix,CName) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \ + return (jint)CName(S3JniLongPtr_sqlite3(jpDb)); \ + } +/** Create a trivial JNI wrapper for (int64 CName(sqlite3*)). */ +#define WRAP_INT64_DB(JniNameSuffix,CName) \ + JniDecl(jlong,JniNameSuffix)(JniArgsEnvClass, jlong jpDb){ \ + return (jlong)CName(S3JniLongPtr_sqlite3(jpDb)); \ + } +/** Create a trivial JNI wrapper for (jstring CName(sqlite3*,int)). */ +#define WRAP_STR_DB_INT(JniNameSuffix,CName) \ + JniDecl(jstring,JniNameSuffix)(JniArgsEnvClass, jlong jpDb, jint ndx){ \ + return s3jni_utf8_to_jstring( \ + CName(S3JniLongPtr_sqlite3(jpDb), (int)ndx), \ + -1); \ + } +/** Create a trivial JNI wrapper for (int CName(sqlite3_value*)). */ +#define WRAP_INT_SVALUE(JniNameSuffix,CName,DfltOnNull) \ + JniDecl(jint,JniNameSuffix)(JniArgsEnvClass, jlong jpSValue){ \ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSValue); \ + return (jint)(sv ? CName(sv): DfltOnNull); \ + } +/** Create a trivial JNI wrapper for (boolean CName(sqlite3_value*)). */ +#define WRAP_BOOL_SVALUE(JniNameSuffix,CName,DfltOnNull) \ + JniDecl(jboolean,JniNameSuffix)(JniArgsEnvClass, jlong jpSValue){ \ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSValue); \ + return (jint)(sv ? CName(sv) : DfltOnNull) \ + ? JNI_TRUE : JNI_FALSE; \ + } + +WRAP_INT_DB(1changes, sqlite3_changes) +WRAP_INT64_DB(1changes64, sqlite3_changes64) +WRAP_INT_STMT(1clear_1bindings, sqlite3_clear_bindings) +WRAP_INT_STMT_INT(1column_1bytes, sqlite3_column_bytes) +WRAP_INT_STMT_INT(1column_1bytes16, sqlite3_column_bytes16) +WRAP_INT_STMT(1column_1count, sqlite3_column_count) +WRAP_STR_STMT_INT(1column_1decltype, sqlite3_column_decltype) +WRAP_STR_STMT_INT(1column_1name, sqlite3_column_name) +WRAP_STR_STMT_INT(1column_1database_1name, sqlite3_column_database_name) +WRAP_STR_STMT_INT(1column_1origin_1name, sqlite3_column_origin_name) +WRAP_STR_STMT_INT(1column_1table_1name, sqlite3_column_table_name) +WRAP_INT_STMT_INT(1column_1type, sqlite3_column_type) +WRAP_INT_STMT(1data_1count, sqlite3_data_count) +WRAP_STR_DB_INT(1db_1name, sqlite3_db_name) +WRAP_INT_DB(1error_1offset, sqlite3_error_offset) +WRAP_INT_DB(1extended_1errcode, sqlite3_extended_errcode) +WRAP_BOOL_DB(1get_1autocommit, sqlite3_get_autocommit) +WRAP_MUTF8_VOID(1libversion, sqlite3_libversion) +WRAP_INT_VOID(1libversion_1number, sqlite3_libversion_number) +WRAP_INT_VOID(1keyword_1count, sqlite3_keyword_count) +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +WRAP_INT_DB(1preupdate_1blobwrite, sqlite3_preupdate_blobwrite) +WRAP_INT_DB(1preupdate_1count, sqlite3_preupdate_count) +WRAP_INT_DB(1preupdate_1depth, sqlite3_preupdate_depth) +#endif +WRAP_INT_INT(1release_1memory, sqlite3_release_memory) +WRAP_INT_INT(1sleep, sqlite3_sleep) +WRAP_MUTF8_VOID(1sourceid, sqlite3_sourceid) +WRAP_BOOL_STMT(1stmt_1busy, sqlite3_stmt_busy) +WRAP_INT_STMT_INT(1stmt_1explain, sqlite3_stmt_explain) +WRAP_INT_STMT(1stmt_1isexplain, sqlite3_stmt_isexplain) +WRAP_BOOL_STMT(1stmt_1readonly, sqlite3_stmt_readonly) +WRAP_INT_DB(1system_1errno, sqlite3_system_errno) +WRAP_INT_VOID(1threadsafe, sqlite3_threadsafe) +WRAP_INT_DB(1total_1changes, sqlite3_total_changes) +WRAP_INT64_DB(1total_1changes64, sqlite3_total_changes64) +WRAP_INT_SVALUE(1value_1encoding, sqlite3_value_encoding,SQLITE_UTF8) +WRAP_BOOL_SVALUE(1value_1frombind, sqlite3_value_frombind,0) +WRAP_INT_SVALUE(1value_1nochange, sqlite3_value_nochange,0) +WRAP_INT_SVALUE(1value_1numeric_1type, sqlite3_value_numeric_type,SQLITE_NULL) +WRAP_INT_SVALUE(1value_1subtype, sqlite3_value_subtype,0) +WRAP_INT_SVALUE(1value_1type, sqlite3_value_type,SQLITE_NULL) + +#undef WRAP_BOOL_DB +#undef WRAP_BOOL_STMT +#undef WRAP_BOOL_SVALUE +#undef WRAP_INT64_DB +#undef WRAP_INT_DB +#undef WRAP_INT_INT +#undef WRAP_INT_STMT +#undef WRAP_INT_STMT_INT +#undef WRAP_INT_SVALUE +#undef WRAP_INT_VOID +#undef WRAP_MUTF8_VOID +#undef WRAP_STR_STMT_INT +#undef WRAP_STR_DB_INT + +S3JniApi(sqlite3_aggregate_context(),jlong,1aggregate_1context)( + JniArgsEnvClass, jobject jCx, jboolean initialize +){ + sqlite3_context * const pCx = PtrGet_sqlite3_context(jCx); + void * const p = pCx + ? sqlite3_aggregate_context(pCx, (int)(initialize + ? (int)sizeof(void*) + : 0)) + : 0; + return S3JniCast_P2L(p); +} + +/* Central auto-extension handler. */ +static int s3jni_run_java_auto_extensions(sqlite3 *pDb, const char **pzErr, + const struct sqlite3_api_routines *ignored){ + int rc = 0; + unsigned i, go = 1; + JNIEnv * env = 0; + S3JniDb * ps; + S3JniEnv * jc; + + if( 0==SJG.autoExt.nExt ) return 0; + env = s3jni_env(); + jc = S3JniEnv_get(); + S3JniDb_mutex_enter; + ps = jc->pdbOpening ? jc->pdbOpening : S3JniDb_from_c(pDb); + if( !ps ){ + *pzErr = sqlite3_mprintf("Unexpected arrival of null S3JniDb in " + "auto-extension runner."); + S3JniDb_mutex_leave; + return SQLITE_ERROR; + } + assert( ps->jDb ); + if( !ps->pDb ){ + assert( jc->pdbOpening == ps ); + rc = sqlite3_set_clientdata(pDb, S3JniDb_clientdata_key, + ps, 0/* we'll re-set this after open() + completes. */); + if( rc ){ + S3JniDb_mutex_leave; + return rc; + } + } + else{ + assert( ps == jc->pdbOpening ); + jc->pdbOpening = 0; + } + S3JniDb_mutex_leave; + NativePointerHolder_set(S3JniNph(sqlite3), ps->jDb, pDb) + /* As of here, the Java/C connection is complete except for the + (temporary) lack of finalizer for the ps object. */; + ps->pDb = pDb; + for( i = 0; go && 0==rc; ++i ){ + S3JniAutoExtension ax = S3JniHook_empty + /* We need a copy of the auto-extension object, with our own + ** local reference to it, to avoid a race condition with another + ** thread manipulating the list during the call and invaliding + ** what ax references. */; + S3JniAutoExt_mutex_enter; + if( i >= SJG.autoExt.nExt ){ + go = 0; + }else{ + S3JniHook_localdup(&SJG.autoExt.aExt[i], &ax); + } + S3JniAutoExt_mutex_leave; + if( ax.jObj ){ + rc = (*env)->CallIntMethod(env, ax.jObj, ax.midCallback, ps->jDb); + S3JniHook_localundup(ax); + S3JniIfThrew { + jthrowable const ex = (*env)->ExceptionOccurred(env); + char * zMsg; + S3JniExceptionClear; + zMsg = s3jni_exception_error_msg(env, ex); + S3JniUnrefLocal(ex); + *pzErr = sqlite3_mprintf("auto-extension threw: %s", zMsg); + sqlite3_free(zMsg); + rc = SQLITE_ERROR; + } + } + } + return rc; +} + +S3JniApi(sqlite3_auto_extension(),jint,1auto_1extension)( + JniArgsEnvClass, jobject jAutoExt +){ + int i; + S3JniAutoExtension * ax = 0; + int rc = 0; + + if( !jAutoExt ) return SQLITE_MISUSE; + S3JniAutoExt_mutex_enter; + for( i = 0; i < SJG.autoExt.nExt; ++i ){ + /* Look for a match. */ + ax = &SJG.autoExt.aExt[i]; + if( ax->jObj && (*env)->IsSameObject(env, ax->jObj, jAutoExt) ){ + /* same object, so this is a no-op. */ + S3JniAutoExt_mutex_leave; + return 0; + } + } + if( i == SJG.autoExt.nExt ){ + assert( SJG.autoExt.nExt <= SJG.autoExt.nAlloc ); + if( SJG.autoExt.nExt == SJG.autoExt.nAlloc ){ + /* Allocate another slot. */ + unsigned n = 1 + SJG.autoExt.nAlloc; + S3JniAutoExtension * const aNew = + s3jni_realloc( SJG.autoExt.aExt, n * sizeof(*ax) ); + if( !aNew ){ + rc = SQLITE_NOMEM; + }else{ + SJG.autoExt.aExt = aNew; + ++SJG.autoExt.nAlloc; + } + } + if( 0==rc ){ + ax = &SJG.autoExt.aExt[SJG.autoExt.nExt]; + rc = S3JniAutoExtension_init(env, ax, jAutoExt); + assert( rc ? (0==ax->jObj && 0==ax->midCallback) + : (0!=ax->jObj && 0!=ax->midCallback) ); + } + } + if( 0==rc ){ + static int once = 0; + if( 0==once && ++once ){ + rc = sqlite3_auto_extension( + (void(*)(void))s3jni_run_java_auto_extensions + /* Reminder: the JNI binding of sqlite3_reset_auto_extension() + ** does not call the core-lib impl. It only clears Java-side + ** auto-extensions. */ + ); + if( rc ){ + assert( ax ); + S3JniAutoExtension_clear(ax); + } + } + if( 0==rc ){ + ++SJG.autoExt.nExt; + } + } + S3JniAutoExt_mutex_leave; + return rc; +} + +S3JniApi(sqlite3_backup_finish(),jint,1backup_1finish)( + JniArgsEnvClass, jlong jpBack +){ + int rc = 0; + if( jpBack!=0 ){ + rc = sqlite3_backup_finish( S3JniLongPtr_sqlite3_backup(jpBack) ); + } + return rc; +} + +S3JniApi(sqlite3_backup_init(),jobject,1backup_1init)( + JniArgsEnvClass, jlong jpDbDest, jstring jTDest, + jlong jpDbSrc, jstring jTSrc +){ + sqlite3 * const pDest = S3JniLongPtr_sqlite3(jpDbDest); + sqlite3 * const pSrc = S3JniLongPtr_sqlite3(jpDbSrc); + char * const zDest = s3jni_jstring_to_utf8(jTDest, 0); + char * const zSrc = s3jni_jstring_to_utf8(jTSrc, 0); + jobject rv = 0; + + if( pDest && pSrc && zDest && zSrc ){ + sqlite3_backup * const pB = + sqlite3_backup_init(pDest, zDest, pSrc, zSrc); + if( pB ){ + rv = new_java_sqlite3_backup(env, pB); + if( !rv ){ + sqlite3_backup_finish( pB ); + } + } + } + sqlite3_free(zDest); + sqlite3_free(zSrc); + return rv; +} + +S3JniApi(sqlite3_backup_pagecount(),jint,1backup_1pagecount)( + JniArgsEnvClass, jlong jpBack +){ + return sqlite3_backup_pagecount(S3JniLongPtr_sqlite3_backup(jpBack)); +} + +S3JniApi(sqlite3_backup_remaining(),jint,1backup_1remaining)( + JniArgsEnvClass, jlong jpBack +){ + return sqlite3_backup_remaining(S3JniLongPtr_sqlite3_backup(jpBack)); +} + +S3JniApi(sqlite3_backup_step(),jint,1backup_1step)( + JniArgsEnvClass, jlong jpBack, jint nPage +){ + return sqlite3_backup_step(S3JniLongPtr_sqlite3_backup(jpBack), (int)nPage); +} + +S3JniApi(sqlite3_bind_blob(),jint,1bind_1blob)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jbyteArray baData, jint nMax +){ + jsize nBA = 0; + jbyte * const pBuf = baData ? s3jni_jbyteArray_bytes2(baData, &nBA) : 0; + int rc; + if( pBuf ){ + if( nMax>nBA ){ + nMax = nBA; + } + rc = sqlite3_bind_blob(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, + pBuf, (int)nMax, SQLITE_TRANSIENT); + s3jni_jbyteArray_release(baData, pBuf); + }else{ + rc = baData + ? SQLITE_NOMEM + : sqlite3_bind_null( S3JniLongPtr_sqlite3_stmt(jpStmt), ndx ); + } + return (jint)rc; +} + +S3JniApi(sqlite3_bind_double(),jint,1bind_1double)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jdouble val +){ + return (jint)sqlite3_bind_double(S3JniLongPtr_sqlite3_stmt(jpStmt), + (int)ndx, (double)val); +} + +S3JniApi(sqlite3_bind_int(),jint,1bind_1int)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jint val +){ + return (jint)sqlite3_bind_int(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, (int)val); +} + +S3JniApi(sqlite3_bind_int64(),jint,1bind_1int64)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jlong val +){ + return (jint)sqlite3_bind_int64(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, (sqlite3_int64)val); +} + +/* +** Bind a new global ref to Object `val` using sqlite3_bind_pointer(). +*/ +S3JniApi(sqlite3_bind_java_object(),jint,1bind_1java_1object)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jobject val +){ + sqlite3_stmt * const pStmt = S3JniLongPtr_sqlite3_stmt(jpStmt); + int rc = SQLITE_MISUSE; + + if(pStmt){ + jobject const rv = S3JniRefGlobal(val); + if( rv ){ + rc = sqlite3_bind_pointer(pStmt, ndx, rv, ResultJavaValuePtrStr, + S3Jni_jobject_finalizer); + }else if(val){ + rc = SQLITE_NOMEM; + }else{ + rc = sqlite3_bind_null(pStmt, ndx); + } + } + return rc; +} + +S3JniApi(sqlite3_bind_null(),jint,1bind_1null)( + JniArgsEnvClass, jlong jpStmt, jint ndx +){ + return (jint)sqlite3_bind_null(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx); +} + +S3JniApi(sqlite3_bind_parameter_count(),jint,1bind_1parameter_1count)( + JniArgsEnvClass, jlong jpStmt +){ + return (jint)sqlite3_bind_parameter_count(S3JniLongPtr_sqlite3_stmt(jpStmt)); +} + +S3JniApi(sqlite3_bind_parameter_index(),jint,1bind_1parameter_1index)( + JniArgsEnvClass, jlong jpStmt, jbyteArray jName +){ + int rc = 0; + jbyte * const pBuf = s3jni_jbyteArray_bytes(jName); + if( pBuf ){ + rc = sqlite3_bind_parameter_index(S3JniLongPtr_sqlite3_stmt(jpStmt), + (const char *)pBuf); + s3jni_jbyteArray_release(jName, pBuf); + } + return rc; +} + +S3JniApi(sqlite3_bind_parameter_name(),jstring,1bind_1parameter_1name)( + JniArgsEnvClass, jlong jpStmt, jint ndx +){ + const char *z = + sqlite3_bind_parameter_name(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx); + return z ? s3jni_utf8_to_jstring(z, -1) : 0; +} + +/* +** Impl of sqlite3_bind_text/text16(). +*/ +static int s3jni__bind_text(int is16, JNIEnv *env, jlong jpStmt, jint ndx, + jbyteArray baData, jint nMax){ + jsize nBA = 0; + jbyte * const pBuf = + baData ? s3jni_jbyteArray_bytes2(baData, &nBA) : 0; + int rc; + if( pBuf ){ + if( nMax>nBA ){ + nMax = nBA; + } + /* Note that we rely on the Java layer having assured that baData + is NUL-terminated if nMax is negative. In order to avoid UB for + such cases, we do not expose the byte-limit arguments in the + public API. */ + rc = is16 + ? sqlite3_bind_text16(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, + pBuf, (int)nMax, SQLITE_TRANSIENT) + : sqlite3_bind_text(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx, + (const char *)pBuf, + (int)nMax, SQLITE_TRANSIENT); + }else{ + rc = baData + ? sqlite3_bind_null(S3JniLongPtr_sqlite3_stmt(jpStmt), (int)ndx) + : SQLITE_NOMEM; + } + s3jni_jbyteArray_release(baData, pBuf); + return (jint)rc; + +} + +S3JniApi(sqlite3_bind_text(),jint,1bind_1text)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jbyteArray baData, jint nMax +){ + return s3jni__bind_text(0, env, jpStmt, ndx, baData, nMax); +} + +S3JniApi(sqlite3_bind_text16(),jint,1bind_1text16)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jbyteArray baData, jint nMax +){ + return s3jni__bind_text(1, env, jpStmt, ndx, baData, nMax); +} + +S3JniApi(sqlite3_bind_value(),jint,1bind_1value)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jlong jpValue +){ + int rc = 0; + sqlite3_stmt * pStmt = S3JniLongPtr_sqlite3_stmt(jpStmt); + if( pStmt ){ + sqlite3_value *v = S3JniLongPtr_sqlite3_value(jpValue); + if( v ){ + rc = sqlite3_bind_value(pStmt, (int)ndx, v); + }else{ + rc = sqlite3_bind_null(pStmt, (int)ndx); + } + }else{ + rc = SQLITE_MISUSE; + } + return (jint)rc; +} + +S3JniApi(sqlite3_bind_zeroblob(),jint,1bind_1zeroblob)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jint n +){ + return (jint)sqlite3_bind_zeroblob(S3JniLongPtr_sqlite3_stmt(jpStmt), + (int)ndx, (int)n); +} + +S3JniApi(sqlite3_bind_zeroblob64(),jint,1bind_1zeroblob64)( + JniArgsEnvClass, jlong jpStmt, jint ndx, jlong n +){ + return (jint)sqlite3_bind_zeroblob64(S3JniLongPtr_sqlite3_stmt(jpStmt), + (int)ndx, (sqlite3_uint64)n); +} + +S3JniApi(sqlite3_blob_bytes(),jint,1blob_1bytes)( + JniArgsEnvClass, jlong jpBlob +){ + return sqlite3_blob_bytes(S3JniLongPtr_sqlite3_blob(jpBlob)); +} + +S3JniApi(sqlite3_blob_close(),jint,1blob_1close)( + JniArgsEnvClass, jlong jpBlob +){ + sqlite3_blob * const b = S3JniLongPtr_sqlite3_blob(jpBlob); + return b ? (jint)sqlite3_blob_close(b) : SQLITE_MISUSE; +} + +S3JniApi(sqlite3_blob_open(),jint,1blob_1open)( + JniArgsEnvClass, jlong jpDb, jstring jDbName, jstring jTbl, jstring jCol, + jlong jRowId, jint flags, jobject jOut +){ + sqlite3 * const db = S3JniLongPtr_sqlite3(jpDb); + sqlite3_blob * pBlob = 0; + char * zDbName = 0, * zTableName = 0, * zColumnName = 0; + int rc; + + if( !db || !jDbName || !jTbl || !jCol ) return SQLITE_MISUSE; + zDbName = s3jni_jstring_to_utf8(jDbName,0); + zTableName = zDbName ? s3jni_jstring_to_utf8(jTbl,0) : 0; + zColumnName = zTableName ? s3jni_jstring_to_utf8(jCol,0) : 0; + rc = zColumnName + ? sqlite3_blob_open(db, zDbName, zTableName, zColumnName, + (sqlite3_int64)jRowId, (int)flags, &pBlob) + : SQLITE_NOMEM; + if( 0==rc ){ + jobject rv = new_java_sqlite3_blob(env, pBlob); + if( !rv ){ + sqlite3_blob_close(pBlob); + rc = SQLITE_NOMEM; + } + OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_blob), jOut, rv); + } + sqlite3_free(zDbName); + sqlite3_free(zTableName); + sqlite3_free(zColumnName); + return rc; +} + +S3JniApi(sqlite3_blob_read(),jint,1blob_1read)( + JniArgsEnvClass, jlong jpBlob, jbyteArray jTgt, jint iOffset +){ + jbyte * const pBa = s3jni_jbyteArray_bytes(jTgt); + int rc = jTgt ? (pBa ? SQLITE_MISUSE : SQLITE_NOMEM) : SQLITE_MISUSE; + if( pBa ){ + jsize const nTgt = (*env)->GetArrayLength(env, jTgt); + rc = sqlite3_blob_read(S3JniLongPtr_sqlite3_blob(jpBlob), pBa, + (int)nTgt, (int)iOffset); + if( 0==rc ){ + s3jni_jbyteArray_commit(jTgt, pBa); + }else{ + s3jni_jbyteArray_release(jTgt, pBa); + } + } + return rc; +} + +S3JniApi(sqlite3_blob_reopen(),jint,1blob_1reopen)( + JniArgsEnvClass, jlong jpBlob, jlong iNewRowId +){ + return (jint)sqlite3_blob_reopen(S3JniLongPtr_sqlite3_blob(jpBlob), + (sqlite3_int64)iNewRowId); +} + +S3JniApi(sqlite3_blob_write(),jint,1blob_1write)( + JniArgsEnvClass, jlong jpBlob, jbyteArray jBa, jint iOffset +){ + sqlite3_blob * const b = S3JniLongPtr_sqlite3_blob(jpBlob); + jbyte * const pBuf = b ? s3jni_jbyteArray_bytes(jBa) : 0; + const jsize nBA = pBuf ? (*env)->GetArrayLength(env, jBa) : 0; + int rc = SQLITE_MISUSE; + if(b && pBuf){ + rc = sqlite3_blob_write( b, pBuf, (int)nBA, (int)iOffset ); + } + s3jni_jbyteArray_release(jBa, pBuf); + return (jint)rc; +} + +/* Central C-to-Java busy handler proxy. */ +static int s3jni_busy_handler(void* pState, int n){ + S3JniDb * const ps = (S3JniDb *)pState; + int rc = 0; + S3JniDeclLocal_env; + S3JniHook hook; + + S3JniHook_localdup(&ps->hooks.busyHandler, &hook); + if( hook.jObj ){ + rc = (*env)->CallIntMethod(env, hook.jObj, + hook.midCallback, (jint)n); + S3JniIfThrew{ + S3JniExceptionWarnCallbackThrew("sqlite3_busy_handler() callback"); + rc = s3jni_db_exception(ps->pDb, SQLITE_ERROR, + "sqlite3_busy_handler() callback threw."); + } + S3JniHook_localundup(hook); + } + return rc; +} + +S3JniApi(sqlite3_busy_handler(),jint,1busy_1handler)( + JniArgsEnvClass, jlong jpDb, jobject jBusy +){ + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); + S3JniHook * const pHook = ps ? &ps->hooks.busyHandler : 0; + S3JniHook hook = S3JniHook_empty; + int rc = 0; + + if( !ps ) return (jint)SQLITE_MISUSE; + S3JniDb_mutex_enter; + if( jBusy ){ + if( pHook->jObj && (*env)->IsSameObject(env, pHook->jObj, jBusy) ){ + /* Same object - this is a no-op. */ + }else{ + jclass const klazz = (*env)->GetObjectClass(env, jBusy); + hook.jObj = S3JniRefGlobal(jBusy); + hook.midCallback = (*env)->GetMethodID(env, klazz, "call", "(I)I"); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + rc = SQLITE_ERROR; + } + } + } + if( 0==rc ){ + if( jBusy ){ + if( hook.jObj ){ /* Replace handler */ + rc = sqlite3_busy_handler(ps->pDb, s3jni_busy_handler, ps); + if( 0==rc ){ + S3JniHook_unref(pHook); + *pHook = hook /* transfer Java ref ownership */; + hook = S3JniHook_empty; + } + }/* else no-op */ + }else{ /* Clear handler */ + rc = sqlite3_busy_handler(ps->pDb, 0, 0); + if( 0==rc ){ + S3JniHook_unref(pHook); + } + } + } + S3JniHook_unref(&hook); + S3JniDb_mutex_leave; + return rc; +} + +S3JniApi(sqlite3_busy_timeout(),jint,1busy_1timeout)( + JniArgsEnvClass, jlong jpDb, jint ms +){ + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); + int rc = SQLITE_MISUSE; + if( ps ){ + S3JniDb_mutex_enter; + S3JniHook_unref(&ps->hooks.busyHandler); + rc = sqlite3_busy_timeout(ps->pDb, (int)ms); + S3JniDb_mutex_leave; + } + return rc; +} + +S3JniApi(sqlite3_cancel_auto_extension(),jboolean,1cancel_1auto_1extension)( + JniArgsEnvClass, jobject jAutoExt +){ + S3JniAutoExtension * ax; + jboolean rc = JNI_FALSE; + int i; + + if( !jAutoExt ){ + return rc; + } + S3JniAutoExt_mutex_enter; + /* This algo corresponds to the one in the core. */ + for( i = SJG.autoExt.nExt-1; i >= 0; --i ){ + ax = &SJG.autoExt.aExt[i]; + if( ax->jObj && (*env)->IsSameObject(env, ax->jObj, jAutoExt) ){ + S3JniAutoExtension_clear(ax); + /* Move final entry into this slot. */ + --SJG.autoExt.nExt; + *ax = SJG.autoExt.aExt[SJG.autoExt.nExt]; + SJG.autoExt.aExt[SJG.autoExt.nExt] = S3JniHook_empty; + assert( !SJG.autoExt.aExt[SJG.autoExt.nExt].jObj ); + rc = JNI_TRUE; + break; + } + } + S3JniAutoExt_mutex_leave; + return rc; +} + +/* Wrapper for sqlite3_close(_v2)(). */ +static jint s3jni_close_db(JNIEnv * const env, jlong jpDb, int version){ + int rc = 0; + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); + + assert(version == 1 || version == 2); + if( ps ){ + rc = 1==version + ? (jint)sqlite3_close(ps->pDb) + : (jint)sqlite3_close_v2(ps->pDb); + } + return (jint)rc; +} + +S3JniApi(sqlite3_close(),jint,1close)(JniArgsEnvClass, jlong pDb){ + return s3jni_close_db(env, pDb, 1); +} + +S3JniApi(sqlite3_close_v2(),jint,1close_1v2)(JniArgsEnvClass, jlong pDb){ + return s3jni_close_db(env, pDb, 2); +} + +/* +** Assumes z is an array of unsigned short and returns the index in +** that array of the first element with the value 0. +*/ +static unsigned int s3jni_utf16_strlen(void const * z){ + unsigned int i = 0; + const unsigned short * p = z; + while( p[i] ) ++i; + return i; +} + +/* Descriptive alias for use with sqlite3_collation_needed(). */ +typedef S3JniHook S3JniCollationNeeded; + +/* Central C-to-Java sqlite3_collation_needed16() hook impl. */ +static void s3jni_collation_needed_impl16(void *pState, sqlite3 *pDb, + int eTextRep, const void * z16Name){ + S3JniCollationNeeded * const pHook = pState; + S3JniDeclLocal_env; + S3JniHook hook; + + S3JniHook_localdup(pHook, &hook); + if( hook.jObj ){ + unsigned int const nName = s3jni_utf16_strlen(z16Name); + jstring jName = (*env)->NewString(env, (jchar const *)z16Name, nName); + + s3jni_oom_check( jName ); + assert( hook.jExtra ); + S3JniIfThrew{ + S3JniExceptionClear; + }else if( hook.jExtra ){ + (*env)->CallVoidMethod(env, hook.jObj, hook.midCallback, + hook.jExtra, (jint)eTextRep, jName); + S3JniIfThrew{ + S3JniExceptionWarnCallbackThrew("sqlite3_collation_needed() callback"); + } + } + S3JniUnrefLocal(jName); + S3JniHook_localundup(hook); + } +} + +S3JniApi(sqlite3_collation_needed(),jint,1collation_1needed)( + JniArgsEnvClass, jlong jpDb, jobject jHook +){ + S3JniDb * ps; + S3JniCollationNeeded * pHook; + int rc = 0; + + S3JniDb_mutex_enter; + ps = S3JniDb_from_jlong(jpDb); + if( !ps ){ + S3JniDb_mutex_leave; + return SQLITE_MISUSE; + } + pHook = &ps->hooks.collationNeeded; + if( pHook->jObj && jHook && + (*env)->IsSameObject(env, pHook->jObj, jHook) ){ + /* no-op */ + }else if( !jHook ){ + rc = sqlite3_collation_needed(ps->pDb, 0, 0); + if( 0==rc ){ + S3JniHook_unref(pHook); + } + }else{ + jclass const klazz = (*env)->GetObjectClass(env, jHook); + jmethodID const xCallback = (*env)->GetMethodID( + env, klazz, "call", "(Lorg/sqlite/jni/capi/sqlite3;ILjava/lang/String;)I" + ); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + rc = s3jni_db_exception(ps->pDb, SQLITE_MISUSE, + "Cannot not find matching call() in " + "CollationNeededCallback object."); + }else{ + rc = sqlite3_collation_needed16(ps->pDb, pHook, + s3jni_collation_needed_impl16); + if( 0==rc ){ + S3JniHook_unref(pHook); + pHook->midCallback = xCallback; + pHook->jObj = S3JniRefGlobal(jHook); + pHook->jExtra = S3JniRefGlobal(ps->jDb); + } + } + } + S3JniDb_mutex_leave; + return rc; +} + +S3JniApi(sqlite3_column_blob(),jbyteArray,1column_1blob)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); + void const * const p = sqlite3_column_blob(pStmt, (int)ndx); + int const n = p ? sqlite3_column_bytes(pStmt, (int)ndx) : 0; + + return p ? s3jni_new_jbyteArray(p, n) : 0; +} + +S3JniApi(sqlite3_column_double(),jdouble,1column_1double)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + return (jdouble)sqlite3_column_double(PtrGet_sqlite3_stmt(jpStmt), (int)ndx); +} + +S3JniApi(sqlite3_column_int(),jint,1column_1int)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + return (jint)sqlite3_column_int(PtrGet_sqlite3_stmt(jpStmt), (int)ndx); +} + +S3JniApi(sqlite3_column_int64(),jlong,1column_1int64)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + return (jlong)sqlite3_column_int64(PtrGet_sqlite3_stmt(jpStmt), (int)ndx); +} + +S3JniApi(sqlite3_column_text(),jbyteArray,1column_1text)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt); + const unsigned char * const p = stmt ? sqlite3_column_text(stmt, (int)ndx) : 0; + const int n = p ? sqlite3_column_bytes(stmt, (int)ndx) : 0; + return p ? s3jni_new_jbyteArray(p, n) : NULL; +} + +#if 0 +// this impl might prove useful. +S3JniApi(sqlite3_column_text(),jstring,1column_1text)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt); + const unsigned char * const p = stmt ? sqlite3_column_text(stmt, (int)ndx) : 0; + const int n = p ? sqlite3_column_bytes(stmt, (int)ndx) : 0; + return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0; +} +#endif + +S3JniApi(sqlite3_column_text16(),jstring,1column_1text16)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + sqlite3_stmt * const stmt = PtrGet_sqlite3_stmt(jpStmt); + const void * const p = stmt ? sqlite3_column_text16(stmt, (int)ndx) : 0; + const int n = p ? sqlite3_column_bytes16(stmt, (int)ndx) : 0; + return s3jni_text16_to_jstring(env, p, n); +} + +S3JniApi(sqlite3_column_value(),jobject,1column_1value)( + JniArgsEnvClass, jobject jpStmt, jint ndx +){ + sqlite3_value * const sv = + sqlite3_column_value(PtrGet_sqlite3_stmt(jpStmt), (int)ndx) + /* reminder: returns an SQL NULL if jpStmt==NULL */; + return new_java_sqlite3_value(env, sv); +} + +/* +** Impl for commit hooks (if isCommit is true) or rollback hooks. +*/ +static int s3jni_commit_rollback_hook_impl(int isCommit, S3JniDb * const ps){ + S3JniDeclLocal_env; + int rc = 0; + S3JniHook hook; + + S3JniHook_localdup(isCommit + ? &ps->hooks.commit : &ps->hooks.rollback, + &hook); + if( hook.jObj ){ + rc = isCommit + ? (int)(*env)->CallIntMethod(env, hook.jObj, hook.midCallback) + : (int)((*env)->CallVoidMethod(env, hook.jObj, hook.midCallback), 0); + S3JniIfThrew{ + rc = s3jni_db_exception(ps->pDb, SQLITE_ERROR, "hook callback threw"); + } + S3JniHook_localundup(hook); + } + return rc; +} + +/* C-to-Java commit hook wrapper. */ +static int s3jni_commit_hook_impl(void *pP){ + return s3jni_commit_rollback_hook_impl(1, pP); +} + +/* C-to-Java rollback hook wrapper. */ +static void s3jni_rollback_hook_impl(void *pP){ + (void)s3jni_commit_rollback_hook_impl(0, pP); +} + +/* +** Proxy for sqlite3_commit_hook() (if isCommit is true) or +** sqlite3_rollback_hook(). +*/ +static jobject s3jni_commit_rollback_hook(int isCommit, JNIEnv * const env, + jlong jpDb, jobject jHook){ + S3JniDb * ps; + jobject pOld = 0; /* previous hoook */ + S3JniHook * pHook; /* ps->hooks.commit|rollback */ + + S3JniDb_mutex_enter; + ps = S3JniDb_from_jlong(jpDb); + if( !ps ){ + s3jni_db_error(ps->pDb, SQLITE_MISUSE, 0); + S3JniDb_mutex_leave; + return 0; + } + pHook = isCommit ? &ps->hooks.commit : &ps->hooks.rollback; + pOld = pHook->jObj; + if( pOld && jHook && + (*env)->IsSameObject(env, pOld, jHook) ){ + /* No-op. */ + }else if( !jHook ){ + if( pOld ){ + jobject tmp = S3JniRefLocal(pOld); + S3JniUnrefGlobal(pOld); + pOld = tmp; + } + *pHook = S3JniHook_empty; + if( isCommit ) sqlite3_commit_hook(ps->pDb, 0, 0); + else sqlite3_rollback_hook(ps->pDb, 0, 0); + }else{ + jclass const klazz = (*env)->GetObjectClass(env, jHook); + jmethodID const xCallback = (*env)->GetMethodID(env, klazz, "call", + isCommit ? "()I" : "()V"); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + S3JniExceptionReport; + S3JniExceptionClear; + s3jni_db_error(ps->pDb, SQLITE_ERROR, + "Cannot not find matching call() method in" + "hook object."); + }else{ + pHook->midCallback = xCallback; + pHook->jObj = S3JniRefGlobal(jHook); + if( isCommit ) sqlite3_commit_hook(ps->pDb, s3jni_commit_hook_impl, ps); + else sqlite3_rollback_hook(ps->pDb, s3jni_rollback_hook_impl, ps); + if( pOld ){ + jobject tmp = S3JniRefLocal(pOld); + S3JniUnrefGlobal(pOld); + pOld = tmp; + } + } + } + S3JniDb_mutex_leave; + return pOld; +} + +S3JniApi(sqlite3_commit_hook(),jobject,1commit_1hook)( + JniArgsEnvClass, jlong jpDb, jobject jHook +){ + return s3jni_commit_rollback_hook(1, env, jpDb, jHook); +} + +S3JniApi(sqlite3_compileoption_get(),jstring,1compileoption_1get)( + JniArgsEnvClass, jint n +){ + const char * z = sqlite3_compileoption_get(n); + jstring const rv = z ? (*env)->NewStringUTF( env, z ) : 0; + /* We know these to be ASCII, so MUTF-8 is fine. */; + s3jni_oom_check(z ? !!rv : 1); + return rv; +} + +S3JniApi(sqlite3_compileoption_used(),jboolean,1compileoption_1used)( + JniArgsEnvClass, jstring name +){ + const char *zUtf8 = s3jni_jstring_to_mutf8(name) + /* We know these to be ASCII, so MUTF-8 is fine (and + hypothetically faster to convert). */; + const jboolean rc = + 0==sqlite3_compileoption_used(zUtf8) ? JNI_FALSE : JNI_TRUE; + s3jni_mutf8_release(name, zUtf8); + return rc; +} + +S3JniApi(sqlite3_complete(),int,1complete)( + JniArgsEnvClass, jbyteArray jSql +){ + jbyte * const pBuf = s3jni_jbyteArray_bytes(jSql); + const jsize nBA = pBuf ? (*env)->GetArrayLength(env, jSql) : 0; + int rc; + + assert( (nBA>0 ? 0==pBuf[nBA-1] : (pBuf ? 0==*pBuf : 1)) + && "Byte array is not NUL-terminated." ); + rc = (pBuf && 0==pBuf[(nBA ? nBA-1 : 0)]) + ? sqlite3_complete( (const char *)pBuf ) + : (jSql ? SQLITE_NOMEM : SQLITE_MISUSE); + s3jni_jbyteArray_release(jSql, pBuf); + return rc; +} + +S3JniApi(sqlite3_config() /*for a small subset of options.*/, + jint,1config__I)(JniArgsEnvClass, jint n){ + switch( n ){ + case SQLITE_CONFIG_SINGLETHREAD: + case SQLITE_CONFIG_MULTITHREAD: + case SQLITE_CONFIG_SERIALIZED: + return sqlite3_config( n ); + default: + return SQLITE_MISUSE; + } +} +/* C-to-Java SQLITE_CONFIG_LOG wrapper. */ +static void s3jni_config_log(void *ignored, int errCode, const char *z){ + S3JniDeclLocal_env; + S3JniHook hook = S3JniHook_empty; + + S3JniHook_localdup(&SJG.hook.configlog, &hook); + if( hook.jObj ){ + jstring const jArg1 = z ? s3jni_utf8_to_jstring(z, -1) : 0; + if( z ? !!jArg1 : 1 ){ + (*env)->CallVoidMethod(env, hook.jObj, hook.midCallback, errCode, jArg1); + } + S3JniIfThrew{ + S3JniExceptionWarnCallbackThrew("SQLITE_CONFIG_LOG callback"); + S3JniExceptionClear; + } + S3JniHook_localundup(hook); + S3JniUnrefLocal(jArg1); + } +} + +S3JniApi(sqlite3_config() /* for SQLITE_CONFIG_LOG */, + jint, 1config__Lorg_sqlite_jni_ConfigLogCallback_2 +)(JniArgsEnvClass, jobject jLog){ + S3JniHook * const pHook = &SJG.hook.configlog; + int rc = 0; + + S3JniGlobal_mutex_enter; + if( !jLog ){ + rc = sqlite3_config( SQLITE_CONFIG_LOG, NULL, NULL ); + if( 0==rc ){ + S3JniHook_unref(pHook); + } + }else if( pHook->jObj && (*env)->IsSameObject(env, jLog, pHook->jObj) ){ + /* No-op */ + }else { + jclass const klazz = (*env)->GetObjectClass(env, jLog); + jmethodID const midCallback = (*env)->GetMethodID(env, klazz, "call", + "(ILjava/lang/String;)V"); + S3JniUnrefLocal(klazz); + if( midCallback ){ + rc = sqlite3_config( SQLITE_CONFIG_LOG, s3jni_config_log, NULL ); + if( 0==rc ){ + S3JniHook_unref(pHook); + pHook->midCallback = midCallback; + pHook->jObj = S3JniRefGlobal(jLog); + } + }else{ + S3JniExceptionWarnIgnore; + rc = SQLITE_ERROR; + } + } + S3JniGlobal_mutex_leave; + return rc; +} + +#ifdef SQLITE_ENABLE_SQLLOG +/* C-to-Java SQLITE_CONFIG_SQLLOG wrapper. */ +static void s3jni_config_sqllog(void *ignored, sqlite3 *pDb, const char *z, int op){ + jobject jArg0 = 0; + jstring jArg1 = 0; + S3JniDeclLocal_env; + S3JniDb * const ps = S3JniDb_from_c(pDb); + S3JniHook hook = S3JniHook_empty; + + if( ps ){ + S3JniHook_localdup(&SJG.hook.sqllog, &hook); + } + if( !hook.jObj ) return; + jArg0 = S3JniRefLocal(ps->jDb); + switch( op ){ + case 0: /* db opened */ + case 1: /* SQL executed */ + jArg1 = s3jni_utf8_to_jstring( z, -1); + break; + case 2: /* db closed */ + break; + default: + (*env)->FatalError(env, "Unhandled 4th arg to SQLITE_CONFIG_SQLLOG."); + break; + } + (*env)->CallVoidMethod(env, hook.jObj, hook.midCallback, jArg0, jArg1, op); + S3JniIfThrew{ + S3JniExceptionWarnCallbackThrew("SQLITE_CONFIG_SQLLOG callback"); + S3JniExceptionClear; + } + S3JniHook_localundup(hook); + S3JniUnrefLocal(jArg0); + S3JniUnrefLocal(jArg1); +} +//! Requirement of SQLITE_CONFIG_SQLLOG. +void sqlite3_init_sqllog(void){ + sqlite3_config( SQLITE_CONFIG_SQLLOG, s3jni_config_sqllog, 0 ); +} +#endif + +S3JniApi(sqlite3_config() /* for SQLITE_CONFIG_SQLLOG */, + jint, 1config__Lorg_sqlite_jni_ConfigSqllogCallback_2)( + JniArgsEnvClass, jobject jLog){ +#ifndef SQLITE_ENABLE_SQLLOG + return SQLITE_MISUSE; +#else + S3JniHook * const pHook = &SJG.hook.sqllog; + int rc = 0; + + S3JniGlobal_mutex_enter; + if( !jLog ){ + rc = sqlite3_config( SQLITE_CONFIG_SQLLOG, NULL ); + if( 0==rc ){ + S3JniHook_unref(pHook); + } + }else if( pHook->jObj && (*env)->IsSameObject(env, jLog, pHook->jObj) ){ + /* No-op */ + }else { + jclass const klazz = (*env)->GetObjectClass(env, jLog); + jmethodID const midCallback = (*env)->GetMethodID(env, klazz, "call", + "(Lorg/sqlite/jni/capi/sqlite3;" + "Ljava/lang/String;" + "I)V"); + S3JniUnrefLocal(klazz); + if( midCallback ){ + rc = sqlite3_config( SQLITE_CONFIG_SQLLOG, s3jni_config_sqllog, NULL ); + if( 0==rc ){ + S3JniHook_unref(pHook); + pHook->midCallback = midCallback; + pHook->jObj = S3JniRefGlobal(jLog); + } + }else{ + S3JniExceptionWarnIgnore; + rc = SQLITE_ERROR; + } + } + S3JniGlobal_mutex_leave; + return rc; +#endif +} + +S3JniApi(sqlite3_context_db_handle(),jobject,1context_1db_1handle)( + JniArgsEnvClass, jobject jpCx +){ + sqlite3_context * const pCx = PtrGet_sqlite3_context(jpCx); + sqlite3 * const pDb = pCx ? sqlite3_context_db_handle(pCx) : 0; + S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0; + return ps ? ps->jDb : 0; +} + +/* +** State for CollationCallbacks. This used to be its own separate +** type, but has since been consolidated with S3JniHook. It retains +** its own typedef for code legibility and searchability reasons. +*/ +typedef S3JniHook S3JniCollationCallback; + +/* +** Proxy for Java-side CollationCallback.xCompare() callbacks. +*/ +static int CollationCallback_xCompare(void *pArg, int nLhs, const void *lhs, + int nRhs, const void *rhs){ + S3JniCollationCallback * const pCC = pArg; + S3JniDeclLocal_env; + jint rc = 0; + if( pCC->jObj ){ + jbyteArray jbaLhs = s3jni_new_jbyteArray(lhs, (jint)nLhs); + jbyteArray jbaRhs = jbaLhs + ? s3jni_new_jbyteArray(rhs, (jint)nRhs) : 0; + if( !jbaRhs ){ + S3JniUnrefLocal(jbaLhs); + /* We have no recovery strategy here. */ + s3jni_oom_check( jbaRhs ); + return 0; + } + rc = (*env)->CallIntMethod(env, pCC->jObj, pCC->midCallback, + jbaLhs, jbaRhs); + S3JniExceptionIgnore; + S3JniUnrefLocal(jbaLhs); + S3JniUnrefLocal(jbaRhs); + } + return (int)rc; +} + +/* CollationCallback finalizer for use by the sqlite3 internals. */ +static void CollationCallback_xDestroy(void *pArg){ + S3JniCollationCallback * const pCC = pArg; + S3JniDeclLocal_env; + S3JniHook_free(pCC); +} + +S3JniApi(sqlite3_create_collation() sqlite3_create_collation_v2(), + jint,1create_1collation +)(JniArgsEnvClass, jobject jDb, jstring name, jint eTextRep, + jobject oCollation){ + int rc; + S3JniDb * ps; + + if( !jDb || !name || !encodingTypeIsValid(eTextRep) ){ + return (jint)SQLITE_MISUSE; + } + S3JniDb_mutex_enter; + ps = S3JniDb_from_java(jDb); + jclass const klazz = (*env)->GetObjectClass(env, oCollation); + jmethodID const midCallback = + (*env)->GetMethodID(env, klazz, "call", "([B[B)I"); + S3JniUnrefLocal(klazz); + S3JniIfThrew{ + rc = s3jni_db_error(ps->pDb, SQLITE_ERROR, + "Could not get call() method from " + "CollationCallback object."); + }else{ + char * const zName = s3jni_jstring_to_utf8(name, 0); + S3JniCollationCallback * const pCC = + zName ? S3JniHook_alloc() : 0; + if( pCC ){ + rc = sqlite3_create_collation_v2(ps->pDb, zName, (int)eTextRep, + pCC, CollationCallback_xCompare, + CollationCallback_xDestroy); + if( 0==rc ){ + pCC->midCallback = midCallback; + pCC->jObj = S3JniRefGlobal(oCollation); + pCC->doXDestroy = 1; + }else{ + CollationCallback_xDestroy(pCC); + } + }else{ + rc = SQLITE_NOMEM; + } + sqlite3_free(zName); + } + S3JniDb_mutex_leave; + return (jint)rc; +} + +S3JniApi(sqlite3_create_function() sqlite3_create_function_v2() + sqlite3_create_window_function(), + jint,1create_1function +)(JniArgsEnvClass, jobject jDb, jstring jFuncName, jint nArg, + jint eTextRep, jobject jFunctor){ + S3JniUdf * s = 0; + int rc; + sqlite3 * const pDb = PtrGet_sqlite3(jDb); + char * zFuncName = 0; + + if( !pDb || !jFuncName ){ + return SQLITE_MISUSE; + }else if( !encodingTypeIsValid(eTextRep) ){ + return s3jni_db_error(pDb, SQLITE_FORMAT, + "Invalid function encoding option."); + } + s = S3JniUdf_alloc(env, jFunctor); + if( !s ) return SQLITE_NOMEM; + + if( UDF_UNKNOWN_TYPE==s->type ){ + rc = s3jni_db_error(pDb, SQLITE_MISUSE, + "Cannot unambiguously determine function type."); + S3JniUdf_free(env, s, 1); + goto error_cleanup; + } + zFuncName = s3jni_jstring_to_utf8(jFuncName,0); + if( !zFuncName ){ + rc = SQLITE_NOMEM; + S3JniUdf_free(env, s, 1); + goto error_cleanup; + } + s->zFuncName = zFuncName /* pass on ownership */; + if( UDF_WINDOW == s->type ){ + rc = sqlite3_create_window_function(pDb, zFuncName, nArg, eTextRep, s, + udf_xStep, udf_xFinal, udf_xValue, + udf_xInverse, S3JniUdf_finalizer); + }else{ + udf_xFunc_f xFunc = 0; + udf_xStep_f xStep = 0; + udf_xFinal_f xFinal = 0; + if( UDF_SCALAR == s->type ){ + xFunc = udf_xFunc; + }else{ + assert( UDF_AGGREGATE == s->type ); + xStep = udf_xStep; + xFinal = udf_xFinal; + } + rc = sqlite3_create_function_v2(pDb, zFuncName, nArg, eTextRep, s, + xFunc, xStep, xFinal, S3JniUdf_finalizer); + } +error_cleanup: + /* Reminder: on sqlite3_create_function() error, s will be + ** destroyed via create_function(). */ + return (jint)rc; +} + + +S3JniApi(sqlite3_db_config() /*for MAINDBNAME*/, + jint,1db_1config__Lorg_sqlite_jni_capi_sqlite3_2ILjava_lang_String_2 +)(JniArgsEnvClass, jobject jDb, jint op, jstring jStr){ + S3JniDb * const ps = S3JniDb_from_java(jDb); + int rc; + char *zStr; + + switch( (ps && jStr) ? op : 0 ){ + case SQLITE_DBCONFIG_MAINDBNAME: + S3JniDb_mutex_enter + /* Protect against a race in modifying/freeing + ps->zMainDbName. */; + zStr = s3jni_jstring_to_utf8( jStr, 0); + if( zStr ){ + rc = sqlite3_db_config(ps->pDb, (int)op, zStr); + if( rc ){ + sqlite3_free( zStr ); + }else{ + sqlite3_free( ps->zMainDbName ); + ps->zMainDbName = zStr; + } + }else{ + rc = SQLITE_NOMEM; + } + S3JniDb_mutex_leave; + break; + case 0: + default: + rc = SQLITE_MISUSE; + } + return rc; +} + +S3JniApi( + sqlite3_db_config(), + /* WARNING: openjdk v19 creates a different mangled name for this + ** function than openjdk v8 does. We account for that by exporting + ** both versions of the name. */ + jint,1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2 +)( + JniArgsEnvClass, jobject jDb, jint op, jint onOff, jobject jOut +){ + S3JniDb * const ps = S3JniDb_from_java(jDb); + int rc; + switch( ps ? op : 0 ){ + case SQLITE_DBCONFIG_ENABLE_FKEY: + case SQLITE_DBCONFIG_ENABLE_TRIGGER: + case SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER: + case SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION: + case SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE: + case SQLITE_DBCONFIG_ENABLE_QPSG: + case SQLITE_DBCONFIG_TRIGGER_EQP: + case SQLITE_DBCONFIG_RESET_DATABASE: + case SQLITE_DBCONFIG_DEFENSIVE: + case SQLITE_DBCONFIG_WRITABLE_SCHEMA: + case SQLITE_DBCONFIG_LEGACY_ALTER_TABLE: + case SQLITE_DBCONFIG_DQS_DML: + case SQLITE_DBCONFIG_DQS_DDL: + case SQLITE_DBCONFIG_ENABLE_VIEW: + case SQLITE_DBCONFIG_LEGACY_FILE_FORMAT: + case SQLITE_DBCONFIG_TRUSTED_SCHEMA: + case SQLITE_DBCONFIG_STMT_SCANSTATUS: + case SQLITE_DBCONFIG_REVERSE_SCANORDER: { + int pOut = 0; + rc = sqlite3_db_config( ps->pDb, (int)op, onOff, &pOut ); + if( 0==rc && jOut ){ + OutputPointer_set_Int32(env, jOut, pOut); + } + break; + } + case 0: + default: + rc = SQLITE_MISUSE; + } + return (jint)rc; +} + +/* +** This is a workaround for openjdk v19 (and possibly others) encoding +** this function's name differently than JDK v8 does. If we do not +** install both names for this function then Java will not be able to +** find the function in both environments. +*/ +JniDecl(jint,1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_00024Int32_2)( + JniArgsEnvClass, jobject jDb, jint op, jint onOff, jobject jOut +){ + return JniFuncName(1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2)( + env, jKlazz, jDb, op, onOff, jOut + ); +} + +S3JniApi(sqlite3_db_filename(),jstring,1db_1filename)( + JniArgsEnvClass, jobject jDb, jstring jDbName +){ + S3JniDb * const ps = S3JniDb_from_java(jDb); + char *zDbName; + jstring jRv = 0; + int nStr = 0; + + if( !ps || !jDbName ){ + return 0; + } + zDbName = s3jni_jstring_to_utf8( jDbName, &nStr); + if( zDbName ){ + char const * zRv = sqlite3_db_filename(ps->pDb, zDbName); + sqlite3_free(zDbName); + if( zRv ){ + jRv = s3jni_utf8_to_jstring( zRv, -1); + } + } + return jRv; +} + +S3JniApi(sqlite3_db_handle(),jobject,1db_1handle)( + JniArgsEnvClass, jobject jpStmt +){ + sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); + sqlite3 * const pDb = pStmt ? sqlite3_db_handle(pStmt) : 0; + S3JniDb * const ps = pDb ? S3JniDb_from_c(pDb) : 0; + return ps ? ps->jDb : 0; +} + +S3JniApi(sqlite3_db_readonly(),jint,1db_1readonly)( + JniArgsEnvClass, jobject jDb, jstring jDbName +){ + int rc = 0; + S3JniDb * const ps = S3JniDb_from_java(jDb); + char *zDbName = jDbName ? s3jni_jstring_to_utf8( jDbName, 0 ) : 0; + rc = sqlite3_db_readonly(ps ? ps->pDb : 0, zDbName); + sqlite3_free(zDbName); + return (jint)rc; +} + +S3JniApi(sqlite3_db_release_memory(),int,1db_1release_1memory)( + JniArgsEnvClass, jobject jDb +){ + sqlite3 * const pDb = PtrGet_sqlite3(jDb); + return pDb ? sqlite3_db_release_memory(pDb) : SQLITE_MISUSE; +} + +S3JniApi(sqlite3_db_status(),jint,1db_1status)( + JniArgsEnvClass, jobject jDb, jint op, jobject jOutCurrent, + jobject jOutHigh, jboolean reset +){ + int iCur = 0, iHigh = 0; + sqlite3 * const pDb = PtrGet_sqlite3(jDb); + int rc = sqlite3_db_status( pDb, op, &iCur, &iHigh, reset ); + if( 0==rc ){ + OutputPointer_set_Int32(env, jOutCurrent, iCur); + OutputPointer_set_Int32(env, jOutHigh, iHigh); + } + return (jint)rc; +} + +S3JniApi(sqlite3_errcode(),jint,1errcode)( + JniArgsEnvClass, jobject jpDb +){ + sqlite3 * const pDb = PtrGet_sqlite3(jpDb); + return pDb ? sqlite3_errcode(pDb) : SQLITE_MISUSE; +} + +S3JniApi(sqlite3_errmsg(),jstring,1errmsg)( + JniArgsEnvClass, jobject jpDb +){ + sqlite3 * const pDb = PtrGet_sqlite3(jpDb); + return pDb ? s3jni_utf8_to_jstring( sqlite3_errmsg(pDb), -1) : 0 + /* We don't use errmsg16() directly only because it would cause an + additional level of internal encoding in sqlite3. The end + effect should be identical to using errmsg16(), however. */; +} + +S3JniApi(sqlite3_errstr(),jstring,1errstr)( + JniArgsEnvClass, jint rcCode +){ + jstring const rv = (*env)->NewStringUTF(env, sqlite3_errstr((int)rcCode)) + /* We know these values to be plain ASCII, so pose no MUTF-8 + ** incompatibility */; + s3jni_oom_check( rv ); + return rv; +} + +#ifndef SQLITE_ENABLE_NORMALIZE +/* Dummy stub for sqlite3_normalized_sql(). Never called. */ +static const char * sqlite3_normalized_sql(sqlite3_stmt *s){ + S3JniDeclLocal_env; + (*env)->FatalError(env, "dummy sqlite3_normalized_sql() was " + "impossibly called.") /* does not return */; + return 0; +} +#endif + +/* +** Impl for sqlite3_expanded_sql() (if isExpanded is true) and +** sqlite3_normalized_sql(). +*/ +static jstring s3jni_xn_sql(int isExpanded, JNIEnv *env, jobject jpStmt){ + jstring rv = 0; + sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); + + if( pStmt ){ + char * zSql = isExpanded + ? sqlite3_expanded_sql(pStmt) + : (char*)sqlite3_normalized_sql(pStmt); + s3jni_oom_fatal(zSql); + if( zSql ){ + rv = s3jni_utf8_to_jstring(zSql, -1); + if( isExpanded ) sqlite3_free(zSql); + } + } + return rv; +} + +S3JniApi(sqlite3_expanded_sql(),jstring,1expanded_1sql)( + JniArgsEnvClass, jobject jpStmt +){ + return s3jni_xn_sql(1, env, jpStmt); +} + +S3JniApi(sqlite3_normalized_sql(),jstring,1normalized_1sql)( + JniArgsEnvClass, jobject jpStmt +){ +#ifdef SQLITE_ENABLE_NORMALIZE + return s3jni_xn_sql(0, env, jpStmt); +#else + return 0; +#endif +} + +S3JniApi(sqlite3_extended_result_codes(),jboolean,1extended_1result_1codes)( + JniArgsEnvClass, jobject jpDb, jboolean onoff +){ + sqlite3 * const pDb = PtrGet_sqlite3(jpDb); + int const rc = pDb ? sqlite3_extended_result_codes(pDb, onoff ? 1 : 0) : 0; + return rc ? JNI_TRUE : JNI_FALSE; +} + +S3JniApi(sqlite3_finalize(),jint,1finalize)( + JniArgsEnvClass, jlong jpStmt +){ + return jpStmt + ? sqlite3_finalize(S3JniLongPtr_sqlite3_stmt(jpStmt)) + : 0; +} + +S3JniApi(sqlite3_get_auxdata(),jobject,1get_1auxdata)( + JniArgsEnvClass, jobject jCx, jint n +){ + return sqlite3_get_auxdata(PtrGet_sqlite3_context(jCx), (int)n); +} + +S3JniApi(sqlite3_initialize(),jint,1initialize)( + JniArgsEnvClass +){ + return sqlite3_initialize(); +} + +S3JniApi(sqlite3_interrupt(),void,1interrupt)( + JniArgsEnvClass, jobject jpDb +){ + sqlite3 * const pDb = PtrGet_sqlite3(jpDb); + if( pDb ){ + sqlite3_interrupt(pDb); + } +} + +S3JniApi(sqlite3_is_interrupted(),jboolean,1is_1interrupted)( + JniArgsEnvClass, jobject jpDb +){ + int rc = 0; + sqlite3 * const pDb = PtrGet_sqlite3(jpDb); + if( pDb ){ + rc = sqlite3_is_interrupted(pDb); + } + return rc ? JNI_TRUE : JNI_FALSE; +} + +/* +** Uncaches the current JNIEnv from the S3JniGlobal state, clearing +** any resources owned by that cache entry and making that slot +** available for re-use. +*/ +JniDecl(jboolean,1java_1uncache_1thread)(JniArgsEnvClass){ + int rc; + S3JniEnv_mutex_enter; + rc = S3JniEnv_uncache(env); + S3JniEnv_mutex_leave; + return rc ? JNI_TRUE : JNI_FALSE; +} + +S3JniApi(sqlite3_keyword_check(),jboolean,1keyword_1check)( + JniArgsEnvClass, jstring jWord +){ + int nWord = 0; + char * zWord = s3jni_jstring_to_utf8(jWord, &nWord); + int rc = 0; + + s3jni_oom_check(jWord ? !!zWord : 1); + if( zWord && nWord ){ + rc = sqlite3_keyword_check(zWord, nWord); + } + sqlite3_free(zWord); + return rc ? JNI_TRUE : JNI_FALSE; +} + +S3JniApi(sqlite3_keyword_name(),jstring,1keyword_1name)( + JniArgsEnvClass, jint ndx +){ + const char * zWord = 0; + int n = 0; + jstring rv = 0; + + if( 0==sqlite3_keyword_name(ndx, &zWord, &n) ){ + rv = s3jni_utf8_to_jstring(zWord, n); + } + return rv; +} + + +S3JniApi(sqlite3_last_insert_rowid(),jlong,1last_1insert_1rowid)( + JniArgsEnvClass, jobject jpDb +){ + return (jlong)sqlite3_last_insert_rowid(PtrGet_sqlite3(jpDb)); +} + +S3JniApi(sqlite3_limit(),jint,1limit)( + JniArgsEnvClass, jobject jpDb, jint id, jint newVal +){ + jint rc = 0; + sqlite3 * const pDb = PtrGet_sqlite3(jpDb); + if( pDb ){ + rc = sqlite3_limit( pDb, (int)id, (int)newVal ); + } + return rc; +} + +/* Pre-open() code common to sqlite3_open[_v2](). */ +static int s3jni_open_pre(JNIEnv * const env, S3JniEnv **jc, + jstring jDbName, char **zDbName, + S3JniDb ** ps){ + int rc = 0; + jobject jDb = 0; + + *jc = S3JniEnv_get(); + if( !*jc ){ + rc = SQLITE_NOMEM; + goto end; + } + *zDbName = jDbName ? s3jni_jstring_to_utf8( jDbName, 0) : 0; + if( jDbName && !*zDbName ){ + rc = SQLITE_NOMEM; + goto end; + } + jDb = new_java_sqlite3(env, 0); + if( !jDb ){ + sqlite3_free(*zDbName); + *zDbName = 0; + rc = SQLITE_NOMEM; + goto end; + } + *ps = S3JniDb_alloc(env, jDb); + if( *ps ){ + (*jc)->pdbOpening = *ps; + }else{ + S3JniUnrefLocal(jDb); + rc = SQLITE_NOMEM; + } +end: + return rc; +} + +/* +** Post-open() code common to both the sqlite3_open() and +** sqlite3_open_v2() bindings. ps->jDb must be the +** org.sqlite.jni.capi.sqlite3 object which will hold the db's native +** pointer. theRc must be the result code of the open() op. If +** *ppDb is NULL then ps is set aside and its state cleared, +** else ps is associated with *ppDb. If *ppDb is not NULL then +** ps->jDb is stored in jOut (an OutputPointer.sqlite3 instance). +** +** Must be called if s3jni_open_pre() succeeds and must not be called +** if it doesn't. +** +** Returns theRc. +*/ +static int s3jni_open_post(JNIEnv * const env, S3JniEnv * const jc, + S3JniDb * ps, sqlite3 **ppDb, + jobject jOut, int theRc){ + int rc = 0; + jc->pdbOpening = 0; + if( *ppDb ){ + assert(ps->jDb); + if( 0==ps->pDb ){ + ps->pDb = *ppDb; + NativePointerHolder_set(S3JniNph(sqlite3), ps->jDb, *ppDb); + }else{ + assert( ps->pDb==*ppDb + && "Set up via s3jni_run_java_auto_extensions()" ); + } + rc = sqlite3_set_clientdata(ps->pDb, S3JniDb_clientdata_key, + ps, S3JniDb_xDestroy) + /* As of here, the Java/C connection is complete */; + }else{ + S3JniDb_set_aside(ps); + ps = 0; + } + OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3), + jOut, ps ? ps->jDb : 0); + return theRc ? theRc : rc; +} + +S3JniApi(sqlite3_open(),jint,1open)( + JniArgsEnvClass, jstring strName, jobject jOut +){ + sqlite3 * pOut = 0; + char *zName = 0; + S3JniDb * ps = 0; + S3JniEnv * jc = 0; + int rc; + + if( 0==jOut ) return SQLITE_MISUSE; + rc = s3jni_open_pre(env, &jc, strName, &zName, &ps); + if( 0==rc ){ + rc = s3jni_open_post(env, jc, ps, &pOut, jOut, + sqlite3_open(zName, &pOut)); + assert(rc==0 ? pOut!=0 : 1); + sqlite3_free(zName); + } + return (jint)rc; +} + +S3JniApi(sqlite3_open_v2(),jint,1open_1v2)( + JniArgsEnvClass, jstring strName, + jobject jOut, jint flags, jstring strVfs +){ + sqlite3 * pOut = 0; + char *zName = 0; + S3JniDb * ps = 0; + S3JniEnv * jc = 0; + char *zVfs = 0; + int rc; + + if( 0==jOut ) return SQLITE_MISUSE; + rc = s3jni_open_pre(env, &jc, strName, &zName, &ps); + if( 0==rc ){ + if( strVfs ){ + zVfs = s3jni_jstring_to_utf8( strVfs, 0); + if( !zVfs ){ + rc = SQLITE_NOMEM; + } + } + if( 0==rc ){ + rc = sqlite3_open_v2(zName, &pOut, (int)flags, zVfs); + } + rc = s3jni_open_post(env, jc, ps, &pOut, jOut, rc); + } + assert(rc==0 ? pOut!=0 : 1); + sqlite3_free(zName); + sqlite3_free(zVfs); + return (jint)rc; +} + +/* Proxy for the sqlite3_prepare[_v2/3]() family. */ +jint sqlite3_jni_prepare_v123( int prepVersion, JNIEnv * const env, jclass self, + jlong jpDb, jbyteArray baSql, + jint nMax, jint prepFlags, + jobject jOutStmt, jobject outTail){ + sqlite3_stmt * pStmt = 0; + jobject jStmt = 0; + const char * zTail = 0; + sqlite3 * const pDb = S3JniLongPtr_sqlite3(jpDb); + jbyte * const pBuf = pDb ? s3jni_jbyteArray_bytes(baSql) : 0; + int rc = SQLITE_ERROR; + + assert(prepVersion==1 || prepVersion==2 || prepVersion==3); + if( !pDb || !jOutStmt ){ + rc = SQLITE_MISUSE; + goto end; + }else if( !pBuf ){ + rc = baSql ? SQLITE_NOMEM : SQLITE_MISUSE; + goto end; + } + jStmt = new_java_sqlite3_stmt(env, 0); + if( !jStmt ){ + rc = SQLITE_NOMEM; + goto end; + } + switch( prepVersion ){ + case 1: rc = sqlite3_prepare(pDb, (const char *)pBuf, + (int)nMax, &pStmt, &zTail); + break; + case 2: rc = sqlite3_prepare_v2(pDb, (const char *)pBuf, + (int)nMax, &pStmt, &zTail); + break; + case 3: rc = sqlite3_prepare_v3(pDb, (const char *)pBuf, + (int)nMax, (unsigned int)prepFlags, + &pStmt, &zTail); + break; + default: + assert(!"Invalid prepare() version"); + } +end: + s3jni_jbyteArray_release(baSql,pBuf); + if( 0==rc ){ + if( 0!=outTail ){ + /* Noting that pBuf is deallocated now but its address is all we need for + ** what follows... */ + assert(zTail ? ((void*)zTail>=(void*)pBuf) : 1); + assert(zTail ? (((int)((void*)zTail - (void*)pBuf)) >= 0) : 1); + OutputPointer_set_Int32( + env, outTail, (int)(zTail ? (zTail - (const char *)pBuf) : 0) + ); + } + if( pStmt ){ + NativePointerHolder_set(S3JniNph(sqlite3_stmt), jStmt, pStmt); + }else{ + /* Happens for comments and whitespace. */ + S3JniUnrefLocal(jStmt); + jStmt = 0; + } + }else{ + S3JniUnrefLocal(jStmt); + jStmt = 0; + } + if( jOutStmt ){ + OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_stmt), + jOutStmt, jStmt); + } + return (jint)rc; +} +S3JniApi(sqlite3_prepare(),jint,1prepare)( + JNIEnv * const env, jclass self, jlong jpDb, jbyteArray baSql, + jint nMax, jobject jOutStmt, jobject outTail +){ + return sqlite3_jni_prepare_v123(1, env, self, jpDb, baSql, nMax, 0, + jOutStmt, outTail); +} +S3JniApi(sqlite3_prepare_v2(),jint,1prepare_1v2)( + JNIEnv * const env, jclass self, jlong jpDb, jbyteArray baSql, + jint nMax, jobject jOutStmt, jobject outTail +){ + return sqlite3_jni_prepare_v123(2, env, self, jpDb, baSql, nMax, 0, + jOutStmt, outTail); +} +S3JniApi(sqlite3_prepare_v3(),jint,1prepare_1v3)( + JNIEnv * const env, jclass self, jlong jpDb, jbyteArray baSql, + jint nMax, jint prepFlags, jobject jOutStmt, jobject outTail +){ + return sqlite3_jni_prepare_v123(3, env, self, jpDb, baSql, nMax, + prepFlags, jOutStmt, outTail); +} + +/* +** Impl for C-to-Java of the callbacks for both sqlite3_update_hook() +** and sqlite3_preupdate_hook(). The differences are that for +** update_hook(): +** +** - pDb is NULL +** - iKey1 is the row ID +** - iKey2 is unused +*/ +static void s3jni_updatepre_hook_impl(void * pState, sqlite3 *pDb, int opId, + const char *zDb, const char *zTable, + sqlite3_int64 iKey1, sqlite3_int64 iKey2){ + S3JniDb * const ps = pState; + S3JniDeclLocal_env; + jstring jDbName; + jstring jTable; + const int isPre = 0!=pDb; + S3JniHook hook; + + S3JniHook_localdup(isPre ? +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + &ps->hooks.preUpdate +#else + &S3JniHook_empty +#endif + : &ps->hooks.update, &hook); + if( !hook.jObj ){ + return; + } + jDbName = s3jni_utf8_to_jstring( zDb, -1); + jTable = jDbName ? s3jni_utf8_to_jstring( zTable, -1) : 0; + S3JniIfThrew { + S3JniExceptionClear; + s3jni_db_error(ps->pDb, SQLITE_NOMEM, 0); + }else{ + assert( hook.jObj ); + assert( hook.midCallback ); + assert( ps->jDb ); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( isPre ) (*env)->CallVoidMethod(env, hook.jObj, hook.midCallback, + ps->jDb, (jint)opId, jDbName, jTable, + (jlong)iKey1, (jlong)iKey2); + else +#endif + (*env)->CallVoidMethod(env, hook.jObj, hook.midCallback, + (jint)opId, jDbName, jTable, (jlong)iKey1); + S3JniIfThrew{ + S3JniExceptionWarnCallbackThrew("sqlite3_(pre)update_hook() callback"); + s3jni_db_exception(ps->pDb, 0, + "sqlite3_(pre)update_hook() callback threw"); + } + } + S3JniUnrefLocal(jDbName); + S3JniUnrefLocal(jTable); + S3JniHook_localundup(hook); +} + +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK +static void s3jni_preupdate_hook_impl(void * pState, sqlite3 *pDb, int opId, + const char *zDb, const char *zTable, + sqlite3_int64 iKey1, sqlite3_int64 iKey2){ + return s3jni_updatepre_hook_impl(pState, pDb, opId, zDb, zTable, + iKey1, iKey2); +} +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ + +static void s3jni_update_hook_impl(void * pState, int opId, const char *zDb, + const char *zTable, sqlite3_int64 nRowid){ + return s3jni_updatepre_hook_impl(pState, NULL, opId, zDb, zTable, nRowid, 0); +} + +#if !defined(SQLITE_ENABLE_PREUPDATE_HOOK) +/* We need no-op impls for preupdate_{count,depth,blobwrite}() */ +S3JniApi(sqlite3_preupdate_blobwrite(),int,1preupdate_1blobwrite)( + JniArgsEnvClass, jlong jDb){ return SQLITE_MISUSE; } +S3JniApi(sqlite3_preupdate_count(),int,1preupdate_1count)( + JniArgsEnvClass, jlong jDb){ return SQLITE_MISUSE; } +S3JniApi(sqlite3_preupdate_depth(),int,1preupdate_1depth)( + JniArgsEnvClass, jlong jDb){ return SQLITE_MISUSE; } +#endif /* !SQLITE_ENABLE_PREUPDATE_HOOK */ + +/* +** JNI wrapper for both sqlite3_update_hook() and +** sqlite3_preupdate_hook() (if isPre is true). +*/ +static jobject s3jni_updatepre_hook(JNIEnv * env, int isPre, jlong jpDb, jobject jHook){ + S3JniDb * const ps = S3JniDb_from_jlong(jpDb); + jclass klazz; + jobject pOld = 0; + jmethodID xCallback; + S3JniHook * pHook; + + if( !ps ) return 0; + S3JniDb_mutex_enter; + pHook = isPre ? +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + &ps->hooks.preUpdate +#else + 0 +#endif + : &ps->hooks.update; + if( !pHook ){ + goto end; + } + pOld = pHook->jObj; + if( pOld && jHook && (*env)->IsSameObject(env, pOld, jHook) ){ + goto end; + } + if( !jHook ){ + if( pOld ){ + jobject tmp = S3JniRefLocal(pOld); + S3JniUnrefGlobal(pOld); + pOld = tmp; + } + *pHook = S3JniHook_empty; +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( isPre ) sqlite3_preupdate_hook(ps->pDb, 0, 0); + else +#endif + sqlite3_update_hook(ps->pDb, 0, 0); + goto end; + } + klazz = (*env)->GetObjectClass(env, jHook); + xCallback = isPre + ? (*env)->GetMethodID(env, klazz, "call", + "(Lorg/sqlite/jni/capi/sqlite3;" + "I" + "Ljava/lang/String;" + "Ljava/lang/String;" + "JJ)V") + : (*env)->GetMethodID(env, klazz, "call", + "(ILjava/lang/String;Ljava/lang/String;J)V"); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + S3JniExceptionClear; + s3jni_db_error(ps->pDb, SQLITE_ERROR, + "Cannot not find matching callback on " + "(pre)update hook object."); + }else{ + pHook->midCallback = xCallback; + pHook->jObj = S3JniRefGlobal(jHook); +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + if( isPre ) sqlite3_preupdate_hook(ps->pDb, s3jni_preupdate_hook_impl, ps); + else +#endif + sqlite3_update_hook(ps->pDb, s3jni_update_hook_impl, ps); + if( pOld ){ + jobject tmp = S3JniRefLocal(pOld); + S3JniUnrefGlobal(pOld); + pOld = tmp; + } + } +end: + S3JniDb_mutex_leave; + return pOld; +} + + +S3JniApi(sqlite3_preupdate_hook(),jobject,1preupdate_1hook)( + JniArgsEnvClass, jlong jpDb, jobject jHook +){ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + return s3jni_updatepre_hook(env, 1, jpDb, jHook); +#else + return NULL; +#endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ +} + +/* Impl for sqlite3_preupdate_{new,old}(). */ +static int s3jni_preupdate_newold(JNIEnv * const env, int isNew, jlong jpDb, + jint iCol, jobject jOut){ +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK + sqlite3 * const pDb = S3JniLongPtr_sqlite3(jpDb); + int rc = SQLITE_MISUSE; + if( pDb ){ + sqlite3_value * pOut = 0; + int (*fOrig)(sqlite3*,int,sqlite3_value**) = + isNew ? sqlite3_preupdate_new : sqlite3_preupdate_old; + rc = fOrig(pDb, (int)iCol, &pOut); + if( 0==rc ){ + jobject pWrap = new_java_sqlite3_value(env, pOut); + if( !pWrap ){ + rc = SQLITE_NOMEM; + } + OutputPointer_set_obj(env, S3JniNph(OutputPointer_sqlite3_value), + jOut, pWrap); + S3JniUnrefLocal(pWrap); + } + } + return rc; +#else + return SQLITE_MISUSE; +#endif +} + +S3JniApi(sqlite3_preupdate_new(),jint,1preupdate_1new)( + JniArgsEnvClass, jlong jpDb, jint iCol, jobject jOut +){ + return s3jni_preupdate_newold(env, 1, jpDb, iCol, jOut); +} + +S3JniApi(sqlite3_preupdate_old(),jint,1preupdate_1old)( + JniArgsEnvClass, jlong jpDb, jint iCol, jobject jOut +){ + return s3jni_preupdate_newold(env, 0, jpDb, iCol, jOut); +} + + +/* Central C-to-Java sqlite3_progress_handler() proxy. */ +static int s3jni_progress_handler_impl(void *pP){ + S3JniDb * const ps = (S3JniDb *)pP; + int rc = 0; + S3JniDeclLocal_env; + S3JniHook hook; + + S3JniHook_localdup(&ps->hooks.progress, &hook); + if( hook.jObj ){ + rc = (int)(*env)->CallIntMethod(env, hook.jObj, hook.midCallback); + S3JniIfThrew{ + rc = s3jni_db_exception(ps->pDb, rc, + "sqlite3_progress_handler() callback threw"); + } + S3JniHook_localundup(hook); + } + return rc; +} + +S3JniApi(sqlite3_progress_handler(),void,1progress_1handler)( + JniArgsEnvClass,jobject jDb, jint n, jobject jProgress +){ + S3JniDb * const ps = S3JniDb_from_java(jDb); + S3JniHook * const pHook = ps ? &ps->hooks.progress : 0; + + if( !ps ) return; + S3JniDb_mutex_enter; + if( n<1 || !jProgress ){ + S3JniHook_unref(pHook); + sqlite3_progress_handler(ps->pDb, 0, 0, 0); + }else{ + jclass const klazz = (*env)->GetObjectClass(env, jProgress); + jmethodID const xCallback = (*env)->GetMethodID(env, klazz, "call", "()I"); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + S3JniExceptionClear; + s3jni_db_error(ps->pDb, SQLITE_ERROR, + "Cannot not find matching xCallback() on " + "ProgressHandler object."); + }else{ + S3JniUnrefGlobal(pHook->jObj); + pHook->midCallback = xCallback; + pHook->jObj = S3JniRefGlobal(jProgress); + sqlite3_progress_handler(ps->pDb, (int)n, s3jni_progress_handler_impl, ps); + } + } + S3JniDb_mutex_leave; +} + +S3JniApi(sqlite3_randomness(),void,1randomness)( + JniArgsEnvClass, jbyteArray jTgt +){ + jbyte * const jba = s3jni_jbyteArray_bytes(jTgt); + if( jba ){ + jsize const nTgt = (*env)->GetArrayLength(env, jTgt); + sqlite3_randomness( (int)nTgt, jba ); + s3jni_jbyteArray_commit(jTgt, jba); + } +} + + +S3JniApi(sqlite3_reset(),jint,1reset)( + JniArgsEnvClass, jobject jpStmt +){ + sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); + return pStmt ? sqlite3_reset(pStmt) : SQLITE_MISUSE; +} + +/* Clears all entries from S3JniGlobal.autoExt. */ +static void s3jni_reset_auto_extension(JNIEnv *env){ + int i; + S3JniAutoExt_mutex_enter; + for( i = 0; i < SJG.autoExt.nExt; ++i ){ + S3JniAutoExtension_clear( &SJG.autoExt.aExt[i] ); + } + SJG.autoExt.nExt = 0; + S3JniAutoExt_mutex_leave; +} + +S3JniApi(sqlite3_reset_auto_extension(),void,1reset_1auto_1extension)( + JniArgsEnvClass +){ + s3jni_reset_auto_extension(env); +} + +/* Impl for sqlite3_result_text/blob() and friends. */ +static void result_blob_text(int as64 /* true for text64/blob64() mode */, + int eTextRep /* 0 for blobs, else SQLITE_UTF... */, + JNIEnv * const env, sqlite3_context *pCx, + jbyteArray jBa, jlong nMax){ + int const asBlob = 0==eTextRep; + if( !pCx ){ + /* We should arguably emit a warning here. But where to log it? */ + return; + }else if( jBa ){ + jbyte * const pBuf = s3jni_jbyteArray_bytes(jBa); + jsize nBA = (*env)->GetArrayLength(env, jBa); + if( nMax>=0 && nBA>(jsize)nMax ){ + nBA = (jsize)nMax; + /** + From the sqlite docs: + + > If the 3rd parameter to any of the sqlite3_result_text* + interfaces other than sqlite3_result_text64() is negative, + then SQLite computes the string length itself by searching + the 2nd parameter for the first zero character. + + Note that the text64() interfaces take an unsigned value for + the length, which Java does not support. This binding takes + the approach of passing on negative values to the C API, + which will in turn fail with SQLITE_TOOBIG at some later + point (recall that the sqlite3_result_xyz() family do not + have result values). + */ + } + if( as64 ){ /* 64-bit... */ + static const jsize nLimit64 = + SQLITE_MAX_ALLOCATION_SIZE/*only _kinda_ arbitrary*/; + if( nBA > nLimit64 ){ + sqlite3_result_error_toobig(pCx); + }else if( asBlob ){ + sqlite3_result_blob64(pCx, pBuf, (sqlite3_uint64)nBA, + SQLITE_TRANSIENT); + }else{ /* text64... */ + if( encodingTypeIsValid(eTextRep) ){ + sqlite3_result_text64(pCx, (const char *)pBuf, + (sqlite3_uint64)nBA, + SQLITE_TRANSIENT, eTextRep); + }else{ + sqlite3_result_error_code(pCx, SQLITE_FORMAT); + } + } + }else{ /* 32-bit... */ + static const jsize nLimit = SQLITE_MAX_ALLOCATION_SIZE; + if( nBA > nLimit ){ + sqlite3_result_error_toobig(pCx); + }else if( asBlob ){ + sqlite3_result_blob(pCx, pBuf, (int)nBA, + SQLITE_TRANSIENT); + }else{ + switch( eTextRep ){ + case SQLITE_UTF8: + sqlite3_result_text(pCx, (const char *)pBuf, (int)nBA, + SQLITE_TRANSIENT); + break; + case SQLITE_UTF16: + sqlite3_result_text16(pCx, (const char *)pBuf, (int)nBA, + SQLITE_TRANSIENT); + break; + case SQLITE_UTF16LE: + sqlite3_result_text16le(pCx, (const char *)pBuf, (int)nBA, + SQLITE_TRANSIENT); + break; + case SQLITE_UTF16BE: + sqlite3_result_text16be(pCx, (const char *)pBuf, (int)nBA, + SQLITE_TRANSIENT); + break; + } + } + s3jni_jbyteArray_release(jBa, pBuf); + } + }else{ + sqlite3_result_null(pCx); + } +} + +S3JniApi(sqlite3_result_blob(),void,1result_1blob)( + JniArgsEnvClass, jobject jpCx, jbyteArray jBa, jint nMax +){ + return result_blob_text(0, 0, env, PtrGet_sqlite3_context(jpCx), jBa, nMax); +} + +S3JniApi(sqlite3_result_blob64(),void,1result_1blob64)( + JniArgsEnvClass, jobject jpCx, jbyteArray jBa, jlong nMax +){ + return result_blob_text(1, 0, env, PtrGet_sqlite3_context(jpCx), jBa, nMax); +} + +S3JniApi(sqlite3_result_double(),void,1result_1double)( + JniArgsEnvClass, jobject jpCx, jdouble v +){ + sqlite3_result_double(PtrGet_sqlite3_context(jpCx), v); +} + +S3JniApi(sqlite3_result_error(),void,1result_1error)( + JniArgsEnvClass, jobject jpCx, jbyteArray baMsg, int eTextRep +){ + const char * zUnspecified = "Unspecified error."; + jsize const baLen = (*env)->GetArrayLength(env, baMsg); + jbyte * const pjBuf = baMsg ? s3jni_jbyteArray_bytes(baMsg) : NULL; + switch( pjBuf ? eTextRep : SQLITE_UTF8 ){ + case SQLITE_UTF8: { + const char *zMsg = pjBuf ? (const char *)pjBuf : zUnspecified; + int const n = pjBuf ? (int)baLen : (int)sqlite3Strlen30(zMsg); + sqlite3_result_error(PtrGet_sqlite3_context(jpCx), zMsg, n); + break; + } + case SQLITE_UTF16: { + const void *zMsg = pjBuf; + sqlite3_result_error16(PtrGet_sqlite3_context(jpCx), zMsg, (int)baLen); + break; + } + default: + sqlite3_result_error(PtrGet_sqlite3_context(jpCx), + "Invalid encoding argument passed " + "to sqlite3_result_error().", -1); + break; + } + s3jni_jbyteArray_release(baMsg,pjBuf); +} + +S3JniApi(sqlite3_result_error_code(),void,1result_1error_1code)( + JniArgsEnvClass, jobject jpCx, jint v +){ + sqlite3_result_error_code(PtrGet_sqlite3_context(jpCx), (int)v); +} + +S3JniApi(sqlite3_result_error_nomem(),void,1result_1error_1nomem)( + JniArgsEnvClass, jobject jpCx +){ + sqlite3_result_error_nomem(PtrGet_sqlite3_context(jpCx)); +} + +S3JniApi(sqlite3_result_error_toobig(),void,1result_1error_1toobig)( + JniArgsEnvClass, jobject jpCx +){ + sqlite3_result_error_toobig(PtrGet_sqlite3_context(jpCx)); +} + +S3JniApi(sqlite3_result_int(),void,1result_1int)( + JniArgsEnvClass, jobject jpCx, jint v +){ + sqlite3_result_int(PtrGet_sqlite3_context(jpCx), (int)v); +} + +S3JniApi(sqlite3_result_int64(),void,1result_1int64)( + JniArgsEnvClass, jobject jpCx, jlong v +){ + sqlite3_result_int64(PtrGet_sqlite3_context(jpCx), (sqlite3_int64)v); +} + +S3JniApi(sqlite3_result_java_object(),void,1result_1java_1object)( + JniArgsEnvClass, jobject jpCx, jobject v +){ + sqlite3_context * pCx = PtrGet_sqlite3_context(jpCx); + if( !pCx ) return; + else if( v ){ + jobject const rjv = S3JniRefGlobal(v); + if( rjv ){ + sqlite3_result_pointer(pCx, rjv, + ResultJavaValuePtrStr, S3Jni_jobject_finalizer); + }else{ + sqlite3_result_error_nomem(PtrGet_sqlite3_context(jpCx)); + } + }else{ + sqlite3_result_null(PtrGet_sqlite3_context(jpCx)); + } +} + +S3JniApi(sqlite3_result_null(),void,1result_1null)( + JniArgsEnvClass, jobject jpCx +){ + sqlite3_result_null(PtrGet_sqlite3_context(jpCx)); +} + +S3JniApi(sqlite3_result_text(),void,1result_1text)( + JniArgsEnvClass, jobject jpCx, jbyteArray jBa, jint nMax +){ + return result_blob_text(0, SQLITE_UTF8, env, + PtrGet_sqlite3_context(jpCx), jBa, nMax); +} + +S3JniApi(sqlite3_result_text64(),void,1result_1text64)( + JniArgsEnvClass, jobject jpCx, jbyteArray jBa, jlong nMax, + jint eTextRep +){ + return result_blob_text(1, eTextRep, env, + PtrGet_sqlite3_context(jpCx), jBa, nMax); +} + +S3JniApi(sqlite3_result_value(),void,1result_1value)( + JniArgsEnvClass, jobject jpCx, jobject jpSVal +){ + sqlite3_result_value(PtrGet_sqlite3_context(jpCx), + PtrGet_sqlite3_value(jpSVal)); +} + +S3JniApi(sqlite3_result_zeroblob(),void,1result_1zeroblob)( + JniArgsEnvClass, jobject jpCx, jint v +){ + sqlite3_result_zeroblob(PtrGet_sqlite3_context(jpCx), (int)v); +} + +S3JniApi(sqlite3_result_zeroblob64(),jint,1result_1zeroblob64)( + JniArgsEnvClass, jobject jpCx, jlong v +){ + return (jint)sqlite3_result_zeroblob64(PtrGet_sqlite3_context(jpCx), + (sqlite3_int64)v); +} + +S3JniApi(sqlite3_rollback_hook(),jobject,1rollback_1hook)( + JniArgsEnvClass, jlong jpDb, jobject jHook +){ + return s3jni_commit_rollback_hook(0, env, jpDb, jHook); +} + +/* Callback for sqlite3_set_authorizer(). */ +int s3jni_xAuth(void* pState, int op,const char*z0, const char*z1, + const char*z2,const char*z3){ + S3JniDb * const ps = pState; + S3JniDeclLocal_env; + S3JniHook hook; + int rc = 0; + + S3JniHook_localdup(&ps->hooks.auth, &hook ); + if( hook.jObj ){ + jstring const s0 = z0 ? s3jni_utf8_to_jstring( z0, -1) : 0; + jstring const s1 = z1 ? s3jni_utf8_to_jstring( z1, -1) : 0; + jstring const s2 = z2 ? s3jni_utf8_to_jstring( z2, -1) : 0; + jstring const s3 = z3 ? s3jni_utf8_to_jstring( z3, -1) : 0; + + rc = (*env)->CallIntMethod(env, hook.jObj, hook.midCallback, (jint)op, + s0, s1, s3, s3); + S3JniIfThrew{ + rc = s3jni_db_exception(ps->pDb, rc, "sqlite3_set_authorizer() callback"); + } + S3JniUnrefLocal(s0); + S3JniUnrefLocal(s1); + S3JniUnrefLocal(s2); + S3JniUnrefLocal(s3); + S3JniHook_localundup(hook); + } + return rc; +} + +S3JniApi(sqlite3_set_authorizer(),jint,1set_1authorizer)( + JniArgsEnvClass,jobject jDb, jobject jHook +){ + S3JniDb * const ps = S3JniDb_from_java(jDb); + S3JniHook * const pHook = ps ? &ps->hooks.auth : 0; + int rc = 0; + + if( !ps ) return SQLITE_MISUSE; + S3JniDb_mutex_enter; + if( !jHook ){ + S3JniHook_unref(pHook); + rc = sqlite3_set_authorizer( ps->pDb, 0, 0 ); + }else{ + jclass klazz; + if( pHook->jObj ){ + if( (*env)->IsSameObject(env, pHook->jObj, jHook) ){ + /* Same object - this is a no-op. */ + S3JniDb_mutex_leave; + return 0; + } + S3JniHook_unref(pHook); + } + pHook->jObj = S3JniRefGlobal(jHook); + klazz = (*env)->GetObjectClass(env, jHook); + pHook->midCallback = (*env)->GetMethodID(env, klazz, + "call", + "(I" + "Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;" + "Ljava/lang/String;" + ")I"); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + rc = s3jni_db_error(ps->pDb, SQLITE_ERROR, + "Error setting up Java parts of authorizer hook."); + }else{ + rc = sqlite3_set_authorizer(ps->pDb, s3jni_xAuth, ps); + } + if( rc ) S3JniHook_unref(pHook); + } + S3JniDb_mutex_leave; + return rc; +} + +S3JniApi(sqlite3_set_auxdata(),void,1set_1auxdata)( + JniArgsEnvClass, jobject jCx, jint n, jobject jAux +){ + sqlite3_set_auxdata(PtrGet_sqlite3_context(jCx), (int)n, + S3JniRefGlobal(jAux), S3Jni_jobject_finalizer); +} + +S3JniApi(sqlite3_set_last_insert_rowid(),void,1set_1last_1insert_1rowid)( + JniArgsEnvClass, jobject jpDb, jlong rowId +){ + sqlite3_set_last_insert_rowid(PtrGet_sqlite3(jpDb), + (sqlite3_int64)rowId); +} + +S3JniApi(sqlite3_shutdown(),jint,1shutdown)( + JniArgsEnvClass +){ + s3jni_reset_auto_extension(env); +#ifdef SQLITE_ENABLE_SQLLOG + S3JniHook_unref(&SJG.hook.sqllog); +#endif + S3JniHook_unref(&SJG.hook.configlog); + /* Free up S3JniDb recycling bin. */ + S3JniDb_mutex_enter; { + while( S3JniGlobal.perDb.aFree ){ + S3JniDb * const d = S3JniGlobal.perDb.aFree; + S3JniGlobal.perDb.aFree = d->pNext; + S3JniDb_clear(env, d); + sqlite3_free(d); + } + } S3JniDb_mutex_leave; + S3JniGlobal_mutex_enter; { + /* Free up S3JniUdf recycling bin. */ + while( S3JniGlobal.udf.aFree ){ + S3JniUdf * const u = S3JniGlobal.udf.aFree; + S3JniGlobal.udf.aFree = u->pNext; + u->pNext = 0; + S3JniUdf_free(env, u, 0); + } + } S3JniGlobal_mutex_leave; + S3JniHook_mutex_enter; { + /* Free up S3JniHook recycling bin. */ + while( S3JniGlobal.hook.aFree ){ + S3JniHook * const u = S3JniGlobal.hook.aFree; + S3JniGlobal.hook.aFree = u->pNext; + u->pNext = 0; + assert( !u->doXDestroy ); + assert( !u->jObj ); + assert( !u->jExtra ); + sqlite3_free( u ); + } + } S3JniHook_mutex_leave; + /* Free up env cache. */ + S3JniEnv_mutex_enter; { + while( SJG.envCache.aHead ){ + S3JniEnv_uncache( SJG.envCache.aHead->env ); + } + } S3JniEnv_mutex_leave; +#if 0 + /* + ** Is automatically closing any still-open dbs a good idea? We will + ** get rid of the perDb list once sqlite3 gets a per-db client + ** state, at which point we won't have a central list of databases + ** to close. + */ + S3JniDb_mutex_enter; + while( SJG.perDb.pHead ){ + s3jni_close_db(env, SJG.perDb.pHead->jDb, 2); + } + S3JniDb_mutex_leave; +#endif + /* Do not clear S3JniGlobal.jvm: it's legal to restart the lib. */ + return sqlite3_shutdown(); +} + +S3JniApi(sqlite3_status(),jint,1status)( + JniArgsEnvClass, jint op, jobject jOutCurrent, jobject jOutHigh, + jboolean reset +){ + int iCur = 0, iHigh = 0; + int rc = sqlite3_status( op, &iCur, &iHigh, reset ); + if( 0==rc ){ + OutputPointer_set_Int32(env, jOutCurrent, iCur); + OutputPointer_set_Int32(env, jOutHigh, iHigh); + } + return (jint)rc; +} + +S3JniApi(sqlite3_status64(),jint,1status64)( + JniArgsEnvClass, jint op, jobject jOutCurrent, jobject jOutHigh, + jboolean reset +){ + sqlite3_int64 iCur = 0, iHigh = 0; + int rc = sqlite3_status64( op, &iCur, &iHigh, reset ); + if( 0==rc ){ + OutputPointer_set_Int64(env, jOutCurrent, iCur); + OutputPointer_set_Int64(env, jOutHigh, iHigh); + } + return (jint)rc; +} + +S3JniApi(sqlite3_stmt_status(),jint,1stmt_1status)( + JniArgsEnvClass, jobject jStmt, jint op, jboolean reset +){ + return sqlite3_stmt_status(PtrGet_sqlite3_stmt(jStmt), + (int)op, reset ? 1 : 0); +} + + +static int s3jni_strlike_glob(int isLike, JNIEnv *const env, + jbyteArray baG, jbyteArray baT, jint escLike){ + int rc = 0; + jbyte * const pG = s3jni_jbyteArray_bytes(baG); + jbyte * const pT = pG ? s3jni_jbyteArray_bytes(baT) : 0; + + /* Note that we're relying on the byte arrays having been + NUL-terminated on the Java side. */ + rc = isLike + ? sqlite3_strlike((const char *)pG, (const char *)pT, + (unsigned int)escLike) + : sqlite3_strglob((const char *)pG, (const char *)pT); + s3jni_jbyteArray_release(baG, pG); + s3jni_jbyteArray_release(baT, pT); + return rc; +} + +S3JniApi(sqlite3_strglob(),jint,1strglob)( + JniArgsEnvClass, jbyteArray baG, jbyteArray baT +){ + return s3jni_strlike_glob(0, env, baG, baT, 0); +} + +S3JniApi(sqlite3_strlike(),jint,1strlike)( + JniArgsEnvClass, jbyteArray baG, jbyteArray baT, jint escChar +){ + return s3jni_strlike_glob(1, env, baG, baT, escChar); +} + +S3JniApi(sqlite3_sql(),jstring,1sql)( + JniArgsEnvClass, jobject jpStmt +){ + sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jpStmt); + jstring rv = 0; + if( pStmt ){ + const char * zSql = 0; + zSql = sqlite3_sql(pStmt); + rv = s3jni_utf8_to_jstring( zSql, -1); + } + return rv; +} + +S3JniApi(sqlite3_step(),jint,1step)( + JniArgsEnvClass,jobject jStmt +){ + sqlite3_stmt * const pStmt = PtrGet_sqlite3_stmt(jStmt); + return pStmt ? (jint)sqlite3_step(pStmt) : (jint)SQLITE_MISUSE; +} + +S3JniApi(sqlite3_table_column_metadata(),int,1table_1column_1metadata)( + JniArgsEnvClass, jobject jDb, jstring jDbName, jstring jTableName, + jstring jColumnName, jobject jDataType, jobject jCollSeq, jobject jNotNull, + jobject jPrimaryKey, jobject jAutoinc +){ + sqlite3 * const db = PtrGet_sqlite3(jDb); + char * zDbName = 0, * zTableName = 0, * zColumnName = 0; + const char * pzCollSeq = 0; + const char * pzDataType = 0; + int pNotNull = 0, pPrimaryKey = 0, pAutoinc = 0; + int rc; + + if( !db || !jDbName || !jTableName ) return SQLITE_MISUSE; + zDbName = s3jni_jstring_to_utf8(jDbName,0); + zTableName = zDbName ? s3jni_jstring_to_utf8(jTableName,0) : 0; + zColumnName = (zTableName && jColumnName) + ? s3jni_jstring_to_utf8(jColumnName,0) : 0; + rc = zTableName + ? sqlite3_table_column_metadata(db, zDbName, zTableName, + zColumnName, &pzDataType, &pzCollSeq, + &pNotNull, &pPrimaryKey, &pAutoinc) + : SQLITE_NOMEM; + if( 0==rc ){ + jstring jseq = jCollSeq + ? (pzCollSeq ? s3jni_utf8_to_jstring(pzCollSeq, -1) : 0) + : 0; + jstring jdtype = jDataType + ? (pzDataType ? s3jni_utf8_to_jstring(pzDataType, -1) : 0) + : 0; + if( (jCollSeq && pzCollSeq && !jseq) + || (jDataType && pzDataType && !jdtype) ){ + rc = SQLITE_NOMEM; + }else{ + if( jNotNull ) OutputPointer_set_Bool(env, jNotNull, pNotNull); + if( jPrimaryKey ) OutputPointer_set_Bool(env, jPrimaryKey, pPrimaryKey); + if( jAutoinc ) OutputPointer_set_Bool(env, jAutoinc, pAutoinc); + if( jCollSeq ) OutputPointer_set_String(env, jCollSeq, jseq); + if( jDataType ) OutputPointer_set_String(env, jDataType, jdtype); + } + S3JniUnrefLocal(jseq); + S3JniUnrefLocal(jdtype); + } + sqlite3_free(zDbName); + sqlite3_free(zTableName); + sqlite3_free(zColumnName); + return rc; +} + +static int s3jni_trace_impl(unsigned traceflag, void *pC, void *pP, void *pX){ + S3JniDb * const ps = (S3JniDb *)pC; + S3JniDeclLocal_env; + jobject jX = NULL /* the tracer's X arg */; + jobject jP = NULL /* the tracer's P arg */; + jobject jPUnref = NULL /* potentially a local ref to jP */; + int rc = 0; + S3JniHook hook; + + S3JniHook_localdup(&ps->hooks.trace, &hook ); + if( !hook.jObj ){ + return 0; + } + switch( traceflag ){ + case SQLITE_TRACE_STMT: + jX = s3jni_utf8_to_jstring( (const char *)pX, -1); + if( !jX ) rc = SQLITE_NOMEM; + break; + case SQLITE_TRACE_PROFILE: + jX = (*env)->NewObject(env, SJG.g.cLong, SJG.g.ctorLong1, + (jlong)*((sqlite3_int64*)pX)); + // hmm. ^^^ (*pX) really is zero. + // MARKER(("profile time = %llu\n", *((sqlite3_int64*)pX))); + s3jni_oom_check( jX ); + if( !jX ) rc = SQLITE_NOMEM; + break; + case SQLITE_TRACE_ROW: + break; + case SQLITE_TRACE_CLOSE: + jP = jPUnref = S3JniRefLocal(ps->jDb); + break; + default: + assert(!"cannot happen - unknown trace flag"); + rc = SQLITE_ERROR; + } + if( 0==rc ){ + if( !jP ){ + /* Create a new temporary sqlite3_stmt wrapper */ + jP = jPUnref = new_java_sqlite3_stmt(env, pP); + if( !jP ){ + rc = SQLITE_NOMEM; + } + } + if( 0==rc ){ + assert(jP); + rc = (int)(*env)->CallIntMethod(env, hook.jObj, hook.midCallback, + (jint)traceflag, jP, jX); + S3JniIfThrew{ + rc = s3jni_db_exception(ps->pDb, SQLITE_ERROR, + "sqlite3_trace_v2() callback threw."); + } + } + } + S3JniUnrefLocal(jPUnref); + S3JniUnrefLocal(jX); + S3JniHook_localundup(hook); + return rc; +} + +S3JniApi(sqlite3_trace_v2(),jint,1trace_1v2)( + JniArgsEnvClass,jobject jDb, jint traceMask, jobject jTracer +){ + S3JniDb * const ps = S3JniDb_from_java(jDb); + int rc; + + if( !ps ) return SQLITE_MISUSE; + if( !traceMask || !jTracer ){ + S3JniDb_mutex_enter; + rc = (jint)sqlite3_trace_v2(ps->pDb, 0, 0, 0); + S3JniHook_unref(&ps->hooks.trace); + S3JniDb_mutex_leave; + }else{ + jclass const klazz = (*env)->GetObjectClass(env, jTracer); + S3JniHook hook = S3JniHook_empty; + hook.midCallback = (*env)->GetMethodID( + env, klazz, "call", "(ILjava/lang/Object;Ljava/lang/Object;)I" + ); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + S3JniExceptionClear; + rc = s3jni_db_error(ps->pDb, SQLITE_ERROR, + "Cannot not find matching call() on " + "TracerCallback object."); + }else{ + hook.jObj = S3JniRefGlobal(jTracer); + S3JniDb_mutex_enter; + rc = sqlite3_trace_v2(ps->pDb, (unsigned)traceMask, s3jni_trace_impl, ps); + if( 0==rc ){ + S3JniHook_unref(&ps->hooks.trace); + ps->hooks.trace = hook /* transfer ownership of reference */; + }else{ + S3JniHook_unref(&hook); + } + S3JniDb_mutex_leave; + } + } + return rc; +} + +S3JniApi(sqlite3_txn_state(),jint,1txn_1state)( + JniArgsEnvClass,jobject jDb, jstring jSchema +){ + sqlite3 * const pDb = PtrGet_sqlite3(jDb); + int rc = SQLITE_MISUSE; + if( pDb ){ + char * zSchema = jSchema + ? s3jni_jstring_to_utf8(jSchema, 0) + : 0; + if( !jSchema || (zSchema && jSchema) ){ + rc = sqlite3_txn_state(pDb, zSchema); + sqlite3_free(zSchema); + }else{ + rc = SQLITE_NOMEM; + } + } + return rc; +} + +S3JniApi(sqlite3_update_hook(),jobject,1update_1hook)( + JniArgsEnvClass, jlong jpDb, jobject jHook +){ + return s3jni_updatepre_hook(env, 0, jpDb, jHook); +} + + +S3JniApi(sqlite3_value_blob(),jbyteArray,1value_1blob)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const jbyte * pBytes = sv ? sqlite3_value_blob(sv) : 0; + int const nLen = pBytes ? sqlite3_value_bytes(sv) : 0; + + s3jni_oom_check( nLen ? !!pBytes : 1 ); + return pBytes + ? s3jni_new_jbyteArray(pBytes, nLen) + : NULL; +} + +S3JniApi(sqlite3_value_bytes(),int,1value_1bytes)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return sv ? sqlite3_value_bytes(sv) : 0; +} + +S3JniApi(sqlite3_value_bytes16(),int,1value_1bytes16)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return sv ? sqlite3_value_bytes16(sv) : 0; +} + + +S3JniApi(sqlite3_value_double(),jdouble,1value_1double)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return (jdouble) (sv ? sqlite3_value_double(sv) : 0.0); +} + + +S3JniApi(sqlite3_value_dup(),jobject,1value_1dup)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + sqlite3_value * const sd = sv ? sqlite3_value_dup(sv) : 0; + jobject rv = sd ? new_java_sqlite3_value(env, sd) : 0; + if( sd && !rv ) { + /* OOM */ + sqlite3_value_free(sd); + } + return rv; +} + +S3JniApi(sqlite3_value_free(),void,1value_1free)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + if( sv ){ + sqlite3_value_free(sv); + } +} + +S3JniApi(sqlite3_value_int(),jint,1value_1int)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return (jint) (sv ? sqlite3_value_int(sv) : 0); +} + +S3JniApi(sqlite3_value_int64(),jlong,1value_1int64)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return (jlong) (sv ? sqlite3_value_int64(sv) : 0LL); +} + +S3JniApi(sqlite3_value_java_object(),jobject,1value_1java_1object)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + return sv + ? sqlite3_value_pointer(sv, ResultJavaValuePtrStr) + : 0; +} + +S3JniApi(sqlite3_value_text(),jbyteArray,1value_1text)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const unsigned char * const p = sv ? sqlite3_value_text(sv) : 0; + int const n = p ? sqlite3_value_bytes(sv) : 0; + return p ? s3jni_new_jbyteArray(p, n) : 0; +} + +#if 0 +// this impl might prove useful. +S3JniApi(sqlite3_value_text(),jstring,1value_1text)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const unsigned char * const p = sv ? sqlite3_value_text(sv) : 0; + int const n = p ? sqlite3_value_bytes(sv) : 0; + return p ? s3jni_utf8_to_jstring( (const char *)p, n) : 0; +} +#endif + +S3JniApi(sqlite3_value_text16(),jstring,1value_1text16)( + JniArgsEnvClass, jlong jpSVal +){ + sqlite3_value * const sv = S3JniLongPtr_sqlite3_value(jpSVal); + const int n = sv ? sqlite3_value_bytes16(sv) : 0; + const void * const p = sv ? sqlite3_value_text16(sv) : 0; + return p ? s3jni_text16_to_jstring(env, p, n) : 0; +} + +JniDecl(void,1jni_1internal_1details)(JniArgsEnvClass){ + MARKER(("\nVarious bits of internal info:\n")); + puts("FTS5 is " +#ifdef SQLITE_ENABLE_FTS5 + "available" +#else + "unavailable" +#endif + "." + ); + puts("sizeofs:"); +#define SO(T) printf("\tsizeof(" #T ") = %u\n", (unsigned)sizeof(T)) + SO(void*); + SO(jmethodID); + SO(jfieldID); + SO(S3JniEnv); + SO(S3JniHook); + SO(S3JniDb); + SO(S3JniNphOps); + printf("\t(^^^ %u NativePointerHolder/OutputPointer.T types)\n", + (unsigned)S3Jni_NphCache_size); + SO(S3JniGlobal); + SO(S3JniGlobal.nph); + SO(S3JniGlobal.metrics); + SO(S3JniAutoExtension); + SO(S3JniUdf); +#undef SO +#ifdef SQLITE_JNI_ENABLE_METRICS + printf("Cache info:\n"); + printf("\tJNIEnv cache: %u allocs, %u misses, %u hits\n", + SJG.metrics.nEnvAlloc, SJG.metrics.nEnvMiss, + SJG.metrics.nEnvHit); + printf("Mutex entry:" + "\n\tglobal = %u" + "\n\tenv = %u" + "\n\tnph = %u for S3JniNphOp init" + "\n\thook = %u" + "\n\tperDb = %u" + "\n\tautoExt list = %u" + "\n\tS3JniUdf = %u (free-list)" + "\n\tmetrics = %u\n", + SJG.metrics.nMutexGlobal, SJG.metrics.nMutexEnv, + SJG.metrics.nMutexNph, SJG.metrics.nMutexHook, + SJG.metrics.nMutexPerDb, SJG.metrics.nMutexAutoExt, + SJG.metrics.nMutexUdf, SJG.metrics.nMetrics); + puts("Allocs:"); + printf("\tS3JniDb: %u alloced (*%u = %u bytes), %u recycled\n", + SJG.metrics.nPdbAlloc, (unsigned) sizeof(S3JniDb), + (unsigned)(SJG.metrics.nPdbAlloc * sizeof(S3JniDb)), + SJG.metrics.nPdbRecycled); + printf("\tS3JniUdf: %u alloced (*%u = %u bytes), %u recycled\n", + SJG.metrics.nUdfAlloc, (unsigned) sizeof(S3JniUdf), + (unsigned)(SJG.metrics.nUdfAlloc * sizeof(S3JniUdf)), + SJG.metrics.nUdfRecycled); + printf("\tS3JniHook: %u alloced (*%u = %u bytes), %u recycled\n", + SJG.metrics.nHookAlloc, (unsigned) sizeof(S3JniHook), + (unsigned)(SJG.metrics.nHookAlloc * sizeof(S3JniHook)), + SJG.metrics.nHookRecycled); + printf("\tS3JniEnv: %u alloced (*%u = %u bytes)\n", + SJG.metrics.nEnvAlloc, (unsigned) sizeof(S3JniEnv), + (unsigned)(SJG.metrics.nEnvAlloc * sizeof(S3JniEnv))); + puts("Java-side UDF calls:"); +#define UDF(T) printf("\t%-8s = %u\n", "x" #T, SJG.metrics.udf.n##T) + UDF(Func); UDF(Step); UDF(Final); UDF(Value); UDF(Inverse); +#undef UDF + printf("xDestroy calls across all callback types: %u\n", + SJG.metrics.nDestroy); +#else + puts("Built without SQLITE_JNI_ENABLE_METRICS."); +#endif +} + +//////////////////////////////////////////////////////////////////////// +// End of the sqlite3_... API bindings. Next up, FTS5... +//////////////////////////////////////////////////////////////////////// +#ifdef SQLITE_ENABLE_FTS5 + +/* Creates a verbose JNI Fts5 function name. */ +#define JniFuncNameFtsXA(Suffix) \ + Java_org_sqlite_jni_fts5_Fts5ExtensionApi_ ## Suffix +#define JniFuncNameFtsApi(Suffix) \ + Java_org_sqlite_jni_fts5_fts5_1api_ ## Suffix +#define JniFuncNameFtsTok(Suffix) \ + Java_org_sqlite_jni_fts5_fts5_tokenizer_ ## Suffix + +#define JniDeclFtsXA(ReturnType,Suffix) \ + JNIEXPORT ReturnType JNICALL \ + JniFuncNameFtsXA(Suffix) +#define JniDeclFtsApi(ReturnType,Suffix) \ + JNIEXPORT ReturnType JNICALL \ + JniFuncNameFtsApi(Suffix) +#define JniDeclFtsTok(ReturnType,Suffix) \ + JNIEXPORT ReturnType JNICALL \ + JniFuncNameFtsTok(Suffix) + +#define PtrGet_fts5_api(OBJ) NativePointerHolder_get(OBJ,S3JniNph(fts5_api)) +#define PtrGet_fts5_tokenizer(OBJ) NativePointerHolder_get(OBJ,S3JniNph(fts5_tokenizer)) +#define PtrGet_Fts5Context(OBJ) NativePointerHolder_get(OBJ,S3JniNph(Fts5Context)) +#define PtrGet_Fts5Tokenizer(OBJ) NativePointerHolder_get(OBJ,S3JniNph(Fts5Tokenizer)) +#define s3jni_ftsext() &sFts5Api/*singleton from sqlite3.c*/ +#define Fts5ExtDecl Fts5ExtensionApi const * const ext = s3jni_ftsext() + +/** + State for binding Java-side FTS5 auxiliary functions. +*/ +typedef struct { + jobject jObj /* functor instance */; + jobject jUserData /* 2nd arg to JNI binding of + xCreateFunction(), ostensibly the 3rd arg + to the lib-level xCreateFunction(), except + that we necessarily use that slot for a + Fts5JniAux instance. */; + char * zFuncName /* Only for error reporting and debug logging */; + jmethodID jmid /* callback member's method ID */; +} Fts5JniAux; + +static void Fts5JniAux_free(Fts5JniAux * const s){ + S3JniDeclLocal_env; + if( env ){ + /*MARKER(("FTS5 aux function cleanup: %s\n", s->zFuncName));*/ + s3jni_call_xDestroy(s->jObj); + S3JniUnrefGlobal(s->jObj); + S3JniUnrefGlobal(s->jUserData); + } + sqlite3_free(s->zFuncName); + sqlite3_free(s); +} + +static void Fts5JniAux_xDestroy(void *p){ + if( p ) Fts5JniAux_free(p); +} + +static Fts5JniAux * Fts5JniAux_alloc(JNIEnv * const env, jobject jObj){ + Fts5JniAux * s = s3jni_malloc( sizeof(Fts5JniAux)); + + if( s ){ + jclass klazz; + memset(s, 0, sizeof(Fts5JniAux)); + s->jObj = S3JniRefGlobal(jObj); + klazz = (*env)->GetObjectClass(env, jObj); + s->jmid = (*env)->GetMethodID(env, klazz, "call", + "(Lorg/sqlite/jni/fts5/Fts5ExtensionApi;" + "Lorg/sqlite/jni/fts5/Fts5Context;" + "Lorg/sqlite/jni/capi/sqlite3_context;" + "[Lorg/sqlite/jni/capi/sqlite3_value;)V"); + S3JniUnrefLocal(klazz); + S3JniIfThrew{ + S3JniExceptionReport; + S3JniExceptionClear; + Fts5JniAux_free(s); + s = 0; + } + } + return s; +} + +static inline jobject new_java_Fts5Context(JNIEnv * const env, Fts5Context *sv){ + return NativePointerHolder_new(env, S3JniNph(Fts5Context), sv); +} +static inline jobject new_java_fts5_api(JNIEnv * const env, fts5_api *sv){ + return NativePointerHolder_new(env, S3JniNph(fts5_api), sv); +} + +/* +** Returns a per-JNIEnv global ref to the Fts5ExtensionApi singleton +** instance, or NULL on OOM. +*/ +static jobject s3jni_getFts5ExensionApi(JNIEnv * const env){ + if( !SJG.fts5.jExt ){ + S3JniGlobal_mutex_enter; + if( !SJG.fts5.jExt ){ + jobject const pNPH = NativePointerHolder_new( + env, S3JniNph(Fts5ExtensionApi), s3jni_ftsext() + ); + if( pNPH ){ + SJG.fts5.jExt = S3JniRefGlobal(pNPH); + S3JniUnrefLocal(pNPH); + } + } + S3JniGlobal_mutex_leave; + } + return SJG.fts5.jExt; +} + +/* +** Returns a pointer to the fts5_api instance for database connection +** db. If an error occurs, returns NULL and leaves an error in the +** database handle (accessible using sqlite3_errcode()/errmsg()). +*/ +static fts5_api *s3jni_fts5_api_from_db(sqlite3 *db){ + fts5_api *pRet = 0; + sqlite3_stmt *pStmt = 0; + if( SQLITE_OK==sqlite3_prepare(db, "SELECT fts5(?1)", -1, &pStmt, 0) ){ + sqlite3_bind_pointer(pStmt, 1, (void*)&pRet, "fts5_api_ptr", NULL); + sqlite3_step(pStmt); + } + sqlite3_finalize(pStmt); + return pRet; +} + +JniDeclFtsApi(jobject,getInstanceForDb)(JniArgsEnvClass,jobject jDb){ + S3JniDb * const ps = S3JniDb_from_java(jDb); +#if 0 + jobject rv = 0; + if( !ps ) return 0; + else if( ps->fts.jApi ){ + rv = ps->fts.jApi; + }else{ + fts5_api * const pApi = s3jni_fts5_api_from_db(ps->pDb); + if( pApi ){ + rv = new_java_fts5_api(env, pApi); + ps->fts.jApi = rv ? S3JniRefGlobal(rv) : 0; + } + } + return rv; +#else + if( ps && !ps->fts.jApi ){ + S3JniDb_mutex_enter; + if( !ps->fts.jApi ){ + fts5_api * const pApi = s3jni_fts5_api_from_db(ps->pDb); + if( pApi ){ + jobject const rv = new_java_fts5_api(env, pApi); + ps->fts.jApi = rv ? S3JniRefGlobal(rv) : 0; + } + } + S3JniDb_mutex_leave; + } + return ps ? ps->fts.jApi : 0; +#endif +} + + +JniDeclFtsXA(jobject,getInstance)(JniArgsEnvClass){ + return s3jni_getFts5ExensionApi(env); +} + +JniDeclFtsXA(jint,xColumnCount)(JniArgsEnvObj,jobject jCtx){ + Fts5ExtDecl; + return (jint)ext->xColumnCount(PtrGet_Fts5Context(jCtx)); +} + +JniDeclFtsXA(jint,xColumnSize)(JniArgsEnvObj,jobject jCtx, jint iIdx, jobject jOut32){ + Fts5ExtDecl; + int n1 = 0; + int const rc = ext->xColumnSize(PtrGet_Fts5Context(jCtx), (int)iIdx, &n1); + if( 0==rc ) OutputPointer_set_Int32(env, jOut32, n1); + return rc; +} + +JniDeclFtsXA(jint,xColumnText)(JniArgsEnvObj,jobject jCtx, jint iCol, + jobject jOut){ + Fts5ExtDecl; + const char *pz = 0; + int pn = 0; + int rc = ext->xColumnText(PtrGet_Fts5Context(jCtx), (int)iCol, + &pz, &pn); + if( 0==rc ){ + jstring jstr = pz ? s3jni_utf8_to_jstring( pz, pn) : 0; + if( pz ){ + if( jstr ){ + OutputPointer_set_String(env, jOut, jstr); + S3JniUnrefLocal(jstr)/*jOut has a reference*/; + }else{ + rc = SQLITE_NOMEM; + } + } + } + return (jint)rc; +} + +JniDeclFtsXA(jint,xColumnTotalSize)(JniArgsEnvObj,jobject jCtx, jint iCol, jobject jOut64){ + Fts5ExtDecl; + sqlite3_int64 nOut = 0; + int const rc = ext->xColumnTotalSize(PtrGet_Fts5Context(jCtx), (int)iCol, &nOut); + if( 0==rc && jOut64 ) OutputPointer_set_Int64(env, jOut64, (jlong)nOut); + return (jint)rc; +} + +/* +** Proxy for fts5_extension_function instances plugged in via +** fts5_api::xCreateFunction(). +*/ +static void s3jni_fts5_extension_function(Fts5ExtensionApi const *pApi, + Fts5Context *pFts, + sqlite3_context *pCx, + int argc, + sqlite3_value **argv){ + Fts5JniAux * const pAux = pApi->xUserData(pFts); + jobject jpCx = 0; + jobjectArray jArgv = 0; + jobject jpFts = 0; + jobject jFXA; + int rc; + S3JniDeclLocal_env; + + assert(pAux); + jFXA = s3jni_getFts5ExensionApi(env); + if( !jFXA ) goto error_oom; + jpFts = new_java_Fts5Context(env, pFts); + if( !jpFts ) goto error_oom; + rc = udf_args(env, pCx, argc, argv, &jpCx, &jArgv); + if( rc ) goto error_oom; + (*env)->CallVoidMethod(env, pAux->jObj, pAux->jmid, + jFXA, jpFts, jpCx, jArgv); + S3JniIfThrew{ + udf_report_exception(env, 1, pCx, pAux->zFuncName, "call"); + } + udf_unargs(env, jpCx, argc, jArgv); + S3JniUnrefLocal(jpFts); + S3JniUnrefLocal(jpCx); + S3JniUnrefLocal(jArgv); + return; +error_oom: + s3jni_db_oom( sqlite3_context_db_handle(pCx) ); + assert( !jArgv ); + assert( !jpCx ); + S3JniUnrefLocal(jpFts); + sqlite3_result_error_nomem(pCx); + return; +} + +JniDeclFtsApi(jint,xCreateFunction)(JniArgsEnvObj, jstring jName, + jobject jUserData, jobject jFunc){ + fts5_api * const pApi = PtrGet_fts5_api(jSelf); + int rc; + char * zName; + Fts5JniAux * pAux; + + assert(pApi); + zName = s3jni_jstring_to_utf8( jName, 0); + if(!zName) return SQLITE_NOMEM; + pAux = Fts5JniAux_alloc(env, jFunc); + if( pAux ){ + rc = pApi->xCreateFunction(pApi, zName, pAux, + s3jni_fts5_extension_function, + Fts5JniAux_xDestroy); + }else{ + rc = SQLITE_NOMEM; + } + if( 0==rc ){ + pAux->jUserData = jUserData ? S3JniRefGlobal(jUserData) : 0; + pAux->zFuncName = zName; + }else{ + sqlite3_free(zName); + } + return (jint)rc; +} + + +typedef struct S3JniFts5AuxData S3JniFts5AuxData; +/* +** TODO: this middle-man struct is no longer necessary. Conider +** removing it and passing around jObj itself instead. +*/ +struct S3JniFts5AuxData { + jobject jObj; +}; + +static void S3JniFts5AuxData_xDestroy(void *x){ + if( x ){ + S3JniFts5AuxData * const p = x; + if( p->jObj ){ + S3JniDeclLocal_env; + s3jni_call_xDestroy(p->jObj); + S3JniUnrefGlobal(p->jObj); + } + sqlite3_free(x); + } +} + +JniDeclFtsXA(jobject,xGetAuxdata)(JniArgsEnvObj,jobject jCtx, jboolean bClear){ + Fts5ExtDecl; + jobject rv = 0; + S3JniFts5AuxData * const pAux = ext->xGetAuxdata(PtrGet_Fts5Context(jCtx), bClear); + if( pAux ){ + if( bClear ){ + if( pAux->jObj ){ + rv = S3JniRefLocal(pAux->jObj); + S3JniUnrefGlobal(pAux->jObj); + } + /* Note that we do not call xDestroy() in this case. */ + sqlite3_free(pAux); + }else{ + rv = pAux->jObj; + } + } + return rv; +} + +JniDeclFtsXA(jint,xInst)(JniArgsEnvObj,jobject jCtx, jint iIdx, jobject jOutPhrase, + jobject jOutCol, jobject jOutOff){ + Fts5ExtDecl; + int n1 = 0, n2 = 2, n3 = 0; + int const rc = ext->xInst(PtrGet_Fts5Context(jCtx), (int)iIdx, &n1, &n2, &n3); + if( 0==rc ){ + OutputPointer_set_Int32(env, jOutPhrase, n1); + OutputPointer_set_Int32(env, jOutCol, n2); + OutputPointer_set_Int32(env, jOutOff, n3); + } + return rc; +} + +JniDeclFtsXA(jint,xInstCount)(JniArgsEnvObj,jobject jCtx, jobject jOut32){ + Fts5ExtDecl; + int nOut = 0; + int const rc = ext->xInstCount(PtrGet_Fts5Context(jCtx), &nOut); + if( 0==rc && jOut32 ) OutputPointer_set_Int32(env, jOut32, nOut); + return (jint)rc; +} + +JniDeclFtsXA(jint,xPhraseCount)(JniArgsEnvObj,jobject jCtx){ + Fts5ExtDecl; + return (jint)ext->xPhraseCount(PtrGet_Fts5Context(jCtx)); +} + +/* Copy the 'a' and 'b' fields from pSrc to Fts5PhraseIter object jIter. */ +static void s3jni_phraseIter_NToJ(JNIEnv *const env, + Fts5PhraseIter const * const pSrc, + jobject jIter){ + S3JniGlobalType * const g = &S3JniGlobal; + assert(g->fts5.jPhraseIter.fidA); + (*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidA, + S3JniCast_P2L(pSrc->a)); + S3JniExceptionIsFatal("Cannot set Fts5PhraseIter.a field."); + (*env)->SetLongField(env, jIter, g->fts5.jPhraseIter.fidB, + S3JniCast_P2L(pSrc->b)); + S3JniExceptionIsFatal("Cannot set Fts5PhraseIter.b field."); +} + +/* Copy the 'a' and 'b' fields from Fts5PhraseIter object jIter to pDest. */ +static void s3jni_phraseIter_JToN(JNIEnv *const env, jobject jIter, + Fts5PhraseIter * const pDest){ + S3JniGlobalType * const g = &S3JniGlobal; + assert(g->fts5.jPhraseIter.fidA); + pDest->a = S3JniCast_L2P( + (*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidA) + ); + S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.a field."); + pDest->b = S3JniCast_L2P( + (*env)->GetLongField(env, jIter, g->fts5.jPhraseIter.fidB) + ); + S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.b field."); +} + +JniDeclFtsXA(jint,xPhraseFirst)(JniArgsEnvObj,jobject jCtx, jint iPhrase, + jobject jIter, jobject jOutCol, + jobject jOutOff){ + Fts5ExtDecl; + Fts5PhraseIter iter; + int rc, iCol = 0, iOff = 0; + rc = ext->xPhraseFirst(PtrGet_Fts5Context(jCtx), (int)iPhrase, + &iter, &iCol, &iOff); + if( 0==rc ){ + OutputPointer_set_Int32(env, jOutCol, iCol); + OutputPointer_set_Int32(env, jOutOff, iOff); + s3jni_phraseIter_NToJ(env, &iter, jIter); + } + return rc; +} + +JniDeclFtsXA(jint,xPhraseFirstColumn)(JniArgsEnvObj,jobject jCtx, jint iPhrase, + jobject jIter, jobject jOutCol){ + Fts5ExtDecl; + Fts5PhraseIter iter; + int rc, iCol = 0; + rc = ext->xPhraseFirstColumn(PtrGet_Fts5Context(jCtx), (int)iPhrase, + &iter, &iCol); + if( 0==rc ){ + OutputPointer_set_Int32(env, jOutCol, iCol); + s3jni_phraseIter_NToJ(env, &iter, jIter); + } + return rc; +} + +JniDeclFtsXA(void,xPhraseNext)(JniArgsEnvObj,jobject jCtx, jobject jIter, + jobject jOutCol, jobject jOutOff){ + Fts5ExtDecl; + Fts5PhraseIter iter; + int iCol = 0, iOff = 0; + s3jni_phraseIter_JToN(env, jIter, &iter); + ext->xPhraseNext(PtrGet_Fts5Context(jCtx), &iter, &iCol, &iOff); + OutputPointer_set_Int32(env, jOutCol, iCol); + OutputPointer_set_Int32(env, jOutOff, iOff); + s3jni_phraseIter_NToJ(env, &iter, jIter); +} + +JniDeclFtsXA(void,xPhraseNextColumn)(JniArgsEnvObj,jobject jCtx, jobject jIter, + jobject jOutCol){ + Fts5ExtDecl; + Fts5PhraseIter iter; + int iCol = 0; + s3jni_phraseIter_JToN(env, jIter, &iter); + ext->xPhraseNextColumn(PtrGet_Fts5Context(jCtx), &iter, &iCol); + OutputPointer_set_Int32(env, jOutCol, iCol); + s3jni_phraseIter_NToJ(env, &iter, jIter); +} + + +JniDeclFtsXA(jint,xPhraseSize)(JniArgsEnvObj,jobject jCtx, jint iPhrase){ + Fts5ExtDecl; + return (jint)ext->xPhraseSize(PtrGet_Fts5Context(jCtx), (int)iPhrase); +} + +/* State for use with xQueryPhrase() and xTokenize(). */ +struct s3jni_xQueryPhraseState { + Fts5ExtensionApi const * ext; + jmethodID midCallback; /* jCallback->call() method */ + jobject jCallback; /* Fts5ExtensionApi.XQueryPhraseCallback instance */ + jobject jFcx; /* (Fts5Context*) for xQueryPhrase() + callback. This is NOT the instance that is + passed to xQueryPhrase(), it's the one + created by xQueryPhrase() for use by its + callback. */ + /* State for xTokenize() */ + struct { + const char * zPrev; + int nPrev; + jbyteArray jba; + } tok; +}; + +static int s3jni_xQueryPhrase(const Fts5ExtensionApi *xapi, + Fts5Context * pFcx, void *pData){ + struct s3jni_xQueryPhraseState * const s = pData; + S3JniDeclLocal_env; + + if( !s->jFcx ){ + s->jFcx = new_java_Fts5Context(env, pFcx); + if( !s->jFcx ) return SQLITE_NOMEM; + } + int rc = (int)(*env)->CallIntMethod(env, s->jCallback, s->midCallback, + SJG.fts5.jExt, s->jFcx); + S3JniIfThrew{ + S3JniExceptionWarnCallbackThrew("xQueryPhrase() callback"); + S3JniExceptionClear; + rc = SQLITE_ERROR; + } + return rc; +} + +JniDeclFtsXA(jint,xQueryPhrase)(JniArgsEnvObj,jobject jFcx, jint iPhrase, + jobject jCallback){ + Fts5ExtDecl; + int rc; + struct s3jni_xQueryPhraseState s; + jclass klazz = jCallback ? (*env)->GetObjectClass(env, jCallback) : NULL; + + if( !klazz ) return SQLITE_MISUSE; + s.jCallback = jCallback; + s.jFcx = 0; + s.ext = ext; + s.midCallback = (*env)->GetMethodID(env, klazz, "call", + "(Lorg/sqlite/jni/fts5/Fts5ExtensionApi;" + "Lorg/sqlite/jni/fts5/Fts5Context;)I"); + S3JniUnrefLocal(klazz); + S3JniExceptionIsFatal("Could not extract xQueryPhraseCallback.call() method."); + rc = ext->xQueryPhrase(PtrGet_Fts5Context(jFcx), iPhrase, &s, + s3jni_xQueryPhrase); + S3JniUnrefLocal(s.jFcx); + return (jint)rc; +} + + +JniDeclFtsXA(jint,xRowCount)(JniArgsEnvObj,jobject jCtx, jobject jOut64){ + Fts5ExtDecl; + sqlite3_int64 nOut = 0; + int const rc = ext->xRowCount(PtrGet_Fts5Context(jCtx), &nOut); + if( 0==rc && jOut64 ) OutputPointer_set_Int64(env, jOut64, (jlong)nOut); + return (jint)rc; +} + +JniDeclFtsXA(jlong,xRowid)(JniArgsEnvObj,jobject jCtx){ + Fts5ExtDecl; + return (jlong)ext->xRowid(PtrGet_Fts5Context(jCtx)); +} + +JniDeclFtsXA(int,xSetAuxdata)(JniArgsEnvObj,jobject jCtx, jobject jAux){ + Fts5ExtDecl; + int rc; + S3JniFts5AuxData * pAux; + + pAux = s3jni_malloc( sizeof(*pAux)); + if( !pAux ){ + if( jAux ){ + /* Emulate how xSetAuxdata() behaves when it cannot alloc + ** its auxdata wrapper. */ + s3jni_call_xDestroy(jAux); + } + return SQLITE_NOMEM; + } + pAux->jObj = S3JniRefGlobal(jAux); + rc = ext->xSetAuxdata(PtrGet_Fts5Context(jCtx), pAux, + S3JniFts5AuxData_xDestroy); + return rc; +} + +/* xToken() impl for xTokenize(). */ +static int s3jni_xTokenize_xToken(void *p, int tFlags, const char* z, + int nZ, int iStart, int iEnd){ + int rc; + S3JniDeclLocal_env; + struct s3jni_xQueryPhraseState * const s = p; + jbyteArray jba; + + S3JniUnrefLocal(s->tok.jba); + s->tok.zPrev = z; + s->tok.nPrev = nZ; + s->tok.jba = s3jni_new_jbyteArray(z, nZ); + if( !s->tok.jba ) return SQLITE_NOMEM; + jba = s->tok.jba; + rc = (int)(*env)->CallIntMethod(env, s->jCallback, s->midCallback, + (jint)tFlags, jba, (jint)iStart, + (jint)iEnd); + S3JniIfThrew { + S3JniExceptionWarnCallbackThrew("xTokenize() callback"); + rc = SQLITE_ERROR; + } + return rc; +} + +/* +** Proxy for Fts5ExtensionApi.xTokenize() and +** fts5_tokenizer.xTokenize() +*/ +static jint s3jni_fts5_xTokenize(JniArgsEnvObj, S3JniNphOp const *pRef, + jint tokFlags, jobject jFcx, + jbyteArray jbaText, jobject jCallback){ + Fts5ExtDecl; + struct s3jni_xQueryPhraseState s; + int rc = 0; + jbyte * const pText = jCallback ? s3jni_jbyteArray_bytes(jbaText) : 0; + jsize nText = pText ? (*env)->GetArrayLength(env, jbaText) : 0; + jclass const klazz = jCallback ? (*env)->GetObjectClass(env, jCallback) : NULL; + + if( !klazz ) return SQLITE_MISUSE; + memset(&s, 0, sizeof(s)); + s.jCallback = jCallback; + s.jFcx = jFcx; + s.ext = ext; + s.midCallback = (*env)->GetMethodID(env, klazz, "call", "(I[BII)I"); + S3JniUnrefLocal(klazz); + S3JniIfThrew { + S3JniExceptionReport; + S3JniExceptionClear; + s3jni_jbyteArray_release(jbaText, pText); + return SQLITE_ERROR; + } + s.tok.jba = S3JniRefLocal(jbaText); + s.tok.zPrev = (const char *)pText; + s.tok.nPrev = (int)nText; + if( pRef == S3JniNph(Fts5ExtensionApi) ){ + rc = ext->xTokenize(PtrGet_Fts5Context(jFcx), + (const char *)pText, (int)nText, + &s, s3jni_xTokenize_xToken); + }else if( pRef == S3JniNph(fts5_tokenizer) ){ + fts5_tokenizer * const pTok = PtrGet_fts5_tokenizer(jSelf); + rc = pTok->xTokenize(PtrGet_Fts5Tokenizer(jFcx), &s, tokFlags, + (const char *)pText, (int)nText, + s3jni_xTokenize_xToken); + }else{ + (*env)->FatalError(env, "This cannot happen. Maintenance required."); + } + if( s.tok.jba ){ + assert( s.tok.zPrev ); + S3JniUnrefLocal(s.tok.jba); + } + s3jni_jbyteArray_release(jbaText, pText); + return (jint)rc; +} + +JniDeclFtsXA(jint,xTokenize)(JniArgsEnvObj,jobject jFcx, jbyteArray jbaText, + jobject jCallback){ + return s3jni_fts5_xTokenize(env, jSelf, S3JniNph(Fts5ExtensionApi), + 0, jFcx, jbaText, jCallback); +} + +JniDeclFtsTok(jint,xTokenize)(JniArgsEnvObj,jobject jFcx, jint tokFlags, + jbyteArray jbaText, jobject jCallback){ + return s3jni_fts5_xTokenize(env, jSelf, S3JniNph(Fts5Tokenizer), + tokFlags, jFcx, jbaText, jCallback); +} + + +JniDeclFtsXA(jobject,xUserData)(JniArgsEnvObj,jobject jFcx){ + Fts5ExtDecl; + Fts5JniAux * const pAux = ext->xUserData(PtrGet_Fts5Context(jFcx)); + return pAux ? pAux->jUserData : 0; +} + +#endif /* SQLITE_ENABLE_FTS5 */ + +//////////////////////////////////////////////////////////////////////// +// End of the main API bindings. Start of SQLTester bits... +//////////////////////////////////////////////////////////////////////// + +#ifdef SQLITE_JNI_ENABLE_SQLTester +typedef struct SQLTesterJni SQLTesterJni; +struct SQLTesterJni { + sqlite3_int64 nDup; +}; +static SQLTesterJni SQLTester = { + 0 +}; + +static void SQLTester_dup_destructor(void*pToFree){ + u64 *p = (u64*)pToFree; + assert( p!=0 ); + p--; + assert( p[0]==0x2bbf4b7c ); + p[0] = 0; + p[1] = 0; + sqlite3_free(p); +} + +/* +** Implementation of +** +** dup(TEXT) +** +** This SQL function simply makes a copy of its text argument. But it +** returns the result using a custom destructor, in order to provide +** tests for the use of Mem.xDel() in the SQLite VDBE. +*/ +static void SQLTester_dup_func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + u64 *pOut; + char *z; + int n = sqlite3_value_bytes(argv[0]); + SQLTesterJni * const p = (SQLTesterJni *)sqlite3_user_data(context); + S3JniDeclLocal_env; + + ++p->nDup; + if( n>0 && (pOut = s3jni_malloc( (n+16)&~7 ))!=0 ){ + pOut[0] = 0x2bbf4b7c; + z = (char*)&pOut[1]; + memcpy(z, sqlite3_value_text(argv[0]), n); + z[n] = 0; + sqlite3_result_text(context, z, n, SQLTester_dup_destructor); + } + return; +} + +/* +** Return the number of calls to the dup() SQL function since the +** SQLTester context was opened or since the last dup_count() call. +*/ +static void SQLTester_dup_count_func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + SQLTesterJni * const p = (SQLTesterJni *)sqlite3_user_data(context); + sqlite3_result_int64(context, p->nDup); + p->nDup = 0; +} + +/* +** Return non-zero if string z matches glob pattern zGlob and zero if the +** pattern does not match. +** +** To repeat: +** +** zero == no match +** non-zero == match +** +** Globbing rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. +** +** [^...] Matches one character not in the enclosed list. +** +** '#' Matches any sequence of one or more digits with an +** optional + or - sign in front, or a hexadecimal +** literal of the form 0x... +*/ +static int SQLTester_strnotglob(const char *zGlob, const char *z){ + int c, c2; + int invert; + int seen; + + while( (c = (*(zGlob++)))!=0 ){ + if( c=='*' ){ + while( (c=(*(zGlob++))) == '*' || c=='?' ){ + if( c=='?' && (*(z++))==0 ) return 0; + } + if( c==0 ){ + return 1; + }else if( c=='[' ){ + while( *z && SQLTester_strnotglob(zGlob-1,z)==0 ){ + z++; + } + return (*z)!=0; + } + while( (c2 = (*(z++)))!=0 ){ + while( c2!=c ){ + c2 = *(z++); + if( c2==0 ) return 0; + } + if( SQLTester_strnotglob(zGlob,z) ) return 1; + } + return 0; + }else if( c=='?' ){ + if( (*(z++))==0 ) return 0; + }else if( c=='[' ){ + int prior_c = 0; + seen = 0; + invert = 0; + c = *(z++); + if( c==0 ) return 0; + c2 = *(zGlob++); + if( c2=='^' ){ + invert = 1; + c2 = *(zGlob++); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = *(zGlob++); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ + c2 = *(zGlob++); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = *(zGlob++); + } + if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='#' ){ + if( z[0]=='0' + && (z[1]=='x' || z[1]=='X') + && sqlite3Isxdigit(z[2]) + ){ + z += 3; + while( sqlite3Isxdigit(z[0]) ){ z++; } + }else{ + if( (z[0]=='-' || z[0]=='+') && sqlite3Isdigit(z[1]) ) z++; + if( !sqlite3Isdigit(z[0]) ) return 0; + z++; + while( sqlite3Isdigit(z[0]) ){ z++; } + } + }else{ + if( c!=(*(z++)) ) return 0; + } + } + return *z==0; +} + +JNIEXPORT jint JNICALL +Java_org_sqlite_jni_capi_SQLTester_strglob( + JniArgsEnvClass, jbyteArray baG, jbyteArray baT +){ + int rc = 0; + jbyte * const pG = s3jni_jbyteArray_bytes(baG); + jbyte * const pT = pG ? s3jni_jbyteArray_bytes(baT) : 0; + + s3jni_oom_fatal(pT); + /* Note that we're relying on the byte arrays having been + NUL-terminated on the Java side. */ + rc = !SQLTester_strnotglob((const char *)pG, (const char *)pT); + s3jni_jbyteArray_release(baG, pG); + s3jni_jbyteArray_release(baT, pT); + return rc; +} + + +static int SQLTester_auto_extension(sqlite3 *pDb, const char **pzErr, + const struct sqlite3_api_routines *ignored){ + sqlite3_create_function(pDb, "dup", 1, SQLITE_UTF8, &SQLTester, + SQLTester_dup_func, 0, 0); + sqlite3_create_function(pDb, "dup_count", 0, SQLITE_UTF8, &SQLTester, + SQLTester_dup_count_func, 0, 0); + return 0; +} + +JNIEXPORT void JNICALL +Java_org_sqlite_jni_capi_SQLTester_installCustomExtensions(JniArgsEnvClass){ + sqlite3_auto_extension( (void(*)(void))SQLTester_auto_extension ); +} + +#endif /* SQLITE_JNI_ENABLE_SQLTester */ +//////////////////////////////////////////////////////////////////////// +// End of SQLTester bindings. Start of lower-level bits. +//////////////////////////////////////////////////////////////////////// + +/* +** Called during static init of the CApi class to set up global +** state. +*/ +JNIEXPORT void JNICALL +Java_org_sqlite_jni_capi_CApi_init(JniArgsEnvClass){ + jclass klazz; + + memset(&S3JniGlobal, 0, sizeof(S3JniGlobal)); + if( (*env)->GetJavaVM(env, &SJG.jvm) ){ + (*env)->FatalError(env, "GetJavaVM() failure shouldn't be possible."); + return; + } + + /* Grab references to various global classes and objects... */ + SJG.g.cLong = S3JniRefGlobal((*env)->FindClass(env,"java/lang/Long")); + S3JniExceptionIsFatal("Error getting reference to Long class."); + SJG.g.ctorLong1 = (*env)->GetMethodID(env, SJG.g.cLong, + "", "(J)V"); + S3JniExceptionIsFatal("Error getting reference to Long constructor."); + + SJG.g.cString = S3JniRefGlobal((*env)->FindClass(env,"java/lang/String")); + S3JniExceptionIsFatal("Error getting reference to String class."); + SJG.g.ctorStringBA = + (*env)->GetMethodID(env, SJG.g.cString, + "", "([BLjava/nio/charset/Charset;)V"); + S3JniExceptionIsFatal("Error getting reference to String(byte[],Charset) ctor."); + SJG.g.stringGetBytes = + (*env)->GetMethodID(env, SJG.g.cString, + "getBytes", "(Ljava/nio/charset/Charset;)[B"); + S3JniExceptionIsFatal("Error getting reference to String.getBytes(Charset)."); + + { /* java.nio.charset.StandardCharsets.UTF_8 */ + jfieldID fUtf8; + klazz = (*env)->FindClass(env,"java/nio/charset/StandardCharsets"); + S3JniExceptionIsFatal("Error getting reference to StandardCharsets class."); + fUtf8 = (*env)->GetStaticFieldID(env, klazz, "UTF_8", + "Ljava/nio/charset/Charset;"); + S3JniExceptionIsFatal("Error getting StandardCharsets.UTF_8 field."); + SJG.g.oCharsetUtf8 = + S3JniRefGlobal((*env)->GetStaticObjectField(env, klazz, fUtf8)); + S3JniExceptionIsFatal("Error getting reference to StandardCharsets.UTF_8."); + S3JniUnrefLocal(klazz); + } + +#ifdef SQLITE_ENABLE_FTS5 + klazz = (*env)->FindClass(env, "org/sqlite/jni/fts5/Fts5PhraseIter"); + S3JniExceptionIsFatal("Error getting reference to org.sqlite.jni.fts5.Fts5PhraseIter."); + SJG.fts5.jPhraseIter.fidA = (*env)->GetFieldID(env, klazz, "a", "J"); + S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.a field."); + SJG.fts5.jPhraseIter.fidB = (*env)->GetFieldID(env, klazz, "b", "J"); + S3JniExceptionIsFatal("Cannot get Fts5PhraseIter.b field."); + S3JniUnrefLocal(klazz); +#endif + + SJG.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + s3jni_oom_fatal( SJG.mutex ); + SJG.hook.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + s3jni_oom_fatal( SJG.hook.mutex ); + SJG.nph.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + s3jni_oom_fatal( SJG.nph.mutex ); + SJG.envCache.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + s3jni_oom_fatal( SJG.envCache.mutex ); + SJG.perDb.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + s3jni_oom_fatal( SJG.perDb.mutex ); + SJG.autoExt.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + s3jni_oom_fatal( SJG.autoExt.mutex ); + +#if S3JNI_METRICS_MUTEX + SJG.metrics.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST); + s3jni_oom_fatal( SJG.metrics.mutex ); +#endif + + sqlite3_shutdown() + /* So that it becomes legal for Java-level code to call + ** sqlite3_config(). */; +} diff -Nru sqlite3-3.42.0/ext/jni/src/c/sqlite3-jni.h sqlite3-3.44.0-0/ext/jni/src/c/sqlite3-jni.h --- sqlite3-3.42.0/ext/jni/src/c/sqlite3-jni.h 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/c/sqlite3-jni.h 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,2379 @@ +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_sqlite_jni_capi_CApi */ + +#ifndef _Included_org_sqlite_jni_capi_CApi +#define _Included_org_sqlite_jni_capi_CApi +#ifdef __cplusplus +extern "C" { +#endif +#undef org_sqlite_jni_capi_CApi_SQLITE_ACCESS_EXISTS +#define org_sqlite_jni_capi_CApi_SQLITE_ACCESS_EXISTS 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READWRITE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READ +#define org_sqlite_jni_capi_CApi_SQLITE_ACCESS_READ 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_DENY +#define org_sqlite_jni_capi_CApi_SQLITE_DENY 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_IGNORE +#define org_sqlite_jni_capi_CApi_SQLITE_IGNORE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_INDEX 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TABLE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_INDEX 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TABLE 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_TRIGGER 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TEMP_VIEW 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_TRIGGER 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_VIEW 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_DELETE +#define org_sqlite_jni_capi_CApi_SQLITE_DELETE 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_INDEX 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TABLE 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_INDEX 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TABLE 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_TRIGGER 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TEMP_VIEW 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_TRIGGER 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_VIEW 17L +#undef org_sqlite_jni_capi_CApi_SQLITE_INSERT +#define org_sqlite_jni_capi_CApi_SQLITE_INSERT 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_PRAGMA +#define org_sqlite_jni_capi_CApi_SQLITE_PRAGMA 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_READ +#define org_sqlite_jni_capi_CApi_SQLITE_READ 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_SELECT +#define org_sqlite_jni_capi_CApi_SQLITE_SELECT 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRANSACTION +#define org_sqlite_jni_capi_CApi_SQLITE_TRANSACTION 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_UPDATE +#define org_sqlite_jni_capi_CApi_SQLITE_UPDATE 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_ATTACH +#define org_sqlite_jni_capi_CApi_SQLITE_ATTACH 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_DETACH +#define org_sqlite_jni_capi_CApi_SQLITE_DETACH 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_ALTER_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_ALTER_TABLE 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_REINDEX +#define org_sqlite_jni_capi_CApi_SQLITE_REINDEX 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_ANALYZE +#define org_sqlite_jni_capi_CApi_SQLITE_ANALYZE 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_CREATE_VTABLE +#define org_sqlite_jni_capi_CApi_SQLITE_CREATE_VTABLE 29L +#undef org_sqlite_jni_capi_CApi_SQLITE_DROP_VTABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DROP_VTABLE 30L +#undef org_sqlite_jni_capi_CApi_SQLITE_FUNCTION +#define org_sqlite_jni_capi_CApi_SQLITE_FUNCTION 31L +#undef org_sqlite_jni_capi_CApi_SQLITE_SAVEPOINT +#define org_sqlite_jni_capi_CApi_SQLITE_SAVEPOINT 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_RECURSIVE +#define org_sqlite_jni_capi_CApi_SQLITE_RECURSIVE 33L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATIC +#define org_sqlite_jni_capi_CApi_SQLITE_STATIC 0LL +#undef org_sqlite_jni_capi_CApi_SQLITE_TRANSIENT +#define org_sqlite_jni_capi_CApi_SQLITE_TRANSIENT -1LL +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETSTART_INVERT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETSTART_INVERT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_NOSAVEPOINT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_NOSAVEPOINT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_INVERT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_INVERT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_IGNORENOOP +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESETAPPLY_IGNORENOOP 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_DATA +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_DATA 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_NOTFOUND +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_NOTFOUND 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONFLICT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONFLICT 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONSTRAINT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_CONSTRAINT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_FOREIGN_KEY +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_FOREIGN_KEY 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_OMIT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_OMIT 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_REPLACE +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_REPLACE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_ABORT +#define org_sqlite_jni_capi_CApi_SQLITE_CHANGESET_ABORT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SINGLETHREAD +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SINGLETHREAD 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MULTITHREAD +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MULTITHREAD 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SERIALIZED +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SERIALIZED 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MALLOC +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MALLOC 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMALLOC +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMALLOC 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SCRATCH +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SCRATCH 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PAGECACHE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PAGECACHE 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_HEAP +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_HEAP 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMSTATUS +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMSTATUS 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MUTEX 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETMUTEX 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOOKASIDE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOOKASIDE 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOG +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_LOG 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_URI +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_URI 17L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE2 +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE2 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE2 +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_GETPCACHE2 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_COVERING_INDEX_SCAN +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_COVERING_INDEX_SCAN 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SQLLOG +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SQLLOG 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MMAP_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MMAP_SIZE 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_WIN32_HEAPSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_WIN32_HEAPSIZE 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE_HDRSZ +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PCACHE_HDRSZ 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PMASZ +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_PMASZ 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_STMTJRNL_SPILL +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_STMTJRNL_SPILL 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SMALL_MALLOC +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SMALL_MALLOC 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SORTERREF_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_SORTERREF_SIZE 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMDB_MAXSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_CONFIG_MEMDB_MAXSIZE 29L +#undef org_sqlite_jni_capi_CApi_SQLITE_INTEGER +#define org_sqlite_jni_capi_CApi_SQLITE_INTEGER 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_FLOAT +#define org_sqlite_jni_capi_CApi_SQLITE_FLOAT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_TEXT +#define org_sqlite_jni_capi_CApi_SQLITE_TEXT 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_BLOB +#define org_sqlite_jni_capi_CApi_SQLITE_BLOB 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_NULL +#define org_sqlite_jni_capi_CApi_SQLITE_NULL 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAINDBNAME +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAINDBNAME 1000L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LOOKASIDE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LOOKASIDE 1001L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FKEY +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FKEY 1002L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_TRIGGER 1003L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER 1004L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION 1005L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE 1006L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_QPSG +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_QPSG 1007L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRIGGER_EQP +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRIGGER_EQP 1008L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_RESET_DATABASE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_RESET_DATABASE 1009L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DEFENSIVE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DEFENSIVE 1010L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_WRITABLE_SCHEMA +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_WRITABLE_SCHEMA 1011L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_ALTER_TABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_ALTER_TABLE 1012L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DML +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DML 1013L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DDL +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_DQS_DDL 1014L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_VIEW +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_ENABLE_VIEW 1015L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_FILE_FORMAT +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRUSTED_SCHEMA +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_STMT_SCANSTATUS +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_STMT_SCANSTATUS 1018L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_REVERSE_SCANORDER +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_REVERSE_SCANORDER 1019L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAX +#define org_sqlite_jni_capi_CApi_SQLITE_DBCONFIG_MAX 1019L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_USED 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_SCHEMA_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_SCHEMA_USED 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_STMT_USED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_STMT_USED 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_HIT +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_HIT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_HIT +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_HIT 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_MISS +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_MISS 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_WRITE 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_DEFERRED_FKS +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_DEFERRED_FKS 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_USED_SHARED 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_CACHE_SPILL 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX +#define org_sqlite_jni_capi_CApi_SQLITE_DBSTATUS_MAX 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF8 +#define org_sqlite_jni_capi_CApi_SQLITE_UTF8 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16LE +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16LE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16BE +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16BE 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16 +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_UTF16_ALIGNED +#define org_sqlite_jni_capi_CApi_SQLITE_UTF16_ALIGNED 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCKSTATE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCKSTATE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_GET_LOCKPROXYFILE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_GET_LOCKPROXYFILE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SET_LOCKPROXYFILE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SET_LOCKPROXYFILE 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LAST_ERRNO +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LAST_ERRNO 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_HINT +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_HINT 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CHUNK_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CHUNK_SIZE 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_FILE_POINTER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_FILE_POINTER 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC_OMITTED +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC_OMITTED 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_AV_RETRY +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_AV_RETRY 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PERSIST_WAL +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PERSIST_WAL 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_OVERWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_OVERWRITE 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFSNAME +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFSNAME 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_POWERSAFE_OVERWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_POWERSAFE_OVERWRITE 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PRAGMA +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PRAGMA 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BUSYHANDLER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BUSYHANDLER 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TEMPFILENAME +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TEMPFILENAME 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_MMAP_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_MMAP_SIZE 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TRACE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_TRACE 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_HAS_MOVED +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_HAS_MOVED 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SYNC 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_PHASETWO +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_PHASETWO 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_SET_HANDLE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_SET_HANDLE 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WAL_BLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WAL_BLOCK 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ZIPVFS +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ZIPVFS 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RBU +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RBU 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFS_POINTER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_VFS_POINTER 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_JOURNAL_POINTER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_JOURNAL_POINTER 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_GET_HANDLE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_WIN32_GET_HANDLE 29L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PDB +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_PDB 30L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BEGIN_ATOMIC_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_BEGIN_ATOMIC_WRITE 31L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_ATOMIC_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_COMMIT_ATOMIC_WRITE 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE 33L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCK_TIMEOUT +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_LOCK_TIMEOUT 34L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_DATA_VERSION +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_DATA_VERSION 35L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_LIMIT +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_SIZE_LIMIT 36L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_DONE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_DONE 37L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESERVE_BYTES +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESERVE_BYTES 38L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_START +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKPT_START 39L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_EXTERNAL_READER +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_EXTERNAL_READER 40L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKSM_FILE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_CKSM_FILE 41L +#undef org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESET_CACHE +#define org_sqlite_jni_capi_CApi_SQLITE_FCNTL_RESET_CACHE 42L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_NONE +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_NONE 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_SHARED +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_SHARED 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_RESERVED +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_RESERVED 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_PENDING +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_PENDING 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCK_EXCLUSIVE +#define org_sqlite_jni_capi_CApi_SQLITE_LOCK_EXCLUSIVE 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC512 +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC512 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC1K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC1K 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC2K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC2K 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC4K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC4K 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC8K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC8K 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC16K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC16K 64L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC32K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC32K 128L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC64K +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_ATOMIC64K 256L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SAFE_APPEND +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SAFE_APPEND 512L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SEQUENTIAL +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_SEQUENTIAL 1024L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN 2048L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_POWERSAFE_OVERWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_POWERSAFE_OVERWRITE 4096L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_IMMUTABLE +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_IMMUTABLE 8192L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOCAP_BATCH_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOCAP_BATCH_ATOMIC 16384L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LENGTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LENGTH 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_SQL_LENGTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_SQL_LENGTH 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COLUMN +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COLUMN 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_EXPR_DEPTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_EXPR_DEPTH 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COMPOUND_SELECT +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_COMPOUND_SELECT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VDBE_OP +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VDBE_OP 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_FUNCTION_ARG +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_FUNCTION_ARG 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_ATTACHED +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_ATTACHED 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LIKE_PATTERN_LENGTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_LIKE_PATTERN_LENGTH 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VARIABLE_NUMBER +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_VARIABLE_NUMBER 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_TRIGGER_DEPTH +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_TRIGGER_DEPTH 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_LIMIT_WORKER_THREADS +#define org_sqlite_jni_capi_CApi_SQLITE_LIMIT_WORKER_THREADS 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_READONLY +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_READONLY 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_READWRITE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_READWRITE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_CREATE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_CREATE 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_URI +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_URI 64L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_MEMORY +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_MEMORY 128L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOMUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOMUTEX 32768L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_FULLMUTEX +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_FULLMUTEX 65536L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_SHAREDCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_SHAREDCACHE 131072L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_PRIVATECACHE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_PRIVATECACHE 262144L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOFOLLOW +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_NOFOLLOW 16777216L +#undef org_sqlite_jni_capi_CApi_SQLITE_OPEN_EXRESCODE +#define org_sqlite_jni_capi_CApi_SQLITE_OPEN_EXRESCODE 33554432L +#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_PERSISTENT +#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_PERSISTENT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NORMALIZE +#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NORMALIZE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NO_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_PREPARE_NO_VTAB 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_OK +#define org_sqlite_jni_capi_CApi_SQLITE_OK 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_INTERNAL +#define org_sqlite_jni_capi_CApi_SQLITE_INTERNAL 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_PERM +#define org_sqlite_jni_capi_CApi_SQLITE_PERM 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_ABORT +#define org_sqlite_jni_capi_CApi_SQLITE_ABORT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCKED +#define org_sqlite_jni_capi_CApi_SQLITE_LOCKED 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOMEM +#define org_sqlite_jni_capi_CApi_SQLITE_NOMEM 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_INTERRUPT +#define org_sqlite_jni_capi_CApi_SQLITE_INTERRUPT 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR 10L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT 11L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTFOUND +#define org_sqlite_jni_capi_CApi_SQLITE_NOTFOUND 12L +#undef org_sqlite_jni_capi_CApi_SQLITE_FULL +#define org_sqlite_jni_capi_CApi_SQLITE_FULL 13L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN 14L +#undef org_sqlite_jni_capi_CApi_SQLITE_PROTOCOL +#define org_sqlite_jni_capi_CApi_SQLITE_PROTOCOL 15L +#undef org_sqlite_jni_capi_CApi_SQLITE_EMPTY +#define org_sqlite_jni_capi_CApi_SQLITE_EMPTY 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_SCHEMA +#define org_sqlite_jni_capi_CApi_SQLITE_SCHEMA 17L +#undef org_sqlite_jni_capi_CApi_SQLITE_TOOBIG +#define org_sqlite_jni_capi_CApi_SQLITE_TOOBIG 18L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT 19L +#undef org_sqlite_jni_capi_CApi_SQLITE_MISMATCH +#define org_sqlite_jni_capi_CApi_SQLITE_MISMATCH 20L +#undef org_sqlite_jni_capi_CApi_SQLITE_MISUSE +#define org_sqlite_jni_capi_CApi_SQLITE_MISUSE 21L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOLFS +#define org_sqlite_jni_capi_CApi_SQLITE_NOLFS 22L +#undef org_sqlite_jni_capi_CApi_SQLITE_AUTH +#define org_sqlite_jni_capi_CApi_SQLITE_AUTH 23L +#undef org_sqlite_jni_capi_CApi_SQLITE_FORMAT +#define org_sqlite_jni_capi_CApi_SQLITE_FORMAT 24L +#undef org_sqlite_jni_capi_CApi_SQLITE_RANGE +#define org_sqlite_jni_capi_CApi_SQLITE_RANGE 25L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTADB +#define org_sqlite_jni_capi_CApi_SQLITE_NOTADB 26L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTICE +#define org_sqlite_jni_capi_CApi_SQLITE_NOTICE 27L +#undef org_sqlite_jni_capi_CApi_SQLITE_WARNING +#define org_sqlite_jni_capi_CApi_SQLITE_WARNING 28L +#undef org_sqlite_jni_capi_CApi_SQLITE_ROW +#define org_sqlite_jni_capi_CApi_SQLITE_ROW 100L +#undef org_sqlite_jni_capi_CApi_SQLITE_DONE +#define org_sqlite_jni_capi_CApi_SQLITE_DONE 101L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR_MISSING_COLLSEQ +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR_MISSING_COLLSEQ 257L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR_RETRY +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR_RETRY 513L +#undef org_sqlite_jni_capi_CApi_SQLITE_ERROR_SNAPSHOT +#define org_sqlite_jni_capi_CApi_SQLITE_ERROR_SNAPSHOT 769L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_READ +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_READ 266L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHORT_READ +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHORT_READ 522L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_WRITE 778L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSYNC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSYNC 1034L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_FSYNC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_FSYNC 1290L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_TRUNCATE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_TRUNCATE 1546L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSTAT +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_FSTAT 1802L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_UNLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_UNLOCK 2058L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_RDLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_RDLOCK 2314L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE 2570L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_BLOCKED +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_BLOCKED 2826L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_NOMEM +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_NOMEM 3082L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_ACCESS +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_ACCESS 3338L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CHECKRESERVEDLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CHECKRESERVEDLOCK 3594L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_LOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_LOCK 3850L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CLOSE 4106L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DIR_CLOSE 4362L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMOPEN +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMOPEN 4618L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMSIZE 4874L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMLOCK 5130L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMMAP +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SHMMAP 5386L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_SEEK +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_SEEK 5642L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE_NOENT +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DELETE_NOENT 5898L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_MMAP +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_MMAP 6154L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_GETTEMPPATH +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_GETTEMPPATH 6410L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CONVPATH +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CONVPATH 6666L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_VNODE +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_VNODE 6922L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_AUTH +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_AUTH 7178L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_BEGIN_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_BEGIN_ATOMIC 7434L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_COMMIT_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_COMMIT_ATOMIC 7690L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_ROLLBACK_ATOMIC +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_ROLLBACK_ATOMIC 7946L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_DATA +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_DATA 8202L +#undef org_sqlite_jni_capi_CApi_SQLITE_IOERR_CORRUPTFS +#define org_sqlite_jni_capi_CApi_SQLITE_IOERR_CORRUPTFS 8458L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCKED_SHAREDCACHE +#define org_sqlite_jni_capi_CApi_SQLITE_LOCKED_SHAREDCACHE 262L +#undef org_sqlite_jni_capi_CApi_SQLITE_LOCKED_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_LOCKED_VTAB 518L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY_RECOVERY +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY_RECOVERY 261L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY_SNAPSHOT +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY_SNAPSHOT 517L +#undef org_sqlite_jni_capi_CApi_SQLITE_BUSY_TIMEOUT +#define org_sqlite_jni_capi_CApi_SQLITE_BUSY_TIMEOUT 773L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_NOTEMPDIR +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_NOTEMPDIR 270L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_ISDIR +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_ISDIR 526L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_FULLPATH +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_FULLPATH 782L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_CONVPATH +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_CONVPATH 1038L +#undef org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_SYMLINK +#define org_sqlite_jni_capi_CApi_SQLITE_CANTOPEN_SYMLINK 1550L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_VTAB 267L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_SEQUENCE +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_SEQUENCE 523L +#undef org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_INDEX +#define org_sqlite_jni_capi_CApi_SQLITE_CORRUPT_INDEX 779L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_RECOVERY +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_RECOVERY 264L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTLOCK +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTLOCK 520L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_ROLLBACK 776L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_DBMOVED +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_DBMOVED 1032L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTINIT +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_CANTINIT 1288L +#undef org_sqlite_jni_capi_CApi_SQLITE_READONLY_DIRECTORY +#define org_sqlite_jni_capi_CApi_SQLITE_READONLY_DIRECTORY 1544L +#undef org_sqlite_jni_capi_CApi_SQLITE_ABORT_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_ABORT_ROLLBACK 516L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_CHECK +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_CHECK 275L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_COMMITHOOK +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_COMMITHOOK 531L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FOREIGNKEY +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FOREIGNKEY 787L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FUNCTION +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_FUNCTION 1043L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_NOTNULL +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_NOTNULL 1299L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PRIMARYKEY +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PRIMARYKEY 1555L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_TRIGGER +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_TRIGGER 1811L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_UNIQUE +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_UNIQUE 2067L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_VTAB +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_VTAB 2323L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_ROWID +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_ROWID 2579L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PINNED +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_PINNED 2835L +#undef org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_DATATYPE +#define org_sqlite_jni_capi_CApi_SQLITE_CONSTRAINT_DATATYPE 3091L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_WAL +#define org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_WAL 283L +#undef org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_NOTICE_RECOVER_ROLLBACK 539L +#undef org_sqlite_jni_capi_CApi_SQLITE_WARNING_AUTOINDEX +#define org_sqlite_jni_capi_CApi_SQLITE_WARNING_AUTOINDEX 284L +#undef org_sqlite_jni_capi_CApi_SQLITE_AUTH_USER +#define org_sqlite_jni_capi_CApi_SQLITE_AUTH_USER 279L +#undef org_sqlite_jni_capi_CApi_SQLITE_OK_LOAD_PERMANENTLY +#define org_sqlite_jni_capi_CApi_SQLITE_OK_LOAD_PERMANENTLY 256L +#undef org_sqlite_jni_capi_CApi_SQLITE_SERIALIZE_NOCOPY +#define org_sqlite_jni_capi_CApi_SQLITE_SERIALIZE_NOCOPY 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_FREEONCLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_FREEONCLOSE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_READONLY +#define org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_READONLY 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_RESIZEABLE +#define org_sqlite_jni_capi_CApi_SQLITE_DESERIALIZE_RESIZEABLE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_SESSION_CONFIG_STRMSIZE +#define org_sqlite_jni_capi_CApi_SQLITE_SESSION_CONFIG_STRMSIZE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_SESSION_OBJCONFIG_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_SESSION_OBJCONFIG_SIZE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_MEMORY_USED +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_MEMORY_USED 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_USED +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_USED 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_OVERFLOW +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_OVERFLOW 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_SIZE 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PARSER_STACK +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PARSER_STACK 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_SIZE +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_PAGECACHE_SIZE 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_COUNT +#define org_sqlite_jni_capi_CApi_SQLITE_STATUS_MALLOC_COUNT 9L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FULLSCAN_STEP +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FULLSCAN_STEP 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_SORT +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_SORT 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_AUTOINDEX +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_AUTOINDEX 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_VM_STEP +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_VM_STEP 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_REPREPARE +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_REPREPARE 5L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_RUN +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_RUN 6L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_MISS +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_MISS 7L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_HIT +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_FILTER_HIT 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_MEMUSED +#define org_sqlite_jni_capi_CApi_SQLITE_STMTSTATUS_MEMUSED 99L +#undef org_sqlite_jni_capi_CApi_SQLITE_SYNC_NORMAL +#define org_sqlite_jni_capi_CApi_SQLITE_SYNC_NORMAL 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_SYNC_FULL +#define org_sqlite_jni_capi_CApi_SQLITE_SYNC_FULL 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_SYNC_DATAONLY +#define org_sqlite_jni_capi_CApi_SQLITE_SYNC_DATAONLY 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_STMT +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_STMT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_PROFILE +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_PROFILE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_ROW +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_ROW 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_TRACE_CLOSE +#define org_sqlite_jni_capi_CApi_SQLITE_TRACE_CLOSE 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_TXN_NONE +#define org_sqlite_jni_capi_CApi_SQLITE_TXN_NONE 0L +#undef org_sqlite_jni_capi_CApi_SQLITE_TXN_READ +#define org_sqlite_jni_capi_CApi_SQLITE_TXN_READ 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_TXN_WRITE +#define org_sqlite_jni_capi_CApi_SQLITE_TXN_WRITE 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_DETERMINISTIC +#define org_sqlite_jni_capi_CApi_SQLITE_DETERMINISTIC 2048L +#undef org_sqlite_jni_capi_CApi_SQLITE_DIRECTONLY +#define org_sqlite_jni_capi_CApi_SQLITE_DIRECTONLY 524288L +#undef org_sqlite_jni_capi_CApi_SQLITE_INNOCUOUS +#define org_sqlite_jni_capi_CApi_SQLITE_INNOCUOUS 2097152L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_SCAN_UNIQUE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_SCAN_UNIQUE 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_EQ +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_EQ 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GT 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LE 8L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LT 16L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GE 32L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_MATCH +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_MATCH 64L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIKE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIKE 65L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GLOB +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_GLOB 66L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_REGEXP +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_REGEXP 67L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_NE +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_NE 68L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOT 69L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOTNULL +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNULL +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_ISNULL 71L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_IS +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_IS 72L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIMIT +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_LIMIT 73L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_OFFSET +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_OFFSET 74L +#undef org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_FUNCTION +#define org_sqlite_jni_capi_CApi_SQLITE_INDEX_CONSTRAINT_FUNCTION 150L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_CONSTRAINT_SUPPORT +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_CONSTRAINT_SUPPORT 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_INNOCUOUS +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_INNOCUOUS 2L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_DIRECTONLY +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_DIRECTONLY 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_VTAB_USES_ALL_SCHEMAS +#define org_sqlite_jni_capi_CApi_SQLITE_VTAB_USES_ALL_SCHEMAS 4L +#undef org_sqlite_jni_capi_CApi_SQLITE_ROLLBACK +#define org_sqlite_jni_capi_CApi_SQLITE_ROLLBACK 1L +#undef org_sqlite_jni_capi_CApi_SQLITE_FAIL +#define org_sqlite_jni_capi_CApi_SQLITE_FAIL 3L +#undef org_sqlite_jni_capi_CApi_SQLITE_REPLACE +#define org_sqlite_jni_capi_CApi_SQLITE_REPLACE 5L +/* + * Class: org_sqlite_jni_capi_CApi + * Method: init + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_init + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_java_uncache_thread + * Signature: ()Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1java_1uncache_1thread + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_aggregate_context + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Z)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1aggregate_1context + (JNIEnv *, jclass, jobject, jboolean); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_auto_extension + * Signature: (Lorg/sqlite/jni/capi/AutoExtensionCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1auto_1extension + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_backup_finish + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1finish + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_backup_init + * Signature: (JLjava/lang/String;JLjava/lang/String;)Lorg/sqlite/jni/capi/sqlite3_backup; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1init + (JNIEnv *, jclass, jlong, jstring, jlong, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_backup_pagecount + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1pagecount + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_backup_remaining + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1remaining + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_backup_step + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1backup_1step + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_blob + * Signature: (JI[BI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1blob + (JNIEnv *, jclass, jlong, jint, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_double + * Signature: (JID)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1double + (JNIEnv *, jclass, jlong, jint, jdouble); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_int + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1int + (JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_int64 + * Signature: (JIJ)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1int64 + (JNIEnv *, jclass, jlong, jint, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_java_object + * Signature: (JILjava/lang/Object;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1java_1object + (JNIEnv *, jclass, jlong, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_null + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1null + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_parameter_count + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1parameter_1count + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_parameter_index + * Signature: (J[B)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1parameter_1index + (JNIEnv *, jclass, jlong, jbyteArray); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_parameter_name + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1parameter_1name + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_text + * Signature: (JI[BI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1text + (JNIEnv *, jclass, jlong, jint, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_text16 + * Signature: (JI[BI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1text16 + (JNIEnv *, jclass, jlong, jint, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_value + * Signature: (JIJ)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1value + (JNIEnv *, jclass, jlong, jint, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_zeroblob + * Signature: (JII)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1zeroblob + (JNIEnv *, jclass, jlong, jint, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_bind_zeroblob64 + * Signature: (JIJ)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1bind_1zeroblob64 + (JNIEnv *, jclass, jlong, jint, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_blob_bytes + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1bytes + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_blob_close + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1close + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_blob_open + * Signature: (JLjava/lang/String;Ljava/lang/String;Ljava/lang/String;JILorg/sqlite/jni/capi/OutputPointer/sqlite3_blob;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1open + (JNIEnv *, jclass, jlong, jstring, jstring, jstring, jlong, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_blob_read + * Signature: (J[BI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1read + (JNIEnv *, jclass, jlong, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_blob_reopen + * Signature: (JJ)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1reopen + (JNIEnv *, jclass, jlong, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_blob_write + * Signature: (J[BI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1blob_1write + (JNIEnv *, jclass, jlong, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_busy_handler + * Signature: (JLorg/sqlite/jni/capi/BusyHandlerCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1busy_1handler + (JNIEnv *, jclass, jlong, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_busy_timeout + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1busy_1timeout + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_cancel_auto_extension + * Signature: (Lorg/sqlite/jni/capi/AutoExtensionCallback;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1cancel_1auto_1extension + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_changes + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1changes + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_changes64 + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1changes64 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_clear_bindings + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1clear_1bindings + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_close + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1close + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_close_v2 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1close_1v2 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_blob + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1blob + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_bytes + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1bytes + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_bytes16 + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1bytes16 + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_count + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1count + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_decltype + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1decltype + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_double + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)D + */ +JNIEXPORT jdouble JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1double + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_int + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1int + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_int64 + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1int64 + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_name + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1name + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_database_name + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1database_1name + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_origin_name + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1origin_1name + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_table_name + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1table_1name + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_text + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1text + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_text16 + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1text16 + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_type + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1type + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_column_value + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;I)Lorg/sqlite/jni/capi/sqlite3_value; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1column_1value + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_collation_needed + * Signature: (JLorg/sqlite/jni/capi/CollationNeededCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1collation_1needed + (JNIEnv *, jclass, jlong, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_commit_hook + * Signature: (JLorg/sqlite/jni/capi/CommitHookCallback;)Lorg/sqlite/jni/capi/CommitHookCallback; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1commit_1hook + (JNIEnv *, jclass, jlong, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_compileoption_get + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1compileoption_1get + (JNIEnv *, jclass, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_compileoption_used + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1compileoption_1used + (JNIEnv *, jclass, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_complete + * Signature: ([B)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1complete + (JNIEnv *, jclass, jbyteArray); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_config + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__I + (JNIEnv *, jclass, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_config + * Signature: (Lorg/sqlite/jni/capi/ConfigSqllogCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__Lorg_sqlite_jni_capi_ConfigSqllogCallback_2 + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_config + * Signature: (Lorg/sqlite/jni/capi/ConfigLogCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1config__Lorg_sqlite_jni_capi_ConfigLogCallback_2 + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_context_db_handle + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)Lorg/sqlite/jni/capi/sqlite3; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1context_1db_1handle + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_create_collation + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;ILorg/sqlite/jni/capi/CollationCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1create_1collation + (JNIEnv *, jclass, jobject, jstring, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_create_function + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;IILorg/sqlite/jni/capi/SQLFunction;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1create_1function + (JNIEnv *, jclass, jobject, jstring, jint, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_data_count + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1data_1count + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_config + * Signature: (Lorg/sqlite/jni/capi/sqlite3;IILorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2IILorg_sqlite_jni_capi_OutputPointer_Int32_2 + (JNIEnv *, jclass, jobject, jint, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_config + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1config__Lorg_sqlite_jni_capi_sqlite3_2ILjava_lang_String_2 + (JNIEnv *, jclass, jobject, jint, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_name + * Signature: (JI)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1name + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_filename + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1filename + (JNIEnv *, jclass, jobject, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_handle + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Lorg/sqlite/jni/capi/sqlite3; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1handle + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_readonly + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1readonly + (JNIEnv *, jclass, jobject, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_release_memory + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1release_1memory + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_db_status + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;Z)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1db_1status + (JNIEnv *, jclass, jobject, jint, jobject, jobject, jboolean); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_errcode + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errcode + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_errmsg + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errmsg + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_error_offset + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1error_1offset + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_errstr + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1errstr + (JNIEnv *, jclass, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_expanded_sql + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1expanded_1sql + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_extended_errcode + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1extended_1errcode + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_extended_result_codes + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Z)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1extended_1result_1codes + (JNIEnv *, jclass, jobject, jboolean); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_get_autocommit + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1get_1autocommit + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_get_auxdata + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1get_1auxdata + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_finalize + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1finalize + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_initialize + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1initialize + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_interrupt + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1interrupt + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_is_interrupted + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1is_1interrupted + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_keyword_check + * Signature: (Ljava/lang/String;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1keyword_1check + (JNIEnv *, jclass, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_keyword_count + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1keyword_1count + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_keyword_name + * Signature: (I)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1keyword_1name + (JNIEnv *, jclass, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_last_insert_rowid + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1last_1insert_1rowid + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_libversion + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1libversion + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_libversion_number + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1libversion_1number + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_limit + * Signature: (Lorg/sqlite/jni/capi/sqlite3;II)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1limit + (JNIEnv *, jclass, jobject, jint, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_normalized_sql + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1normalized_1sql + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_open + * Signature: (Ljava/lang/String;Lorg/sqlite/jni/capi/OutputPointer/sqlite3;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1open + (JNIEnv *, jclass, jstring, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_open_v2 + * Signature: (Ljava/lang/String;Lorg/sqlite/jni/capi/OutputPointer/sqlite3;ILjava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1open_1v2 + (JNIEnv *, jclass, jstring, jobject, jint, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_prepare + * Signature: (J[BILorg/sqlite/jni/capi/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1prepare + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_prepare_v2 + * Signature: (J[BILorg/sqlite/jni/capi/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1prepare_1v2 + (JNIEnv *, jclass, jlong, jbyteArray, jint, jobject, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_prepare_v3 + * Signature: (J[BIILorg/sqlite/jni/capi/OutputPointer/sqlite3_stmt;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1prepare_1v3 + (JNIEnv *, jclass, jlong, jbyteArray, jint, jint, jobject, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_preupdate_blobwrite + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1blobwrite + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_preupdate_count + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1count + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_preupdate_depth + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1depth + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_preupdate_hook + * Signature: (JLorg/sqlite/jni/capi/PreupdateHookCallback;)Lorg/sqlite/jni/capi/PreupdateHookCallback; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1hook + (JNIEnv *, jclass, jlong, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_preupdate_new + * Signature: (JILorg/sqlite/jni/capi/OutputPointer/sqlite3_value;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1new + (JNIEnv *, jclass, jlong, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_preupdate_old + * Signature: (JILorg/sqlite/jni/capi/OutputPointer/sqlite3_value;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1preupdate_1old + (JNIEnv *, jclass, jlong, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_progress_handler + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILorg/sqlite/jni/capi/ProgressHandlerCallback;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1progress_1handler + (JNIEnv *, jclass, jobject, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_randomness + * Signature: ([B)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1randomness + (JNIEnv *, jclass, jbyteArray); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_release_memory + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1release_1memory + (JNIEnv *, jclass, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_reset + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1reset + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_reset_auto_extension + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1reset_1auto_1extension + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_double + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;D)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1double + (JNIEnv *, jclass, jobject, jdouble); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_error + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BI)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error + (JNIEnv *, jclass, jobject, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_error_toobig + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1toobig + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_error_nomem + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1nomem + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_error_code + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1error_1code + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_null + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1null + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_int + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1int + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_int64 + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;J)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1int64 + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_java_object + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Ljava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1java_1object + (JNIEnv *, jclass, jobject, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_value + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;Lorg/sqlite/jni/capi/sqlite3_value;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1value + (JNIEnv *, jclass, jobject, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_zeroblob + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;I)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1zeroblob + (JNIEnv *, jclass, jobject, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_zeroblob64 + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1zeroblob64 + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_blob + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BI)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1blob + (JNIEnv *, jclass, jobject, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_blob64 + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BJ)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1blob64 + (JNIEnv *, jclass, jobject, jbyteArray, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_text + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BI)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1text + (JNIEnv *, jclass, jobject, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_result_text64 + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;[BJI)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1result_1text64 + (JNIEnv *, jclass, jobject, jbyteArray, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_rollback_hook + * Signature: (JLorg/sqlite/jni/capi/RollbackHookCallback;)Lorg/sqlite/jni/capi/RollbackHookCallback; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1rollback_1hook + (JNIEnv *, jclass, jlong, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_set_authorizer + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Lorg/sqlite/jni/capi/AuthorizerCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1set_1authorizer + (JNIEnv *, jclass, jobject, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_set_auxdata + * Signature: (Lorg/sqlite/jni/capi/sqlite3_context;ILjava/lang/Object;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1set_1auxdata + (JNIEnv *, jclass, jobject, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_set_last_insert_rowid + * Signature: (Lorg/sqlite/jni/capi/sqlite3;J)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1set_1last_1insert_1rowid + (JNIEnv *, jclass, jobject, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_shutdown + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1shutdown + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_sleep + * Signature: (I)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1sleep + (JNIEnv *, jclass, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_sourceid + * Signature: ()Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1sourceid + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_sql + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1sql + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_status + * Signature: (ILorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;Z)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1status + (JNIEnv *, jclass, jint, jobject, jobject, jboolean); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_status64 + * Signature: (ILorg/sqlite/jni/capi/OutputPointer/Int64;Lorg/sqlite/jni/capi/OutputPointer/Int64;Z)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1status64 + (JNIEnv *, jclass, jint, jobject, jobject, jboolean); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_step + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1step + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_stmt_busy + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1busy + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_stmt_explain + * Signature: (JI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1explain + (JNIEnv *, jclass, jlong, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_stmt_isexplain + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1isexplain + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_stmt_readonly + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1readonly + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_stmt_status + * Signature: (Lorg/sqlite/jni/capi/sqlite3_stmt;IZ)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1stmt_1status + (JNIEnv *, jclass, jobject, jint, jboolean); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_strglob + * Signature: ([B[B)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1strglob + (JNIEnv *, jclass, jbyteArray, jbyteArray); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_strlike + * Signature: ([B[BI)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1strlike + (JNIEnv *, jclass, jbyteArray, jbyteArray, jint); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_system_errno + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1system_1errno + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_table_column_metadata + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;Ljava/lang/String;Ljava/lang/String;Lorg/sqlite/jni/capi/OutputPointer/String;Lorg/sqlite/jni/capi/OutputPointer/String;Lorg/sqlite/jni/capi/OutputPointer/Bool;Lorg/sqlite/jni/capi/OutputPointer/Bool;Lorg/sqlite/jni/capi/OutputPointer/Bool;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1table_1column_1metadata + (JNIEnv *, jclass, jobject, jstring, jstring, jstring, jobject, jobject, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_threadsafe + * Signature: ()I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1threadsafe + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_total_changes + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1total_1changes + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_total_changes64 + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1total_1changes64 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_trace_v2 + * Signature: (Lorg/sqlite/jni/capi/sqlite3;ILorg/sqlite/jni/capi/TraceV2Callback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1trace_1v2 + (JNIEnv *, jclass, jobject, jint, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_txn_state + * Signature: (Lorg/sqlite/jni/capi/sqlite3;Ljava/lang/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1txn_1state + (JNIEnv *, jclass, jobject, jstring); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_update_hook + * Signature: (JLorg/sqlite/jni/capi/UpdateHookCallback;)Lorg/sqlite/jni/capi/UpdateHookCallback; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1update_1hook + (JNIEnv *, jclass, jlong, jobject); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_blob + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1blob + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_bytes + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1bytes + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_bytes16 + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1bytes16 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_double + * Signature: (J)D + */ +JNIEXPORT jdouble JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1double + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_dup + * Signature: (J)Lorg/sqlite/jni/capi/sqlite3_value; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1dup + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_encoding + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1encoding + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_free + * Signature: (J)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1free + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_frombind + * Signature: (J)Z + */ +JNIEXPORT jboolean JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1frombind + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_int + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1int + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_int64 + * Signature: (J)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1int64 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_java_object + * Signature: (J)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1java_1object + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_nochange + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1nochange + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_numeric_type + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1numeric_1type + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_subtype + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1subtype + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_text + * Signature: (J)[B + */ +JNIEXPORT jbyteArray JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1text + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_text16 + * Signature: (J)Ljava/lang/String; + */ +JNIEXPORT jstring JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1text16 + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_value_type + * Signature: (J)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1value_1type + (JNIEnv *, jclass, jlong); + +/* + * Class: org_sqlite_jni_capi_CApi + * Method: sqlite3_jni_internal_details + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_CApi_sqlite3_1jni_1internal_1details + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_sqlite_jni_capi_SQLTester */ + +#ifndef _Included_org_sqlite_jni_capi_SQLTester +#define _Included_org_sqlite_jni_capi_SQLTester +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_sqlite_jni_capi_SQLTester + * Method: strglob + * Signature: ([B[B)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_capi_SQLTester_strglob + (JNIEnv *, jclass, jbyteArray, jbyteArray); + +/* + * Class: org_sqlite_jni_capi_SQLTester + * Method: installCustomExtensions + * Signature: ()V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_capi_SQLTester_installCustomExtensions + (JNIEnv *, jclass); + +#ifdef __cplusplus +} +#endif +#endif +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_sqlite_jni_fts5_Fts5ExtensionApi */ + +#ifndef _Included_org_sqlite_jni_fts5_Fts5ExtensionApi +#define _Included_org_sqlite_jni_fts5_Fts5ExtensionApi +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: getInstance + * Signature: ()Lorg/sqlite/jni/fts5/Fts5ExtensionApi; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_getInstance + (JNIEnv *, jclass); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xColumnCount + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnCount + (JNIEnv *, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xColumnSize + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnSize + (JNIEnv *, jobject, jobject, jint, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xColumnText + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/String;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnText + (JNIEnv *, jobject, jobject, jint, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xColumnTotalSize + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/Int64;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xColumnTotalSize + (JNIEnv *, jobject, jobject, jint, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xGetAuxdata + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Z)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xGetAuxdata + (JNIEnv *, jobject, jobject, jboolean); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xInst + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xInst + (JNIEnv *, jobject, jobject, jint, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xInstCount + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xInstCount + (JNIEnv *, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xPhraseCount + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseCount + (JNIEnv *, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xPhraseFirst + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseFirst + (JNIEnv *, jobject, jobject, jint, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xPhraseFirstColumn + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseFirstColumn + (JNIEnv *, jobject, jobject, jint, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xPhraseNext + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;Lorg/sqlite/jni/capi/OutputPointer/Int32;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseNext + (JNIEnv *, jobject, jobject, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xPhraseNextColumn + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/fts5/Fts5PhraseIter;Lorg/sqlite/jni/capi/OutputPointer/Int32;)V + */ +JNIEXPORT void JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseNextColumn + (JNIEnv *, jobject, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xPhraseSize + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;I)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xPhraseSize + (JNIEnv *, jobject, jobject, jint); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xQueryPhrase + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;ILorg/sqlite/jni/fts5/Fts5ExtensionApi/XQueryPhraseCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xQueryPhrase + (JNIEnv *, jobject, jobject, jint, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xRowCount + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Lorg/sqlite/jni/capi/OutputPointer/Int64;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xRowCount + (JNIEnv *, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xRowid + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;)J + */ +JNIEXPORT jlong JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xRowid + (JNIEnv *, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xSetAuxdata + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;Ljava/lang/Object;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xSetAuxdata + (JNIEnv *, jobject, jobject, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xTokenize + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;[BLorg/sqlite/jni/fts5/XTokenizeCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xTokenize + (JNIEnv *, jobject, jobject, jbyteArray, jobject); + +/* + * Class: org_sqlite_jni_fts5_Fts5ExtensionApi + * Method: xUserData + * Signature: (Lorg/sqlite/jni/fts5/Fts5Context;)Ljava/lang/Object; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_fts5_Fts5ExtensionApi_xUserData + (JNIEnv *, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_sqlite_jni_fts5_fts5_api */ + +#ifndef _Included_org_sqlite_jni_fts5_fts5_api +#define _Included_org_sqlite_jni_fts5_fts5_api +#ifdef __cplusplus +extern "C" { +#endif +#undef org_sqlite_jni_fts5_fts5_api_iVersion +#define org_sqlite_jni_fts5_fts5_api_iVersion 2L +/* + * Class: org_sqlite_jni_fts5_fts5_api + * Method: getInstanceForDb + * Signature: (Lorg/sqlite/jni/capi/sqlite3;)Lorg/sqlite/jni/fts5/fts5_api; + */ +JNIEXPORT jobject JNICALL Java_org_sqlite_jni_fts5_fts5_1api_getInstanceForDb + (JNIEnv *, jclass, jobject); + +/* + * Class: org_sqlite_jni_fts5_fts5_api + * Method: xCreateFunction + * Signature: (Ljava/lang/String;Ljava/lang/Object;Lorg/sqlite/jni/fts5/fts5_extension_function;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_fts5_1api_xCreateFunction + (JNIEnv *, jobject, jstring, jobject, jobject); + +#ifdef __cplusplus +} +#endif +#endif +/* DO NOT EDIT THIS FILE - it is machine generated */ +#include +/* Header for class org_sqlite_jni_fts5_fts5_tokenizer */ + +#ifndef _Included_org_sqlite_jni_fts5_fts5_tokenizer +#define _Included_org_sqlite_jni_fts5_fts5_tokenizer +#ifdef __cplusplus +extern "C" { +#endif +/* + * Class: org_sqlite_jni_fts5_fts5_tokenizer + * Method: xTokenize + * Signature: (Lorg/sqlite/jni/fts5/Fts5Tokenizer;I[BLorg/sqlite/jni/fts5/XTokenizeCallback;)I + */ +JNIEXPORT jint JNICALL Java_org_sqlite_jni_fts5_fts5_1tokenizer_xTokenize + (JNIEnv *, jobject, jobject, jint, jbyteArray, jobject); + +#ifdef __cplusplus +} +#endif +#endif diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/annotation/NotNull.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/annotation/NotNull.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/annotation/NotNull.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/annotation/NotNull.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,59 @@ +/* +** 2023-09-27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file houses the NotNull annotaion for the sqlite3 C API. +*/ +package org.sqlite.jni.annotation; + +/** + This annotation is for flagging parameters which may not legally be + null or point to closed/finalized C-side resources. + +

In the case of Java types which map directly to C struct types + (e.g. {@link org.sqlite.jni.sqlite3}, {@link + org.sqlite.jni.sqlite3_stmt}, and {@link + org.sqlite.jni.sqlite3_context}), a closed/finalized resource is + also considered to be null for purposes this annotation because the + C-side effect of passing such a handle is the same as if null is + passed.

+ +

When used in the context of Java interfaces which are called + from the C APIs, this annotation communicates that the C API will + never pass a null value to the callback for that parameter.

+ +

Passing a null, for this annotation's definition of null, for + any parameter marked with this annoation specifically invokes + undefined behavior.

+ +

Passing 0 (i.e. C NULL) or a negative value for any long-type + parameter marked with this annoation specifically invokes undefined + behavior. Such values are treated as C pointers in the JNI + layer.

+ +

Note that the C-style API does not throw any exceptions on its + own because it has a no-throw policy in order to retain its C-style + semantics, but it may trigger NullPointerExceptions (or similar) if + passed a null for a parameter flagged with this annotation.

+ +

This annotation is informational only. No policy is in place to + programmatically ensure that NotNull is conformed to in client + code.

+ +

This annotation is solely for the use by the classes in the + org.sqlite package and subpackages, but is made public so that + javadoc will link to it from the annotated functions. It is not + part of the public API and client-level code must not rely on + it.

+*/ +@java.lang.annotation.Documented +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) +@java.lang.annotation.Target(java.lang.annotation.ElementType.PARAMETER) +public @interface NotNull{} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/annotation/Nullable.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/annotation/Nullable.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/annotation/Nullable.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/annotation/Nullable.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,32 @@ +/* +** 2023-09-27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file houses the Nullable annotaion for the sqlite3 C API. +*/ +package org.sqlite.jni.annotation; + +/** + This annotation is for flagging parameters which may legally be + null, noting that they may behave differently if passed null but + are prepared to expect null as a value. When used in the context of + callback methods which are called into from the C APIs, this + annotation communicates that the C API may pass a null value to the + callback. + +

This annotation is solely for the use by the classes in this + package but is made public so that javadoc will link to it from the + annotated functions. It is not part of the public API and + client-level code must not rely on it. +*/ +@java.lang.annotation.Documented +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.SOURCE) +@java.lang.annotation.Target(java.lang.annotation.ElementType.PARAMETER) +public @interface Nullable{} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/annotation/package-info.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/annotation/package-info.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/annotation/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/annotation/package-info.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,17 @@ +/* +** 2023-09-27 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +*/ +/** + This package houses annotations specific to the JNI bindings of the + SQLite3 C API. +*/ +package org.sqlite.jni.annotation; diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,34 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; +import org.sqlite.jni.annotation.NotNull; + +/** + An implementation of {@link CollationCallback} which provides a + no-op xDestroy() method. +*/ +public abstract class AbstractCollationCallback + implements CollationCallback, XDestroyCallback { + /** + Must compare the given byte arrays and return the result using + {@code memcmp()} semantics. + */ + public abstract int call(@NotNull byte[] lhs, @NotNull byte[] rhs); + + /** + Optionally override to be notified when the UDF is finalized by + SQLite. This implementation does nothing. + */ + public void xDestroy(){} +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,72 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + + +/** + A SQLFunction implementation for aggregate functions. Its T is the + data type of its "accumulator" state, an instance of which is + intended to be be managed using the getAggregateState() and + takeAggregateState() methods. +*/ +public abstract class AggregateFunction implements SQLFunction { + + /** + As for the xStep() argument of the C API's + sqlite3_create_function(). If this function throws, the + exception is not propagated and a warning might be emitted to a + debugging channel. + */ + public abstract void xStep(sqlite3_context cx, sqlite3_value[] args); + + /** + As for the xFinal() argument of the C API's sqlite3_create_function(). + If this function throws, it is translated into an sqlite3_result_error(). + */ + public abstract void xFinal(sqlite3_context cx); + + /** + Optionally override to be notified when the UDF is finalized by + SQLite. + */ + public void xDestroy() {} + + /** Per-invocation state for the UDF. */ + private final SQLFunction.PerContextState map = + new SQLFunction.PerContextState<>(); + + /** + To be called from the implementation's xStep() method, as well + as the xValue() and xInverse() methods of the {@link WindowFunction} + subclass, to fetch the current per-call UDF state. On the + first call to this method for any given sqlite3_context + argument, the context is set to the given initial value. On all other + calls, the 2nd argument is ignored. + + @see SQLFunction.PerContextState#getAggregateState + */ + protected final ValueHolder getAggregateState(sqlite3_context cx, T initialValue){ + return map.getAggregateState(cx, initialValue); + } + + /** + To be called from the implementation's xFinal() method to fetch + the final state of the UDF and remove its mapping. + + see SQLFunction.PerContextState#takeAggregateState + */ + protected final T takeAggregateState(sqlite3_context cx){ + return map.takeAggregateState(cx); + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,28 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; +import org.sqlite.jni.annotation.*; + +/** + Callback for use with {@link CApi#sqlite3_set_authorizer}. +*/ +public interface AuthorizerCallback extends CallbackProxy { + /** + Must function as described for the C-level + sqlite3_set_authorizer() callback. + */ + int call(int opId, @Nullable String s1, @Nullable String s2, + @Nullable String s3, @Nullable String s4); + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,40 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with the {@link CApi#sqlite3_auto_extension} + family of APIs. +*/ +public interface AutoExtensionCallback extends CallbackProxy { + /** + Must function as described for a C-level + sqlite3_auto_extension() callback. + +

This callback may throw and the exception's error message will + be set as the db's error string. + +

Tips for implementations: + +

- Opening a database from an auto-extension handler will lead to + an endless recursion of the auto-handler triggering itself + indirectly for each newly-opened database. + +

- If this routine is stateful, it may be useful to make the + overridden method synchronized. + +

- Results are undefined if the given db is closed by an auto-extension. + */ + int call(sqlite3 db); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,26 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_busy_handler}. +*/ +public interface BusyHandlerCallback extends CallbackProxy { + /** + Must function as documented for the C-level + sqlite3_busy_handler() callback argument, minus the (void*) + argument the C-level function requires. + */ + int call(int n); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,44 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; +/** + This marker interface exists soley for use as a documentation and + class-grouping tool. It should be applied to interfaces or + classes which have a call() method implementing some specific + callback interface on behalf of the C library. + +

Unless very explicitely documented otherwise, callbacks must + never throw. Any which do throw but should not might trigger debug + output regarding the error, but the exception will not be + propagated. For callback interfaces which support returning error + info to the core, the JNI binding will convert any exceptions to + C-level error information. For callback interfaces which do not + support, all exceptions will necessarily be suppressed in order to + retain the C-style no-throw semantics. + +

Callbacks of this style follow a common naming convention: + +

1) They use the UpperCamelCase form of the C function they're + proxying for, minus the {@code sqlite3_} prefix, plus a {@code + Callback} suffix. e.g. {@code sqlite3_busy_handler()}'s callback is + named {@code BusyHandlerCallback}. Exceptions are made where that + would potentially be ambiguous, e.g. {@link ConfigSqllogCallback} + instead of {@code ConfigCallback} because the {@code + sqlite3_config()} interface may need to support more callback types + in the future. + +

2) They all have a {@code call()} method but its signature is + callback-specific. +*/ +public interface CallbackProxy {} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CApi.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CApi.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CApi.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CApi.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,2449 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file declares JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; +import java.nio.charset.StandardCharsets; +import java.lang.annotation.Retention; +import java.lang.annotation.RetentionPolicy; +import java.lang.annotation.Target; +import java.lang.annotation.Documented; +import java.lang.annotation.ElementType; +import org.sqlite.jni.annotation.*; +import java.util.Arrays; + +/** + This class contains the entire C-style sqlite3 JNI API binding, + minus a few bits and pieces declared in other files. For client-side + use, a static import is recommended: + +

{@code
+  import static org.sqlite.jni.capi.CApi.*;
+  }
+ +

The C-side part can be found in sqlite3-jni.c. + +

This class is package-private in order to keep Java clients from + having direct access to the low-level C-style APIs, a design + decision made by Java developers based on the C-style API being + riddled with opportunities for Java developers to proverbially shoot + themselves in the foot with. Third-party copies of this code may + eliminate that guard by simply changing this class from + package-private to public. Its methods which are intended to be + exposed that way are all public. + +

Only functions which materially differ from their C counterparts + are documented here, and only those material differences are + documented. The C documentation is otherwise applicable for these + APIs: + +

https://sqlite.org/c3ref/intro.html + +

A handful of Java-specific APIs have been added which are + documented here. A number of convenience overloads are provided + which are not documented but whose semantics map 1-to-1 in an + intuitive manner. e.g. {@link + #sqlite3_result_set(sqlite3_context,int)} is equivalent to {@link + #sqlite3_result_int}, and sqlite3_result_set() has many + type-specific overloads. + +

Notes regarding Java's Modified UTF-8 vs standard UTF-8: + +

SQLite internally uses UTF-8 encoding, whereas Java natively uses + UTF-16. Java JNI has routines for converting to and from UTF-8, + but JNI uses what its docs call modified UTF-8 (see links below) + Care must be taken when converting Java strings to or from standard + UTF-8 to ensure that the proper conversion is performed. In short, + Java's {@code String.getBytes(StandardCharsets.UTF_8)} performs the proper + conversion in Java, and there are no JNI C APIs for that conversion + (JNI's {@code NewStringUTF()} requires its input to be in MUTF-8). + +

The known consequences and limitations this discrepancy places on + the SQLite3 JNI binding include: + +

    + +
  • C functions which take C-style strings without a length argument + require special care when taking input from Java. In particular, + Java strings converted to byte arrays for encoding purposes are not + NUL-terminated, and conversion to a Java byte array must sometimes + be careful to add one. Functions which take a length do not require + this so long as the length is provided. Search the CApi class + for "\0" for many examples. + +
+ +

Further reading: + +

https://stackoverflow.com/questions/57419723 +

https://stackoverflow.com/questions/7921016 +

https://itecnote.com/tecnote/java-getting-true-utf-8-characters-in-java-jni/ +

https://docs.oracle.com/javase/8/docs/api/java/lang/Character.html#unicode +

https://docs.oracle.com/javase/8/docs/api/java/io/DataInput.html#modified-utf-8 + +*/ +public final class CApi { + static { + System.loadLibrary("sqlite3-jni"); + } + //! Not used + private CApi(){} + //! Called from static init code. + private static native void init(); + + /** + Returns a nul-terminated copy of s as a UTF-8-encoded byte array, + or null if s is null. + */ + private static byte[] nulTerminateUtf8(String s){ + return null==s ? null : (s+"\0").getBytes(StandardCharsets.UTF_8); + } + + /** + Each thread which uses the SQLite3 JNI APIs should call + sqlite3_jni_uncache_thread() when it is done with the library - + either right before it terminates or when it finishes using the + SQLite API. This will clean up any cached per-thread info. + +

This process does not close any databases or finalize + any prepared statements because their ownership does not depend on + a given thread. For proper library behavior, and to + avoid C-side leaks, be sure to finalize all statements and close + all databases before calling this function. + +

Calling this from the main application thread is not strictly + required. Additional threads must call this before ending or they + will leak cache entries in the C heap, which in turn may keep + numerous Java-side global references active. + +

This routine returns false without side effects if the current + JNIEnv is not cached, else returns true, but this information is + primarily for testing of the JNI bindings and is not information + which client-level code can use to make any informed decisions. + */ + public static native boolean sqlite3_java_uncache_thread(); + + ////////////////////////////////////////////////////////////////////// + // Maintenance reminder: please keep the sqlite3_.... functions + // alphabetized. The SQLITE_... values. on the other hand, are + // grouped by category. + + /** + Functions exactly like the native form except that (A) the 2nd + argument is a boolean instead of an int and (B) the returned + value is not a pointer address and is only intended for use as a + per-UDF-call lookup key in a higher-level data structure. + +

Passing a true second argument is analogous to passing some + unspecified small, non-0 positive value to the C API and passing + false is equivalent to passing 0 to the C API. + +

Like the C API, it returns 0 if allocation fails or if + initialize is false and no prior aggregate context was allocated + for cx. If initialize is true then it returns 0 only on + allocation error. In all casses, 0 is considered the sentinel + "not a key" value. + */ + public static native long sqlite3_aggregate_context(sqlite3_context cx, boolean initialize); + + /** + Functions almost as documented for the C API, with these + exceptions: + +

- The callback interface is shorter because of + cross-language differences. Specifically, 3rd argument to the C + auto-extension callback interface is unnecessary here. + +

The C API docs do not specifically say so, but if the list of + auto-extensions is manipulated from an auto-extension, it is + undefined which, if any, auto-extensions will subsequently + execute for the current database. That is, doing so will result + in unpredictable, but not undefined, behavior. + +

See the AutoExtension class docs for more information. + */ + public static native int sqlite3_auto_extension(@NotNull AutoExtensionCallback callback); + + static native int sqlite3_backup_finish(@NotNull long ptrToBackup); + + public static int sqlite3_backup_finish(@NotNull sqlite3_backup b){ + return sqlite3_backup_finish(b.clearNativePointer()); + } + + static native sqlite3_backup sqlite3_backup_init( + @NotNull long ptrToDbDest, @NotNull String destTableName, + @NotNull long ptrToDbSrc, @NotNull String srcTableName + ); + + public static sqlite3_backup sqlite3_backup_init( + @NotNull sqlite3 dbDest, @NotNull String destTableName, + @NotNull sqlite3 dbSrc, @NotNull String srcTableName + ){ + return sqlite3_backup_init( dbDest.getNativePointer(), destTableName, + dbSrc.getNativePointer(), srcTableName ); + } + + static native int sqlite3_backup_pagecount(@NotNull long ptrToBackup); + + public static int sqlite3_backup_pagecount(@NotNull sqlite3_backup b){ + return sqlite3_backup_pagecount(b.getNativePointer()); + } + + static native int sqlite3_backup_remaining(@NotNull long ptrToBackup); + + public static int sqlite3_backup_remaining(@NotNull sqlite3_backup b){ + return sqlite3_backup_remaining(b.getNativePointer()); + } + + static native int sqlite3_backup_step(@NotNull long ptrToBackup, int nPage); + + public static int sqlite3_backup_step(@NotNull sqlite3_backup b, int nPage){ + return sqlite3_backup_step(b.getNativePointer(), nPage); + } + + static native int sqlite3_bind_blob( + @NotNull long ptrToStmt, int ndx, @Nullable byte[] data, int n + ); + + /** + If n is negative, SQLITE_MISUSE is returned. If n>data.length + then n is silently truncated to data.length. + */ + static int sqlite3_bind_blob( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data, int n + ){ + return sqlite3_bind_blob(stmt.getNativePointer(), ndx, data, n); + } + + public static int sqlite3_bind_blob( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data + ){ + return (null==data) + ? sqlite3_bind_null(stmt.getNativePointer(), ndx) + : sqlite3_bind_blob(stmt.getNativePointer(), ndx, data, data.length); + } + + static native int sqlite3_bind_double( + @NotNull long ptrToStmt, int ndx, double v + ); + + public static int sqlite3_bind_double( + @NotNull sqlite3_stmt stmt, int ndx, double v + ){ + return sqlite3_bind_double(stmt.getNativePointer(), ndx, v); + } + + static native int sqlite3_bind_int( + @NotNull long ptrToStmt, int ndx, int v + ); + + public static int sqlite3_bind_int( + @NotNull sqlite3_stmt stmt, int ndx, int v + ){ + return sqlite3_bind_int(stmt.getNativePointer(), ndx, v); + } + + static native int sqlite3_bind_int64( + @NotNull long ptrToStmt, int ndx, long v + ); + + public static int sqlite3_bind_int64(@NotNull sqlite3_stmt stmt, int ndx, long v){ + return sqlite3_bind_int64( stmt.getNativePointer(), ndx, v ); + } + + static native int sqlite3_bind_java_object( + @NotNull long ptrToStmt, int ndx, @Nullable Object o + ); + + /** + Binds the given object at the given index. If o is null then this behaves like + sqlite3_bind_null(). + + @see #sqlite3_result_java_object + */ + public static int sqlite3_bind_java_object( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable Object o + ){ + return sqlite3_bind_java_object(stmt.getNativePointer(), ndx, o); + } + + static native int sqlite3_bind_null(@NotNull long ptrToStmt, int ndx); + + public static int sqlite3_bind_null(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_bind_null(stmt.getNativePointer(), ndx); + } + + static native int sqlite3_bind_parameter_count(@NotNull long ptrToStmt); + + public static int sqlite3_bind_parameter_count(@NotNull sqlite3_stmt stmt){ + return sqlite3_bind_parameter_count(stmt.getNativePointer()); + } + + /** + Requires that paramName be a NUL-terminated UTF-8 string. + + This overload is private because: (A) to keep users from + inadvertently passing non-NUL-terminated byte arrays (an easy + thing to do). (B) it is cheaper to NUL-terminate the + String-to-byte-array conversion in the public-facing Java-side + overload than to do that in C, so that signature is the + public-facing one. + */ + private static native int sqlite3_bind_parameter_index( + @NotNull long ptrToStmt, @NotNull byte[] paramName + ); + + public static int sqlite3_bind_parameter_index( + @NotNull sqlite3_stmt stmt, @NotNull String paramName + ){ + final byte[] utf8 = nulTerminateUtf8(paramName); + return null==utf8 ? 0 : sqlite3_bind_parameter_index(stmt.getNativePointer(), utf8); + } + + static native String sqlite3_bind_parameter_name( + @NotNull long ptrToStmt, int index + ); + + public static String sqlite3_bind_parameter_name(@NotNull sqlite3_stmt stmt, int index){ + return sqlite3_bind_parameter_name(stmt.getNativePointer(), index); + } + + static native int sqlite3_bind_text( + @NotNull long ptrToStmt, int ndx, @Nullable byte[] utf8, int maxBytes + ); + + /** + Works like the C-level sqlite3_bind_text() but assumes + SQLITE_TRANSIENT for the final C API parameter. The byte array is + assumed to be in UTF-8 encoding. + +

If data is not null and maxBytes>utf8.length then maxBytes is + silently truncated to utf8.length. If maxBytes is negative then + results are undefined if data is not null and does not contain a + NUL byte. + */ + static int sqlite3_bind_text( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] utf8, int maxBytes + ){ + return sqlite3_bind_text(stmt.getNativePointer(), ndx, utf8, maxBytes); + } + + /** + Converts data, if not null, to a UTF-8-encoded byte array and + binds it as such, returning the result of the C-level + sqlite3_bind_null() or sqlite3_bind_text(). + */ + public static int sqlite3_bind_text( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable String data + ){ + if( null==data ) return sqlite3_bind_null(stmt.getNativePointer(), ndx); + final byte[] utf8 = data.getBytes(StandardCharsets.UTF_8); + return sqlite3_bind_text(stmt.getNativePointer(), ndx, utf8, utf8.length); + } + + /** + Requires that utf8 be null or in UTF-8 encoding. + */ + public static int sqlite3_bind_text( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] utf8 + ){ + return ( null==utf8 ) + ? sqlite3_bind_null(stmt.getNativePointer(), ndx) + : sqlite3_bind_text(stmt.getNativePointer(), ndx, utf8, utf8.length); + } + + static native int sqlite3_bind_text16( + @NotNull long ptrToStmt, int ndx, @Nullable byte[] data, int maxBytes + ); + + /** + Identical to the sqlite3_bind_text() overload with the same + signature but requires that its input be encoded in UTF-16 in + platform byte order. + */ + static int sqlite3_bind_text16( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data, int maxBytes + ){ + return sqlite3_bind_text16(stmt.getNativePointer(), ndx, data, maxBytes); + } + + /** + Converts its string argument to UTF-16 and binds it as such, returning + the result of the C-side function of the same name. The 3rd argument + may be null. + */ + public static int sqlite3_bind_text16( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable String data + ){ + if(null == data) return sqlite3_bind_null(stmt, ndx); + final byte[] bytes = data.getBytes(StandardCharsets.UTF_16); + return sqlite3_bind_text16(stmt.getNativePointer(), ndx, bytes, bytes.length); + } + + /** + Requires that data be null or in UTF-16 encoding in platform byte + order. Returns the result of the C-level sqlite3_bind_null() or + sqlite3_bind_text16(). + */ + public static int sqlite3_bind_text16( + @NotNull sqlite3_stmt stmt, int ndx, @Nullable byte[] data + ){ + return (null == data) + ? sqlite3_bind_null(stmt.getNativePointer(), ndx) + : sqlite3_bind_text16(stmt.getNativePointer(), ndx, data, data.length); + } + + static native int sqlite3_bind_value(@NotNull long ptrToStmt, int ndx, long ptrToValue); + + /** + Functions like the C-level sqlite3_bind_value(), or + sqlite3_bind_null() if val is null. + */ + public static int sqlite3_bind_value(@NotNull sqlite3_stmt stmt, int ndx, sqlite3_value val){ + return sqlite3_bind_value(stmt.getNativePointer(), ndx, + null==val ? 0L : val.getNativePointer()); + } + + static native int sqlite3_bind_zeroblob(@NotNull long ptrToStmt, int ndx, int n); + + public static int sqlite3_bind_zeroblob(@NotNull sqlite3_stmt stmt, int ndx, int n){ + return sqlite3_bind_zeroblob(stmt.getNativePointer(), ndx, n); + } + + static native int sqlite3_bind_zeroblob64( + @NotNull long ptrToStmt, int ndx, long n + ); + + public static int sqlite3_bind_zeroblob64(@NotNull sqlite3_stmt stmt, int ndx, long n){ + return sqlite3_bind_zeroblob64(stmt.getNativePointer(), ndx, n); + } + + static native int sqlite3_blob_bytes(@NotNull long ptrToBlob); + + public static int sqlite3_blob_bytes(@NotNull sqlite3_blob blob){ + return sqlite3_blob_bytes(blob.getNativePointer()); + } + + static native int sqlite3_blob_close(@Nullable long ptrToBlob); + + public static int sqlite3_blob_close(@Nullable sqlite3_blob blob){ + return sqlite3_blob_close(blob.clearNativePointer()); + } + + static native int sqlite3_blob_open( + @NotNull long ptrToDb, @NotNull String dbName, + @NotNull String tableName, @NotNull String columnName, + long iRow, int flags, @NotNull OutputPointer.sqlite3_blob out + ); + + public static int sqlite3_blob_open( + @NotNull sqlite3 db, @NotNull String dbName, + @NotNull String tableName, @NotNull String columnName, + long iRow, int flags, @NotNull OutputPointer.sqlite3_blob out + ){ + return sqlite3_blob_open(db.getNativePointer(), dbName, tableName, + columnName, iRow, flags, out); + } + + /** + Convenience overload. + */ + public static sqlite3_blob sqlite3_blob_open( + @NotNull sqlite3 db, @NotNull String dbName, + @NotNull String tableName, @NotNull String columnName, + long iRow, int flags ){ + final OutputPointer.sqlite3_blob out = new OutputPointer.sqlite3_blob(); + sqlite3_blob_open(db.getNativePointer(), dbName, tableName, columnName, + iRow, flags, out); + return out.take(); + }; + + static native int sqlite3_blob_read( + @NotNull long ptrToBlob, @NotNull byte[] target, int iOffset + ); + + public static int sqlite3_blob_read( + @NotNull sqlite3_blob b, @NotNull byte[] target, int iOffset + ){ + return sqlite3_blob_read(b.getNativePointer(), target, iOffset); + } + + static native int sqlite3_blob_reopen( + @NotNull long ptrToBlob, long newRowId + ); + + public static int sqlite3_blob_reopen(@NotNull sqlite3_blob b, long newRowId){ + return sqlite3_blob_reopen(b.getNativePointer(), newRowId); + } + + static native int sqlite3_blob_write( + @NotNull long ptrToBlob, @NotNull byte[] bytes, int iOffset + ); + + public static int sqlite3_blob_write( + @NotNull sqlite3_blob b, @NotNull byte[] bytes, int iOffset + ){ + return sqlite3_blob_write(b.getNativePointer(), bytes, iOffset); + } + + static native int sqlite3_busy_handler( + @NotNull long ptrToDb, @Nullable BusyHandlerCallback handler + ); + + /** + As for the C-level function of the same name, with a + BusyHandlerCallback instance in place of a callback + function. Pass it a null handler to clear the busy handler. + */ + public static int sqlite3_busy_handler( + @NotNull sqlite3 db, @Nullable BusyHandlerCallback handler + ){ + return sqlite3_busy_handler(db.getNativePointer(), handler); + } + + static native int sqlite3_busy_timeout(@NotNull long ptrToDb, int ms); + + public static int sqlite3_busy_timeout(@NotNull sqlite3 db, int ms){ + return sqlite3_busy_timeout(db.getNativePointer(), ms); + } + + public static native boolean sqlite3_cancel_auto_extension( + @NotNull AutoExtensionCallback ax + ); + + static native int sqlite3_changes(@NotNull long ptrToDb); + + public static int sqlite3_changes(@NotNull sqlite3 db){ + return sqlite3_changes(db.getNativePointer()); + } + + static native long sqlite3_changes64(@NotNull long ptrToDb); + + public static long sqlite3_changes64(@NotNull sqlite3 db){ + return sqlite3_changes64(db.getNativePointer()); + } + + static native int sqlite3_clear_bindings(@NotNull long ptrToStmt); + + public static int sqlite3_clear_bindings(@NotNull sqlite3_stmt stmt){ + return sqlite3_clear_bindings(stmt.getNativePointer()); + } + + static native int sqlite3_close(@Nullable long ptrToDb); + + public static int sqlite3_close(@Nullable sqlite3 db){ + int rc = 0; + if( null!=db ){ + rc = sqlite3_close(db.getNativePointer()); + if( 0==rc ) db.clearNativePointer(); + } + return rc; + } + + static native int sqlite3_close_v2(@Nullable long ptrToDb); + + public static int sqlite3_close_v2(@Nullable sqlite3 db){ + return db==null ? 0 : sqlite3_close_v2(db.clearNativePointer()); + } + + public static native byte[] sqlite3_column_blob( + @NotNull sqlite3_stmt stmt, int ndx + ); + + static native int sqlite3_column_bytes(@NotNull long ptrToStmt, int ndx); + + public static int sqlite3_column_bytes(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_bytes(stmt.getNativePointer(), ndx); + } + + static native int sqlite3_column_bytes16(@NotNull long ptrToStmt, int ndx); + + public static int sqlite3_column_bytes16(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_bytes16(stmt.getNativePointer(), ndx); + } + + static native int sqlite3_column_count(@NotNull long ptrToStmt); + + public static int sqlite3_column_count(@NotNull sqlite3_stmt stmt){ + return sqlite3_column_count(stmt.getNativePointer()); + } + + static native String sqlite3_column_decltype(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_decltype(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_decltype(stmt.getNativePointer(), ndx); + } + + public static native double sqlite3_column_double( + @NotNull sqlite3_stmt stmt, int ndx + ); + + public static native int sqlite3_column_int( + @NotNull sqlite3_stmt stmt, int ndx + ); + + public static native long sqlite3_column_int64( + @NotNull sqlite3_stmt stmt, int ndx + ); + + static native String sqlite3_column_name(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_name(stmt.getNativePointer(), ndx); + } + + static native String sqlite3_column_database_name(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_database_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_database_name(stmt.getNativePointer(), ndx); + } + + static native String sqlite3_column_origin_name(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_origin_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_origin_name(stmt.getNativePointer(), ndx); + } + + static native String sqlite3_column_table_name(@NotNull long ptrToStmt, int ndx); + + public static String sqlite3_column_table_name(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_table_name(stmt.getNativePointer(), ndx); + } + + /** + Functions identially to the C API, and this note is just to + stress that the returned bytes are encoded as UTF-8. It returns + null if the underlying C-level sqlite3_column_text() returns NULL + or on allocation error. + + @see #sqlite3_column_text16(sqlite3_stmt,int) + */ + public static native byte[] sqlite3_column_text( + @NotNull sqlite3_stmt stmt, int ndx + ); + + public static native String sqlite3_column_text16( + @NotNull sqlite3_stmt stmt, int ndx + ); + + // The real utility of this function is questionable. + // /** + // Returns a Java value representation based on the value of + // sqlite_value_type(). For integer types it returns either Integer + // or Long, depending on whether the value will fit in an + // Integer. For floating-point values it always returns type Double. + + // If the column was bound using sqlite3_result_java_object() then + // that value, as an Object, is returned. + // */ + // public static Object sqlite3_column_to_java(@NotNull sqlite3_stmt stmt, + // int ndx){ + // sqlite3_value v = sqlite3_column_value(stmt, ndx); + // Object rv = null; + // if(null == v) return v; + // v = sqlite3_value_dup(v)/*need a protected value*/; + // if(null == v) return v /* OOM error in C */; + // if(112/* 'p' */ == sqlite3_value_subtype(v)){ + // rv = sqlite3_value_java_object(v); + // }else{ + // switch(sqlite3_value_type(v)){ + // case SQLITE_INTEGER: { + // final long i = sqlite3_value_int64(v); + // rv = (i<=0x7fffffff && i>=-0x7fffffff-1) + // ? new Integer((int)i) : new Long(i); + // break; + // } + // case SQLITE_FLOAT: rv = new Double(sqlite3_value_double(v)); break; + // case SQLITE_BLOB: rv = sqlite3_value_blob(v); break; + // case SQLITE_TEXT: rv = sqlite3_value_text16(v); break; + // default: break; + // } + // } + // sqlite3_value_free(v); + // return rv; + // } + + static native int sqlite3_column_type(@NotNull long ptrToStmt, int ndx); + + public static int sqlite3_column_type(@NotNull sqlite3_stmt stmt, int ndx){ + return sqlite3_column_type(stmt.getNativePointer(), ndx); + } + + public static native sqlite3_value sqlite3_column_value( + @NotNull sqlite3_stmt stmt, int ndx + ); + + static native int sqlite3_collation_needed( + @NotNull long ptrToDb, @Nullable CollationNeededCallback callback + ); + + /** + This functions like C's sqlite3_collation_needed16() because + Java's string type is inherently compatible with that interface. + */ + public static int sqlite3_collation_needed( + @NotNull sqlite3 db, @Nullable CollationNeededCallback callback + ){ + return sqlite3_collation_needed(db.getNativePointer(), callback); + } + + static native CommitHookCallback sqlite3_commit_hook( + @NotNull long ptrToDb, @Nullable CommitHookCallback hook + ); + + public static CommitHookCallback sqlite3_commit_hook( + @NotNull sqlite3 db, @Nullable CommitHookCallback hook + ){ + return sqlite3_commit_hook(db.getNativePointer(), hook); + } + + public static native String sqlite3_compileoption_get(int n); + + public static native boolean sqlite3_compileoption_used(String optName); + + /** + This implementation is private because it's too easy to pass it + non-NUL-terminated byte arrays from client code. + */ + private static native int sqlite3_complete( + @NotNull byte[] nulTerminatedUtf8Sql + ); + + /** + Unlike the C API, this returns SQLITE_MISUSE if its argument is + null (as opposed to invoking UB). + */ + public static int sqlite3_complete(@NotNull String sql){ + return sqlite3_complete( nulTerminateUtf8(sql) ); + } + + + /** +

Works like in the C API with the exception that it only supports + the following subset of configution flags: + +

SQLITE_CONFIG_SINGLETHREAD + SQLITE_CONFIG_MULTITHREAD + SQLITE_CONFIG_SERIALIZED + +

Others may be added in the future. It returns SQLITE_MISUSE if + given an argument it does not handle. + +

Note that sqlite3_config() is not threadsafe with regards to + the rest of the library. This must not be called when any other + library APIs are being called. + */ + public static native int sqlite3_config(int op); + + /** + If the native library was built with SQLITE_ENABLE_SQLLOG defined + then this acts as a proxy for C's + sqlite3_config(SQLITE_ENABLE_SQLLOG,...). This sets or clears the + logger. If installation of a logger fails, any previous logger is + retained. + +

If not built with SQLITE_ENABLE_SQLLOG defined, this returns + SQLITE_MISUSE. + +

Note that sqlite3_config() is not threadsafe with regards to + the rest of the library. This must not be called when any other + library APIs are being called. + */ + public static native int sqlite3_config( @Nullable ConfigSqllogCallback logger ); + + /** + The sqlite3_config() overload for handling the SQLITE_CONFIG_LOG + option. + */ + public static native int sqlite3_config( @Nullable ConfigLogCallback logger ); + + /** + Unlike the C API, this returns null if its argument is + null (as opposed to invoking UB). + */ + public static native sqlite3 sqlite3_context_db_handle( + @NotNull sqlite3_context cx + ); + + public static native int sqlite3_create_collation( + @NotNull sqlite3 db, @NotNull String name, int eTextRep, + @NotNull CollationCallback col + ); + + /** + The Java counterpart to the C-native sqlite3_create_function(), + sqlite3_create_function_v2(), and + sqlite3_create_window_function(). Which one it behaves like + depends on which methods the final argument implements. See + SQLFunction's subclasses (ScalarFunction, AggregateFunction, + and WindowFunction) for details. + +

Unlike the C API, this returns SQLITE_MISUSE null if its db or + functionName arguments are null (as opposed to invoking UB). + */ + public static native int sqlite3_create_function( + @NotNull sqlite3 db, @NotNull String functionName, + int nArg, int eTextRep, @NotNull SQLFunction func + ); + + static native int sqlite3_data_count(@NotNull long ptrToStmt); + + public static int sqlite3_data_count(@NotNull sqlite3_stmt stmt){ + return sqlite3_data_count(stmt.getNativePointer()); + } + + /** + Overload for sqlite3_db_config() calls which take (int,int*) + variadic arguments. Returns SQLITE_MISUSE if op is not one of the + SQLITE_DBCONFIG_... options which uses this call form. + +

Unlike the C API, this returns SQLITE_MISUSE if its db argument + are null (as opposed to invoking UB). + */ + public static native int sqlite3_db_config( + @NotNull sqlite3 db, int op, int onOff, @Nullable OutputPointer.Int32 out + ); + + /** + Overload for sqlite3_db_config() calls which take a (const char*) + variadic argument. As of SQLite3 v3.43 the only such option is + SQLITE_DBCONFIG_MAINDBNAME. Returns SQLITE_MISUSE if op is not + SQLITE_DBCONFIG_MAINDBNAME, but that set of options may be + extended in future versions. + */ + public static native int sqlite3_db_config( + @NotNull sqlite3 db, int op, @NotNull String val + ); + + private static native String sqlite3_db_name(@NotNull long ptrToDb, int ndx); + + public static String sqlite3_db_name(@NotNull sqlite3 db, int ndx){ + return null==db ? null : sqlite3_db_name(db.getNativePointer(), ndx); + } + + + public static native String sqlite3_db_filename( + @NotNull sqlite3 db, @NotNull String dbName + ); + + public static native sqlite3 sqlite3_db_handle(@NotNull sqlite3_stmt stmt); + + public static native int sqlite3_db_readonly(@NotNull sqlite3 db, String dbName); + + public static native int sqlite3_db_release_memory(sqlite3 db); + + public static native int sqlite3_db_status( + @NotNull sqlite3 db, int op, @NotNull OutputPointer.Int32 pCurrent, + @NotNull OutputPointer.Int32 pHighwater, boolean reset + ); + + public static native int sqlite3_errcode(@NotNull sqlite3 db); + + public static native String sqlite3_errmsg(@NotNull sqlite3 db); + + static native int sqlite3_error_offset(@NotNull long ptrToDb); + + /** + Note that the returned byte offset values assume UTF-8-encoded + inputs, so won't always match character offsets in Java Strings. + */ + public static int sqlite3_error_offset(@NotNull sqlite3 db){ + return sqlite3_error_offset(db.getNativePointer()); + } + + public static native String sqlite3_errstr(int resultCode); + + public static native String sqlite3_expanded_sql(@NotNull sqlite3_stmt stmt); + + static native int sqlite3_extended_errcode(@NotNull long ptrToDb); + + public static int sqlite3_extended_errcode(@NotNull sqlite3 db){ + return sqlite3_extended_errcode(db.getNativePointer()); + } + + public static native boolean sqlite3_extended_result_codes( + @NotNull sqlite3 db, boolean onoff + ); + + static native boolean sqlite3_get_autocommit(@NotNull long ptrToDb); + + public static boolean sqlite3_get_autocommit(@NotNull sqlite3 db){ + return sqlite3_get_autocommit(db.getNativePointer()); + } + + public static native Object sqlite3_get_auxdata( + @NotNull sqlite3_context cx, int n + ); + + static native int sqlite3_finalize(long ptrToStmt); + + public static int sqlite3_finalize(@NotNull sqlite3_stmt stmt){ + return null==stmt ? 0 : sqlite3_finalize(stmt.clearNativePointer()); + } + + public static native int sqlite3_initialize(); + + public static native void sqlite3_interrupt(@NotNull sqlite3 db); + + public static native boolean sqlite3_is_interrupted(@NotNull sqlite3 db); + + public static native boolean sqlite3_keyword_check(@NotNull String word); + + public static native int sqlite3_keyword_count(); + + public static native String sqlite3_keyword_name(int index); + + + public static native long sqlite3_last_insert_rowid(@NotNull sqlite3 db); + + public static native String sqlite3_libversion(); + + public static native int sqlite3_libversion_number(); + + public static native int sqlite3_limit(@NotNull sqlite3 db, int id, int newVal); + + /** + Only available if built with SQLITE_ENABLE_NORMALIZE. If not, it always + returns null. + */ + public static native String sqlite3_normalized_sql(@NotNull sqlite3_stmt stmt); + + /** + Works like its C counterpart and makes the native pointer of the + underling (sqlite3*) object available via + ppDb.getNativePointer(). That pointer is necessary for looking up + the JNI-side native, but clients need not pay it any + heed. Passing the object to sqlite3_close() or sqlite3_close_v2() + will clear that pointer mapping. + +

Recall that even if opening fails, the output pointer might be + non-null. Any error message about the failure will be in that + object and it is up to the caller to sqlite3_close() that + db handle. + */ + public static native int sqlite3_open( + @Nullable String filename, @NotNull OutputPointer.sqlite3 ppDb + ); + + /** + Convenience overload which returns its db handle directly. The returned + object might not have been successfully opened: use sqlite3_errcode() to + check whether it is in an error state. + +

Ownership of the returned value is passed to the caller, who must eventually + pass it to sqlite3_close() or sqlite3_close_v2(). + */ + public static sqlite3 sqlite3_open(@Nullable String filename){ + final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); + sqlite3_open(filename, out); + return out.take(); + }; + + public static native int sqlite3_open_v2( + @Nullable String filename, @NotNull OutputPointer.sqlite3 ppDb, + int flags, @Nullable String zVfs + ); + + /** + Has the same semantics as the sqlite3-returning sqlite3_open() + but uses sqlite3_open_v2() instead of sqlite3_open(). + */ + public static sqlite3 sqlite3_open_v2(@Nullable String filename, int flags, + @Nullable String zVfs){ + final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); + sqlite3_open_v2(filename, out, flags, zVfs); + return out.take(); + }; + + /** + The sqlite3_prepare() family of functions require slightly + different signatures than their native counterparts, but (A) they + retain functionally equivalent semantics and (B) overloading + allows us to install several convenience forms. + +

All of them which take their SQL in the form of a byte[] require + that it be in UTF-8 encoding unless explicitly noted otherwise. + +

The forms which take a "tail" output pointer return (via that + output object) the index into their SQL byte array at which the + end of the first SQL statement processed by the call was + found. That's fundamentally how the C APIs work but making use of + that value requires more copying of the input SQL into + consecutively smaller arrays in order to consume all of + it. (There is an example of doing that in this project's Tester1 + class.) For that vast majority of uses, that capability is not + necessary, however, and overloads are provided which gloss over + that. + +

Results are undefined if maxBytes>sqlUtf8.length. + +

This routine is private because its maxBytes value is not + strictly necessary in the Java interface, as sqlUtf8.length tells + us the information we need. Making this public would give clients + more ways to shoot themselves in the foot without providing any + real utility. + */ + private static native int sqlite3_prepare( + @NotNull long ptrToDb, @NotNull byte[] sqlUtf8, int maxBytes, + @NotNull OutputPointer.sqlite3_stmt outStmt, + @Nullable OutputPointer.Int32 pTailOffset + ); + + /** + Works like the canonical sqlite3_prepare() but its "tail" output + argument is returned as the index offset into the given + UTF-8-encoded byte array at which SQL parsing stopped. The + semantics are otherwise identical to the C API counterpart. + +

Several overloads provided simplified call signatures. + */ + public static int sqlite3_prepare( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, + @NotNull OutputPointer.sqlite3_stmt outStmt, + @Nullable OutputPointer.Int32 pTailOffset + ){ + return sqlite3_prepare(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, pTailOffset); + } + + public static int sqlite3_prepare( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, + @NotNull OutputPointer.sqlite3_stmt outStmt + ){ + return sqlite3_prepare(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, null); + } + + public static int sqlite3_prepare( + @NotNull sqlite3 db, @NotNull String sql, + @NotNull OutputPointer.sqlite3_stmt outStmt + ){ + final byte[] utf8 = sql.getBytes(StandardCharsets.UTF_8); + return sqlite3_prepare(db.getNativePointer(), utf8, utf8.length, + outStmt, null); + } + + /** + Convenience overload which returns its statement handle directly, + or null on error or when reading only whitespace or + comments. sqlite3_errcode() can be used to determine whether + there was an error or the input was empty. Ownership of the + returned object is passed to the caller, who must eventually pass + it to sqlite3_finalize(). + */ + public static sqlite3_stmt sqlite3_prepare( + @NotNull sqlite3 db, @NotNull String sql + ){ + final OutputPointer.sqlite3_stmt out = new OutputPointer.sqlite3_stmt(); + sqlite3_prepare(db, sql, out); + return out.take(); + } + /** + @see #sqlite3_prepare + */ + private static native int sqlite3_prepare_v2( + @NotNull long ptrToDb, @NotNull byte[] sqlUtf8, int maxBytes, + @NotNull OutputPointer.sqlite3_stmt outStmt, + @Nullable OutputPointer.Int32 pTailOffset + ); + + /** + Works like the canonical sqlite3_prepare_v2() but its "tail" + output paramter is returned as the index offset into the given + byte array at which SQL parsing stopped. + */ + public static int sqlite3_prepare_v2( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, + @NotNull OutputPointer.sqlite3_stmt outStmt, + @Nullable OutputPointer.Int32 pTailOffset + ){ + return sqlite3_prepare_v2(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, pTailOffset); + } + + public static int sqlite3_prepare_v2( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, + @NotNull OutputPointer.sqlite3_stmt outStmt + ){ + return sqlite3_prepare_v2(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + outStmt, null); + } + + public static int sqlite3_prepare_v2( + @NotNull sqlite3 db, @NotNull String sql, + @NotNull OutputPointer.sqlite3_stmt outStmt + ){ + final byte[] utf8 = sql.getBytes(StandardCharsets.UTF_8); + return sqlite3_prepare_v2(db.getNativePointer(), utf8, utf8.length, + outStmt, null); + } + + /** + Works identically to the sqlite3_stmt-returning sqlite3_prepare() + but uses sqlite3_prepare_v2(). + */ + public static sqlite3_stmt sqlite3_prepare_v2( + @NotNull sqlite3 db, @NotNull String sql + ){ + final OutputPointer.sqlite3_stmt out = new OutputPointer.sqlite3_stmt(); + sqlite3_prepare_v2(db, sql, out); + return out.take(); + } + + /** + @see #sqlite3_prepare + */ + private static native int sqlite3_prepare_v3( + @NotNull long ptrToDb, @NotNull byte[] sqlUtf8, int maxBytes, + int prepFlags, @NotNull OutputPointer.sqlite3_stmt outStmt, + @Nullable OutputPointer.Int32 pTailOffset + ); + + /** + Works like the canonical sqlite3_prepare_v2() but its "tail" + output paramter is returned as the index offset into the given + byte array at which SQL parsing stopped. + */ + public static int sqlite3_prepare_v3( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int prepFlags, + @NotNull OutputPointer.sqlite3_stmt outStmt, + @Nullable OutputPointer.Int32 pTailOffset + ){ + return sqlite3_prepare_v3(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + prepFlags, outStmt, pTailOffset); + } + + /** + Convenience overload which elides the seldom-used pTailOffset + parameter. + */ + public static int sqlite3_prepare_v3( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, int prepFlags, + @NotNull OutputPointer.sqlite3_stmt outStmt + ){ + return sqlite3_prepare_v3(db.getNativePointer(), sqlUtf8, sqlUtf8.length, + prepFlags, outStmt, null); + } + + /** + Convenience overload which elides the seldom-used pTailOffset + parameter and converts the given string to UTF-8 before passing + it on. + */ + public static int sqlite3_prepare_v3( + @NotNull sqlite3 db, @NotNull String sql, int prepFlags, + @NotNull OutputPointer.sqlite3_stmt outStmt + ){ + final byte[] utf8 = sql.getBytes(StandardCharsets.UTF_8); + return sqlite3_prepare_v3(db.getNativePointer(), utf8, utf8.length, + prepFlags, outStmt, null); + } + + /** + Works identically to the sqlite3_stmt-returning sqlite3_prepare() + but uses sqlite3_prepare_v3(). + */ + public static sqlite3_stmt sqlite3_prepare_v3( + @NotNull sqlite3 db, @NotNull String sql, int prepFlags + ){ + final OutputPointer.sqlite3_stmt out = new OutputPointer.sqlite3_stmt(); + sqlite3_prepare_v3(db, sql, prepFlags, out); + return out.take(); + } + + /** + A convenience wrapper around sqlite3_prepare_v3() which accepts + an arbitrary amount of input provided as a UTF-8-encoded byte + array. It loops over the input bytes looking for + statements. Each one it finds is passed to p.call(), passing + ownership of it to that function. If p.call() returns 0, looping + continues, else the loop stops. + +

If p.call() throws, the exception is propagated. + +

How each statement is handled, including whether it is finalized + or not, is up to the callback object. e.g. the callback might + collect them for later use. If it does not collect them then it + must finalize them. See PrepareMultiCallback.Finalize for a + simple proxy which does that. + */ + public static int sqlite3_prepare_multi( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, + int preFlags, + @NotNull PrepareMultiCallback p){ + final OutputPointer.Int32 oTail = new OutputPointer.Int32(); + int pos = 0, n = 1; + byte[] sqlChunk = sqlUtf8; + int rc = 0; + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + while(0==rc && pos 0){ + sqlChunk = Arrays.copyOfRange(sqlChunk, pos, + sqlChunk.length); + } + if( 0==sqlChunk.length ) break; + rc = sqlite3_prepare_v3(db, sqlChunk, preFlags, outStmt, oTail); + if( 0!=rc ) break; + pos = oTail.value; + stmt = outStmt.take(); + if( null == stmt ){ + // empty statement was parsed. + continue; + } + rc = p.call(stmt); + } + return rc; + } + + /** + Convenience overload which accepts its SQL as a String and uses + no statement-preparation flags. + */ + public static int sqlite3_prepare_multi( + @NotNull sqlite3 db, @NotNull byte[] sqlUtf8, + @NotNull PrepareMultiCallback p){ + return sqlite3_prepare_multi(db, sqlUtf8, 0, p); + } + + /** + Convenience overload which accepts its SQL as a String. + */ + public static int sqlite3_prepare_multi( + @NotNull sqlite3 db, @NotNull String sql, int prepFlags, + @NotNull PrepareMultiCallback p){ + return sqlite3_prepare_multi( + db, sql.getBytes(StandardCharsets.UTF_8), prepFlags, p + ); + } + + /** + Convenience overload which accepts its SQL as a String and uses + no statement-preparation flags. + */ + public static int sqlite3_prepare_multi( + @NotNull sqlite3 db, @NotNull String sql, + @NotNull PrepareMultiCallback p){ + return sqlite3_prepare_multi(db, sql, 0, p); + } + + /** + Convenience overload which accepts its SQL as a String + array. They will be concatenated together as-is, with no + separator, and passed on to one of the other overloads. + */ + public static int sqlite3_prepare_multi( + @NotNull sqlite3 db, @NotNull String[] sql, int prepFlags, + @NotNull PrepareMultiCallback p){ + return sqlite3_prepare_multi(db, String.join("",sql), prepFlags, p); + } + + /** + Convenience overload which uses no statement-preparation flags. + */ + public static int sqlite3_prepare_multi( + @NotNull sqlite3 db, @NotNull String[] sql, + @NotNull PrepareMultiCallback p){ + return sqlite3_prepare_multi(db, sql, 0, p); + } + + static native int sqlite3_preupdate_blobwrite(@NotNull long ptrToDb); + + /** + If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this + acts as a proxy for C's sqlite3_preupdate_blobwrite(), else it returns + SQLITE_MISUSE with no side effects. + */ + public static int sqlite3_preupdate_blobwrite(@NotNull sqlite3 db){ + return sqlite3_preupdate_blobwrite(db.getNativePointer()); + } + + static native int sqlite3_preupdate_count(@NotNull long ptrToDb); + + /** + If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this + acts as a proxy for C's sqlite3_preupdate_count(), else it returns + SQLITE_MISUSE with no side effects. + */ + public static int sqlite3_preupdate_count(@NotNull sqlite3 db){ + return sqlite3_preupdate_count(db.getNativePointer()); + } + + static native int sqlite3_preupdate_depth(@NotNull long ptrToDb); + + /** + If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this + acts as a proxy for C's sqlite3_preupdate_depth(), else it returns + SQLITE_MISUSE with no side effects. + */ + public static int sqlite3_preupdate_depth(@NotNull sqlite3 db){ + return sqlite3_preupdate_depth(db.getNativePointer()); + } + + static native PreupdateHookCallback sqlite3_preupdate_hook( + @NotNull long ptrToDb, @Nullable PreupdateHookCallback hook + ); + + /** + If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, this + acts as a proxy for C's sqlite3_preupdate_hook(), else it returns null + with no side effects. + */ + public static PreupdateHookCallback sqlite3_preupdate_hook( + @NotNull sqlite3 db, @Nullable PreupdateHookCallback hook + ){ + return sqlite3_preupdate_hook(db.getNativePointer(), hook); + } + + static native int sqlite3_preupdate_new(@NotNull long ptrToDb, int col, + @NotNull OutputPointer.sqlite3_value out); + + /** + If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, + this acts as a proxy for C's sqlite3_preupdate_new(), else it + returns SQLITE_MISUSE with no side effects. + */ + public static int sqlite3_preupdate_new(@NotNull sqlite3 db, int col, + @NotNull OutputPointer.sqlite3_value out){ + return sqlite3_preupdate_new(db.getNativePointer(), col, out); + } + + /** + Convenience wrapper for the 3-arg sqlite3_preupdate_new() which returns + null on error. + */ + public static sqlite3_value sqlite3_preupdate_new(@NotNull sqlite3 db, int col){ + final OutputPointer.sqlite3_value out = new OutputPointer.sqlite3_value(); + sqlite3_preupdate_new(db.getNativePointer(), col, out); + return out.take(); + } + + static native int sqlite3_preupdate_old(@NotNull long ptrToDb, int col, + @NotNull OutputPointer.sqlite3_value out); + + /** + If the C API was built with SQLITE_ENABLE_PREUPDATE_HOOK defined, + this acts as a proxy for C's sqlite3_preupdate_old(), else it + returns SQLITE_MISUSE with no side effects. + */ + public static int sqlite3_preupdate_old(@NotNull sqlite3 db, int col, + @NotNull OutputPointer.sqlite3_value out){ + return sqlite3_preupdate_old(db.getNativePointer(), col, out); + } + + /** + Convenience wrapper for the 3-arg sqlite3_preupdate_old() which returns + null on error. + */ + public static sqlite3_value sqlite3_preupdate_old(@NotNull sqlite3 db, int col){ + final OutputPointer.sqlite3_value out = new OutputPointer.sqlite3_value(); + sqlite3_preupdate_old(db.getNativePointer(), col, out); + return out.take(); + } + + public static native void sqlite3_progress_handler( + @NotNull sqlite3 db, int n, @Nullable ProgressHandlerCallback h + ); + + public static native void sqlite3_randomness(byte[] target); + + public static native int sqlite3_release_memory(int n); + + public static native int sqlite3_reset(@NotNull sqlite3_stmt stmt); + + /** + Works like the C API except that it has no side effects if auto + extensions are currently running. (The JNI-level list of + extensions cannot be manipulated while it is being traversed.) + */ + public static native void sqlite3_reset_auto_extension(); + + public static native void sqlite3_result_double( + @NotNull sqlite3_context cx, double v + ); + + /** + The main sqlite3_result_error() impl of which all others are + proxies. eTextRep must be one of SQLITE_UTF8 or SQLITE_UTF16 and + msg must be encoded correspondingly. Any other eTextRep value + results in the C-level sqlite3_result_error() being called with a + complaint about the invalid argument. + */ + static native void sqlite3_result_error( + @NotNull sqlite3_context cx, @NotNull byte[] msg, int eTextRep + ); + + public static void sqlite3_result_error( + @NotNull sqlite3_context cx, @NotNull byte[] utf8 + ){ + sqlite3_result_error(cx, utf8, SQLITE_UTF8); + } + + public static void sqlite3_result_error( + @NotNull sqlite3_context cx, @NotNull String msg + ){ + final byte[] utf8 = msg.getBytes(StandardCharsets.UTF_8); + sqlite3_result_error(cx, utf8, SQLITE_UTF8); + } + + public static void sqlite3_result_error16( + @NotNull sqlite3_context cx, @NotNull byte[] utf16 + ){ + sqlite3_result_error(cx, utf16, SQLITE_UTF16); + } + + public static void sqlite3_result_error16( + @NotNull sqlite3_context cx, @NotNull String msg + ){ + final byte[] utf16 = msg.getBytes(StandardCharsets.UTF_16); + sqlite3_result_error(cx, utf16, SQLITE_UTF16); + } + + /** + Equivalent to passing e.toString() to {@link + #sqlite3_result_error(sqlite3_context,String)}. Note that + toString() is used instead of getMessage() because the former + prepends the exception type name to the message. + */ + public static void sqlite3_result_error( + @NotNull sqlite3_context cx, @NotNull Exception e + ){ + sqlite3_result_error(cx, e.toString()); + } + + public static native void sqlite3_result_error_toobig( + @NotNull sqlite3_context cx + ); + + public static native void sqlite3_result_error_nomem( + @NotNull sqlite3_context cx + ); + + public static native void sqlite3_result_error_code( + @NotNull sqlite3_context cx, int c + ); + + public static native void sqlite3_result_null( + @NotNull sqlite3_context cx + ); + + public static native void sqlite3_result_int( + @NotNull sqlite3_context cx, int v + ); + + public static native void sqlite3_result_int64( + @NotNull sqlite3_context cx, long v + ); + + /** + Binds the SQL result to the given object, or {@link + #sqlite3_result_null} if {@code o} is null. Use {@link + #sqlite3_value_java_object} to fetch it. + +

This is implemented in terms of C's sqlite3_result_pointer(), + but that function is not exposed to JNI because (A) + cross-language semantic mismatch and (B) Java doesn't need that + argument for its intended purpose (type safety). + +

Note that there is no sqlite3_column_java_object(), as the + C-level API has no sqlite3_column_pointer() to proxy. + + @see #sqlite3_value_java_object + @see #sqlite3_bind_java_object + */ + public static native void sqlite3_result_java_object( + @NotNull sqlite3_context cx, @NotNull Object o + ); + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, @NotNull Boolean v + ){ + sqlite3_result_int(cx, v ? 1 : 0); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, boolean v + ){ + sqlite3_result_int(cx, v ? 1 : 0); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, @NotNull Double v + ){ + sqlite3_result_double(cx, v); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, double v + ){ + sqlite3_result_double(cx, v); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, @NotNull Integer v + ){ + sqlite3_result_int(cx, v); + } + + public static void sqlite3_result_set(@NotNull sqlite3_context cx, int v){ + sqlite3_result_int(cx, v); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, @NotNull Long v + ){ + sqlite3_result_int64(cx, v); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, long v + ){ + sqlite3_result_int64(cx, v); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, @Nullable String v + ){ + if( null==v ) sqlite3_result_null(cx); + else sqlite3_result_text(cx, v); + } + + public static void sqlite3_result_set( + @NotNull sqlite3_context cx, @Nullable byte[] blob + ){ + if( null==blob ) sqlite3_result_null(cx); + else sqlite3_result_blob(cx, blob, blob.length); + } + + public static native void sqlite3_result_value( + @NotNull sqlite3_context cx, @NotNull sqlite3_value v + ); + + public static native void sqlite3_result_zeroblob( + @NotNull sqlite3_context cx, int n + ); + + public static native int sqlite3_result_zeroblob64( + @NotNull sqlite3_context cx, long n + ); + + /** + This overload is private because its final parameter is arguably + unnecessary in Java. + */ + private static native void sqlite3_result_blob( + @NotNull sqlite3_context cx, @Nullable byte[] blob, int maxLen + ); + + public static void sqlite3_result_blob( + @NotNull sqlite3_context cx, @Nullable byte[] blob + ){ + sqlite3_result_blob(cx, blob, (int)(null==blob ? 0 : blob.length)); + } + + /** + Binds the given text using C's sqlite3_result_blob64() unless: + +

    + +
  • @param blob is null: translates to sqlite3_result_null()
  • + +
  • @param blob is too large: translates to + sqlite3_result_error_toobig()
  • + +
+ +

If @param maxLen is larger than blob.length, it is truncated + to that value. If it is negative, results are undefined.

+ +

This overload is private because its final parameter is + arguably unnecessary in Java.

+ */ + private static native void sqlite3_result_blob64( + @NotNull sqlite3_context cx, @Nullable byte[] blob, long maxLen + ); + + public static void sqlite3_result_blob64( + @NotNull sqlite3_context cx, @Nullable byte[] blob + ){ + sqlite3_result_blob64(cx, blob, (long)(null==blob ? 0 : blob.length)); + } + + /** + This overload is private because its final parameter is + arguably unnecessary in Java. + */ + private static native void sqlite3_result_text( + @NotNull sqlite3_context cx, @Nullable byte[] utf8, int maxLen + ); + + public static void sqlite3_result_text( + @NotNull sqlite3_context cx, @Nullable byte[] utf8 + ){ + sqlite3_result_text(cx, utf8, null==utf8 ? 0 : utf8.length); + } + + public static void sqlite3_result_text( + @NotNull sqlite3_context cx, @Nullable String text + ){ + if(null == text) sqlite3_result_null(cx); + else{ + final byte[] utf8 = text.getBytes(StandardCharsets.UTF_8); + sqlite3_result_text(cx, utf8, utf8.length); + } + } + + /** + Binds the given text using C's sqlite3_result_text64() unless: + +
    + +
  • text is null: translates to a call to sqlite3_result_null()
  • + +
  • text is too large: translates to a call to + {@link #sqlite3_result_error_toobig}
  • + +
  • The @param encoding argument has an invalid value: translates to + {@link sqlite3_result_error_code} with code SQLITE_FORMAT.
  • + +
+ + If maxLength (in bytes, not characters) is larger than + text.length, it is silently truncated to text.length. If it is + negative, results are undefined. If text is null, the subsequent + arguments are ignored. + + This overload is private because its maxLength parameter is + arguably unnecessary in Java. + */ + private static native void sqlite3_result_text64( + @NotNull sqlite3_context cx, @Nullable byte[] text, + long maxLength, int encoding + ); + + /** + Sets the current UDF result to the given bytes, which are assumed + be encoded in UTF-16 using the platform's byte order. + */ + public static void sqlite3_result_text16( + @NotNull sqlite3_context cx, @Nullable byte[] utf16 + ){ + if(null == utf16) sqlite3_result_null(cx); + else sqlite3_result_text64(cx, utf16, utf16.length, SQLITE_UTF16); + } + + public static void sqlite3_result_text16( + @NotNull sqlite3_context cx, @Nullable String text + ){ + if(null == text) sqlite3_result_null(cx); + else{ + final byte[] b = text.getBytes(StandardCharsets.UTF_16); + sqlite3_result_text64(cx, b, b.length, SQLITE_UTF16); + } + } + + static native RollbackHookCallback sqlite3_rollback_hook( + @NotNull long ptrToDb, @Nullable RollbackHookCallback hook + ); + + public static RollbackHookCallback sqlite3_rollback_hook( + @NotNull sqlite3 db, @Nullable RollbackHookCallback hook + ){ + return sqlite3_rollback_hook(db.getNativePointer(), hook); + } + + public static native int sqlite3_set_authorizer( + @NotNull sqlite3 db, @Nullable AuthorizerCallback auth + ); + + public static native void sqlite3_set_auxdata( + @NotNull sqlite3_context cx, int n, @Nullable Object data + ); + + public static native void sqlite3_set_last_insert_rowid( + @NotNull sqlite3 db, long rowid + ); + + + /** + In addition to calling the C-level sqlite3_shutdown(), the JNI + binding also cleans up all stale per-thread state managed by the + library, as well as any registered auto-extensions, and frees up + various bits of memory. Calling this while database handles or + prepared statements are still active will leak resources. Trying + to use those objects after this routine is called invoked + undefined behavior. + */ + public static synchronized native int sqlite3_shutdown(); + + public static native int sqlite3_sleep(int ms); + + public static native String sqlite3_sourceid(); + + public static native String sqlite3_sql(@NotNull sqlite3_stmt stmt); + + //! Consider removing this. We can use sqlite3_status64() instead, + // or use that one's impl with this one's name. + public static native int sqlite3_status( + int op, @NotNull OutputPointer.Int32 pCurrent, + @NotNull OutputPointer.Int32 pHighwater, boolean reset + ); + + public static native int sqlite3_status64( + int op, @NotNull OutputPointer.Int64 pCurrent, + @NotNull OutputPointer.Int64 pHighwater, boolean reset + ); + + public static native int sqlite3_step(@NotNull sqlite3_stmt stmt); + + public static native boolean sqlite3_stmt_busy(@NotNull sqlite3_stmt stmt); + + static native int sqlite3_stmt_explain(@NotNull long ptrToStmt, int op); + + public static int sqlite3_stmt_explain(@NotNull sqlite3_stmt stmt, int op){ + return sqlite3_stmt_explain(stmt.getNativePointer(), op); + } + + static native int sqlite3_stmt_isexplain(@NotNull long ptrToStmt); + + public static int sqlite3_stmt_isexplain(@NotNull sqlite3_stmt stmt){ + return sqlite3_stmt_isexplain(stmt.getNativePointer()); + } + + public static native boolean sqlite3_stmt_readonly(@NotNull sqlite3_stmt stmt); + + public static native int sqlite3_stmt_status( + @NotNull sqlite3_stmt stmt, int op, boolean reset + ); + + /** + Internal impl of the public sqlite3_strglob() method. Neither + argument may be null and both must be NUL-terminated UTF-8. + + This overload is private because: (A) to keep users from + inadvertently passing non-NUL-terminated byte arrays (an easy + thing to do). (B) it is cheaper to NUL-terminate the + String-to-byte-array conversion in the Java implementation + (sqlite3_strglob(String,String)) than to do that in C, so that + signature is the public-facing one. + */ + private static native int sqlite3_strglob( + @NotNull byte[] glob, @NotNull byte[] nullTerminatedUtf8 + ); + + public static int sqlite3_strglob( + @NotNull String glob, @NotNull String txt + ){ + return sqlite3_strglob(nulTerminateUtf8(glob), + nulTerminateUtf8(txt)); + } + + /** + The LIKE counterpart of the private sqlite3_strglob() method. + */ + private static native int sqlite3_strlike( + @NotNull byte[] glob, @NotNull byte[] nullTerminatedUtf8, + int escChar + ); + + public static int sqlite3_strlike( + @NotNull String glob, @NotNull String txt, char escChar + ){ + return sqlite3_strlike(nulTerminateUtf8(glob), + nulTerminateUtf8(txt), + (int)escChar); + } + + static native int sqlite3_system_errno(@NotNull long ptrToDb); + + public static int sqlite3_system_errno(@NotNull sqlite3 db){ + return sqlite3_system_errno(db.getNativePointer()); + } + + public static native int sqlite3_table_column_metadata( + @NotNull sqlite3 db, @NotNull String zDbName, + @NotNull String zTableName, @NotNull String zColumnName, + @Nullable OutputPointer.String pzDataType, + @Nullable OutputPointer.String pzCollSeq, + @Nullable OutputPointer.Bool pNotNull, + @Nullable OutputPointer.Bool pPrimaryKey, + @Nullable OutputPointer.Bool pAutoinc + ); + + /** + Convenience overload which returns its results via a single + output object. If this function returns non-0 (error), the the + contents of the output object are not modified. + */ + public static int sqlite3_table_column_metadata( + @NotNull sqlite3 db, @NotNull String zDbName, + @NotNull String zTableName, @NotNull String zColumnName, + @NotNull TableColumnMetadata out){ + return sqlite3_table_column_metadata( + db, zDbName, zTableName, zColumnName, + out.pzDataType, out.pzCollSeq, out.pNotNull, + out.pPrimaryKey, out.pAutoinc); + } + + /** + Convenience overload which returns the column metadata object on + success and null on error. + */ + public static TableColumnMetadata sqlite3_table_column_metadata( + @NotNull sqlite3 db, @NotNull String zDbName, + @NotNull String zTableName, @NotNull String zColumnName){ + final TableColumnMetadata out = new TableColumnMetadata(); + return 0==sqlite3_table_column_metadata( + db, zDbName, zTableName, zColumnName, out + ) ? out : null; + } + + public static native int sqlite3_threadsafe(); + + static native int sqlite3_total_changes(@NotNull long ptrToDb); + + public static int sqlite3_total_changes(@NotNull sqlite3 db){ + return sqlite3_total_changes(db.getNativePointer()); + } + + static native long sqlite3_total_changes64(@NotNull long ptrToDb); + + public static long sqlite3_total_changes64(@NotNull sqlite3 db){ + return sqlite3_total_changes64(db.getNativePointer()); + } + + /** + Works like C's sqlite3_trace_v2() except that the 3rd argument to that + function is elided here because the roles of that functions' 3rd and 4th + arguments are encapsulated in the final argument to this function. + +

Unlike the C API, which is documented as always returning 0, + this implementation returns non-0 if initialization of the tracer + mapping state fails (e.g. on OOM). + */ + public static native int sqlite3_trace_v2( + @NotNull sqlite3 db, int traceMask, @Nullable TraceV2Callback tracer + ); + + public static native int sqlite3_txn_state( + @NotNull sqlite3 db, @Nullable String zSchema + ); + + static native UpdateHookCallback sqlite3_update_hook( + @NotNull long ptrToDb, @Nullable UpdateHookCallback hook + ); + + public static UpdateHookCallback sqlite3_update_hook( + @NotNull sqlite3 db, @Nullable UpdateHookCallback hook + ){ + return sqlite3_update_hook(db.getNativePointer(), hook); + } + + /* + Note that: + + void * sqlite3_user_data(sqlite3_context*) + + Is not relevant in the JNI binding, as its feature is replaced by + the ability to pass an object, including any relevant state, to + sqlite3_create_function(). + */ + + static native byte[] sqlite3_value_blob(@NotNull long ptrToValue); + + public static byte[] sqlite3_value_blob(@NotNull sqlite3_value v){ + return sqlite3_value_blob(v.getNativePointer()); + } + + static native int sqlite3_value_bytes(@NotNull long ptrToValue); + + public static int sqlite3_value_bytes(@NotNull sqlite3_value v){ + return sqlite3_value_bytes(v.getNativePointer()); + } + + static native int sqlite3_value_bytes16(@NotNull long ptrToValue); + + public static int sqlite3_value_bytes16(@NotNull sqlite3_value v){ + return sqlite3_value_bytes16(v.getNativePointer()); + } + + static native double sqlite3_value_double(@NotNull long ptrToValue); + + public static double sqlite3_value_double(@NotNull sqlite3_value v){ + return sqlite3_value_double(v.getNativePointer()); + } + + static native sqlite3_value sqlite3_value_dup(@NotNull long ptrToValue); + + public static sqlite3_value sqlite3_value_dup(@NotNull sqlite3_value v){ + return sqlite3_value_dup(v.getNativePointer()); + } + + static native int sqlite3_value_encoding(@NotNull long ptrToValue); + + public static int sqlite3_value_encoding(@NotNull sqlite3_value v){ + return sqlite3_value_encoding(v.getNativePointer()); + } + + static native void sqlite3_value_free(@Nullable long ptrToValue); + + public static void sqlite3_value_free(@Nullable sqlite3_value v){ + sqlite3_value_free(v.getNativePointer()); + } + + static native boolean sqlite3_value_frombind(@NotNull long ptrToValue); + + public static boolean sqlite3_value_frombind(@NotNull sqlite3_value v){ + return sqlite3_value_frombind(v.getNativePointer()); + } + + static native int sqlite3_value_int(@NotNull long ptrToValue); + + public static int sqlite3_value_int(@NotNull sqlite3_value v){ + return sqlite3_value_int(v.getNativePointer()); + } + + static native long sqlite3_value_int64(@NotNull long ptrToValue); + + public static long sqlite3_value_int64(@NotNull sqlite3_value v){ + return sqlite3_value_int64(v.getNativePointer()); + } + + static native Object sqlite3_value_java_object(@NotNull long ptrToValue); + + /** + If the given value was set using {@link + #sqlite3_result_java_object} then this function returns that + object, else it returns null. + +

It is up to the caller to inspect the object to determine its + type, and cast it if necessary. + */ + public static Object sqlite3_value_java_object(@NotNull sqlite3_value v){ + return sqlite3_value_java_object(v.getNativePointer()); + } + + /** + A variant of sqlite3_value_java_object() which returns the + fetched object cast to T if the object is an instance of the + given Class, else it returns null. + */ + @SuppressWarnings("unchecked") + public static T sqlite3_value_java_casted(@NotNull sqlite3_value v, + @NotNull Class type){ + final Object o = sqlite3_value_java_object(v); + return type.isInstance(o) ? (T)o : null; + } + + static native int sqlite3_value_nochange(@NotNull long ptrToValue); + + public static int sqlite3_value_nochange(@NotNull sqlite3_value v){ + return sqlite3_value_nochange(v.getNativePointer()); + } + + static native int sqlite3_value_numeric_type(@NotNull long ptrToValue); + + public static int sqlite3_value_numeric_type(@NotNull sqlite3_value v){ + return sqlite3_value_numeric_type(v.getNativePointer()); + } + + static native int sqlite3_value_subtype(@NotNull long ptrToValue); + + public static int sqlite3_value_subtype(@NotNull sqlite3_value v){ + return sqlite3_value_subtype(v.getNativePointer()); + } + + static native byte[] sqlite3_value_text(@NotNull long ptrToValue); + + /** + Functions identially to the C API, and this note is just to + stress that the returned bytes are encoded as UTF-8. It returns + null if the underlying C-level sqlite3_value_text() returns NULL + or on allocation error. + */ + public static byte[] sqlite3_value_text(@NotNull sqlite3_value v){ + return sqlite3_value_text(v.getNativePointer()); + } + + static native String sqlite3_value_text16(@NotNull long ptrToValue); + + public static String sqlite3_value_text16(@NotNull sqlite3_value v){ + return sqlite3_value_text16(v.getNativePointer()); + } + + static native int sqlite3_value_type(@NotNull long ptrToValue); + + public static int sqlite3_value_type(@NotNull sqlite3_value v){ + return sqlite3_value_type(v.getNativePointer()); + } + + /** + This is NOT part of the public API. It exists solely as a place + for this code's developers to collect internal metrics and such. + It has no stable interface. It may go way or change behavior at + any time. + */ + public static native void sqlite3_jni_internal_details(); + + ////////////////////////////////////////////////////////////////////// + // SQLITE_... constants follow... + + // version info + public static final int SQLITE_VERSION_NUMBER = sqlite3_libversion_number(); + public static final String SQLITE_VERSION = sqlite3_libversion(); + public static final String SQLITE_SOURCE_ID = sqlite3_sourceid(); + + // access + public static final int SQLITE_ACCESS_EXISTS = 0; + public static final int SQLITE_ACCESS_READWRITE = 1; + public static final int SQLITE_ACCESS_READ = 2; + + // authorizer + public static final int SQLITE_DENY = 1; + public static final int SQLITE_IGNORE = 2; + public static final int SQLITE_CREATE_INDEX = 1; + public static final int SQLITE_CREATE_TABLE = 2; + public static final int SQLITE_CREATE_TEMP_INDEX = 3; + public static final int SQLITE_CREATE_TEMP_TABLE = 4; + public static final int SQLITE_CREATE_TEMP_TRIGGER = 5; + public static final int SQLITE_CREATE_TEMP_VIEW = 6; + public static final int SQLITE_CREATE_TRIGGER = 7; + public static final int SQLITE_CREATE_VIEW = 8; + public static final int SQLITE_DELETE = 9; + public static final int SQLITE_DROP_INDEX = 10; + public static final int SQLITE_DROP_TABLE = 11; + public static final int SQLITE_DROP_TEMP_INDEX = 12; + public static final int SQLITE_DROP_TEMP_TABLE = 13; + public static final int SQLITE_DROP_TEMP_TRIGGER = 14; + public static final int SQLITE_DROP_TEMP_VIEW = 15; + public static final int SQLITE_DROP_TRIGGER = 16; + public static final int SQLITE_DROP_VIEW = 17; + public static final int SQLITE_INSERT = 18; + public static final int SQLITE_PRAGMA = 19; + public static final int SQLITE_READ = 20; + public static final int SQLITE_SELECT = 21; + public static final int SQLITE_TRANSACTION = 22; + public static final int SQLITE_UPDATE = 23; + public static final int SQLITE_ATTACH = 24; + public static final int SQLITE_DETACH = 25; + public static final int SQLITE_ALTER_TABLE = 26; + public static final int SQLITE_REINDEX = 27; + public static final int SQLITE_ANALYZE = 28; + public static final int SQLITE_CREATE_VTABLE = 29; + public static final int SQLITE_DROP_VTABLE = 30; + public static final int SQLITE_FUNCTION = 31; + public static final int SQLITE_SAVEPOINT = 32; + public static final int SQLITE_RECURSIVE = 33; + + // blob finalizers: these should, because they are treated as + // special pointer values in C, ideally have the same sizeof() as + // the platform's (void*), but we can't know that size from here. + public static final long SQLITE_STATIC = 0; + public static final long SQLITE_TRANSIENT = -1; + + // changeset + public static final int SQLITE_CHANGESETSTART_INVERT = 2; + public static final int SQLITE_CHANGESETAPPLY_NOSAVEPOINT = 1; + public static final int SQLITE_CHANGESETAPPLY_INVERT = 2; + public static final int SQLITE_CHANGESETAPPLY_IGNORENOOP = 4; + public static final int SQLITE_CHANGESET_DATA = 1; + public static final int SQLITE_CHANGESET_NOTFOUND = 2; + public static final int SQLITE_CHANGESET_CONFLICT = 3; + public static final int SQLITE_CHANGESET_CONSTRAINT = 4; + public static final int SQLITE_CHANGESET_FOREIGN_KEY = 5; + public static final int SQLITE_CHANGESET_OMIT = 0; + public static final int SQLITE_CHANGESET_REPLACE = 1; + public static final int SQLITE_CHANGESET_ABORT = 2; + + // config + public static final int SQLITE_CONFIG_SINGLETHREAD = 1; + public static final int SQLITE_CONFIG_MULTITHREAD = 2; + public static final int SQLITE_CONFIG_SERIALIZED = 3; + public static final int SQLITE_CONFIG_MALLOC = 4; + public static final int SQLITE_CONFIG_GETMALLOC = 5; + public static final int SQLITE_CONFIG_SCRATCH = 6; + public static final int SQLITE_CONFIG_PAGECACHE = 7; + public static final int SQLITE_CONFIG_HEAP = 8; + public static final int SQLITE_CONFIG_MEMSTATUS = 9; + public static final int SQLITE_CONFIG_MUTEX = 10; + public static final int SQLITE_CONFIG_GETMUTEX = 11; + public static final int SQLITE_CONFIG_LOOKASIDE = 13; + public static final int SQLITE_CONFIG_PCACHE = 14; + public static final int SQLITE_CONFIG_GETPCACHE = 15; + public static final int SQLITE_CONFIG_LOG = 16; + public static final int SQLITE_CONFIG_URI = 17; + public static final int SQLITE_CONFIG_PCACHE2 = 18; + public static final int SQLITE_CONFIG_GETPCACHE2 = 19; + public static final int SQLITE_CONFIG_COVERING_INDEX_SCAN = 20; + public static final int SQLITE_CONFIG_SQLLOG = 21; + public static final int SQLITE_CONFIG_MMAP_SIZE = 22; + public static final int SQLITE_CONFIG_WIN32_HEAPSIZE = 23; + public static final int SQLITE_CONFIG_PCACHE_HDRSZ = 24; + public static final int SQLITE_CONFIG_PMASZ = 25; + public static final int SQLITE_CONFIG_STMTJRNL_SPILL = 26; + public static final int SQLITE_CONFIG_SMALL_MALLOC = 27; + public static final int SQLITE_CONFIG_SORTERREF_SIZE = 28; + public static final int SQLITE_CONFIG_MEMDB_MAXSIZE = 29; + + // data types + public static final int SQLITE_INTEGER = 1; + public static final int SQLITE_FLOAT = 2; + public static final int SQLITE_TEXT = 3; + public static final int SQLITE_BLOB = 4; + public static final int SQLITE_NULL = 5; + + // db config + public static final int SQLITE_DBCONFIG_MAINDBNAME = 1000; + public static final int SQLITE_DBCONFIG_LOOKASIDE = 1001; + public static final int SQLITE_DBCONFIG_ENABLE_FKEY = 1002; + public static final int SQLITE_DBCONFIG_ENABLE_TRIGGER = 1003; + public static final int SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER = 1004; + public static final int SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION = 1005; + public static final int SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE = 1006; + public static final int SQLITE_DBCONFIG_ENABLE_QPSG = 1007; + public static final int SQLITE_DBCONFIG_TRIGGER_EQP = 1008; + public static final int SQLITE_DBCONFIG_RESET_DATABASE = 1009; + public static final int SQLITE_DBCONFIG_DEFENSIVE = 1010; + public static final int SQLITE_DBCONFIG_WRITABLE_SCHEMA = 1011; + public static final int SQLITE_DBCONFIG_LEGACY_ALTER_TABLE = 1012; + public static final int SQLITE_DBCONFIG_DQS_DML = 1013; + public static final int SQLITE_DBCONFIG_DQS_DDL = 1014; + public static final int SQLITE_DBCONFIG_ENABLE_VIEW = 1015; + public static final int SQLITE_DBCONFIG_LEGACY_FILE_FORMAT = 1016; + public static final int SQLITE_DBCONFIG_TRUSTED_SCHEMA = 1017; + public static final int SQLITE_DBCONFIG_STMT_SCANSTATUS = 1018; + public static final int SQLITE_DBCONFIG_REVERSE_SCANORDER = 1019; + public static final int SQLITE_DBCONFIG_MAX = 1019; + + // db status + public static final int SQLITE_DBSTATUS_LOOKASIDE_USED = 0; + public static final int SQLITE_DBSTATUS_CACHE_USED = 1; + public static final int SQLITE_DBSTATUS_SCHEMA_USED = 2; + public static final int SQLITE_DBSTATUS_STMT_USED = 3; + public static final int SQLITE_DBSTATUS_LOOKASIDE_HIT = 4; + public static final int SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE = 5; + public static final int SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL = 6; + public static final int SQLITE_DBSTATUS_CACHE_HIT = 7; + public static final int SQLITE_DBSTATUS_CACHE_MISS = 8; + public static final int SQLITE_DBSTATUS_CACHE_WRITE = 9; + public static final int SQLITE_DBSTATUS_DEFERRED_FKS = 10; + public static final int SQLITE_DBSTATUS_CACHE_USED_SHARED = 11; + public static final int SQLITE_DBSTATUS_CACHE_SPILL = 12; + public static final int SQLITE_DBSTATUS_MAX = 12; + + // encodings + public static final int SQLITE_UTF8 = 1; + public static final int SQLITE_UTF16LE = 2; + public static final int SQLITE_UTF16BE = 3; + public static final int SQLITE_UTF16 = 4; + public static final int SQLITE_UTF16_ALIGNED = 8; + + // fcntl + public static final int SQLITE_FCNTL_LOCKSTATE = 1; + public static final int SQLITE_FCNTL_GET_LOCKPROXYFILE = 2; + public static final int SQLITE_FCNTL_SET_LOCKPROXYFILE = 3; + public static final int SQLITE_FCNTL_LAST_ERRNO = 4; + public static final int SQLITE_FCNTL_SIZE_HINT = 5; + public static final int SQLITE_FCNTL_CHUNK_SIZE = 6; + public static final int SQLITE_FCNTL_FILE_POINTER = 7; + public static final int SQLITE_FCNTL_SYNC_OMITTED = 8; + public static final int SQLITE_FCNTL_WIN32_AV_RETRY = 9; + public static final int SQLITE_FCNTL_PERSIST_WAL = 10; + public static final int SQLITE_FCNTL_OVERWRITE = 11; + public static final int SQLITE_FCNTL_VFSNAME = 12; + public static final int SQLITE_FCNTL_POWERSAFE_OVERWRITE = 13; + public static final int SQLITE_FCNTL_PRAGMA = 14; + public static final int SQLITE_FCNTL_BUSYHANDLER = 15; + public static final int SQLITE_FCNTL_TEMPFILENAME = 16; + public static final int SQLITE_FCNTL_MMAP_SIZE = 18; + public static final int SQLITE_FCNTL_TRACE = 19; + public static final int SQLITE_FCNTL_HAS_MOVED = 20; + public static final int SQLITE_FCNTL_SYNC = 21; + public static final int SQLITE_FCNTL_COMMIT_PHASETWO = 22; + public static final int SQLITE_FCNTL_WIN32_SET_HANDLE = 23; + public static final int SQLITE_FCNTL_WAL_BLOCK = 24; + public static final int SQLITE_FCNTL_ZIPVFS = 25; + public static final int SQLITE_FCNTL_RBU = 26; + public static final int SQLITE_FCNTL_VFS_POINTER = 27; + public static final int SQLITE_FCNTL_JOURNAL_POINTER = 28; + public static final int SQLITE_FCNTL_WIN32_GET_HANDLE = 29; + public static final int SQLITE_FCNTL_PDB = 30; + public static final int SQLITE_FCNTL_BEGIN_ATOMIC_WRITE = 31; + public static final int SQLITE_FCNTL_COMMIT_ATOMIC_WRITE = 32; + public static final int SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE = 33; + public static final int SQLITE_FCNTL_LOCK_TIMEOUT = 34; + public static final int SQLITE_FCNTL_DATA_VERSION = 35; + public static final int SQLITE_FCNTL_SIZE_LIMIT = 36; + public static final int SQLITE_FCNTL_CKPT_DONE = 37; + public static final int SQLITE_FCNTL_RESERVE_BYTES = 38; + public static final int SQLITE_FCNTL_CKPT_START = 39; + public static final int SQLITE_FCNTL_EXTERNAL_READER = 40; + public static final int SQLITE_FCNTL_CKSM_FILE = 41; + public static final int SQLITE_FCNTL_RESET_CACHE = 42; + + // flock + public static final int SQLITE_LOCK_NONE = 0; + public static final int SQLITE_LOCK_SHARED = 1; + public static final int SQLITE_LOCK_RESERVED = 2; + public static final int SQLITE_LOCK_PENDING = 3; + public static final int SQLITE_LOCK_EXCLUSIVE = 4; + + // iocap + public static final int SQLITE_IOCAP_ATOMIC = 1; + public static final int SQLITE_IOCAP_ATOMIC512 = 2; + public static final int SQLITE_IOCAP_ATOMIC1K = 4; + public static final int SQLITE_IOCAP_ATOMIC2K = 8; + public static final int SQLITE_IOCAP_ATOMIC4K = 16; + public static final int SQLITE_IOCAP_ATOMIC8K = 32; + public static final int SQLITE_IOCAP_ATOMIC16K = 64; + public static final int SQLITE_IOCAP_ATOMIC32K = 128; + public static final int SQLITE_IOCAP_ATOMIC64K = 256; + public static final int SQLITE_IOCAP_SAFE_APPEND = 512; + public static final int SQLITE_IOCAP_SEQUENTIAL = 1024; + public static final int SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN = 2048; + public static final int SQLITE_IOCAP_POWERSAFE_OVERWRITE = 4096; + public static final int SQLITE_IOCAP_IMMUTABLE = 8192; + public static final int SQLITE_IOCAP_BATCH_ATOMIC = 16384; + + // limits + public static final int SQLITE_LIMIT_LENGTH = 0; + public static final int SQLITE_LIMIT_SQL_LENGTH = 1; + public static final int SQLITE_LIMIT_COLUMN = 2; + public static final int SQLITE_LIMIT_EXPR_DEPTH = 3; + public static final int SQLITE_LIMIT_COMPOUND_SELECT = 4; + public static final int SQLITE_LIMIT_VDBE_OP = 5; + public static final int SQLITE_LIMIT_FUNCTION_ARG = 6; + public static final int SQLITE_LIMIT_ATTACHED = 7; + public static final int SQLITE_LIMIT_LIKE_PATTERN_LENGTH = 8; + public static final int SQLITE_LIMIT_VARIABLE_NUMBER = 9; + public static final int SQLITE_LIMIT_TRIGGER_DEPTH = 10; + public static final int SQLITE_LIMIT_WORKER_THREADS = 11; + + // open flags + + public static final int SQLITE_OPEN_READONLY = 0x00000001 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_READWRITE = 0x00000002 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_CREATE = 0x00000004 /* Ok for sqlite3_open_v2() */; + //public static final int SQLITE_OPEN_DELETEONCLOSE = 0x00000008 /* VFS only */; + //public static final int SQLITE_OPEN_EXCLUSIVE = 0x00000010 /* VFS only */; + //public static final int SQLITE_OPEN_AUTOPROXY = 0x00000020 /* VFS only */; + public static final int SQLITE_OPEN_URI = 0x00000040 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_MEMORY = 0x00000080 /* Ok for sqlite3_open_v2() */; + //public static final int SQLITE_OPEN_MAIN_DB = 0x00000100 /* VFS only */; + //public static final int SQLITE_OPEN_TEMP_DB = 0x00000200 /* VFS only */; + //public static final int SQLITE_OPEN_TRANSIENT_DB = 0x00000400 /* VFS only */; + //public static final int SQLITE_OPEN_MAIN_JOURNAL = 0x00000800 /* VFS only */; + //public static final int SQLITE_OPEN_TEMP_JOURNAL = 0x00001000 /* VFS only */; + //public static final int SQLITE_OPEN_SUBJOURNAL = 0x00002000 /* VFS only */; + //public static final int SQLITE_OPEN_SUPER_JOURNAL = 0x00004000 /* VFS only */; + public static final int SQLITE_OPEN_NOMUTEX = 0x00008000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_FULLMUTEX = 0x00010000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_SHAREDCACHE = 0x00020000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_PRIVATECACHE = 0x00040000 /* Ok for sqlite3_open_v2() */; + //public static final int SQLITE_OPEN_WAL = 0x00080000 /* VFS only */; + public static final int SQLITE_OPEN_NOFOLLOW = 0x01000000 /* Ok for sqlite3_open_v2() */; + public static final int SQLITE_OPEN_EXRESCODE = 0x02000000 /* Extended result codes */; + + // prepare flags + public static final int SQLITE_PREPARE_PERSISTENT = 1; + public static final int SQLITE_PREPARE_NORMALIZE = 2; + public static final int SQLITE_PREPARE_NO_VTAB = 4; + + // result codes + public static final int SQLITE_OK = 0; + public static final int SQLITE_ERROR = 1; + public static final int SQLITE_INTERNAL = 2; + public static final int SQLITE_PERM = 3; + public static final int SQLITE_ABORT = 4; + public static final int SQLITE_BUSY = 5; + public static final int SQLITE_LOCKED = 6; + public static final int SQLITE_NOMEM = 7; + public static final int SQLITE_READONLY = 8; + public static final int SQLITE_INTERRUPT = 9; + public static final int SQLITE_IOERR = 10; + public static final int SQLITE_CORRUPT = 11; + public static final int SQLITE_NOTFOUND = 12; + public static final int SQLITE_FULL = 13; + public static final int SQLITE_CANTOPEN = 14; + public static final int SQLITE_PROTOCOL = 15; + public static final int SQLITE_EMPTY = 16; + public static final int SQLITE_SCHEMA = 17; + public static final int SQLITE_TOOBIG = 18; + public static final int SQLITE_CONSTRAINT = 19; + public static final int SQLITE_MISMATCH = 20; + public static final int SQLITE_MISUSE = 21; + public static final int SQLITE_NOLFS = 22; + public static final int SQLITE_AUTH = 23; + public static final int SQLITE_FORMAT = 24; + public static final int SQLITE_RANGE = 25; + public static final int SQLITE_NOTADB = 26; + public static final int SQLITE_NOTICE = 27; + public static final int SQLITE_WARNING = 28; + public static final int SQLITE_ROW = 100; + public static final int SQLITE_DONE = 101; + public static final int SQLITE_ERROR_MISSING_COLLSEQ = 257; + public static final int SQLITE_ERROR_RETRY = 513; + public static final int SQLITE_ERROR_SNAPSHOT = 769; + public static final int SQLITE_IOERR_READ = 266; + public static final int SQLITE_IOERR_SHORT_READ = 522; + public static final int SQLITE_IOERR_WRITE = 778; + public static final int SQLITE_IOERR_FSYNC = 1034; + public static final int SQLITE_IOERR_DIR_FSYNC = 1290; + public static final int SQLITE_IOERR_TRUNCATE = 1546; + public static final int SQLITE_IOERR_FSTAT = 1802; + public static final int SQLITE_IOERR_UNLOCK = 2058; + public static final int SQLITE_IOERR_RDLOCK = 2314; + public static final int SQLITE_IOERR_DELETE = 2570; + public static final int SQLITE_IOERR_BLOCKED = 2826; + public static final int SQLITE_IOERR_NOMEM = 3082; + public static final int SQLITE_IOERR_ACCESS = 3338; + public static final int SQLITE_IOERR_CHECKRESERVEDLOCK = 3594; + public static final int SQLITE_IOERR_LOCK = 3850; + public static final int SQLITE_IOERR_CLOSE = 4106; + public static final int SQLITE_IOERR_DIR_CLOSE = 4362; + public static final int SQLITE_IOERR_SHMOPEN = 4618; + public static final int SQLITE_IOERR_SHMSIZE = 4874; + public static final int SQLITE_IOERR_SHMLOCK = 5130; + public static final int SQLITE_IOERR_SHMMAP = 5386; + public static final int SQLITE_IOERR_SEEK = 5642; + public static final int SQLITE_IOERR_DELETE_NOENT = 5898; + public static final int SQLITE_IOERR_MMAP = 6154; + public static final int SQLITE_IOERR_GETTEMPPATH = 6410; + public static final int SQLITE_IOERR_CONVPATH = 6666; + public static final int SQLITE_IOERR_VNODE = 6922; + public static final int SQLITE_IOERR_AUTH = 7178; + public static final int SQLITE_IOERR_BEGIN_ATOMIC = 7434; + public static final int SQLITE_IOERR_COMMIT_ATOMIC = 7690; + public static final int SQLITE_IOERR_ROLLBACK_ATOMIC = 7946; + public static final int SQLITE_IOERR_DATA = 8202; + public static final int SQLITE_IOERR_CORRUPTFS = 8458; + public static final int SQLITE_LOCKED_SHAREDCACHE = 262; + public static final int SQLITE_LOCKED_VTAB = 518; + public static final int SQLITE_BUSY_RECOVERY = 261; + public static final int SQLITE_BUSY_SNAPSHOT = 517; + public static final int SQLITE_BUSY_TIMEOUT = 773; + public static final int SQLITE_CANTOPEN_NOTEMPDIR = 270; + public static final int SQLITE_CANTOPEN_ISDIR = 526; + public static final int SQLITE_CANTOPEN_FULLPATH = 782; + public static final int SQLITE_CANTOPEN_CONVPATH = 1038; + public static final int SQLITE_CANTOPEN_SYMLINK = 1550; + public static final int SQLITE_CORRUPT_VTAB = 267; + public static final int SQLITE_CORRUPT_SEQUENCE = 523; + public static final int SQLITE_CORRUPT_INDEX = 779; + public static final int SQLITE_READONLY_RECOVERY = 264; + public static final int SQLITE_READONLY_CANTLOCK = 520; + public static final int SQLITE_READONLY_ROLLBACK = 776; + public static final int SQLITE_READONLY_DBMOVED = 1032; + public static final int SQLITE_READONLY_CANTINIT = 1288; + public static final int SQLITE_READONLY_DIRECTORY = 1544; + public static final int SQLITE_ABORT_ROLLBACK = 516; + public static final int SQLITE_CONSTRAINT_CHECK = 275; + public static final int SQLITE_CONSTRAINT_COMMITHOOK = 531; + public static final int SQLITE_CONSTRAINT_FOREIGNKEY = 787; + public static final int SQLITE_CONSTRAINT_FUNCTION = 1043; + public static final int SQLITE_CONSTRAINT_NOTNULL = 1299; + public static final int SQLITE_CONSTRAINT_PRIMARYKEY = 1555; + public static final int SQLITE_CONSTRAINT_TRIGGER = 1811; + public static final int SQLITE_CONSTRAINT_UNIQUE = 2067; + public static final int SQLITE_CONSTRAINT_VTAB = 2323; + public static final int SQLITE_CONSTRAINT_ROWID = 2579; + public static final int SQLITE_CONSTRAINT_PINNED = 2835; + public static final int SQLITE_CONSTRAINT_DATATYPE = 3091; + public static final int SQLITE_NOTICE_RECOVER_WAL = 283; + public static final int SQLITE_NOTICE_RECOVER_ROLLBACK = 539; + public static final int SQLITE_WARNING_AUTOINDEX = 284; + public static final int SQLITE_AUTH_USER = 279; + public static final int SQLITE_OK_LOAD_PERMANENTLY = 256; + + // serialize + public static final int SQLITE_SERIALIZE_NOCOPY = 1; + public static final int SQLITE_DESERIALIZE_FREEONCLOSE = 1; + public static final int SQLITE_DESERIALIZE_READONLY = 4; + public static final int SQLITE_DESERIALIZE_RESIZEABLE = 2; + + // session + public static final int SQLITE_SESSION_CONFIG_STRMSIZE = 1; + public static final int SQLITE_SESSION_OBJCONFIG_SIZE = 1; + + // sqlite3 status + public static final int SQLITE_STATUS_MEMORY_USED = 0; + public static final int SQLITE_STATUS_PAGECACHE_USED = 1; + public static final int SQLITE_STATUS_PAGECACHE_OVERFLOW = 2; + public static final int SQLITE_STATUS_MALLOC_SIZE = 5; + public static final int SQLITE_STATUS_PARSER_STACK = 6; + public static final int SQLITE_STATUS_PAGECACHE_SIZE = 7; + public static final int SQLITE_STATUS_MALLOC_COUNT = 9; + + // stmt status + public static final int SQLITE_STMTSTATUS_FULLSCAN_STEP = 1; + public static final int SQLITE_STMTSTATUS_SORT = 2; + public static final int SQLITE_STMTSTATUS_AUTOINDEX = 3; + public static final int SQLITE_STMTSTATUS_VM_STEP = 4; + public static final int SQLITE_STMTSTATUS_REPREPARE = 5; + public static final int SQLITE_STMTSTATUS_RUN = 6; + public static final int SQLITE_STMTSTATUS_FILTER_MISS = 7; + public static final int SQLITE_STMTSTATUS_FILTER_HIT = 8; + public static final int SQLITE_STMTSTATUS_MEMUSED = 99; + + // sync flags + public static final int SQLITE_SYNC_NORMAL = 2; + public static final int SQLITE_SYNC_FULL = 3; + public static final int SQLITE_SYNC_DATAONLY = 16; + + // tracing flags + public static final int SQLITE_TRACE_STMT = 1; + public static final int SQLITE_TRACE_PROFILE = 2; + public static final int SQLITE_TRACE_ROW = 4; + public static final int SQLITE_TRACE_CLOSE = 8; + + // transaction state + public static final int SQLITE_TXN_NONE = 0; + public static final int SQLITE_TXN_READ = 1; + public static final int SQLITE_TXN_WRITE = 2; + + // udf flags + public static final int SQLITE_DETERMINISTIC = 0x000000800; + public static final int SQLITE_DIRECTONLY = 0x000080000; + public static final int SQLITE_INNOCUOUS = 0x000200000; + + // virtual tables + public static final int SQLITE_INDEX_SCAN_UNIQUE = 1; + public static final int SQLITE_INDEX_CONSTRAINT_EQ = 2; + public static final int SQLITE_INDEX_CONSTRAINT_GT = 4; + public static final int SQLITE_INDEX_CONSTRAINT_LE = 8; + public static final int SQLITE_INDEX_CONSTRAINT_LT = 16; + public static final int SQLITE_INDEX_CONSTRAINT_GE = 32; + public static final int SQLITE_INDEX_CONSTRAINT_MATCH = 64; + public static final int SQLITE_INDEX_CONSTRAINT_LIKE = 65; + public static final int SQLITE_INDEX_CONSTRAINT_GLOB = 66; + public static final int SQLITE_INDEX_CONSTRAINT_REGEXP = 67; + public static final int SQLITE_INDEX_CONSTRAINT_NE = 68; + public static final int SQLITE_INDEX_CONSTRAINT_ISNOT = 69; + public static final int SQLITE_INDEX_CONSTRAINT_ISNOTNULL = 70; + public static final int SQLITE_INDEX_CONSTRAINT_ISNULL = 71; + public static final int SQLITE_INDEX_CONSTRAINT_IS = 72; + public static final int SQLITE_INDEX_CONSTRAINT_LIMIT = 73; + public static final int SQLITE_INDEX_CONSTRAINT_OFFSET = 74; + public static final int SQLITE_INDEX_CONSTRAINT_FUNCTION = 150; + public static final int SQLITE_VTAB_CONSTRAINT_SUPPORT = 1; + public static final int SQLITE_VTAB_INNOCUOUS = 2; + public static final int SQLITE_VTAB_DIRECTONLY = 3; + public static final int SQLITE_VTAB_USES_ALL_SCHEMAS = 4; + public static final int SQLITE_ROLLBACK = 1; + public static final int SQLITE_FAIL = 3; + public static final int SQLITE_REPLACE = 5; + static { + // This MUST come after the SQLITE_MAX_... values or else + // attempting to modify them silently fails. + init(); + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CollationCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CollationCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CollationCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CollationCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,35 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; +import org.sqlite.jni.annotation.NotNull; + +/** + Callback for use with {@link CApi#sqlite3_create_collation}. + + @see AbstractCollationCallback +*/ +public interface CollationCallback + extends CallbackProxy, XDestroyCallback { + /** + Must compare the given byte arrays and return the result using + {@code memcmp()} semantics. + */ + int call(@NotNull byte[] lhs, @NotNull byte[] rhs); + + /** + Called by SQLite when the collation is destroyed. If a collation + requires custom cleanup, override this method. + */ + void xDestroy(); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,28 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_collation_needed}. +*/ +public interface CollationNeededCallback extends CallbackProxy { + /** + Has the same semantics as the C-level sqlite3_create_collation() + callback. + +

If it throws, the exception message is passed on to the db and + the exception is suppressed. + */ + int call(sqlite3 db, int eTextRep, String collationName); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_commit_hook}. +*/ +public interface CommitHookCallback extends CallbackProxy { + /** + Works as documented for the C-level sqlite3_commit_hook() + callback. Must not throw. + */ + int call(); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-08-23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A callback for use with sqlite3_config(). +*/ +public interface ConfigLogCallback { + /** + Must function as described for a C-level callback for + {@link CApi#sqlite3_config(ConfigLogCallback)}, with the slight signature change. + */ + void call(int errCode, String msg); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-08-23 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A callback for use with sqlite3_config(). +*/ +public interface ConfigSqllogCallback { + /** + Must function as described for a C-level callback for + {@link CApi#sqlite3_config(ConfigSqllogCallback)}, with the slight signature change. + */ + void call(sqlite3 db, String msg, int msgType ); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,46 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A helper for passing pointers between JNI C code and Java, in + particular for output pointers of high-level object types in the + sqlite3 C API, e.g. (sqlite3**) and (sqlite3_stmt**). This is + intended to be subclassed and the ContextType is intended to be the + class which is doing the subclassing. The intent of the ContextType + is strictly to provide some level of type safety by avoiding that + NativePointerHolder is not inadvertently passed to an incompatible + function signature. + + These objects do not own the pointer they refer to. They are + intended simply to communicate that pointer between C and Java. +*/ +public class NativePointerHolder { + //! Only set from JNI, where access permissions don't matter. + private volatile long nativePointer = 0; + /** + For use ONLY by package-level APIs which act as proxies for + close/finalize operations. Such ops must call this to zero out + the pointer so that this object is not carrying a stale + pointer. This function returns the prior value of the pointer and + sets it to 0. + */ + final long clearNativePointer() { + final long rv = nativePointer; + nativePointer= 0; + return rv; + } + + public final long getNativePointer(){ return nativePointer; } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/OutputPointer.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/OutputPointer.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/OutputPointer.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/OutputPointer.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,231 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Helper classes for handling JNI output pointers. + +

We do not use a generic OutputPointer because working with those + from the native JNI code is unduly quirky due to a lack of + autoboxing at that level. + +

The usage is similar for all of thes types: + +

{@code
+   OutputPointer.sqlite3 out = new OutputPointer.sqlite3();
+   assert( null==out.get() );
+   int rc = sqlite3_open(":memory:", out);
+   if( 0!=rc ) ... error;
+   assert( null!=out.get() );
+   sqlite3 db = out.take();
+   assert( null==out.get() );
+   }
+ +

With the minor exception that the primitive types permit direct + access to the object's value via the `value` property, whereas the + JNI-level opaque types do not permit client-level code to set that + property. + +

Warning: do not share instances of these classes across + threads. Doing so may lead to corrupting sqlite3-internal state. +*/ +public final class OutputPointer { + + /** + Output pointer for use with routines, such as sqlite3_open(), + which return a database handle via an output pointer. These + pointers can only be set by the JNI layer, not by client-level + code. + */ + public static final class sqlite3 { + private org.sqlite.jni.capi.sqlite3 value; + /** Initializes with a null value. */ + public sqlite3(){value = null;} + /** Sets the current value to null. */ + public void clear(){value = null;} + /** Returns the current value. */ + public final org.sqlite.jni.capi.sqlite3 get(){return value;} + /** Equivalent to calling get() then clear(). */ + public final org.sqlite.jni.capi.sqlite3 take(){ + final org.sqlite.jni.capi.sqlite3 v = value; + value = null; + return v; + } + } + + /** + Output pointer for sqlite3_blob_open(). These + pointers can only be set by the JNI layer, not by client-level + code. + */ + public static final class sqlite3_blob { + private org.sqlite.jni.capi.sqlite3_blob value; + /** Initializes with a null value. */ + public sqlite3_blob(){value = null;} + /** Sets the current value to null. */ + public void clear(){value = null;} + /** Returns the current value. */ + public final org.sqlite.jni.capi.sqlite3_blob get(){return value;} + /** Equivalent to calling get() then clear(). */ + public final org.sqlite.jni.capi.sqlite3_blob take(){ + final org.sqlite.jni.capi.sqlite3_blob v = value; + value = null; + return v; + } + } + + /** + Output pointer for use with routines, such as sqlite3_prepare(), + which return a statement handle via an output pointer. These + pointers can only be set by the JNI layer, not by client-level + code. + */ + public static final class sqlite3_stmt { + private org.sqlite.jni.capi.sqlite3_stmt value; + /** Initializes with a null value. */ + public sqlite3_stmt(){value = null;} + /** Sets the current value to null. */ + public void clear(){value = null;} + /** Returns the current value. */ + public final org.sqlite.jni.capi.sqlite3_stmt get(){return value;} + /** Equivalent to calling get() then clear(). */ + public final org.sqlite.jni.capi.sqlite3_stmt take(){ + final org.sqlite.jni.capi.sqlite3_stmt v = value; + value = null; + return v; + } + } + + /** + Output pointer for use with routines, such as sqlite3_prepupdate_new(), + which return a sqlite3_value handle via an output pointer. These + pointers can only be set by the JNI layer, not by client-level + code. + */ + public static final class sqlite3_value { + private org.sqlite.jni.capi.sqlite3_value value; + /** Initializes with a null value. */ + public sqlite3_value(){value = null;} + /** Sets the current value to null. */ + public void clear(){value = null;} + /** Returns the current value. */ + public final org.sqlite.jni.capi.sqlite3_value get(){return value;} + /** Equivalent to calling get() then clear(). */ + public final org.sqlite.jni.capi.sqlite3_value take(){ + final org.sqlite.jni.capi.sqlite3_value v = value; + value = null; + return v; + } + } + + /** + Output pointer for use with native routines which return booleans + via integer output pointers. + */ + public static final class Bool { + /** + This is public for ease of use. Accessors are provided for + consistency with the higher-level types. + */ + public boolean value; + /** Initializes with the value 0. */ + public Bool(){this(false);} + /** Initializes with the value v. */ + public Bool(boolean v){value = v;} + /** Returns the current value. */ + public final boolean get(){return value;} + /** Sets the current value to v. */ + public final void set(boolean v){value = v;} + } + + /** + Output pointer for use with native routines which return integers via + output pointers. + */ + public static final class Int32 { + /** + This is public for ease of use. Accessors are provided for + consistency with the higher-level types. + */ + public int value; + /** Initializes with the value 0. */ + public Int32(){this(0);} + /** Initializes with the value v. */ + public Int32(int v){value = v;} + /** Returns the current value. */ + public final int get(){return value;} + /** Sets the current value to v. */ + public final void set(int v){value = v;} + } + + /** + Output pointer for use with native routines which return 64-bit integers + via output pointers. + */ + public static final class Int64 { + /** + This is public for ease of use. Accessors are provided for + consistency with the higher-level types. + */ + public long value; + /** Initializes with the value 0. */ + public Int64(){this(0);} + /** Initializes with the value v. */ + public Int64(long v){value = v;} + /** Returns the current value. */ + public final long get(){return value;} + /** Sets the current value. */ + public final void set(long v){value = v;} + } + + /** + Output pointer for use with native routines which return strings via + output pointers. + */ + public static final class String { + /** + This is public for ease of use. Accessors are provided for + consistency with the higher-level types. + */ + public java.lang.String value; + /** Initializes with a null value. */ + public String(){this(null);} + /** Initializes with the value v. */ + public String(java.lang.String v){value = v;} + /** Returns the current value. */ + public final java.lang.String get(){return value;} + /** Sets the current value. */ + public final void set(java.lang.String v){value = v;} + } + + /** + Output pointer for use with native routines which return byte + arrays via output pointers. + */ + public static final class ByteArray { + /** + This is public for ease of use. Accessors are provided for + consistency with the higher-level types. + */ + public byte[] value; + /** Initializes with the value null. */ + public ByteArray(){this(null);} + /** Initializes with the value v. */ + public ByteArray(byte[] v){value = v;} + /** Returns the current value. */ + public final byte[] get(){return value;} + /** Sets the current value. */ + public final void set(byte[] v){value = v;} + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/package-info.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/package-info.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/package-info.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/package-info.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,89 @@ +/** + This package houses a JNI binding to the SQLite3 C API. + +

The primary interfaces are in {@link + org.sqlite.jni.capi.CApi}.

+ +

API Goals and Requirements

+ +
    + +
  • A 1-to-1(-ish) mapping of the C API to Java via JNI, insofar + as cross-language semantics allow for. A closely-related goal is + that the C + documentation should be usable as-is, insofar as possible, + for most of the JNI binding. As a rule, undocumented symbols in + the Java interface behave as documented for their C API + counterpart. Only semantic differences and Java-specific features + are documented here.
  • + +
  • Support Java as far back as version 8 (2014).
  • + +
  • Environment-independent. Should work everywhere both Java and + SQLite3 do.
  • + +
  • No 3rd-party dependencies beyond the JDK. That includes no + build-level dependencies for specific IDEs and toolchains. We + welcome the addition of build files for arbitrary environments + insofar as they neither interfere with each other nor become a + maintenance burden for the sqlite developers.
  • + +
+ +

Non-Goals

+ +
    + +
  • Creation of high-level OO wrapper APIs. Clients are free to + create them off of the C-style API.
  • + +
  • Support for mixed-mode operation, where client code accesses + SQLite both via the Java-side API and the C API via their own + native code. In such cases, proxy functionalities (primarily + callback handler wrappers of all sorts) may fail because the + C-side use of the SQLite APIs will bypass those proxies.
  • + +
+ +

State of this API

+ +

As of version 3.43, this software is in "tech preview" form. We + tentatively plan to stamp it as stable with the 3.44 release.

+ +

Threading Considerations

+ +

This API is, if built with SQLITE_THREADSAFE set to 1 or 2, + thread-safe, insofar as the C API guarantees, with some addenda:

+ +
    + +
  • It is not legal to use Java-facing SQLite3 resource handles + (sqlite3, sqlite3_stmt, etc) from multiple threads concurrently, + nor to use any database-specific resources concurrently in a + thread separate from the one the database is currently in use + in. i.e. do not use a sqlite3_stmt in thread #2 when thread #1 is + using the database which prepared that handle. + +
    Violating this will eventually corrupt the JNI-level bindings + between Java's and C's view of the database. This is a limitation + of the JNI bindings, not the lower-level library. +
  • + +
  • It is legal to use a given handle, and database-specific + resources, across threads, so long as no two threads pass + resources owned by the same database into the library + concurrently. +
  • + +
+ +

Any number of threads may, of course, create and use any number + of database handles they wish. Care only needs to be taken when + those handles or their associated resources cross threads, or...

+ +

When built with SQLITE_THREADSAFE=0 then no threading guarantees + are provided and multi-threaded use of the library will provoke + undefined behavior.

+ +*/ +package org.sqlite.jni.capi; diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,78 @@ +/* +** 2023-09-13 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_prepare_multi}. +*/ +public interface PrepareMultiCallback extends CallbackProxy { + + /** + Gets passed a sqlite3_stmt which it may handle in arbitrary ways, + transfering ownership of it to this function. + + sqlite3_prepare_multi() will _not_ finalize st - it is up + to the call() implementation how st is handled. + + Must return 0 on success or an SQLITE_... code on error. + + See the {@link Finalize} class for a wrapper which finalizes the + statement after calling a proxy PrepareMultiCallback. + */ + int call(sqlite3_stmt st); + + /** + A PrepareMultiCallback impl which wraps a separate impl and finalizes + any sqlite3_stmt passed to its callback. + */ + public static final class Finalize implements PrepareMultiCallback { + private PrepareMultiCallback p; + /** + p is the proxy to call() when this.call() is called. + */ + public Finalize( PrepareMultiCallback p ){ + this.p = p; + } + /** + Calls the call() method of the proxied callback and either returns its + result or propagates an exception. Either way, it passes its argument to + sqlite3_finalize() before returning. + */ + @Override public int call(sqlite3_stmt st){ + try { + return this.p.call(st); + }finally{ + CApi.sqlite3_finalize(st); + } + } + } + + /** + A PrepareMultiCallback impl which steps entirely through a result set, + ignoring all non-error results. + */ + public static final class StepAll implements PrepareMultiCallback { + public StepAll(){} + /** + Calls sqlite3_step() on st until it returns something other than + SQLITE_ROW. If the final result is SQLITE_DONE then 0 is returned, + else the result of the final step is returned. + */ + @Override public int call(sqlite3_stmt st){ + int rc = CApi.SQLITE_DONE; + while( CApi.SQLITE_ROW == (rc = CApi.sqlite3_step(st)) ){} + return CApi.SQLITE_DONE==rc ? 0 : rc; + } + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,26 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_preupdate_hook}. +*/ +public interface PreupdateHookCallback extends CallbackProxy { + /** + Must function as described for the C-level sqlite3_preupdate_hook() + callback. + */ + void call(sqlite3 db, int op, String dbName, String dbTable, + long iKey1, long iKey2 ); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,27 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_progress_handler}. +*/ +public interface ProgressHandlerCallback extends CallbackProxy { + /** + Works as documented for the C-level sqlite3_progress_handler() callback. + +

If it throws, the exception message is passed on to the db and + the exception is suppressed. + */ + int call(); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ResultCode.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ResultCode.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ResultCode.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ResultCode.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,155 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + This enum contains all of the core and "extended" result codes used + by the sqlite3 library. It is provided not for use with the C-style + API (with which it won't work) but for higher-level code which may + find it useful to map SQLite result codes to human-readable names. +*/ +public enum ResultCode { + SQLITE_OK(CApi.SQLITE_OK), + SQLITE_ERROR(CApi.SQLITE_ERROR), + SQLITE_INTERNAL(CApi.SQLITE_INTERNAL), + SQLITE_PERM(CApi.SQLITE_PERM), + SQLITE_ABORT(CApi.SQLITE_ABORT), + SQLITE_BUSY(CApi.SQLITE_BUSY), + SQLITE_LOCKED(CApi.SQLITE_LOCKED), + SQLITE_NOMEM(CApi.SQLITE_NOMEM), + SQLITE_READONLY(CApi.SQLITE_READONLY), + SQLITE_INTERRUPT(CApi.SQLITE_INTERRUPT), + SQLITE_IOERR(CApi.SQLITE_IOERR), + SQLITE_CORRUPT(CApi.SQLITE_CORRUPT), + SQLITE_NOTFOUND(CApi.SQLITE_NOTFOUND), + SQLITE_FULL(CApi.SQLITE_FULL), + SQLITE_CANTOPEN(CApi.SQLITE_CANTOPEN), + SQLITE_PROTOCOL(CApi.SQLITE_PROTOCOL), + SQLITE_EMPTY(CApi.SQLITE_EMPTY), + SQLITE_SCHEMA(CApi.SQLITE_SCHEMA), + SQLITE_TOOBIG(CApi.SQLITE_TOOBIG), + SQLITE_CONSTRAINT(CApi.SQLITE_CONSTRAINT), + SQLITE_MISMATCH(CApi.SQLITE_MISMATCH), + SQLITE_MISUSE(CApi.SQLITE_MISUSE), + SQLITE_NOLFS(CApi.SQLITE_NOLFS), + SQLITE_AUTH(CApi.SQLITE_AUTH), + SQLITE_FORMAT(CApi.SQLITE_FORMAT), + SQLITE_RANGE(CApi.SQLITE_RANGE), + SQLITE_NOTADB(CApi.SQLITE_NOTADB), + SQLITE_NOTICE(CApi.SQLITE_NOTICE), + SQLITE_WARNING(CApi.SQLITE_WARNING), + SQLITE_ROW(CApi.SQLITE_ROW), + SQLITE_DONE(CApi.SQLITE_DONE), + SQLITE_ERROR_MISSING_COLLSEQ(CApi.SQLITE_ERROR_MISSING_COLLSEQ), + SQLITE_ERROR_RETRY(CApi.SQLITE_ERROR_RETRY), + SQLITE_ERROR_SNAPSHOT(CApi.SQLITE_ERROR_SNAPSHOT), + SQLITE_IOERR_READ(CApi.SQLITE_IOERR_READ), + SQLITE_IOERR_SHORT_READ(CApi.SQLITE_IOERR_SHORT_READ), + SQLITE_IOERR_WRITE(CApi.SQLITE_IOERR_WRITE), + SQLITE_IOERR_FSYNC(CApi.SQLITE_IOERR_FSYNC), + SQLITE_IOERR_DIR_FSYNC(CApi.SQLITE_IOERR_DIR_FSYNC), + SQLITE_IOERR_TRUNCATE(CApi.SQLITE_IOERR_TRUNCATE), + SQLITE_IOERR_FSTAT(CApi.SQLITE_IOERR_FSTAT), + SQLITE_IOERR_UNLOCK(CApi.SQLITE_IOERR_UNLOCK), + SQLITE_IOERR_RDLOCK(CApi.SQLITE_IOERR_RDLOCK), + SQLITE_IOERR_DELETE(CApi.SQLITE_IOERR_DELETE), + SQLITE_IOERR_BLOCKED(CApi.SQLITE_IOERR_BLOCKED), + SQLITE_IOERR_NOMEM(CApi.SQLITE_IOERR_NOMEM), + SQLITE_IOERR_ACCESS(CApi.SQLITE_IOERR_ACCESS), + SQLITE_IOERR_CHECKRESERVEDLOCK(CApi.SQLITE_IOERR_CHECKRESERVEDLOCK), + SQLITE_IOERR_LOCK(CApi.SQLITE_IOERR_LOCK), + SQLITE_IOERR_CLOSE(CApi.SQLITE_IOERR_CLOSE), + SQLITE_IOERR_DIR_CLOSE(CApi.SQLITE_IOERR_DIR_CLOSE), + SQLITE_IOERR_SHMOPEN(CApi.SQLITE_IOERR_SHMOPEN), + SQLITE_IOERR_SHMSIZE(CApi.SQLITE_IOERR_SHMSIZE), + SQLITE_IOERR_SHMLOCK(CApi.SQLITE_IOERR_SHMLOCK), + SQLITE_IOERR_SHMMAP(CApi.SQLITE_IOERR_SHMMAP), + SQLITE_IOERR_SEEK(CApi.SQLITE_IOERR_SEEK), + SQLITE_IOERR_DELETE_NOENT(CApi.SQLITE_IOERR_DELETE_NOENT), + SQLITE_IOERR_MMAP(CApi.SQLITE_IOERR_MMAP), + SQLITE_IOERR_GETTEMPPATH(CApi.SQLITE_IOERR_GETTEMPPATH), + SQLITE_IOERR_CONVPATH(CApi.SQLITE_IOERR_CONVPATH), + SQLITE_IOERR_VNODE(CApi.SQLITE_IOERR_VNODE), + SQLITE_IOERR_AUTH(CApi.SQLITE_IOERR_AUTH), + SQLITE_IOERR_BEGIN_ATOMIC(CApi.SQLITE_IOERR_BEGIN_ATOMIC), + SQLITE_IOERR_COMMIT_ATOMIC(CApi.SQLITE_IOERR_COMMIT_ATOMIC), + SQLITE_IOERR_ROLLBACK_ATOMIC(CApi.SQLITE_IOERR_ROLLBACK_ATOMIC), + SQLITE_IOERR_DATA(CApi.SQLITE_IOERR_DATA), + SQLITE_IOERR_CORRUPTFS(CApi.SQLITE_IOERR_CORRUPTFS), + SQLITE_LOCKED_SHAREDCACHE(CApi.SQLITE_LOCKED_SHAREDCACHE), + SQLITE_LOCKED_VTAB(CApi.SQLITE_LOCKED_VTAB), + SQLITE_BUSY_RECOVERY(CApi.SQLITE_BUSY_RECOVERY), + SQLITE_BUSY_SNAPSHOT(CApi.SQLITE_BUSY_SNAPSHOT), + SQLITE_BUSY_TIMEOUT(CApi.SQLITE_BUSY_TIMEOUT), + SQLITE_CANTOPEN_NOTEMPDIR(CApi.SQLITE_CANTOPEN_NOTEMPDIR), + SQLITE_CANTOPEN_ISDIR(CApi.SQLITE_CANTOPEN_ISDIR), + SQLITE_CANTOPEN_FULLPATH(CApi.SQLITE_CANTOPEN_FULLPATH), + SQLITE_CANTOPEN_CONVPATH(CApi.SQLITE_CANTOPEN_CONVPATH), + SQLITE_CANTOPEN_SYMLINK(CApi.SQLITE_CANTOPEN_SYMLINK), + SQLITE_CORRUPT_VTAB(CApi.SQLITE_CORRUPT_VTAB), + SQLITE_CORRUPT_SEQUENCE(CApi.SQLITE_CORRUPT_SEQUENCE), + SQLITE_CORRUPT_INDEX(CApi.SQLITE_CORRUPT_INDEX), + SQLITE_READONLY_RECOVERY(CApi.SQLITE_READONLY_RECOVERY), + SQLITE_READONLY_CANTLOCK(CApi.SQLITE_READONLY_CANTLOCK), + SQLITE_READONLY_ROLLBACK(CApi.SQLITE_READONLY_ROLLBACK), + SQLITE_READONLY_DBMOVED(CApi.SQLITE_READONLY_DBMOVED), + SQLITE_READONLY_CANTINIT(CApi.SQLITE_READONLY_CANTINIT), + SQLITE_READONLY_DIRECTORY(CApi.SQLITE_READONLY_DIRECTORY), + SQLITE_ABORT_ROLLBACK(CApi.SQLITE_ABORT_ROLLBACK), + SQLITE_CONSTRAINT_CHECK(CApi.SQLITE_CONSTRAINT_CHECK), + SQLITE_CONSTRAINT_COMMITHOOK(CApi.SQLITE_CONSTRAINT_COMMITHOOK), + SQLITE_CONSTRAINT_FOREIGNKEY(CApi.SQLITE_CONSTRAINT_FOREIGNKEY), + SQLITE_CONSTRAINT_FUNCTION(CApi.SQLITE_CONSTRAINT_FUNCTION), + SQLITE_CONSTRAINT_NOTNULL(CApi.SQLITE_CONSTRAINT_NOTNULL), + SQLITE_CONSTRAINT_PRIMARYKEY(CApi.SQLITE_CONSTRAINT_PRIMARYKEY), + SQLITE_CONSTRAINT_TRIGGER(CApi.SQLITE_CONSTRAINT_TRIGGER), + SQLITE_CONSTRAINT_UNIQUE(CApi.SQLITE_CONSTRAINT_UNIQUE), + SQLITE_CONSTRAINT_VTAB(CApi.SQLITE_CONSTRAINT_VTAB), + SQLITE_CONSTRAINT_ROWID(CApi.SQLITE_CONSTRAINT_ROWID), + SQLITE_CONSTRAINT_PINNED(CApi.SQLITE_CONSTRAINT_PINNED), + SQLITE_CONSTRAINT_DATATYPE(CApi.SQLITE_CONSTRAINT_DATATYPE), + SQLITE_NOTICE_RECOVER_WAL(CApi.SQLITE_NOTICE_RECOVER_WAL), + SQLITE_NOTICE_RECOVER_ROLLBACK(CApi.SQLITE_NOTICE_RECOVER_ROLLBACK), + SQLITE_WARNING_AUTOINDEX(CApi.SQLITE_WARNING_AUTOINDEX), + SQLITE_AUTH_USER(CApi.SQLITE_AUTH_USER), + SQLITE_OK_LOAD_PERMANENTLY(CApi.SQLITE_OK_LOAD_PERMANENTLY); + + public final int value; + + ResultCode(int rc){ + value = rc; + ResultCodeMap.set(rc, this); + } + + /** + Returns the entry from this enum for the given result code, or + null if no match is found. + */ + public static ResultCode getEntryForInt(int rc){ + return ResultCodeMap.get(rc); + } + + /** + Internal level of indirection required because we cannot initialize + static enum members in an enum before the enum constructor is + invoked. + */ + private static final class ResultCodeMap { + private static final java.util.Map i2e + = new java.util.HashMap<>(); + private static void set(int rc, ResultCode e){ i2e.put(rc, e); } + private static ResultCode get(int rc){ return i2e.get(rc); } + } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_rollback_hook}. +*/ +public interface RollbackHookCallback extends CallbackProxy { + /** + Works as documented for the C-level sqlite3_rollback_hook() + callback. + */ + void call(); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,33 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + + +/** + A SQLFunction implementation for scalar functions. +*/ +public abstract class ScalarFunction implements SQLFunction { + /** + As for the xFunc() argument of the C API's + sqlite3_create_function(). If this function throws, it is + translated into an sqlite3_result_error(). + */ + public abstract void xFunc(sqlite3_context cx, sqlite3_value[] args); + + /** + Optionally override to be notified when the UDF is finalized by + SQLite. This default implementation does nothing. + */ + public void xDestroy() {} +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/SQLFunction.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/SQLFunction.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/SQLFunction.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,103 @@ +/* +** 2023-07-22 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + SQLFunction is used in conjunction with the + sqlite3_create_function() JNI-bound API to give that native code + access to the callback functions needed in order to implement SQL + functions in Java. + +

+ + This class is not used by itself, but is a marker base class. The + three UDF types are modelled by the inner classes Scalar, + Aggregate, and Window. Most simply, clients may subclass + those, or create anonymous classes from them, to implement + UDFs. Clients are free to create their own classes for use with + UDFs, so long as they conform to the public interfaces defined by + those three classes. The JNI layer only actively relies on the + SQLFunction base class and the method names and signatures used by + the UDF callback interfaces. +*/ +public interface SQLFunction { + + /** + PerContextState assists aggregate and window functions in + managing their accumulator state across calls to the UDF's + callbacks. + +

T must be of a type which can be legally stored as a value in + java.util.HashMap. + +

If a given aggregate or window function is called multiple times + in a single SQL statement, e.g. SELECT MYFUNC(A), MYFUNC(B)..., + then the clients need some way of knowing which call is which so + that they can map their state between their various UDF callbacks + and reset it via xFinal(). This class takes care of such + mappings. + +

This class works by mapping + sqlite3_context.getAggregateContext() to a single piece of + state, of a client-defined type (the T part of this class), which + persists across a "matching set" of the UDF's callbacks. + +

This class is a helper providing commonly-needed functionality + - it is not required for use with aggregate or window functions. + Client UDFs are free to perform such mappings using custom + approaches. The provided {@link AggregateFunction} and {@link + WindowFunction} classes use this. + */ + public static final class PerContextState { + private final java.util.Map> map + = new java.util.HashMap<>(); + + /** + Should be called from a UDF's xStep(), xValue(), and xInverse() + methods, passing it that method's first argument and an initial + value for the persistent state. If there is currently no + mapping for the given context within the map, one is created + using the given initial value, else the existing one is used + and the 2nd argument is ignored. It returns a ValueHolder + which can be used to modify that state directly without + requiring that the client update the underlying map's entry. + +

The caller is obligated to eventually call + takeAggregateState() to clear the mapping. + */ + public ValueHolder getAggregateState(sqlite3_context cx, T initialValue){ + final Long key = cx.getAggregateContext(true); + ValueHolder rc = null==key ? null : map.get(key); + if( null==rc ){ + map.put(key, rc = new ValueHolder<>(initialValue)); + } + return rc; + } + + /** + Should be called from a UDF's xFinal() method and passed that + method's first argument. This function removes the value + associated with cx.getAggregateContext() from the map and + returns it, returning null if no other UDF method has been + called to set up such a mapping. The latter condition will be + the case if a UDF is used in a statement which has no result + rows. + */ + public T takeAggregateState(sqlite3_context cx){ + final ValueHolder h = map.remove(cx.getAggregateContext(false)); + return null==h ? null : h.value; + } + } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,31 @@ +/* +** 2023-09-03 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A wrapper for passing C-level (sqlite3_backup*) instances around in + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java and C + via JNI. +*/ +public final class sqlite3_backup extends NativePointerHolder + implements AutoCloseable { + // Only invoked from JNI. + private sqlite3_backup(){} + + @Override public void close(){ + CApi.sqlite3_backup_finish(this); + } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,31 @@ +/* +** 2023-09-03 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A wrapper for passing C-level (sqlite3_blob*) instances around in + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java and C + via JNI. +*/ +public final class sqlite3_blob extends NativePointerHolder + implements AutoCloseable { + // Only invoked from JNI. + private sqlite3_blob(){} + + @Override public void close(){ + CApi.sqlite3_blob_close(this.clearNativePointer()); + } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,79 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + sqlite3_context instances are used in conjunction with user-defined + SQL functions (a.k.a. UDFs). +*/ +public final class sqlite3_context extends NativePointerHolder { + private Long aggregateContext = null; + + /** + getAggregateContext() corresponds to C's + sqlite3_aggregate_context(), with a slightly different interface + to account for cross-language differences. It serves the same + purposes in a slightly different way: it provides a key which is + stable across invocations of a UDF's callbacks, such that all + calls into those callbacks can determine which "set" of those + calls they belong to. + +

Note that use of this method is not a requirement for proper use + of this class. sqlite3_aggregate_context() can also be used. + +

If the argument is true and the aggregate context has not yet + been set up, it will be initialized and fetched on demand, else it + won't. The intent is that xStep(), xValue(), and xInverse() + methods pass true and xFinal() methods pass false. + +

This function treats numeric 0 as null, always returning null instead + of 0. + +

If this object is being used in the context of an aggregate or + window UDF, this function returns a non-0 value which is distinct + for each set of UDF callbacks from a single invocation of the + UDF, otherwise it returns 0. The returned value is only only + valid within the context of execution of a single SQL statement, + and must not be re-used by future invocations of the UDF in + different SQL statements. + +

Consider this SQL, where MYFUNC is a user-defined aggregate function: + +

{@code
+     SELECT MYFUNC(A), MYFUNC(B) FROM T;
+     }
+ +

The xStep() and xFinal() methods of the callback need to be able + to differentiate between those two invocations in order to + perform their work properly. The value returned by + getAggregateContext() will be distinct for each of those + invocations of MYFUNC() and is intended to be used as a lookup + key for mapping callback invocations to whatever client-defined + state is needed by the UDF. + +

There is one case where this will return null in the context + of an aggregate or window function: if the result set has no + rows, the UDF's xFinal() will be called without any other x...() + members having been called. In that one case, no aggregate + context key will have been generated. xFinal() implementations + need to be prepared to accept that condition as legal. + */ + public synchronized Long getAggregateContext(boolean initIfNeeded){ + if( aggregateContext==null ){ + aggregateContext = CApi.sqlite3_aggregate_context(this, initIfNeeded); + if( !initIfNeeded && null==aggregateContext ) aggregateContext = 0L; + } + return (null==aggregateContext || 0!=aggregateContext) ? aggregateContext : null; + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,43 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A wrapper for communicating C-level (sqlite3*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java + and C via JNI. +*/ +public final class sqlite3 extends NativePointerHolder + implements AutoCloseable { + + // Only invoked from JNI + private sqlite3(){} + + public String toString(){ + final long ptr = getNativePointer(); + if( 0==ptr ){ + return sqlite3.class.getSimpleName()+"@null"; + } + final String fn = CApi.sqlite3_db_filename(this, "main"); + return sqlite3.class.getSimpleName() + +"@"+String.format("0x%08x",ptr) + +"["+((null == fn) ? "" : fn)+"]" + ; + } + + @Override public void close(){ + CApi.sqlite3_close_v2(this.clearNativePointer()); + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,30 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A wrapper for communicating C-level (sqlite3_stmt*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java and C + via JNI. +*/ +public final class sqlite3_stmt extends NativePointerHolder + implements AutoCloseable { + // Only invoked from JNI. + private sqlite3_stmt(){} + + @Override public void close(){ + CApi.sqlite3_finalize(this.clearNativePointer()); + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,19 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +public final class sqlite3_value extends NativePointerHolder { + //! Invoked only from JNI. + private sqlite3_value(){} +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/SQLTester.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/SQLTester.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/SQLTester.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/SQLTester.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,1433 @@ +/* +** 2023-08-08 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains the main application entry pointer for the +** SQLTester framework. +*/ +package org.sqlite.jni.capi; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; +import java.nio.charset.StandardCharsets; +import java.util.regex.*; +import static org.sqlite.jni.capi.CApi.*; + +/** + Modes for how to escape (or not) column values and names from + SQLTester.execSql() to the result buffer output. +*/ +enum ResultBufferMode { + //! Do not append to result buffer + NONE, + //! Append output escaped. + ESCAPED, + //! Append output as-is + ASIS +}; + +/** + Modes to specify how to emit multi-row output from + SQLTester.execSql() to the result buffer. +*/ +enum ResultRowMode { + //! Keep all result rows on one line, space-separated. + ONELINE, + //! Add a newline between each result row. + NEWLINE +}; + +/** + Base exception type for test-related failures. +*/ +class SQLTesterException extends RuntimeException { + private boolean bFatal = false; + + SQLTesterException(String msg){ + super(msg); + } + + protected SQLTesterException(String msg, boolean fatal){ + super(msg); + bFatal = fatal; + } + + /** + Indicates whether the framework should consider this exception + type as immediately fatal to the test run or not. + */ + final boolean isFatal(){ return bFatal; } +} + +class DbException extends SQLTesterException { + DbException(sqlite3 db, int rc, boolean closeDb){ + super("DB error #"+rc+": "+sqlite3_errmsg(db),true); + if( closeDb ) sqlite3_close_v2(db); + } + DbException(sqlite3 db, int rc){ + this(db, rc, false); + } +} + +/** + Generic test-failed exception. + */ +class TestScriptFailed extends SQLTesterException { + public TestScriptFailed(TestScript ts, String msg){ + super(ts.getOutputPrefix()+": "+msg, true); + } +} + +/** + Thrown when an unknown test command is encountered in a script. +*/ +class UnknownCommand extends SQLTesterException { + public UnknownCommand(TestScript ts, String cmd){ + super(ts.getOutputPrefix()+": unknown command: "+cmd, false); + } +} + +/** + Thrown when an "incompatible directive" is found in a script. This + can be the presence of a C-preprocessor construct, specific + metadata tags within a test script's header, or specific test + constructs which are incompatible with this particular + implementation. +*/ +class IncompatibleDirective extends SQLTesterException { + public IncompatibleDirective(TestScript ts, String line){ + super(ts.getOutputPrefix()+": incompatible directive: "+line, false); + } +} + +/** + Console output utility class. +*/ +class Outer { + private int verbosity = 0; + + static void out(Object val){ + System.out.print(val); + } + + Outer out(Object... vals){ + for(Object v : vals) out(v); + return this; + } + + Outer outln(Object... vals){ + out(vals).out("\n"); + return this; + } + + Outer verbose(Object... vals){ + if(verbosity>0){ + out("VERBOSE",(verbosity>1 ? "+: " : ": ")).outln(vals); + } + return this; + } + + void setVerbosity(int level){ + verbosity = level; + } + + int getVerbosity(){ + return verbosity; + } + + public boolean isVerbose(){return verbosity > 0;} + +} + +/** +

This class provides an application which aims to implement the + rudimentary SQL-driven test tool described in the accompanying + {@code test-script-interpreter.md}. + +

This class is an internal testing tool, not part of the public + interface but is (A) in the same package as the library because + access permissions require it to be so and (B) the JDK8 javadoc + offers no way to filter individual classes out of the doc + generation process (it can only exclude packages, but see (A)). + +

An instance of this application provides a core set of services + which TestScript instances use for processing testing logic. + TestScripts, in turn, delegate the concrete test work to Command + objects, which the TestScript parses on their behalf. +*/ +public class SQLTester { + //! List of input script files. + private final java.util.List listInFiles = new ArrayList<>(); + //! Console output utility. + private final Outer outer = new Outer(); + //! Test input buffer. + private final StringBuilder inputBuffer = new StringBuilder(); + //! Test result buffer. + private final StringBuilder resultBuffer = new StringBuilder(); + //! Buffer for REQUIRED_PROPERTIES pragmas. + private final StringBuilder dbInitSql = new StringBuilder(); + //! Output representation of SQL NULL. + private String nullView = "nil"; + //! Total tests run. + private int nTotalTest = 0; + //! Total test script files run. + private int nTestFile = 0; + //! Number of scripts which were aborted. + private int nAbortedScript = 0; + //! Incremented by test case handlers + private int nTest = 0; + //! True to enable column name output from execSql() + private boolean emitColNames; + //! True to keep going regardless of how a test fails. + private boolean keepGoing = false; + //! The list of available db handles. + private final sqlite3[] aDb = new sqlite3[7]; + //! Index into aDb of the current db. + private int iCurrentDb = 0; + //! Name of the default db, re-created for each script. + private final String initialDbName = "test.db"; + + + public SQLTester(){ + reset(); + } + + void setVerbosity(int level){ + this.outer.setVerbosity( level ); + } + int getVerbosity(){ + return this.outer.getVerbosity(); + } + boolean isVerbose(){ + return this.outer.isVerbose(); + } + + void outputColumnNames(boolean b){ emitColNames = b; } + + void verbose(Object... vals){ + outer.verbose(vals); + } + + void outln(Object... vals){ + outer.outln(vals); + } + + void out(Object... vals){ + outer.out(vals); + } + + //! Adds the given test script to the to-test list. + public void addTestScript(String filename){ + listInFiles.add(filename); + //verbose("Added file ",filename); + } + + private void setupInitialDb() throws DbException { + if( null==aDb[0] ){ + Util.unlink(initialDbName); + openDb(0, initialDbName, true); + }else{ + outln("WARNING: setupInitialDb() unexpectedly ", + "triggered while it is opened."); + } + } + + static final String[] startEmoji = { + "🚴", "🏄", "🏇", "🤸", "⛹", "🏊", "⛷", "🧗", "🏋" + }; + static final int nStartEmoji = startEmoji.length; + static int iStartEmoji = 0; + + private static String nextStartEmoji(){ + return startEmoji[iStartEmoji++ % nStartEmoji]; + } + + public void runTests() throws Exception { + final long tStart = System.currentTimeMillis(); + for(String f : listInFiles){ + reset(); + ++nTestFile; + final TestScript ts = new TestScript(f); + outln(nextStartEmoji(), " starting [",f,"]"); + boolean threw = false; + final long timeStart = System.currentTimeMillis(); + try{ + ts.run(this); + }catch(SQLTesterException e){ + threw = true; + outln("🔥EXCEPTION: ",e.getClass().getSimpleName(),": ",e.getMessage()); + ++nAbortedScript; + if( keepGoing ) outln("Continuing anyway becaure of the keep-going option."); + else if( e.isFatal() ) throw e; + }finally{ + final long timeEnd = System.currentTimeMillis(); + outln("🏁",(threw ? "❌" : "✅")," ",nTest," test(s) in ", + (timeEnd-timeStart),"ms."); + } + } + final long tEnd = System.currentTimeMillis(); + outln("Total run-time: ",(tEnd-tStart),"ms"); + Util.unlink(initialDbName); + } + + private StringBuilder clearBuffer(StringBuilder b){ + b.setLength(0);; + return b; + } + + StringBuilder clearInputBuffer(){ + return clearBuffer(inputBuffer); + } + + StringBuilder clearResultBuffer(){ + return clearBuffer(resultBuffer); + } + + StringBuilder getInputBuffer(){ return inputBuffer; } + + void appendInput(String n, boolean addNL){ + inputBuffer.append(n); + if(addNL) inputBuffer.append('\n'); + } + + void appendResult(String n, boolean addNL){ + resultBuffer.append(n); + if(addNL) resultBuffer.append('\n'); + } + + void appendDbInitSql(String n) throws DbException { + dbInitSql.append(n).append('\n'); + if( null!=getCurrentDb() ){ + //outln("RUNNING DB INIT CODE: ",n); + execSql(null, true, ResultBufferMode.NONE, null, n); + } + } + String getDbInitSql(){ return dbInitSql.toString(); } + + String getInputText(){ return inputBuffer.toString(); } + + String getResultText(){ return resultBuffer.toString(); } + + private String takeBuffer(StringBuilder b){ + final String rc = b.toString(); + clearBuffer(b); + return rc; + } + + String takeInputBuffer(){ return takeBuffer(inputBuffer); } + + String takeResultBuffer(){ return takeBuffer(resultBuffer); } + + int getCurrentDbId(){ return iCurrentDb; } + + SQLTester affirmDbId(int n) throws IndexOutOfBoundsException { + if(n<0 || n>=aDb.length){ + throw new IndexOutOfBoundsException("illegal db number: "+n); + } + return this; + } + + sqlite3 setCurrentDb(int n) throws Exception{ + affirmDbId(n); + iCurrentDb = n; + return this.aDb[n]; + } + + sqlite3 getCurrentDb(){ return aDb[iCurrentDb]; } + + sqlite3 getDbById(int id) throws Exception{ + return affirmDbId(id).aDb[id]; + } + + void closeDb(int id) { + final sqlite3 db = affirmDbId(id).aDb[id]; + if( null != db ){ + sqlite3_close_v2(db); + aDb[id] = null; + } + } + + void closeDb() { closeDb(iCurrentDb); } + + void closeAllDbs(){ + for(int i = 0; i 0){ + //outln("RUNNING DB INIT CODE: ",dbInitSql.toString()); + rc = execSql(db, false, ResultBufferMode.NONE, + null, dbInitSql.toString()); + } + if( 0!=rc ){ + throw new DbException(db, rc, true); + } + return aDb[iCurrentDb] = db; + } + + sqlite3 openDb(int slot, String name, boolean createIfNeeded) throws DbException { + affirmDbId(slot); + iCurrentDb = slot; + return openDb(name, createIfNeeded); + } + + /** + Resets all tester context state except for that related to + tracking running totals. + */ + void reset(){ + clearInputBuffer(); + clearResultBuffer(); + clearBuffer(dbInitSql); + closeAllDbs(); + nTest = 0; + nullView = "nil"; + emitColNames = false; + iCurrentDb = 0; + //dbInitSql.append("SELECT 1;"); + } + + void setNullValue(String v){nullView = v;} + + /** + If true, encountering an unknown command in a script causes the + remainder of the script to be skipped, rather than aborting the + whole script run. + */ + boolean skipUnknownCommands(){ + // Currently hard-coded. Potentially a flag someday. + return true; + } + + void incrementTestCounter(){ ++nTest; ++nTotalTest; } + + //! "Special" characters - we have to escape output if it contains any. + static final Pattern patternSpecial = Pattern.compile( + "[\\x00-\\x20\\x22\\x5c\\x7b\\x7d]" + ); + //! Either of '{' or '}'. + static final Pattern patternSquiggly = Pattern.compile("[{}]"); + + /** + Returns v or some escaped form of v, as defined in the tester's + spec doc. + */ + String escapeSqlValue(String v){ + if( "".equals(v) ) return "{}"; + Matcher m = patternSpecial.matcher(v); + if( !m.find() ){ + return v /* no escaping needed */; + } + m = patternSquiggly.matcher(v); + if( !m.find() ){ + return "{"+v+"}"; + } + final StringBuilder sb = new StringBuilder("\""); + final int n = v.length(); + for(int i = 0; i < n; ++i){ + final char ch = v.charAt(i); + switch(ch){ + case '\\': sb.append("\\\\"); break; + case '"': sb.append("\\\""); break; + default: + //verbose("CHAR ",(int)ch," ",ch," octal=",String.format("\\%03o", (int)ch)); + if( (int)ch < 32 ) sb.append(String.format("\\%03o", (int)ch)); + else sb.append(ch); + break; + } + } + sb.append("\""); + return sb.toString(); + } + + private void appendDbErr(sqlite3 db, StringBuilder sb, int rc){ + sb.append(org.sqlite.jni.capi.ResultCode.getEntryForInt(rc)).append(' '); + final String msg = escapeSqlValue(sqlite3_errmsg(db)); + if( '{' == msg.charAt(0) ){ + sb.append(msg); + }else{ + sb.append('{').append(msg).append('}'); + } + } + + /** + Runs SQL on behalf of test commands and outputs the results following + the very specific rules of the test framework. + + If db is null, getCurrentDb() is assumed. If throwOnError is true then + any db-side error will result in an exception, else they result in + the db's result code. + + appendMode specifies how/whether to append results to the result + buffer. rowMode specifies whether to output all results in a + single line or one line per row. If appendMode is + ResultBufferMode.NONE then rowMode is ignored and may be null. + */ + public int execSql(sqlite3 db, boolean throwOnError, + ResultBufferMode appendMode, ResultRowMode rowMode, + String sql) throws SQLTesterException { + if( null==db && null==aDb[0] ){ + // Delay opening of the initial db to enable tests to change its + // name and inject on-connect code via, e.g., the MEMDB + // directive. this setup as the potential to misinteract with + // auto-extension timing and must be done carefully. + setupInitialDb(); + } + final OutputPointer.Int32 oTail = new OutputPointer.Int32(); + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + final byte[] sqlUtf8 = sql.getBytes(StandardCharsets.UTF_8); + if( null==db ) db = getCurrentDb(); + int pos = 0, n = 1; + byte[] sqlChunk = sqlUtf8; + int rc = 0; + sqlite3_stmt stmt = null; + int spacing = 0 /* emit a space for --result if>0 */ ; + final StringBuilder sb = (ResultBufferMode.NONE==appendMode) + ? null : resultBuffer; + //outln("sqlChunk len= = ",sqlChunk.length); + try{ + while(pos < sqlChunk.length){ + if(pos > 0){ + sqlChunk = Arrays.copyOfRange(sqlChunk, pos, + sqlChunk.length); + } + if( 0==sqlChunk.length ) break; + rc = sqlite3_prepare_v2(db, sqlChunk, outStmt, oTail); + /*outln("PREPARE rc ",rc," oTail=",oTail.get(),": ", + new String(sqlChunk,StandardCharsets.UTF_8),"\n");*/ + if( 0!=rc ){ + if(throwOnError){ + throw new DbException(db, rc); + }else if( null!=sb ){ + appendDbErr(db, sb, rc); + } + break; + } + pos = oTail.value; + stmt = outStmt.take(); + if( null == stmt ){ + // empty statement was parsed. + continue; + } + if( null!=sb ){ + // Add the output to the result buffer... + final int nCol = sqlite3_column_count(stmt); + String colName = null, val = null; + while( SQLITE_ROW == (rc = sqlite3_step(stmt)) ){ + for(int i = 0; i < nCol; ++i){ + if( spacing++ > 0 ) sb.append(' '); + if( emitColNames ){ + colName = sqlite3_column_name(stmt, i); + switch(appendMode){ + case ASIS: + sb.append( colName ); + break; + case ESCAPED: + sb.append( escapeSqlValue(colName) ); + break; + default: + throw new SQLTesterException("Unhandled ResultBufferMode: "+appendMode); + } + sb.append(' '); + } + val = sqlite3_column_text16(stmt, i); + if( null==val ){ + sb.append( nullView ); + continue; + } + switch(appendMode){ + case ASIS: + sb.append( val ); + break; + case ESCAPED: + sb.append( escapeSqlValue(val) ); + break; + default: + throw new SQLTesterException("Unhandled ResultBufferMode: "+appendMode); + } + } + if( ResultRowMode.NEWLINE == rowMode ){ + spacing = 0; + sb.append('\n'); + } + } + }else{ + while( SQLITE_ROW == (rc = sqlite3_step(stmt)) ){} + } + sqlite3_finalize(stmt); + stmt = null; + if(SQLITE_ROW==rc || SQLITE_DONE==rc) rc = 0; + else if( rc!=0 ){ + if( null!=sb ){ + appendDbErr(db, sb, rc); + } + break; + } + } + }finally{ + sqlite3_reset(stmt + /* In order to trigger an exception in the + INSERT...RETURNING locking scenario: + https://sqlite.org/forum/forumpost/36f7a2e7494897df */); + sqlite3_finalize(stmt); + } + if( 0!=rc && throwOnError ){ + throw new DbException(db, rc); + } + return rc; + } + + public static void main(String[] argv) throws Exception{ + installCustomExtensions(); + boolean dumpInternals = false; + final SQLTester t = new SQLTester(); + for(String a : argv){ + if(a.startsWith("-")){ + final String flag = a.replaceFirst("-+",""); + if( flag.equals("verbose") ){ + // Use --verbose up to 3 times + t.setVerbosity(t.getVerbosity() + 1); + }else if( flag.equals("keep-going") ){ + t.keepGoing = true; + }else if( flag.equals("internals") ){ + dumpInternals = true; + }else{ + throw new IllegalArgumentException("Unhandled flag: "+flag); + } + continue; + } + t.addTestScript(a); + } + final AutoExtensionCallback ax = new AutoExtensionCallback() { + private final SQLTester tester = t; + @Override public int call(sqlite3 db){ + final String init = tester.getDbInitSql(); + if( !init.isEmpty() ){ + tester.execSql(db, true, ResultBufferMode.NONE, null, init); + } + return 0; + } + }; + sqlite3_auto_extension(ax); + try { + t.runTests(); + }finally{ + sqlite3_cancel_auto_extension(ax); + t.outln("Processed ",t.nTotalTest," test(s) in ",t.nTestFile," file(s)."); + if( t.nAbortedScript > 0 ){ + t.outln("Aborted ",t.nAbortedScript," script(s)."); + } + if( dumpInternals ){ + sqlite3_jni_internal_details(); + } + } + } + + /** + Internal impl of the public strglob() method. Neither argument + may be NULL and both _MUST_ be NUL-terminated. + */ + private static native int strglob(byte[] glob, byte[] txt); + + /** + Works essentially the same as sqlite3_strglob() except that the + glob character '#' matches a sequence of one or more digits. It + does not match when it appears at the start or middle of a series + of digits, e.g. "#23" or "1#3", but will match at the end, + e.g. "12#". + */ + static int strglob(String glob, String txt){ + return strglob( + (glob+"\0").getBytes(StandardCharsets.UTF_8), + (txt+"\0").getBytes(StandardCharsets.UTF_8) + ); + } + + /** + Sets up C-side components needed by the test framework. This must + not be called until main() is triggered so that it does not + interfere with library clients who don't use this class. + */ + static native void installCustomExtensions(); + static { + System.loadLibrary("sqlite3-jni") + /* Interestingly, when SQLTester is the main app, we have to + load that lib from here. The same load from CApi does + not happen early enough. Without this, + installCustomExtensions() is an unresolved symbol. */; + } + +} + +/** + General utilities for the SQLTester bits. +*/ +final class Util { + + //! Throws a new T, appending all msg args into a string for the message. + static void toss(Class errorType, Object... msg) throws Exception { + StringBuilder sb = new StringBuilder(); + for(Object s : msg) sb.append(s); + final java.lang.reflect.Constructor ctor = + errorType.getConstructor(String.class); + throw ctor.newInstance(sb.toString()); + } + + static void toss(Object... msg) throws Exception{ + toss(RuntimeException.class, msg); + } + + //! Tries to delete the given file, silently ignoring failure. + static void unlink(String filename){ + try{ + final java.io.File f = new java.io.File(filename); + f.delete(); + }catch(Exception e){ + /* ignore */ + } + } + + /** + Appends all entries in argv[1..end] into a space-separated + string, argv[0] is not included because it's expected to be a + command name. + */ + static String argvToString(String[] argv){ + StringBuilder sb = new StringBuilder(); + for(int i = 1; i < argv.length; ++i ){ + if( i>1 ) sb.append(" "); + sb.append( argv[i] ); + } + return sb.toString(); + } + +} + +/** + Base class for test script commands. It provides a set of utility + APIs for concrete command implementations. + + Each subclass must have a public no-arg ctor and must implement + the process() method which is abstract in this class. + + Commands are intended to be stateless, except perhaps for counters + and similar internals. Specifically, no state which changes the + behavior between any two invocations of process() should be + retained. +*/ +abstract class Command { + protected Command(){} + + /** + Must process one command-unit of work and either return + (on success) or throw (on error). + + The first two arguments specify the context of the test. The TestScript + provides the content of the test and the SQLTester providers the sandbox + in which that script is being evaluated. + + argv is a list with the command name followed by any arguments to + that command. The argcCheck() method from this class provides + very basic argc validation. + */ + public abstract void process( + SQLTester st, TestScript ts, String[] argv + ) throws Exception; + + /** + If argv.length-1 (-1 because the command's name is in argv[0]) does not + fall in the inclusive range (min,max) then this function throws. Use + a max value of -1 to mean unlimited. + */ + protected final void argcCheck(TestScript ts, String[] argv, int min, int max) throws Exception{ + int argc = argv.length-1; + if(argc=0 && argc>max)){ + if( min==max ){ + ts.toss(argv[0]," requires exactly ",min," argument(s)"); + }else if(max>0){ + ts.toss(argv[0]," requires ",min,"-",max," arguments."); + }else{ + ts.toss(argv[0]," requires at least ",min," arguments."); + } + } + } + + /** + Equivalent to argcCheck(argv,argc,argc). + */ + protected final void argcCheck(TestScript ts, String[] argv, int argc) throws Exception{ + argcCheck(ts, argv, argc, argc); + } +} + +//! --close command +class CloseDbCommand extends Command { + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,0,1); + Integer id; + if(argv.length>1){ + String arg = argv[1]; + if("all".equals(arg)){ + t.closeAllDbs(); + return; + } + else{ + id = Integer.parseInt(arg); + } + }else{ + id = t.getCurrentDbId(); + } + t.closeDb(id); + } +} + +//! --column-names command +class ColumnNamesCommand extends Command { + public void process( + SQLTester st, TestScript ts, String[] argv + ) throws Exception{ + argcCheck(ts,argv,1); + st.outputColumnNames( Integer.parseInt(argv[1])!=0 ); + } +} + +//! --db command +class DbCommand extends Command { + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,1); + t.setCurrentDb( Integer.parseInt(argv[1]) ); + } +} + +//! --glob command +class GlobCommand extends Command { + private boolean negate = false; + public GlobCommand(){} + protected GlobCommand(boolean negate){ this.negate = negate; } + + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,1,-1); + t.incrementTestCounter(); + final String sql = t.takeInputBuffer(); + int rc = t.execSql(null, true, ResultBufferMode.ESCAPED, + ResultRowMode.ONELINE, sql); + final String result = t.getResultText(); + final String sArgs = Util.argvToString(argv); + //t2.verbose2(argv[0]," rc = ",rc," result buffer:\n", result,"\nargs:\n",sArgs); + final String glob = Util.argvToString(argv); + rc = SQLTester.strglob(glob, result); + if( (negate && 0==rc) || (!negate && 0!=rc) ){ + ts.toss(argv[0], " mismatch: ", glob," vs input: ",result); + } + } +} + +//! --json command +class JsonCommand extends ResultCommand { + public JsonCommand(){ super(ResultBufferMode.ASIS); } +} + +//! --json-block command +class JsonBlockCommand extends TableResultCommand { + public JsonBlockCommand(){ super(true); } +} + +//! --new command +class NewDbCommand extends OpenDbCommand { + public NewDbCommand(){ super(true); } +} + +//! Placeholder dummy/no-op commands +class NoopCommand extends Command { + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + } +} + +//! --notglob command +class NotGlobCommand extends GlobCommand { + public NotGlobCommand(){ + super(true); + } +} + +//! --null command +class NullCommand extends Command { + public void process( + SQLTester st, TestScript ts, String[] argv + ) throws Exception{ + argcCheck(ts,argv,1); + st.setNullValue( argv[1] ); + } +} + +//! --open command +class OpenDbCommand extends Command { + private boolean createIfNeeded = false; + public OpenDbCommand(){} + protected OpenDbCommand(boolean c){createIfNeeded = c;} + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,1); + t.openDb(argv[1], createIfNeeded); + } +} + +//! --print command +class PrintCommand extends Command { + public void process( + SQLTester st, TestScript ts, String[] argv + ) throws Exception{ + st.out(ts.getOutputPrefix(),": "); + if( 1==argv.length ){ + st.out( st.getInputText() ); + }else{ + st.outln( Util.argvToString(argv) ); + } + } +} + +//! --result command +class ResultCommand extends Command { + private final ResultBufferMode bufferMode; + protected ResultCommand(ResultBufferMode bm){ bufferMode = bm; } + public ResultCommand(){ this(ResultBufferMode.ESCAPED); } + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,0,-1); + t.incrementTestCounter(); + final String sql = t.takeInputBuffer(); + //ts.verbose2(argv[0]," SQL =\n",sql); + int rc = t.execSql(null, false, bufferMode, ResultRowMode.ONELINE, sql); + final String result = t.getResultText().trim(); + final String sArgs = argv.length>1 ? Util.argvToString(argv) : ""; + if( !result.equals(sArgs) ){ + t.outln(argv[0]," FAILED comparison. Result buffer:\n", + result,"\nExpected result:\n",sArgs); + ts.toss(argv[0]+" comparison failed."); + } + } +} + +//! --run command +class RunCommand extends Command { + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,0,1); + final sqlite3 db = (1==argv.length) + ? t.getCurrentDb() : t.getDbById( Integer.parseInt(argv[1]) ); + final String sql = t.takeInputBuffer(); + final int rc = t.execSql(db, false, ResultBufferMode.NONE, + ResultRowMode.ONELINE, sql); + if( 0!=rc && t.isVerbose() ){ + String msg = sqlite3_errmsg(db); + ts.verbose1(argv[0]," non-fatal command error #",rc,": ", + msg,"\nfor SQL:\n",sql); + } + } +} + +//! --tableresult command +class TableResultCommand extends Command { + private final boolean jsonMode; + protected TableResultCommand(boolean jsonMode){ this.jsonMode = jsonMode; } + public TableResultCommand(){ this(false); } + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,0); + t.incrementTestCounter(); + String body = ts.fetchCommandBody(t); + if( null==body ) ts.toss("Missing ",argv[0]," body."); + body = body.trim(); + if( !body.endsWith("\n--end") ){ + ts.toss(argv[0], " must be terminated with --end."); + }else{ + body = body.substring(0, body.length()-6); + } + final String[] globs = body.split("\\s*\\n\\s*"); + if( globs.length < 1 ){ + ts.toss(argv[0], " requires 1 or more ", + (jsonMode ? "json snippets" : "globs"),"."); + } + final String sql = t.takeInputBuffer(); + t.execSql(null, true, + jsonMode ? ResultBufferMode.ASIS : ResultBufferMode.ESCAPED, + ResultRowMode.NEWLINE, sql); + final String rbuf = t.getResultText(); + final String[] res = rbuf.split("\n"); + if( res.length != globs.length ){ + ts.toss(argv[0], " failure: input has ", res.length, + " row(s) but expecting ",globs.length); + } + for(int i = 0; i < res.length; ++i){ + final String glob = globs[i].replaceAll("\\s+"," ").trim(); + //ts.verbose2(argv[0]," <<",glob,">> vs <<",res[i],">>"); + if( jsonMode ){ + if( !glob.equals(res[i]) ){ + ts.toss(argv[0], " json <<",glob, ">> does not match: <<", + res[i],">>"); + } + }else if( 0 != SQLTester.strglob(glob, res[i]) ){ + ts.toss(argv[0], " glob <<",glob,">> does not match: <<",res[i],">>"); + } + } + } +} + +//! --testcase command +class TestCaseCommand extends Command { + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,1); + ts.setTestCaseName(argv[1]); + t.clearResultBuffer(); + t.clearInputBuffer(); + } +} + +//! --verbosity command +class VerbosityCommand extends Command { + public void process(SQLTester t, TestScript ts, String[] argv) throws Exception{ + argcCheck(ts,argv,1); + ts.setVerbosity( Integer.parseInt(argv[1]) ); + } +} + +class CommandDispatcher { + + private static java.util.Map commandMap = + new java.util.HashMap<>(); + + /** + Returns a (cached) instance mapped to name, or null if no match + is found. + */ + static Command getCommandByName(String name){ + Command rv = commandMap.get(name); + if( null!=rv ) return rv; + switch(name){ + case "close": rv = new CloseDbCommand(); break; + case "column-names": rv = new ColumnNamesCommand(); break; + case "db": rv = new DbCommand(); break; + case "glob": rv = new GlobCommand(); break; + case "json": rv = new JsonCommand(); break; + case "json-block": rv = new JsonBlockCommand(); break; + case "new": rv = new NewDbCommand(); break; + case "notglob": rv = new NotGlobCommand(); break; + case "null": rv = new NullCommand(); break; + case "oom": rv = new NoopCommand(); break; + case "open": rv = new OpenDbCommand(); break; + case "print": rv = new PrintCommand(); break; + case "result": rv = new ResultCommand(); break; + case "run": rv = new RunCommand(); break; + case "tableresult": rv = new TableResultCommand(); break; + case "testcase": rv = new TestCaseCommand(); break; + case "verbosity": rv = new VerbosityCommand(); break; + default: rv = null; break; + } + if( null!=rv ) commandMap.put(name, rv); + return rv; + } + + /** + Treats argv[0] as a command name, looks it up with + getCommandByName(), and calls process() on that instance, passing + it arguments given to this function. + */ + static void dispatch(SQLTester tester, TestScript ts, String[] argv) throws Exception{ + final Command cmd = getCommandByName(argv[0]); + if(null == cmd){ + throw new UnknownCommand(ts, argv[0]); + } + cmd.process(tester, ts, argv); + } +} + + +/** + This class represents a single test script. It handles (or + delegates) its the reading-in and parsing, but the details of + evaluation are delegated elsewhere. +*/ +class TestScript { + //! input file + private String filename = null; + //! Name pulled from the SCRIPT_MODULE_NAME directive of the file + private String moduleName = null; + //! Current test case name. + private String testCaseName = null; + //! Content buffer state. + private final Cursor cur = new Cursor(); + //! Utility for console output. + private final Outer outer = new Outer(); + + //! File content and parse state. + private static final class Cursor { + private final StringBuilder sb = new StringBuilder(); + byte[] src = null; + //! Current position in this.src. + int pos = 0; + //! Current line number. Starts at 0 for internal reasons and will + // line up with 1-based reality once parsing starts. + int lineNo = 0 /* yes, zero */; + //! Putback value for this.pos. + int putbackPos = 0; + //! Putback line number + int putbackLineNo = 0; + //! Peeked-to pos, used by peekLine() and consumePeeked(). + int peekedPos = 0; + //! Peeked-to line number. + int peekedLineNo = 0; + + //! Restore parsing state to the start of the stream. + void rewind(){ + sb.setLength(0); + pos = lineNo = putbackPos = putbackLineNo = peekedPos = peekedLineNo = 0 + /* kinda missing memset() about now. */; + } + } + + private byte[] readFile(String filename) throws Exception { + return java.nio.file.Files.readAllBytes(java.nio.file.Paths.get(filename)); + } + + /** + Initializes the script with the content of the given file. + Throws if it cannot read the file. + */ + public TestScript(String filename) throws Exception{ + this.filename = filename; + setVerbosity(2); + cur.src = readFile(filename); + } + + public String getFilename(){ + return filename; + } + + public String getModuleName(){ + return moduleName; + } + + /** + Verbosity level 0 produces no debug/verbose output. Level 1 produces + some and level 2 produces more. + */ + public void setVerbosity(int level){ + outer.setVerbosity(level); + } + + public String getOutputPrefix(){ + String rc = "["+(moduleName==null ? "" : moduleName)+"]"; + if( null!=testCaseName ) rc += "["+testCaseName+"]"; + if( null!=filename ) rc += "["+filename+"]"; + return rc + " line "+ cur.lineNo; + } + + static final String[] verboseLabel = {"🔈",/*"🔉",*/"🔊","📢"}; + //! Output vals only if level<=current verbosity level. + private TestScript verboseN(int level, Object... vals){ + final int verbosity = outer.getVerbosity(); + if(verbosity>=level){ + outer.out( verboseLabel[level-1], getOutputPrefix(), " ",level,": " + ).outln(vals); + } + return this; + } + + TestScript verbose1(Object... vals){return verboseN(1,vals);} + TestScript verbose2(Object... vals){return verboseN(2,vals);} + TestScript verbose3(Object... vals){return verboseN(3,vals);} + + private void reset(){ + testCaseName = null; + cur.rewind(); + } + + void setTestCaseName(String n){ testCaseName = n; } + + /** + Returns the next line from the buffer, minus the trailing EOL. + + Returns null when all input is consumed. Throws if it reads + illegally-encoded input, e.g. (non-)characters in the range + 128-256. + */ + String getLine(){ + if( cur.pos==cur.src.length ){ + return null /* EOF */; + } + cur.putbackPos = cur.pos; + cur.putbackLineNo = cur.lineNo; + cur.sb.setLength(0); + final boolean skipLeadingWs = false; + byte b = 0, prevB = 0; + int i = cur.pos; + if(skipLeadingWs) { + /* Skip any leading spaces, including newlines. This will eliminate + blank lines. */ + for(; i < cur.src.length; ++i, prevB=b){ + b = cur.src[i]; + switch((int)b){ + case 32/*space*/: case 9/*tab*/: case 13/*CR*/: continue; + case 10/*NL*/: ++cur.lineNo; continue; + default: break; + } + break; + } + if( i==cur.src.length ){ + return null /* EOF */; + } + } + boolean doBreak = false; + final byte[] aChar = {0,0,0,0} /* multi-byte char buffer */; + int nChar = 0 /* number of bytes in the char */; + for(; i < cur.src.length && !doBreak; ++i){ + b = cur.src[i]; + switch( (int)b ){ + case 13/*CR*/: continue; + case 10/*NL*/: + ++cur.lineNo; + if(cur.sb.length()>0) doBreak = true; + // Else it's an empty string + break; + default: + /* Multi-byte chars need to be gathered up and appended at + one time. Appending individual bytes to the StringBuffer + appends their integer value. */ + nChar = 1; + switch( b & 0xF0 ){ + case 0xC0: nChar = 2; break; + case 0xE0: nChar = 3; break; + case 0xF0: nChar = 4; break; + default: + if( b > 127 ) this.toss("Invalid character (#"+(int)b+")."); + break; + } + if( 1==nChar ){ + cur.sb.append((char)b); + }else{ + for(int x = 0; x < nChar; ++x) aChar[x] = cur.src[i+x]; + cur.sb.append(new String(Arrays.copyOf(aChar, nChar), + StandardCharsets.UTF_8)); + i += nChar-1; + } + break; + } + } + cur.pos = i; + final String rv = cur.sb.toString(); + if( i==cur.src.length && 0==rv.length() ){ + return null /* EOF */; + } + return rv; + }/*getLine()*/ + + /** + Fetches the next line then resets the cursor to its pre-call + state. consumePeeked() can be used to consume this peeked line + without having to re-parse it. + */ + String peekLine(){ + final int oldPos = cur.pos; + final int oldPB = cur.putbackPos; + final int oldPBL = cur.putbackLineNo; + final int oldLine = cur.lineNo; + try{ return getLine(); } + finally{ + cur.peekedPos = cur.pos; + cur.peekedLineNo = cur.lineNo; + cur.pos = oldPos; + cur.lineNo = oldLine; + cur.putbackPos = oldPB; + cur.putbackLineNo = oldPBL; + } + } + + /** + Only valid after calling peekLine() and before calling getLine(). + This places the cursor to the position it would have been at had + the peekLine() had been fetched with getLine(). + */ + void consumePeeked(){ + cur.pos = cur.peekedPos; + cur.lineNo = cur.peekedLineNo; + } + + /** + Restores the cursor to the position it had before the previous + call to getLine(). + */ + void putbackLine(){ + cur.pos = cur.putbackPos; + cur.lineNo = cur.putbackLineNo; + } + + private boolean checkRequiredProperties(SQLTester t, String[] props) throws SQLTesterException{ + if( true ) return false; + int nOk = 0; + for(String rp : props){ + verbose1("REQUIRED_PROPERTIES: ",rp); + switch(rp){ + case "RECURSIVE_TRIGGERS": + t.appendDbInitSql("pragma recursive_triggers=on;"); + ++nOk; + break; + case "TEMPSTORE_FILE": + /* This _assumes_ that the lib is built with SQLITE_TEMP_STORE=1 or 2, + which we just happen to know is the case */ + t.appendDbInitSql("pragma temp_store=1;"); + ++nOk; + break; + case "TEMPSTORE_MEM": + /* This _assumes_ that the lib is built with SQLITE_TEMP_STORE=1 or 2, + which we just happen to know is the case */ + t.appendDbInitSql("pragma temp_store=0;"); + ++nOk; + break; + case "AUTOVACUUM": + t.appendDbInitSql("pragma auto_vacuum=full;"); + ++nOk; + case "INCRVACUUM": + t.appendDbInitSql("pragma auto_vacuum=incremental;"); + ++nOk; + default: + break; + } + } + return props.length == nOk; + } + + private static final Pattern patternRequiredProperties = + Pattern.compile(" REQUIRED_PROPERTIES:[ \\t]*(\\S.*)\\s*$"); + private static final Pattern patternScriptModuleName = + Pattern.compile(" SCRIPT_MODULE_NAME:[ \\t]*(\\S+)\\s*$"); + private static final Pattern patternMixedModuleName = + Pattern.compile(" ((MIXED_)?MODULE_NAME):[ \\t]*(\\S+)\\s*$"); + private static final Pattern patternCommand = + Pattern.compile("^--(([a-z-]+)( .*)?)$"); + + /** + Looks for "directives." If a compatible one is found, it is + processed and this function returns. If an incompatible one is found, + a description of it is returned and processing of the test must + end immediately. + */ + private void checkForDirective( + SQLTester tester, String line + ) throws IncompatibleDirective { + if(line.startsWith("#")){ + throw new IncompatibleDirective(this, "C-preprocessor input: "+line); + }else if(line.startsWith("---")){ + new IncompatibleDirective(this, "triple-dash: "+line); + } + Matcher m = patternScriptModuleName.matcher(line); + if( m.find() ){ + moduleName = m.group(1); + return; + } + m = patternRequiredProperties.matcher(line); + if( m.find() ){ + final String rp = m.group(1); + if( ! checkRequiredProperties( tester, rp.split("\\s+") ) ){ + throw new IncompatibleDirective(this, "REQUIRED_PROPERTIES: "+rp); + } + } + m = patternMixedModuleName.matcher(line); + if( m.find() ){ + throw new IncompatibleDirective(this, m.group(1)+": "+m.group(3)); + } + if( line.indexOf("\n|")>=0 ){ + throw new IncompatibleDirective(this, "newline-pipe combination."); + } + return; + } + + boolean isCommandLine(String line, boolean checkForImpl){ + final Matcher m = patternCommand.matcher(line); + boolean rc = m.find(); + if( rc && checkForImpl ){ + rc = null!=CommandDispatcher.getCommandByName(m.group(2)); + } + return rc; + } + + /** + If line looks like a command, returns an argv for that command + invocation, else returns null. + */ + String[] getCommandArgv(String line){ + final Matcher m = patternCommand.matcher(line); + return m.find() ? m.group(1).trim().split("\\s+") : null; + } + + /** + Fetches lines until the next recognized command. Throws if + checkForDirective() does. Returns null if there is no input or + it's only whitespace. The returned string retains all whitespace. + + Note that "subcommands", --command-like constructs in the body + which do not match a known command name are considered to be + content, not commands. + */ + String fetchCommandBody(SQLTester tester){ + final StringBuilder sb = new StringBuilder(); + String line; + while( (null != (line = peekLine())) ){ + checkForDirective(tester, line); + if( isCommandLine(line, true) ) break; + else { + sb.append(line).append("\n"); + consumePeeked(); + } + } + line = sb.toString(); + return line.trim().isEmpty() ? null : line; + } + + private void processCommand(SQLTester t, String[] argv) throws Exception{ + verbose1("running command: ",argv[0], " ", Util.argvToString(argv)); + if(outer.getVerbosity()>1){ + final String input = t.getInputText(); + if( !input.isEmpty() ) verbose3("Input buffer = ",input); + } + CommandDispatcher.dispatch(t, this, argv); + } + + void toss(Object... msg) throws TestScriptFailed { + StringBuilder sb = new StringBuilder(); + for(Object s : msg) sb.append(s); + throw new TestScriptFailed(this, sb.toString()); + } + + /** + Runs this test script in the context of the given tester object. + */ + public boolean run(SQLTester tester) throws Exception { + reset(); + setVerbosity(tester.getVerbosity()); + String line, directive; + String[] argv; + while( null != (line = getLine()) ){ + verbose3("input line: ",line); + checkForDirective(tester, line); + argv = getCommandArgv(line); + if( null!=argv ){ + processCommand(tester, argv); + continue; + } + tester.appendInput(line,true); + } + return true; + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,35 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + A wrapper object for use with sqlite3_table_column_metadata(). + They are populated only via that interface. +*/ +public final class TableColumnMetadata { + OutputPointer.Bool pNotNull = new OutputPointer.Bool(); + OutputPointer.Bool pPrimaryKey = new OutputPointer.Bool(); + OutputPointer.Bool pAutoinc = new OutputPointer.Bool(); + OutputPointer.String pzCollSeq = new OutputPointer.String(); + OutputPointer.String pzDataType = new OutputPointer.String(); + + public TableColumnMetadata(){ + } + + public String getDataType(){ return pzDataType.value; } + public String getCollation(){ return pzCollSeq.value; } + public boolean isNotNull(){ return pNotNull.value; } + public boolean isPrimaryKey(){ return pPrimaryKey.value; } + public boolean isAutoincrement(){ return pAutoinc.value; } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/Tester1.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/Tester1.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/Tester1.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/Tester1.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,1976 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.capi; +import static org.sqlite.jni.capi.CApi.*; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import java.util.concurrent.Future; + +/** + An annotation for Tester1 tests which we do not want to run in + reflection-driven test mode because either they are not suitable + for multi-threaded threaded mode or we have to control their execution + order. +*/ +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) +@interface ManualTest{} +/** + Annotation for Tester1 tests which mark those which must be skipped + in multi-threaded mode. +*/ +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) +@interface SingleThreadOnly{} + +public class Tester1 implements Runnable { + //! True when running in multi-threaded mode. + private static boolean mtMode = false; + //! True to sleep briefly between tests. + private static boolean takeNaps = false; + //! True to shuffle the order of the tests. + private static boolean shuffle = false; + //! True to dump the list of to-run tests to stdout. + private static boolean listRunTests = false; + //! True to squelch all out() and outln() output. + private static boolean quietMode = false; + //! Total number of runTests() calls. + private static int nTestRuns = 0; + //! List of test*() methods to run. + private static List testMethods = null; + //! List of exceptions collected by run() + private static List listErrors = new ArrayList<>(); + private static final class Metrics { + //! Number of times createNewDb() (or equivalent) is invoked. + volatile int dbOpen = 0; + } + + private Integer tId; + + Tester1(Integer id){ + tId = id; + } + + static final Metrics metrics = new Metrics(); + + public static synchronized void outln(){ + if( !quietMode ){ + System.out.println(""); + } + } + + public static synchronized void outPrefix(){ + if( !quietMode ){ + System.out.print(Thread.currentThread().getName()+": "); + } + } + + public static synchronized void outln(Object val){ + if( !quietMode ){ + outPrefix(); + System.out.println(val); + } + } + + public static synchronized void out(Object val){ + if( !quietMode ){ + System.out.print(val); + } + } + + @SuppressWarnings("unchecked") + public static synchronized void out(Object... vals){ + if( !quietMode ){ + outPrefix(); + for(Object v : vals) out(v); + } + } + + @SuppressWarnings("unchecked") + public static synchronized void outln(Object... vals){ + if( !quietMode ){ + out(vals); out("\n"); + } + } + + static volatile int affirmCount = 0; + public static synchronized int affirm(Boolean v, String comment){ + ++affirmCount; + if( false ) assert( v /* prefer assert over exception if it's enabled because + the JNI layer sometimes has to suppress exceptions, + so they might be squelched on their way back to the + top. */); + if( !v ) throw new RuntimeException(comment); + return affirmCount; + } + + public static void affirm(Boolean v){ + affirm(v, "Affirmation failed."); + } + + @SingleThreadOnly /* because it's thread-agnostic */ + private void test1(){ + affirm(sqlite3_libversion_number() == SQLITE_VERSION_NUMBER); + } + + public static sqlite3 createNewDb(){ + final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); + int rc = sqlite3_open(":memory:", out); + ++metrics.dbOpen; + sqlite3 db = out.take(); + if( 0!=rc ){ + final String msg = + null==db ? sqlite3_errstr(rc) : sqlite3_errmsg(db); + sqlite3_close(db); + throw new RuntimeException("Opening db failed: "+msg); + } + affirm( null == out.get() ); + affirm( 0 != db.getNativePointer() ); + rc = sqlite3_busy_timeout(db, 2000); + affirm( 0 == rc ); + return db; + } + + public static void execSql(sqlite3 db, String[] sql){ + execSql(db, String.join("", sql)); + } + + public static int execSql(sqlite3 db, boolean throwOnError, String sql){ + OutputPointer.Int32 oTail = new OutputPointer.Int32(); + final byte[] sqlUtf8 = sql.getBytes(StandardCharsets.UTF_8); + int pos = 0, n = 1; + byte[] sqlChunk = sqlUtf8; + int rc = 0; + sqlite3_stmt stmt = null; + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + while(pos < sqlChunk.length){ + if(pos > 0){ + sqlChunk = Arrays.copyOfRange(sqlChunk, pos, + sqlChunk.length); + } + if( 0==sqlChunk.length ) break; + rc = sqlite3_prepare_v2(db, sqlChunk, outStmt, oTail); + if(throwOnError) affirm(0 == rc); + else if( 0!=rc ) break; + pos = oTail.value; + stmt = outStmt.take(); + if( null == stmt ){ + // empty statement was parsed. + continue; + } + affirm(0 != stmt.getNativePointer()); + while( SQLITE_ROW == (rc = sqlite3_step(stmt)) ){ + } + sqlite3_finalize(stmt); + affirm(0 == stmt.getNativePointer()); + if(0!=rc && SQLITE_ROW!=rc && SQLITE_DONE!=rc){ + break; + } + } + sqlite3_finalize(stmt); + if(SQLITE_ROW==rc || SQLITE_DONE==rc) rc = 0; + if( 0!=rc && throwOnError){ + throw new RuntimeException("db op failed with rc=" + +rc+": "+sqlite3_errmsg(db)); + } + return rc; + } + + public static void execSql(sqlite3 db, String sql){ + execSql(db, true, sql); + } + + public static sqlite3_stmt prepare(sqlite3 db, boolean throwOnError, String sql){ + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + int rc = sqlite3_prepare_v2(db, sql, outStmt); + if( throwOnError ){ + affirm( 0 == rc ); + } + final sqlite3_stmt rv = outStmt.take(); + affirm( null == outStmt.get() ); + if( throwOnError ){ + affirm( 0 != rv.getNativePointer() ); + } + return rv; + } + + public static sqlite3_stmt prepare(sqlite3 db, String sql){ + return prepare(db, true, sql); + } + + private void showCompileOption(){ + int i = 0; + String optName; + outln("compile options:"); + for( ; null != (optName = sqlite3_compileoption_get(i)); ++i){ + outln("\t"+optName+"\t (used="+ + sqlite3_compileoption_used(optName)+")"); + } + } + + private void testCompileOption(){ + int i = 0; + String optName; + for( ; null != (optName = sqlite3_compileoption_get(i)); ++i){ + } + affirm( i > 10 ); + affirm( null==sqlite3_compileoption_get(-1) ); + } + + private void testOpenDb1(){ + final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); + int rc = sqlite3_open(":memory:", out); + ++metrics.dbOpen; + sqlite3 db = out.get(); + affirm(0 == rc); + affirm(db.getNativePointer()!=0); + sqlite3_db_config(db, SQLITE_DBCONFIG_DEFENSIVE, 1, null) + /* This function has different mangled names in jdk8 vs jdk19, + and this call is here to ensure that the build fails + if it cannot find both names. */; + + affirm( 0==sqlite3_db_readonly(db,"main") ); + affirm( 0==sqlite3_db_readonly(db,null) ); + affirm( 0>sqlite3_db_readonly(db,"nope") ); + affirm( 0>sqlite3_db_readonly(null,null) ); + affirm( 0==sqlite3_last_insert_rowid(null) ); + + // These interrupt checks are only to make sure that the JNI binding + // has the proper exported symbol names. They don't actually test + // anything useful. + affirm( !sqlite3_is_interrupted(db) ); + sqlite3_interrupt(db); + affirm( sqlite3_is_interrupted(db) ); + sqlite3_close_v2(db); + affirm(0 == db.getNativePointer()); + } + + private void testOpenDb2(){ + final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); + int rc = sqlite3_open_v2(":memory:", out, + SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE, null); + ++metrics.dbOpen; + affirm(0 == rc); + sqlite3 db = out.get(); + affirm(0 != db.getNativePointer()); + sqlite3_close_v2(db); + affirm(0 == db.getNativePointer()); + } + + private void testPrepare123(){ + sqlite3 db = createNewDb(); + int rc; + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + rc = sqlite3_prepare(db, "CREATE TABLE t1(a);", outStmt); + affirm(0 == rc); + sqlite3_stmt stmt = outStmt.take(); + affirm(0 != stmt.getNativePointer()); + affirm( !sqlite3_stmt_readonly(stmt) ); + affirm( db == sqlite3_db_handle(stmt) ); + rc = sqlite3_step(stmt); + affirm(SQLITE_DONE == rc); + sqlite3_finalize(stmt); + affirm( null == sqlite3_db_handle(stmt) ); + affirm(0 == stmt.getNativePointer()); + + { /* Demonstrate how to use the "zTail" option of + sqlite3_prepare() family of functions. */ + OutputPointer.Int32 oTail = new OutputPointer.Int32(); + final byte[] sqlUtf8 = + "CREATE TABLE t2(a); INSERT INTO t2(a) VALUES(1),(2),(3)" + .getBytes(StandardCharsets.UTF_8); + int pos = 0, n = 1; + byte[] sqlChunk = sqlUtf8; + while(pos < sqlChunk.length){ + if(pos > 0){ + sqlChunk = Arrays.copyOfRange(sqlChunk, pos, sqlChunk.length); + } + //outln("SQL chunk #"+n+" length = "+sqlChunk.length+", pos = "+pos); + if( 0==sqlChunk.length ) break; + rc = sqlite3_prepare_v2(db, sqlChunk, outStmt, oTail); + affirm(0 == rc); + stmt = outStmt.get(); + pos = oTail.value; + /*outln("SQL tail pos = "+pos+". Chunk = "+ + (new String(Arrays.copyOfRange(sqlChunk,0,pos), + StandardCharsets.UTF_8)));*/ + switch(n){ + case 1: affirm(19 == pos); break; + case 2: affirm(36 == pos); break; + default: affirm( false /* can't happen */ ); + + } + ++n; + affirm(0 != stmt.getNativePointer()); + rc = sqlite3_step(stmt); + affirm(SQLITE_DONE == rc); + sqlite3_finalize(stmt); + affirm(0 == stmt.getNativePointer()); + } + } + + + rc = sqlite3_prepare_v3(db, "INSERT INTO t2(a) VALUES(1),(2),(3)", + SQLITE_PREPARE_NORMALIZE, outStmt); + affirm(0 == rc); + stmt = outStmt.get(); + affirm(0 != stmt.getNativePointer()); + sqlite3_finalize(stmt); + affirm(0 == stmt.getNativePointer() ); + + affirm( 0==sqlite3_errcode(db) ); + stmt = sqlite3_prepare(db, "intentional error"); + affirm( null==stmt ); + affirm( 0!=sqlite3_errcode(db) ); + affirm( 0==sqlite3_errmsg(db).indexOf("near \"intentional\"") ); + sqlite3_finalize(stmt); + stmt = sqlite3_prepare(db, "/* empty input*/\n-- comments only"); + affirm( null==stmt ); + affirm( 0==sqlite3_errcode(db) ); + sqlite3_close_v2(db); + } + + private void testBindFetchInt(){ + sqlite3 db = createNewDb(); + execSql(db, "CREATE TABLE t(a)"); + + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(:a);"); + affirm(1 == sqlite3_bind_parameter_count(stmt)); + final int paramNdx = sqlite3_bind_parameter_index(stmt, ":a"); + affirm(1 == paramNdx); + affirm( ":a".equals(sqlite3_bind_parameter_name(stmt, paramNdx))); + int total1 = 0; + long rowid = -1; + int changes = sqlite3_changes(db); + int changesT = sqlite3_total_changes(db); + long changes64 = sqlite3_changes64(db); + long changesT64 = sqlite3_total_changes64(db); + int rc; + for(int i = 99; i < 102; ++i ){ + total1 += i; + rc = sqlite3_bind_int(stmt, paramNdx, i); + affirm(0 == rc); + rc = sqlite3_step(stmt); + sqlite3_reset(stmt); + affirm(SQLITE_DONE == rc); + long x = sqlite3_last_insert_rowid(db); + affirm(x > rowid); + rowid = x; + } + sqlite3_finalize(stmt); + affirm(300 == total1); + affirm(sqlite3_changes(db) > changes); + affirm(sqlite3_total_changes(db) > changesT); + affirm(sqlite3_changes64(db) > changes64); + affirm(sqlite3_total_changes64(db) > changesT64); + stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); + affirm( sqlite3_stmt_readonly(stmt) ); + affirm( !sqlite3_stmt_busy(stmt) ); + int total2 = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + affirm( sqlite3_stmt_busy(stmt) ); + total2 += sqlite3_column_int(stmt, 0); + sqlite3_value sv = sqlite3_column_value(stmt, 0); + affirm( null != sv ); + affirm( 0 != sv.getNativePointer() ); + affirm( SQLITE_INTEGER == sqlite3_value_type(sv) ); + } + affirm( !sqlite3_stmt_busy(stmt) ); + sqlite3_finalize(stmt); + affirm(total1 == total2); + + // sqlite3_value_frombind() checks... + stmt = prepare(db, "SELECT 1, ?"); + sqlite3_bind_int(stmt, 1, 2); + rc = sqlite3_step(stmt); + affirm( SQLITE_ROW==rc ); + affirm( !sqlite3_value_frombind(sqlite3_column_value(stmt, 0)) ); + affirm( sqlite3_value_frombind(sqlite3_column_value(stmt, 1)) ); + sqlite3_finalize(stmt); + + sqlite3_close_v2(db); + affirm(0 == db.getNativePointer()); + } + + private void testBindFetchInt64(){ + try (sqlite3 db = createNewDb()){ + execSql(db, "CREATE TABLE t(a)"); + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); + long total1 = 0; + for(long i = 0xffffffff; i < 0xffffffff + 3; ++i ){ + total1 += i; + sqlite3_bind_int64(stmt, 1, i); + sqlite3_step(stmt); + sqlite3_reset(stmt); + } + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); + long total2 = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + total2 += sqlite3_column_int64(stmt, 0); + } + sqlite3_finalize(stmt); + affirm(total1 == total2); + //sqlite3_close_v2(db); + } + } + + private void testBindFetchDouble(){ + try (sqlite3 db = createNewDb()){ + execSql(db, "CREATE TABLE t(a)"); + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); + double total1 = 0; + for(double i = 1.5; i < 5.0; i = i + 1.0 ){ + total1 += i; + sqlite3_bind_double(stmt, 1, i); + sqlite3_step(stmt); + sqlite3_reset(stmt); + } + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); + double total2 = 0; + int counter = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + ++counter; + total2 += sqlite3_column_double(stmt, 0); + } + affirm(4 == counter); + sqlite3_finalize(stmt); + affirm(total2<=total1+0.01 && total2>=total1-0.01); + //sqlite3_close_v2(db); + } + } + + private void testBindFetchText(){ + sqlite3 db = createNewDb(); + execSql(db, "CREATE TABLE t(a)"); + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); + String[] list1 = { "hell🤩", "w😃rld", "!🤩" }; + int rc; + int n = 0; + for( String e : list1 ){ + rc = (0==n) + ? sqlite3_bind_text(stmt, 1, e) + : sqlite3_bind_text16(stmt, 1, e); + affirm(0 == rc); + rc = sqlite3_step(stmt); + affirm(SQLITE_DONE==rc); + sqlite3_reset(stmt); + } + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); + StringBuilder sbuf = new StringBuilder(); + n = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + final sqlite3_value sv = sqlite3_value_dup(sqlite3_column_value(stmt,0)); + final String txt = sqlite3_column_text16(stmt, 0); + sbuf.append( txt ); + affirm( txt.equals(new String( + sqlite3_column_text(stmt, 0), + StandardCharsets.UTF_8 + )) ); + affirm( txt.length() < sqlite3_value_bytes(sv) ); + affirm( txt.equals(new String( + sqlite3_value_text(sv), + StandardCharsets.UTF_8)) ); + affirm( txt.length() == sqlite3_value_bytes16(sv)/2 ); + affirm( txt.equals(sqlite3_value_text16(sv)) ); + sqlite3_value_free(sv); + ++n; + } + sqlite3_finalize(stmt); + affirm(3 == n); + affirm("w😃rldhell🤩!🤩".equals(sbuf.toString())); + + try( sqlite3_stmt stmt2 = prepare(db, "SELECT ?, ?") ){ + rc = sqlite3_bind_text(stmt2, 1, ""); + affirm( 0==rc ); + rc = sqlite3_bind_text(stmt2, 2, (String)null); + affirm( 0==rc ); + rc = sqlite3_step(stmt2); + affirm( SQLITE_ROW==rc ); + byte[] colBa = sqlite3_column_text(stmt2, 0); + affirm( 0==colBa.length ); + colBa = sqlite3_column_text(stmt2, 1); + affirm( null==colBa ); + //sqlite3_finalize(stmt); + } + + if(true){ + sqlite3_close_v2(db); + }else{ + // Let the Object.finalize() override deal with it. + } + } + + private void testBindFetchBlob(){ + sqlite3 db = createNewDb(); + execSql(db, "CREATE TABLE t(a)"); + sqlite3_stmt stmt = prepare(db, "INSERT INTO t(a) VALUES(?);"); + byte[] list1 = { 0x32, 0x33, 0x34 }; + int rc = sqlite3_bind_blob(stmt, 1, list1); + affirm( 0==rc ); + rc = sqlite3_step(stmt); + affirm(SQLITE_DONE == rc); + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT a FROM t ORDER BY a DESC;"); + int n = 0; + int total = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + byte[] blob = sqlite3_column_blob(stmt, 0); + affirm(3 == blob.length); + int i = 0; + for(byte b : blob){ + affirm(b == list1[i++]); + total += b; + } + ++n; + } + sqlite3_finalize(stmt); + affirm(1 == n); + affirm(total == 0x32 + 0x33 + 0x34); + sqlite3_close_v2(db); + } + + private void testSql(){ + sqlite3 db = createNewDb(); + sqlite3_stmt stmt = prepare(db, "SELECT 1"); + affirm( "SELECT 1".equals(sqlite3_sql(stmt)) ); + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT ?"); + sqlite3_bind_text(stmt, 1, "hell😃"); + final String expect = "SELECT 'hell😃'"; + affirm( expect.equals(sqlite3_expanded_sql(stmt)) ); + String n = sqlite3_normalized_sql(stmt); + affirm( null==n || "SELECT?;".equals(n) ); + sqlite3_finalize(stmt); + sqlite3_close(db); + } + + private void testCollation(){ + final sqlite3 db = createNewDb(); + execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')"); + final ValueHolder xDestroyCalled = new ValueHolder<>(0); + final CollationCallback myCollation = new CollationCallback() { + private String myState = + "this is local state. There is much like it, but this is mine."; + @Override + // Reverse-sorts its inputs... + public int call(byte[] lhs, byte[] rhs){ + int len = lhs.length > rhs.length ? rhs.length : lhs.length; + int c = 0, i = 0; + for(i = 0; i < len; ++i){ + c = lhs[i] - rhs[i]; + if(0 != c) break; + } + if(0==c){ + if(i < lhs.length) c = 1; + else if(i < rhs.length) c = -1; + } + return -c; + } + @Override + public void xDestroy() { + // Just demonstrates that xDestroy is called. + ++xDestroyCalled.value; + } + }; + final CollationNeededCallback collLoader = new CollationNeededCallback(){ + @Override + public int call(sqlite3 dbArg, int eTextRep, String collationName){ + affirm(dbArg == db/* as opposed to a temporary object*/); + return sqlite3_create_collation(dbArg, "reversi", eTextRep, myCollation); + } + }; + int rc = sqlite3_collation_needed(db, collLoader); + affirm( 0 == rc ); + rc = sqlite3_collation_needed(db, collLoader); + affirm( 0 == rc /* Installing the same object again is a no-op */); + sqlite3_stmt stmt = prepare(db, "SELECT a FROM t ORDER BY a COLLATE reversi"); + int counter = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + final String val = sqlite3_column_text16(stmt, 0); + ++counter; + //outln("REVERSI'd row#"+counter+": "+val); + switch(counter){ + case 1: affirm("c".equals(val)); break; + case 2: affirm("b".equals(val)); break; + case 3: affirm("a".equals(val)); break; + } + } + affirm(3 == counter); + sqlite3_finalize(stmt); + stmt = prepare(db, "SELECT a FROM t ORDER BY a"); + counter = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + final String val = sqlite3_column_text16(stmt, 0); + ++counter; + //outln("Non-REVERSI'd row#"+counter+": "+val); + switch(counter){ + case 3: affirm("c".equals(val)); break; + case 2: affirm("b".equals(val)); break; + case 1: affirm("a".equals(val)); break; + } + } + affirm(3 == counter); + sqlite3_finalize(stmt); + affirm( 0 == xDestroyCalled.value ); + rc = sqlite3_collation_needed(db, null); + affirm( 0 == rc ); + sqlite3_close_v2(db); + affirm( 0 == db.getNativePointer() ); + affirm( 1 == xDestroyCalled.value ); + } + + @SingleThreadOnly /* because it's thread-agnostic */ + private void testToUtf8(){ + /** + https://docs.oracle.com/javase/8/docs/api/java/nio/charset/Charset.html + + Let's ensure that we can convert to standard UTF-8 in Java code + (noting that the JNI native API has no way to do this). + */ + final byte[] ba = "a \0 b".getBytes(StandardCharsets.UTF_8); + affirm( 5 == ba.length /* as opposed to 6 in modified utf-8 */); + } + + private void testStatus(){ + final OutputPointer.Int64 cur64 = new OutputPointer.Int64(); + final OutputPointer.Int64 high64 = new OutputPointer.Int64(); + final OutputPointer.Int32 cur32 = new OutputPointer.Int32(); + final OutputPointer.Int32 high32 = new OutputPointer.Int32(); + final sqlite3 db = createNewDb(); + execSql(db, "create table t(a); insert into t values(1),(2),(3)"); + + int rc = sqlite3_status(SQLITE_STATUS_MEMORY_USED, cur32, high32, false); + affirm( 0 == rc ); + affirm( cur32.value > 0 ); + affirm( high32.value >= cur32.value ); + + rc = sqlite3_status64(SQLITE_STATUS_MEMORY_USED, cur64, high64, false); + affirm( 0 == rc ); + affirm( cur64.value > 0 ); + affirm( high64.value >= cur64.value ); + + cur32.value = 0; + high32.value = 1; + rc = sqlite3_db_status(db, SQLITE_DBSTATUS_SCHEMA_USED, cur32, high32, false); + affirm( 0 == rc ); + affirm( cur32.value > 0 ); + affirm( high32.value == 0 /* always 0 for SCHEMA_USED */ ); + + sqlite3_close_v2(db); + } + + private void testUdf1(){ + final sqlite3 db = createNewDb(); + // These ValueHolders are just to confirm that the func did what we want... + final ValueHolder xDestroyCalled = new ValueHolder<>(false); + final ValueHolder xFuncAccum = new ValueHolder<>(0); + final ValueHolder neverEverDoThisInClientCode = new ValueHolder<>(null); + final ValueHolder neverEverDoThisInClientCode2 = new ValueHolder<>(null); + + // Create an SQLFunction instance using one of its 3 subclasses: + // Scalar, Aggregate, or Window: + SQLFunction func = + // Each of the 3 subclasses requires a different set of + // functions, all of which must be implemented. Anonymous + // classes are a convenient way to implement these. + new ScalarFunction(){ + public void xFunc(sqlite3_context cx, sqlite3_value[] args){ + affirm(db == sqlite3_context_db_handle(cx)); + if( null==neverEverDoThisInClientCode.value ){ + /* !!!NEVER!!! hold a reference to an sqlite3_value or + sqlite3_context object like this in client code! They + are ONLY legal for the duration of their single + call. We do it here ONLY to test that the defenses + against clients doing this are working. */ + neverEverDoThisInClientCode2.value = cx; + neverEverDoThisInClientCode.value = args; + } + int result = 0; + for( sqlite3_value v : args ) result += sqlite3_value_int(v); + xFuncAccum.value += result;// just for post-run testing + sqlite3_result_int(cx, result); + } + /* OPTIONALLY override xDestroy... */ + public void xDestroy(){ + xDestroyCalled.value = true; + } + }; + + // Register and use the function... + int rc = sqlite3_create_function(db, "myfunc", -1, SQLITE_UTF8, func); + affirm(0 == rc); + affirm(0 == xFuncAccum.value); + final sqlite3_stmt stmt = prepare(db, "SELECT myfunc(1,2,3)"); + int n = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + affirm( 6 == sqlite3_column_int(stmt, 0) ); + ++n; + } + sqlite3_finalize(stmt); + affirm(1 == n); + affirm(6 == xFuncAccum.value); + affirm( !xDestroyCalled.value ); + affirm( null!=neverEverDoThisInClientCode.value ); + affirm( null!=neverEverDoThisInClientCode2.value ); + affirm( 0 xFuncAccum = new ValueHolder<>(0); + + SQLFunction funcAgg = new AggregateFunction(){ + @Override public void xStep(sqlite3_context cx, sqlite3_value[] args){ + /** Throwing from here should emit loud noise on stdout or stderr + but the exception is supressed because we have no way to inform + sqlite about it from these callbacks. */ + //throw new RuntimeException("Throwing from an xStep"); + } + @Override public void xFinal(sqlite3_context cx){ + throw new RuntimeException("Throwing from an xFinal"); + } + }; + int rc = sqlite3_create_function(db, "myagg", 1, SQLITE_UTF8, funcAgg); + affirm(0 == rc); + affirm(0 == xFuncAccum.value); + sqlite3_stmt stmt = prepare(db, "SELECT myagg(1)"); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + affirm( 0 != rc ); + affirm( sqlite3_errmsg(db).indexOf("an xFinal") > 0 ); + + SQLFunction funcSc = new ScalarFunction(){ + @Override public void xFunc(sqlite3_context cx, sqlite3_value[] args){ + throw new RuntimeException("Throwing from an xFunc"); + } + }; + rc = sqlite3_create_function(db, "mysca", 0, SQLITE_UTF8, funcSc); + affirm(0 == rc); + affirm(0 == xFuncAccum.value); + stmt = prepare(db, "SELECT mysca()"); + rc = sqlite3_step(stmt); + sqlite3_finalize(stmt); + affirm( 0 != rc ); + affirm( sqlite3_errmsg(db).indexOf("an xFunc") > 0 ); + rc = sqlite3_create_function(db, "mysca", 1, -1, funcSc); + affirm( SQLITE_FORMAT==rc, "invalid encoding value." ); + sqlite3_close_v2(db); + } + + @SingleThreadOnly + private void testUdfJavaObject(){ + affirm( !mtMode ); + final sqlite3 db = createNewDb(); + final ValueHolder testResult = new ValueHolder<>(db); + final ValueHolder boundObj = new ValueHolder<>(42); + final SQLFunction func = new ScalarFunction(){ + public void xFunc(sqlite3_context cx, sqlite3_value args[]){ + sqlite3_result_java_object(cx, testResult.value); + affirm( sqlite3_value_java_object(args[0]) == boundObj ); + } + }; + int rc = sqlite3_create_function(db, "myfunc", -1, SQLITE_UTF8, func); + affirm(0 == rc); + sqlite3_stmt stmt = prepare(db, "select myfunc(?)"); + affirm( 0 != stmt.getNativePointer() ); + affirm( testResult.value == db ); + rc = sqlite3_bind_java_object(stmt, 1, boundObj); + affirm( 0==rc ); + int n = 0; + if( SQLITE_ROW == sqlite3_step(stmt) ){ + final sqlite3_value v = sqlite3_column_value(stmt, 0); + affirm( testResult.value == sqlite3_value_java_object(v) ); + affirm( testResult.value == sqlite3_value_java_casted(v, sqlite3.class) ); + affirm( testResult.value == + sqlite3_value_java_casted(v, testResult.value.getClass()) ); + affirm( testResult.value == sqlite3_value_java_casted(v, Object.class) ); + affirm( null == sqlite3_value_java_casted(v, String.class) ); + ++n; + } + sqlite3_finalize(stmt); + affirm( 1 == n ); + affirm( 0==sqlite3_db_release_memory(db) ); + sqlite3_close_v2(db); + } + + private void testUdfAggregate(){ + final sqlite3 db = createNewDb(); + final ValueHolder xFinalNull = + // To confirm that xFinal() is called with no aggregate state + // when the corresponding result set is empty. + new ValueHolder<>(false); + SQLFunction func = new AggregateFunction(){ + @Override + public void xStep(sqlite3_context cx, sqlite3_value[] args){ + final ValueHolder agg = this.getAggregateState(cx, 0); + agg.value += sqlite3_value_int(args[0]); + affirm( agg == this.getAggregateState(cx, 0) ); + } + @Override + public void xFinal(sqlite3_context cx){ + final Integer v = this.takeAggregateState(cx); + if(null == v){ + xFinalNull.value = true; + sqlite3_result_null(cx); + }else{ + sqlite3_result_int(cx, v); + } + } + }; + execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES(1),(2),(3)"); + int rc = sqlite3_create_function(db, "myfunc", 1, SQLITE_UTF8, func); + affirm(0 == rc); + sqlite3_stmt stmt = prepare(db, "select myfunc(a), myfunc(a+10) from t"); + affirm( 0==sqlite3_stmt_status(stmt, SQLITE_STMTSTATUS_RUN, false) ); + int n = 0; + if( SQLITE_ROW == sqlite3_step(stmt) ){ + int v = sqlite3_column_int(stmt, 0); + affirm( 6 == v ); + int v2 = sqlite3_column_int(stmt, 1); + affirm( 30+v == v2 ); + ++n; + } + affirm( 1==n ); + affirm(!xFinalNull.value); + sqlite3_reset(stmt); + affirm( 1==sqlite3_stmt_status(stmt, SQLITE_STMTSTATUS_RUN, false) ); + // Ensure that the accumulator is reset on subsequent calls... + n = 0; + if( SQLITE_ROW == sqlite3_step(stmt) ){ + final int v = sqlite3_column_int(stmt, 0); + affirm( 6 == v ); + ++n; + } + sqlite3_finalize(stmt); + affirm( 1==n ); + + stmt = prepare(db, "select myfunc(a), myfunc(a+a) from t order by a"); + n = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + final int c0 = sqlite3_column_int(stmt, 0); + final int c1 = sqlite3_column_int(stmt, 1); + ++n; + affirm( 6 == c0 ); + affirm( 12 == c1 ); + } + sqlite3_finalize(stmt); + affirm( 1 == n ); + affirm(!xFinalNull.value); + + execSql(db, "SELECT myfunc(1) WHERE 0"); + affirm(xFinalNull.value); + sqlite3_close_v2(db); + } + + private void testUdfWindow(){ + final sqlite3 db = createNewDb(); + /* Example window function, table, and results taken from: + https://sqlite.org/windowfunctions.html#udfwinfunc */ + final SQLFunction func = new WindowFunction(){ + + private void xStepInverse(sqlite3_context cx, int v){ + this.getAggregateState(cx,0).value += v; + } + @Override public void xStep(sqlite3_context cx, sqlite3_value[] args){ + this.xStepInverse(cx, sqlite3_value_int(args[0])); + } + @Override public void xInverse(sqlite3_context cx, sqlite3_value[] args){ + this.xStepInverse(cx, -sqlite3_value_int(args[0])); + } + + private void xFinalValue(sqlite3_context cx, Integer v){ + if(null == v) sqlite3_result_null(cx); + else sqlite3_result_int(cx, v); + } + @Override public void xFinal(sqlite3_context cx){ + xFinalValue(cx, this.takeAggregateState(cx)); + } + @Override public void xValue(sqlite3_context cx){ + xFinalValue(cx, this.getAggregateState(cx,null).value); + } + }; + int rc = sqlite3_create_function(db, "winsumint", 1, SQLITE_UTF8, func); + affirm( 0 == rc ); + execSql(db, new String[] { + "CREATE TEMP TABLE twin(x, y); INSERT INTO twin VALUES", + "('a', 4),('b', 5),('c', 3),('d', 8),('e', 1)" + }); + final sqlite3_stmt stmt = prepare(db, + "SELECT x, winsumint(y) OVER ("+ + "ORDER BY x ROWS BETWEEN 1 PRECEDING AND 1 FOLLOWING"+ + ") AS sum_y "+ + "FROM twin ORDER BY x;"); + affirm( 0 == rc ); + int n = 0; + while( SQLITE_ROW == sqlite3_step(stmt) ){ + final String s = sqlite3_column_text16(stmt, 0); + final int i = sqlite3_column_int(stmt, 1); + switch(++n){ + case 1: affirm( "a".equals(s) && 9==i ); break; + case 2: affirm( "b".equals(s) && 12==i ); break; + case 3: affirm( "c".equals(s) && 16==i ); break; + case 4: affirm( "d".equals(s) && 12==i ); break; + case 5: affirm( "e".equals(s) && 9==i ); break; + default: affirm( false /* cannot happen */ ); + } + } + sqlite3_finalize(stmt); + affirm( 5 == n ); + sqlite3_close_v2(db); + } + + private void listBoundMethods(){ + if(false){ + final java.lang.reflect.Field[] declaredFields = + CApi.class.getDeclaredFields(); + outln("Bound constants:\n"); + for(java.lang.reflect.Field field : declaredFields) { + if(java.lang.reflect.Modifier.isStatic(field.getModifiers())) { + outln("\t",field.getName()); + } + } + } + final java.lang.reflect.Method[] declaredMethods = + CApi.class.getDeclaredMethods(); + final java.util.List funcList = new java.util.ArrayList<>(); + for(java.lang.reflect.Method m : declaredMethods){ + if((m.getModifiers() & java.lang.reflect.Modifier.STATIC) != 0){ + final String name = m.getName(); + if(name.startsWith("sqlite3_")){ + funcList.add(name); + } + } + } + int count = 0; + java.util.Collections.sort(funcList); + for(String n : funcList){ + ++count; + outln("\t",n,"()"); + } + outln(count," functions named sqlite3_*."); + } + + private void testTrace(){ + final sqlite3 db = createNewDb(); + final ValueHolder counter = new ValueHolder<>(0); + /* Ensure that characters outside of the UTF BMP survive the trip + from Java to sqlite3 and back to Java. (At no small efficiency + penalty.) */ + final String nonBmpChar = "😃"; + int rc = sqlite3_trace_v2( + db, SQLITE_TRACE_STMT | SQLITE_TRACE_PROFILE + | SQLITE_TRACE_ROW | SQLITE_TRACE_CLOSE, + new TraceV2Callback(){ + @Override public int call(int traceFlag, Object pNative, Object x){ + ++counter.value; + //outln("TRACE "+traceFlag+" pNative = "+pNative.getClass().getName()); + switch(traceFlag){ + case SQLITE_TRACE_STMT: + affirm(pNative instanceof sqlite3_stmt); + //outln("TRACE_STMT sql = "+x); + affirm(x instanceof String); + affirm( ((String)x).indexOf(nonBmpChar) > 0 ); + break; + case SQLITE_TRACE_PROFILE: + affirm(pNative instanceof sqlite3_stmt); + affirm(x instanceof Long); + //outln("TRACE_PROFILE time = "+x); + break; + case SQLITE_TRACE_ROW: + affirm(pNative instanceof sqlite3_stmt); + affirm(null == x); + //outln("TRACE_ROW = "+sqlite3_column_text16((sqlite3_stmt)pNative, 0)); + break; + case SQLITE_TRACE_CLOSE: + affirm(pNative instanceof sqlite3); + affirm(null == x); + break; + default: + affirm(false /*cannot happen*/); + break; + } + return 0; + } + }); + affirm( 0==rc ); + execSql(db, "SELECT coalesce(null,null,'"+nonBmpChar+"'); "+ + "SELECT 'w"+nonBmpChar+"orld'"); + affirm( 6 == counter.value ); + sqlite3_close_v2(db); + affirm( 7 == counter.value ); + } + + @SingleThreadOnly /* because threads inherently break this test */ + private static void testBusy(){ + final String dbName = "_busy-handler.db"; + final OutputPointer.sqlite3 outDb = new OutputPointer.sqlite3(); + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + + int rc = sqlite3_open(dbName, outDb); + ++metrics.dbOpen; + affirm( 0 == rc ); + final sqlite3 db1 = outDb.get(); + execSql(db1, "CREATE TABLE IF NOT EXISTS t(a)"); + rc = sqlite3_open(dbName, outDb); + ++metrics.dbOpen; + affirm( 0 == rc ); + affirm( outDb.get() != db1 ); + final sqlite3 db2 = outDb.get(); + + affirm( "main".equals( sqlite3_db_name(db1, 0) ) ); + rc = sqlite3_db_config(db1, SQLITE_DBCONFIG_MAINDBNAME, "foo"); + affirm( sqlite3_db_filename(db1, "foo").endsWith(dbName) ); + affirm( "foo".equals( sqlite3_db_name(db1, 0) ) ); + + final ValueHolder xBusyCalled = new ValueHolder<>(0); + BusyHandlerCallback handler = new BusyHandlerCallback(){ + @Override public int call(int n){ + //outln("busy handler #"+n); + return n > 2 ? 0 : ++xBusyCalled.value; + } + }; + rc = sqlite3_busy_handler(db2, handler); + affirm(0 == rc); + + // Force a locked condition... + execSql(db1, "BEGIN EXCLUSIVE"); + rc = sqlite3_prepare_v2(db2, "SELECT * from t", outStmt); + affirm( SQLITE_BUSY == rc); + affirm( null == outStmt.get() ); + affirm( 3 == xBusyCalled.value ); + sqlite3_close_v2(db1); + sqlite3_close_v2(db2); + try{ + final java.io.File f = new java.io.File(dbName); + f.delete(); + }catch(Exception e){ + /* ignore */ + } + } + + private void testProgress(){ + final sqlite3 db = createNewDb(); + final ValueHolder counter = new ValueHolder<>(0); + sqlite3_progress_handler(db, 1, new ProgressHandlerCallback(){ + @Override public int call(){ + ++counter.value; + return 0; + } + }); + execSql(db, "SELECT 1; SELECT 2;"); + affirm( counter.value > 0 ); + int nOld = counter.value; + sqlite3_progress_handler(db, 0, null); + execSql(db, "SELECT 1; SELECT 2;"); + affirm( nOld == counter.value ); + sqlite3_close_v2(db); + } + + private void testCommitHook(){ + final sqlite3 db = createNewDb(); + final ValueHolder counter = new ValueHolder<>(0); + final ValueHolder hookResult = new ValueHolder<>(0); + final CommitHookCallback theHook = new CommitHookCallback(){ + @Override public int call(){ + ++counter.value; + return hookResult.value; + } + }; + CommitHookCallback oldHook = sqlite3_commit_hook(db, theHook); + affirm( null == oldHook ); + execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')"); + affirm( 2 == counter.value ); + execSql(db, "BEGIN; SELECT 1; SELECT 2; COMMIT;"); + affirm( 2 == counter.value /* NOT invoked if no changes are made */ ); + execSql(db, "BEGIN; update t set a='d' where a='c'; COMMIT;"); + affirm( 3 == counter.value ); + oldHook = sqlite3_commit_hook(db, theHook); + affirm( theHook == oldHook ); + execSql(db, "BEGIN; update t set a='e' where a='d'; COMMIT;"); + affirm( 4 == counter.value ); + oldHook = sqlite3_commit_hook(db, null); + affirm( theHook == oldHook ); + execSql(db, "BEGIN; update t set a='f' where a='e'; COMMIT;"); + affirm( 4 == counter.value ); + oldHook = sqlite3_commit_hook(db, null); + affirm( null == oldHook ); + execSql(db, "BEGIN; update t set a='g' where a='f'; COMMIT;"); + affirm( 4 == counter.value ); + + final CommitHookCallback newHook = new CommitHookCallback(){ + @Override public int call(){return 0;} + }; + oldHook = sqlite3_commit_hook(db, newHook); + affirm( null == oldHook ); + execSql(db, "BEGIN; update t set a='h' where a='g'; COMMIT;"); + affirm( 4 == counter.value ); + oldHook = sqlite3_commit_hook(db, theHook); + affirm( newHook == oldHook ); + execSql(db, "BEGIN; update t set a='i' where a='h'; COMMIT;"); + affirm( 5 == counter.value ); + hookResult.value = SQLITE_ERROR; + int rc = execSql(db, false, "BEGIN; update t set a='j' where a='i'; COMMIT;"); + affirm( SQLITE_CONSTRAINT == rc ); + affirm( 6 == counter.value ); + sqlite3_close_v2(db); + } + + private void testUpdateHook(){ + final sqlite3 db = createNewDb(); + final ValueHolder counter = new ValueHolder<>(0); + final ValueHolder expectedOp = new ValueHolder<>(0); + final UpdateHookCallback theHook = new UpdateHookCallback(){ + @Override + public void call(int opId, String dbName, String tableName, long rowId){ + ++counter.value; + if( 0!=expectedOp.value ){ + affirm( expectedOp.value == opId ); + } + } + }; + UpdateHookCallback oldHook = sqlite3_update_hook(db, theHook); + affirm( null == oldHook ); + expectedOp.value = SQLITE_INSERT; + execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')"); + affirm( 3 == counter.value ); + expectedOp.value = SQLITE_UPDATE; + execSql(db, "update t set a='d' where a='c';"); + affirm( 4 == counter.value ); + oldHook = sqlite3_update_hook(db, theHook); + affirm( theHook == oldHook ); + expectedOp.value = SQLITE_DELETE; + execSql(db, "DELETE FROM t where a='d'"); + affirm( 5 == counter.value ); + oldHook = sqlite3_update_hook(db, null); + affirm( theHook == oldHook ); + execSql(db, "update t set a='e' where a='b';"); + affirm( 5 == counter.value ); + oldHook = sqlite3_update_hook(db, null); + affirm( null == oldHook ); + + final UpdateHookCallback newHook = new UpdateHookCallback(){ + @Override public void call(int opId, String dbName, String tableName, long rowId){ + } + }; + oldHook = sqlite3_update_hook(db, newHook); + affirm( null == oldHook ); + execSql(db, "update t set a='h' where a='a'"); + affirm( 5 == counter.value ); + oldHook = sqlite3_update_hook(db, theHook); + affirm( newHook == oldHook ); + expectedOp.value = SQLITE_UPDATE; + execSql(db, "update t set a='i' where a='h'"); + affirm( 6 == counter.value ); + sqlite3_close_v2(db); + } + + /** + This test is functionally identical to testUpdateHook(), only with a + different callback type. + */ + private void testPreUpdateHook(){ + if( !sqlite3_compileoption_used("ENABLE_PREUPDATE_HOOK") ){ + //outln("Skipping testPreUpdateHook(): no pre-update hook support."); + return; + } + final sqlite3 db = createNewDb(); + final ValueHolder counter = new ValueHolder<>(0); + final ValueHolder expectedOp = new ValueHolder<>(0); + final PreupdateHookCallback theHook = new PreupdateHookCallback(){ + @Override + public void call(sqlite3 db, int opId, String dbName, String dbTable, + long iKey1, long iKey2 ){ + ++counter.value; + switch( opId ){ + case SQLITE_UPDATE: + affirm( 0 < sqlite3_preupdate_count(db) ); + affirm( null != sqlite3_preupdate_new(db, 0) ); + affirm( null != sqlite3_preupdate_old(db, 0) ); + break; + case SQLITE_INSERT: + affirm( null != sqlite3_preupdate_new(db, 0) ); + break; + case SQLITE_DELETE: + affirm( null != sqlite3_preupdate_old(db, 0) ); + break; + default: + break; + } + if( 0!=expectedOp.value ){ + affirm( expectedOp.value == opId ); + } + } + }; + PreupdateHookCallback oldHook = sqlite3_preupdate_hook(db, theHook); + affirm( null == oldHook ); + expectedOp.value = SQLITE_INSERT; + execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')"); + affirm( 3 == counter.value ); + expectedOp.value = SQLITE_UPDATE; + execSql(db, "update t set a='d' where a='c';"); + affirm( 4 == counter.value ); + oldHook = sqlite3_preupdate_hook(db, theHook); + affirm( theHook == oldHook ); + expectedOp.value = SQLITE_DELETE; + execSql(db, "DELETE FROM t where a='d'"); + affirm( 5 == counter.value ); + oldHook = sqlite3_preupdate_hook(db, null); + affirm( theHook == oldHook ); + execSql(db, "update t set a='e' where a='b';"); + affirm( 5 == counter.value ); + oldHook = sqlite3_preupdate_hook(db, null); + affirm( null == oldHook ); + + final PreupdateHookCallback newHook = new PreupdateHookCallback(){ + @Override + public void call(sqlite3 db, int opId, String dbName, + String tableName, long iKey1, long iKey2){ + } + }; + oldHook = sqlite3_preupdate_hook(db, newHook); + affirm( null == oldHook ); + execSql(db, "update t set a='h' where a='a'"); + affirm( 5 == counter.value ); + oldHook = sqlite3_preupdate_hook(db, theHook); + affirm( newHook == oldHook ); + expectedOp.value = SQLITE_UPDATE; + execSql(db, "update t set a='i' where a='h'"); + affirm( 6 == counter.value ); + + sqlite3_close_v2(db); + } + + private void testRollbackHook(){ + final sqlite3 db = createNewDb(); + final ValueHolder counter = new ValueHolder<>(0); + final RollbackHookCallback theHook = new RollbackHookCallback(){ + @Override public void call(){ + ++counter.value; + } + }; + RollbackHookCallback oldHook = sqlite3_rollback_hook(db, theHook); + affirm( null == oldHook ); + execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')"); + affirm( 0 == counter.value ); + execSql(db, false, "BEGIN; SELECT 1; SELECT 2; ROLLBACK;"); + affirm( 1 == counter.value /* contra to commit hook, is invoked if no changes are made */ ); + + final RollbackHookCallback newHook = new RollbackHookCallback(){ + @Override public void call(){return;} + }; + oldHook = sqlite3_rollback_hook(db, newHook); + affirm( theHook == oldHook ); + execSql(db, false, "BEGIN; SELECT 1; ROLLBACK;"); + affirm( 1 == counter.value ); + oldHook = sqlite3_rollback_hook(db, theHook); + affirm( newHook == oldHook ); + execSql(db, false, "BEGIN; SELECT 1; ROLLBACK;"); + affirm( 2 == counter.value ); + int rc = execSql(db, false, "BEGIN; SELECT 1; ROLLBACK;"); + affirm( 0 == rc ); + affirm( 3 == counter.value ); + sqlite3_close_v2(db); + } + + /** + If FTS5 is available, runs FTS5 tests, else returns with no side + effects. If it is available but loading of the FTS5 bits fails, + it throws. + */ + @SuppressWarnings("unchecked") + @SingleThreadOnly /* because the Fts5 parts are not yet known to be + thread-safe */ + private void testFts5() throws Exception { + if( !sqlite3_compileoption_used("ENABLE_FTS5") ){ + //outln("SQLITE_ENABLE_FTS5 is not set. Skipping FTS5 tests."); + return; + } + Exception err = null; + try { + Class t = Class.forName("org.sqlite.jni.fts5.TesterFts5"); + java.lang.reflect.Constructor ctor = t.getConstructor(); + ctor.setAccessible(true); + final long timeStart = System.currentTimeMillis(); + ctor.newInstance() /* will run all tests */; + final long timeEnd = System.currentTimeMillis(); + outln("FTS5 Tests done in ",(timeEnd - timeStart),"ms"); + }catch(ClassNotFoundException e){ + outln("FTS5 classes not loaded."); + err = e; + }catch(NoSuchMethodException e){ + outln("FTS5 tester ctor not found."); + err = e; + }catch(Exception e){ + outln("Instantiation of FTS5 tester threw."); + err = e; + } + if( null != err ){ + outln("Exception: "+err); + err.printStackTrace(); + throw err; + } + } + + private void testAuthorizer(){ + final sqlite3 db = createNewDb(); + final ValueHolder counter = new ValueHolder<>(0); + final ValueHolder authRc = new ValueHolder<>(0); + final AuthorizerCallback auth = new AuthorizerCallback(){ + public int call(int op, String s0, String s1, String s2, String s3){ + ++counter.value; + //outln("xAuth(): "+s0+" "+s1+" "+s2+" "+s3); + return authRc.value; + } + }; + execSql(db, "CREATE TABLE t(a); INSERT INTO t(a) VALUES('a'),('b'),('c')"); + sqlite3_set_authorizer(db, auth); + execSql(db, "UPDATE t SET a=1"); + affirm( 1 == counter.value ); + authRc.value = SQLITE_DENY; + int rc = execSql(db, false, "UPDATE t SET a=2"); + affirm( SQLITE_AUTH==rc ); + // TODO: expand these tests considerably + sqlite3_close(db); + } + + @SingleThreadOnly /* because multiple threads legitimately make these + results unpredictable */ + private synchronized void testAutoExtension(){ + final ValueHolder val = new ValueHolder<>(0); + final ValueHolder toss = new ValueHolder<>(null); + final AutoExtensionCallback ax = new AutoExtensionCallback(){ + @Override public int call(sqlite3 db){ + ++val.value; + if( null!=toss.value ){ + throw new RuntimeException(toss.value); + } + return 0; + } + }; + int rc = sqlite3_auto_extension( ax ); + affirm( 0==rc ); + sqlite3_close(createNewDb()); + affirm( 1==val.value ); + sqlite3_close(createNewDb()); + affirm( 2==val.value ); + sqlite3_reset_auto_extension(); + sqlite3_close(createNewDb()); + affirm( 2==val.value ); + rc = sqlite3_auto_extension( ax ); + affirm( 0==rc ); + // Must not add a new entry + rc = sqlite3_auto_extension( ax ); + affirm( 0==rc ); + sqlite3_close( createNewDb() ); + affirm( 3==val.value ); + + sqlite3 db = createNewDb(); + affirm( 4==val.value ); + execSql(db, "ATTACH ':memory:' as foo"); + affirm( 4==val.value, "ATTACH uses the same connection, not sub-connections." ); + sqlite3_close(db); + db = null; + + affirm( sqlite3_cancel_auto_extension(ax) ); + affirm( !sqlite3_cancel_auto_extension(ax) ); + sqlite3_close(createNewDb()); + affirm( 4==val.value ); + rc = sqlite3_auto_extension( ax ); + affirm( 0==rc ); + Exception err = null; + toss.value = "Throwing from auto_extension."; + try{ + sqlite3_close(createNewDb()); + }catch(Exception e){ + err = e; + } + affirm( err!=null ); + affirm( err.getMessage().indexOf(toss.value)>0 ); + toss.value = null; + + val.value = 0; + final AutoExtensionCallback ax2 = new AutoExtensionCallback(){ + @Override public synchronized int call(sqlite3 db){ + ++val.value; + return 0; + } + }; + rc = sqlite3_auto_extension( ax2 ); + affirm( 0 == rc ); + sqlite3_close(createNewDb()); + affirm( 2 == val.value ); + affirm( sqlite3_cancel_auto_extension(ax) ); + affirm( !sqlite3_cancel_auto_extension(ax) ); + sqlite3_close(createNewDb()); + affirm( 3 == val.value ); + rc = sqlite3_auto_extension( ax ); + affirm( 0 == rc ); + sqlite3_close(createNewDb()); + affirm( 5 == val.value ); + affirm( sqlite3_cancel_auto_extension(ax2) ); + affirm( !sqlite3_cancel_auto_extension(ax2) ); + sqlite3_close(createNewDb()); + affirm( 6 == val.value ); + rc = sqlite3_auto_extension( ax2 ); + affirm( 0 == rc ); + sqlite3_close(createNewDb()); + affirm( 8 == val.value ); + + sqlite3_reset_auto_extension(); + sqlite3_close(createNewDb()); + affirm( 8 == val.value ); + affirm( !sqlite3_cancel_auto_extension(ax) ); + affirm( !sqlite3_cancel_auto_extension(ax2) ); + sqlite3_close(createNewDb()); + affirm( 8 == val.value ); + } + + + private void testColumnMetadata(){ + final sqlite3 db = createNewDb(); + execSql(db, new String[] { + "CREATE TABLE t(a duck primary key not null collate noCase); ", + "INSERT INTO t(a) VALUES(1),(2),(3);" + }); + OutputPointer.Bool bNotNull = new OutputPointer.Bool(); + OutputPointer.Bool bPrimaryKey = new OutputPointer.Bool(); + OutputPointer.Bool bAutoinc = new OutputPointer.Bool(); + OutputPointer.String zCollSeq = new OutputPointer.String(); + OutputPointer.String zDataType = new OutputPointer.String(); + int rc = sqlite3_table_column_metadata( + db, "main", "t", "a", zDataType, zCollSeq, + bNotNull, bPrimaryKey, bAutoinc); + affirm( 0==rc ); + affirm( bPrimaryKey.value ); + affirm( !bAutoinc.value ); + affirm( bNotNull.value ); + affirm( "noCase".equals(zCollSeq.value) ); + affirm( "duck".equals(zDataType.value) ); + + TableColumnMetadata m = + sqlite3_table_column_metadata(db, "main", "t", "a"); + affirm( null != m ); + affirm( bPrimaryKey.value == m.isPrimaryKey() ); + affirm( bAutoinc.value == m.isAutoincrement() ); + affirm( bNotNull.value == m.isNotNull() ); + affirm( zCollSeq.value.equals(m.getCollation()) ); + affirm( zDataType.value.equals(m.getDataType()) ); + + affirm( null == sqlite3_table_column_metadata(db, "nope", "t", "a") ); + affirm( null == sqlite3_table_column_metadata(db, "main", "nope", "a") ); + + m = sqlite3_table_column_metadata(db, "main", "t", null) + /* Check only for existence of table */; + affirm( null != m ); + affirm( m.isPrimaryKey() ); + affirm( !m.isAutoincrement() ); + affirm( !m.isNotNull() ); + affirm( "BINARY".equalsIgnoreCase(m.getCollation()) ); + affirm( "INTEGER".equalsIgnoreCase(m.getDataType()) ); + + sqlite3_close_v2(db); + } + + private void testTxnState(){ + final sqlite3 db = createNewDb(); + affirm( SQLITE_TXN_NONE == sqlite3_txn_state(db, null) ); + affirm( sqlite3_get_autocommit(db) ); + execSql(db, "BEGIN;"); + affirm( !sqlite3_get_autocommit(db) ); + affirm( SQLITE_TXN_NONE == sqlite3_txn_state(db, null) ); + execSql(db, "SELECT * FROM sqlite_schema;"); + affirm( SQLITE_TXN_READ == sqlite3_txn_state(db, "main") ); + execSql(db, "CREATE TABLE t(a);"); + affirm( SQLITE_TXN_WRITE == sqlite3_txn_state(db, null) ); + execSql(db, "ROLLBACK;"); + affirm( SQLITE_TXN_NONE == sqlite3_txn_state(db, null) ); + sqlite3_close_v2(db); + } + + + private void testExplain(){ + final sqlite3 db = createNewDb(); + sqlite3_stmt stmt = prepare(db,"SELECT 1"); + + affirm( 0 == sqlite3_stmt_isexplain(stmt) ); + int rc = sqlite3_stmt_explain(stmt, 1); + affirm( 1 == sqlite3_stmt_isexplain(stmt) ); + rc = sqlite3_stmt_explain(stmt, 2); + affirm( 2 == sqlite3_stmt_isexplain(stmt) ); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + } + + private void testLimit(){ + final sqlite3 db = createNewDb(); + int v; + + v = sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1); + affirm( v > 0 ); + affirm( v == sqlite3_limit(db, SQLITE_LIMIT_LENGTH, v-1) ); + affirm( v-1 == sqlite3_limit(db, SQLITE_LIMIT_LENGTH, -1) ); + sqlite3_close_v2(db); + } + + private void testComplete(){ + affirm( 0==sqlite3_complete("select 1") ); + affirm( 0!=sqlite3_complete("select 1;") ); + affirm( 0!=sqlite3_complete("nope 'nope' 'nope' 1;"), "Yup" ); + } + + private void testKeyword(){ + final int n = sqlite3_keyword_count(); + affirm( n>0 ); + affirm( !sqlite3_keyword_check("_nope_") ); + affirm( sqlite3_keyword_check("seLect") ); + affirm( null!=sqlite3_keyword_name(0) ); + affirm( null!=sqlite3_keyword_name(n-1) ); + affirm( null==sqlite3_keyword_name(n) ); + } + + private void testBackup(){ + final sqlite3 dbDest = createNewDb(); + + try (sqlite3 dbSrc = createNewDb()) { + execSql(dbSrc, new String[]{ + "pragma page_size=512; VACUUM;", + "create table t(a);", + "insert into t(a) values(1),(2),(3);" + }); + affirm( null==sqlite3_backup_init(dbSrc,"main",dbSrc,"main") ); + try (sqlite3_backup b = sqlite3_backup_init(dbDest,"main",dbSrc,"main")) { + affirm( null!=b ); + affirm( b.getNativePointer()!=0 ); + int rc; + while( SQLITE_DONE!=(rc = sqlite3_backup_step(b, 1)) ){ + affirm( 0==rc ); + } + affirm( sqlite3_backup_pagecount(b) > 0 ); + rc = sqlite3_backup_finish(b); + affirm( 0==rc ); + affirm( b.getNativePointer()==0 ); + } + } + + try (sqlite3_stmt stmt = prepare(dbDest,"SELECT sum(a) from t")) { + sqlite3_step(stmt); + affirm( sqlite3_column_int(stmt,0) == 6 ); + } + sqlite3_close_v2(dbDest); + } + + private void testRandomness(){ + byte[] foo = new byte[20]; + int i = 0; + for( byte b : foo ){ + i += b; + } + affirm( i==0 ); + sqlite3_randomness(foo); + for( byte b : foo ){ + if(b!=0) ++i; + } + affirm( i!=0, "There's a very slight chance that 0 is actually correct." ); + } + + private void testBlobOpen(){ + final sqlite3 db = createNewDb(); + + execSql(db, "CREATE TABLE T(a BLOB);" + +"INSERT INTO t(rowid,a) VALUES(1, 'def'),(2, 'XYZ');" + ); + final OutputPointer.sqlite3_blob pOut = new OutputPointer.sqlite3_blob(); + int rc = sqlite3_blob_open(db, "main", "t", "a", + sqlite3_last_insert_rowid(db), 1, pOut); + affirm( 0==rc ); + sqlite3_blob b = pOut.take(); + affirm( null!=b ); + affirm( 0!=b.getNativePointer() ); + affirm( 3==sqlite3_blob_bytes(b) ); + rc = sqlite3_blob_write( b, new byte[] {100, 101, 102 /*"DEF"*/}, 0); + affirm( 0==rc ); + rc = sqlite3_blob_close(b); + affirm( 0==rc ); + rc = sqlite3_blob_close(b); + affirm( 0!=rc ); + affirm( 0==b.getNativePointer() ); + sqlite3_stmt stmt = prepare(db,"SELECT length(a), a FROM t ORDER BY a"); + affirm( SQLITE_ROW == sqlite3_step(stmt) ); + affirm( 3 == sqlite3_column_int(stmt,0) ); + affirm( "def".equals(sqlite3_column_text16(stmt,1)) ); + sqlite3_finalize(stmt); + + b = sqlite3_blob_open(db, "main", "t", "a", + sqlite3_last_insert_rowid(db), 1); + affirm( null!=b ); + rc = sqlite3_blob_reopen(b, 2); + affirm( 0==rc ); + final byte[] tgt = new byte[3]; + rc = sqlite3_blob_read(b, tgt, 0); + affirm( 0==rc ); + affirm( 100==tgt[0] && 101==tgt[1] && 102==tgt[2], "DEF" ); + rc = sqlite3_blob_close(b); + affirm( 0==rc ); + sqlite3_close_v2(db); + } + + private void testPrepareMulti(){ + final sqlite3 db = createNewDb(); + final String[] sql = { + "create table t(","a)", + "; insert into t(a) values(1),(2),(3);", + "select a from t;" + }; + final List liStmt = new ArrayList(); + final PrepareMultiCallback proxy = new PrepareMultiCallback.StepAll(); + PrepareMultiCallback m = new PrepareMultiCallback() { + @Override public int call(sqlite3_stmt st){ + liStmt.add(st); + return proxy.call(st); + } + }; + int rc = sqlite3_prepare_multi(db, sql, m); + affirm( 0==rc ); + affirm( liStmt.size() == 3 ); + for( sqlite3_stmt st : liStmt ){ + sqlite3_finalize(st); + } + sqlite3_close_v2(db); + } + + /* Copy/paste/rename this to add new tests. */ + private void _testTemplate(){ + final sqlite3 db = createNewDb(); + sqlite3_stmt stmt = prepare(db,"SELECT 1"); + sqlite3_finalize(stmt); + sqlite3_close_v2(db); + } + + + @ManualTest /* we really only want to run this test manually */ + private void testSleep(){ + out("Sleeping briefly... "); + sqlite3_sleep(600); + outln("Woke up."); + } + + private void nap() throws InterruptedException { + if( takeNaps ){ + Thread.sleep(java.util.concurrent.ThreadLocalRandom.current().nextInt(3, 17), 0); + } + } + + @ManualTest /* because we only want to run this test on demand */ + private void testFail(){ + affirm( false, "Intentional failure." ); + } + + private void runTests(boolean fromThread) throws Exception { + if(false) showCompileOption(); + List mlist = testMethods; + affirm( null!=mlist ); + if( shuffle ){ + mlist = new ArrayList<>( testMethods.subList(0, testMethods.size()) ); + java.util.Collections.shuffle(mlist); + } + if( listRunTests ){ + synchronized(this.getClass()){ + if( !fromThread ){ + out("Initial test"," list: "); + for(java.lang.reflect.Method m : testMethods){ + out(m.getName()+" "); + } + outln(); + outln("(That list excludes some which are hard-coded to run.)"); + } + out("Running"," tests: "); + for(java.lang.reflect.Method m : mlist){ + out(m.getName()+" "); + } + outln(); + } + } + for(java.lang.reflect.Method m : mlist){ + nap(); + try{ + m.invoke(this); + }catch(java.lang.reflect.InvocationTargetException e){ + outln("FAILURE: ",m.getName(),"(): ", e.getCause()); + throw e; + } + } + synchronized( this.getClass() ){ + ++nTestRuns; + } + } + + public void run() { + try { + runTests(0!=this.tId); + }catch(Exception e){ + synchronized( listErrors ){ + listErrors.add(e); + } + }finally{ + affirm( sqlite3_java_uncache_thread() ); + affirm( !sqlite3_java_uncache_thread() ); + } + } + + /** + Runs the basic sqlite3 JNI binding sanity-check suite. + + CLI flags: + + -q|-quiet: disables most test output. + + -t|-thread N: runs the tests in N threads + concurrently. Default=1. + + -r|-repeat N: repeats the tests in a loop N times, each one + consisting of the -thread value's threads. + + -shuffle: randomizes the order of most of the test functions. + + -naps: sleep small random intervals between tests in order to add + some chaos for cross-thread contention. + + -list-tests: outputs the list of tests being run, minus some + which are hard-coded. This is noisy in multi-threaded mode. + + -fail: forces an exception to be thrown during the test run. Use + with -shuffle to make its appearance unpredictable. + + -v: emit some developer-mode info at the end. + */ + public static void main(String[] args) throws Exception { + Integer nThread = 1; + boolean doSomethingForDev = false; + Integer nRepeat = 1; + boolean forceFail = false; + boolean sqlLog = false; + boolean configLog = false; + boolean squelchTestOutput = false; + for( int i = 0; i < args.length; ){ + String arg = args[i++]; + if(arg.startsWith("-")){ + arg = arg.replaceFirst("-+",""); + if(arg.equals("v")){ + doSomethingForDev = true; + //listBoundMethods(); + }else if(arg.equals("t") || arg.equals("thread")){ + nThread = Integer.parseInt(args[i++]); + }else if(arg.equals("r") || arg.equals("repeat")){ + nRepeat = Integer.parseInt(args[i++]); + }else if(arg.equals("shuffle")){ + shuffle = true; + }else if(arg.equals("list-tests")){ + listRunTests = true; + }else if(arg.equals("fail")){ + forceFail = true; + }else if(arg.equals("sqllog")){ + sqlLog = true; + }else if(arg.equals("configlog")){ + configLog = true; + }else if(arg.equals("naps")){ + takeNaps = true; + }else if(arg.equals("q") || arg.equals("quiet")){ + squelchTestOutput = true; + }else{ + throw new IllegalArgumentException("Unhandled flag:"+arg); + } + } + } + + if( sqlLog ){ + if( sqlite3_compileoption_used("ENABLE_SQLLOG") ){ + final ConfigSqllogCallback log = new ConfigSqllogCallback() { + @Override public void call(sqlite3 db, String msg, int op){ + switch(op){ + case 0: outln("Opening db: ",db); break; + case 1: outln("SQL ",db,": ",msg); break; + case 2: outln("Closing db: ",db); break; + } + } + }; + int rc = sqlite3_config( log ); + affirm( 0==rc ); + rc = sqlite3_config( (ConfigSqllogCallback)null ); + affirm( 0==rc ); + rc = sqlite3_config( log ); + affirm( 0==rc ); + }else{ + outln("WARNING: -sqllog is not active because library was built ", + "without SQLITE_ENABLE_SQLLOG."); + } + } + if( configLog ){ + final ConfigLogCallback log = new ConfigLogCallback() { + @Override public void call(int code, String msg){ + outln("ConfigLogCallback: ",ResultCode.getEntryForInt(code),": ", msg); + }; + }; + int rc = sqlite3_config( log ); + affirm( 0==rc ); + rc = sqlite3_config( (ConfigLogCallback)null ); + affirm( 0==rc ); + rc = sqlite3_config( log ); + affirm( 0==rc ); + } + + quietMode = squelchTestOutput; + outln("If you just saw warning messages regarding CallStaticObjectMethod, ", + "you are very likely seeing the side effects of a known openjdk8 ", + "bug. It is unsightly but does not affect the library."); + + { + // Build list of tests to run from the methods named test*(). + testMethods = new ArrayList<>(); + int nSkipped = 0; + for(final java.lang.reflect.Method m : Tester1.class.getDeclaredMethods()){ + final String name = m.getName(); + if( name.equals("testFail") ){ + if( forceFail ){ + testMethods.add(m); + } + }else if( !m.isAnnotationPresent( ManualTest.class ) ){ + if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){ + if( 0==nSkipped++ ){ + out("Skipping tests in multi-thread mode:"); + } + out(" "+name+"()"); + }else if( name.startsWith("test") ){ + testMethods.add(m); + } + } + } + if( nSkipped>0 ) out("\n"); + } + + final long timeStart = System.currentTimeMillis(); + int nLoop = 0; + switch( sqlite3_threadsafe() ){ /* Sanity checking */ + case 0: + affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ), + "Could not switch to single-thread mode." ); + affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_MULTITHREAD ), + "Could switch to multithread mode." ); + affirm( SQLITE_ERROR==sqlite3_config( SQLITE_CONFIG_SERIALIZED ), + "Could not switch to serialized threading mode." ); + outln("This is a single-threaded build. Not using threads."); + nThread = 1; + break; + case 1: + case 2: + affirm( 0==sqlite3_config( SQLITE_CONFIG_SINGLETHREAD ), + "Could not switch to single-thread mode." ); + affirm( 0==sqlite3_config( SQLITE_CONFIG_MULTITHREAD ), + "Could not switch to multithread mode." ); + affirm( 0==sqlite3_config( SQLITE_CONFIG_SERIALIZED ), + "Could not switch to serialized threading mode." ); + break; + default: + affirm( false, "Unhandled SQLITE_THREADSAFE value." ); + } + outln("libversion_number: ", + sqlite3_libversion_number(),"\n", + sqlite3_libversion(),"\n",SQLITE_SOURCE_ID,"\n", + "SQLITE_THREADSAFE=",sqlite3_threadsafe()); + final boolean showLoopCount = (nRepeat>1 && nThread>1); + if( showLoopCount ){ + outln("Running ",nRepeat," loop(s) with ",nThread," thread(s) each."); + } + if( takeNaps ) outln("Napping between tests is enabled."); + for( int n = 0; n < nRepeat; ++n ){ + ++nLoop; + if( showLoopCount ) out((1==nLoop ? "" : " ")+nLoop); + if( nThread<=1 ){ + new Tester1(0).runTests(false); + continue; + } + Tester1.mtMode = true; + final ExecutorService ex = Executors.newFixedThreadPool( nThread ); + for( int i = 0; i < nThread; ++i ){ + ex.submit( new Tester1(i), i ); + } + ex.shutdown(); + try{ + ex.awaitTermination(nThread*200, java.util.concurrent.TimeUnit.MILLISECONDS); + ex.shutdownNow(); + }catch (InterruptedException ie){ + ex.shutdownNow(); + Thread.currentThread().interrupt(); + } + if( !listErrors.isEmpty() ){ + quietMode = false; + outln("TEST ERRORS:"); + Exception err = null; + for( Exception e : listErrors ){ + e.printStackTrace(); + if( null==err ) err = e; + } + if( null!=err ) throw err; + } + } + if( showLoopCount ) outln(); + quietMode = false; + + final long timeEnd = System.currentTimeMillis(); + outln("Tests done. Metrics across ",nTestRuns," total iteration(s):"); + outln("\tAssertions checked: ",affirmCount); + outln("\tDatabases opened: ",metrics.dbOpen); + if( doSomethingForDev ){ + sqlite3_jni_internal_details(); + } + affirm( 0==sqlite3_release_memory(1) ); + sqlite3_shutdown(); + int nMethods = 0; + int nNatives = 0; + final java.lang.reflect.Method[] declaredMethods = + CApi.class.getDeclaredMethods(); + for(java.lang.reflect.Method m : declaredMethods){ + final int mod = m.getModifiers(); + if( 0!=(mod & java.lang.reflect.Modifier.STATIC) ){ + final String name = m.getName(); + if(name.startsWith("sqlite3_")){ + ++nMethods; + if( 0!=(mod & java.lang.reflect.Modifier.NATIVE) ){ + ++nNatives; + } + } + } + } + outln("\tCApi.sqlite3_*() methods: "+ + nMethods+" total, with "+ + nNatives+" native, "+ + (nMethods - nNatives)+" Java" + ); + outln("\tTotal test time = " + +(timeEnd - timeStart)+"ms"); + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,50 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; +import org.sqlite.jni.annotation.Nullable; + +/** + Callback for use with {@link CApi#sqlite3_trace_v2}. +*/ +public interface TraceV2Callback extends CallbackProxy { + /** + Called by sqlite3 for various tracing operations, as per + sqlite3_trace_v2(). Note that this interface elides the 2nd + argument to the native trace callback, as that role is better + filled by instance-local state. + +

These callbacks may throw, in which case their exceptions are + converted to C-level error information. + +

The 2nd argument to this function, if non-null, will be a an + sqlite3 or sqlite3_stmt object, depending on the first argument + (see below). + +

The final argument to this function is the "X" argument + documented for sqlite3_trace() and sqlite3_trace_v2(). Its type + depends on value of the first argument: + +

- SQLITE_TRACE_STMT: pNative is a sqlite3_stmt. pX is a String + containing the prepared SQL. + +

- SQLITE_TRACE_PROFILE: pNative is a sqlite3_stmt. pX is a Long + holding an approximate number of nanoseconds the statement took + to run. + +

- SQLITE_TRACE_ROW: pNative is a sqlite3_stmt. pX is null. + +

- SQLITE_TRACE_CLOSE: pNative is a sqlite3. pX is null. + */ + int call(int traceFlag, Object pNative, @Nullable Object pX); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for use with {@link CApi#sqlite3_update_hook}. +*/ +public interface UpdateHookCallback extends CallbackProxy { + /** + Must function as described for the C-level sqlite3_update_hook() + callback. + */ + void call(int opId, String dbName, String tableName, long rowId); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ValueHolder.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ValueHolder.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.capi; + +/** + A helper class which simply holds a single value. Its primary use + is for communicating values out of anonymous classes, as doing so + requires a "final" reference. +*/ +public class ValueHolder { + public T value; + public ValueHolder(){} + public ValueHolder(T v){value = v;} +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/WindowFunction.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/WindowFunction.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/WindowFunction.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/WindowFunction.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,39 @@ +/* +** 2023-08-25 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + + +/** + A SQLFunction implementation for window functions. Note that + WindowFunction inherits from {@link AggregateFunction} and each + instance is required to implement the inherited abstract methods + from that class. See {@link AggregateFunction} for information on + managing the UDF's invocation-specific state. +*/ +public abstract class WindowFunction extends AggregateFunction { + + /** + As for the xInverse() argument of the C API's + sqlite3_create_window_function(). If this function throws, the + exception is not propagated and a warning might be emitted + to a debugging channel. + */ + public abstract void xInverse(sqlite3_context cx, sqlite3_value[] args); + + /** + As for the xValue() argument of the C API's sqlite3_create_window_function(). + See xInverse() for the fate of any exceptions this throws. + */ + public abstract void xValue(sqlite3_context cx); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,37 @@ +/* +** 2023-07-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file declares JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.capi; + +/** + Callback for a hook called by SQLite when certain client-provided + state are destroyed. It gets its name from the pervasive use of + the symbol name xDestroy() for this purpose in the C API + documentation. +*/ +public interface XDestroyCallback { + /** + Must perform any cleanup required by this object. Must not + throw. Must not call back into the sqlite3 API, else it might + invoke a deadlock. + + WARNING: as a rule, it is never safe to register individual + instances with this interface multiple times in the + library. e.g., do not register the same CollationCallback with + multiple arities or names using sqlite3_create_collation(). If + this rule is violated, the library will eventually try to free + each individual reference, leading to memory corruption or a + crash via duplicate free(). + */ + public void xDestroy(); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/fts5_api.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/fts5_api.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/fts5_api.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/fts5_api.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,76 @@ +/* +** 2023-08-05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; +import org.sqlite.jni.annotation.*; +import org.sqlite.jni.capi.*; + +/** + A wrapper for communicating C-level (fts5_api*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java and C + via JNI. +*/ +public final class fts5_api extends NativePointerHolder { + /* Only invoked from JNI */ + private fts5_api(){} + + public static final int iVersion = 2; + + /** + Returns the fts5_api instance associated with the given db, or + null if something goes horribly wrong. + */ + public static synchronized native fts5_api getInstanceForDb(@NotNull sqlite3 db); + + public synchronized native int xCreateFunction(@NotNull String name, + @Nullable Object userData, + @NotNull fts5_extension_function xFunction); + + /** + Convenience overload which passes null as the 2nd argument to the + 3-parameter form. + */ + public int xCreateFunction(@NotNull String name, + @NotNull fts5_extension_function xFunction){ + return xCreateFunction(name, null, xFunction); + } + + // /* Create a new auxiliary function */ + // int (*xCreateFunction)( + // fts5_api *pApi, + // const char *zName, + // void *pContext, + // fts5_extension_function xFunction, + // void (*xDestroy)(void*) + // ); + + // Still potentially todo: + + // int (*xCreateTokenizer)( + // fts5_api *pApi, + // const char *zName, + // void *pContext, + // fts5_tokenizer *pTokenizer, + // void (*xDestroy)(void*) + // ); + + // /* Find an existing tokenizer */ + // int (*xFindTokenizer)( + // fts5_api *pApi, + // const char *zName, + // void **ppContext, + // fts5_tokenizer *pTokenizer + // ); + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,24 @@ +/* +** 2023-08-04 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; +import org.sqlite.jni.capi.*; + +/** + A wrapper for communicating C-level (Fts5Context*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java and C + via JNI. +*/ +public final class Fts5Context extends NativePointerHolder { +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,97 @@ +/* +** 2023-08-04 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; +import java.nio.charset.StandardCharsets; +import org.sqlite.jni.capi.*; +import org.sqlite.jni.annotation.*; + +/** +*/ +public final class Fts5ExtensionApi extends NativePointerHolder { + //! Only called from JNI + private Fts5ExtensionApi(){} + private final int iVersion = 2; + + /* Callback type for used by xQueryPhrase(). */ + public static interface XQueryPhraseCallback { + int call(Fts5ExtensionApi fapi, Fts5Context cx); + } + + /** + Returns the singleton instance of this class. + */ + public static native Fts5ExtensionApi getInstance(); + + public native int xColumnCount(@NotNull Fts5Context fcx); + + public native int xColumnSize(@NotNull Fts5Context cx, int iCol, + @NotNull OutputPointer.Int32 pnToken); + + public native int xColumnText(@NotNull Fts5Context cx, int iCol, + @NotNull OutputPointer.String txt); + + public native int xColumnTotalSize(@NotNull Fts5Context fcx, int iCol, + @NotNull OutputPointer.Int64 pnToken); + + public native Object xGetAuxdata(@NotNull Fts5Context cx, boolean clearIt); + + public native int xInst(@NotNull Fts5Context cx, int iIdx, + @NotNull OutputPointer.Int32 piPhrase, + @NotNull OutputPointer.Int32 piCol, + @NotNull OutputPointer.Int32 piOff); + + public native int xInstCount(@NotNull Fts5Context fcx, + @NotNull OutputPointer.Int32 pnInst); + + public native int xPhraseCount(@NotNull Fts5Context fcx); + + public native int xPhraseFirst(@NotNull Fts5Context cx, int iPhrase, + @NotNull Fts5PhraseIter iter, + @NotNull OutputPointer.Int32 iCol, + @NotNull OutputPointer.Int32 iOff); + + public native int xPhraseFirstColumn(@NotNull Fts5Context cx, int iPhrase, + @NotNull Fts5PhraseIter iter, + @NotNull OutputPointer.Int32 iCol); + public native void xPhraseNext(@NotNull Fts5Context cx, + @NotNull Fts5PhraseIter iter, + @NotNull OutputPointer.Int32 iCol, + @NotNull OutputPointer.Int32 iOff); + public native void xPhraseNextColumn(@NotNull Fts5Context cx, + @NotNull Fts5PhraseIter iter, + @NotNull OutputPointer.Int32 iCol); + public native int xPhraseSize(@NotNull Fts5Context fcx, int iPhrase); + + public native int xQueryPhrase(@NotNull Fts5Context cx, int iPhrase, + @NotNull XQueryPhraseCallback callback); + public native int xRowCount(@NotNull Fts5Context fcx, + @NotNull OutputPointer.Int64 nRow); + + public native long xRowid(@NotNull Fts5Context cx); + /* Note that the JNI binding lacks the C version's xDelete() + callback argument. Instead, if pAux has an xDestroy() method, it + is called if the FTS5 API finalizes the aux state (including if + allocation of storage for the auxdata fails). Any reference to + pAux held by the JNI layer will be relinquished regardless of + whether pAux has an xDestroy() method. */ + + public native int xSetAuxdata(@NotNull Fts5Context cx, @Nullable Object pAux); + + public native int xTokenize(@NotNull Fts5Context cx, @NotNull byte[] pText, + @NotNull XTokenizeCallback callback); + + public native Object xUserData(Fts5Context cx); + //^^^ returns the pointer passed as the 3rd arg to the C-level + // fts5_api::xCreateFunction(). +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,47 @@ +/* +** 2023-08-05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; + +/** + JNI-level wrapper for C's fts5_extension_function type. +*/ +public interface fts5_extension_function { + // typedef void (*fts5_extension_function)( + // const Fts5ExtensionApi *pApi, /* API offered by current FTS version */ + // Fts5Context *pFts, /* First arg to pass to pApi functions */ + // sqlite3_context *pCtx, /* Context for returning result/error */ + // int nVal, /* Number of values in apVal[] array */ + // sqlite3_value **apVal /* Array of trailing arguments */ + // ); + + /** + The callback implementation, corresponding to the xFunction + argument of C's fts5_api::xCreateFunction(). + */ + void call(Fts5ExtensionApi ext, Fts5Context fCx, + sqlite3_context pCx, sqlite3_value argv[]); + /** + Is called when this function is destroyed by sqlite3. Typically + this function will be empty. + */ + void xDestroy(); + + public static abstract class Abstract implements fts5_extension_function { + @Override public abstract void call(Fts5ExtensionApi ext, Fts5Context fCx, + sqlite3_context pCx, sqlite3_value argv[]); + @Override public void xDestroy(){} + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,32 @@ +/* +** 2023-08-05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; + +/** + INCOMPLETE AND COMPLETELY UNTESTED. + + A utility object for holding FTS5-specific types and constants + which are used by multiple FTS5 classes. +*/ +public final class Fts5 { + /* Not used */ + private Fts5(){} + + + public static final int FTS5_TOKENIZE_QUERY = 0x0001; + public static final int FTS5_TOKENIZE_PREFIX = 0x0002; + public static final int FTS5_TOKENIZE_DOCUMENT = 0x0004; + public static final int FTS5_TOKENIZE_AUX = 0x0008; + public static final int FTS5_TOKEN_COLOCATED = 0x0001; +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-08-04 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; +import org.sqlite.jni.capi.NativePointerHolder; + +/** + A wrapper for C-level Fts5PhraseIter. They are only modified and + inspected by native-level code. +*/ +public final class Fts5PhraseIter extends NativePointerHolder { + //! Updated and used only by native code. + private long a; + private long b; +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,49 @@ +/* +** 2023-08-05 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; +import org.sqlite.jni.capi.NativePointerHolder; +import org.sqlite.jni.annotation.NotNull; + +/** + A wrapper for communicating C-level (fts5_tokenizer*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java and C + via JNI. +*/ +public final class fts5_tokenizer extends NativePointerHolder { + /* Only invoked by JNI */ + private fts5_tokenizer(){} + + // int (*xCreate)(void*, const char **azArg, int nArg, Fts5Tokenizer **ppOut); + // void (*xDelete)(Fts5Tokenizer*); + + public native int xTokenize(@NotNull Fts5Tokenizer t, int tokFlags, + @NotNull byte pText[], + @NotNull XTokenizeCallback callback); + + + // int (*xTokenize)(Fts5Tokenizer*, + // void *pCtx, + // int flags, /* Mask of FTS5_TOKENIZE_* flags */ + // const char *pText, int nText, + // int (*xToken)( + // void *pCtx, /* Copy of 2nd argument to xTokenize() */ + // int tflags, /* Mask of FTS5_TOKEN_* flags */ + // const char *pToken, /* Pointer to buffer containing token */ + // int nToken, /* Size of token in bytes */ + // int iStart, /* Byte offset of token within input text */ + // int iEnd /* Byte offset of end of token within input text */ + // ) + // ); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,31 @@ +/* +** 2023-08-05x +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; +import org.sqlite.jni.capi.NativePointerHolder; + +/** + INCOMPLETE AND COMPLETELY UNTESTED. + + A wrapper for communicating C-level (Fts5Tokenizer*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java and C + via JNI. + + At the C level, the Fts5Tokenizer type is essentially a void + pointer used specifically for tokenizers. +*/ +public final class Fts5Tokenizer extends NativePointerHolder { + //! Only called from JNI. + private Fts5Tokenizer(){} +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,832 @@ +/* +** 2023-08-04 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.fts5; +import static org.sqlite.jni.capi.CApi.*; +import static org.sqlite.jni.capi.Tester1.*; +import org.sqlite.jni.capi.*; +import org.sqlite.jni.fts5.*; + +import java.util.*; + +public class TesterFts5 { + + private static void test1(){ + final Fts5ExtensionApi fea = Fts5ExtensionApi.getInstance(); + affirm( null != fea ); + affirm( fea.getNativePointer() != 0 ); + affirm( fea == Fts5ExtensionApi.getInstance() )/*singleton*/; + + sqlite3 db = createNewDb(); + fts5_api fApi = fts5_api.getInstanceForDb(db); + affirm( fApi != null ); + affirm( fApi == fts5_api.getInstanceForDb(db) /* singleton per db */ ); + + execSql(db, new String[] { + "CREATE VIRTUAL TABLE ft USING fts5(a, b);", + "INSERT INTO ft(rowid, a, b) VALUES(1, 'X Y', 'Y Z');", + "INSERT INTO ft(rowid, a, b) VALUES(2, 'A Z', 'Y Y');" + }); + + final String pUserData = "This is pUserData"; + final int outputs[] = {0, 0}; + final fts5_extension_function func = new fts5_extension_function(){ + @Override public void call(Fts5ExtensionApi ext, Fts5Context fCx, + sqlite3_context pCx, sqlite3_value argv[]){ + final int nCols = ext.xColumnCount(fCx); + affirm( 2 == nCols ); + affirm( nCols == argv.length ); + affirm( ext.xUserData(fCx) == pUserData ); + final OutputPointer.String op = new OutputPointer.String(); + final OutputPointer.Int32 colsz = new OutputPointer.Int32(); + final OutputPointer.Int64 colTotalSz = new OutputPointer.Int64(); + for(int i = 0; i < nCols; ++i ){ + int rc = ext.xColumnText(fCx, i, op); + affirm( 0 == rc ); + final String val = op.value; + affirm( val.equals(sqlite3_value_text16(argv[i])) ); + rc = ext.xColumnSize(fCx, i, colsz); + affirm( 0==rc ); + affirm( 3==sqlite3_value_bytes(argv[i]) ); + rc = ext.xColumnTotalSize(fCx, i, colTotalSz); + affirm( 0==rc ); + } + ++outputs[0]; + } + public void xDestroy(){ + outputs[1] = 1; + } + }; + + int rc = fApi.xCreateFunction("myaux", pUserData, func); + affirm( 0==rc ); + + affirm( 0==outputs[0] ); + execSql(db, "select myaux(ft,a,b) from ft;"); + affirm( 2==outputs[0] ); + affirm( 0==outputs[1] ); + sqlite3_close_v2(db); + affirm( 1==outputs[1] ); + } + + /* + ** Argument sql is a string containing one or more SQL statements + ** separated by ";" characters. This function executes each of these + ** statements against the database passed as the first argument. If + ** no error occurs, the results of the SQL script are returned as + ** an array of strings. If an error does occur, a RuntimeException is + ** thrown. + */ + private static String[] sqlite3_exec(sqlite3 db, String sql) { + List aOut = new ArrayList(); + + /* Iterate through the list of SQL statements. For each, step through + ** it and add any results to the aOut[] array. */ + int rc = sqlite3_prepare_multi(db, sql, new PrepareMultiCallback() { + @Override public int call(sqlite3_stmt pStmt){ + while( SQLITE_ROW==sqlite3_step(pStmt) ){ + int ii; + for(ii=0; ii, ); + */ + class fts5_aux implements fts5_extension_function { + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length>1 ){ + throw new RuntimeException("fts5_aux: wrong number of args"); + } + + boolean bClear = (argv.length==1); + Object obj = ext.xGetAuxdata(fCx, bClear); + if( obj instanceof String ){ + sqlite3_result_text16(pCx, (String)obj); + } + + if( argv.length==1 ){ + String val = sqlite3_value_text16(argv[0]); + if( !val.equals("") ){ + ext.xSetAuxdata(fCx, val); + } + } + } + public void xDestroy(){ } + }; + + /* + ** fts5_inst(); + ** + ** This is used to test the xInstCount() and xInst() APIs. It returns a + ** text value containing a Tcl list with xInstCount() elements. Each + ** element is itself a list of 3 integers - the phrase number, column + ** number and token offset returned by each call to xInst(). + */ + fts5_extension_function fts5_inst = new fts5_extension_function(){ + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length!=0 ){ + throw new RuntimeException("fts5_inst: wrong number of args"); + } + + OutputPointer.Int32 pnInst = new OutputPointer.Int32(); + OutputPointer.Int32 piPhrase = new OutputPointer.Int32(); + OutputPointer.Int32 piCol = new OutputPointer.Int32(); + OutputPointer.Int32 piOff = new OutputPointer.Int32(); + String ret = new String(); + + int rc = ext.xInstCount(fCx, pnInst); + int nInst = pnInst.get(); + int ii; + + for(ii=0; rc==SQLITE_OK && ii0 ) ret += " "; + ret += "{"+piPhrase.get()+" "+piCol.get()+" "+piOff.get()+"}"; + } + + sqlite3_result_text(pCx, ret); + } + public void xDestroy(){ } + }; + + /* + ** fts5_pinst(); + ** + ** Like SQL function fts5_inst(), except using the following + ** + ** xPhraseCount + ** xPhraseFirst + ** xPhraseNext + */ + fts5_extension_function fts5_pinst = new fts5_extension_function(){ + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length!=0 ){ + throw new RuntimeException("fts5_pinst: wrong number of args"); + } + + OutputPointer.Int32 piCol = new OutputPointer.Int32(); + OutputPointer.Int32 piOff = new OutputPointer.Int32(); + String ret = new String(); + int rc = SQLITE_OK; + + int nPhrase = ext.xPhraseCount(fCx); + int ii; + + for(ii=0; rc==SQLITE_OK && ii=0; + ext.xPhraseNext(fCx, pIter, piCol, piOff) + ){ + if( !ret.equals("") ) ret += " "; + ret += "{"+ii+" "+piCol.get()+" "+piOff.get()+"}"; + } + } + + if( rc!=SQLITE_OK ){ + throw new RuntimeException("fts5_pinst: rc=" + rc); + }else{ + sqlite3_result_text(pCx, ret); + } + } + public void xDestroy(){ } + }; + + /* + ** fts5_pcolinst(); + ** + ** Like SQL function fts5_pinst(), except using the following + ** + ** xPhraseFirstColumn + ** xPhraseNextColumn + */ + fts5_extension_function fts5_pcolinst = new fts5_extension_function(){ + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length!=0 ){ + throw new RuntimeException("fts5_pcolinst: wrong number of args"); + } + + OutputPointer.Int32 piCol = new OutputPointer.Int32(); + String ret = new String(); + int rc = SQLITE_OK; + + int nPhrase = ext.xPhraseCount(fCx); + int ii; + + for(ii=0; rc==SQLITE_OK && ii=0; + ext.xPhraseNextColumn(fCx, pIter, piCol) + ){ + if( !ret.equals("") ) ret += " "; + ret += "{"+ii+" "+piCol.get()+"}"; + } + } + + if( rc!=SQLITE_OK ){ + throw new RuntimeException("fts5_pcolinst: rc=" + rc); + }else{ + sqlite3_result_text(pCx, ret); + } + } + public void xDestroy(){ } + }; + + /* + ** fts5_rowcount(); + */ + fts5_extension_function fts5_rowcount = new fts5_extension_function(){ + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length!=0 ){ + throw new RuntimeException("fts5_rowcount: wrong number of args"); + } + OutputPointer.Int64 pnRow = new OutputPointer.Int64(); + + int rc = ext.xRowCount(fCx, pnRow); + if( rc==SQLITE_OK ){ + sqlite3_result_int64(pCx, pnRow.get()); + }else{ + throw new RuntimeException("fts5_rowcount: rc=" + rc); + } + } + public void xDestroy(){ } + }; + + /* + ** fts5_phrasesize(); + */ + fts5_extension_function fts5_phrasesize = new fts5_extension_function(){ + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length!=1 ){ + throw new RuntimeException("fts5_phrasesize: wrong number of args"); + } + int iPhrase = sqlite3_value_int(argv[0]); + + int sz = ext.xPhraseSize(fCx, iPhrase); + sqlite3_result_int(pCx, sz); + } + public void xDestroy(){ } + }; + + /* + ** fts5_phrasehits(, ); + ** + ** Use the xQueryPhrase() API to determine how many hits, in total, + ** there are for phrase in the database. + */ + fts5_extension_function fts5_phrasehits = new fts5_extension_function(){ + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length!=1 ){ + throw new RuntimeException("fts5_phrasesize: wrong number of args"); + } + int iPhrase = sqlite3_value_int(argv[0]); + int rc = SQLITE_OK; + + class MyCallback implements Fts5ExtensionApi.XQueryPhraseCallback { + public int nRet = 0; + public int getRet() { return nRet; } + + @Override + public int call(Fts5ExtensionApi fapi, Fts5Context cx){ + OutputPointer.Int32 pnInst = new OutputPointer.Int32(); + int rc = fapi.xInstCount(cx, pnInst); + nRet += pnInst.get(); + return rc; + } + }; + + MyCallback xCall = new MyCallback(); + rc = ext.xQueryPhrase(fCx, iPhrase, xCall); + if( rc!=SQLITE_OK ){ + throw new RuntimeException("fts5_phrasehits: rc=" + rc); + } + sqlite3_result_int(pCx, xCall.getRet()); + } + public void xDestroy(){ } + }; + + /* + ** fts5_tokenize(, ) + */ + fts5_extension_function fts5_tokenize = new fts5_extension_function(){ + @Override public void call( + Fts5ExtensionApi ext, + Fts5Context fCx, + sqlite3_context pCx, + sqlite3_value argv[] + ){ + if( argv.length!=1 ){ + throw new RuntimeException("fts5_tokenize: wrong number of args"); + } + byte[] utf8 = sqlite3_value_text(argv[0]); + int rc = SQLITE_OK; + + class MyCallback implements XTokenizeCallback { + private List myList = new ArrayList(); + + public String getval() { + return String.join("+", myList); + } + + @Override + public int call(int tFlags, byte[] txt, int iStart, int iEnd){ + try { + String str = new String(txt, "UTF-8"); + myList.add(str); + } catch (Exception e) { + } + return SQLITE_OK; + } + }; + + MyCallback xCall = new MyCallback(); + ext.xTokenize(fCx, utf8, xCall); + sqlite3_result_text16(pCx, xCall.getval()); + + if( rc!=SQLITE_OK ){ + throw new RuntimeException("fts5_tokenize: rc=" + rc); + } + } + public void xDestroy(){ } + }; + + fts5_api api = fts5_api.getInstanceForDb(db); + api.xCreateFunction("fts5_rowid", fts5_rowid); + api.xCreateFunction("fts5_columncount", fts5_columncount); + api.xCreateFunction("fts5_columnsize", fts5_columnsize); + api.xCreateFunction("fts5_columntext", fts5_columntext); + api.xCreateFunction("fts5_columntotalsize", fts5_columntsize); + + api.xCreateFunction("fts5_aux1", new fts5_aux()); + api.xCreateFunction("fts5_aux2", new fts5_aux()); + + api.xCreateFunction("fts5_inst", fts5_inst); + api.xCreateFunction("fts5_pinst", fts5_pinst); + api.xCreateFunction("fts5_pcolinst", fts5_pcolinst); + api.xCreateFunction("fts5_rowcount", fts5_rowcount); + api.xCreateFunction("fts5_phrasesize", fts5_phrasesize); + api.xCreateFunction("fts5_phrasehits", fts5_phrasehits); + api.xCreateFunction("fts5_tokenize", fts5_tokenize); + } + /* + ** Test of various Fts5ExtensionApi methods + */ + private static void test2(){ + + /* Open db and populate an fts5 table */ + sqlite3 db = createNewDb(); + do_execsql_test(db, + "CREATE VIRTUAL TABLE ft USING fts5(a, b);" + + "INSERT INTO ft(rowid, a, b) VALUES(-9223372036854775808, 'x', 'x');" + + "INSERT INTO ft(rowid, a, b) VALUES(0, 'x', 'x');" + + "INSERT INTO ft(rowid, a, b) VALUES(1, 'x y z', 'x y z');" + + "INSERT INTO ft(rowid, a, b) VALUES(2, 'x y z', 'x z');" + + "INSERT INTO ft(rowid, a, b) VALUES(3, 'x y z', 'x y z');" + + "INSERT INTO ft(rowid, a, b) VALUES(9223372036854775807, 'x', 'x');" + ); + + create_test_functions(db); + + /* Test that fts5_rowid() seems to work */ + do_execsql_test(db, + "SELECT rowid==fts5_rowid(ft) FROM ft('x')", + "[1, 1, 1, 1, 1, 1]" + ); + + /* Test fts5_columncount() */ + do_execsql_test(db, + "SELECT fts5_columncount(ft) FROM ft('x')", + "[2, 2, 2, 2, 2, 2]" + ); + + /* Test fts5_columnsize() */ + do_execsql_test(db, + "SELECT fts5_columnsize(ft, 0) FROM ft('x') ORDER BY rowid", + "[1, 1, 3, 3, 3, 1]" + ); + do_execsql_test(db, + "SELECT fts5_columnsize(ft, 1) FROM ft('x') ORDER BY rowid", + "[1, 1, 3, 2, 3, 1]" + ); + do_execsql_test(db, + "SELECT fts5_columnsize(ft, -1) FROM ft('x') ORDER BY rowid", + "[2, 2, 6, 5, 6, 2]" + ); + + /* Test that xColumnSize() returns SQLITE_RANGE if the column number + ** is out-of range */ + try { + do_execsql_test(db, + "SELECT fts5_columnsize(ft, 2) FROM ft('x') ORDER BY rowid" + ); + } catch( RuntimeException e ){ + affirm( e.getMessage().matches(".*column index out of range") ); + } + + /* Test fts5_columntext() */ + do_execsql_test(db, + "SELECT fts5_columntext(ft, 0) FROM ft('x') ORDER BY rowid", + "[x, x, x y z, x y z, x y z, x]" + ); + do_execsql_test(db, + "SELECT fts5_columntext(ft, 1) FROM ft('x') ORDER BY rowid", + "[x, x, x y z, x z, x y z, x]" + ); + do_execsql_test(db, + "SELECT fts5_columntext(ft, 2) FROM ft('x') ORDER BY rowid", + "[null, null, null, null, null, null]" + ); + + /* Test fts5_columntotalsize() */ + do_execsql_test(db, + "SELECT fts5_columntotalsize(ft, 0) FROM ft('x') ORDER BY rowid", + "[12, 12, 12, 12, 12, 12]" + ); + do_execsql_test(db, + "SELECT fts5_columntotalsize(ft, 1) FROM ft('x') ORDER BY rowid", + "[11, 11, 11, 11, 11, 11]" + ); + do_execsql_test(db, + "SELECT fts5_columntotalsize(ft, -1) FROM ft('x') ORDER BY rowid", + "[23, 23, 23, 23, 23, 23]" + ); + + /* Test that xColumnTotalSize() returns SQLITE_RANGE if the column + ** number is out-of range */ + try { + do_execsql_test(db, + "SELECT fts5_columntotalsize(ft, 2) FROM ft('x') ORDER BY rowid" + ); + } catch( RuntimeException e ){ + affirm( e.getMessage().matches(".*column index out of range") ); + } + + do_execsql_test(db, + "SELECT rowid, fts5_rowcount(ft) FROM ft('z')", + "[1, 6, 2, 6, 3, 6]" + ); + + sqlite3_close_v2(db); + } + + /* + ** Test of various Fts5ExtensionApi methods + */ + private static void test3(){ + + /* Open db and populate an fts5 table */ + sqlite3 db = createNewDb(); + do_execsql_test(db, + "CREATE VIRTUAL TABLE ft USING fts5(a, b);" + + "INSERT INTO ft(a, b) VALUES('the one', 1);" + + "INSERT INTO ft(a, b) VALUES('the two', 2);" + + "INSERT INTO ft(a, b) VALUES('the three', 3);" + + "INSERT INTO ft(a, b) VALUES('the four', '');" + ); + create_test_functions(db); + + /* Test fts5_aux1() + fts5_aux2() - users of xGetAuxdata and xSetAuxdata */ + do_execsql_test(db, + "SELECT fts5_aux1(ft, a) FROM ft('the')", + "[null, the one, the two, the three]" + ); + do_execsql_test(db, + "SELECT fts5_aux2(ft, b) FROM ft('the')", + "[null, 1, 2, 3]" + ); + do_execsql_test(db, + "SELECT fts5_aux1(ft, a), fts5_aux2(ft, b) FROM ft('the')", + "[null, null, the one, 1, the two, 2, the three, 3]" + ); + do_execsql_test(db, + "SELECT fts5_aux1(ft, b), fts5_aux1(ft) FROM ft('the')", + "[null, 1, 1, 2, 2, 3, 3, null]" + ); + } + + /* + ** Test of various Fts5ExtensionApi methods + */ + private static void test4(){ + + /* Open db and populate an fts5 table */ + sqlite3 db = createNewDb(); + create_test_functions(db); + do_execsql_test(db, + "CREATE VIRTUAL TABLE ft USING fts5(a, b);" + + "INSERT INTO ft(a, b) VALUES('one two three', 'two three four');" + + "INSERT INTO ft(a, b) VALUES('two three four', 'three four five');" + + "INSERT INTO ft(a, b) VALUES('three four five', 'four five six');" + ); + + + do_execsql_test(db, + "SELECT fts5_inst(ft) FROM ft('two')", + "[{0 0 1} {0 1 0}, {0 0 0}]" + ); + do_execsql_test(db, + "SELECT fts5_inst(ft) FROM ft('four')", + "[{0 1 2}, {0 0 2} {0 1 1}, {0 0 1} {0 1 0}]" + ); + + do_execsql_test(db, + "SELECT fts5_inst(ft) FROM ft('a OR b OR four')", + "[{2 1 2}, {2 0 2} {2 1 1}, {2 0 1} {2 1 0}]" + ); + do_execsql_test(db, + "SELECT fts5_inst(ft) FROM ft('two four')", + "[{0 0 1} {0 1 0} {1 1 2}, {0 0 0} {1 0 2} {1 1 1}]" + ); + + do_execsql_test(db, + "SELECT fts5_pinst(ft) FROM ft('two')", + "[{0 0 1} {0 1 0}, {0 0 0}]" + ); + do_execsql_test(db, + "SELECT fts5_pinst(ft) FROM ft('four')", + "[{0 1 2}, {0 0 2} {0 1 1}, {0 0 1} {0 1 0}]" + ); + do_execsql_test(db, + "SELECT fts5_pinst(ft) FROM ft('a OR b OR four')", + "[{2 1 2}, {2 0 2} {2 1 1}, {2 0 1} {2 1 0}]" + ); + do_execsql_test(db, + "SELECT fts5_pinst(ft) FROM ft('two four')", + "[{0 0 1} {0 1 0} {1 1 2}, {0 0 0} {1 0 2} {1 1 1}]" + ); + + do_execsql_test(db, + "SELECT fts5_pcolinst(ft) FROM ft('two')", + "[{0 0} {0 1}, {0 0}]" + ); + do_execsql_test(db, + "SELECT fts5_pcolinst(ft) FROM ft('four')", + "[{0 1}, {0 0} {0 1}, {0 0} {0 1}]" + ); + do_execsql_test(db, + "SELECT fts5_pcolinst(ft) FROM ft('a OR b OR four')", + "[{2 1}, {2 0} {2 1}, {2 0} {2 1}]" + ); + do_execsql_test(db, + "SELECT fts5_pcolinst(ft) FROM ft('two four')", + "[{0 0} {0 1} {1 1}, {0 0} {1 0} {1 1}]" + ); + + do_execsql_test(db, + "SELECT fts5_phrasesize(ft, 0) FROM ft('four five six') LIMIT 1;", + "[1]" + ); + do_execsql_test(db, + "SELECT fts5_phrasesize(ft, 0) FROM ft('four + five + six') LIMIT 1;", + "[3]" + ); + + + sqlite3_close_v2(db); + } + + private static void test5(){ + /* Open db and populate an fts5 table */ + sqlite3 db = createNewDb(); + create_test_functions(db); + do_execsql_test(db, + "CREATE VIRTUAL TABLE ft USING fts5(x, b);" + + "INSERT INTO ft(x) VALUES('one two three four five six seven eight');" + + "INSERT INTO ft(x) VALUES('one two one four one six one eight');" + + "INSERT INTO ft(x) VALUES('one two three four five six seven eight');" + ); + + do_execsql_test(db, + "SELECT fts5_phrasehits(ft, 0) FROM ft('one') LIMIT 1", + "[6]" + ); + + sqlite3_close_v2(db); + } + + private static void test6(){ + sqlite3 db = createNewDb(); + create_test_functions(db); + do_execsql_test(db, + "CREATE VIRTUAL TABLE ft USING fts5(x, b);" + + "INSERT INTO ft(x) VALUES('one two three four five six seven eight');" + ); + + do_execsql_test(db, + "SELECT fts5_tokenize(ft, 'abc def ghi') FROM ft('one')", + "[abc+def+ghi]" + ); + do_execsql_test(db, + "SELECT fts5_tokenize(ft, 'it''s BEEN a...') FROM ft('one')", + "[it+s+been+a]" + ); + + sqlite3_close_v2(db); + } + + private static synchronized void runTests(){ + test1(); + test2(); + test3(); + test4(); + test5(); + test6(); + } + + public TesterFts5(){ + runTests(); + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,22 @@ +/* +** 2023-08-04 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the JNI bindings for the sqlite3 C API. +*/ +package org.sqlite.jni.fts5; + + +/** + Callback type for use with xTokenize() variants. +*/ +public interface XTokenizeCallback { + int call(int tFlags, byte[] txt, int iStart, int iEnd); +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/test-script-interpreter.md sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/test-script-interpreter.md --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/test-script-interpreter.md 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/test-script-interpreter.md 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,269 @@ +# Specifications For A Rudimentary SQLite Test Script Interpreter + +## Overview + +The purpose of the Test Script Interpreter is to read and interpret +script files that contain SQL commands and desired results. The +interpreter will check results and report an discrepencies found. + +The test script files are ASCII text files. The filename always ends with +".test". Each script is evaluated independently; context does not carry +forward from one script to the next. So, for example, the --null command +run in one test script does not cause any changes in the behavior of +subsequent test scripts. All open database connections are closed +at the end of each test script. All database files created by a test +script are deleted when the script finishes. + +## Parsing Rules: + + 1. The test script is read line by line, where a line is a sequence of + characters that runs up to the next '\\n' (0x0a) character or until + the end of the file. There is never a need to read ahead past the + end of the current line. + + 2. If any line contains the string " MODULE_NAME:" (with a space before + the initial "M") or "MIXED_MODULE_NAME:" then that test script is + incompatible with this spec. Processing of the test script should + end immediately. There is no need to read any more of the file. + In verbose mode, the interpreter might choose to emit an informational + messages saying that the test script was abandoned due to an + incompatible module type. + + 3. If any line contains the string "SCRIPT_MODULE_NAME:" then the input + script is known to be of the correct type for this specification and + processing may continue. The "MODULE_NAME" checking in steps 2 and 3 + may optionally be discontinued after sighting a "SCRIPT_MODULE_NAME". + + 4. If any line contains "REQUIRED_PROPERTIES:" and that substring is followed + by any non-whitespace text, then the script is not compatible with this + spec. Processing should stop immediately. In verbose mode, the + interpreter might choose to emit an information message saying that the + test script was abandoned due to unsupported requirement properties. + + 5. If any line begins with the "\|" (0x7c) character, that indicates that + the input script is not compatible with this specification. Processing + of the script should stop immediately. In verbose mode, the interpreter + might choose to emit an informational message indicating that the + test script was abandoned because it contained "a dbtotxt format database + specification". + + 6. Any line that begins with "#" is a C-preprocessor line. The interpreter + described by this spec does not know how to deal with C-preprocessor lines. + Hence, processing should be abandoned. In verbose mode, the interpreter + might emit an informational message similar to + "script NAME abandoned due to C-preprocessor line: ..." + + 7. If a line begins with exactly two minus signs followed by a + lowercase letter, that is a command. Process commands as described + below. + + 8. All other lines should be accumulated into the "input buffer". + The various commands will have access to this input buffer. + Some commands will reset the buffer. + +## Initialization + +The initial state of the interpreter at the start of processing each script +is as if the following command sequence had been run: + +> ~~~ +--close all +--db 0 +--new test.db +--null nil +~~~ + +In words, all database connections are closed except for connection 0 (the +default) which is open on an empty database named "test.db". The string +"nil" is displayed for NULL column values. + +The only context carried forward after the evaluation of one test script +into the evaluation of the next test script is the count of the number of +tests run and the number of failures seen. + +## Commands: + +Each command looks like an SQL comment. The command begins at the left +margin (no leading space) and starts with exactly 2 minus signs ("-"). +The command name consists of lowercase letters and maybe a "-" or two. +Some commands have arguments. +The arguments are separated from the command name by one or more spaces. + +Commands have access to the input buffer and might reset the input buffer. +The command can also optionally read (and consume) additional text from +script that comes after the command. + +Unknown or unrecognized commands indicate that the script contains features +that are not (yet) supported by this specification. Processing of the +script should terminate immediately. When this happens and when the +interpreter is in a "verbose" mode, the interpreter might choose to emit +an informational message along the lines of "test script NAME abandoned +due to unsupported command: --whatever". + +The initial implemention will only recognize a few commands. Other +commands may be added later. The following is the initial set of +commands: + +### The --testcase command + +Every test case starts with a --testcase command. The --testcase +command resets both the "input buffer" and the "result buffer". The +argument to the --testcase command is the name of the test case. That +test case name is used for logging and debugging and when printing +errors. The input buffer is set to the body of the test case. + +### The --result command + +The --result command tries to execute the text in the input buffer as SQL. +For each row of result coming out of this SQL, the text of that result is +appended to the "result buffer". If a result row contains multiple columns, +the columns are processed from left to right. For each column, text is +appended to the result buffer according to the following rules: + + * If the result buffer already contains some text, append a space. + (In this way, all column values and all row values are separated from + each other by a single space.) + + * If sqlite3_column_text() returns NULL, then append "nil" - or + some other text that is specified by the --null command - and skip + all subsequent rules. + + * If sqlite3_column_text() is an empty string, append `{}` to the + result buffer and skip all subsequent rules. + + * If sqlite3_column_text() does not contain any special + characters, append it to the result buffer without any + formatting and skip all subsequent rules. Special characters are: + 0x00 to 0x20 (inclusive), double-quote (0x22), backslash (0x5c), + curly braces (0x7b and 0x7d). + + * If sqlite3_column_text() does not contains curly braces, then put + the text inside of `{...}` and append it and skip all subsequent rules. + + * Append the text within double-quotes (`"..."`) and within the text + escape '"' and '\\' by prepending a single '\\' and escape any + control characters (characters less than 0x20) using octal notation: + '\\NNN'. + +If an error is encountered while running the SQL, then append the +symbolic C-preprocessor name for the error +code (ex: "SQLITE_CONSTRAINT") as if it were a column value. Then append +the error message text as if it where a column value. Then stop processing. + +After the SQL text has been run, compare the content of the result buffer +against the argument to the --result command and report a testing error if +there are any differences. + +The --result command resets the input buffer, but it does not reset +the result buffer. This distinction does not matter for the --result +command itself, but it is important for related commands like --glob +and --notglob. Sometimes test cases will contains a bunch of SQL +followed by multiple --glob and/or --notglob statements. All of the +globs should be evaluted agains the result buffer correct, but the SQL +should only be run once. This is accomplished by resetting the input +buffer but not the result buffer. + +### The --glob command + +The --glob command works just like --result except that the argument to +--glob is interpreted as a TEST-GLOB pattern and the results are compared +using that glob pattern rather than using strcmp(). Other than that, +the two operate the same. + +The TEST-GLOB pattern is slightly different for a standard GLOB: + + * The '*' character matches zero or more characters. + + * The '?' character matches any single character + + * The '[...]' character sequence machines a single character + in between the brackets. + + * The '#' character matches one or more digits (This is the main + difference between standard unix-glob and TEST-GLOB. unix-glob + does not have this feature. It was added to because it comes + up a lot during SQLite testing.) + +### The --notglob command + +The --notglob command works just like --glob except that it reports an +error if the GLOB does match, rather than if the GLOB does not matches. + +### The --oom command + +This command is to be used for out-of-memory testing. It means that +OOM errors should be simulated to ensure that SQLite is able to deal with +them. This command can be silently ignored for now. We might add support +for this later. + +### The --tableresult command + +The --tableresult command works like --glob except that the GLOB pattern +to be matched is taken from subsequent lines of the input script up to +the next --end. Every span of one or more whitespace characters in this +pattern text is collapsed into a single space (0x20). +Leading and trailing whitespace are removed from the pattern. +The --end that ends the GLOB pattern is not part of the GLOB pattern, but +the --end is consumed from the script input. + +### The --new and --open commands + +The --new and --open commands cause a database file to be opened. +The name of the file is the argument to the command. The --new command +opens an initially empty database (it deletes the file before opening it) +whereas the --open command opens an existing database if it already +exists. + +### The --db command + +The script interpreter can have up to 7 different SQLite database +connections open at a time. The --db command is used to switch between +them. The argument to --db is an integer between 0 and 6 that selects +which database connection to use moving forward. + +### The --close command + +The --close command causes an existing database connection to close. +This command is a no-op if the database connection is not currently +open. There can be up to 7 different database connections, numbered 0 +through 6. The number of the database connection to close is an +argument to the --close command, which will fail if an out-of-range +value is provided. Or if the argument to --close is "all" then all +open database connections are closed. If passed no argument, the +currently-active database is assumed. + +### The --null command + +The NULL command changes the text that is used to represent SQL NULL +values in the result buffer. + +### The --run command + +The --run command executes text in the input buffer as if it where SQL. +However, nothing is added to the result buffer. Any output from the SQL +is silently ignored. Errors in the SQL are silently ignored. + +The --run command normally executes the SQL in the current database +connection. However, if --run has an argument that is an integer between +0 and 6 then the SQL is run in the alternative database connection specified +by that argument. + +### The --json and --json-block commands + +The --json and --json-block commands work like --result and --tableresult, +respectively. The difference is that column values are appended to the +result buffer literally, without ever enclosing the values in `{...}` or +`"..."` and without escaping any characters in the column value and comparison +is always an exact strcmp() not a GLOB. + +### The --print command + +The --print command emits both its arguments and its body (if any) to +stdout, indenting each line of output. + +### The --column-names command + +The --column-names command requires 0 or 1 as an argument, to disable +resp. enable it, and modifies SQL execution to include column names +in output. When this option is on, each column value emitted gets +prefixed by its column name, with a single space between them. diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,82 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.annotation.*; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; + +/** + EXPERIMENTAL/INCOMPLETE/UNTESTED + + A SqlFunction implementation for aggregate functions. The T type + represents the type of data accumulated by this aggregate while it + works. e.g. a SUM()-like UDF might use Integer or Long and a + CONCAT()-like UDF might use a StringBuilder or a List. +*/ +public abstract class AggregateFunction implements SqlFunction { + + /** + As for the xStep() argument of the C API's + sqlite3_create_function(). If this function throws, the + exception is reported via sqlite3_result_error(). + */ + public abstract void xStep(SqlFunction.Arguments args); + + /** + As for the xFinal() argument of the C API's + sqlite3_create_function(). If this function throws, it is + translated into sqlite3_result_error(). + + Note that the passed-in object will not actually contain any + arguments for xFinal() but will contain the context object needed + for setting the call's result or error state. + */ + public abstract void xFinal(SqlFunction.Arguments args); + + /** + Optionally override to be notified when the UDF is finalized by + SQLite. + */ + public void xDestroy() {} + + /** Per-invocation state for the UDF. */ + private final SqlFunction.PerContextState map = + new SqlFunction.PerContextState<>(); + + /** + To be called from the implementation's xStep() method, as well + as the xValue() and xInverse() methods of the {@link WindowFunction} + subclass, to fetch the current per-call UDF state. On the + first call to this method for any given sqlite3_context + argument, the context is set to the given initial value. On all other + calls, the 2nd argument is ignored. + + @see SQLFunction.PerContextState#getAggregateState + */ + protected final ValueHolder getAggregateState(SqlFunction.Arguments args, T initialValue){ + return map.getAggregateState(args, initialValue); + } + + /** + To be called from the implementation's xFinal() method to fetch + the final state of the UDF and remove its mapping. + + see SQLFunction.PerContextState#takeAggregateState + */ + protected final T takeAggregateState(SqlFunction.Arguments args){ + return map.takeAggregateState(args); + } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,37 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.annotation.*; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; + +/** + The SqlFunction type for scalar SQL functions. +*/ +public abstract class ScalarFunction implements SqlFunction { + /** + As for the xFunc() argument of the C API's + sqlite3_create_function(). If this function throws, it is + translated into an sqlite3_result_error(). + */ + public abstract void xFunc(SqlFunction.Arguments args); + + /** + Optionally override to be notified when the UDF is finalized by + SQLite. This default implementation does nothing. + */ + public void xDestroy() {} + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,301 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.capi.sqlite3_context; +import org.sqlite.jni.capi.sqlite3_value; + +/** + Base marker interface for SQLite's three types of User-Defined SQL + Functions (UDFs): Scalar, Aggregate, and Window functions. +*/ +public interface SqlFunction { + + /** + The Arguments type is an abstraction on top of the lower-level + UDF function argument types. It provides _most_ of the functionality + of the lower-level interface, insofar as possible without "leaking" + those types into this API. + */ + public final static class Arguments implements Iterable{ + private final sqlite3_context cx; + private final sqlite3_value args[]; + public final int length; + + /** + Must be passed the context and arguments for the UDF call this + object is wrapping. Intended to be used by internal proxy + classes which "convert" the lower-level interface into this + package's higher-level interface, e.g. ScalarAdapter and + AggregateAdapter. + + Passing null for the args is equivalent to passing a length-0 + array. + */ + Arguments(sqlite3_context cx, sqlite3_value args[]){ + this.cx = cx; + this.args = args==null ? new sqlite3_value[0] : args;; + this.length = this.args.length; + } + + /** + Wrapper for a single SqlFunction argument. Primarily intended + for use with the Arguments class's Iterable interface. + */ + public final static class Arg { + private final Arguments a; + private final int ndx; + /* Only for use by the Arguments class. */ + private Arg(Arguments a, int ndx){ + this.a = a; + this.ndx = ndx; + } + /** Returns this argument's index in its parent argument list. */ + public int getIndex(){return ndx;} + public int getInt(){return a.getInt(ndx);} + public long getInt64(){return a.getInt64(ndx);} + public double getDouble(){return a.getDouble(ndx);} + public byte[] getBlob(){return a.getBlob(ndx);} + public byte[] getText(){return a.getText(ndx);} + public String getText16(){return a.getText16(ndx);} + public int getBytes(){return a.getBytes(ndx);} + public int getBytes16(){return a.getBytes16(ndx);} + public Object getObject(){return a.getObject(ndx);} + public T getObjectCasted(Class type){ return a.getObjectCasted(ndx, type); } + public int getType(){return a.getType(ndx);} + public Object getAuxData(){return a.getAuxData(ndx);} + public void setAuxData(Object o){a.setAuxData(ndx, o);} + } + + @Override + public java.util.Iterator iterator(){ + final Arg[] proxies = new Arg[args.length]; + for( int i = 0; i < args.length; ++i ){ + proxies[i] = new Arg(this, i); + } + return java.util.Arrays.stream(proxies).iterator(); + } + + /** + Returns the sqlite3_value at the given argument index or throws + an IllegalArgumentException exception if ndx is out of range. + */ + private sqlite3_value valueAt(int ndx){ + if(ndx<0 || ndx>=args.length){ + throw new IllegalArgumentException( + "SQL function argument index "+ndx+" is out of range." + ); + } + return args[ndx]; + } + + sqlite3_context getContext(){return cx;} + + public int getArgCount(){ return args.length; } + + public int getInt(int arg){return CApi.sqlite3_value_int(valueAt(arg));} + public long getInt64(int arg){return CApi.sqlite3_value_int64(valueAt(arg));} + public double getDouble(int arg){return CApi.sqlite3_value_double(valueAt(arg));} + public byte[] getBlob(int arg){return CApi.sqlite3_value_blob(valueAt(arg));} + public byte[] getText(int arg){return CApi.sqlite3_value_text(valueAt(arg));} + public String getText16(int arg){return CApi.sqlite3_value_text16(valueAt(arg));} + public int getBytes(int arg){return CApi.sqlite3_value_bytes(valueAt(arg));} + public int getBytes16(int arg){return CApi.sqlite3_value_bytes16(valueAt(arg));} + public Object getObject(int arg){return CApi.sqlite3_value_java_object(valueAt(arg));} + public T getObjectCasted(int arg, Class type){ + return CApi.sqlite3_value_java_casted(valueAt(arg), type); + } + + public int getType(int arg){return CApi.sqlite3_value_type(valueAt(arg));} + public int getSubtype(int arg){return CApi.sqlite3_value_subtype(valueAt(arg));} + public int getNumericType(int arg){return CApi.sqlite3_value_numeric_type(valueAt(arg));} + public int getNoChange(int arg){return CApi.sqlite3_value_nochange(valueAt(arg));} + public boolean getFromBind(int arg){return CApi.sqlite3_value_frombind(valueAt(arg));} + public int getEncoding(int arg){return CApi.sqlite3_value_encoding(valueAt(arg));} + + public void resultInt(int v){ CApi.sqlite3_result_int(cx, v); } + public void resultInt64(long v){ CApi.sqlite3_result_int64(cx, v); } + public void resultDouble(double v){ CApi.sqlite3_result_double(cx, v); } + public void resultError(String msg){CApi.sqlite3_result_error(cx, msg);} + public void resultError(Exception e){CApi.sqlite3_result_error(cx, e);} + public void resultErrorTooBig(){CApi.sqlite3_result_error_toobig(cx);} + public void resultErrorCode(int rc){CApi.sqlite3_result_error_code(cx, rc);} + public void resultObject(Object o){CApi.sqlite3_result_java_object(cx, o);} + public void resultNull(){CApi.sqlite3_result_null(cx);} + public void resultArg(int argNdx){CApi.sqlite3_result_value(cx, valueAt(argNdx));} + public void resultZeroBlob(long n){ + // Throw on error? If n is too big, + // sqlite3_result_error_toobig() is automatically called. + CApi.sqlite3_result_zeroblob64(cx, n); + } + + public void resultBlob(byte[] blob){CApi.sqlite3_result_blob(cx, blob);} + public void resultText(byte[] utf8){CApi.sqlite3_result_text(cx, utf8);} + public void resultText(String txt){CApi.sqlite3_result_text(cx, txt);} + public void resultText16(byte[] utf16){CApi.sqlite3_result_text16(cx, utf16);} + public void resultText16(String txt){CApi.sqlite3_result_text16(cx, txt);} + + public void setAuxData(int arg, Object o){ + /* From the API docs: https://www.sqlite.org/c3ref/get_auxdata.html + + The value of the N parameter to these interfaces should be + non-negative. Future enhancements may make use of negative N + values to define new kinds of function caching behavior. + */ + valueAt(arg); + CApi.sqlite3_set_auxdata(cx, arg, o); + } + + public Object getAuxData(int arg){ + valueAt(arg); + return CApi.sqlite3_get_auxdata(cx, arg); + } + } + + /** + PerContextState assists aggregate and window functions in + managing their accumulator state across calls to the UDF's + callbacks. + +

T must be of a type which can be legally stored as a value in + java.util.HashMap. + +

If a given aggregate or window function is called multiple times + in a single SQL statement, e.g. SELECT MYFUNC(A), MYFUNC(B)..., + then the clients need some way of knowing which call is which so + that they can map their state between their various UDF callbacks + and reset it via xFinal(). This class takes care of such + mappings. + +

This class works by mapping + sqlite3_context.getAggregateContext() to a single piece of + state, of a client-defined type (the T part of this class), which + persists across a "matching set" of the UDF's callbacks. + +

This class is a helper providing commonly-needed functionality + - it is not required for use with aggregate or window functions. + Client UDFs are free to perform such mappings using custom + approaches. The provided {@link AggregateFunction} and {@link + WindowFunction} classes use this. + */ + public static final class PerContextState { + private final java.util.Map> map + = new java.util.HashMap<>(); + + /** + Should be called from a UDF's xStep(), xValue(), and xInverse() + methods, passing it that method's first argument and an initial + value for the persistent state. If there is currently no + mapping for the given context within the map, one is created + using the given initial value, else the existing one is used + and the 2nd argument is ignored. It returns a ValueHolder + which can be used to modify that state directly without + requiring that the client update the underlying map's entry. + +

The caller is obligated to eventually call + takeAggregateState() to clear the mapping. + */ + public ValueHolder getAggregateState(SqlFunction.Arguments args, T initialValue){ + final Long key = args.getContext().getAggregateContext(true); + ValueHolder rc = null==key ? null : map.get(key); + if( null==rc ){ + map.put(key, rc = new ValueHolder<>(initialValue)); + } + return rc; + } + + /** + Should be called from a UDF's xFinal() method and passed that + method's first argument. This function removes the value + associated with with the arguments' aggregate context from the + map and returns it, returning null if no other UDF method has + been called to set up such a mapping. The latter condition will + be the case if a UDF is used in a statement which has no result + rows. + */ + public T takeAggregateState(SqlFunction.Arguments args){ + final ValueHolder h = map.remove(args.getContext().getAggregateContext(false)); + return null==h ? null : h.value; + } + } + + /** + Internal-use adapter for wrapping this package's ScalarFunction + for use with the org.sqlite.jni.capi.ScalarFunction interface. + */ + static final class ScalarAdapter extends org.sqlite.jni.capi.ScalarFunction { + final ScalarFunction impl; + ScalarAdapter(ScalarFunction impl){ + this.impl = impl; + } + /** + Proxies this.impl.xFunc(), adapting the call arguments to that + function's signature. If the proxy throws, it's translated to + sqlite_result_error() with the exception's message. + */ + public void xFunc(sqlite3_context cx, sqlite3_value[] args){ + try{ + impl.xFunc( new SqlFunction.Arguments(cx, args) ); + }catch(Exception e){ + CApi.sqlite3_result_error(cx, e); + } + } + + public void xDestroy(){ + impl.xDestroy(); + } + } + + /** + Internal-use adapter for wrapping this package's AggregateFunction + for use with the org.sqlite.jni.capi.AggregateFunction interface. + */ + static final class AggregateAdapter extends org.sqlite.jni.capi.AggregateFunction { + final AggregateFunction impl; + AggregateAdapter(AggregateFunction impl){ + this.impl = impl; + } + + /** + Proxies this.impl.xStep(), adapting the call arguments to that + function's signature. If the proxied function throws, it is + translated to sqlite_result_error() with the exception's + message. + */ + public void xStep(sqlite3_context cx, sqlite3_value[] args){ + try{ + impl.xStep( new SqlFunction.Arguments(cx, args) ); + }catch(Exception e){ + CApi.sqlite3_result_error(cx, e); + } + } + + /** + As for the xFinal() argument of the C API's sqlite3_create_function(). + If the proxied function throws, it is translated into a sqlite3_result_error(). + */ + public void xFinal(sqlite3_context cx){ + try{ + impl.xFinal( new SqlFunction.Arguments(cx, null) ); + }catch(Exception e){ + CApi.sqlite3_result_error(cx, e); + } + } + + public void xDestroy(){ + impl.xDestroy(); + } + } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,82 @@ +/* +** 2023-10-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import static org.sqlite.jni.capi.CApi.*; +import org.sqlite.jni.capi.sqlite3; + +/** + A wrapper for communicating C-level (sqlite3*) instances with + Java. These wrappers do not own their associated pointer, they + simply provide a type-safe way to communicate it between Java + and C via JNI. +*/ +public final class SqliteException extends java.lang.RuntimeException { + int errCode = SQLITE_ERROR; + int xerrCode = SQLITE_ERROR; + int errOffset = -1; + int sysErrno = 0; + + /** + Records the given error string and uses SQLITE_ERROR for both the + error code and extended error code. + */ + public SqliteException(String msg){ + super(msg); + } + + /** + Uses sqlite3_errstr(sqlite3ResultCode) for the error string and + sets both the error code and extended error code to the given + value. + */ + public SqliteException(int sqlite3ResultCode){ + super(sqlite3_errstr(sqlite3ResultCode)); + errCode = xerrCode = sqlite3ResultCode; + } + + /** + Records the current error state of db (which must not be null and + must refer to an opened db object). Note that this does NOT close + the db. + + Design note: closing the db on error is likely only useful during + a failed db-open operation, and the place(s) where that can + happen are inside this library, not client-level code. + */ + SqliteException(sqlite3 db){ + super(sqlite3_errmsg(db)); + errCode = sqlite3_errcode(db); + xerrCode = sqlite3_extended_errcode(db); + errOffset = sqlite3_error_offset(db); + sysErrno = sqlite3_system_errno(db); + } + + /** + Records the current error state of db (which must not be null and + must refer to an open database). + */ + public SqliteException(Sqlite db){ + this(db.nativeHandle()); + } + + public SqliteException(Sqlite.Stmt stmt){ + this( stmt.db() ); + } + + public int errcode(){ return errCode; } + public int extendedErrcode(){ return xerrCode; } + public int errorOffset(){ return errOffset; } + public int systemErrno(){ return sysErrno; } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,218 @@ +/* +** 2023-10-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file is part of the wrapper1 interface for sqlite3. +*/ +package org.sqlite.jni.wrapper1; +import java.nio.charset.StandardCharsets; +import static org.sqlite.jni.capi.CApi.*; +import org.sqlite.jni.capi.CApi; +import org.sqlite.jni.capi.sqlite3; +import org.sqlite.jni.capi.sqlite3_stmt; +import org.sqlite.jni.capi.OutputPointer; + +/** + This class represents a database connection, analog to the C-side + sqlite3 class but with added argument validation, exceptions, and + similar "smoothing of sharp edges" to make the API safe to use from + Java. It also acts as a namespace for other types for which + individual instances are tied to a specific database connection. +*/ +public final class Sqlite implements AutoCloseable { + private sqlite3 db; + + //! Used only by the open() factory functions. + private Sqlite(sqlite3 db){ + this.db = db; + } + + /** + Returns a newly-opened db connection or throws SqliteException if + opening fails. All arguments are as documented for + sqlite3_open_v2(). + + Design question: do we want static factory functions or should + this be reformulated as a constructor? + */ + public static Sqlite open(String filename, int flags, String vfsName){ + final OutputPointer.sqlite3 out = new OutputPointer.sqlite3(); + final int rc = sqlite3_open_v2(filename, out, flags, vfsName); + final sqlite3 n = out.take(); + if( 0!=rc ){ + if( null==n ) throw new SqliteException(rc); + final SqliteException ex = new SqliteException(n); + n.close(); + throw ex; + } + return new Sqlite(n); + } + + public static Sqlite open(String filename, int flags){ + return open(filename, flags, null); + } + + public static Sqlite open(String filename){ + return open(filename, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE, null); + } + + @Override public void close(){ + if(null!=this.db){ + this.db.close(); + this.db = null; + } + } + + /** + Returns this object's underlying native db handle, or null if + this instance has been closed. This is very specifically not + public. + */ + sqlite3 nativeHandle(){ return this.db; } + + private sqlite3 affirmOpen(){ + if( null==db || 0==db.getNativePointer() ){ + throw new IllegalArgumentException("This database instance is closed."); + } + return this.db; + } + + // private byte[] stringToUtf8(String s){ + // return s==null ? null : s.getBytes(StandardCharsets.UTF_8); + // } + + private void affirmRcOk(int rc){ + if( 0!=rc ){ + throw new SqliteException(db); + } + } + + /** + Corresponds to the sqlite3_stmt class. Use Sqlite.prepare() to + create new instances. + */ + public final class Stmt implements AutoCloseable { + private Sqlite _db = null; + private sqlite3_stmt stmt = null; + /** Only called by the prepare() factory functions. */ + Stmt(Sqlite db, sqlite3_stmt stmt){ + this._db = db; + this.stmt = stmt; + } + + sqlite3_stmt nativeHandle(){ + return stmt; + } + + private sqlite3_stmt affirmOpen(){ + if( null==stmt || 0==stmt.getNativePointer() ){ + throw new IllegalArgumentException("This Stmt has been finalized."); + } + return stmt; + } + + /** + Corresponds to sqlite3_finalize(), but we cannot override the + name finalize() here because this one requires a different + signature. It does not throw on error here because "destructors + do not throw." If it returns non-0, the object is still + finalized. + */ + public int finalizeStmt(){ + int rc = 0; + if( null!=stmt ){ + sqlite3_finalize(stmt); + stmt = null; + } + return rc; + } + + @Override public void close(){ + finalizeStmt(); + } + + /** + Throws if rc is any value other than 0, SQLITE_ROW, or + SQLITE_DONE, else returns rc. + */ + private int checkRc(int rc){ + switch(rc){ + case 0: + case SQLITE_ROW: + case SQLITE_DONE: return rc; + default: + throw new SqliteException(this); + } + } + + /** + Works like sqlite3_step() but throws SqliteException for any + result other than 0, SQLITE_ROW, or SQLITE_DONE. + */ + public int step(){ + return checkRc(sqlite3_step(affirmOpen())); + } + + public Sqlite db(){ return this._db; } + + /** + Works like sqlite3_reset() but throws on error. + */ + public void reset(){ + checkRc(sqlite3_reset(affirmOpen())); + } + + public void clearBindings(){ + sqlite3_clear_bindings( affirmOpen() ); + } + } + + + /** + prepare() TODOs include: + + - overloads taking byte[] and ByteBuffer. + + - multi-statement processing, like CApi.sqlite3_prepare_multi() + but using a callback specific to the higher-level Stmt class + rather than the sqlite3_stmt class. + */ + public Stmt prepare(String sql, int prepFlags){ + final OutputPointer.sqlite3_stmt out = new OutputPointer.sqlite3_stmt(); + final int rc = sqlite3_prepare_v3(affirmOpen(), sql, prepFlags, out); + affirmRcOk(rc); + return new Stmt(this, out.take()); + } + + public Stmt prepare(String sql){ + return prepare(sql, 0); + } + + public void createFunction(String name, int nArg, int eTextRep, ScalarFunction f ){ + int rc = CApi.sqlite3_create_function(affirmOpen(), name, nArg, eTextRep, + new SqlFunction.ScalarAdapter(f)); + if( 0!=rc ) throw new SqliteException(db); + } + + public void createFunction(String name, int nArg, ScalarFunction f){ + this.createFunction(name, nArg, CApi.SQLITE_UTF8, f); + } + + public void createFunction(String name, int nArg, int eTextRep, AggregateFunction f ){ + int rc = CApi.sqlite3_create_function(affirmOpen(), name, nArg, eTextRep, + new SqlFunction.AggregateAdapter(f)); + if( 0!=rc ) throw new SqliteException(db); + } + + public void createFunction(String name, int nArg, AggregateFunction f){ + this.createFunction(name, nArg, CApi.SQLITE_UTF8, f); + } + +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,584 @@ +/* +** 2023-10-09 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.wrapper1; +//import static org.sqlite.jni.capi.CApi.*; +import java.nio.charset.StandardCharsets; +import java.util.Arrays; +import java.util.ArrayList; +import java.util.List; +import java.util.concurrent.ExecutorService; +import java.util.concurrent.Executors; +import org.sqlite.jni.capi.*; + +/** + An annotation for Tester2 tests which we do not want to run in + reflection-driven test mode because either they are not suitable + for multi-threaded threaded mode or we have to control their execution + order. +*/ +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) +@interface ManualTest{} +/** + Annotation for Tester2 tests which mark those which must be skipped + in multi-threaded mode. +*/ +@java.lang.annotation.Retention(java.lang.annotation.RetentionPolicy.RUNTIME) +@java.lang.annotation.Target({java.lang.annotation.ElementType.METHOD}) +@interface SingleThreadOnly{} + +public class Tester2 implements Runnable { + //! True when running in multi-threaded mode. + private static boolean mtMode = false; + //! True to sleep briefly between tests. + private static boolean takeNaps = false; + //! True to shuffle the order of the tests. + private static boolean shuffle = false; + //! True to dump the list of to-run tests to stdout. + private static boolean listRunTests = false; + //! True to squelch all out() and outln() output. + private static boolean quietMode = false; + //! Total number of runTests() calls. + private static int nTestRuns = 0; + //! List of test*() methods to run. + private static List testMethods = null; + //! List of exceptions collected by run() + private static List listErrors = new ArrayList<>(); + private static final class Metrics { + //! Number of times createNewDb() (or equivalent) is invoked. + volatile int dbOpen = 0; + } + + //! Instance ID. + private Integer tId; + + Tester2(Integer id){ + tId = id; + } + + static final Metrics metrics = new Metrics(); + + public static synchronized void outln(){ + if( !quietMode ){ + System.out.println(""); + } + } + + public static synchronized void outPrefix(){ + if( !quietMode ){ + System.out.print(Thread.currentThread().getName()+": "); + } + } + + public static synchronized void outln(Object val){ + if( !quietMode ){ + outPrefix(); + System.out.println(val); + } + } + + public static synchronized void out(Object val){ + if( !quietMode ){ + System.out.print(val); + } + } + + @SuppressWarnings("unchecked") + public static synchronized void out(Object... vals){ + if( !quietMode ){ + outPrefix(); + for(Object v : vals) out(v); + } + } + + @SuppressWarnings("unchecked") + public static synchronized void outln(Object... vals){ + if( !quietMode ){ + out(vals); out("\n"); + } + } + + static volatile int affirmCount = 0; + public static synchronized int affirm(Boolean v, String comment){ + ++affirmCount; + if( false ) assert( v /* prefer assert over exception if it's enabled because + the JNI layer sometimes has to suppress exceptions, + so they might be squelched on their way back to the + top. */); + if( !v ) throw new RuntimeException(comment); + return affirmCount; + } + + public static void affirm(Boolean v){ + affirm(v, "Affirmation failed."); + } + + + public static void execSql(Sqlite db, String[] sql){ + execSql(db, String.join("", sql)); + } + + public static int execSql(Sqlite dbw, boolean throwOnError, String sql){ + final sqlite3 db = dbw.nativeHandle(); + OutputPointer.Int32 oTail = new OutputPointer.Int32(); + final byte[] sqlUtf8 = sql.getBytes(StandardCharsets.UTF_8); + int pos = 0, n = 1; + byte[] sqlChunk = sqlUtf8; + int rc = 0; + sqlite3_stmt stmt = null; + final OutputPointer.sqlite3_stmt outStmt = new OutputPointer.sqlite3_stmt(); + while(pos < sqlChunk.length){ + if(pos > 0){ + sqlChunk = Arrays.copyOfRange(sqlChunk, pos, + sqlChunk.length); + } + if( 0==sqlChunk.length ) break; + rc = CApi.sqlite3_prepare_v2(db, sqlChunk, outStmt, oTail); + if(throwOnError) affirm(0 == rc); + else if( 0!=rc ) break; + pos = oTail.value; + stmt = outStmt.take(); + if( null == stmt ){ + // empty statement was parsed. + continue; + } + affirm(0 != stmt.getNativePointer()); + while( CApi.SQLITE_ROW == (rc = CApi.sqlite3_step(stmt)) ){ + } + CApi.sqlite3_finalize(stmt); + affirm(0 == stmt.getNativePointer()); + if(0!=rc && CApi.SQLITE_ROW!=rc && CApi.SQLITE_DONE!=rc){ + break; + } + } + CApi.sqlite3_finalize(stmt); + if(CApi.SQLITE_ROW==rc || CApi.SQLITE_DONE==rc) rc = 0; + if( 0!=rc && throwOnError){ + throw new SqliteException(db); + } + return rc; + } + + static void execSql(Sqlite db, String sql){ + execSql(db, true, sql); + } + + @SingleThreadOnly /* because it's thread-agnostic */ + private void test1(){ + affirm(CApi.sqlite3_libversion_number() == CApi.SQLITE_VERSION_NUMBER); + } + + /* Copy/paste/rename this to add new tests. */ + private void _testTemplate(){ + //final sqlite3 db = createNewDb(); + //sqlite3_stmt stmt = prepare(db,"SELECT 1"); + //sqlite3_finalize(stmt); + //sqlite3_close_v2(db); + } + + private void nap() throws InterruptedException { + if( takeNaps ){ + Thread.sleep(java.util.concurrent.ThreadLocalRandom.current().nextInt(3, 17), 0); + } + } + + Sqlite openDb(String name){ + final Sqlite db = Sqlite.open(name, CApi.SQLITE_OPEN_READWRITE| + CApi.SQLITE_OPEN_CREATE| + CApi.SQLITE_OPEN_EXRESCODE); + ++metrics.dbOpen; + return db; + } + + Sqlite openDb(){ return openDb(":memory:"); } + + void testOpenDb1(){ + Sqlite db = openDb(); + affirm( 0!=db.nativeHandle().getNativePointer() ); + db.close(); + affirm( null==db.nativeHandle() ); + + SqliteException ex = null; + try { + db = openDb("/no/such/dir/.../probably"); + }catch(SqliteException e){ + ex = e; + } + affirm( ex!=null ); + affirm( ex.errcode() != 0 ); + affirm( ex.extendedErrcode() != 0 ); + affirm( ex.errorOffset() < 0 ); + // there's no reliable way to predict what ex.systemErrno() might be + } + + void testPrepare1(){ + try (Sqlite db = openDb()) { + Sqlite.Stmt stmt = db.prepare("SELECT 1"); + affirm( null!=stmt.nativeHandle() ); + affirm( CApi.SQLITE_ROW == stmt.step() ); + affirm( CApi.SQLITE_DONE == stmt.step() ); + stmt.reset(); + affirm( CApi.SQLITE_ROW == stmt.step() ); + affirm( CApi.SQLITE_DONE == stmt.step() ); + affirm( 0 == stmt.finalizeStmt() ); + affirm( null==stmt.nativeHandle() ); + + stmt = db.prepare("SELECT 1"); + affirm( CApi.SQLITE_ROW == stmt.step() ); + affirm( 0 == stmt.finalizeStmt() ) + /* getting a non-0 out of sqlite3_finalize() is tricky */; + affirm( null==stmt.nativeHandle() ); + } + } + + void testUdfScalar(){ + final ValueHolder xDestroyCalled = new ValueHolder<>(0); + try (Sqlite db = openDb()) { + execSql(db, "create table t(a); insert into t(a) values(1),(2),(3)"); + final ValueHolder vh = new ValueHolder<>(0); + final ScalarFunction f = new ScalarFunction(){ + public void xFunc(SqlFunction.Arguments args){ + for( SqlFunction.Arguments.Arg arg : args ){ + vh.value += arg.getInt(); + } + } + public void xDestroy(){ + ++xDestroyCalled.value; + } + }; + db.createFunction("myfunc", -1, f); + execSql(db, "select myfunc(1,2,3)"); + affirm( 6 == vh.value ); + vh.value = 0; + execSql(db, "select myfunc(-1,-2,-3)"); + affirm( -6 == vh.value ); + affirm( 0 == xDestroyCalled.value ); + } + affirm( 1 == xDestroyCalled.value ); + } + + void testUdfAggregate(){ + final ValueHolder xDestroyCalled = new ValueHolder<>(0); + final ValueHolder vh = new ValueHolder<>(0); + try (Sqlite db = openDb()) { + execSql(db, "create table t(a); insert into t(a) values(1),(2),(3)"); + final AggregateFunction f = new AggregateFunction(){ + public void xStep(SqlFunction.Arguments args){ + final ValueHolder agg = this.getAggregateState(args, 0); + for( SqlFunction.Arguments.Arg arg : args ){ + agg.value += arg.getInt(); + } + } + public void xFinal(SqlFunction.Arguments args){ + final Integer v = this.takeAggregateState(args); + if( null==v ) args.resultNull(); + else args.resultInt(v); + vh.value = v; + } + public void xDestroy(){ + ++xDestroyCalled.value; + } + }; + db.createFunction("myagg", -1, f); + execSql(db, "select myagg(a) from t"); + affirm( 6 == vh.value ); + affirm( 0 == xDestroyCalled.value ); + } + affirm( 1 == xDestroyCalled.value ); + } + + private void runTests(boolean fromThread) throws Exception { + List mlist = testMethods; + affirm( null!=mlist ); + if( shuffle ){ + mlist = new ArrayList<>( testMethods.subList(0, testMethods.size()) ); + java.util.Collections.shuffle(mlist); + } + if( listRunTests ){ + synchronized(this.getClass()){ + if( !fromThread ){ + out("Initial test"," list: "); + for(java.lang.reflect.Method m : testMethods){ + out(m.getName()+" "); + } + outln(); + outln("(That list excludes some which are hard-coded to run.)"); + } + out("Running"," tests: "); + for(java.lang.reflect.Method m : mlist){ + out(m.getName()+" "); + } + outln(); + } + } + for(java.lang.reflect.Method m : mlist){ + nap(); + try{ + m.invoke(this); + }catch(java.lang.reflect.InvocationTargetException e){ + outln("FAILURE: ",m.getName(),"(): ", e.getCause()); + throw e; + } + } + synchronized( this.getClass() ){ + ++nTestRuns; + } + } + + public void run() { + try { + runTests(0!=this.tId); + }catch(Exception e){ + synchronized( listErrors ){ + listErrors.add(e); + } + }finally{ + affirm( CApi.sqlite3_java_uncache_thread() ); + affirm( !CApi.sqlite3_java_uncache_thread() ); + } + } + + /** + Runs the basic sqlite3 JNI binding sanity-check suite. + + CLI flags: + + -q|-quiet: disables most test output. + + -t|-thread N: runs the tests in N threads + concurrently. Default=1. + + -r|-repeat N: repeats the tests in a loop N times, each one + consisting of the -thread value's threads. + + -shuffle: randomizes the order of most of the test functions. + + -naps: sleep small random intervals between tests in order to add + some chaos for cross-thread contention. + + -list-tests: outputs the list of tests being run, minus some + which are hard-coded. This is noisy in multi-threaded mode. + + -fail: forces an exception to be thrown during the test run. Use + with -shuffle to make its appearance unpredictable. + + -v: emit some developer-mode info at the end. + */ + public static void main(String[] args) throws Exception { + Integer nThread = 1; + boolean doSomethingForDev = false; + Integer nRepeat = 1; + boolean forceFail = false; + boolean sqlLog = false; + boolean configLog = false; + boolean squelchTestOutput = false; + for( int i = 0; i < args.length; ){ + String arg = args[i++]; + if(arg.startsWith("-")){ + arg = arg.replaceFirst("-+",""); + if(arg.equals("v")){ + doSomethingForDev = true; + //listBoundMethods(); + }else if(arg.equals("t") || arg.equals("thread")){ + nThread = Integer.parseInt(args[i++]); + }else if(arg.equals("r") || arg.equals("repeat")){ + nRepeat = Integer.parseInt(args[i++]); + }else if(arg.equals("shuffle")){ + shuffle = true; + }else if(arg.equals("list-tests")){ + listRunTests = true; + }else if(arg.equals("fail")){ + forceFail = true; + }else if(arg.equals("sqllog")){ + sqlLog = true; + }else if(arg.equals("configlog")){ + configLog = true; + }else if(arg.equals("naps")){ + takeNaps = true; + }else if(arg.equals("q") || arg.equals("quiet")){ + squelchTestOutput = true; + }else{ + throw new IllegalArgumentException("Unhandled flag:"+arg); + } + } + } + + if( sqlLog ){ + if( CApi.sqlite3_compileoption_used("ENABLE_SQLLOG") ){ + final ConfigSqllogCallback log = new ConfigSqllogCallback() { + @Override public void call(sqlite3 db, String msg, int op){ + switch(op){ + case 0: outln("Opening db: ",db); break; + case 1: outln("SQL ",db,": ",msg); break; + case 2: outln("Closing db: ",db); break; + } + } + }; + int rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( (ConfigSqllogCallback)null ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + }else{ + outln("WARNING: -sqllog is not active because library was built ", + "without SQLITE_ENABLE_SQLLOG."); + } + } + if( configLog ){ + final ConfigLogCallback log = new ConfigLogCallback() { + @Override public void call(int code, String msg){ + outln("ConfigLogCallback: ",ResultCode.getEntryForInt(code),": ", msg); + }; + }; + int rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( (ConfigLogCallback)null ); + affirm( 0==rc ); + rc = CApi.sqlite3_config( log ); + affirm( 0==rc ); + } + + quietMode = squelchTestOutput; + outln("If you just saw warning messages regarding CallStaticObjectMethod, ", + "you are very likely seeing the side effects of a known openjdk8 ", + "bug. It is unsightly but does not affect the library."); + + { + // Build list of tests to run from the methods named test*(). + testMethods = new ArrayList<>(); + int nSkipped = 0; + for(final java.lang.reflect.Method m : Tester2.class.getDeclaredMethods()){ + final String name = m.getName(); + if( name.equals("testFail") ){ + if( forceFail ){ + testMethods.add(m); + } + }else if( !m.isAnnotationPresent( ManualTest.class ) ){ + if( nThread>1 && m.isAnnotationPresent( SingleThreadOnly.class ) ){ + if( 0==nSkipped++ ){ + out("Skipping tests in multi-thread mode:"); + } + out(" "+name+"()"); + }else if( name.startsWith("test") ){ + testMethods.add(m); + } + } + } + if( nSkipped>0 ) out("\n"); + } + + final long timeStart = System.currentTimeMillis(); + int nLoop = 0; + switch( CApi.sqlite3_threadsafe() ){ /* Sanity checking */ + case 0: + affirm( CApi.SQLITE_ERROR==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SINGLETHREAD ), + "Could not switch to single-thread mode." ); + affirm( CApi.SQLITE_ERROR==CApi.sqlite3_config( CApi.SQLITE_CONFIG_MULTITHREAD ), + "Could switch to multithread mode." ); + affirm( CApi.SQLITE_ERROR==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SERIALIZED ), + "Could not switch to serialized threading mode." ); + outln("This is a single-threaded build. Not using threads."); + nThread = 1; + break; + case 1: + case 2: + affirm( 0==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SINGLETHREAD ), + "Could not switch to single-thread mode." ); + affirm( 0==CApi.sqlite3_config( CApi.SQLITE_CONFIG_MULTITHREAD ), + "Could not switch to multithread mode." ); + affirm( 0==CApi.sqlite3_config( CApi.SQLITE_CONFIG_SERIALIZED ), + "Could not switch to serialized threading mode." ); + break; + default: + affirm( false, "Unhandled SQLITE_THREADSAFE value." ); + } + outln("libversion_number: ", + CApi.sqlite3_libversion_number(),"\n", + CApi.sqlite3_libversion(),"\n",CApi.SQLITE_SOURCE_ID,"\n", + "SQLITE_THREADSAFE=",CApi.sqlite3_threadsafe()); + final boolean showLoopCount = (nRepeat>1 && nThread>1); + if( showLoopCount ){ + outln("Running ",nRepeat," loop(s) with ",nThread," thread(s) each."); + } + if( takeNaps ) outln("Napping between tests is enabled."); + for( int n = 0; n < nRepeat; ++n ){ + ++nLoop; + if( showLoopCount ) out((1==nLoop ? "" : " ")+nLoop); + if( nThread<=1 ){ + new Tester2(0).runTests(false); + continue; + } + Tester2.mtMode = true; + final ExecutorService ex = Executors.newFixedThreadPool( nThread ); + for( int i = 0; i < nThread; ++i ){ + ex.submit( new Tester2(i), i ); + } + ex.shutdown(); + try{ + ex.awaitTermination(nThread*200, java.util.concurrent.TimeUnit.MILLISECONDS); + ex.shutdownNow(); + }catch (InterruptedException ie){ + ex.shutdownNow(); + Thread.currentThread().interrupt(); + } + if( !listErrors.isEmpty() ){ + quietMode = false; + outln("TEST ERRORS:"); + Exception err = null; + for( Exception e : listErrors ){ + e.printStackTrace(); + if( null==err ) err = e; + } + if( null!=err ) throw err; + } + } + if( showLoopCount ) outln(); + quietMode = false; + + final long timeEnd = System.currentTimeMillis(); + outln("Tests done. Metrics across ",nTestRuns," total iteration(s):"); + outln("\tAssertions checked: ",affirmCount); + outln("\tDatabases opened: ",metrics.dbOpen); + if( doSomethingForDev ){ + CApi.sqlite3_jni_internal_details(); + } + affirm( 0==CApi.sqlite3_release_memory(1) ); + CApi.sqlite3_shutdown(); + int nMethods = 0; + int nNatives = 0; + int nCanonical = 0; + final java.lang.reflect.Method[] declaredMethods = + CApi.class.getDeclaredMethods(); + for(java.lang.reflect.Method m : declaredMethods){ + final int mod = m.getModifiers(); + if( 0!=(mod & java.lang.reflect.Modifier.STATIC) ){ + final String name = m.getName(); + if(name.startsWith("sqlite3_")){ + ++nMethods; + if( 0!=(mod & java.lang.reflect.Modifier.NATIVE) ){ + ++nNatives; + } + } + } + } + outln("\tCApi.sqlite3_*() methods: "+ + nMethods+" total, with "+ + nNatives+" native, "+ + (nMethods - nNatives)+" Java" + ); + outln("\tTotal test time = " + +(timeEnd - timeStart)+"ms"); + } +} diff -Nru sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java --- sqlite3-3.42.0/ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,25 @@ +/* +** 2023-10-16 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** This file contains a set of tests for the sqlite3 JNI bindings. +*/ +package org.sqlite.jni.wrapper1; + +/** + A helper class which simply holds a single value. Its primary use + is for communicating values out of anonymous classes, as doing so + requires a "final" reference. +*/ +public class ValueHolder { + public T value; + public ValueHolder(){} + public ValueHolder(T v){value = v;} +} diff -Nru sqlite3-3.42.0/ext/jni/src/tests/000-000-sanity.test sqlite3-3.44.0-0/ext/jni/src/tests/000-000-sanity.test --- sqlite3-3.42.0/ext/jni/src/tests/000-000-sanity.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/tests/000-000-sanity.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,53 @@ +/* +** This is a comment. There are many like it but this one is mine. +** +** SCRIPT_MODULE_NAME: sanity-check +** xMIXED_MODULE_NAME: mixed-module +** xMODULE_NAME: module-name +** xREQUIRED_PROPERTIES: small fast reliable +** xREQUIRED_PROPERTIES: RECURSIVE_TRIGGERS +** xREQUIRED_PROPERTIES: TEMPSTORE_FILE TEMPSTORE_MEM +** xREQUIRED_PROPERTIES: AUTOVACUUM INCRVACUUM +** +*/ +--print starting up 😃 +--close all +--oom +--db 0 +--new my.db +--null zilch +--testcase 1.0 +SELECT 1, null; +--result 1 zilch +--glob *zil* +--notglob *ZIL* +SELECT 1, 2; +intentional error; +--run +--testcase json-1 +SELECT json_array(1,2,3) +--json [1,2,3] +--testcase tableresult-1 + select 1, 'a'; + select 2, 'b'; +--tableresult + # [a-z] + 2 b +--end +--testcase json-block-1 + select json_array(1,2,3); + select json_object('a',1,'b',2); +--json-block + [1,2,3] + {"a":1,"b":2} +--end +--testcase col-names-on +--column-names 1 + select 1 as 'a', 2 as 'b'; +--result a 1 b 2 +--testcase col-names-off +--column-names 0 + select 1 as 'a', 2 as 'b'; +--result 1 2 +--close +--print reached the end 😃 diff -Nru sqlite3-3.42.0/ext/jni/src/tests/000-001-ignored.test sqlite3-3.44.0-0/ext/jni/src/tests/000-001-ignored.test --- sqlite3-3.42.0/ext/jni/src/tests/000-001-ignored.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/tests/000-001-ignored.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,9 @@ +/* +** This script must be marked as ignored because it contains +** content which triggers that condition. +** +** SCRIPT_MODULE_NAME: ignored +** +*/ + +| diff -Nru sqlite3-3.42.0/ext/jni/src/tests/900-001-fts.test sqlite3-3.44.0-0/ext/jni/src/tests/900-001-fts.test --- sqlite3-3.42.0/ext/jni/src/tests/900-001-fts.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/jni/src/tests/900-001-fts.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,12 @@ +/* +** SCRIPT_MODULE_NAME: fts5-sanity-checks +** xREQUIRED_PROPERTIES: FTS5 +** +*/ + +--testcase 1.0 +CREATE VIRTUAL TABLE email USING fts5(sender, title, body); +insert into email values('fred','Help!','Dear Sir...'); +insert into email values('barney','Assistance','Dear Madam...'); +select * from email where email match 'assistance'; +--result barney Assistance {Dear Madam...} diff -Nru sqlite3-3.42.0/ext/lsm1/lsm_vtab.c sqlite3-3.44.0-0/ext/lsm1/lsm_vtab.c --- sqlite3-3.42.0/ext/lsm1/lsm_vtab.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/lsm1/lsm_vtab.c 2023-11-04 14:23:58.000000000 +0000 @@ -1061,6 +1061,11 @@ lsm1Rollback, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; diff -Nru sqlite3-3.42.0/ext/misc/amatch.c sqlite3-3.44.0-0/ext/misc/amatch.c --- sqlite3-3.42.0/ext/misc/amatch.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/amatch.c 2023-11-04 14:23:58.000000000 +0000 @@ -1475,7 +1475,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff -Nru sqlite3-3.42.0/ext/misc/btreeinfo.c sqlite3-3.44.0-0/ext/misc/btreeinfo.c --- sqlite3-3.42.0/ext/misc/btreeinfo.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/btreeinfo.c 2023-11-04 14:23:58.000000000 +0000 @@ -411,7 +411,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "sqlite_btreeinfo", &binfo_module, 0); } diff -Nru sqlite3-3.42.0/ext/misc/carray.c sqlite3-3.44.0-0/ext/misc/carray.c --- sqlite3-3.42.0/ext/misc/carray.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/carray.c 2023-11-04 14:23:58.000000000 +0000 @@ -409,6 +409,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadow */ + 0 /* xIntegrity */ }; /* diff -Nru sqlite3-3.42.0/ext/misc/closure.c sqlite3-3.44.0-0/ext/misc/closure.c --- sqlite3-3.42.0/ext/misc/closure.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/closure.c 2023-11-04 14:23:58.000000000 +0000 @@ -939,7 +939,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff -Nru sqlite3-3.42.0/ext/misc/completion.c sqlite3-3.44.0-0/ext/misc/completion.c --- sqlite3-3.42.0/ext/misc/completion.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/completion.c 2023-11-04 14:23:58.000000000 +0000 @@ -470,7 +470,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff -Nru sqlite3-3.42.0/ext/misc/csv.c sqlite3-3.44.0-0/ext/misc/csv.c --- sqlite3-3.42.0/ext/misc/csv.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/csv.c 2023-11-04 14:23:58.000000000 +0000 @@ -897,6 +897,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #ifdef SQLITE_TEST @@ -929,6 +934,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_TEST */ diff -Nru sqlite3-3.42.0/ext/misc/decimal.c sqlite3-3.44.0-0/ext/misc/decimal.c --- sqlite3-3.42.0/ext/misc/decimal.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/decimal.c 2023-11-04 14:23:58.000000000 +0000 @@ -58,41 +58,24 @@ } /* -** Allocate a new Decimal object. Initialize it to the number given -** by the input string. +** Allocate a new Decimal object initialized to the text in zIn[]. +** Return NULL if any kind of error occurs. */ -static Decimal *decimal_new( - sqlite3_context *pCtx, - sqlite3_value *pIn, - int nAlt, - const unsigned char *zAlt -){ - Decimal *p; - int n, i; - const unsigned char *zIn; +static Decimal *decimalNewFromText(const char *zIn, int n){ + Decimal *p = 0; + int i; int iExp = 0; + p = sqlite3_malloc( sizeof(*p) ); - if( p==0 ) goto new_no_mem; + if( p==0 ) goto new_from_text_failed; p->sign = 0; p->oom = 0; p->isInit = 1; p->isNull = 0; p->nDigit = 0; p->nFrac = 0; - if( zAlt ){ - n = nAlt, - zIn = zAlt; - }else{ - if( sqlite3_value_type(pIn)==SQLITE_NULL ){ - p->a = 0; - p->isNull = 1; - return p; - } - n = sqlite3_value_bytes(pIn); - zIn = sqlite3_value_text(pIn); - } p->a = sqlite3_malloc64( n+1 ); - if( p->a==0 ) goto new_no_mem; + if( p->a==0 ) goto new_from_text_failed; for(i=0; isspace(zIn[i]); i++){} if( zIn[i]=='-' ){ p->sign = 1; @@ -143,7 +126,7 @@ } if( iExp>0 ){ p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); - if( p->a==0 ) goto new_no_mem; + if( p->a==0 ) goto new_from_text_failed; memset(p->a+p->nDigit, 0, iExp); p->nDigit += iExp; } @@ -162,7 +145,7 @@ } if( iExp>0 ){ p->a = sqlite3_realloc64(p->a, p->nDigit + iExp + 1 ); - if( p->a==0 ) goto new_no_mem; + if( p->a==0 ) goto new_from_text_failed; memmove(p->a+iExp, p->a, p->nDigit); memset(p->a, 0, iExp); p->nDigit += iExp; @@ -171,7 +154,76 @@ } return p; -new_no_mem: +new_from_text_failed: + if( p ){ + if( p->a ) sqlite3_free(p->a); + sqlite3_free(p); + } + return 0; +} + +/* Forward reference */ +static Decimal *decimalFromDouble(double); + +/* +** Allocate a new Decimal object from an sqlite3_value. Return a pointer +** to the new object, or NULL if there is an error. If the pCtx argument +** is not NULL, then errors are reported on it as well. +** +** If the pIn argument is SQLITE_TEXT or SQLITE_INTEGER, it is converted +** directly into a Decimal. For SQLITE_FLOAT or for SQLITE_BLOB of length +** 8 bytes, the resulting double value is expanded into its decimal equivalent. +** If pIn is NULL or if it is a BLOB that is not exactly 8 bytes in length, +** then NULL is returned. +*/ +static Decimal *decimal_new( + sqlite3_context *pCtx, /* Report error here, if not null */ + sqlite3_value *pIn, /* Construct the decimal object from this */ + int bTextOnly /* Always interpret pIn as text if true */ +){ + Decimal *p = 0; + int eType = sqlite3_value_type(pIn); + if( bTextOnly && (eType==SQLITE_FLOAT || eType==SQLITE_BLOB) ){ + eType = SQLITE_TEXT; + } + switch( eType ){ + case SQLITE_TEXT: + case SQLITE_INTEGER: { + const char *zIn = (const char*)sqlite3_value_text(pIn); + int n = sqlite3_value_bytes(pIn); + p = decimalNewFromText(zIn, n); + if( p==0 ) goto new_failed; + break; + } + + case SQLITE_FLOAT: { + p = decimalFromDouble(sqlite3_value_double(pIn)); + break; + } + + case SQLITE_BLOB: { + const unsigned char *x; + unsigned int i; + sqlite3_uint64 v = 0; + double r; + + if( sqlite3_value_bytes(pIn)!=sizeof(r) ) break; + x = sqlite3_value_blob(pIn); + for(i=0; ioom ){ + sqlite3_result_error_nomem(pCtx); + return; + } + if( p->isNull ){ + sqlite3_result_null(pCtx); + return; + } + for(nDigit=p->nDigit; nDigit>0 && p->a[nDigit-1]==0; nDigit--){} + for(nZero=0; nZeroa[nZero]==0; nZero++){} + nFrac = p->nFrac + (nDigit - p->nDigit); + nDigit -= nZero; + z = sqlite3_malloc( nDigit+20 ); + if( z==0 ){ + sqlite3_result_error_nomem(pCtx); + return; + } + if( nDigit==0 ){ + zero = 0; + a = &zero; + nDigit = 1; + nFrac = 0; + }else{ + a = &p->a[nZero]; + } + if( p->sign && nDigit>0 ){ + z[0] = '-'; + }else{ + z[0] = '+'; + } + z[1] = a[0]+'0'; + z[2] = '.'; + if( nDigit==1 ){ + z[3] = '0'; + i = 4; + }else{ + for(i=1; iisNull ) goto cmp_done; - pB = decimal_new(context, argv[1], 0, 0); + pB = decimal_new(context, argv[1], 1); if( pB==0 || pB->isNull ) goto cmp_done; rc = decimal_cmp(pA, pB); if( rc<0 ) rc = -1; @@ -338,7 +435,7 @@ } /* -** Add the value pB into pA. +** Add the value pB into pA. A := A + B. ** ** Both pA and pB might become denormalized by this routine. */ @@ -408,6 +505,172 @@ } /* +** Multiply A by B. A := A * B +** +** All significant digits after the decimal point are retained. +** Trailing zeros after the decimal point are omitted as long as +** the number of digits after the decimal point is no less than +** either the number of digits in either input. +*/ +static void decimalMul(Decimal *pA, Decimal *pB){ + signed char *acc = 0; + int i, j, k; + int minFrac; + + if( pA==0 || pA->oom || pA->isNull + || pB==0 || pB->oom || pB->isNull + ){ + goto mul_end; + } + acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 ); + if( acc==0 ){ + pA->oom = 1; + goto mul_end; + } + memset(acc, 0, pA->nDigit + pB->nDigit + 2); + minFrac = pA->nFrac; + if( pB->nFracnFrac; + for(i=pA->nDigit-1; i>=0; i--){ + signed char f = pA->a[i]; + int carry = 0, x; + for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){ + x = acc[k] + f*pB->a[j] + carry; + acc[k] = x%10; + carry = x/10; + } + x = acc[k] + carry; + acc[k] = x%10; + acc[k-1] += x/10; + } + sqlite3_free(pA->a); + pA->a = acc; + acc = 0; + pA->nDigit += pB->nDigit + 2; + pA->nFrac += pB->nFrac; + pA->sign ^= pB->sign; + while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){ + pA->nFrac--; + pA->nDigit--; + } + +mul_end: + sqlite3_free(acc); +} + +/* +** Create a new Decimal object that contains an integer power of 2. +*/ +static Decimal *decimalPow2(int N){ + Decimal *pA = 0; /* The result to be returned */ + Decimal *pX = 0; /* Multiplier */ + if( N<-20000 || N>20000 ) goto pow2_fault; + pA = decimalNewFromText("1.0", 3); + if( pA==0 || pA->oom ) goto pow2_fault; + if( N==0 ) return pA; + if( N>0 ){ + pX = decimalNewFromText("2.0", 3); + }else{ + N = -N; + pX = decimalNewFromText("0.5", 3); + } + if( pX==0 || pX->oom ) goto pow2_fault; + while( 1 /* Exit by break */ ){ + if( N & 1 ){ + decimalMul(pA, pX); + if( pA->oom ) goto pow2_fault; + } + N >>= 1; + if( N==0 ) break; + decimalMul(pX, pX); + } + decimal_free(pX); + return pA; + +pow2_fault: + decimal_free(pA); + decimal_free(pX); + return 0; +} + +/* +** Use an IEEE754 binary64 ("double") to generate a new Decimal object. +*/ +static Decimal *decimalFromDouble(double r){ + sqlite3_int64 m, a; + int e; + int isNeg; + Decimal *pA; + Decimal *pX; + char zNum[100]; + if( r<0.0 ){ + isNeg = 1; + r = -r; + }else{ + isNeg = 0; + } + memcpy(&a,&r,sizeof(a)); + if( a==0 ){ + e = 0; + m = 0; + }else{ + e = a>>52; + m = a & ((((sqlite3_int64)1)<<52)-1); + if( e==0 ){ + m <<= 1; + }else{ + m |= ((sqlite3_int64)1)<<52; + } + while( e<1075 && m>0 && (m&1)==0 ){ + m >>= 1; + e++; + } + if( isNeg ) m = -m; + e = e - 1075; + if( e>971 ){ + return 0; /* A NaN or an Infinity */ + } + } + + /* At this point m is the integer significand and e is the exponent */ + sqlite3_snprintf(sizeof(zNum), zNum, "%lld", m); + pA = decimalNewFromText(zNum, (int)strlen(zNum)); + pX = decimalPow2(e); + decimalMul(pA, pX); + decimal_free(pX); + return pA; +} + +/* +** SQL Function: decimal(X) +** OR: decimal_exp(X) +** +** Convert input X into decimal and then back into text. +** +** If X is originally a float, then a full decimal expansion of that floating +** point value is done. Or if X is an 8-byte blob, it is interpreted +** as a float and similarly expanded. +** +** The decimal_exp(X) function returns the result in exponential notation. +** decimal(X) returns a complete decimal, without the e+NNN at the end. +*/ +static void decimalFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + Decimal *p = decimal_new(context, argv[0], 0); + UNUSED_PARAMETER(argc); + if( p ){ + if( sqlite3_user_data(context)!=0 ){ + decimal_result_sci(context, p); + }else{ + decimal_result(context, p); + } + decimal_free(p); + } +} + +/* ** Compare text in decimal order. */ static int decimalCollFunc( @@ -417,8 +680,8 @@ ){ const unsigned char *zA = (const unsigned char*)pKey1; const unsigned char *zB = (const unsigned char*)pKey2; - Decimal *pA = decimal_new(0, 0, nKey1, zA); - Decimal *pB = decimal_new(0, 0, nKey2, zB); + Decimal *pA = decimalNewFromText((const char*)zA, nKey1); + Decimal *pB = decimalNewFromText((const char*)zB, nKey2); int rc; UNUSED_PARAMETER(notUsed); if( pA==0 || pB==0 ){ @@ -443,8 +706,8 @@ int argc, sqlite3_value **argv ){ - Decimal *pA = decimal_new(context, argv[0], 0, 0); - Decimal *pB = decimal_new(context, argv[1], 0, 0); + Decimal *pA = decimal_new(context, argv[0], 1); + Decimal *pB = decimal_new(context, argv[1], 1); UNUSED_PARAMETER(argc); decimal_add(pA, pB); decimal_result(context, pA); @@ -456,8 +719,8 @@ int argc, sqlite3_value **argv ){ - Decimal *pA = decimal_new(context, argv[0], 0, 0); - Decimal *pB = decimal_new(context, argv[1], 0, 0); + Decimal *pA = decimal_new(context, argv[0], 1); + Decimal *pB = decimal_new(context, argv[1], 1); UNUSED_PARAMETER(argc); if( pB ){ pB->sign = !pB->sign; @@ -495,7 +758,7 @@ p->nFrac = 0; } if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pArg = decimal_new(context, argv[0], 0, 0); + pArg = decimal_new(context, argv[0], 1); decimal_add(p, pArg); decimal_free(pArg); } @@ -510,7 +773,7 @@ p = sqlite3_aggregate_context(context, sizeof(*p)); if( p==0 ) return; if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - pArg = decimal_new(context, argv[0], 0, 0); + pArg = decimal_new(context, argv[0], 1); if( pArg ) pArg->sign = !pArg->sign; decimal_add(p, pArg); decimal_free(pArg); @@ -531,66 +794,49 @@ ** SQL Function: decimal_mul(X, Y) ** ** Return the product of X and Y. -** -** All significant digits after the decimal point are retained. -** Trailing zeros after the decimal point are omitted as long as -** the number of digits after the decimal point is no less than -** either the number of digits in either input. */ static void decimalMulFunc( sqlite3_context *context, int argc, sqlite3_value **argv ){ - Decimal *pA = decimal_new(context, argv[0], 0, 0); - Decimal *pB = decimal_new(context, argv[1], 0, 0); - signed char *acc = 0; - int i, j, k; - int minFrac; + Decimal *pA = decimal_new(context, argv[0], 1); + Decimal *pB = decimal_new(context, argv[1], 1); UNUSED_PARAMETER(argc); if( pA==0 || pA->oom || pA->isNull || pB==0 || pB->oom || pB->isNull ){ goto mul_end; } - acc = sqlite3_malloc64( pA->nDigit + pB->nDigit + 2 ); - if( acc==0 ){ - sqlite3_result_error_nomem(context); + decimalMul(pA, pB); + if( pA->oom ){ goto mul_end; } - memset(acc, 0, pA->nDigit + pB->nDigit + 2); - minFrac = pA->nFrac; - if( pB->nFracnFrac; - for(i=pA->nDigit-1; i>=0; i--){ - signed char f = pA->a[i]; - int carry = 0, x; - for(j=pB->nDigit-1, k=i+j+3; j>=0; j--, k--){ - x = acc[k] + f*pB->a[j] + carry; - acc[k] = x%10; - carry = x/10; - } - x = acc[k] + carry; - acc[k] = x%10; - acc[k-1] += x/10; - } - sqlite3_free(pA->a); - pA->a = acc; - acc = 0; - pA->nDigit += pB->nDigit + 2; - pA->nFrac += pB->nFrac; - pA->sign ^= pB->sign; - while( pA->nFrac>minFrac && pA->a[pA->nDigit-1]==0 ){ - pA->nFrac--; - pA->nDigit--; - } decimal_result(context, pA); mul_end: - sqlite3_free(acc); decimal_free(pA); decimal_free(pB); } +/* +** SQL Function: decimal_pow2(N) +** +** Return the N-th power of 2. N must be an integer. +*/ +static void decimalPow2Func( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + UNUSED_PARAMETER(argc); + if( sqlite3_value_type(argv[0])==SQLITE_INTEGER ){ + Decimal *pA = decimalPow2(sqlite3_value_int(argv[0])); + decimal_result_sci(context, pA); + decimal_free(pA); + } +} + #ifdef _WIN32 __declspec(dllexport) #endif @@ -603,13 +849,16 @@ static const struct { const char *zFuncName; int nArg; + int iArg; void (*xFunc)(sqlite3_context*,int,sqlite3_value**); } aFunc[] = { - { "decimal", 1, decimalFunc }, - { "decimal_cmp", 2, decimalCmpFunc }, - { "decimal_add", 2, decimalAddFunc }, - { "decimal_sub", 2, decimalSubFunc }, - { "decimal_mul", 2, decimalMulFunc }, + { "decimal", 1, 0, decimalFunc }, + { "decimal_exp", 1, 1, decimalFunc }, + { "decimal_cmp", 2, 0, decimalCmpFunc }, + { "decimal_add", 2, 0, decimalAddFunc }, + { "decimal_sub", 2, 0, decimalSubFunc }, + { "decimal_mul", 2, 0, decimalMulFunc }, + { "decimal_pow2", 1, 0, decimalPow2Func }, }; unsigned int i; (void)pzErrMsg; /* Unused parameter */ @@ -619,7 +868,7 @@ for(i=0; i<(int)(sizeof(aFunc)/sizeof(aFunc[0])) && rc==SQLITE_OK; i++){ rc = sqlite3_create_function(db, aFunc[i].zFuncName, aFunc[i].nArg, SQLITE_UTF8|SQLITE_INNOCUOUS|SQLITE_DETERMINISTIC, - 0, aFunc[i].xFunc, 0, 0); + aFunc[i].iArg ? db : 0, aFunc[i].xFunc, 0, 0); } if( rc==SQLITE_OK ){ rc = sqlite3_create_window_function(db, "decimal_sum", 1, diff -Nru sqlite3-3.42.0/ext/misc/explain.c sqlite3-3.44.0-0/ext/misc/explain.c --- sqlite3-3.42.0/ext/misc/explain.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/explain.c 2023-11-04 14:23:58.000000000 +0000 @@ -293,6 +293,7 @@ 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff -Nru sqlite3-3.42.0/ext/misc/fileio.c sqlite3-3.44.0-0/ext/misc/fileio.c --- sqlite3-3.42.0/ext/misc/fileio.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/fileio.c 2023-11-04 14:23:58.000000000 +0000 @@ -983,6 +983,7 @@ 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc = sqlite3_create_module(db, "fsdir", &fsdirModule, 0); diff -Nru sqlite3-3.42.0/ext/misc/fossildelta.c sqlite3-3.44.0-0/ext/misc/fossildelta.c --- sqlite3-3.42.0/ext/misc/fossildelta.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/fossildelta.c 2023-11-04 14:23:58.000000000 +0000 @@ -1058,7 +1058,8 @@ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; diff -Nru sqlite3-3.42.0/ext/misc/fuzzer.c sqlite3-3.44.0-0/ext/misc/fuzzer.c --- sqlite3-3.42.0/ext/misc/fuzzer.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/fuzzer.c 2023-11-04 14:23:58.000000000 +0000 @@ -1165,6 +1165,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff -Nru sqlite3-3.42.0/ext/misc/ieee754.c sqlite3-3.44.0-0/ext/misc/ieee754.c --- sqlite3-3.42.0/ext/misc/ieee754.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/ieee754.c 2023-11-04 14:23:58.000000000 +0000 @@ -256,6 +256,37 @@ } } +/* +** SQL Function: ieee754_inc(r,N) +** +** Move the floating point value r by N quantums and return the new +** values. +** +** Behind the scenes: this routine merely casts r into a 64-bit unsigned +** integer, adds N, then casts the value back into float. +** +** Example: To find the smallest positive number: +** +** SELECT ieee754_inc(0.0,+1); +*/ +static void ieee754inc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + double r; + sqlite3_int64 N; + sqlite3_uint64 m1, m2; + double r2; + UNUSED_PARAMETER(argc); + r = sqlite3_value_double(argv[0]); + N = sqlite3_value_int64(argv[1]); + memcpy(&m1, &r, 8); + m2 = m1 + N; + memcpy(&r2, &m2, 8); + sqlite3_result_double(context, r2); +} + #ifdef _WIN32 __declspec(dllexport) @@ -277,7 +308,7 @@ { "ieee754_exponent", 1, 2, ieee754func }, { "ieee754_to_blob", 1, 0, ieee754func_to_blob }, { "ieee754_from_blob", 1, 0, ieee754func_from_blob }, - + { "ieee754_inc", 2, 0, ieee754inc }, }; unsigned int i; int rc = SQLITE_OK; diff -Nru sqlite3-3.42.0/ext/misc/memstat.c sqlite3-3.44.0-0/ext/misc/memstat.c --- sqlite3-3.42.0/ext/misc/memstat.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/memstat.c 2023-11-04 14:23:58.000000000 +0000 @@ -396,6 +396,7 @@ 0, /* xRelease */ 0, /* xRollbackTo */ 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff -Nru sqlite3-3.42.0/ext/misc/mmapwarm.c sqlite3-3.44.0-0/ext/misc/mmapwarm.c --- sqlite3-3.42.0/ext/misc/mmapwarm.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/mmapwarm.c 2023-11-04 14:23:58.000000000 +0000 @@ -38,7 +38,7 @@ int rc = SQLITE_OK; char *zSql = 0; int pgsz = 0; - int nTotal = 0; + unsigned int nTotal = 0; if( 0==sqlite3_get_autocommit(db) ) return SQLITE_MISUSE; @@ -86,8 +86,8 @@ rc = p->xFetch(pFd, pgsz*iPg, pgsz, (void**)&pMap); if( rc!=SQLITE_OK || pMap==0 ) break; - nTotal += pMap[0]; - nTotal += pMap[pgsz-1]; + nTotal += (unsigned int)pMap[0]; + nTotal += (unsigned int)pMap[pgsz-1]; rc = p->xUnfetch(pFd, pgsz*iPg, (void*)pMap); if( rc!=SQLITE_OK ) break; @@ -103,5 +103,6 @@ if( rc==SQLITE_OK ) rc = rc2; } + (void)nTotal; return rc; } diff -Nru sqlite3-3.42.0/ext/misc/pcachetrace.c sqlite3-3.44.0-0/ext/misc/pcachetrace.c --- sqlite3-3.42.0/ext/misc/pcachetrace.c 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/pcachetrace.c 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,179 @@ +/* +** 2023-06-21 +** +** The author disclaims copyright to this source code. In place of +** a legal notice, here is a blessing: +** +** May you do good and not evil. +** May you find forgiveness for yourself and forgive others. +** May you share freely, never taking more than you give. +** +************************************************************************* +** +** This file implements an extension that uses the SQLITE_CONFIG_PCACHE2 +** mechanism to add a tracing layer on top of pluggable page cache of +** SQLite. If this extension is registered prior to sqlite3_initialize(), +** it will cause all page cache activities to be logged on standard output, +** or to some other FILE specified by the initializer. +** +** This file needs to be compiled into the application that uses it. +** +** This extension is used to implement the --pcachetrace option of the +** command-line shell. +*/ +#include +#include +#include + +/* The original page cache routines */ +static sqlite3_pcache_methods2 pcacheBase; +static FILE *pcachetraceOut; + +/* Methods that trace pcache activity */ +static int pcachetraceInit(void *pArg){ + int nRes; + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xInit(%p)\n", pArg); + } + nRes = pcacheBase.xInit(pArg); + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xInit(%p) -> %d\n", pArg, nRes); + } + return nRes; +} +static void pcachetraceShutdown(void *pArg){ + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xShutdown(%p)\n", pArg); + } + pcacheBase.xShutdown(pArg); +} +static sqlite3_pcache *pcachetraceCreate(int szPage, int szExtra, int bPurge){ + sqlite3_pcache *pRes; + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xCreate(%d,%d,%d)\n", + szPage, szExtra, bPurge); + } + pRes = pcacheBase.xCreate(szPage, szExtra, bPurge); + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xCreate(%d,%d,%d) -> %p\n", + szPage, szExtra, bPurge, pRes); + } + return pRes; +} +static void pcachetraceCachesize(sqlite3_pcache *p, int nCachesize){ + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xCachesize(%p, %d)\n", p, nCachesize); + } + pcacheBase.xCachesize(p, nCachesize); +} +static int pcachetracePagecount(sqlite3_pcache *p){ + int nRes; + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xPagecount(%p)\n", p); + } + nRes = pcacheBase.xPagecount(p); + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xPagecount(%p) -> %d\n", p, nRes); + } + return nRes; +} +static sqlite3_pcache_page *pcachetraceFetch( + sqlite3_pcache *p, + unsigned key, + int crFg +){ + sqlite3_pcache_page *pRes; + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xFetch(%p,%u,%d)\n", p, key, crFg); + } + pRes = pcacheBase.xFetch(p, key, crFg); + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xFetch(%p,%u,%d) -> %p\n", + p, key, crFg, pRes); + } + return pRes; +} +static void pcachetraceUnpin( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + int bDiscard +){ + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xUnpin(%p, %p, %d)\n", + p, pPg, bDiscard); + } + pcacheBase.xUnpin(p, pPg, bDiscard); +} +static void pcachetraceRekey( + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, + unsigned oldKey, + unsigned newKey +){ + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xRekey(%p, %p, %u, %u)\n", + p, pPg, oldKey, newKey); + } + pcacheBase.xRekey(p, pPg, oldKey, newKey); +} +static void pcachetraceTruncate(sqlite3_pcache *p, unsigned n){ + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xTruncate(%p, %u)\n", p, n); + } + pcacheBase.xTruncate(p, n); +} +static void pcachetraceDestroy(sqlite3_pcache *p){ + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xDestroy(%p)\n", p); + } + pcacheBase.xDestroy(p); +} +static void pcachetraceShrink(sqlite3_pcache *p){ + if( pcachetraceOut ){ + fprintf(pcachetraceOut, "PCACHETRACE: xShrink(%p)\n", p); + } + pcacheBase.xShrink(p); +} + +/* The substitute pcache methods */ +static sqlite3_pcache_methods2 ersaztPcacheMethods = { + 0, + 0, + pcachetraceInit, + pcachetraceShutdown, + pcachetraceCreate, + pcachetraceCachesize, + pcachetracePagecount, + pcachetraceFetch, + pcachetraceUnpin, + pcachetraceRekey, + pcachetraceTruncate, + pcachetraceDestroy, + pcachetraceShrink +}; + +/* Begin tracing memory allocations to out. */ +int sqlite3PcacheTraceActivate(FILE *out){ + int rc = SQLITE_OK; + if( pcacheBase.xFetch==0 ){ + rc = sqlite3_config(SQLITE_CONFIG_GETPCACHE2, &pcacheBase); + if( rc==SQLITE_OK ){ + rc = sqlite3_config(SQLITE_CONFIG_PCACHE2, &ersaztPcacheMethods); + } + } + pcachetraceOut = out; + return rc; +} + +/* Deactivate memory tracing */ +int sqlite3PcacheTraceDeactivate(void){ + int rc = SQLITE_OK; + if( pcacheBase.xFetch!=0 ){ + rc = sqlite3_config(SQLITE_CONFIG_PCACHE2, &pcacheBase); + if( rc==SQLITE_OK ){ + memset(&pcacheBase, 0, sizeof(pcacheBase)); + } + } + pcachetraceOut = 0; + return rc; +} diff -Nru sqlite3-3.42.0/ext/misc/prefixes.c sqlite3-3.44.0-0/ext/misc/prefixes.c --- sqlite3-3.42.0/ext/misc/prefixes.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/prefixes.c 2023-11-04 14:23:58.000000000 +0000 @@ -248,7 +248,8 @@ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; /* diff -Nru sqlite3-3.42.0/ext/misc/qpvtab.c sqlite3-3.44.0-0/ext/misc/qpvtab.c --- sqlite3-3.42.0/ext/misc/qpvtab.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/qpvtab.c 2023-11-04 14:23:58.000000000 +0000 @@ -439,7 +439,8 @@ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ diff -Nru sqlite3-3.42.0/ext/misc/series.c sqlite3-3.44.0-0/ext/misc/series.c --- sqlite3-3.42.0/ext/misc/series.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/misc/series.c 2023-11-04 14:23:58.000000000 +0000 @@ -330,6 +330,10 @@ return SQLITE_OK; } +#ifndef LARGEST_UINT64 +#define LARGEST_UINT64 (0xffffffff|(((sqlite3_uint64)0xffffffff)<<32)) +#endif + /* ** Return the rowid for the current row, logically equivalent to n+1 where ** "n" is the ascending integer in the aforesaid production definition. @@ -337,7 +341,7 @@ static int seriesRowid(sqlite3_vtab_cursor *cur, sqlite_int64 *pRowid){ series_cursor *pCur = (series_cursor*)cur; sqlite3_uint64 n = pCur->ss.uSeqIndexNow; - *pRowid = (sqlite3_int64)((n<0xffffffffffffffff)? n+1 : 0); + *pRowid = (sqlite3_int64)((n #include #include +#include #include @@ -2200,7 +2201,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollback */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc = sqlite3_create_module(db, "zipfile" , &zipfileModule, 0); diff -Nru sqlite3-3.42.0/ext/recover/dbdata.c sqlite3-3.44.0-0/ext/recover/dbdata.c --- sqlite3-3.42.0/ext/recover/dbdata.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/recover/dbdata.c 2023-11-04 14:23:58.000000000 +0000 @@ -73,13 +73,12 @@ */ #if !defined(SQLITEINT_H) -#include "sqlite3ext.h" +#include "sqlite3.h" typedef unsigned char u8; typedef unsigned int u32; #endif -SQLITE_EXTENSION_INIT1 #include #include @@ -664,8 +663,14 @@ if( pCsr->pHdrPtr>&pCsr->pRec[pCsr->nRec] ){ bNextPage = 1; }else{ + int szField = 0; pCsr->pHdrPtr += dbdataGetVarintU32(pCsr->pHdrPtr, &iType); - pCsr->pPtr += dbdataValueBytes(iType); + szField = dbdataValueBytes(iType); + if( (pCsr->nRec - (pCsr->pPtr - pCsr->pRec))pPtr = &pCsr->pRec[pCsr->nRec]; + }else{ + pCsr->pPtr += szField; + } } } } @@ -928,7 +933,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; int rc = sqlite3_create_module(db, "sqlite_dbdata", &dbdata_module, 0); @@ -938,15 +944,11 @@ return rc; } -#ifdef _WIN32 -__declspec(dllexport) -#endif int sqlite3_dbdata_init( sqlite3 *db, char **pzErrMsg, const sqlite3_api_routines *pApi ){ - SQLITE_EXTENSION_INIT2(pApi); (void)pzErrMsg; return sqlite3DbdataRegister(db); } diff -Nru sqlite3-3.42.0/ext/recover/recovercorrupt2.test sqlite3-3.44.0-0/ext/recover/recovercorrupt2.test --- sqlite3-3.42.0/ext/recover/recovercorrupt2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/recover/recovercorrupt2.test 2023-11-04 14:23:58.000000000 +0000 @@ -285,5 +285,244 @@ list [catch { $R finish } msg] $msg } {0 {}} +#------------------------------------------------------------------------- +# +reset_db +do_test 6.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 8192 pagesize 4096 filename abc.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 02 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................ +| 96: 00 2e 6e b8 0d 00 00 00 01 0f dc 00 0f dc 00 00 ..n............. +| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 22 01 06 17 ................ +| 4064: 11 11 01 31 74 61 62 6c 65 74 31 74 31 02 43 52 ...1tablet1t1.CR +| 4080: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 78 29 EATE TABLE t1(x) +| page 2 offset 4096 +| 0: 0d 00 00 00 01 0f e2 00 0f e2 00 00 00 00 00 00 ................ +| 4064: 00 00 1c 01 02 41 61 62 63 64 65 66 67 68 69 6a .....Aabcdefghij +| 4080: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a klmnopqrstuvwxyz +| end abc.db +}]} {} +do_test 6.1 { + set R [sqlite3_recover_init db main test.db2] + catch { $R run } + list [catch { $R finish } msg] $msg +} {0 {}} + +reset_db +breakpoint +do_test 6.2 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 8192 pagesize 4096 filename abc.db +| page 1 offset 0 +| 0: 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00 SQLite format 3. +| 16: 10 00 01 01 00 40 20 20 00 00 00 02 00 00 00 02 .....@ ........ +| 32: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 04 ................ +| 48: 00 00 00 00 00 00 00 00 00 00 00 01 00 00 00 00 ................ +| 80: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 02 ................ +| 96: 00 2e 6e b8 0d 00 00 00 01 0f dc 00 0f dc 00 00 ..n............. +| 4048: 00 00 00 00 00 00 00 00 00 00 00 00 22 01 06 17 ................ +| 4064: 11 11 01 31 74 61 62 6c 65 74 31 74 31 02 43 52 ...1tablet1t1.CR +| 4080: 45 41 54 45 20 54 41 42 4c 45 20 74 31 28 78 29 EATE TABLE t1(x) +| page 2 offset 4096 +| 0: 0d 00 00 00 01 0f e2 00 0f e2 00 00 00 00 00 00 ................ +| 4064: 00 00 1c 01 02 8F FF FF FF 7E 65 66 67 68 69 6a .....Aabcdefghij +| 4080: 6b 6c 6d 6e 6f 70 71 72 73 74 75 76 77 78 79 7a klmnopqrstuvwxyz +| end abc.db +}]} {} +do_test 6.3 { + set R [sqlite3_recover_init db main test.db2] + catch { $R run } + list [catch { $R finish } msg] $msg +} {0 {}} + +reset_db +breakpoint +do_test 7.0 { + sqlite3 db {} + db deserialize [decode_hexdb { +| size 4108 pagesize 4096 filename x1.db +| page 1 offset 0 +| 0: 02 01 00 00 00 00 14 15 40 00 00 00 00 00 00 00 ........@....... +| 16: 33 3a 6d 65 6d 6f 72 79 3a 02 02 02 02 02 02 02 3:memory:....... +| 32: 02 02 02 02 02 02 12 02 02 02 63 6f 6c 6f 72 20 ..........color +| 48: 73 70 61 63 00 f3 a0 81 a1 00 00 a0 02 02 02 02 spac............ +| 64: 69 95 73 6f 36 00 ff 0d 00 97 8c 90 3f 0a 70 02 i.so6.......?.p. +| 80: 02 02 02 02 02 02 02 02 02 02 02 02 02 01 00 00 ................ +| 96: 06 02 02 02 02 5f 02 02 02 2c 02 02 02 02 02 02 ....._...,...... +| 112: 02 02 02 02 02 02 02 02 02 12 02 02 02 63 6f 6c .............col +| 128: 6f 72 20 73 70 61 63 00 f3 a0 81 a1 00 00 a0 02 or spac......... +| 144: 02 02 02 69 95 73 6f 36 00 ff 0d 00 97 8c 90 3f ...i.so6.......? +| 160: 0a 70 02 02 02 02 02 02 02 02 02 02 02 02 02 02 .p.............. +| 176: 01 00 00 06 02 02 02 02 5f 02 02 02 2c 02 02 00 ........_...,... +| 192: 00 01 00 01 00 00 00 01 00 02 fe 00 00 03 00 01 ................ +| 208: 00 00 00 01 c5 04 00 00 00 01 00 01 00 00 00 01 ................ +| 224: 00 fa 02 00 00 00 03 00 01 00 00 00 81 00 04 00 ................ +| 240: 00 00 01 00 01 00 00 00 01 00 02 00 fe 00 03 00 ................ +| 256: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................ +| 272: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................ +| 288: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................ +| 304: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................ +| 320: 01 00 02 00 00 00 03 00 01 00 00 00 40 00 84 00 ............@... +| 336: 84 00 84 00 01 00 00 00 09 00 06 00 f5 00 01 00 ................ +| 352: 08 01 03 00 03 00 62 00 62 00 23 00 01 00 62 00 ......b.b.#...b. +| 368: 04 00 1e 00 62 00 62 00 62 00 01 00 00 00 0a 00 ....b.b.b....... +| 384: 01 00 03 00 01 00 03 00 04 00 02 00 01 00 01 00 ................ +| 400: 08 00 01 00 31 c6 00 03 00 0c 00 12 00 18 00 02 ....1........... +| 416: 00 05 00 08 00 02 00 06 00 08 00 02 00 07 00 08 ................ +| 432: 00 02 00 01 00 01 00 08 00 01 00 0c 00 03 00 16 ................ +| 448: 00 1c 00 22 00 01 00 03 00 05 00 06 00 07 00 02 ................ +| 464: 00 05 00 09 00 02 00 06 00 09 00 02 00 07 00 09 ................ +| 480: 00 00 00 00 01 00 05 00 00 00 01 00 01 00 00 00 ................ +| 496: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................ +| 512: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................ +| 528: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................ +| 544: 01 00 02 00 00 f6 03 00 00 02 00 00 01 00 04 00 ................ +| 560: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................ +| 576: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................ +| 592: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................ +| 608: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................ +| 624: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................ +| 640: 01 3d 02 00 00 00 03 00 06 00 00 00 01 00 01 00 .=.............. +| 656: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................ +| 672: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................ +| 688: 01 00 02 00 00 00 55 52 4c 52 65 71 75 65 73 74 ......URLRequest +| 704: 43 6f 6e 00 00 00 01 01 0e d4 00 04 00 00 00 01 Con............. +| 720: 0e f8 00 04 00 00 00 01 0f 1c 00 04 00 00 00 01 ................ +| 736: 0f 00 00 01 00 00 00 01 0f 86 00 01 00 00 00 01 ................ +| 752: 0f 84 00 01 00 00 00 01 00 00 01 0f c0 00 01 00 ................ +| 768: 00 00 01 0f e8 00 d6 0f 00 01 6f 00 02 0f d6 00 ..........o..... +| 784: 02 34 03 03 03 00 01 00 00 00 01 00 05 00 00 00 .4.............. +| 800: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................ +| 816: 00 00 01 00 04 00 00 00 01 00 01 00 00 00 01 00 ................ +| 832: 02 00 00 00 03 00 01 00 10 00 01 00 04 00 00 00 ................ +| 848: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 00 02 ................ +| 864: 00 00 01 40 04 00 00 03 01 00 01 00 00 00 01 00 ...@............ +| 880: 02 00 00 00 03 00 01 00 00 00 00 00 01 0e f8 00 ................ +| 896: 04 77 4f 46 32 73 40 23 70 00 00 00 70 00 1f 00 .wOF2s@#p...p... +| 912: 00 00 d8 00 00 00 ff ff 00 00 00 00 43 00 00 00 ............C... +| 928: 00 00 ff ff ff ff ff 00 00 a8 00 00 0c 00 00 00 ................ +| 1024: 00 00 00 00 00 00 00 00 00 00 10 22 00 22 0f 00 ................ +| 1040: 00 00 00 00 00 00 10 22 00 00 70 00 1f 00 00 0f ..........p..... +| 1056: d8 00 00 00 00 00 00 00 00 00 03 00 00 00 00 00 ................ +| 1072: 00 01 00 00 00 3f 23 70 00 00 00 01 0f 1c 00 04 .....?#p........ +| 1088: 00 00 00 01 0f 40 00 01 00 00 00 01 0f 86 00 01 .....@.......... +| 1104: 00 00 00 01 0f 84 00 01 00 00 00 01 00 00 01 0f ................ +| 1120: c0 00 01 00 00 00 01 0f e8 00 01 0f d6 00 6f 00 ..............o. +| 1136: 02 0f d6 00 03 02 31 03 2b 03 2a f2 00 0f d4 00 ......1.+.*..... +| 1152: 01 00 08 00 01 00 04 03 2b 00 02 02 32 00 01 0f ........+...2... +| 1168: c8 01 15 00 02 20 c8 00 02 12 ad 02 00 24 06 c0 ..... .......$.. +| 1184: 00 00 00 03 00 00 01 24 00 2a 06 e4 00 00 00 03 .......$.*...... +| 1200: 00 00 01 25 00 38 07 0e 00 00 00 03 00 00 01 26 ...%.8.........& +| 1216: 00 34 07 46 00 00 00 03 00 00 01 27 00 1c 07 7a .4.F.......'...z +| 1232: 00 00 00 03 00 00 01 28 00 2a 07 96 00 00 00 03 .......(.*...... +| 1248: 00 e5 01 29 00 34 07 c0 00 00 00 03 00 00 01 2a ...).4.........* +| 1264: 67 34 07 f4 00 00 00 03 00 00 01 2b 00 22 08 28 g4.........+...( +| 1280: 00 00 00 00 01 00 01 00 00 00 01 00 02 00 00 00 ................ +| 1296: 03 00 01 00 00 00 01 00 00 00 01 00 00 00 01 00 ................ +| 1312: 01 00 00 00 01 00 02 00 00 00 03 00 00 02 00 00 ................ +| 1328: 01 00 04 00 00 00 01 00 01 00 00 00 01 00 02 00 ................ +| 1344: 00 00 03 00 01 00 00 00 01 00 04 00 00 00 01 00 ................ +| 1360: 01 00 00 00 01 00 02 00 00 00 03 00 01 00 00 21 ...............! +| 1376: 04 00 01 00 00 00 00 00 01 00 00 00 01 00 02 00 ................ +| 1392: 00 00 03 00 01 00 00 00 01 00 04 00 00 00 01 00 ................ +| 1408: 01 00 00 00 01 00 02 00 00 00 03 00 01 00 00 00 ................ +| 1424: 01 00 05 00 00 00 01 00 01 00 00 01 00 02 02 02 ................ +| 1440: 12 02 02 02 63 6f 6c 6f 72 20 73 70 61 63 00 f3 ....color spac.. +| 1456: a0 81 a1 00 00 a0 02 02 02 02 69 95 73 6f 36 00 ..........i.so6. +| 1472: ff 0d 00 97 8c 90 3f 0a 70 02 02 02 02 02 02 02 ......?.p....... +| 1488: 02 02 02 02 02 02 02 01 00 00 06 02 02 02 02 5f ..............._ +| 1504: 02 02 02 2c 02 02 00 00 01 00 01 00 00 00 01 00 ...,............ +| 1520: 02 fe 00 00 03 00 01 00 00 00 01 c5 04 00 00 00 ................ +| 1536: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................ +| 1552: 00 00 81 00 04 00 00 00 01 00 01 00 00 00 01 00 ................ +| 1568: 02 00 fe 00 03 00 01 00 00 00 01 00 04 00 00 00 ................ +| 1584: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................ +| 1600: 00 00 01 00 04 00 00 00 01 00 01 00 00 00 01 00 ................ +| 1616: 02 00 00 00 03 00 01 00 00 00 01 00 04 00 00 00 ................ +| 1632: 01 00 01 00 00 00 01 00 02 00 00 00 03 00 01 00 ................ +| 1648: 00 00 40 00 84 00 84 00 84 00 01 00 00 00 09 00 ..@............. +| 1664: 06 00 f5 00 01 00 08 01 03 15 15 15 15 15 15 15 ................ +| 1680: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................ +| 1696: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................ +| 1712: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................ +| 1728: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................ +| 1744: 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 15 ................ +| 1760: 15 15 15 15 15 15 15 15 15 15 15 00 03 00 62 00 ..............b. +| 1776: 62 00 23 00 01 00 62 00 04 00 1e 00 62 00 62 00 b.#...b.....b.b. +| 1792: 62 00 01 00 00 00 0a 00 01 00 03 00 01 00 03 00 b............... +| 1808: 04 00 02 00 01 00 01 00 08 00 01 00 31 c6 00 03 ............1... +| 1824: 00 0c 00 12 00 18 00 02 00 05 00 08 00 02 00 06 ................ +| 1840: 00 08 00 02 00 07 00 08 00 02 00 01 00 01 00 08 ................ +| 1856: 00 01 00 0c 00 03 00 16 00 1c 00 22 00 01 00 03 ................ +| 1872: 00 05 00 06 00 07 00 02 00 05 00 09 00 02 00 06 ................ +| 1888: 00 09 00 02 00 07 00 09 00 00 00 00 01 00 05 00 ................ +| 1904: 00 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 ................ +| 1920: 01 00 00 00 01 00 04 00 00 00 01 00 01 00 00 00 ................ +| 1936: 01 00 02 00 00 00 03 00 01 00 00 00 01 00 04 00 ................ +| 1952: 00 00 01 0f d6 00 02 34 03 03 03 00 01 00 00 00 .......4........ +| 1968: 01 00 05 00 00 00 01 00 01 00 00 00 01 00 02 00 ................ +| 1984: 00 00 03 00 01 00 00 00 01 00 04 00 00 00 01 00 ................ +| 2000: 01 00 00 00 01 00 02 fc 42 dc 19 5c 74 23 18 cd ........B...t#.. +| 2016: b3 a5 a8 7a 90 40 1d 66 12 5d e5 4f 85 00 68 f4 ...z.@.f.].O..h. +| 2032: 05 98 86 25 24 dd bc c2 f6 f6 4e a3 e2 61 d2 c6 ...%$.....N..a.. +| 2048: aa c1 56 50 d4 80 82 35 f1 e2 59 41 50 a6 da 51 ..VP...5..YAP..Q +| 2064: d4 62 9c 19 94 58 aa 31 30 8a 22 c2 5f 33 2b c9 .b...X.10..._3+. +| 2080: b6 e6 b4 11 4e 51 82 c4 d8 b6 d8 b4 06 04 fb 68 ....NQ.........h +| 2096: f4 d2 6f e7 cb 8a a8 82 d5 74 00 00 00 00 00 00 ..o......t...... +| 2368: 00 00 00 00 00 00 00 00 00 08 00 00 00 00 00 00 ................ +| 2432: 00 00 00 00 00 03 00 01 00 10 00 01 00 04 00 00 ................ +| 2448: 00 01 00 01 00 00 00 01 00 02 00 00 00 03 00 00 ................ +| 2464: 02 00 00 01 40 04 00 00 03 01 00 01 00 00 00 01 ....@........... +| 2480: 00 02 00 00 00 03 00 01 00 00 00 00 00 01 0e f8 ................ +| 2496: 00 04 77 4f 46 32 73 40 23 70 00 00 00 70 00 1f ..wOF2s@#p...p.. +| 2512: 00 00 00 d8 00 00 00 ff ff 00 00 00 00 43 00 00 .............C.. +| 2528: 00 00 00 ff ff ff ff ff 00 00 a8 00 00 0c 00 00 ................ +| 2624: 00 00 00 00 00 00 00 00 00 00 00 10 22 00 22 0f ................ +| 2640: 00 00 00 00 00 00 00 10 22 00 00 70 00 1f 00 00 ...........p.... +| 2656: 0f d8 00 00 00 00 00 00 00 00 00 03 00 00 00 00 ................ +| 2672: 00 00 01 00 00 00 3f 23 70 00 00 00 01 0f 1c 00 ......?#p....... +| 2688: 04 00 00 00 01 0f 40 00 01 00 00 00 01 0f 86 00 ......@......... +| 2704: 01 00 00 00 01 0f 84 00 01 00 00 00 01 00 00 01 ................ +| 2720: 0f c0 00 01 00 00 00 01 0f e8 00 01 0f d6 00 6f ...............o +| 2736: 00 02 0f d6 00 03 02 31 03 2b 03 2a f2 00 0f d4 .......1.+.*.... +| 2752: 00 01 00 08 00 01 00 04 03 2b 00 02 02 32 00 01 .........+...2.. +| 2768: 0f c8 01 15 00 02 20 c8 00 02 12 ad 02 00 24 06 ...... .......$. +| 2784: c0 00 00 5a 03 00 00 01 24 00 2a 06 e4 00 00 00 ...Z....$.*..... +| 2800: 03 00 00 01 25 00 38 07 0e 00 00 00 03 00 00 01 ....%.8......... +| 2816: 26 00 34 07 46 00 00 00 03 00 00 01 27 00 1c 07 &.4.F.......'... +| 2832: 7a 00 00 00 03 00 00 01 28 00 2a 07 96 00 00 00 z.......(.*..... +| 2848: 03 00 e5 01 29 00 34 07 c0 00 00 00 03 00 00 01 ....).4......... +| 2864: 2a 67 34 07 f4 00 00 00 03 00 00 01 2b 00 22 08 *g4.........+... +| 2880: 28 00 00 00 00 01 00 01 00 00 00 01 00 02 00 00 (............... +| 2896: 00 03 00 01 00 00 00 01 00 00 00 01 00 00 00 01 ................ +| 2912: 00 01 00 00 00 01 00 02 00 00 00 03 00 00 02 00 ................ +| 2928: 00 01 00 04 00 00 00 01 00 01 00 00 00 00 00 00 ................ +| 2992: 00 48 00 00 00 00 00 00 00 00 00 00 00 00 00 00 .H.............. +| 3504: 00 00 00 00 00 00 00 00 00 00 00 97 00 00 00 00 ................ +| 3904: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 09 ................ +| 3920: 03 fe 00 00 01 36 00 3c 0a 38 00 00 00 03 00 00 .....6.<.8...... +| 3936: 01 37 00 20 0a 74 00 00 00 fb ff ff 00 38 00 2a .7. .t.......8.* +| 3952: 0a 94 00 00 00 03 00 00 01 39 4f 54 54 4f 00 0e .........9OTTO.. +| 3968: 00 80 00 03 00 60 43 46 46 20 e3 ae 89 2a 00 00 .....`CFF ...*.. +| 3984: 02 b0 00 00 02 76 42 50 4f 53 00 15 00 0a 00 00 .....vBPOS...... +| 4000: 05 28 00 00 00 0c 54 53 55 42 c9 70 c3 06 00 00 .(....TSUB.p.... +| 4016: 05 34 1f 00 40 00 48 00 00 00 00 00 00 00 00 00 .4..@.H......... +| 4064: 00 00 00 00 00 08 00 01 00 01 00 01 00 01 00 06 ................ +| 4080: 00 02 00 08 00 01 00 01 00 01 00 01 00 00 00 00 ................ +| end x1.db +}]} {} +do_test 7.1 { + set R [sqlite3_recover_init db main test.db2] + catch { $R run } + list [catch { $R finish } msg] $msg +} {1 {file is not a database}} + finish_test diff -Nru sqlite3-3.42.0/ext/recover/sqlite3recover.c sqlite3-3.44.0-0/ext/recover/sqlite3recover.c --- sqlite3-3.42.0/ext/recover/sqlite3recover.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/recover/sqlite3recover.c 2023-11-04 14:23:58.000000000 +0000 @@ -2103,7 +2103,7 @@ if( iFree>(n-4) ) return 0; iNext = recoverGetU16(&a[iFree]); nByte = recoverGetU16(&a[iFree+2]); - if( iFree+nByte>n ) return 0; + if( iFree+nByte>n || nByte<4 ) return 0; if( iNext && iNextnBusy = 1; pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; pRtree->eCoordType = RTREE_COORD_REAL32; pRtree->nDim = 2; pRtree->nDim2 = 4; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); /* Create/Connect to the underlying relational database schema. If @@ -1683,7 +1687,6 @@ } if( rc==SQLITE_OK ){ int rc2; - pRtree->iReinsertHeight = -1; rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); rc2 = nodeRelease(pRtree, pLeaf); if( rc==SQLITE_OK ){ @@ -1780,7 +1783,8 @@ rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - rtreeShadowName /* xShadowName */ + rtreeShadowName, /* xShadowName */ + rtreeIntegrity /* xIntegrity */ }; static int sqlite3_geopoly_init(sqlite3 *db){ diff -Nru sqlite3-3.42.0/ext/rtree/rtree1.test sqlite3-3.44.0-0/ext/rtree/rtree1.test --- sqlite3-3.42.0/ext/rtree/rtree1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtree1.test 2023-11-04 14:23:58.000000000 +0000 @@ -756,4 +756,45 @@ SELECT * FROM t1 JOIN t0 ON true RIGHT JOIN rt0 ON x0>a WHERE x0 = 0; } {- - 0 0.0 0.0} +# 2023-05-19 https://sqlite.org/forum/forumpost/da61c4a1b5b4af19 +# Do not omit constraints that involve equality comparisons of +# floating-point values. +# +reset_db +do_execsql_test 21.0 { + CREATE VIRTUAL TABLE t1 USING rtree(id, x0, x1); + INSERT INTO t1 VALUES(0, 1, 9223372036854775807); + SELECT count(*) FROM t1 WHERE x1=9223372036854775807; +} {0} +do_execsql_test 21.1 { + SELECT x1=9223372036854775807 FROM t1; +} {0} + +# 2023-05-22 https://sqlite.org/forum/forumpost/da70ee0d0d +# Round-off error associated with using large integer constraints on +# a rtree search. +# +if {$tcl_platform(machine)!="i686" || $tcl_platform(os)!="Linux"} { + reset_db + do_execsql_test 22.0 { + CREATE VIRTUAL TABLE t1 USING rtree ( id, x0, x1 ); + INSERT INTO t1 VALUES (123, 9223372036854775799, 9223372036854775800); + SELECT id FROM t1 WHERE x0 > 9223372036854775807; + } {123} + do_execsql_test 22.1 { + SELECT id, x0 > 9223372036854775807 AS 'a0' FROM t1; + } {123 1} +} + +# 2023-10-14 dbsqlfuzz --sql-fuzz find. rtreecheck() should not call +# BEGIN/COMMIT because that causes problems with statement transactions, +# and it is unnecessary. +# +reset_db +do_test 23.0 { + db eval {CREATE TABLE t1(a,b,c);} + catch {db eval {CREATE TABLE t2 AS SELECT rtreecheck('t1') AS y;}} + db eval {PRAGMA integrity_check;} +} {ok} + finish_test diff -Nru sqlite3-3.42.0/ext/rtree/rtree8.test sqlite3-3.44.0-0/ext/rtree/rtree8.test --- sqlite3-3.42.0/ext/rtree/rtree8.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtree8.test 2023-11-04 14:23:58.000000000 +0000 @@ -75,7 +75,7 @@ # populate_t1 1500 do_rtree_integrity_test rtree8-1.3.0 t1 -do_execsql_test rtree8-1.3.1 { SELECT max(nodeno) FROM t1_node } {164} +do_execsql_test rtree8-1.3.1 { SELECT max(nodeno) FROM t1_node } {183} do_test rtree8-1.3.2 { set rowids [execsql {SELECT min(rowid) FROM t1_rowid GROUP BY nodeno}] set stmt_list [list] diff -Nru sqlite3-3.42.0/ext/rtree/rtreeA.test sqlite3-3.44.0-0/ext/rtree/rtreeA.test --- sqlite3-3.42.0/ext/rtree/rtreeA.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtreeA.test 2023-11-04 14:23:58.000000000 +0000 @@ -113,7 +113,7 @@ SELECT rtreecheck('main', 't1') } {{Node 1 missing from database Wrong number of entries in %_rowid table - expected 0, actual 500 -Wrong number of entries in %_parent table - expected 0, actual 23}} +Wrong number of entries in %_parent table - expected 0, actual 25}} do_execsql_test rtreeA-1.2.0 { DROP TABLE t1_node } {} do_corruption_tests rtreeA-1.2 -error "database disk image is malformed" { @@ -191,7 +191,7 @@ SELECT rtreecheck('main', 't1') } {{Rtree depth out of range (65535) Wrong number of entries in %_rowid table - expected 0, actual 499 -Wrong number of entries in %_parent table - expected 0, actual 23}} +Wrong number of entries in %_parent table - expected 0, actual 25}} #------------------------------------------------------------------------- # Set the "number of entries" field on some nodes incorrectly. diff -Nru sqlite3-3.42.0/ext/rtree/rtree.c sqlite3-3.44.0-0/ext/rtree/rtree.c --- sqlite3-3.42.0/ext/rtree/rtree.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtree.c 2023-11-04 14:23:58.000000000 +0000 @@ -96,6 +96,11 @@ #endif #endif /* !defined(SQLITE_AMALGAMATION) */ +/* Macro to check for 4-byte alignment. Only used inside of assert() */ +#ifdef SQLITE_DEBUG +# define FOUR_BYTE_ALIGNED(X) ((((char*)(X) - (char*)0) & 3)==0) +#endif + #include #include #include @@ -161,6 +166,7 @@ int iDepth; /* Current depth of the r-tree structure */ char *zDb; /* Name of database containing r-tree table */ char *zName; /* Name of r-tree table */ + char *zNodeName; /* Name of the %_node table */ u32 nBusy; /* Current number of users of this structure */ i64 nRowEst; /* Estimated number of rows in this table */ u32 nCursor; /* Number of open cursors */ @@ -173,7 +179,6 @@ ** headed by the node (leaf nodes have RtreeNode.iNode==0). */ RtreeNode *pDeleted; - int iReinsertHeight; /* Height of sub-trees Reinsert() has run on */ /* Blob I/O on xxx_node */ sqlite3_blob *pNodeBlob; @@ -195,7 +200,7 @@ /* Statement for writing to the "aux:" fields, if there are any */ sqlite3_stmt *pWriteAux; - RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ + RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ }; /* Possible values for Rtree.eCoordType: */ @@ -470,15 +475,20 @@ ** -DSQLITE_RUNTIME_BYTEORDER=1 is set, then byte-order is determined ** at run-time. */ -#ifndef SQLITE_BYTEORDER -# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ +#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ +# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define SQLITE_BYTEORDER 4321 +# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define SQLITE_BYTEORDER 1234 +# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 +# define SQLITE_BYTEORDER 4321 +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) -# define SQLITE_BYTEORDER 1234 -# elif defined(sparc) || defined(__ppc__) || \ - defined(__ARMEB__) || defined(__AARCH64EB__) -# define SQLITE_BYTEORDER 4321 +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 # else # define SQLITE_BYTEORDER 0 # endif @@ -502,7 +512,7 @@ return (p[0]<<8) + p[1]; } static void readCoord(u8 *p, RtreeCoord *pCoord){ - assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ + assert( FOUR_BYTE_ALIGNED(p) ); #if SQLITE_BYTEORDER==1234 && MSVC_VERSION>=1300 pCoord->u = _byteswap_ulong(*(u32*)p); #elif SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 @@ -556,7 +566,7 @@ } static int writeCoord(u8 *p, RtreeCoord *pCoord){ u32 i; - assert( (((sqlite3_uint64)p)&3)==0 ); /* p is always 4-byte aligned */ + assert( FOUR_BYTE_ALIGNED(p) ); assert( sizeof(RtreeCoord)==4 ); assert( sizeof(u32)==4 ); #if SQLITE_BYTEORDER==1234 && GCC_VERSION>=4003000 @@ -727,11 +737,9 @@ } } if( pRtree->pNodeBlob==0 ){ - char *zTab = sqlite3_mprintf("%s_node", pRtree->zName); - if( zTab==0 ) return SQLITE_NOMEM; - rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, zTab, "data", iNode, 0, + rc = sqlite3_blob_open(pRtree->db, pRtree->zDb, pRtree->zNodeName, + "data", iNode, 0, &pRtree->pNodeBlob); - sqlite3_free(zTab); } if( rc ){ nodeBlobReset(pRtree); @@ -1284,7 +1292,7 @@ assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); - assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ + assert( FOUR_BYTE_ALIGNED(pCellData) ); switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ case RTREE_FALSE: break; /* Never satisfied */ @@ -1337,7 +1345,7 @@ || p->op==RTREE_GT || p->op==RTREE_EQ || p->op==RTREE_TRUE || p->op==RTREE_FALSE ); pCellData += 8 + p->iCoord*4; - assert( (((sqlite3_uint64)pCellData)&3)==0 ); /* 4-byte aligned */ + assert( FOUR_BYTE_ALIGNED(pCellData) ); RTREE_DECODE_COORD(eInt, pCellData, xN); switch( p->op ){ case RTREE_TRUE: return; /* Always satisfied */ @@ -1907,7 +1915,20 @@ p->pInfo->nCoord = pRtree->nDim2; p->pInfo->anQueue = pCsr->anQueue; p->pInfo->mxLevel = pRtree->iDepth + 1; - }else if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ + }else if( eType==SQLITE_INTEGER ){ + sqlite3_int64 iVal = sqlite3_value_int64(argv[ii]); +#ifdef SQLITE_RTREE_INT_ONLY + p->u.rValue = iVal; +#else + p->u.rValue = (double)iVal; + if( iVal>=((sqlite3_int64)1)<<48 + || iVal<=-(((sqlite3_int64)1)<<48) + ){ + if( p->op==RTREE_LT ) p->op = RTREE_LE; + if( p->op==RTREE_GT ) p->op = RTREE_GE; + } +#endif + }else if( eType==SQLITE_FLOAT ){ #ifdef SQLITE_RTREE_INT_ONLY p->u.rValue = sqlite3_value_int64(argv[ii]); #else @@ -2038,11 +2059,12 @@ || p->op==SQLITE_INDEX_CONSTRAINT_MATCH) ){ u8 op; + u8 doOmit = 1; switch( p->op ){ - case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; break; - case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; break; + case SQLITE_INDEX_CONSTRAINT_EQ: op = RTREE_EQ; doOmit = 0; break; + case SQLITE_INDEX_CONSTRAINT_GT: op = RTREE_GT; doOmit = 0; break; case SQLITE_INDEX_CONSTRAINT_LE: op = RTREE_LE; break; - case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break; + case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; doOmit = 0; break; case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break; case SQLITE_INDEX_CONSTRAINT_MATCH: op = RTREE_MATCH; break; default: op = 0; break; @@ -2051,15 +2073,19 @@ zIdxStr[iIdx++] = op; zIdxStr[iIdx++] = (char)(p->iColumn - 1 + '0'); pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2); - pIdxInfo->aConstraintUsage[ii].omit = 1; + pIdxInfo->aConstraintUsage[ii].omit = doOmit; } } } pIdxInfo->idxNum = 2; pIdxInfo->needToFreeIdxStr = 1; - if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){ - return SQLITE_NOMEM; + if( iIdx>0 ){ + pIdxInfo->idxStr = sqlite3_malloc( iIdx+1 ); + if( pIdxInfo->idxStr==0 ){ + return SQLITE_NOMEM; + } + memcpy(pIdxInfo->idxStr, zIdxStr, iIdx+1); } nRow = pRtree->nRowEst >> (iIdx/2); @@ -2138,31 +2164,22 @@ */ static int cellContains(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){ int ii; - int isInt = (pRtree->eCoordType==RTREE_COORD_INT32); - for(ii=0; iinDim2; ii+=2){ - RtreeCoord *a1 = &p1->aCoord[ii]; - RtreeCoord *a2 = &p2->aCoord[ii]; - if( (!isInt && (a2[0].fa1[1].f)) - || ( isInt && (a2[0].ia1[1].i)) - ){ - return 0; + if( pRtree->eCoordType==RTREE_COORD_INT32 ){ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].ia1[1].i ) return 0; + } + }else{ + for(ii=0; iinDim2; ii+=2){ + RtreeCoord *a1 = &p1->aCoord[ii]; + RtreeCoord *a2 = &p2->aCoord[ii]; + if( a2[0].fa1[1].f ) return 0; } } return 1; } -/* -** Return the amount cell p would grow by if it were unioned with pCell. -*/ -static RtreeDValue cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){ - RtreeDValue area; - RtreeCell cell; - memcpy(&cell, p, sizeof(RtreeCell)); - area = cellArea(pRtree, &cell); - cellUnion(pRtree, &cell, pCell); - return (cellArea(pRtree, &cell)-area); -} - static RtreeDValue cellOverlap( Rtree *pRtree, RtreeCell *p, @@ -2209,38 +2226,52 @@ for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){ int iCell; sqlite3_int64 iBest = 0; - + int bFound = 0; RtreeDValue fMinGrowth = RTREE_ZERO; RtreeDValue fMinArea = RTREE_ZERO; - int nCell = NCELL(pNode); - RtreeCell cell; RtreeNode *pChild = 0; - RtreeCell *aCell = 0; - - /* Select the child node which will be enlarged the least if pCell - ** is inserted into it. Resolve ties by choosing the entry with - ** the smallest area. + /* First check to see if there is are any cells in pNode that completely + ** contains pCell. If two or more cells in pNode completely contain pCell + ** then pick the smallest. */ for(iCell=0; iCell1 ){ - int iLeft = 0; - int iRight = 0; - - int nLeft = nIdx/2; - int nRight = nIdx-nLeft; - int *aLeft = aIdx; - int *aRight = &aIdx[nLeft]; - - SortByDistance(aLeft, nLeft, aDistance, aSpare); - SortByDistance(aRight, nRight, aDistance, aSpare); - - memcpy(aSpare, aLeft, sizeof(int)*nLeft); - aLeft = aSpare; - - while( iLeftnDim; iDim++){ - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]); - aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]); - } - } - for(iDim=0; iDimnDim; iDim++){ - aCenterCoord[iDim] = (aCenterCoord[iDim]/(nCell*(RtreeDValue)2)); - } - - for(ii=0; iinDim; iDim++){ - RtreeDValue coord = (DCOORD(aCell[ii].aCoord[iDim*2+1]) - - DCOORD(aCell[ii].aCoord[iDim*2])); - aDistance[ii] += (coord-aCenterCoord[iDim])*(coord-aCenterCoord[iDim]); - } - } - - SortByDistance(aOrder, nCell, aDistance, aSpare); - nodeZero(pRtree, pNode); - - for(ii=0; rc==SQLITE_OK && ii<(nCell-(RTREE_MINCELLS(pRtree)+1)); ii++){ - RtreeCell *p = &aCell[aOrder[ii]]; - nodeInsertCell(pRtree, pNode, p); - if( p->iRowid==pCell->iRowid ){ - if( iHeight==0 ){ - rc = rowidWrite(pRtree, p->iRowid, pNode->iNode); - }else{ - rc = parentWrite(pRtree, p->iRowid, pNode->iNode); - } - } - } - if( rc==SQLITE_OK ){ - rc = fixBoundingBox(pRtree, pNode); - } - for(; rc==SQLITE_OK && iiiNode currently contains - ** the height of the sub-tree headed by the cell. - */ - RtreeNode *pInsert; - RtreeCell *p = &aCell[aOrder[ii]]; - rc = ChooseLeaf(pRtree, p, iHeight, &pInsert); - if( rc==SQLITE_OK ){ - int rc2; - rc = rtreeInsertCell(pRtree, pInsert, p, iHeight); - rc2 = nodeRelease(pRtree, pInsert); - if( rc==SQLITE_OK ){ - rc = rc2; - } - } - } - - sqlite3_free(aCell); - return rc; -} - + /* ** Insert cell pCell into node pNode. Node pNode is the head of a ** subtree iHeight high (leaf nodes have iHeight==0). @@ -2989,12 +2848,7 @@ } } if( nodeInsertCell(pRtree, pNode, pCell) ){ - if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){ - rc = SplitNode(pRtree, pNode, pCell, iHeight); - }else{ - pRtree->iReinsertHeight = iHeight; - rc = Reinsert(pRtree, pNode, pCell, iHeight); - } + rc = SplitNode(pRtree, pNode, pCell, iHeight); }else{ rc = AdjustTree(pRtree, pNode, pCell); if( ALWAYS(rc==SQLITE_OK) ){ @@ -3337,7 +3191,6 @@ } if( rc==SQLITE_OK ){ int rc2; - pRtree->iReinsertHeight = -1; rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0); rc2 = nodeRelease(pRtree, pLeaf); if( rc==SQLITE_OK ){ @@ -3478,8 +3331,11 @@ return 0; } +/* Forward declaration */ +static int rtreeIntegrity(sqlite3_vtab*, const char*, const char*, int, char**); + static sqlite3_module rtreeModule = { - 3, /* iVersion */ + 4, /* iVersion */ rtreeCreate, /* xCreate - create a table */ rtreeConnect, /* xConnect - connect to an existing table */ rtreeBestIndex, /* xBestIndex - Determine search strategy */ @@ -3502,7 +3358,8 @@ rtreeSavepoint, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - rtreeShadowName /* xShadowName */ + rtreeShadowName, /* xShadowName */ + rtreeIntegrity /* xIntegrity */ }; static int rtreeSqlInit( @@ -3758,22 +3615,27 @@ } sqlite3_vtab_config(db, SQLITE_VTAB_CONSTRAINT_SUPPORT, 1); + sqlite3_vtab_config(db, SQLITE_VTAB_INNOCUOUS); + /* Allocate the sqlite3_vtab structure */ nDb = (int)strlen(argv[1]); nName = (int)strlen(argv[2]); - pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName+2); + pRtree = (Rtree *)sqlite3_malloc64(sizeof(Rtree)+nDb+nName*2+8); if( !pRtree ){ return SQLITE_NOMEM; } - memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2); + memset(pRtree, 0, sizeof(Rtree)+nDb+nName*2+8); pRtree->nBusy = 1; pRtree->base.pModule = &rtreeModule; pRtree->zDb = (char *)&pRtree[1]; pRtree->zName = &pRtree->zDb[nDb+1]; + pRtree->zNodeName = &pRtree->zName[nName+1]; pRtree->eCoordType = (u8)eCoordType; memcpy(pRtree->zDb, argv[1], nDb); memcpy(pRtree->zName, argv[2], nName); + memcpy(pRtree->zNodeName, argv[2], nName); + memcpy(&pRtree->zNodeName[nName], "_node", 6); /* Create/Connect to the underlying relational database schema. If @@ -4270,7 +4132,6 @@ ){ RtreeCheck check; /* Common context for various routines */ sqlite3_stmt *pStmt = 0; /* Used to find column count of rtree table */ - int bEnd = 0; /* True if transaction should be closed */ int nAux = 0; /* Number of extra columns. */ /* Initialize the context object */ @@ -4279,14 +4140,6 @@ check.zDb = zDb; check.zTab = zTab; - /* If there is not already an open transaction, open one now. This is - ** to ensure that the queries run as part of this integrity-check operate - ** on a consistent snapshot. */ - if( sqlite3_get_autocommit(db) ){ - check.rc = sqlite3_exec(db, "BEGIN", 0, 0, 0); - bEnd = 1; - } - /* Find the number of auxiliary columns */ if( check.rc==SQLITE_OK ){ pStmt = rtreeCheckPrepare(&check, "SELECT * FROM %Q.'%q_rowid'", zDb, zTab); @@ -4327,16 +4180,35 @@ sqlite3_finalize(check.aCheckMapping[0]); sqlite3_finalize(check.aCheckMapping[1]); - /* If one was opened, close the transaction */ - if( bEnd ){ - int rc = sqlite3_exec(db, "END", 0, 0, 0); - if( check.rc==SQLITE_OK ) check.rc = rc; - } *pzReport = check.zReport; return check.rc; } /* +** Implementation of the xIntegrity method for Rtree. +*/ +static int rtreeIntegrity( + sqlite3_vtab *pVtab, /* The virtual table to check */ + const char *zSchema, /* Schema in which the virtual table lives */ + const char *zName, /* Name of the virtual table */ + int isQuick, /* True for a quick_check */ + char **pzErr /* Write results here */ +){ + Rtree *pRtree = (Rtree*)pVtab; + int rc; + assert( pzErr!=0 && *pzErr==0 ); + UNUSED_PARAMETER(zSchema); + UNUSED_PARAMETER(zName); + UNUSED_PARAMETER(isQuick); + rc = rtreeCheckTable(pRtree->db, pRtree->zDb, pRtree->zName, pzErr); + if( rc==SQLITE_OK && *pzErr ){ + *pzErr = sqlite3_mprintf("In RTree %s.%s:\n%z", + pRtree->zDb, pRtree->zName, *pzErr); + } + return rc; +} + +/* ** Usage: ** ** rtreecheck(); diff -Nru sqlite3-3.42.0/ext/rtree/rtreecheck.test sqlite3-3.44.0-0/ext/rtree/rtreecheck.test --- sqlite3-3.42.0/ext/rtree/rtreecheck.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtreecheck.test 2023-11-04 14:23:58.000000000 +0000 @@ -78,6 +78,11 @@ SELECT rtreecheck('r1') } {{Dimension 0 of cell 0 on node 1 is corrupt Dimension 1 of cell 3 on node 1 is corrupt}} +do_execsql_test 2.3b { + PRAGMA integrity_check; +} {{In RTree main.r1: +Dimension 0 of cell 0 on node 1 is corrupt +Dimension 1 of cell 3 on node 1 is corrupt}} setup_simple_db do_execsql_test 2.4 { @@ -85,12 +90,21 @@ SELECT rtreecheck('r1') } {{Mapping (3 -> 1) missing from %_rowid table Wrong number of entries in %_rowid table - expected 5, actual 4}} +do_execsql_test 2.4b { + PRAGMA integrity_check +} {{In RTree main.r1: +Mapping (3 -> 1) missing from %_rowid table +Wrong number of entries in %_rowid table - expected 5, actual 4}} setup_simple_db do_execsql_test 2.5 { UPDATE r1_rowid SET nodeno=2 WHERE rowid=3; SELECT rtreecheck('r1') } {{Found (3 -> 2) in %_rowid table, expected (3 -> 1)}} +do_execsql_test 2.5b { + PRAGMA integrity_check +} {{In RTree main.r1: +Found (3 -> 2) in %_rowid table, expected (3 -> 1)}} reset_db do_execsql_test 3.0 { @@ -104,14 +118,16 @@ INSERT INTO r1 VALUES(7, 5, 0x00000080); INSERT INTO r1 VALUES(8, 5, 0x40490fdb); INSERT INTO r1 VALUES(9, 0x7f800000, 0x7f900000); - SELECT rtreecheck('r1') -} {ok} + SELECT rtreecheck('r1'); + PRAGMA integrity_check; +} {ok ok} do_execsql_test 3.1 { CREATE VIRTUAL TABLE r2 USING rtree_i32(id, x1, x2); INSERT INTO r2 VALUES(2, -1*(1<<31), -1*(1<<31)+5); - SELECT rtreecheck('r2') -} {ok} + SELECT rtreecheck('r2'); + PRAGMA integrity_check; +} {ok ok} sqlite3_db_config db DEFENSIVE 0 do_execsql_test 3.2 { @@ -125,6 +141,11 @@ UPDATE r2_node SET data = X'00001234'; SELECT rtreecheck('r2')!='ok'; } {1} +do_execsql_test 3.4 { + PRAGMA integrity_check; +} {{In RTree main.r2: +Node 1 is too small for cell count of 4660 (4 bytes) +Wrong number of entries in %_rowid table - expected 0, actual 1}} do_execsql_test 4.0 { CREATE TABLE notanrtree(i); @@ -181,4 +202,3 @@ } finish_test - diff -Nru sqlite3-3.42.0/ext/rtree/rtreedoc.test sqlite3-3.44.0-0/ext/rtree/rtreedoc.test --- sqlite3-3.42.0/ext/rtree/rtreedoc.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtreedoc.test 2023-11-04 14:23:58.000000000 +0000 @@ -601,11 +601,21 @@ SELECT A.id FROM demo_index AS A, demo_index AS B WHERE A.maxX>=B.minX AND A.minX<=B.maxX AND A.maxY>=B.minY AND A.minY<=B.maxY - AND B.id=28269; + AND B.id=28269 ORDER BY +A.id; } { - 28293 28216 28322 28286 28269 - 28215 28336 28262 28291 28320 - 28313 28298 28287 + 28215 + 28216 + 28262 + 28269 + 28286 + 28287 + 28291 + 28293 + 28298 + 28313 + 28320 + 28322 + 28336 } # EVIDENCE-OF: R-02723-34107 Note that it is not necessary for all @@ -1575,7 +1585,7 @@ do_test 3.6 { execsql { INSERT INTO rt2_parent VALUES(1000, 1000) } execsql { SELECT rtreecheck('rt2') } -} {{Wrong number of entries in %_parent table - expected 9, actual 10}} +} {{Wrong number of entries in %_parent table - expected 10, actual 11}} execsql ROLLBACK diff -Nru sqlite3-3.42.0/ext/rtree/rtreefuzz001.test sqlite3-3.44.0-0/ext/rtree/rtreefuzz001.test --- sqlite3-3.42.0/ext/rtree/rtreefuzz001.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtreefuzz001.test 2023-11-04 14:23:58.000000000 +0000 @@ -1043,7 +1043,7 @@ | end crash-2e81f5dce5cbd4.db}] execsql { PRAGMA writable_schema = 1;} catchsql {UPDATE t1 SET ex= ex ISNULL} -} {1 {database disk image is malformed}} +} {0 {}} do_test rtreefuzz001-600 { sqlite3 db {} diff -Nru sqlite3-3.42.0/ext/rtree/rtree_util.tcl sqlite3-3.44.0-0/ext/rtree/rtree_util.tcl --- sqlite3-3.42.0/ext/rtree/rtree_util.tcl 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/rtree/rtree_util.tcl 2023-11-04 14:23:58.000000000 +0000 @@ -192,6 +192,6 @@ } proc do_rtree_integrity_test {tn tbl} { - uplevel [list do_execsql_test $tn "SELECT rtreecheck('$tbl')" ok] + uplevel [list do_execsql_test $tn.1 "SELECT rtreecheck('$tbl')" ok] + uplevel [list do_execsql_test $tn.2 "PRAGMA integrity_check" ok] } - diff -Nru sqlite3-3.42.0/ext/session/session3.test sqlite3-3.44.0-0/ext/session/session3.test --- sqlite3-3.42.0/ext/session/session3.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/session/session3.test 2023-11-04 14:23:58.000000000 +0000 @@ -135,8 +135,8 @@ DROP TABLE t2; CREATE TABLE t2(a, b PRIMARY KEY, c, d); } - list [catch { S changeset } msg] $msg -} {1 SQLITE_SCHEMA} + catch { S changeset } +} {0} do_test 2.2.3 { S delete sqlite3session S db main @@ -167,8 +167,8 @@ CREATE TABLE t2(a, b PRIMARY KEY, c, d); INSERT INTO t2 VALUES(4, 5, 6, 7); } - list [catch { S changeset } msg] $msg -} {1 SQLITE_SCHEMA} + catch { S changeset } +} {0} do_test 2.3 { S delete diff -Nru sqlite3-3.42.0/ext/session/sessionalter.test sqlite3-3.44.0-0/ext/session/sessionalter.test --- sqlite3-3.42.0/ext/session/sessionalter.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/session/sessionalter.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,238 @@ +# 2023 October 02 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements that the sessions module interacts well with +# the ALTER TABLE ADD COLUMN command. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl + +ifcapable !session {finish_test; return} +set testprefix sessionalter + + +forcedelete test.db2 +sqlite3 db2 test.db2 + +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); +} + +do_execsql_test -db db2 1.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b, c DEFAULT 1234); +} + +do_then_apply_sql { + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); +} + +do_execsql_test -db db2 1.2 { + SELECT * FROM t1 +} { + 1 one 1234 + 2 two 1234 +} + +do_then_apply_sql { + UPDATE t1 SET b='four' WHERE a=2; +} + +do_execsql_test -db db2 1.3 { + SELECT * FROM t1 +} { + 1 one 1234 + 2 four 1234 +} + +do_then_apply_sql { + DELETE FROM t1 WHERE a=1; +} + +do_execsql_test -db db2 1.4 { + SELECT * FROM t1 +} { + 2 four 1234 +} + +db2 close + +#-------------------------------------------------------------------------- +reset_db + +do_execsql_test 2.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); +} + +do_test 2.1 { + sqlite3session S db main + S attach t1 + set {} {} +} {} +do_execsql_test 2.2 { + INSERT INTO t1 VALUES(1, 2); + ALTER TABLE t1 ADD COLUMN c DEFAULT 'abcd'; + INSERT INTO t1 VALUES(2, 3, 4); +} +do_changeset_test 2.3 S { + {INSERT t1 0 X.. {} {i 1 i 2 t abcd}} + {INSERT t1 0 X.. {} {i 2 i 3 i 4}} +} + +do_iterator_test 2.4 {} { + DELETE FROM t1 WHERE a=2; + ALTER TABLE t1 ADD COLUMN d DEFAULT 'abcd'; + ALTER TABLE t1 ADD COLUMN e DEFAULT 5; + ALTER TABLE t1 ADD COLUMN f DEFAULT 7.2; + -- INSERT INTO t1 VALUES(9, 9, 9, 9); +} { + {DELETE t1 0 X..... {i 2 i 3 i 4 t abcd i 5 f 7.2} {}} +} + +#------------------------------------------------------------------------- +# Tests of the sqlite3changegroup_xxx() APIs. +# +reset_db +do_execsql_test 3.0 { + CREATE TABLE t1(x INTEGER PRIMARY KEY, y); + CREATE TABLE t2(x PRIMARY KEY, y); + CREATE TABLE t3(x, y); + CREATE TABLE t4(y PRIMARY KEY, x) WITHOUT ROWID; + + INSERT INTO t1 VALUES(1, 2), (3, 4), (5, 6); + INSERT INTO t2 VALUES('one', 'two'), ('three', 'four'), ('five', 'six'); + INSERT INTO t3 VALUES(1, 2), (3, 4), (5, 6); + + INSERT INTO t4(x, y) VALUES(1, 2), (3, 4), (5, 6); +} + +db_save_and_close +foreach {tn sql1 at sql2} { + 1 { + INSERT INTO t1(x, y) VALUES(7, 8); + } { + ALTER TABLE t1 ADD COLUMN z DEFAULT 10; + } { + UPDATE t1 SET y=11 WHERE x=7; + } + + 2 { + UPDATE t2 SET y='two.two' WHERE x='one'; + DELETE FROM t2 WHERE x='five'; + INSERT INTO t2(x, y) VALUES('seven', 'eight'); + } { + ALTER TABLE t2 ADD COLUMN z; + ALTER TABLE t2 ADD COLUMN zz; + } { + } + + 3 { + DELETE FROM t2 WHERE x='five'; + } { + ALTER TABLE t2 ADD COLUMN z DEFAULT 'xyz'; + } { + } + + 4 { + UPDATE t2 SET y='two.two' WHERE x='three'; + } { + ALTER TABLE t2 ADD COLUMN z; + } { + UPDATE t2 SET z='abc' WHERE x='one'; + } + + 5* { + UPDATE t2 SET y='two.two' WHERE x='three'; + } { + ALTER TABLE t2 ADD COLUMN z DEFAULT 'defu1'; + } { + } + + 6* { + INSERT INTO t2(x, y) VALUES('nine', 'ten'); + } { + ALTER TABLE t2 ADD COLUMN z; + ALTER TABLE t2 ADD COLUMN a DEFAULT 'eelve'; + ALTER TABLE t2 ADD COLUMN b DEFAULT x'1234abcd'; + ALTER TABLE t2 ADD COLUMN c DEFAULT 4.2; + ALTER TABLE t2 ADD COLUMN d DEFAULT NULL; + } { + } + + 7 { + INSERT INTO t3(x, y) VALUES(7, 8); + UPDATE t3 SET y='fourteen' WHERE x=1; + DELETE FROM t3 WHERE x=3; + } { + ALTER TABLE t3 ADD COLUMN c; + } { + INSERT INTO t3(x, y, c) VALUES(9, 10, 11); + } + + 8 { + INSERT INTO t4(x, y) VALUES(7, 8); + UPDATE t4 SET y='fourteen' WHERE x=1; + DELETE FROM t4 WHERE x=3; + } { + ALTER TABLE t4 ADD COLUMN c; + } { + INSERT INTO t4(x, y, c) VALUES(9, 10, 11); + } +} { + foreach {tn2 cmd} { + 1 changeset_from_sql + 2 patchset_from_sql + } { + db_restore_and_reopen + + set C1 [$cmd $sql1] + execsql $at + set C2 [$cmd $sql2] + + sqlite3changegroup grp + grp schema db main + grp add $C1 + grp add $C2 + set T1 [grp output] + grp delete + + db_restore_and_reopen + execsql $at + set T2 [$cmd "$sql1 ; $sql2"] + + if {[string range $tn end end]!="*"} { + do_test 3.1.$tn.$tn2.1 { changeset_to_list $T1 } [changeset_to_list $T2] + set testname "$tn.$tn2" + } else { + set testname "[string range $tn 0 end-1].$tn2" + } + + db_restore_and_reopen + proc xConflict {args} { return "REPLACE" } + sqlite3changeset_apply_v2 db $T1 xConflict + set S1 [scksum db main] + + db_restore_and_reopen + sqlite3changeset_apply_v2 db $T2 xConflict + set S2 [scksum db main] + + # if { $tn==7 } { puts [changeset_to_list $T1] } + + do_test 3.1.$tn.2 { set S1 } $S2 + } +} + + +finish_test + diff -Nru sqlite3-3.42.0/ext/session/sessionfault3.test sqlite3-3.44.0-0/ext/session/sessionfault3.test --- sqlite3-3.42.0/ext/session/sessionfault3.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/session/sessionfault3.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,59 @@ +# 2016 October 6 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# The focus of this file is testing the session module. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} +set testprefix sessionfault3 + +do_execsql_test 1.0 { + CREATE TABLE t1(a, b, PRIMARY KEY(a)); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); + INSERT INTO t1 VALUES('five', 'six'); +} + +set C1 [changeset_from_sql { + INSERT INTO t1 VALUES('seven', 'eight'); + UPDATE t1 SET b=6 WHERE a='five'; + DELETE FROM t1 WHERE a=1; +}] + +do_execsql_test 1.1 { + ALTER TABLE t1 ADD COLUMN d DEFAULT 123; + ALTER TABLE t1 ADD COLUMN e DEFAULT 'string'; +} + +set C2 [changeset_from_sql { + UPDATE t1 SET e='new value' WHERE a='seven'; + INSERT INTO t1 VALUES(0, 0, 0, 0); +}] + +do_faultsim_test 1 -faults oom* -prep { + sqlite3changegroup G +} -body { + G schema db main + G add $::C1 + G add $::C2 + G output + set {} {} +} -test { + catch { G delete } + faultsim_test_result {0 {}} {1 SQLITE_NOMEM} +} + +finish_test diff -Nru sqlite3-3.42.0/ext/session/sessionnoact.test sqlite3-3.44.0-0/ext/session/sessionnoact.test --- sqlite3-3.42.0/ext/session/sessionnoact.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/session/sessionnoact.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,110 @@ +# 2023 October 20 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. +# + +if {![info exists testdir]} { + set testdir [file join [file dirname [info script]] .. .. test] +} +source [file join [file dirname [info script]] session_common.tcl] +source $testdir/tester.tcl +ifcapable !session {finish_test; return} + +set testprefix sessionnoact + +do_execsql_test 1.0 { + CREATE TABLE p1(a INTEGER PRIMARY KEY, b, c UNIQUE); + INSERT INTO p1 VALUES(1, 1, 'one'); + INSERT INTO p1 VALUES(2, 2, 'two'); + INSERT INTO p1 VALUES(3, 3, 'three'); + INSERT INTO p1 VALUES(4, 4, 'four'); +} + +db_save + +set C [changeset_from_sql { + DELETE FROM p1 WHERE a=2; + UPDATE p1 SET c='six' WHERE a=3; + INSERT INTO p1 VALUES(5, 5, 'two'); + INSERT INTO p1 VALUES(6, 6, 'three'); +}] + +db_restore_and_reopen + +do_execsql_test 1.1 { + CREATE TABLE c1(x INTEGER PRIMARY KEY, y, + FOREIGN KEY(y) REFERENCES p1(c) ON DELETE CASCADE ON UPDATE SET NULL + ); + + INSERT INTO c1 VALUES(10, 'one'); + INSERT INTO c1 VALUES(20, 'two'); + INSERT INTO c1 VALUES(30, 'three'); + INSERT INTO c1 VALUES(40, 'four'); +} + +db_save + +do_execsql_test 1.2 { + PRAGMA foreign_keys = 1; +} + +set ::nConflict 0 +proc conflict {args} { + incr ::nConflict + return "OMIT" +} + +sqlite3changeset_apply_v2 db $C conflict + +do_execsql_test 1.3 { + SELECT * FROM c1 +} { + 10 one + 30 {} + 40 four +} + +db_restore_and_reopen + +do_execsql_test 1.4 { + PRAGMA foreign_keys = 1; +} + +do_execsql_test 1.5 { + UPDATE p1 SET c=12345 WHERE a = 45; +} + +sqlite3changeset_apply_v2 -noaction db $C conflict +do_execsql_test 1.6 { + SELECT * FROM c1 +} { + 10 one + 20 two + 30 three + 40 four +} + +do_execsql_test 1.7 { + PRAGMA foreign_keys = 1; + UPDATE p1 SET c = 'ten' WHERE c='two'; + SELECT * FROM c1; +} { + 10 one + 20 {} + 30 three + 40 four +} + +do_execsql_test 1.8 { + PRAGMA foreign_key_check +} + +finish_test diff -Nru sqlite3-3.42.0/ext/session/sqlite3session.c sqlite3-3.44.0-0/ext/session/sqlite3session.c --- sqlite3-3.42.0/ext/session/sqlite3session.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/session/sqlite3session.c 2023-11-04 14:23:58.000000000 +0000 @@ -119,6 +119,18 @@ ** The data associated with each hash-table entry is a structure containing ** a subset of the initial values that the modified row contained at the ** start of the session. Or no initial values if the row was inserted. +** +** pDfltStmt: +** This is only used by the sqlite3changegroup_xxx() APIs, not by +** regular sqlite3_session objects. It is a SELECT statement that +** selects the default value for each table column. For example, +** if the table is +** +** CREATE TABLE xx(a DEFAULT 1, b, c DEFAULT 'abc') +** +** then this variable is the compiled version of: +** +** SELECT 1, NULL, 'abc' */ struct SessionTable { SessionTable *pNext; @@ -127,10 +139,12 @@ int bStat1; /* True if this is sqlite_stat1 */ int bRowid; /* True if this table uses rowid for PK */ const char **azCol; /* Column names */ + const char **azDflt; /* Default value expressions */ u8 *abPK; /* Array of primary key flags */ int nEntry; /* Total number of entries in hash table */ int nChange; /* Size of apChange[] array */ SessionChange **apChange; /* Hash table buckets */ + sqlite3_stmt *pDfltStmt; }; /* @@ -299,6 +313,7 @@ struct SessionChange { u8 op; /* One of UPDATE, DELETE, INSERT */ u8 bIndirect; /* True if this change is "indirect" */ + u16 nRecordField; /* Number of fields in aRecord[] */ int nMaxSize; /* Max size of eventual changeset record */ int nRecord; /* Number of bytes in buffer aRecord[] */ u8 *aRecord; /* Buffer containing old.* record */ @@ -324,7 +339,7 @@ ** Read a varint value from aBuf[] into *piVal. Return the number of ** bytes read. */ -static int sessionVarintGet(u8 *aBuf, int *piVal){ +static int sessionVarintGet(const u8 *aBuf, int *piVal){ return getVarint32(aBuf, *piVal); } @@ -587,9 +602,11 @@ ** Return the number of bytes of space occupied by the value (including ** the type byte). */ -static int sessionSerialLen(u8 *a){ - int e = *a; +static int sessionSerialLen(const u8 *a){ + int e; int n; + assert( a!=0 ); + e = *a; if( e==0 || e==0xFF ) return 1; if( e==SQLITE_NULL ) return 1; if( e==SQLITE_INTEGER || e==SQLITE_FLOAT ) return 9; @@ -891,6 +908,7 @@ rc = pSession->hook.xOld(pSession->hook.pCtx, iCol, &pVal); } assert( rc==SQLITE_OK ); + (void)rc; /* Suppress warning about unused variable */ if( sqlite3_value_type(pVal)!=eType ) return 0; /* A SessionChange object never has a NULL value in a PK column */ @@ -993,13 +1011,14 @@ ** ** For example, if the table is declared as: ** -** CREATE TABLE tbl1(w, x, y, z, PRIMARY KEY(w, z)); +** CREATE TABLE tbl1(w, x DEFAULT 'abc', y, z, PRIMARY KEY(w, z)); ** -** Then the four output variables are populated as follows: +** Then the five output variables are populated as follows: ** ** *pnCol = 4 ** *pzTab = "tbl1" ** *pazCol = {"w", "x", "y", "z"} +** *pazDflt = {NULL, 'abc', NULL, NULL} ** *pabPK = {1, 0, 0, 1} ** ** All returned buffers are part of the same single allocation, which must @@ -1013,6 +1032,7 @@ int *pnCol, /* OUT: number of columns */ const char **pzTab, /* OUT: Copy of zThis */ const char ***pazCol, /* OUT: Array of column names for table */ + const char ***pazDflt, /* OUT: Array of default value expressions */ u8 **pabPK, /* OUT: Array of booleans - true for PK col */ int *pbRowid /* OUT: True if only PK is a rowid */ ){ @@ -1025,11 +1045,18 @@ int i; u8 *pAlloc = 0; char **azCol = 0; + char **azDflt = 0; u8 *abPK = 0; int bRowid = 0; /* Set to true to use rowid as PK */ assert( pazCol && pabPK ); + *pazCol = 0; + *pabPK = 0; + *pnCol = 0; + if( pzTab ) *pzTab = 0; + if( pazDflt ) *pazDflt = 0; + nThis = sqlite3Strlen30(zThis); if( nThis==12 && 0==sqlite3_stricmp("sqlite_stat1", zThis) ){ rc = sqlite3_table_column_metadata(db, zDb, zThis, 0, 0, 0, 0, 0, 0); @@ -1043,39 +1070,28 @@ }else if( rc==SQLITE_ERROR ){ zPragma = sqlite3_mprintf(""); }else{ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return rc; } }else{ zPragma = sqlite3_mprintf("PRAGMA '%q'.table_info('%q')", zDb, zThis); } if( !zPragma ){ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return SQLITE_NOMEM; } rc = sqlite3_prepare_v2(db, zPragma, -1, &pStmt, 0); sqlite3_free(zPragma); if( rc!=SQLITE_OK ){ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; return rc; } nByte = nThis + 1; bRowid = (pbRowid!=0); while( SQLITE_ROW==sqlite3_step(pStmt) ){ - nByte += sqlite3_column_bytes(pStmt, 1); + nByte += sqlite3_column_bytes(pStmt, 1); /* name */ + nByte += sqlite3_column_bytes(pStmt, 4); /* dflt_value */ nDbCol++; - if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; + if( sqlite3_column_int(pStmt, 5) ) bRowid = 0; /* pk */ } if( nDbCol==0 ) bRowid = 0; nDbCol += bRowid; @@ -1083,15 +1099,18 @@ rc = sqlite3_reset(pStmt); if( rc==SQLITE_OK ){ - nByte += nDbCol * (sizeof(const char *) + sizeof(u8) + 1); + nByte += nDbCol * (sizeof(const char *)*2 + sizeof(u8) + 1 + 1); pAlloc = sessionMalloc64(pSession, nByte); if( pAlloc==0 ){ rc = SQLITE_NOMEM; + }else{ + memset(pAlloc, 0, nByte); } } if( rc==SQLITE_OK ){ azCol = (char **)pAlloc; - pAlloc = (u8 *)&azCol[nDbCol]; + azDflt = (char**)&azCol[nDbCol]; + pAlloc = (u8 *)&azDflt[nDbCol]; abPK = (u8 *)pAlloc; pAlloc = &abPK[nDbCol]; if( pzTab ){ @@ -1111,11 +1130,21 @@ } while( SQLITE_ROW==sqlite3_step(pStmt) ){ int nName = sqlite3_column_bytes(pStmt, 1); + int nDflt = sqlite3_column_bytes(pStmt, 4); const unsigned char *zName = sqlite3_column_text(pStmt, 1); + const unsigned char *zDflt = sqlite3_column_text(pStmt, 4); + if( zName==0 ) break; memcpy(pAlloc, zName, nName+1); azCol[i] = (char *)pAlloc; pAlloc += nName+1; + if( zDflt ){ + memcpy(pAlloc, zDflt, nDflt+1); + azDflt[i] = (char *)pAlloc; + pAlloc += nDflt+1; + }else{ + azDflt[i] = 0; + } abPK[i] = sqlite3_column_int(pStmt, 5); i++; } @@ -1126,14 +1155,11 @@ ** free any allocation made. An error code will be returned in this case. */ if( rc==SQLITE_OK ){ - *pazCol = (const char **)azCol; + *pazCol = (const char**)azCol; + if( pazDflt ) *pazDflt = (const char**)azDflt; *pabPK = abPK; *pnCol = nDbCol; }else{ - *pazCol = 0; - *pabPK = 0; - *pnCol = 0; - if( pzTab ) *pzTab = 0; sessionFree(pSession, azCol); } if( pbRowid ) *pbRowid = bRowid; @@ -1142,10 +1168,9 @@ } /* -** 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, initalize the SessionTable.nCol, azCol[] and -** abPK[] arrays accordingly. +** This function is called to initialize the SessionTable.nCol, azCol[] +** abPK[] and azDflt[] members of SessionTable object pTab. If these +** fields are already initilialized, this function is a no-op. ** ** 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 @@ -1153,15 +1178,22 @@ ** indicate that updates on this table should be ignored. SessionTable.abPK ** is set to NULL in this case. */ -static int sessionInitTable(sqlite3_session *pSession, SessionTable *pTab){ +static int sessionInitTable( + sqlite3_session *pSession, /* Optional session handle */ + SessionTable *pTab, /* Table object to initialize */ + sqlite3 *db, /* Database handle to read schema from */ + const char *zDb /* Name of db - "main", "temp" etc. */ +){ + int rc = SQLITE_OK; + if( pTab->nCol==0 ){ u8 *abPK; assert( pTab->azCol==0 || pTab->abPK==0 ); - pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, - pTab->zName, &pTab->nCol, 0, &pTab->azCol, &abPK, - (pSession->bImplicitPK ? &pTab->bRowid : 0) + rc = sessionTableInfo(pSession, db, zDb, + pTab->zName, &pTab->nCol, 0, &pTab->azCol, &pTab->azDflt, &abPK, + ((pSession==0 || pSession->bImplicitPK) ? &pTab->bRowid : 0) ); - if( pSession->rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ int i; for(i=0; inCol; i++){ if( abPK[i] ){ @@ -1173,14 +1205,321 @@ pTab->bStat1 = 1; } - if( pSession->bEnableSize ){ + if( pSession && pSession->bEnableSize ){ pSession->nMaxChangesetSize += ( 1 + sessionVarintLen(pTab->nCol) + pTab->nCol + strlen(pTab->zName)+1 ); } } } - return (pSession->rc || pTab->abPK==0); + + if( pSession ){ + pSession->rc = rc; + return (rc || pTab->abPK==0); + } + return rc; +} + +/* +** Re-initialize table object pTab. +*/ +static int sessionReinitTable(sqlite3_session *pSession, SessionTable *pTab){ + int nCol = 0; + const char **azCol = 0; + const char **azDflt = 0; + u8 *abPK = 0; + int bRowid = 0; + + assert( pSession->rc==SQLITE_OK ); + + pSession->rc = sessionTableInfo(pSession, pSession->db, pSession->zDb, + pTab->zName, &nCol, 0, &azCol, &azDflt, &abPK, + (pSession->bImplicitPK ? &bRowid : 0) + ); + if( pSession->rc==SQLITE_OK ){ + if( pTab->nCol>nCol || pTab->bRowid!=bRowid ){ + pSession->rc = SQLITE_SCHEMA; + }else{ + int ii; + int nOldCol = pTab->nCol; + for(ii=0; iinCol ){ + if( pTab->abPK[ii]!=abPK[ii] ){ + pSession->rc = SQLITE_SCHEMA; + } + }else if( abPK[ii] ){ + pSession->rc = SQLITE_SCHEMA; + } + } + + if( pSession->rc==SQLITE_OK ){ + const char **a = pTab->azCol; + pTab->azCol = azCol; + pTab->nCol = nCol; + pTab->azDflt = azDflt; + pTab->abPK = abPK; + azCol = a; + } + if( pSession->bEnableSize ){ + pSession->nMaxChangesetSize += (nCol - nOldCol); + pSession->nMaxChangesetSize += sessionVarintLen(nCol); + pSession->nMaxChangesetSize -= sessionVarintLen(nOldCol); + } + } + } + + sqlite3_free((char*)azCol); + return pSession->rc; +} + +/* +** Session-change object (*pp) contains an old.* record with fewer than +** nCol fields. This function updates it with the default values for +** the missing fields. +*/ +static void sessionUpdateOneChange( + sqlite3_session *pSession, /* For memory accounting */ + int *pRc, /* IN/OUT: Error code */ + SessionChange **pp, /* IN/OUT: Change object to update */ + int nCol, /* Number of columns now in table */ + sqlite3_stmt *pDflt /* SELECT */ +){ + SessionChange *pOld = *pp; + + while( pOld->nRecordFieldnRecordField; + int eType = sqlite3_column_type(pDflt, iField); + switch( eType ){ + case SQLITE_NULL: + nIncr = 1; + break; + case SQLITE_INTEGER: + case SQLITE_FLOAT: + nIncr = 9; + break; + default: { + int n = sqlite3_column_bytes(pDflt, iField); + nIncr = 1 + sessionVarintLen(n) + n; + assert( eType==SQLITE_TEXT || eType==SQLITE_BLOB ); + break; + } + } + + nByte = nIncr + (sizeof(SessionChange) + pOld->nRecord); + pNew = sessionMalloc64(pSession, nByte); + if( pNew==0 ){ + *pRc = SQLITE_NOMEM; + return; + }else{ + memcpy(pNew, pOld, sizeof(SessionChange)); + pNew->aRecord = (u8*)&pNew[1]; + memcpy(pNew->aRecord, pOld->aRecord, pOld->nRecord); + pNew->aRecord[pNew->nRecord++] = (u8)eType; + switch( eType ){ + case SQLITE_INTEGER: { + i64 iVal = sqlite3_column_int64(pDflt, iField); + sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); + pNew->nRecord += 8; + break; + } + + case SQLITE_FLOAT: { + double rVal = sqlite3_column_double(pDflt, iField); + i64 iVal = 0; + memcpy(&iVal, &rVal, sizeof(rVal)); + sessionPutI64(&pNew->aRecord[pNew->nRecord], iVal); + pNew->nRecord += 8; + break; + } + + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pDflt, iField); + const char *z = (const char*)sqlite3_column_text(pDflt, iField); + pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); + memcpy(&pNew->aRecord[pNew->nRecord], z, n); + pNew->nRecord += n; + break; + } + + case SQLITE_BLOB: { + int n = sqlite3_column_bytes(pDflt, iField); + const u8 *z = (const u8*)sqlite3_column_blob(pDflt, iField); + pNew->nRecord += sessionVarintPut(&pNew->aRecord[pNew->nRecord], n); + memcpy(&pNew->aRecord[pNew->nRecord], z, n); + pNew->nRecord += n; + break; + } + + default: + assert( eType==SQLITE_NULL ); + break; + } + + sessionFree(pSession, pOld); + *pp = pOld = pNew; + pNew->nRecordField++; + pNew->nMaxSize += nIncr; + if( pSession ){ + pSession->nMaxChangesetSize += nIncr; + } + } + } +} + +/* +** Ensure that there is room in the buffer to append nByte bytes of data. +** If not, use sqlite3_realloc() to grow the buffer so that there is. +** +** If successful, return zero. Otherwise, if an OOM condition is encountered, +** set *pRc to SQLITE_NOMEM and return non-zero. +*/ +static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ +#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) + i64 nReq = p->nBuf + nByte; + if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ + u8 *aNew; + i64 nNew = p->nAlloc ? p->nAlloc : 128; + + do { + nNew = nNew*2; + }while( nNewSESSION_MAX_BUFFER_SZ ){ + nNew = SESSION_MAX_BUFFER_SZ; + if( nNewaBuf, nNew); + if( 0==aNew ){ + *pRc = SQLITE_NOMEM; + }else{ + p->aBuf = aNew; + p->nAlloc = nNew; + } + } + return (*pRc!=SQLITE_OK); +} + + +/* +** This function is a no-op if *pRc is other than SQLITE_OK when it is +** called. Otherwise, append a string to the buffer. All bytes in the string +** up to (but not including) the nul-terminator are written to the buffer. +** +** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before +** returning. +*/ +static void sessionAppendStr( + SessionBuffer *p, + const char *zStr, + int *pRc +){ + int nStr = sqlite3Strlen30(zStr); + if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ + memcpy(&p->aBuf[p->nBuf], zStr, nStr); + p->nBuf += nStr; + p->aBuf[p->nBuf] = 0x00; + } +} + +/* +** Format a string using printf() style formatting and then append it to the +** buffer using sessionAppendString(). +*/ +static void sessionAppendPrintf( + SessionBuffer *p, /* Buffer to append to */ + int *pRc, + const char *zFmt, + ... +){ + if( *pRc==SQLITE_OK ){ + char *zApp = 0; + va_list ap; + va_start(ap, zFmt); + zApp = sqlite3_vmprintf(zFmt, ap); + if( zApp==0 ){ + *pRc = SQLITE_NOMEM; + }else{ + sessionAppendStr(p, zApp, pRc); + } + va_end(ap); + sqlite3_free(zApp); + } +} + +/* +** Prepare a statement against database handle db that SELECTs a single +** row containing the default values for each column in table pTab. For +** example, if pTab is declared as: +** +** CREATE TABLE pTab(a PRIMARY KEY, b DEFAULT 123, c DEFAULT 'abcd'); +** +** Then this function prepares and returns the SQL statement: +** +** SELECT NULL, 123, 'abcd'; +*/ +static int sessionPrepareDfltStmt( + sqlite3 *db, /* Database handle */ + SessionTable *pTab, /* Table to prepare statement for */ + sqlite3_stmt **ppStmt /* OUT: Statement handle */ +){ + SessionBuffer sql = {0,0,0}; + int rc = SQLITE_OK; + const char *zSep = " "; + int ii = 0; + + *ppStmt = 0; + sessionAppendPrintf(&sql, &rc, "SELECT"); + for(ii=0; iinCol; ii++){ + const char *zDflt = pTab->azDflt[ii] ? pTab->azDflt[ii] : "NULL"; + sessionAppendPrintf(&sql, &rc, "%s%s", zSep, zDflt); + zSep = ", "; + } + if( rc==SQLITE_OK ){ + rc = sqlite3_prepare_v2(db, (const char*)sql.aBuf, -1, ppStmt, 0); + } + sqlite3_free(sql.aBuf); + + return rc; +} + +/* +** Table pTab has one or more existing change-records with old.* records +** with fewer than pTab->nCol columns. This function updates all such +** change-records with the default values for the missing columns. +*/ +static int sessionUpdateChanges(sqlite3_session *pSession, SessionTable *pTab){ + sqlite3_stmt *pStmt = 0; + int rc = pSession->rc; + + rc = sessionPrepareDfltStmt(pSession->db, pTab, &pStmt); + if( rc==SQLITE_OK && SQLITE_ROW==sqlite3_step(pStmt) ){ + int ii = 0; + SessionChange **pp = 0; + for(ii=0; iinChange; ii++){ + for(pp=&pTab->apChange[ii]; *pp; pp=&((*pp)->pNext)){ + if( (*pp)->nRecordField!=pTab->nCol ){ + sessionUpdateOneChange(pSession, &rc, pp, pTab->nCol, pStmt); + } + } + } + } + + pSession->rc = rc; + rc = sqlite3_finalize(pStmt); + if( pSession->rc==SQLITE_OK ) pSession->rc = rc; + return pSession->rc; } /* @@ -1343,16 +1682,22 @@ int iHash; int bNull = 0; int rc = SQLITE_OK; + int nExpect = 0; SessionStat1Ctx stat1 = {{0,0,0,0,0},0}; if( pSession->rc ) return; /* Load table details if required */ - if( sessionInitTable(pSession, pTab) ) return; + if( sessionInitTable(pSession, pTab, pSession->db, pSession->zDb) ) return; /* Check the number of columns in this xPreUpdate call matches the ** number of columns in the table. */ - if( (pTab->nCol-pTab->bRowid)!=pSession->hook.xCount(pSession->hook.pCtx) ){ + nExpect = pSession->hook.xCount(pSession->hook.pCtx); + if( (pTab->nCol-pTab->bRowid)nCol-pTab->bRowid)!=nExpect ){ pSession->rc = SQLITE_SCHEMA; return; } @@ -1429,7 +1774,7 @@ } /* Allocate the change object */ - pC = (SessionChange *)sessionMalloc64(pSession, nByte); + pC = (SessionChange*)sessionMalloc64(pSession, nByte); if( !pC ){ rc = SQLITE_NOMEM; goto error_out; @@ -1462,6 +1807,7 @@ if( pSession->bIndirect || pSession->hook.xDepth(pSession->hook.pCtx) ){ pC->bIndirect = 1; } + pC->nRecordField = pTab->nCol; pC->nRecord = nByte; pC->op = op; pC->pNext = pTab->apChange[iHash]; @@ -1841,7 +2187,7 @@ /* Locate and if necessary initialize the target table object */ rc = sessionFindTable(pSession, zTbl, &pTo); if( pTo==0 ) goto diff_out; - if( sessionInitTable(pSession, pTo) ){ + if( sessionInitTable(pSession, pTo, pSession->db, pSession->zDb) ){ rc = pSession->rc; goto diff_out; } @@ -1854,7 +2200,7 @@ int bRowid = 0; u8 *abPK; const char **azCol = 0; - rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, &abPK, + rc = sessionTableInfo(0, db, zFrom, zTbl, &nCol, 0, &azCol, 0, &abPK, pSession->bImplicitPK ? &bRowid : 0 ); if( rc==SQLITE_OK ){ @@ -1969,6 +2315,7 @@ sessionFree(pSession, p); } } + sqlite3_finalize(pTab->pDfltStmt); sessionFree(pSession, (char*)pTab->azCol); /* cast works around VC++ bug */ sessionFree(pSession, pTab->apChange); sessionFree(pSession, pTab); @@ -2003,7 +2350,7 @@ /* Assert that all allocations have been freed and then free the ** session object itself. */ - assert( pSession->nMalloc==0 ); + // assert( pSession->nMalloc==0 ); sqlite3_free(pSession); } @@ -2075,48 +2422,6 @@ } /* -** Ensure that there is room in the buffer to append nByte bytes of data. -** If not, use sqlite3_realloc() to grow the buffer so that there is. -** -** If successful, return zero. Otherwise, if an OOM condition is encountered, -** set *pRc to SQLITE_NOMEM and return non-zero. -*/ -static int sessionBufferGrow(SessionBuffer *p, i64 nByte, int *pRc){ -#define SESSION_MAX_BUFFER_SZ (0x7FFFFF00 - 1) - i64 nReq = p->nBuf + nByte; - if( *pRc==SQLITE_OK && nReq>p->nAlloc ){ - u8 *aNew; - i64 nNew = p->nAlloc ? p->nAlloc : 128; - - do { - nNew = nNew*2; - }while( nNewSESSION_MAX_BUFFER_SZ ){ - nNew = SESSION_MAX_BUFFER_SZ; - if( nNewaBuf, nNew); - if( 0==aNew ){ - *pRc = SQLITE_NOMEM; - }else{ - p->aBuf = aNew; - p->nAlloc = nNew; - } - } - return (*pRc!=SQLITE_OK); -} - -/* ** Append the value passed as the second argument to the buffer passed ** as the first. ** @@ -2186,27 +2491,6 @@ /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is -** called. Otherwise, append a string to the buffer. All bytes in the string -** up to (but not including) the nul-terminator are written to the buffer. -** -** If an OOM condition is encountered, set *pRc to SQLITE_NOMEM before -** returning. -*/ -static void sessionAppendStr( - SessionBuffer *p, - const char *zStr, - int *pRc -){ - int nStr = sqlite3Strlen30(zStr); - if( 0==sessionBufferGrow(p, nStr+1, pRc) ){ - memcpy(&p->aBuf[p->nBuf], zStr, nStr); - p->nBuf += nStr; - p->aBuf[p->nBuf] = 0x00; - } -} - -/* -** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string representation of integer iVal ** to the buffer. No nul-terminator is written. ** @@ -2223,27 +2507,6 @@ sessionAppendStr(p, aBuf, pRc); } -static void sessionAppendPrintf( - SessionBuffer *p, /* Buffer to append to */ - int *pRc, - const char *zFmt, - ... -){ - if( *pRc==SQLITE_OK ){ - char *zApp = 0; - va_list ap; - va_start(ap, zFmt); - zApp = sqlite3_vmprintf(zFmt, ap); - if( zApp==0 ){ - *pRc = SQLITE_NOMEM; - }else{ - sessionAppendStr(p, zApp, pRc); - } - va_end(ap); - sqlite3_free(zApp); - } -} - /* ** This function is a no-op if *pRc is other than SQLITE_OK when it is ** called. Otherwise, append the string zStr enclosed in quotes (") and @@ -2734,26 +2997,16 @@ for(pTab=pSession->pTable; rc==SQLITE_OK && pTab; pTab=pTab->pNext){ if( pTab->nEntry ){ const char *zName = pTab->zName; - int nCol = 0; /* Number of columns in table */ - u8 *abPK = 0; /* Primary key array */ - const char **azCol = 0; /* Table columns */ int i; /* Used to iterate through hash buckets */ sqlite3_stmt *pSel = 0; /* SELECT statement to query table pTab */ int nRewind = buf.nBuf; /* Initial size of write buffer */ int nNoop; /* Size of buffer after writing tbl header */ - int bRowid = 0; + int nOldCol = pTab->nCol; /* Check the table schema is still Ok. */ - rc = sessionTableInfo( - 0, db, pSession->zDb, zName, &nCol, 0, &azCol, &abPK, - (pSession->bImplicitPK ? &bRowid : 0) - ); - if( rc==SQLITE_OK && ( - pTab->nCol!=nCol - || pTab->bRowid!=bRowid - || memcmp(abPK, pTab->abPK, nCol) - )){ - rc = SQLITE_SCHEMA; + rc = sessionReinitTable(pSession, pTab); + if( rc==SQLITE_OK && pTab->nCol!=nOldCol ){ + rc = sessionUpdateChanges(pSession, pTab); } /* Write a table header */ @@ -2761,8 +3014,8 @@ /* Build and compile a statement to execute: */ if( rc==SQLITE_OK ){ - rc = sessionSelectStmt( - db, 0, pSession->zDb, zName, bRowid, nCol, azCol, abPK, &pSel + rc = sessionSelectStmt(db, 0, pSession->zDb, + zName, pTab->bRowid, pTab->nCol, pTab->azCol, pTab->abPK, &pSel ); } @@ -2771,22 +3024,22 @@ SessionChange *p; /* Used to iterate through changes */ for(p=pTab->apChange[i]; rc==SQLITE_OK && p; p=p->pNext){ - rc = sessionSelectBind(pSel, nCol, abPK, p); + rc = sessionSelectBind(pSel, pTab->nCol, pTab->abPK, p); if( rc!=SQLITE_OK ) continue; if( sqlite3_step(pSel)==SQLITE_ROW ){ if( p->op==SQLITE_INSERT ){ int iCol; sessionAppendByte(&buf, SQLITE_INSERT, &rc); sessionAppendByte(&buf, p->bIndirect, &rc); - for(iCol=0; iColnCol; iCol++){ sessionAppendCol(&buf, pSel, iCol, &rc); } }else{ - assert( abPK!=0 ); /* Because sessionSelectStmt() returned ok */ - rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, abPK); + assert( pTab->abPK!=0 ); + rc = sessionAppendUpdate(&buf, bPatchset, pSel, p, pTab->abPK); } }else if( p->op!=SQLITE_INSERT ){ - rc = sessionAppendDelete(&buf, bPatchset, p, nCol, abPK); + rc = sessionAppendDelete(&buf, bPatchset, p, pTab->nCol,pTab->abPK); } if( rc==SQLITE_OK ){ rc = sqlite3_reset(pSel); @@ -2811,7 +3064,6 @@ if( buf.nBuf==nNoop ){ buf.nBuf = nRewind; } - sqlite3_free((char*)azCol); /* cast works around VC++ bug */ } } @@ -3235,15 +3487,19 @@ } } if( eType==SQLITE_INTEGER || eType==SQLITE_FLOAT ){ - sqlite3_int64 v = sessionGetI64(aVal); - if( eType==SQLITE_INTEGER ){ - sqlite3VdbeMemSetInt64(apOut[i], v); + if( (pIn->nData-pIn->iNext)<8 ){ + rc = SQLITE_CORRUPT_BKPT; }else{ - double d; - memcpy(&d, &v, 8); - sqlite3VdbeMemSetDouble(apOut[i], d); + sqlite3_int64 v = sessionGetI64(aVal); + if( eType==SQLITE_INTEGER ){ + sqlite3VdbeMemSetInt64(apOut[i], v); + }else{ + double d; + memcpy(&d, &v, 8); + sqlite3VdbeMemSetDouble(apOut[i], d); + } + pIn->iNext += 8; } - pIn->iNext += 8; } } } @@ -4936,7 +5192,7 @@ sqlite3changeset_pk(pIter, &abPK, 0); rc = sessionTableInfo(0, db, "main", zNew, - &sApply.nCol, &zTab, &sApply.azCol, &sApply.abPK, &sApply.bRowid + &sApply.nCol, &zTab, &sApply.azCol, 0, &sApply.abPK, &sApply.bRowid ); if( rc!=SQLITE_OK ) break; for(i=0; iflags & SQLITE_FkNoAction; + + if( flags & SQLITE_CHANGESETAPPLY_FKNOACTION ){ + db->flags |= ((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } + if( rc==SQLITE_OK ){ rc = sessionChangesetApply( db, pIter, xFilter, xConflict, pCtx, ppRebase, pnRebase, flags ); } + + if( (flags & SQLITE_CHANGESETAPPLY_FKNOACTION) && savedFlag==0 ){ + assert( db->flags & SQLITE_FkNoAction ); + db->flags &= ~((u64)SQLITE_FkNoAction); + db->aDb[0].pSchema->schema_cookie -= 32; + } return rc; } @@ -5160,6 +5429,9 @@ int rc; /* Error code */ int bPatch; /* True to accumulate patchsets */ SessionTable *pList; /* List of tables in current patch */ + + sqlite3 *db; /* Configured by changegroup_schema() */ + char *zDb; /* Configured by changegroup_schema() */ }; /* @@ -5180,6 +5452,7 @@ ){ SessionChange *pNew = 0; int rc = SQLITE_OK; + assert( aRec!=0 ); if( !pExist ){ pNew = (SessionChange *)sqlite3_malloc64(sizeof(SessionChange) + nRec); @@ -5346,6 +5619,114 @@ } /* +** Check if a changeset entry with nCol columns and the PK array passed +** as the final argument to this function is compatible with SessionTable +** pTab. If so, return 1. Otherwise, if they are incompatible in some way, +** return 0. +*/ +static int sessionChangesetCheckCompat( + SessionTable *pTab, + int nCol, + u8 *abPK +){ + if( pTab->azCol && nColnCol ){ + int ii; + for(ii=0; iinCol; ii++){ + u8 bPK = (ii < nCol) ? abPK[ii] : 0; + if( pTab->abPK[ii]!=bPK ) return 0; + } + return 1; + } + return (pTab->nCol==nCol && 0==memcmp(abPK, pTab->abPK, nCol)); +} + +static int sessionChangesetExtendRecord( + sqlite3_changegroup *pGrp, + SessionTable *pTab, + int nCol, + int op, + const u8 *aRec, + int nRec, + SessionBuffer *pOut +){ + int rc = SQLITE_OK; + int ii = 0; + + assert( pTab->azCol ); + assert( nColnCol ); + + pOut->nBuf = 0; + if( op==SQLITE_INSERT || (op==SQLITE_DELETE && pGrp->bPatch==0) ){ + /* Append the missing default column values to the record. */ + sessionAppendBlob(pOut, aRec, nRec, &rc); + if( rc==SQLITE_OK && pTab->pDfltStmt==0 ){ + rc = sessionPrepareDfltStmt(pGrp->db, pTab, &pTab->pDfltStmt); + } + for(ii=nCol; rc==SQLITE_OK && iinCol; ii++){ + int eType = sqlite3_column_type(pTab->pDfltStmt, ii); + sessionAppendByte(pOut, eType, &rc); + switch( eType ){ + case SQLITE_FLOAT: + case SQLITE_INTEGER: { + i64 iVal; + if( eType==SQLITE_INTEGER ){ + iVal = sqlite3_column_int64(pTab->pDfltStmt, ii); + }else{ + double rVal = sqlite3_column_int64(pTab->pDfltStmt, ii); + memcpy(&iVal, &rVal, sizeof(i64)); + } + if( SQLITE_OK==sessionBufferGrow(pOut, 8, &rc) ){ + sessionPutI64(&pOut->aBuf[pOut->nBuf], iVal); + } + break; + } + + case SQLITE_BLOB: + case SQLITE_TEXT: { + int n = sqlite3_column_bytes(pTab->pDfltStmt, ii); + sessionAppendVarint(pOut, n, &rc); + if( eType==SQLITE_TEXT ){ + const u8 *z = (const u8*)sqlite3_column_text(pTab->pDfltStmt, ii); + sessionAppendBlob(pOut, z, n, &rc); + }else{ + const u8 *z = (const u8*)sqlite3_column_blob(pTab->pDfltStmt, ii); + sessionAppendBlob(pOut, z, n, &rc); + } + break; + } + + default: + assert( eType==SQLITE_NULL ); + break; + } + } + }else if( op==SQLITE_UPDATE ){ + /* Append missing "undefined" entries to the old.* record. And, if this + ** is an UPDATE, to the new.* record as well. */ + int iOff = 0; + if( pGrp->bPatch==0 ){ + for(ii=0; iinCol-nCol); ii++){ + sessionAppendByte(pOut, 0x00, &rc); + } + } + + sessionAppendBlob(pOut, &aRec[iOff], nRec-iOff, &rc); + for(ii=0; ii<(pTab->nCol-nCol); ii++){ + sessionAppendByte(pOut, 0x00, &rc); + } + }else{ + assert( op==SQLITE_DELETE && pGrp->bPatch ); + sessionAppendBlob(pOut, aRec, nRec, &rc); + } + + return rc; +} + +/* ** Add all changes in the changeset traversed by the iterator passed as ** the first argument to the changegroup hash tables. */ @@ -5358,6 +5739,7 @@ int nRec; int rc = SQLITE_OK; SessionTable *pTab = 0; + SessionBuffer rec = {0, 0, 0}; while( SQLITE_ROW==sessionChangesetNext(pIter, &aRec, &nRec, 0) ){ const char *zNew; @@ -5369,6 +5751,9 @@ SessionChange *pExist = 0; SessionChange **pp; + /* Ensure that only changesets, or only patchsets, but not a mixture + ** of both, are being combined. It is an error to try to combine a + ** changeset and a patchset. */ if( pGrp->pList==0 ){ pGrp->bPatch = pIter->bPatchset; }else if( pIter->bPatchset!=pGrp->bPatch ){ @@ -5401,18 +5786,38 @@ pTab->zName = (char*)&pTab->abPK[nCol]; memcpy(pTab->zName, zNew, nNew+1); + if( pGrp->db ){ + pTab->nCol = 0; + rc = sessionInitTable(0, pTab, pGrp->db, pGrp->zDb); + if( rc ){ + assert( pTab->azCol==0 ); + sqlite3_free(pTab); + break; + } + } + /* The new object must be linked on to the end of the list, not ** simply added to the start of it. This is to ensure that the ** tables within the output of sqlite3changegroup_output() are in ** the right order. */ for(ppTab=&pGrp->pList; *ppTab; ppTab=&(*ppTab)->pNext); *ppTab = pTab; - }else if( pTab->nCol!=nCol || memcmp(pTab->abPK, abPK, nCol) ){ + } + + if( !sessionChangesetCheckCompat(pTab, nCol, abPK) ){ rc = SQLITE_SCHEMA; break; } } + if( nColnCol ){ + assert( pGrp->db ); + rc = sessionChangesetExtendRecord(pGrp, pTab, nCol, op, aRec, nRec, &rec); + if( rc ) break; + aRec = rec.aBuf; + nRec = rec.nBuf; + } + if( sessionGrowHash(0, pIter->bPatchset, pTab) ){ rc = SQLITE_NOMEM; break; @@ -5450,6 +5855,7 @@ } } + sqlite3_free(rec.aBuf); if( rc==SQLITE_OK ) rc = pIter->rc; return rc; } @@ -5537,6 +5943,31 @@ } /* +** Provide a database schema to the changegroup object. +*/ +int sqlite3changegroup_schema( + sqlite3_changegroup *pGrp, + sqlite3 *db, + const char *zDb +){ + int rc = SQLITE_OK; + + if( pGrp->pList || pGrp->db ){ + /* Cannot add a schema after one or more calls to sqlite3changegroup_add(), + ** or after sqlite3changegroup_schema() has already been called. */ + rc = SQLITE_MISUSE; + }else{ + pGrp->zDb = sqlite3_mprintf("%s", zDb); + if( pGrp->zDb==0 ){ + rc = SQLITE_NOMEM; + }else{ + pGrp->db = db; + } + } + return rc; +} + +/* ** Add the changeset currently stored in buffer pData, size nData bytes, ** to changeset-group p. */ @@ -5599,6 +6030,7 @@ */ void sqlite3changegroup_delete(sqlite3_changegroup *pGrp){ if( pGrp ){ + sqlite3_free(pGrp->zDb); sessionDeleteTable(0, pGrp->pList); sqlite3_free(pGrp); } diff -Nru sqlite3-3.42.0/ext/session/sqlite3session.h sqlite3-3.44.0-0/ext/session/sqlite3session.h --- sqlite3-3.42.0/ext/session/sqlite3session.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/session/sqlite3session.h 2023-11-04 14:23:58.000000000 +0000 @@ -885,6 +885,18 @@ /* +** CAPI3REF: Upgrade the Schema of a Changeset/Patchset +*/ +int sqlite3changeset_upgrade( + sqlite3 *db, + const char *zDb, + int nIn, const void *pIn, /* Input changeset */ + int *pnOut, void **ppOut /* OUT: Inverse of input */ +); + + + +/* ** CAPI3REF: Changegroup Handle ** ** A changegroup is an object used to combine two or more @@ -931,6 +943,38 @@ int sqlite3changegroup_new(sqlite3_changegroup **pp); /* +** CAPI3REF: Add a Schema to a Changegroup +** METHOD: sqlite3_changegroup_schema +** +** This method may be used to optionally enforce the rule that the changesets +** added to the changegroup handle must match the schema of database zDb +** ("main", "temp", or the name of an attached database). If +** sqlite3changegroup_add() is called to add a changeset that is not compatible +** with the configured schema, SQLITE_SCHEMA is returned and the changegroup +** object is left in an undefined state. +** +** A changeset schema is considered compatible with the database schema in +** the same way as for sqlite3changeset_apply(). Specifically, for each +** table in the changeset, there exists a database table with: +** +**

    +**
  • The name identified by the changeset, and +**
  • at least as many columns as recorded in the changeset, and +**
  • the primary key columns in the same position as recorded in +** the changeset. +**
+** +** The output of the changegroup object always has the same schema as the +** database nominated using this function. In cases where changesets passed +** to sqlite3changegroup_add() have fewer columns than the corresponding table +** in the database schema, these are filled in using the default column +** values from the database schema. This makes it possible to combined +** changesets that have different numbers of columns for a single table +** within a changegroup, provided that they are otherwise compatible. +*/ +int sqlite3changegroup_schema(sqlite3_changegroup*, sqlite3*, const char *zDb); + +/* ** CAPI3REF: Add A Changeset To A Changegroup ** METHOD: sqlite3_changegroup ** @@ -998,13 +1042,18 @@ ** If the new changeset contains changes to a table that is already present ** in the changegroup, then the number of columns and the position of the ** primary key columns for the table must be consistent. If this is not the -** case, this function fails with SQLITE_SCHEMA. If the input changeset -** appears to be corrupt and the corruption is detected, SQLITE_CORRUPT is -** returned. Or, if an out-of-memory condition occurs during processing, this -** function returns SQLITE_NOMEM. In all cases, if an error occurs the state -** of the final contents of the changegroup is undefined. +** case, this function fails with SQLITE_SCHEMA. Except, if the changegroup +** object has been configured with a database schema using the +** sqlite3changegroup_schema() API, then it is possible to combine changesets +** with different numbers of columns for a single table, provided that +** they are otherwise compatible. +** +** If the input changeset appears to be corrupt and the corruption is +** detected, SQLITE_CORRUPT is returned. Or, if an out-of-memory condition +** occurs during processing, this function returns SQLITE_NOMEM. ** -** If no error occurs, SQLITE_OK is returned. +** In all cases, if an error occurs the state of the final contents of the +** changegroup is undefined. If no error occurs, SQLITE_OK is returned. */ int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData); @@ -1269,10 +1318,17 @@ **
  • an insert change if all fields of the conflicting row match ** the row being inserted. ** +** +**
    SQLITE_CHANGESETAPPLY_FKNOACTION
    +** If this flag it set, then all foreign key constraints in the target +** database behave as if they were declared with "ON UPDATE NO ACTION ON +** DELETE NO ACTION", even if they are actually CASCADE, RESTRICT, SET NULL +** or SET DEFAULT. */ #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT 0x0001 #define SQLITE_CHANGESETAPPLY_INVERT 0x0002 #define SQLITE_CHANGESETAPPLY_IGNORENOOP 0x0004 +#define SQLITE_CHANGESETAPPLY_FKNOACTION 0x0008 /* ** CAPI3REF: Constants Passed To The Conflict Handler diff -Nru sqlite3-3.42.0/ext/session/test_session.c sqlite3-3.44.0-0/ext/session/test_session.c --- sqlite3-3.42.0/ext/session/test_session.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/session/test_session.c 2023-11-04 14:23:58.000000000 +0000 @@ -392,7 +392,6 @@ }; size_t sz = sizeof(aOpt[0]); - int rc; int iArg; int iOpt; if( Tcl_GetIndexFromObjStruct(interp,objv[2],aOpt,sz,"option",0,&iOpt) ){ @@ -812,9 +811,12 @@ while( objc>1 ){ const char *z1 = Tcl_GetString(objv[1]); int n = strlen(z1); - if( n>1 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){ + if( n>3 && n<=12 && 0==sqlite3_strnicmp("-nosavepoint", z1, n) ){ flags |= SQLITE_CHANGESETAPPLY_NOSAVEPOINT; } + else if( n>3 && n<=9 && 0==sqlite3_strnicmp("-noaction", z1, n) ){ + flags |= SQLITE_CHANGESETAPPLY_FKNOACTION; + } else if( n>2 && n<=7 && 0==sqlite3_strnicmp("-invert", z1, n) ){ flags |= SQLITE_CHANGESETAPPLY_INVERT; } @@ -1452,12 +1454,144 @@ return TCL_OK; } +typedef struct TestChangegroup TestChangegroup; +struct TestChangegroup { + sqlite3_changegroup *pGrp; +}; + +/* +** Destructor for Tcl changegroup command object. +*/ +static void test_changegroup_del(void *clientData){ + TestChangegroup *pGrp = (TestChangegroup*)clientData; + sqlite3changegroup_delete(pGrp->pGrp); + ckfree(pGrp); +} + +/* +** Tclcmd: $changegroup schema DB DBNAME +** Tclcmd: $changegroup add CHANGESET +** Tclcmd: $changegroup output +** Tclcmd: $changegroup delete +*/ +static int SQLITE_TCLAPI test_changegroup_cmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + TestChangegroup *p = (TestChangegroup*)clientData; + static struct ChangegroupCmd { + const char *zSub; + int nArg; + const char *zMsg; + int iSub; + } aSub[] = { + { "schema", 2, "DB DBNAME", }, /* 0 */ + { "add", 1, "CHANGESET", }, /* 1 */ + { "output", 0, "", }, /* 2 */ + { "delete", 0, "", }, /* 3 */ + { 0 } + }; + int rc = TCL_OK; + int iSub = 0; + + if( objc<2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "SUBCOMMAND ..."); + return TCL_ERROR; + } + rc = Tcl_GetIndexFromObjStruct(interp, + objv[1], aSub, sizeof(aSub[0]), "sub-command", 0, &iSub + ); + if( rc!=TCL_OK ) return rc; + if( objc!=2+aSub[iSub].nArg ){ + Tcl_WrongNumArgs(interp, 2, objv, aSub[iSub].zMsg); + return TCL_ERROR; + } + + switch( iSub ){ + case 0: { /* schema */ + sqlite3 *db = 0; + const char *zDb = Tcl_GetString(objv[3]); + if( dbHandleFromObj(interp, objv[2], &db) ){ + return TCL_ERROR; + } + rc = sqlite3changegroup_schema(p->pGrp, db, zDb); + if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); + break; + }; + + case 1: { /* add */ + int nByte = 0; + const u8 *aByte = Tcl_GetByteArrayFromObj(objv[2], &nByte); + rc = sqlite3changegroup_add(p->pGrp, nByte, (void*)aByte); + if( rc!=SQLITE_OK ) rc = test_session_error(interp, rc, 0); + break; + }; + + case 2: { /* output */ + int nByte = 0; + u8 *aByte = 0; + rc = sqlite3changegroup_output(p->pGrp, &nByte, (void**)&aByte); + if( rc!=SQLITE_OK ){ + rc = test_session_error(interp, rc, 0); + }else{ + Tcl_SetObjResult(interp, Tcl_NewByteArrayObj(aByte, nByte)); + } + sqlite3_free(aByte); + break; + }; + + default: { /* delete */ + assert( iSub==3 ); + Tcl_DeleteCommand(interp, Tcl_GetString(objv[0])); + break; + } + } + + return rc; +} + +/* +** Tclcmd: sqlite3changegroup CMD +*/ +static int SQLITE_TCLAPI test_sqlite3changegroup( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + int rc; /* sqlite3changegroup_new() return code */ + TestChangegroup *p; /* New wrapper object */ + + if( objc!=2 ){ + Tcl_WrongNumArgs(interp, 1, objv, "CMD"); + return TCL_ERROR; + } + + p = (TestChangegroup*)ckalloc(sizeof(TestChangegroup)); + memset(p, 0, sizeof(TestChangegroup)); + rc = sqlite3changegroup_new(&p->pGrp); + if( rc!=SQLITE_OK ){ + ckfree((char*)p); + return test_session_error(interp, rc, 0); + } + + Tcl_CreateObjCommand( + interp, Tcl_GetString(objv[1]), test_changegroup_cmd, (ClientData)p, + test_changegroup_del + ); + Tcl_SetObjResult(interp, objv[1]); + return TCL_OK; +} + int TestSession_Init(Tcl_Interp *interp){ struct Cmd { const char *zCmd; Tcl_ObjCmdProc *xProc; } aCmd[] = { { "sqlite3session", test_sqlite3session }, + { "sqlite3changegroup", test_sqlite3changegroup }, { "sqlite3session_foreach", test_sqlite3session_foreach }, { "sqlite3changeset_invert", test_sqlite3changeset_invert }, { "sqlite3changeset_concat", test_sqlite3changeset_concat }, diff -Nru sqlite3-3.42.0/ext/wasm/api/extern-post-js.c-pp.js sqlite3-3.44.0-0/ext/wasm/api/extern-post-js.c-pp.js --- sqlite3-3.42.0/ext/wasm/api/extern-post-js.c-pp.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/extern-post-js.c-pp.js 2023-11-04 14:23:58.000000000 +0000 @@ -23,10 +23,7 @@ impls which Emscripten installs at some point in the file above this. */ - const originalInit = - /* Maintenance reminder: DO NOT use `self.` here. It's correct - for non-ES6 Module cases but wrong for ES6 modules because those - resolve this symbol differently. */ sqlite3InitModule; + const originalInit = sqlite3InitModule; if(!originalInit){ throw new Error("Expecting globalThis.sqlite3InitModule to be defined by the Emscripten build."); } @@ -65,19 +62,19 @@ globalThis.sqlite3InitModule = function ff(...args){ //console.warn("Using replaced sqlite3InitModule()",globalThis.location); return originalInit(...args).then((EmscriptenModule)=>{ +//#if wasmfs if('undefined'!==typeof WorkerGlobalScope && - (EmscriptenModule['ENVIRONMENT_IS_PTHREAD'] - || EmscriptenModule['_pthread_self'] - || 'function'===typeof threadAlert - || globalThis?.location?.pathname?.endsWith?.('.worker.js') - )){ + EmscriptenModule['ENVIRONMENT_IS_PTHREAD']){ /** Workaround for wasmfs-generated worker, which calls this routine from each individual thread and requires that its - argument be returned. All of the criteria above are fragile, - based solely on inspection of the offending code, not public - Emscripten details. */ + argument be returned. The conditional criteria above are + fragile, based solely on inspection of the offending code, + not public Emscripten details. */ + //console.warn("sqlite3InitModule() returning E-module.",EmscriptenModule); return EmscriptenModule; } +//#endif + //console.warn("sqlite3InitModule() returning sqlite3 object."); const s = EmscriptenModule.sqlite3; s.scriptInfo = initModuleState; //console.warn("sqlite3.scriptInfo =",s.scriptInfo); @@ -124,5 +121,6 @@ return globalThis.sqlite3InitModule /* required for ESM */; })(); //#if target=es6-module -export default toExportForESM; +sqlite3InitModule = toExportForESM; +export default sqlite3InitModule; //#endif diff -Nru sqlite3-3.42.0/ext/wasm/api/README.md sqlite3-3.44.0-0/ext/wasm/api/README.md --- sqlite3-3.42.0/ext/wasm/api/README.md 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/README.md 2023-11-04 14:23:58.000000000 +0000 @@ -83,15 +83,18 @@ helpers for use by downstream code which creates `sqlite3_vfs` and `sqlite3_module` implementations. - **`sqlite3-vfs-opfs.c-pp.js`**\ - is an sqlite3 VFS implementation which supports Google Chrome's - Origin-Private FileSystem (OPFS) as a storage layer to provide - persistent storage for database files in a browser. It requires... + is an sqlite3 VFS implementation which supports the Origin-Private + FileSystem (OPFS) as a storage layer to provide persistent storage + for database files in a browser. It requires... - **`sqlite3-opfs-async-proxy.js`**\ is the asynchronous backend part of the OPFS proxy. It speaks directly to the (async) OPFS API and channels those results back to its synchronous counterpart. This file, because it must be started in its own Worker, is not part of the amalgamation. -- **`api/sqlite3-api-cleanup.js`**\ +- **`sqlite3-vfs-opfs-sahpool.c-pp.js`**\ + is another sqlite3 VFS supporting the OPFS, but uses a completely + different approach that the above-listed one. +- **`sqlite3-api-cleanup.js`**\ The previous files do not immediately extend the library. Instead they add callback functions to be called during its bootstrapping. Some also temporarily create global objects in order @@ -108,13 +111,15 @@ with `c-pp`](#c-pp), noting that such preprocessing may be applied after all of the relevant files are concatenated. That extension is used primarily to keep the code maintainers cognisant of the fact that -those files contain constructs which will not run as-is in JavaScript. +those files contain constructs which may not run as-is in any given +JavaScript environment. The build process glues those files together, resulting in -`sqlite3-api.js`, which is everything except for the `post-js-*.js` -files, and `sqlite3.js`, which is the Emscripten-generated amalgamated -output and includes the `post-js-*.js` parts, as well as the -Emscripten-provided module loading pieces. +`sqlite3-api.js`, which is everything except for the +`pre/post-js-*.js` files, and `sqlite3.js`, which is the +Emscripten-generated amalgamated output and includes the +`pre/post-js-*.js` parts, as well as the Emscripten-provided module +loading pieces. The non-JS outlier file is `sqlite3-wasm.c`: it is a proxy for `sqlite3.c` which `#include`'s that file and adds a couple more @@ -152,8 +157,8 @@ ------------------------------------------------------------------------ Certain files in the build require preprocessing to filter in/out -parts which differ between vanilla JS builds and ES6 Module -(a.k.a. esm) builds. The preprocessor application itself is in +parts which differ between vanilla JS, ES6 Modules, and node.js +builds. The preprocessor application itself is in [`c-pp.c`](/file/ext/wasm/c-pp.c) and the complete technical details of such preprocessing are maintained in [`GNUMakefile`](/file/ext/wasm/GNUmakefile). diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-api-cleanup.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-cleanup.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-api-cleanup.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-cleanup.js 2023-11-04 14:23:58.000000000 +0000 @@ -22,8 +22,10 @@ */ const SABC = Object.assign( Object.create(null), { - exports: Module['asm'], - memory: Module.wasmMemory /* gets set if built with -sIMPORT_MEMORY */ + exports: ('undefined'===typeof wasmExports) + ? Module['asm']/* emscripten <=3.1.43 */ + : wasmExports /* emscripten >=3.1.44 */, + memory: Module.wasmMemory /* gets set if built with -sIMPORTED_MEMORY */ }, globalThis.sqlite3ApiConfig || {} ); diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-api-glue.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-glue.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-api-glue.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-glue.js 2023-11-04 14:23:58.000000000 +0000 @@ -608,6 +608,7 @@ ["sqlite3_wasm_db_vfs", "sqlite3_vfs*", "sqlite3*","string"], ["sqlite3_wasm_vfs_create_file", "int", "sqlite3_vfs*","string","*", "int"], + ["sqlite3_wasm_posix_create_file", "int", "string","*", "int"], ["sqlite3_wasm_vfs_unlink", "int", "sqlite3_vfs*","string"] ]; @@ -728,6 +729,15 @@ Populate api object with sqlite3_...() by binding the "raw" wasm exports into type-converting proxies using wasm.xWrap(). */ + if(0 === wasm.exports.sqlite3_step.length){ + /* This environment wraps exports in nullary functions, which means + we must disable the arg-count validation we otherwise perform + on the wrappers. */ + wasm.xWrap.doArgcCheck = false; + sqlite3.config.warn( + "Disabling sqlite3.wasm.xWrap.doArgcCheck due to environmental quirks." + ); + } for(const e of wasm.bindingSignatures){ capi[e[0]] = wasm.xWrap.apply(null, e); } @@ -878,9 +888,9 @@ consistency with non-special-case wrappings. */ const __dbArgcMismatch = (pDb,f,n)=>{ - return sqlite3.util.sqlite3_wasm_db_error(pDb, capi.SQLITE_MISUSE, - f+"() requires "+n+" argument"+ - (1===n?"":'s')+"."); + return util.sqlite3_wasm_db_error(pDb, capi.SQLITE_MISUSE, + f+"() requires "+n+" argument"+ + (1===n?"":'s')+"."); }; /** Code duplication reducer for functions which take an encoding diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-api-oo1.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-oo1.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-api-oo1.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-oo1.js 2023-11-04 14:23:58.000000000 +0000 @@ -55,6 +55,7 @@ if(sqliteResultCode){ if(dbPtr instanceof DB) dbPtr = dbPtr.pointer; toss3( + sqliteResultCode, "sqlite3 result code",sqliteResultCode+":", (dbPtr ? capi.sqlite3_errmsg(dbPtr) @@ -330,10 +331,15 @@ - `db`: the DB object which created the statement. - - `columnCount`: the number of result columns in the query, or 0 for - queries which cannot return results. + - `columnCount`: the number of result columns in the query, or 0 + for queries which cannot return results. This property is a proxy + for sqlite3_column_count() and its use in loops should be avoided + because of the call overhead associated with that. The + `columnCount` is not cached when the Stmt is created because a + schema change made via a separate db connection between this + statement's preparation and when it is stepped may invalidate it. - - `parameterCount`: the number of bindable paramters in the query. + - `parameterCount`: the number of bindable parameters in the query. */ const Stmt = function(){ if(BindTypes!==arguments[2]){ @@ -341,7 +347,6 @@ } this.db = arguments[0]; __ptrMap.set(this, arguments[1]); - this.columnCount = capi.sqlite3_column_count(this.pointer); this.parameterCount = capi.sqlite3_bind_parameter_count(this.pointer); }; @@ -473,7 +478,9 @@ const __selectFirstRow = (db, sql, bind, ...getArgs)=>{ const stmt = db.prepare(sql); try { - return stmt.bind(bind).step() ? stmt.get(...getArgs) : undefined; + const rc = stmt.bind(bind).step() ? stmt.get(...getArgs) : undefined; + stmt.reset(/*for INSERT...RETURNING locking case*/); + return rc; }finally{ stmt.finalize(); } @@ -499,6 +506,9 @@ "Not an error." The various non-0 non-error codes need to be checked for in client code where they are expected. + The thrown exception's `resultCode` property will be the value of + the second argument to this function. + If it does not throw, it returns its first argument. */ DB.checkRc = (db,resultCode)=>checkSqlite3Rc(db,resultCode); @@ -546,7 +556,10 @@ } const pDb = this.pointer; Object.keys(__stmtMap.get(this)).forEach((k,s)=>{ - if(s && s.pointer) s.finalize(); + if(s && s.pointer){ + try{s.finalize()} + catch(e){/*ignore*/} + } }); __ptrMap.delete(this); __stmtMap.delete(this); @@ -701,18 +714,18 @@ with identical names. - `callback` = a function which gets called for each row of the - result set, but only if that statement has any result - _rows_. The callback's "this" is the options object, noting - that this function synthesizes one if the caller does not pass - one to exec(). The second argument passed to the callback is - always the current Stmt object, as it's needed if the caller - wants to fetch the column names or some such (noting that they - could also be fetched via `this.columnNames`, if the client - provides the `columnNames` option). If the callback returns a - literal `false` (as opposed to any other falsy value, e.g. an - implicit `undefined` return), any ongoing statement-`step()` - iteration stops without an error. The return value of the - callback is otherwise ignored. + result set, but only if that statement has any result rows. The + callback's "this" is the options object, noting that this + function synthesizes one if the caller does not pass one to + exec(). The second argument passed to the callback is always + the current Stmt object, as it's needed if the caller wants to + fetch the column names or some such (noting that they could + also be fetched via `this.columnNames`, if the client provides + the `columnNames` option). If the callback returns a literal + `false` (as opposed to any other falsy value, e.g. an implicit + `undefined` return), any ongoing statement-`step()` iteration + stops without an error. The return value of the callback is + otherwise ignored. ACHTUNG: The callback MUST NOT modify the Stmt object. Calling any of the Stmt.get() variants, Stmt.getColumnName(), or @@ -733,7 +746,7 @@ A.1) `'array'` (the default) causes the results of `stmt.get([])` to be passed to the `callback` and/or appended - to `resultRows` + to `resultRows`. A.2) `'object'` causes the results of `stmt.get(Object.create(null))` to be passed to the @@ -744,8 +757,8 @@ A.3) `'stmt'` causes the current Stmt to be passed to the callback, but this mode will trigger an exception if - `resultRows` is an array because appending the statement to - the array would be downright unhelpful. + `resultRows` is an array because appending the transient + statement to the array would be downright unhelpful. B) An integer, indicating a zero-based column in the result row. Only that one single value will be passed on. @@ -775,7 +788,7 @@ should return: A) The default value is (usually) `"this"`, meaning that the - DB object itself should be returned. The exceptions is if + DB object itself should be returned. The exception is if the caller passes neither of `callback` nor `returnValue` but does pass an explicit `rowMode` then the default `returnValue` is `"resultRows"`, described below. @@ -857,38 +870,53 @@ bind = null; } if(evalFirstResult && stmt.columnCount){ - /* Only forward SELECT results for the FIRST query + /* Only forward SELECT-style results for the FIRST query in the SQL which potentially has them. */ + let gotColNames = Array.isArray( + opt.columnNames + /* As reported in + https://sqlite.org/forum/forumpost/7774b773937cbe0a + we need to delay fetching of the column names until + after the first step() (if we step() at all) because + a schema change between the prepare() and step(), via + another connection, may invalidate the column count + and names. */) ? 0 : 1; evalFirstResult = false; - if(Array.isArray(opt.columnNames)){ - stmt.getColumnNames(opt.columnNames); - } if(arg.cbArg || resultRows){ - for(; stmt.step(); stmt._isLocked = false){ - stmt._isLocked = true; + for(; stmt.step(); stmt._lockedByExec = false){ + if(0===gotColNames++) stmt.getColumnNames(opt.columnNames); + stmt._lockedByExec = true; const row = arg.cbArg(stmt); if(resultRows) resultRows.push(row); if(callback && false === callback.call(opt, row, stmt)){ break; } } - stmt._isLocked = false; + stmt._lockedByExec = false; + } + if(0===gotColNames){ + /* opt.columnNames was provided but we visited no result rows */ + stmt.getColumnNames(opt.columnNames); } }else{ stmt.step(); } - stmt.finalize(); + stmt.reset( + /* In order to trigger an exception in the + INSERT...RETURNING locking scenario: + https://sqlite.org/forum/forumpost/36f7a2e7494897df + */).finalize(); stmt = null; - } + }/*prepare() loop*/ }/*catch(e){ sqlite3.config.warn("DB.exec() is propagating exception",opt,e); throw e; }*/finally{ + wasm.scopedAllocPop(stack); if(stmt){ - delete stmt._isLocked; + delete stmt._lockedByExec; stmt.finalize(); } - wasm.scopedAllocPop(stack); } return arg.returnVal(); }/*exec()*/, @@ -1107,6 +1135,7 @@ try { stmt.bind(bind); while(stmt.step()) rc.push(stmt.get(0,asType)); + stmt.reset(/*for INSERT...RETURNING locking case*/); }finally{ stmt.finalize(); } @@ -1241,7 +1270,7 @@ not throw, it returns this object. */ checkRc: function(resultCode){ - return DB.checkRc(this, resultCode); + return checkSqlite3Rc(this, resultCode); } }/*DB.prototype*/; @@ -1302,15 +1331,15 @@ }; /** - If stmt._isLocked is truthy, this throws an exception + If stmt._lockedByExec is truthy, this throws an exception complaining that the 2nd argument (an operation name, e.g. "bind()") is not legal while the statement is "locked". Locking happens before an exec()-like callback is passed a statement, to ensure that the callback does not mutate or finalize the statement. If it does not throw, it returns stmt. */ - const affirmUnlocked = function(stmt,currentOpName){ - if(stmt._isLocked){ + const affirmNotLockedByExec = function(stmt,currentOpName){ + if(stmt._lockedByExec){ toss3("Operation is illegal when statement is locked:",currentOpName); } return stmt; @@ -1323,14 +1352,11 @@ success. */ const bindOne = function f(stmt,ndx,bindType,val){ - affirmUnlocked(affirmStmtOpen(stmt), 'bind()'); + affirmNotLockedByExec(affirmStmtOpen(stmt), 'bind()'); if(!f._){ f._tooBigInt = (v)=>toss3( "BigInt value is too big to store without precision loss:", v ); - /* Reminder: when not in BigInt mode, it's impossible for - JS to represent a number out of the range we can bind, - so we have no range checking. */ f._ = { string: function(stmt, ndx, val, asBlob){ const [pStr, n] = wasm.allocCString(val, true); @@ -1404,46 +1430,67 @@ Stmt.prototype = { /** - "Finalizes" this statement. This is a no-op if the - statement has already been finalizes. Returns - undefined. Most methods in this class will throw if called - after this is. + "Finalizes" this statement. This is a no-op if the statement + has already been finalized. Returns the result of + sqlite3_finalize() (0 on success, non-0 on error), or the + undefined value if the statement has already been + finalized. Regardless of success or failure, most methods in + this class will throw if called after this is. + + This method always throws if called when it is illegal to do + so. Namely, when triggered via a per-row callback handler of a + DB.exec() call. */ finalize: function(){ if(this.pointer){ - affirmUnlocked(this,'finalize()'); + affirmNotLockedByExec(this,'finalize()'); + const rc = capi.sqlite3_finalize(this.pointer); delete __stmtMap.get(this.db)[this.pointer]; - capi.sqlite3_finalize(this.pointer); __ptrMap.delete(this); delete this._mayGet; - delete this.columnCount; delete this.parameterCount; + delete this._lockedByExec; delete this.db; - delete this._isLocked; + return rc; } }, - /** Clears all bound values. Returns this object. - Throws if this statement has been finalized. */ + /** + Clears all bound values. Returns this object. Throws if this + statement has been finalized or if modification of the + statement is currently illegal (e.g. in the per-row callback of + a DB.exec() call). + */ clearBindings: function(){ - affirmUnlocked(affirmStmtOpen(this), 'clearBindings()') + affirmNotLockedByExec(affirmStmtOpen(this), 'clearBindings()') capi.sqlite3_clear_bindings(this.pointer); this._mayGet = false; return this; }, /** - Resets this statement so that it may be step()ed again - from the beginning. Returns this object. Throws if this - statement has been finalized. + Resets this statement so that it may be step()ed again from the + beginning. Returns this object. Throws if this statement has + been finalized, if it may not legally be reset because it is + currently being used from a DB.exec() callback, or if the + underlying call to sqlite3_reset() returns non-0. If passed a truthy argument then this.clearBindings() is also called, otherwise any existing bindings, along with any memory allocated for them, are retained. + + In versions 3.42.0 and earlier, this function did not throw if + sqlite3_reset() returns non-0, but it was discovered that + throwing (or significant extra client-side code) is necessary + in order to avoid certain silent failure scenarios, as + discussed at: + + https://sqlite.org/forum/forumpost/36f7a2e7494897df */ reset: function(alsoClearBinds){ - affirmUnlocked(this,'reset()'); + affirmNotLockedByExec(this,'reset()'); if(alsoClearBinds) this.clearBindings(); - capi.sqlite3_reset(affirmStmtOpen(this).pointer); + const rc = capi.sqlite3_reset(affirmStmtOpen(this).pointer); this._mayGet = false; + checkSqlite3Rc(this.db, rc); return this; }, /** @@ -1592,7 +1639,7 @@ value is returned. Throws on error. */ step: function(){ - affirmUnlocked(this, 'step()'); + affirmNotLockedByExec(this, 'step()'); const rc = capi.sqlite3_step(affirmStmtOpen(this).pointer); switch(rc){ case capi.SQLITE_DONE: return this._mayGet = false; @@ -1627,11 +1674,9 @@ return this.reset(); }, /** - Functions like step() except that it finalizes this statement - immediately after stepping unless the step cannot be performed - because the statement is locked. Throws on error, but any error - other than the statement-is-locked case will also trigger - finalization of this statement. + Functions like step() except that it calls finalize() on this + statement immediately after stepping, even if the step() call + throws. On success, it returns true if the step indicated that a row of data was available, else it returns false. @@ -1643,9 +1688,14 @@ ``` */ stepFinalize: function(){ - const rc = this.step(); - this.finalize(); - return rc; + try{ + const rc = this.step(); + this.reset(/*for INSERT...RETURNING locking case*/); + return rc; + }finally{ + try{this.finalize()} + catch(e){/*ignored*/} + } }, /** Fetches the value from the given 0-based column index of @@ -1686,13 +1736,15 @@ } if(Array.isArray(ndx)){ let i = 0; - while(itoss3("The columnCount property is read-only.") + }); /** The OO API's public namespace. */ sqlite3.oo1 = { diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-api-prologue.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-prologue.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-api-prologue.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-prologue.js 2023-11-04 14:23:58.000000000 +0000 @@ -53,7 +53,7 @@ - `memory`[^1]: optional WebAssembly.Memory object, defaulting to `exports.memory`. In Emscripten environments this should be set - to `Module.wasmMemory` if the build uses `-sIMPORT_MEMORY`, or be + to `Module.wasmMemory` if the build uses `-sIMPORTED_MEMORY`, or be left undefined/falsy to default to `exports.memory` when using WASM-exported memory. @@ -88,12 +88,12 @@ can be replaced with (e.g.) empty functions to squelch all such output. - - `wasmfsOpfsDir`[^1]: As of 2022-12-17, this feature does not - currently work due to incompatible Emscripten-side changes made - in the WASMFS+OPFS combination. This option is currently ignored. + - `wasmfsOpfsDir`[^1]: Specifies the "mount point" of the OPFS-backed + filesystem in WASMFS-capable builds. - [^1] = This property may optionally be a function, in which case this - function re-assigns calls that function to fetch the value, + + [^1] = This property may optionally be a function, in which case + this function calls that function to fetch the value, enabling delayed evaluation. The returned object is the top-level sqlite3 namespace object. @@ -125,11 +125,11 @@ log: console.log.bind(console), wasmfsOpfsDir: '/opfs', /** - useStdAlloc is just for testing an allocator discrepancy. The + useStdAlloc is just for testing allocator discrepancies. The docs guarantee that this is false in the canonical builds. For 99% of purposes it doesn't matter which allocators we use, but - it becomes significant with, e.g., sqlite3_deserialize() - and certain wasm.xWrap.resultAdapter()s. + it becomes significant with, e.g., sqlite3_deserialize() and + certain wasm.xWrap.resultAdapter()s. */ useStdAlloc: false }, apiConfig || {}); @@ -149,11 +149,6 @@ config[k] = config[k](); } }); - config.wasmOpfsDir = - /* 2022-12-17: WASMFS+OPFS can no longer be activated from the - main thread (aborts via a failed assert() if it's attempted), - which eliminates any(?) benefit to supporting it. */ false; - /** The main sqlite3 binding API gets installed into this object, mimicking the C API as closely as we can. The numerous members @@ -777,8 +772,43 @@ isSharedTypedArray, toss: function(...args){throw new Error(args.join(' '))}, toss3, - typedArrayPart - }; + typedArrayPart, + /** + Given a byte array or ArrayBuffer, this function throws if the + lead bytes of that buffer do not hold a SQLite3 database header, + else it returns without side effects. + + Added in 3.44. + */ + affirmDbHeader: function(bytes){ + if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes); + const header = "SQLite format 3"; + if( header.length > bytes.byteLength ){ + toss3("Input does not contain an SQLite3 database header."); + } + for(let i = 0; i < header.length; ++i){ + if( header.charCodeAt(i) !== bytes[i] ){ + toss3("Input does not contain an SQLite3 database header."); + } + } + }, + /** + Given a byte array or ArrayBuffer, this function throws if the + database does not, at a cursory glance, appear to be an SQLite3 + database. It only examines the size and header, but further + checks may be added in the future. + + Added in 3.44. + */ + affirmIsDb: function(bytes){ + if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes); + const n = bytes.byteLength; + if(n<512 || n%512!==0) { + toss3("Byte array size",n,"is invalid for an SQLite3 db."); + } + util.affirmDbHeader(bytes); + } + }/*util*/; Object.assign(wasm, { /** @@ -809,7 +839,7 @@ || toss3("Missing API config.exports (WASM module exports)."), /** - When Emscripten compiles with `-sIMPORT_MEMORY`, it + When Emscripten compiles with `-sIMPORTED_MEMORY`, it initalizes the heap and imports it into wasm, as opposed to the other way around. In this case, the memory is not available via this.exports.memory. @@ -1105,7 +1135,23 @@ return 1===n ? wasm.pstack.alloc(safePtrSize ? 8 : wasm.ptrSizeof) : wasm.pstack.allocChunks(n, safePtrSize ? 8 : wasm.ptrSizeof); + }, + + /** + Records the current pstack position, calls the given function, + passing it the sqlite3 object, then restores the pstack + regardless of whether the function throws. Returns the result + of the call or propagates an exception on error. + + Added in 3.44. + */ + call: function(f){ + const stackPos = wasm.pstack.pointer; + try{ return f(sqlite3) } finally{ + wasm.pstack.restore(stackPos); + } } + })/*wasm.pstack*/; Object.defineProperties(wasm.pstack, { /** @@ -1177,31 +1223,31 @@ /** State for sqlite3_wasmfs_opfs_dir(). */ let __wasmfsOpfsDir = undefined; /** - 2022-12-17: incompatible WASMFS changes have made WASMFS+OPFS - unavailable from the main thread, which eliminates the most - significant benefit of supporting WASMFS. This function is now a - no-op which always returns a falsy value. Before that change, - this function behaved as documented below (and how it will again - if we can find a compelling reason to support it). - If the wasm environment has a WASMFS/OPFS-backed persistent storage directory, its path is returned by this function. If it does not then it returns "" (noting that "" is a falsy value). The first time this is called, this function inspects the current environment to determine whether persistence support is available - and, if it is, enables it (if needed). + and, if it is, enables it (if needed). After the first call it + always returns the cached result. - This function currently only recognizes the WASMFS/OPFS storage - combination and its path refers to storage rooted in the - Emscripten-managed virtual filesystem. + If the returned string is not empty, any files stored under the + given path (recursively) are housed in OPFS storage. If the + returned string is empty, this particular persistent storage + option is not available on the client. + + Though the mount point name returned by this function is intended + to remain stable, clients should not hard-coded it anywhere. Always call this function to get the path. + + Note that this function is a no-op in must builds of this + library, as the WASMFS capability requires a custom + build. */ capi.sqlite3_wasmfs_opfs_dir = function(){ if(undefined !== __wasmfsOpfsDir) return __wasmfsOpfsDir; // If we have no OPFS, there is no persistent dir const pdir = config.wasmfsOpfsDir; - console.error("sqlite3_wasmfs_opfs_dir() can no longer work due "+ - "to incompatible WASMFS changes. It will be removed."); if(!pdir || !globalThis.FileSystemHandle || !globalThis.FileSystemDirectoryHandle @@ -1223,8 +1269,6 @@ }; /** - Experimental and subject to change or removal. - Returns true if sqlite3.capi.sqlite3_wasmfs_opfs_dir() is a non-empty string and the given name starts with (that string + '/'), else returns false. @@ -1234,13 +1278,6 @@ return (p && name) ? name.startsWith(p+'/') : false; }; - // This bit is highly arguable and is incompatible with the fiddle shell. - if(false && 0===wasm.exports.sqlite3_vfs_find(0)){ - /* Assume that sqlite3_initialize() has not yet been called. - This will be the case in an SQLITE_OS_KV build. */ - wasm.exports.sqlite3_initialize(); - } - /** Given an `sqlite3*`, an sqlite3_vfs name, and an optional db name (defaulting to "main"), returns a truthy value (see below) if @@ -1371,6 +1408,74 @@ }; /** + If the current environment supports the POSIX file APIs, this routine + creates (or overwrites) the given file using those APIs. This is + primarily intended for use in Emscripten-based builds where the POSIX + APIs are transparently proxied by an in-memory virtual filesystem. + It may behave diffrently in other environments. + + The first argument must be either a JS string or WASM C-string + holding the filename. Note that this routine does _not_ create + intermediary directories if the filename has a directory part. + + The 2nd argument may either a valid WASM memory pointer, an + ArrayBuffer, or a Uint8Array. The 3rd must be the length, in + bytes, of the data array to copy. If the 2nd argument is an + ArrayBuffer or Uint8Array and the 3rd is not a positive integer + then the 3rd defaults to the array's byteLength value. + + Results are undefined if data is a WASM pointer and dataLen is + exceeds data's bounds. + + Throws if any arguments are invalid or if creating or writing to + the file fails. + + Added in 3.43 as an alternative for the deprecated + sqlite3_js_vfs_create_file(). + */ + capi.sqlite3_js_posix_create_file = function(filename, data, dataLen){ + let pData; + if(data && wasm.isPtr(data)){ + pData = data; + }else if(data instanceof ArrayBuffer || data instanceof Uint8Array){ + pData = wasm.allocFromTypedArray(data); + if(arguments.length<3 || !util.isInt32(dataLen) || dataLen<0){ + dataLen = data.byteLength; + } + }else{ + SQLite3Error.toss("Invalid 2nd argument for sqlite3_js_posix_create_file()."); + } + try{ + if(!util.isInt32(dataLen) || dataLen<0){ + SQLite3Error.toss("Invalid 3rd argument for sqlite3_js_posix_create_file()."); + } + const rc = wasm.sqlite3_wasm_posix_create_file(filename, pData, dataLen); + if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code", + capi.sqlite3_js_rc_str(rc)); + }finally{ + wasm.dealloc(pData); + } + }; + + /** + Deprecation warning: this function does not work properly in + debug builds of sqlite3 because its out-of-scope use of the + sqlite3_vfs API triggers assertions in the core library. That + was unfortunately not discovered until 2023-08-11. This function + is now deprecated and should not be used in new code. + + Alternative options: + + - "unix" VFS and its variants can get equivalent functionality + with sqlite3_js_posix_create_file(). + + - OPFS: use either sqlite3.oo1.OpfsDb.importDb(), for the "opfs" + VFS, or the importDb() method of the PoolUtil object provided + by the "opfs-sahpool" OPFS (noting that its VFS name may differ + depending on client-side configuration). We cannot proxy those + from here because the former is necessarily asynchronous and + the latter requires information not available to this function. + Creates a file using the storage appropriate for the given sqlite3_vfs. The first argument may be a VFS name (JS string only, NOT a WASM C-string), WASM-managed `sqlite3_vfs*`, or @@ -1416,9 +1521,13 @@ VFS nor the WASM environment imposes requirements which break it. - "opfs": uses OPFS storage and creates directory parts of the - filename. + filename. It can only be used to import an SQLite3 database + file and will fail if given anything else. */ capi.sqlite3_js_vfs_create_file = function(vfs, filename, data, dataLen){ + config.warn("sqlite3_js_vfs_create_file() is deprecated and", + "should be avoided because it can lead to C-level crashes.", + "See its documentation for alternative options."); let pData; if(data){ if(wasm.isPtr(data)){ @@ -1446,10 +1555,30 @@ if(rc) SQLite3Error.toss("Creation of file failed with sqlite3 result code", capi.sqlite3_js_rc_str(rc)); }finally{ - wasm.dealloc(pData); + wasm.dealloc(pData); } }; + /** + Converts SQL input from a variety of convenient formats + to plain strings. + + If v is a string, it is returned as-is. If it is-a Array, its + join("") result is returned. If is is a Uint8Array, Int8Array, + or ArrayBuffer, it is assumed to hold UTF-8-encoded text and is + decoded to a string. If it looks like a WASM pointer, + wasm.cstrToJs(sql) is returned. Else undefined is returned. + + Added in 3.44 + */ + capi.sqlite3_js_sql_to_string = (sql)=>{ + if('string' === typeof sql){ + return sql; + } + const x = flexibleString(v); + return x===v ? undefined : x; + } + if( util.isUIThread() ){ /* Features specific to the main window thread... */ @@ -1659,7 +1788,8 @@ do not. */ tgt.push(capi.sqlite3_value_to_js( - wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)) + wasm.peekPtr(pArgv + (wasm.ptrSizeof * i)), + throwIfCannotConvert )); } return tgt; @@ -1875,6 +2005,9 @@ client: undefined, /** + This function is not part of the public interface, but a + piece of internal bootstrapping infrastructure. + Performs any optional asynchronous library-level initialization which might be required. This function returns a Promise which resolves to the sqlite3 namespace object. Any error in the @@ -1890,27 +2023,19 @@ then it must be called by client-level code, which must not use the library until the returned promise resolves. - Bug: if called while a prior call is still resolving, the 2nd - call will resolve prematurely, before the 1st call has finished - resolving. The current build setup precludes that possibility, - so it's only a hypothetical problem if/when this function - ever needs to be invoked by clients. + If called multiple times it will return the same promise on + subsequent calls. The current build setup precludes that + possibility, so it's only a hypothetical problem if/when this + function ever needs to be invoked by clients. In Emscripten-based builds, this function is called automatically and deleted from this object. */ - asyncPostInit: async function(){ - let lip = sqlite3ApiBootstrap.initializersAsync; + asyncPostInit: async function ff(){ + if(ff.isReady instanceof Promise) return ff.isReady; + let lia = sqlite3ApiBootstrap.initializersAsync; delete sqlite3ApiBootstrap.initializersAsync; - if(!lip || !lip.length) return Promise.resolve(sqlite3); - lip = lip.map((f)=>{ - const p = (f instanceof Promise) ? f : f(sqlite3); - return p.catch((e)=>{ - console.error("an async sqlite3 initializer failed:",e); - throw e; - }); - }); - const postInit = ()=>{ + const postInit = async ()=>{ if(!sqlite3.__isUnderTest){ /* Delete references to internal-only APIs which are used by some initializers. Retain them when running in test mode @@ -1919,23 +2044,25 @@ /* It's conceivable that we might want to expose StructBinder to client-side code, but it's only useful if clients build their own sqlite3.wasm which contains their - one C struct types. */ + own C struct types. */ delete sqlite3.StructBinder; } return sqlite3; }; - if(1){ - /* Run all initializers in sequence. The advantage is that it - allows us to have post-init cleanup defined outside of this - routine at the end of the list and have it run at a - well-defined time. */ - let p = lip.shift(); - while(lip.length) p = p.then(lip.shift()); - return p.then(postInit); - }else{ - /* Run them in an arbitrary order. */ - return Promise.all(lip).then(postInit); + const catcher = (e)=>{ + config.error("an async sqlite3 initializer failed:",e); + throw e; + }; + if(!lia || !lia.length){ + return ff.isReady = postInit().catch(catcher); } + lia = lia.map((f)=>{ + return (f instanceof Function) ? async x=>f(sqlite3) : f; + }); + lia.push(postInit); + let p = Promise.resolve(sqlite3); + while(lia.length) p = p.then(lia.shift()); + return ff.isReady = p.catch(catcher); }, /** scriptInfo ideally gets injected into this object by the @@ -1995,7 +2122,7 @@ specifically for initializers which are asynchronous. All entries in this list must be either async functions, non-async functions which return a Promise, or a Promise. Each function in the list is called - with the sqlite3 ojbect as its only argument. + with the sqlite3 object as its only argument. The resolved value of any Promise is ignored and rejection will kill the asyncPostInit() process (at an indeterminate point because all diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-api-worker1.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-worker1.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-api-worker1.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-api-worker1.js 2023-11-04 14:23:58.000000000 +0000 @@ -278,6 +278,19 @@ The arguments are in the same form accepted by oo1.DB.exec(), with the exceptions noted below. + If the `countChanges` arguments property (added in version 3.43) is + truthy then the `result` property contained by the returned object + will have a `changeCount` property which holds the number of changes + made by the provided SQL. Because the SQL may contain an arbitrary + number of statements, the `changeCount` is calculated by calling + `sqlite3_total_changes()` before and after the SQL is evaluated. If + the value of `countChanges` is 64 then the `changeCount` property + will be returned as a 64-bit integer in the form of a BigInt (noting + that that will trigger an exception if used in a BigInt-incapable + build). In the latter case, the number of changes is calculated by + calling `sqlite3_total_changes64()` before and after the SQL is + evaluated. + A function-type args.callback property cannot cross the window/Worker boundary, so is not useful here. If args.callback is a string then it is assumed to be a @@ -320,7 +333,6 @@ if(!(globalThis.WorkerGlobalScope instanceof Function)){ toss("initWorker1API() must be run from a Worker thread."); } - const self = this.self; const sqlite3 = this.sqlite3 || toss("Missing this.sqlite3 object."); const DB = sqlite3.oo1.DB; @@ -523,7 +535,13 @@ } } try { + const changeCount = !!rc.countChanges + ? db.changes(true,(64===rc.countChanges)) + : undefined; db.exec(rc); + if(undefined !== changeCount){ + rc.changeCount = db.changes(true,64===rc.countChanges) - changeCount; + } if(rc.callback instanceof Function){ rc.callback = theCallback; /* Post a sentinel message to tell the client that the end @@ -638,5 +656,5 @@ }, wState.xfer); }; globalThis.postMessage({type:'sqlite3-api',result:'worker1-ready'}); -}.bind({self, sqlite3}); +}.bind({sqlite3}); }); diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-opfs-async-proxy.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-opfs-async-proxy.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-opfs-async-proxy.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-opfs-async-proxy.js 2023-11-04 14:23:58.000000000 +0000 @@ -35,6 +35,9 @@ https://developer.chrome.com/blog/sync-methods-for-accesshandles/ + Firefox v111 and Safari 16.4, both released in March 2023, also + include this. + We cannot change to the sync forms at this point without breaking clients who use Chrome v104-ish or higher. truncate(), getSize(), flush(), and close() are now (as of v108) synchronous. Calling them @@ -818,9 +821,24 @@ } while(!flagAsyncShutdown){ try { - if('timed-out'===Atomics.wait( + if('not-equal'!==Atomics.wait( state.sabOPView, state.opIds.whichOp, 0, state.asyncIdleWaitTime )){ + /* Maintenance note: we compare against 'not-equal' because + + https://github.com/tomayac/sqlite-wasm/issues/12 + + is reporting that this occassionally, under high loads, + returns 'ok', which leads to the whichOp being 0 (which + isn't a valid operation ID and leads to an exception, + along with a corresponding ugly console log + message). Unfortunately, the conditions for that cannot + be reliably reproduced. The only place in our code which + writes a 0 to the state.opIds.whichOp SharedArrayBuffer + index is a few lines down from here, and that instance + is required in order for clear communication between + the sync half of this proxy and this half. + */ await releaseImplicitLocks(); continue; } diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 2023-11-04 14:23:58.000000000 +0000 @@ -1,3 +1,4 @@ +//#ifnot target=node /* 2022-09-18 @@ -23,7 +24,7 @@ installOpfsVfs() returns a Promise which, on success, installs an sqlite3_vfs named "opfs", suitable for use with all sqlite3 APIs which accept a VFS. It is intended to be called via - sqlite3ApiBootstrap.initializersAsync or an equivalent mechanism. + sqlite3ApiBootstrap.initializers or an equivalent mechanism. The installed VFS uses the Origin-Private FileSystem API for all file storage. On error it is rejected with an exception @@ -101,6 +102,10 @@ options = Object.create(null); } const urlParams = new URL(globalThis.location.href).searchParams; + if(urlParams.has('opfs-disable')){ + //sqlite3.config.warn('Explicitly not installing "opfs" VFS due to opfs-disable flag.'); + return Promise.resolve(sqlite3); + } if(undefined===options.verbose){ options.verbose = urlParams.has('opfs-verbose') ? (+urlParams.get('opfs-verbose') || 2) : 1; @@ -118,11 +123,11 @@ options.proxyUri = options.proxyUri(); } const thePromise = new Promise(function(promiseResolve_, promiseReject_){ - const loggers = { - 0:sqlite3.config.error, - 1:sqlite3.config.warn, - 2:sqlite3.config.log - }; + const loggers = [ + sqlite3.config.error, + sqlite3.config.warn, + sqlite3.config.log + ]; const logImpl = (level,...args)=>{ if(options.verbose>level) loggers[level]("OPFS syncer:",...args); }; @@ -131,6 +136,7 @@ const error = (...args)=>logImpl(0, ...args); const toss = sqlite3.util.toss; const capi = sqlite3.capi; + const util = sqlite3.util; const wasm = sqlite3.wasm; const sqlite3_vfs = capi.sqlite3_vfs; const sqlite3_file = capi.sqlite3_file; @@ -191,17 +197,18 @@ s.count = s.time = 0; } }/*metrics*/; - const opfsVfs = new sqlite3_vfs(); const opfsIoMethods = new sqlite3_io_methods(); + const opfsVfs = new sqlite3_vfs() + .addOnDispose( ()=>opfsIoMethods.dispose()); let promiseWasRejected = undefined; const promiseReject = (err)=>{ promiseWasRejected = true; opfsVfs.dispose(); return promiseReject_(err); }; - const promiseResolve = (value)=>{ + const promiseResolve = ()=>{ promiseWasRejected = false; - return promiseResolve_(value); + return promiseResolve_(sqlite3); }; const W = //#if target=es6-bundler-friendly @@ -235,17 +242,17 @@ ? new sqlite3_vfs(pDVfs) : null /* dVfs will be null when sqlite3 is built with SQLITE_OS_OTHER. */; + opfsIoMethods.$iVersion = 1; opfsVfs.$iVersion = 2/*yes, two*/; opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof; opfsVfs.$mxPathname = 1024/*sure, why not?*/; opfsVfs.$zName = wasm.allocCString("opfs"); // All C-side memory of opfsVfs is zeroed out, but just to be explicit: opfsVfs.$xDlOpen = opfsVfs.$xDlError = opfsVfs.$xDlSym = opfsVfs.$xDlClose = null; - opfsVfs.ondispose = [ + opfsVfs.addOnDispose( '$zName', opfsVfs.$zName, - 'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null), - 'cleanup opfsIoMethods', ()=>opfsIoMethods.dispose() - ]; + 'cleanup default VFS wrapper', ()=>(dVfs ? dVfs.dispose() : null) + ); /** Pedantic sidebar about opfsVfs.ondispose: the entries in that array are items to clean up when opfsVfs.dispose() is called, but in this @@ -298,6 +305,7 @@ lock contention to free up. */ state.asyncIdleWaitTime = 150; + /** Whether the async counterpart should log exceptions to the serialization channel. That produces a great deal of @@ -484,7 +492,8 @@ This proxy de/serializes cross-thread function arguments and output-pointer values via the state.sabIO SharedArrayBuffer, using the region defined by (state.sabS11nOffset, - state.sabS11nOffset]. Only one dataset is recorded at a time. + state.sabS11nOffset + state.sabS11nSize]. Only one dataset is + recorded at a time. This is not a general-purpose format. It only supports the range of operations, and data sizes, needed by the @@ -831,22 +840,19 @@ /* If it turns out that we need to adjust for timezone, see: https://stackoverflow.com/a/11760121/1458521 */ wasm.poke(pOut, 2440587.5 + (new Date().getTime()/86400000), - 'double'); + 'double'); return 0; }, xCurrentTimeInt64: function(pVfs,pOut){ - // TODO: confirm that this calculation is correct wasm.poke(pOut, (2440587.5 * 86400000) + new Date().getTime(), - 'i64'); + 'i64'); return 0; }, xDelete: function(pVfs, zName, doSyncDir){ mTimeStart('xDelete'); - opRun('xDelete', wasm.cstrToJs(zName), doSyncDir, false); - /* We're ignoring errors because we cannot yet differentiate - between harmless and non-harmless failures. */ + const rc = opRun('xDelete', wasm.cstrToJs(zName), doSyncDir, false); mTimeEnd(); - return 0; + return rc; }, xFullPathname: function(pVfs,zName,nOut,pOut){ /* Until/unless we have some notion of "current dir" @@ -1088,7 +1094,7 @@ propagate any exception on error, rather than returning false. */ opfsUtil.unlink = async function(fsEntryName, recursive = false, - throwOnError = false){ + throwOnError = false){ try { const [hDir, filenamePart] = await opfsUtil.getDirForFilename(fsEntryName, false); @@ -1163,11 +1169,102 @@ doDir(opt.directory, 0); }; - //TODO to support fiddle and worker1 db upload: - //opfsUtil.createFile = function(absName, content=undefined){...} - //We have sqlite3.wasm.sqlite3_wasm_vfs_create_file() for this - //purpose but its interface and name are still under - //consideration. + /** + impl of importDb() when it's given a function as its second + argument. + */ + const importDbChunked = async function(filename, callback){ + const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true); + const hFile = await hDir.getFileHandle(fnamePart, {create:true}); + let sah = await hFile.createSyncAccessHandle(); + let nWrote = 0, chunk, checkedHeader = false, err = false; + try{ + sah.truncate(0); + while( undefined !== (chunk = await callback()) ){ + if(chunk instanceof ArrayBuffer) chunk = new Uint8Array(chunk); + if( 0===nWrote && chunk.byteLength>=15 ){ + util.affirmDbHeader(chunk); + checkedHeader = true; + } + sah.write(chunk, {at: nWrote}); + nWrote += chunk.byteLength; + } + if( nWrote < 512 || 0!==nWrote % 512 ){ + toss("Input size",nWrote,"is not correct for an SQLite database."); + } + if( !checkedHeader ){ + const header = new Uint8Array(20); + sah.read( header, {at: 0} ); + util.affirmDbHeader( header ); + } + sah.write(new Uint8Array([1,1]), {at: 18}/*force db out of WAL mode*/); + return nWrote; + }catch(e){ + await sah.close(); + sah = undefined; + await hDir.removeEntry( fnamePart ).catch(()=>{}); + throw e; + }finally { + if( sah ) await sah.close(); + } + }; + + /** + Asynchronously imports the given bytes (a byte array or + ArrayBuffer) into the given database file. + + If passed a function for its second argument, its behaviour + changes to async and it imports its data in chunks fed to it by + the given callback function. It calls the callback (which may + be async) repeatedly, expecting either a Uint8Array or + ArrayBuffer (to denote new input) or undefined (to denote + EOF). For so long as the callback continues to return + non-undefined, it will append incoming data to the given + VFS-hosted database file. When called this way, the resolved + value of the returned Promise is the number of bytes written to + the target file. + + It very specifically requires the input to be an SQLite3 + database and throws if that's not the case. It does so in + order to prevent this function from taking on a larger scope + than it is specifically intended to. i.e. we do not want it to + become a convenience for importing arbitrary files into OPFS. + + This routine rewrites the database header bytes in the output + file (not the input array) to force disabling of WAL mode. + + On error this throws and the state of the input file is + undefined (it depends on where the exception was triggered). + + On success, resolves to the number of bytes written. + */ + opfsUtil.importDb = async function(filename, bytes){ + if( bytes instanceof Function ){ + return importDbChunked(filename, bytes); + } + if(bytes instanceof ArrayBuffer) bytes = new Uint8Array(bytes); + util.affirmIsDb(bytes); + const n = bytes.byteLength; + const [hDir, fnamePart] = await opfsUtil.getDirForFilename(filename, true); + let sah, err, nWrote = 0; + try { + const hFile = await hDir.getFileHandle(fnamePart, {create:true}); + sah = await hFile.createSyncAccessHandle(); + sah.truncate(0); + nWrote = sah.write(bytes, {at: 0}); + if(nWrote != n){ + toss("Expected to write "+n+" bytes but wrote "+nWrote+"."); + } + sah.write(new Uint8Array([1,1]), {at: 18}) /* force db out of WAL mode */; + return nWrote; + }catch(e){ + if( sah ){ await sah.close(); sah = undefined; } + await hDir.removeEntry( fnamePart ).catch(()=>{}); + throw e; + }finally{ + if( sah ) await sah.close(); + } + }; if(sqlite3.oo1){ const OpfsDb = function(...args){ @@ -1177,6 +1274,7 @@ }; OpfsDb.prototype = Object.create(sqlite3.oo1.DB.prototype); sqlite3.oo1.OpfsDb = OpfsDb; + OpfsDb.importDb = opfsUtil.importDb; sqlite3.oo1.DB.dbCtorHelper.setVfsPostOpenSql( opfsVfs.pointer, function(oo1Db, sqlite3){ @@ -1185,19 +1283,23 @@ contention. */ sqlite3.capi.sqlite3_busy_timeout(oo1Db, 10000); sqlite3.capi.sqlite3_exec(oo1Db, [ - /* Truncate journal mode is faster than delete for - this vfs, per speedtest1. That gap seems to have closed with - Chrome version 108 or 109, but "persist" is very roughly 5-6% - faster than truncate in initial tests. - - For later analysis: Roy Hashimoto notes that TRUNCATE - and PERSIST modes may decrease OPFS concurrency because - multiple connections can open the journal file in those - modes: + /* As of July 2023, the PERSIST journal mode on OPFS is + somewhat slower than DELETE or TRUNCATE (it was faster + before Chrome version 108 or 109). TRUNCATE and DELETE + have very similar performance on OPFS. + + Roy Hashimoto notes that TRUNCATE and PERSIST modes may + decrease OPFS concurrency because multiple connections + can open the journal file in those modes: https://github.com/rhashimoto/wa-sqlite/issues/68 + + Given that, and the fact that testing has not revealed + any appreciable difference between performance of + TRUNCATE and DELETE modes on OPFS, we currently (as of + 2023-07-13) default to DELETE mode. */ - "pragma journal_mode=persist;", + "pragma journal_mode=DELETE;", /* This vfs benefits hugely from cache on moderate/large speedtest1 --size 50 and --size 100 workloads. We @@ -1318,10 +1420,10 @@ sqlite3.opfs = opfsUtil; opfsUtil.rootDirectory = d; log("End of OPFS sqlite3_vfs setup.", opfsVfs); - promiseResolve(sqlite3); + promiseResolve(); }).catch(promiseReject); }else{ - promiseResolve(sqlite3); + promiseResolve(); } }catch(e){ error(e); @@ -1358,7 +1460,10 @@ }); }catch(e){ sqlite3.config.error("installOpfsVfs() exception:",e); - throw e; + return Promise.reject(e); } }); }/*sqlite3ApiBootstrap.initializers.push()*/); +//#else +/* The OPFS VFS parts are elided from builds targeting node.js. */ +//#endif target=node diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,1287 @@ +//#ifnot target=node +/* + 2023-07-14 + + The author disclaims copyright to this source code. In place of a + legal notice, here is a blessing: + + * May you do good and not evil. + * May you find forgiveness for yourself and forgive others. + * May you share freely, never taking more than you give. + + *********************************************************************** + + This file holds a sqlite3_vfs backed by OPFS storage which uses a + different implementation strategy than the "opfs" VFS. This one is a + port of Roy Hashimoto's OPFS SyncAccessHandle pool: + + https://github.com/rhashimoto/wa-sqlite/blob/master/src/examples/AccessHandlePoolVFS.js + + As described at: + + https://github.com/rhashimoto/wa-sqlite/discussions/67 + + with Roy's explicit permission to permit us to port his to our + infrastructure rather than having to clean-room reverse-engineer it: + + https://sqlite.org/forum/forumpost/e140d84e71 + + Primary differences from the "opfs" VFS include: + + - This one avoids the need for a sub-worker to synchronize + communication between the synchronous C API and the + only-partly-synchronous OPFS API. + + - It does so by opening a fixed number of OPFS files at + library-level initialization time, obtaining SyncAccessHandles to + each, and manipulating those handles via the synchronous sqlite3_vfs + interface. If it cannot open them (e.g. they are already opened by + another tab) then the VFS will not be installed. + + - Because of that, this one lacks all library-level concurrency + support. + + - Also because of that, it does not require the SharedArrayBuffer, + so can function without the COOP/COEP HTTP response headers. + + - It can hypothetically support Safari 16.4+, whereas the "opfs" VFS + requires v17 due to a subworker/storage bug in 16.x which makes it + incompatible with that VFS. + + - This VFS requires the "semi-fully-sync" FileSystemSyncAccessHandle + (hereafter "SAH") APIs released with Chrome v108 (and all other + major browsers released since March 2023). If that API is not + detected, the VFS is not registered. +*/ +globalThis.sqlite3ApiBootstrap.initializers.push(function(sqlite3){ + 'use strict'; + const toss = sqlite3.util.toss; + const toss3 = sqlite3.util.toss3; + const initPromises = Object.create(null); + const capi = sqlite3.capi; + const util = sqlite3.util; + const wasm = sqlite3.wasm; + // Config opts for the VFS... + const SECTOR_SIZE = 4096; + const HEADER_MAX_PATH_SIZE = 512; + const HEADER_FLAGS_SIZE = 4; + const HEADER_DIGEST_SIZE = 8; + const HEADER_CORPUS_SIZE = HEADER_MAX_PATH_SIZE + HEADER_FLAGS_SIZE; + const HEADER_OFFSET_FLAGS = HEADER_MAX_PATH_SIZE; + const HEADER_OFFSET_DIGEST = HEADER_CORPUS_SIZE; + const HEADER_OFFSET_DATA = SECTOR_SIZE; + /* Bitmask of file types which may persist across sessions. + SQLITE_OPEN_xyz types not listed here may be inadvertently + left in OPFS but are treated as transient by this VFS and + they will be cleaned up during VFS init. */ + const PERSISTENT_FILE_TYPES = + capi.SQLITE_OPEN_MAIN_DB | + capi.SQLITE_OPEN_MAIN_JOURNAL | + capi.SQLITE_OPEN_SUPER_JOURNAL | + capi.SQLITE_OPEN_WAL /* noting that WAL support is + unavailable in the WASM build.*/; + + /** Subdirectory of the VFS's space where "opaque" (randomly-named) + files are stored. Changing this effectively invalidates the data + stored under older names (orphaning it), so don't do that. */ + const OPAQUE_DIR_NAME = ".opaque"; + + /** + Returns short a string of random alphanumeric characters + suitable for use as a random filename. + */ + const getRandomName = ()=>Math.random().toString(36).slice(2); + + const textDecoder = new TextDecoder(); + const textEncoder = new TextEncoder(); + + const optionDefaults = Object.assign(Object.create(null),{ + name: 'opfs-sahpool', + directory: undefined /* derived from .name */, + initialCapacity: 6, + clearOnInit: false, + /* Logging verbosity 3+ == everything, 2 == warnings+errors, 1 == + errors only. */ + verbosity: 2 + }); + + /** Logging routines, from most to least serious. */ + const loggers = [ + sqlite3.config.error, + sqlite3.config.warn, + sqlite3.config.log + ]; + const log = sqlite3.config.log; + const warn = sqlite3.config.warn; + const error = sqlite3.config.error; + + /* Maps (sqlite3_vfs*) to OpfsSAHPool instances */ + const __mapVfsToPool = new Map(); + const getPoolForVfs = (pVfs)=>__mapVfsToPool.get(pVfs); + const setPoolForVfs = (pVfs,pool)=>{ + if(pool) __mapVfsToPool.set(pVfs, pool); + else __mapVfsToPool.delete(pVfs); + }; + /* Maps (sqlite3_file*) to OpfsSAHPool instances */ + const __mapSqlite3File = new Map(); + const getPoolForPFile = (pFile)=>__mapSqlite3File.get(pFile); + const setPoolForPFile = (pFile,pool)=>{ + if(pool) __mapSqlite3File.set(pFile, pool); + else __mapSqlite3File.delete(pFile); + }; + + /** + Impls for the sqlite3_io_methods methods. Maintenance reminder: + members are in alphabetical order to simplify finding them. + */ + const ioMethods = { + xCheckReservedLock: function(pFile,pOut){ + const pool = getPoolForPFile(pFile); + pool.log('xCheckReservedLock'); + pool.storeErr(); + wasm.poke32(pOut, 1); + return 0; + }, + xClose: function(pFile){ + const pool = getPoolForPFile(pFile); + pool.storeErr(); + const file = pool.getOFileForS3File(pFile); + if(file) { + try{ + pool.log(`xClose ${file.path}`); + pool.mapS3FileToOFile(pFile, false); + file.sah.flush(); + if(file.flags & capi.SQLITE_OPEN_DELETEONCLOSE){ + pool.deletePath(file.path); + } + }catch(e){ + return pool.storeErr(e, capi.SQLITE_IOERR); + } + } + return 0; + }, + xDeviceCharacteristics: function(pFile){ + return capi.SQLITE_IOCAP_UNDELETABLE_WHEN_OPEN; + }, + xFileControl: function(pFile, opId, pArg){ + return capi.SQLITE_NOTFOUND; + }, + xFileSize: function(pFile,pSz64){ + const pool = getPoolForPFile(pFile); + pool.log(`xFileSize`); + const file = pool.getOFileForS3File(pFile); + const size = file.sah.getSize() - HEADER_OFFSET_DATA; + //log(`xFileSize ${file.path} ${size}`); + wasm.poke64(pSz64, BigInt(size)); + return 0; + }, + xLock: function(pFile,lockType){ + const pool = getPoolForPFile(pFile); + pool.log(`xLock ${lockType}`); + pool.storeErr(); + const file = pool.getOFileForS3File(pFile); + file.lockType = lockType; + return 0; + }, + xRead: function(pFile,pDest,n,offset64){ + const pool = getPoolForPFile(pFile); + pool.storeErr(); + const file = pool.getOFileForS3File(pFile); + pool.log(`xRead ${file.path} ${n} @ ${offset64}`); + try { + const nRead = file.sah.read( + wasm.heap8u().subarray(pDest, pDest+n), + {at: HEADER_OFFSET_DATA + Number(offset64)} + ); + if(nRead < n){ + wasm.heap8u().fill(0, pDest + nRead, pDest + n); + return capi.SQLITE_IOERR_SHORT_READ; + } + return 0; + }catch(e){ + return pool.storeErr(e, capi.SQLITE_IOERR); + } + }, + xSectorSize: function(pFile){ + return SECTOR_SIZE; + }, + xSync: function(pFile,flags){ + const pool = getPoolForPFile(pFile); + pool.log(`xSync ${flags}`); + pool.storeErr(); + const file = pool.getOFileForS3File(pFile); + //log(`xSync ${file.path} ${flags}`); + try{ + file.sah.flush(); + return 0; + }catch(e){ + return pool.storeErr(e, capi.SQLITE_IOERR); + } + }, + xTruncate: function(pFile,sz64){ + const pool = getPoolForPFile(pFile); + pool.log(`xTruncate ${sz64}`); + pool.storeErr(); + const file = pool.getOFileForS3File(pFile); + //log(`xTruncate ${file.path} ${iSize}`); + try{ + file.sah.truncate(HEADER_OFFSET_DATA + Number(sz64)); + return 0; + }catch(e){ + return pool.storeErr(e, capi.SQLITE_IOERR); + } + }, + xUnlock: function(pFile,lockType){ + const pool = getPoolForPFile(pFile); + pool.log('xUnlock'); + const file = pool.getOFileForS3File(pFile); + file.lockType = lockType; + return 0; + }, + xWrite: function(pFile,pSrc,n,offset64){ + const pool = getPoolForPFile(pFile); + pool.storeErr(); + const file = pool.getOFileForS3File(pFile); + pool.log(`xWrite ${file.path} ${n} ${offset64}`); + try{ + const nBytes = file.sah.write( + wasm.heap8u().subarray(pSrc, pSrc+n), + { at: HEADER_OFFSET_DATA + Number(offset64) } + ); + return n===nBytes ? 0 : toss("Unknown write() failure."); + }catch(e){ + return pool.storeErr(e, capi.SQLITE_IOERR); + } + } + }/*ioMethods*/; + + const opfsIoMethods = new capi.sqlite3_io_methods(); + opfsIoMethods.$iVersion = 1; + sqlite3.vfs.installVfs({ + io: {struct: opfsIoMethods, methods: ioMethods} + }); + + /** + Impls for the sqlite3_vfs methods. Maintenance reminder: members + are in alphabetical order to simplify finding them. + */ + const vfsMethods = { + xAccess: function(pVfs,zName,flags,pOut){ + //log(`xAccess ${wasm.cstrToJs(zName)}`); + const pool = getPoolForVfs(pVfs); + pool.storeErr(); + try{ + const name = pool.getPath(zName); + wasm.poke32(pOut, pool.hasFilename(name) ? 1 : 0); + }catch(e){ + /*ignored*/ + wasm.poke32(pOut, 0); + } + return 0; + }, + xCurrentTime: function(pVfs,pOut){ + wasm.poke(pOut, 2440587.5 + (new Date().getTime()/86400000), + 'double'); + return 0; + }, + xCurrentTimeInt64: function(pVfs,pOut){ + wasm.poke(pOut, (2440587.5 * 86400000) + new Date().getTime(), + 'i64'); + return 0; + }, + xDelete: function(pVfs, zName, doSyncDir){ + const pool = getPoolForVfs(pVfs); + pool.log(`xDelete ${wasm.cstrToJs(zName)}`); + pool.storeErr(); + try{ + pool.deletePath(pool.getPath(zName)); + return 0; + }catch(e){ + pool.storeErr(e); + return capi.SQLITE_IOERR_DELETE; + } + }, + xFullPathname: function(pVfs,zName,nOut,pOut){ + //const pool = getPoolForVfs(pVfs); + //pool.log(`xFullPathname ${wasm.cstrToJs(zName)}`); + const i = wasm.cstrncpy(pOut, zName, nOut); + return i nOut) wasm.poke8(pOut + nOut - 1, 0); + }catch(e){ + return capi.SQLITE_NOMEM; + }finally{ + wasm.scopedAllocPop(scope); + } + } + return e ? (e.sqlite3Rc || capi.SQLITE_IOERR) : 0; + }, + //xSleep is optionally defined below + xOpen: function f(pVfs, zName, pFile, flags, pOutFlags){ + const pool = getPoolForVfs(pVfs); + try{ + pool.log(`xOpen ${wasm.cstrToJs(zName)} ${flags}`); + // First try to open a path that already exists in the file system. + const path = (zName && wasm.peek8(zName)) + ? pool.getPath(zName) + : getRandomName(); + let sah = pool.getSAHForPath(path); + if(!sah && (flags & capi.SQLITE_OPEN_CREATE)) { + // File not found so try to create it. + if(pool.getFileCount() < pool.getCapacity()) { + // Choose an unassociated OPFS file from the pool. + sah = pool.nextAvailableSAH(); + pool.setAssociatedPath(sah, path, flags); + }else{ + // File pool is full. + toss('SAH pool is full. Cannot create file',path); + } + } + if(!sah){ + toss('file not found:',path); + } + // Subsequent I/O methods are only passed the sqlite3_file + // pointer, so map the relevant info we need to that pointer. + const file = {path, flags, sah}; + pool.mapS3FileToOFile(pFile, file); + file.lockType = capi.SQLITE_LOCK_NONE; + const sq3File = new capi.sqlite3_file(pFile); + sq3File.$pMethods = opfsIoMethods.pointer; + sq3File.dispose(); + wasm.poke32(pOutFlags, flags); + return 0; + }catch(e){ + pool.storeErr(e); + return capi.SQLITE_CANTOPEN; + } + }/*xOpen()*/ + }/*vfsMethods*/; + + /** + Creates and initializes an sqlite3_vfs instance for an + OpfsSAHPool. The argument is the VFS's name (JS string). + + Throws if the VFS name is already registered or if something + goes terribly wrong via sqlite3.vfs.installVfs(). + + Maintenance reminder: the only detail about the returned object + which is specific to any given OpfsSAHPool instance is the $zName + member. All other state is identical. + */ + const createOpfsVfs = function(vfsName){ + if( sqlite3.capi.sqlite3_vfs_find(vfsName)){ + toss3("VFS name is already registered:", vfsName); + } + const opfsVfs = new capi.sqlite3_vfs(); + /* We fetch the default VFS so that we can inherit some + methods from it. */ + const pDVfs = capi.sqlite3_vfs_find(null); + const dVfs = pDVfs + ? new capi.sqlite3_vfs(pDVfs) + : null /* dVfs will be null when sqlite3 is built with + SQLITE_OS_OTHER. */; + opfsVfs.$iVersion = 2/*yes, two*/; + opfsVfs.$szOsFile = capi.sqlite3_file.structInfo.sizeof; + opfsVfs.$mxPathname = HEADER_MAX_PATH_SIZE; + opfsVfs.addOnDispose( + opfsVfs.$zName = wasm.allocCString(vfsName), + ()=>setPoolForVfs(opfsVfs.pointer, 0) + ); + + if(dVfs){ + /* Inherit certain VFS members from the default VFS, + if available. */ + opfsVfs.$xRandomness = dVfs.$xRandomness; + opfsVfs.$xSleep = dVfs.$xSleep; + dVfs.dispose(); + } + if(!opfsVfs.$xRandomness && !vfsMethods.xRandomness){ + /* If the default VFS has no xRandomness(), add a basic JS impl... */ + vfsMethods.xRandomness = function(pVfs, nOut, pOut){ + const heap = wasm.heap8u(); + let i = 0; + for(; i < nOut; ++i) heap[pOut + i] = (Math.random()*255000) & 0xFF; + return i; + }; + } + if(!opfsVfs.$xSleep && !vfsMethods.xSleep){ + vfsMethods.xSleep = (pVfs,ms)=>0; + } + sqlite3.vfs.installVfs({ + vfs: {struct: opfsVfs, methods: vfsMethods} + }); + return opfsVfs; + }; + + /** + Class for managing OPFS-related state for the + OPFS SharedAccessHandle Pool sqlite3_vfs. + */ + class OpfsSAHPool { + /* OPFS dir in which VFS metadata is stored. */ + vfsDir; + /* Directory handle to this.vfsDir. */ + #dhVfsRoot; + /* Directory handle to the subdir of this.#dhVfsRoot which holds + the randomly-named "opaque" files. This subdir exists in the + hope that we can eventually support client-created files in + this.#dhVfsRoot. */ + #dhOpaque; + /* Directory handle to this.dhVfsRoot's parent dir. Needed + for a VFS-wipe op. */ + #dhVfsParent; + /* Maps SAHs to their opaque file names. */ + #mapSAHToName = new Map(); + /* Maps client-side file names to SAHs. */ + #mapFilenameToSAH = new Map(); + /* Set of currently-unused SAHs. */ + #availableSAH = new Set(); + /* Maps (sqlite3_file*) to xOpen's file objects. */ + #mapS3FileToOFile_ = new Map(); + + /* Maps SAH to an abstract File Object which contains + various metadata about that handle. */ + //#mapSAHToMeta = new Map(); + + /** Buffer used by [sg]etAssociatedPath(). */ + #apBody = new Uint8Array(HEADER_CORPUS_SIZE); + // DataView for this.#apBody + #dvBody; + + // associated sqlite3_vfs instance + #cVfs; + + // Logging verbosity. See optionDefaults.verbosity. + #verbosity; + + constructor(options = Object.create(null)){ + this.#verbosity = options.verbosity ?? optionDefaults.verbosity; + this.vfsName = options.name || optionDefaults.name; + this.#cVfs = createOpfsVfs(this.vfsName); + setPoolForVfs(this.#cVfs.pointer, this); + this.vfsDir = options.directory || ("."+this.vfsName); + this.#dvBody = + new DataView(this.#apBody.buffer, this.#apBody.byteOffset); + this.isReady = this + .reset(!!(options.clearOnInit ?? optionDefaults.clearOnInit)) + .then(()=>{ + if(this.$error) throw this.$error; + return this.getCapacity() + ? Promise.resolve(undefined) + : this.addCapacity(options.initialCapacity + || optionDefaults.initialCapacity); + }); + } + + #logImpl(level,...args){ + if(this.#verbosity>level) loggers[level](this.vfsName+":",...args); + }; + log(...args){this.#logImpl(2, ...args)}; + warn(...args){this.#logImpl(1, ...args)}; + error(...args){this.#logImpl(0, ...args)}; + + getVfs(){return this.#cVfs} + + /* Current pool capacity. */ + getCapacity(){return this.#mapSAHToName.size} + + /* Current number of in-use files from pool. */ + getFileCount(){return this.#mapFilenameToSAH.size} + + /* Returns an array of the names of all + currently-opened client-specified filenames. */ + getFileNames(){ + const rc = []; + const iter = this.#mapFilenameToSAH.keys(); + for(const n of iter) rc.push(n); + return rc; + } + +// #createFileObject(sah,clientName,opaqueName){ +// const f = Object.assign(Object.create(null),{ +// clientName, opaqueName +// }); +// this.#mapSAHToMeta.set(sah, f); +// return f; +// } +// #unmapFileObject(sah){ +// this.#mapSAHToMeta.delete(sah); +// } + + /** + Adds n files to the pool's capacity. This change is + persistent across settings. Returns a Promise which resolves + to the new capacity. + */ + async addCapacity(n){ + for(let i = 0; i < n; ++i){ + const name = getRandomName(); + const h = await this.#dhOpaque.getFileHandle(name, {create:true}); + const ah = await h.createSyncAccessHandle(); + this.#mapSAHToName.set(ah,name); + this.setAssociatedPath(ah, '', 0); + //this.#createFileObject(ah,undefined,name); + } + return this.getCapacity(); + } + + /** + Reduce capacity by n, but can only reduce up to the limit + of currently-available SAHs. Returns a Promise which resolves + to the number of slots really removed. + */ + async reduceCapacity(n){ + let nRm = 0; + for(const ah of Array.from(this.#availableSAH)){ + if(nRm === n || this.getFileCount() === this.getCapacity()){ + break; + } + const name = this.#mapSAHToName.get(ah); + //this.#unmapFileObject(ah); + ah.close(); + await this.#dhOpaque.removeEntry(name); + this.#mapSAHToName.delete(ah); + this.#availableSAH.delete(ah); + ++nRm; + } + return nRm; + } + + /** + Releases all currently-opened SAHs. The only legal + operation after this is acquireAccessHandles(). + */ + releaseAccessHandles(){ + for(const ah of this.#mapSAHToName.keys()) ah.close(); + this.#mapSAHToName.clear(); + this.#mapFilenameToSAH.clear(); + this.#availableSAH.clear(); + } + + /** + Opens all files under this.vfsDir/this.#dhOpaque and acquires + a SAH for each. returns a Promise which resolves to no value + but completes once all SAHs are acquired. If acquiring an SAH + throws, SAHPool.$error will contain the corresponding + exception. + + If clearFiles is true, the client-stored state of each file is + cleared when its handle is acquired, including its name, flags, + and any data stored after the metadata block. + */ + async acquireAccessHandles(clearFiles){ + const files = []; + for await (const [name,h] of this.#dhOpaque){ + if('file'===h.kind){ + files.push([name,h]); + } + } + return Promise.all(files.map(async([name,h])=>{ + try{ + const ah = await h.createSyncAccessHandle() + this.#mapSAHToName.set(ah, name); + if(clearFiles){ + ah.truncate(HEADER_OFFSET_DATA); + this.setAssociatedPath(ah, '', 0); + }else{ + const path = this.getAssociatedPath(ah); + if(path){ + this.#mapFilenameToSAH.set(path, ah); + }else{ + this.#availableSAH.add(ah); + } + } + }catch(e){ + this.storeErr(e); + this.releaseAccessHandles(); + throw e; + } + })); + } + + /** + Given an SAH, returns the client-specified name of + that file by extracting it from the SAH's header. + + On error, it disassociates SAH from the pool and + returns an empty string. + */ + getAssociatedPath(sah){ + sah.read(this.#apBody, {at: 0}); + // Delete any unexpected files left over by previous + // untimely errors... + const flags = this.#dvBody.getUint32(HEADER_OFFSET_FLAGS); + if(this.#apBody[0] && + ((flags & capi.SQLITE_OPEN_DELETEONCLOSE) || + (flags & PERSISTENT_FILE_TYPES)===0)){ + warn(`Removing file with unexpected flags ${flags.toString(16)}`, + this.#apBody); + this.setAssociatedPath(sah, '', 0); + return ''; + } + + const fileDigest = new Uint32Array(HEADER_DIGEST_SIZE / 4); + sah.read(fileDigest, {at: HEADER_OFFSET_DIGEST}); + const compDigest = this.computeDigest(this.#apBody); + if(fileDigest.every((v,i) => v===compDigest[i])){ + // Valid digest + const pathBytes = this.#apBody.findIndex((v)=>0===v); + if(0===pathBytes){ + // This file is unassociated, so truncate it to avoid + // leaving stale db data laying around. + sah.truncate(HEADER_OFFSET_DATA); + } + return pathBytes + ? textDecoder.decode(this.#apBody.subarray(0,pathBytes)) + : ''; + }else{ + // Invalid digest + warn('Disassociating file with bad digest.'); + this.setAssociatedPath(sah, '', 0); + return ''; + } + } + + /** + Stores the given client-defined path and SQLITE_OPEN_xyz flags + into the given SAH. If path is an empty string then the file is + disassociated from the pool but its previous name is preserved + in the metadata. + */ + setAssociatedPath(sah, path, flags){ + const enc = textEncoder.encodeInto(path, this.#apBody); + if(HEADER_MAX_PATH_SIZE <= enc.written + 1/*NUL byte*/){ + toss("Path too long:",path); + } + this.#apBody.fill(0, enc.written, HEADER_MAX_PATH_SIZE); + this.#dvBody.setUint32(HEADER_OFFSET_FLAGS, flags); + + const digest = this.computeDigest(this.#apBody); + sah.write(this.#apBody, {at: 0}); + sah.write(digest, {at: HEADER_OFFSET_DIGEST}); + sah.flush(); + + if(path){ + this.#mapFilenameToSAH.set(path, sah); + this.#availableSAH.delete(sah); + }else{ + // This is not a persistent file, so eliminate the contents. + sah.truncate(HEADER_OFFSET_DATA); + this.#availableSAH.add(sah); + } + } + + /** + Computes a digest for the given byte array and returns it as a + two-element Uint32Array. This digest gets stored in the + metadata for each file as a validation check. Changing this + algorithm invalidates all existing databases for this VFS, so + don't do that. + */ + computeDigest(byteArray){ + let h1 = 0xdeadbeef; + let h2 = 0x41c6ce57; + for(const v of byteArray){ + h1 = 31 * h1 + (v * 307); + h2 = 31 * h2 + (v * 307); + } + return new Uint32Array([h1>>>0, h2>>>0]); + } + + /** + Re-initializes the state of the SAH pool, releasing and + re-acquiring all handles. + + See acquireAccessHandles() for the specifics of the clearFiles + argument. + */ + async reset(clearFiles){ + await this.isReady; + let h = await navigator.storage.getDirectory(); + let prev, prevName; + for(const d of this.vfsDir.split('/')){ + if(d){ + prev = h; + h = await h.getDirectoryHandle(d,{create:true}); + } + } + this.#dhVfsRoot = h; + this.#dhVfsParent = prev; + this.#dhOpaque = await this.#dhVfsRoot.getDirectoryHandle( + OPAQUE_DIR_NAME,{create:true} + ); + this.releaseAccessHandles(); + return this.acquireAccessHandles(clearFiles); + } + + /** + Returns the pathname part of the given argument, + which may be any of: + + - a URL object + - A JS string representing a file name + - Wasm C-string representing a file name + + All "../" parts and duplicate slashes are resolve/removed from + the returned result. + */ + getPath(arg) { + if(wasm.isPtr(arg)) arg = wasm.cstrToJs(arg); + return ((arg instanceof URL) + ? arg + : new URL(arg, 'file://localhost/')).pathname; + } + + /** + Removes the association of the given client-specified file + name (JS string) from the pool. Returns true if a mapping + is found, else false. + */ + deletePath(path) { + const sah = this.#mapFilenameToSAH.get(path); + if(sah) { + // Un-associate the name from the SAH. + this.#mapFilenameToSAH.delete(path); + this.setAssociatedPath(sah, '', 0); + } + return !!sah; + } + + /** + Sets e (an Error object) as this object's current error. Pass a + falsy (or no) value to clear it. If code is truthy it is + assumed to be an SQLITE_xxx result code, defaulting to + SQLITE_IOERR if code is falsy. + + Returns the 2nd argument. + */ + storeErr(e,code){ + if(e){ + e.sqlite3Rc = code || capi.SQLITE_IOERR; + this.error(e); + } + this.$error = e; + return code; + } + /** + Pops this object's Error object and returns + it (a falsy value if no error is set). + */ + popErr(){ + const rc = this.$error; + this.$error = undefined; + return rc; + } + + /** + Returns the next available SAH without removing + it from the set. + */ + nextAvailableSAH(){ + const [rc] = this.#availableSAH.keys(); + return rc; + } + + /** + Given an (sqlite3_file*), returns the mapped + xOpen file object. + */ + getOFileForS3File(pFile){ + return this.#mapS3FileToOFile_.get(pFile); + } + /** + Maps or unmaps (if file is falsy) the given (sqlite3_file*) + to an xOpen file object and to this pool object. + */ + mapS3FileToOFile(pFile,file){ + if(file){ + this.#mapS3FileToOFile_.set(pFile, file); + setPoolForPFile(pFile, this); + }else{ + this.#mapS3FileToOFile_.delete(pFile); + setPoolForPFile(pFile, false); + } + } + + /** + Returns true if the given client-defined file name is in this + object's name-to-SAH map. + */ + hasFilename(name){ + return this.#mapFilenameToSAH.has(name) + } + + /** + Returns the SAH associated with the given + client-defined file name. + */ + getSAHForPath(path){ + return this.#mapFilenameToSAH.get(path); + } + + /** + Removes this object's sqlite3_vfs registration and shuts down + this object, releasing all handles, mappings, and whatnot, + including deleting its data directory. There is currently no + way to "revive" the object and reaquire its resources. + + This function is intended primarily for testing. + + Resolves to true if it did its job, false if the + VFS has already been shut down. + */ + async removeVfs(){ + if(!this.#cVfs.pointer || !this.#dhOpaque) return false; + capi.sqlite3_vfs_unregister(this.#cVfs.pointer); + this.#cVfs.dispose(); + try{ + this.releaseAccessHandles(); + await this.#dhVfsRoot.removeEntry(OPAQUE_DIR_NAME, {recursive: true}); + this.#dhOpaque = undefined; + await this.#dhVfsParent.removeEntry( + this.#dhVfsRoot.name, {recursive: true} + ); + this.#dhVfsRoot = this.#dhVfsParent = undefined; + }catch(e){ + sqlite3.config.error(this.vfsName,"removeVfs() failed:",e); + /*otherwise ignored - there is no recovery strategy*/ + } + return true; + } + + + //! Documented elsewhere in this file. + exportFile(name){ + const sah = this.#mapFilenameToSAH.get(name) || toss("File not found:",name); + const n = sah.getSize() - HEADER_OFFSET_DATA; + const b = new Uint8Array(n>0 ? n : 0); + if(n>0){ + const nRead = sah.read(b, {at: HEADER_OFFSET_DATA}); + if(nRead != n){ + toss("Expected to read "+n+" bytes but read "+nRead+"."); + } + } + return b; + } + + //! Impl for importDb() when its 2nd arg is a function. + async importDbChunked(name, callback){ + const sah = this.#mapFilenameToSAH.get(name) + || this.nextAvailableSAH() + || toss("No available handles to import to."); + sah.truncate(0); + let nWrote = 0, chunk, checkedHeader = false, err = false; + try{ + while( undefined !== (chunk = await callback()) ){ + if(chunk instanceof ArrayBuffer) chunk = new Uint8Array(chunk); + if( 0===nWrote && chunk.byteLength>=15 ){ + util.affirmDbHeader(chunk); + checkedHeader = true; + } + sah.write(chunk, {at: HEADER_OFFSET_DATA + nWrote}); + nWrote += chunk.byteLength; + } + if( nWrote < 512 || 0!==nWrote % 512 ){ + toss("Input size",nWrote,"is not correct for an SQLite database."); + } + if( !checkedHeader ){ + const header = new Uint8Array(20); + sah.read( header, {at: 0} ); + util.affirmDbHeader( header ); + } + sah.write(new Uint8Array([1,1]), { + at: HEADER_OFFSET_DATA + 18 + }/*force db out of WAL mode*/); + }catch(e){ + this.setAssociatedPath(sah, '', 0); + throw e; + } + this.setAssociatedPath(sah, name, capi.SQLITE_OPEN_MAIN_DB); + return nWrote; + } + + //! Documented elsewhere in this file. + importDb(name, bytes){ + if( bytes instanceof ArrayBuffer ) bytes = new Uint8Array(bytes); + else if( bytes instanceof Function ) return this.importDbChunked(name, bytes); + const sah = this.#mapFilenameToSAH.get(name) + || this.nextAvailableSAH() + || toss("No available handles to import to."); + const n = bytes.byteLength; + if(n<512 || n%512!=0){ + toss("Byte array size is invalid for an SQLite db."); + } + const header = "SQLite format 3"; + for(let i = 0; i < header.length; ++i){ + if( header.charCodeAt(i) !== bytes[i] ){ + toss("Input does not contain an SQLite database header."); + } + } + const nWrote = sah.write(bytes, {at: HEADER_OFFSET_DATA}); + if(nWrote != n){ + this.setAssociatedPath(sah, '', 0); + toss("Expected to write "+n+" bytes but wrote "+nWrote+"."); + }else{ + sah.write(new Uint8Array([1,1]), {at: HEADER_OFFSET_DATA+18} + /* force db out of WAL mode */); + this.setAssociatedPath(sah, name, capi.SQLITE_OPEN_MAIN_DB); + } + return nWrote; + } + + }/*class OpfsSAHPool*/; + + + /** + A OpfsSAHPoolUtil instance is exposed to clients in order to + manipulate an OpfsSAHPool object without directly exposing that + object and allowing for some semantic changes compared to that + class. + + Class docs are in the client-level docs for + installOpfsSAHPoolVfs(). + */ + class OpfsSAHPoolUtil { + /* This object's associated OpfsSAHPool. */ + #p; + + constructor(sahPool){ + this.#p = sahPool; + this.vfsName = sahPool.vfsName; + } + + async addCapacity(n){ return this.#p.addCapacity(n) } + + async reduceCapacity(n){ return this.#p.reduceCapacity(n) } + + getCapacity(){ return this.#p.getCapacity(this.#p) } + + getFileCount(){ return this.#p.getFileCount() } + getFileNames(){ return this.#p.getFileNames() } + + async reserveMinimumCapacity(min){ + const c = this.#p.getCapacity(); + return (c < min) ? this.#p.addCapacity(min - c) : c; + } + + exportFile(name){ return this.#p.exportFile(name) } + + importDb(name, bytes){ return this.#p.importDb(name,bytes) } + + async wipeFiles(){ return this.#p.reset(true) } + + unlink(filename){ return this.#p.deletePath(filename) } + + async removeVfs(){ return this.#p.removeVfs() } + + }/* class OpfsSAHPoolUtil */; + + /** + Returns a resolved Promise if the current environment + has a "fully-sync" SAH impl, else a rejected Promise. + */ + const apiVersionCheck = async ()=>{ + const dh = await navigator.storage.getDirectory(); + const fn = '.opfs-sahpool-sync-check-'+getRandomName(); + const fh = await dh.getFileHandle(fn, { create: true }); + const ah = await fh.createSyncAccessHandle(); + const close = ah.close(); + await close; + await dh.removeEntry(fn); + if(close?.then){ + toss("The local OPFS API is too old for opfs-sahpool:", + "it has an async FileSystemSyncAccessHandle.close() method."); + } + return true; + }; + + /** Only for testing a rejection case. */ + let instanceCounter = 0; + + /** + installOpfsSAHPoolVfs() asynchronously initializes the OPFS + SyncAccessHandle (a.k.a. SAH) Pool VFS. It returns a Promise which + either resolves to a utility object described below or rejects with + an Error value. + + Initialization of this VFS is not automatic because its + registration requires that it lock all resources it + will potentially use, even if client code does not want + to use them. That, in turn, can lead to locking errors + when, for example, one page in a given origin has loaded + this VFS but does not use it, then another page in that + origin tries to use the VFS. If the VFS were automatically + registered, the second page would fail to load the VFS + due to OPFS locking errors. + + If this function is called more than once with a given "name" + option (see below), it will return the same Promise. Calls for + different names will return different Promises which resolve to + independent objects and refer to different VFS registrations. + + On success, the resulting Promise resolves to a utility object + which can be used to query and manipulate the pool. Its API is + described at the end of these docs. + + This function accepts an options object to configure certain + parts but it is only acknowledged for the very first call and + ignored for all subsequent calls. + + The options, in alphabetical order: + + - `clearOnInit`: (default=false) if truthy, contents and filename + mapping are removed from each SAH it is acquired during + initalization of the VFS, leaving the VFS's storage in a pristine + state. Use this only for databases which need not survive a page + reload. + + - `initialCapacity`: (default=6) Specifies the default capacity of + the VFS. This should not be set unduly high because the VFS has + to open (and keep open) a file for each entry in the pool. This + setting only has an effect when the pool is initially empty. It + does not have any effect if a pool already exists. + + - `directory`: (default="."+`name`) Specifies the OPFS directory + name in which to store metadata for the `"opfs-sahpool"` + sqlite3_vfs. Only one instance of this VFS can be installed per + JavaScript engine, and any two engines with the same storage + directory name will collide with each other, leading to locking + errors and the inability to register the VFS in the second and + subsequent engine. Using a different directory name for each + application enables different engines in the same HTTP origin to + co-exist, but their data are invisible to each other. Changing + this name will effectively orphan any databases stored under + previous names. The default is unspecified but descriptive. This + option may contain multiple path elements, e.g. "foo/bar/baz", + and they are created automatically. In practice there should be + no driving need to change this. ACHTUNG: all files in this + directory are assumed to be managed by the VFS. Do not place + other files in that directory, as they may be deleted or + otherwise modified by the VFS. + + - `name`: (default="opfs-sahpool") sets the name to register this + VFS under. Normally this should not be changed, but it is + possible to register this VFS under multiple names so long as + each has its own separate directory to work from. The storage for + each is invisible to all others. The name must be a string + compatible with `sqlite3_vfs_register()` and friends and suitable + for use in URI-style database file names. + + Achtung: if a custom `name` is provided, a custom `directory` + must also be provided if any other instance is registered with + the default directory. If no directory is explicitly provided + then a directory name is synthesized from the `name` option. + + Peculiarities of this VFS: + + - Paths given to it _must_ be absolute. Relative paths will not + be properly recognized. This is arguably a bug but correcting it + requires some hoop-jumping in routines which have no business + doing tricks. + + - It is possible to install multiple instances under different + names, each sandboxed from one another inside their own private + directory. This feature exists primarily as a way for disparate + applications within a given HTTP origin to use this VFS without + introducing locking issues between them. + + + The API for the utility object passed on by this function's + Promise, in alphabetical order... + + - [async] number addCapacity(n) + + Adds `n` entries to the current pool. This change is persistent + across sessions so should not be called automatically at each app + startup (but see `reserveMinimumCapacity()`). Its returned Promise + resolves to the new capacity. Because this operation is necessarily + asynchronous, the C-level VFS API cannot call this on its own as + needed. + + - byteArray exportFile(name) + + Synchronously reads the contents of the given file into a Uint8Array + and returns it. This will throw if the given name is not currently + in active use or on I/O error. Note that the given name is _not_ + visible directly in OPFS (or, if it is, it's not from this VFS). + + - number getCapacity() + + Returns the number of files currently contained + in the SAH pool. The default capacity is only large enough for one + or two databases and their associated temp files. + + - number getFileCount() + + Returns the number of files from the pool currently allocated to + slots. This is not the same as the files being "opened". + + - array getFileNames() + + Returns an array of the names of the files currently allocated to + slots. This list is the same length as getFileCount(). + + - void importDb(name, bytes) + + Imports the contents of an SQLite database, provided as a byte + array or ArrayBuffer, under the given name, overwriting any + existing content. Throws if the pool has no available file slots, + on I/O error, or if the input does not appear to be a + database. In the latter case, only a cursory examination is made. + Note that this routine is _only_ for importing database files, + not arbitrary files, the reason being that this VFS will + automatically clean up any non-database files so importing them + is pointless. + + If passed a function for its second argument, its behavior + changes to asynchronous and it imports its data in chunks fed to + it by the given callback function. It calls the callback (which + may be async) repeatedly, expecting either a Uint8Array or + ArrayBuffer (to denote new input) or undefined (to denote + EOF). For so long as the callback continues to return + non-undefined, it will append incoming data to the given + VFS-hosted database file. The result of the resolved Promise when + called this way is the size of the resulting database. + + On succes this routine rewrites the database header bytes in the + output file (not the input array) to force disabling of WAL mode. + + On a write error, the handle is removed from the pool and made + available for re-use. + + - [async] number reduceCapacity(n) + + Removes up to `n` entries from the pool, with the caveat that it can + only remove currently-unused entries. It returns a Promise which + resolves to the number of entries actually removed. + + - [async] boolean removeVfs() + + Unregisters the opfs-sahpool VFS and removes its directory from OPFS + (which means that _all client content_ is removed). After calling + this, the VFS may no longer be used and there is no way to re-add it + aside from reloading the current JavaScript context. + + Results are undefined if a database is currently in use with this + VFS. + + The returned Promise resolves to true if it performed the removal + and false if the VFS was not installed. + + If the VFS has a multi-level directory, e.g. "/foo/bar/baz", _only_ + the bottom-most directory is removed because this VFS cannot know for + certain whether the higher-level directories contain data which + should be removed. + + - [async] number reserveMinimumCapacity(min) + + If the current capacity is less than `min`, the capacity is + increased to `min`, else this returns with no side effects. The + resulting Promise resolves to the new capacity. + + - boolean unlink(filename) + + If a virtual file exists with the given name, disassociates it from + the pool and returns true, else returns false without side + effects. Results are undefined if the file is currently in active + use. + + - string vfsName + + The SQLite VFS name under which this pool's VFS is registered. + + - [async] void wipeFiles() + + Clears all client-defined state of all SAHs and makes all of them + available for re-use by the pool. Results are undefined if any such + handles are currently in use, e.g. by an sqlite3 db. + */ + sqlite3.installOpfsSAHPoolVfs = async function(options=Object.create(null)){ + const vfsName = options.name || optionDefaults.name; + if(0 && 2===++instanceCounter){ + throw new Error("Just testing rejection."); + } + if(initPromises[vfsName]){ + //console.warn("Returning same OpfsSAHPool result",options,vfsName,initPromises[vfsName]); + return initPromises[vfsName]; + } + if(!globalThis.FileSystemHandle || + !globalThis.FileSystemDirectoryHandle || + !globalThis.FileSystemFileHandle || + !globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle || + !navigator?.storage?.getDirectory){ + return (initPromises[vfsName] = Promise.reject(new Error("Missing required OPFS APIs."))); + } + + /** + Maintenance reminder: the order of ASYNC ops in this function + is significant. We need to have them all chained at the very + end in order to be able to catch a race condition where + installOpfsSAHPoolVfs() is called twice in rapid succession, + e.g.: + + installOpfsSAHPoolVfs().then(console.warn.bind(console)); + installOpfsSAHPoolVfs().then(console.warn.bind(console)); + + If the timing of the async calls is not "just right" then that + second call can end up triggering the init a second time and chaos + ensues. + */ + return initPromises[vfsName] = apiVersionCheck().then(async function(){ + if(options.$testThrowInInit){ + throw options.$testThrowInInit; + } + const thePool = new OpfsSAHPool(options); + return thePool.isReady.then(async()=>{ + /** The poolUtil object will be the result of the + resolved Promise. */ + const poolUtil = new OpfsSAHPoolUtil(thePool); + if(sqlite3.oo1){ + const oo1 = sqlite3.oo1; + const theVfs = thePool.getVfs(); + const OpfsSAHPoolDb = function(...args){ + const opt = oo1.DB.dbCtorHelper.normalizeArgs(...args); + opt.vfs = theVfs.$zName; + oo1.DB.dbCtorHelper.call(this, opt); + }; + OpfsSAHPoolDb.prototype = Object.create(oo1.DB.prototype); + // yes or no? OpfsSAHPoolDb.PoolUtil = poolUtil; + poolUtil.OpfsSAHPoolDb = OpfsSAHPoolDb; + oo1.DB.dbCtorHelper.setVfsPostOpenSql( + theVfs.pointer, + function(oo1Db, sqlite3){ + sqlite3.capi.sqlite3_exec(oo1Db, [ + /* See notes in sqlite3-vfs-opfs.js */ + "pragma journal_mode=DELETE;", + "pragma cache_size=-16384;" + ], 0, 0, 0); + } + ); + }/*extend sqlite3.oo1*/ + thePool.log("VFS initialized."); + return poolUtil; + }).catch(async (e)=>{ + await thePool.removeVfs().catch(()=>{}); + return e; + }); + }).catch((err)=>{ + //error("rejecting promise:",err); + return initPromises[vfsName] = Promise.reject(err); + }); + }/*installOpfsSAHPoolVfs()*/; +}/*sqlite3ApiBootstrap.initializers*/); +//#else +/* + The OPFS SAH Pool VFS parts are elided from builds targeting + node.js. +*/ +//#endif target=node diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-v-helper.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-v-helper.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-v-helper.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-v-helper.js 2023-11-04 14:23:58.000000000 +0000 @@ -100,7 +100,7 @@ ACHTUNG: because we cannot generically know how to transform JS exceptions into result codes, the installed functions do no - automatic catching of exceptions. It is critical, to avoid + automatic catching of exceptions. It is critical, to avoid undefined behavior in the C layer, that methods mapped via this function do not throw. The exception, as it were, to that rule is... @@ -295,7 +295,8 @@ - If `struct.$zName` is falsy and the entry has a string-type `name` property, `struct.$zName` is set to the C-string form of - that `name` value before registerVfs() is called. + that `name` value before registerVfs() is called. That string + gets added to the on-dispose state of the struct. On success returns this object. Throws on error. */ @@ -608,7 +609,7 @@ This is to facilitate creation of those methods inline in the passed-in object without requiring the client to explicitly get a reference to one of them in order to assign it to the other - one. + one. The `catchExceptions`-installed handlers will account for identical references to the above functions and will install the diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-wasi.h sqlite3-3.44.0-0/ext/wasm/api/sqlite3-wasi.h --- sqlite3-3.42.0/ext/wasm/api/sqlite3-wasi.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-wasi.h 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -/** - Dummy function stubs to get sqlite3.c compiling with - wasi-sdk. This requires, in addition: - - -D_WASI_EMULATED_MMAN -D_WASI_EMULATED_GETPID - - -lwasi-emulated-getpid -*/ -typedef unsigned mode_t; -int fchmod(int fd, mode_t mode); -int fchmod(int fd, mode_t mode){ - return (fd && mode) ? 0 : 0; -} -typedef unsigned uid_t; -typedef uid_t gid_t; -int fchown(int fd, uid_t owner, gid_t group); -int fchown(int fd, uid_t owner, gid_t group){ - return (fd && owner && group) ? 0 : 0; -} -uid_t geteuid(void); -uid_t geteuid(void){return 0;} -#if !defined(F_WRLCK) -enum { -F_WRLCK, -F_RDLCK, -F_GETLK, -F_SETLK, -F_UNLCK -}; -#endif - -#undef HAVE_PREAD - -#include -#define WASM__KEEP __attribute__((used)) - -#if 0 -/** - wasi-sdk cannot build sqlite3's default VFS without at least the following - functions. They are apparently syscalls which clients have to implement or - otherwise obtain. - - https://github.com/WebAssembly/WASI/blob/main/phases/snapshot/docs.md -*/ -environ_get -environ_sizes_get -clock_time_get -fd_close -fd_fdstat_get -fd_fdstat_set_flags -fd_filestat_get -fd_filestat_set_size -fd_pread -fd_prestat_get -fd_prestat_dir_name -fd_read -fd_seek -fd_sync -fd_write -path_create_directory -path_filestat_get -path_filestat_set_times -path_open -path_readlink -path_remove_directory -path_unlink_file -poll_oneoff -proc_exit -#endif diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-wasm.c sqlite3-3.44.0-0/ext/wasm/api/sqlite3-wasm.c --- sqlite3-3.42.0/ext/wasm/api/sqlite3-wasm.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-wasm.c 2023-11-04 14:23:58.000000000 +0000 @@ -84,6 +84,14 @@ /**********************************************************************/ /* SQLITE_ENABLE_... */ +/* +** Unconditionally enable API_ARMOR in the WASM build. It ensures that +** public APIs behave predictable in the face of passing illegal NULLs +** or ranges which might otherwise invoke undefined behavior. +*/ +#undef SQLITE_ENABLE_API_ARMOR +#define SQLITE_ENABLE_API_ARMOR 1 + #ifndef SQLITE_ENABLE_BYTECODE_VTAB # define SQLITE_ENABLE_BYTECODE_VTAB 1 #endif @@ -122,12 +130,6 @@ #endif /**********************************************************************/ -/* SQLITE_M... */ -#ifndef SQLITE_MAX_ALLOCATION_SIZE -# define SQLITE_MAX_ALLOCATION_SIZE 0x1fffffff -#endif - -/**********************************************************************/ /* SQLITE_O... */ #ifndef SQLITE_OMIT_DEPRECATED # define SQLITE_OMIT_DEPRECATED 1 @@ -141,9 +143,6 @@ #ifndef SQLITE_OMIT_UTF16 # define SQLITE_OMIT_UTF16 1 #endif -#ifndef SQLITE_OMIT_WAL -# define SQLITE_OMIT_WAL 1 -#endif #ifndef SQLITE_OS_KV_OPTIONAL # define SQLITE_OS_KV_OPTIONAL 1 #endif @@ -151,7 +150,7 @@ /**********************************************************************/ /* SQLITE_T... */ #ifndef SQLITE_TEMP_STORE -# define SQLITE_TEMP_STORE 3 +# define SQLITE_TEMP_STORE 2 #endif #ifndef SQLITE_THREADSAFE # define SQLITE_THREADSAFE 0 @@ -295,7 +294,7 @@ */ SQLITE_WASM_EXPORT void sqlite3_wasm_pstack_restore(unsigned char * p){ assert(p>=PStack.pBegin && p<=PStack.pEnd && p>=PStack.pPos); - assert(0==(p & 0x7)); + assert(0==((unsigned long long)p & 0x7)); if(p>=PStack.pBegin && p<=PStack.pEnd /*&& p>=PStack.pPos*/){ PStack.pPos = p; } @@ -355,7 +354,9 @@ if( db!=0 ){ if( 0!=zMsg ){ const int nMsg = sqlite3Strlen30(zMsg); + sqlite3_mutex_enter(sqlite3_db_mutex(db)); sqlite3ErrorWithMsg(db, err_code, "%.*s", nMsg, zMsg); + sqlite3_mutex_leave(sqlite3_db_mutex(db)); }else{ sqlite3ErrorWithMsg(db, err_code, NULL); } @@ -1353,6 +1354,13 @@ ** This function is NOT part of the sqlite3 public API. It is strictly ** for use by the sqlite project's own JS/WASM bindings. ** +** ACHTUNG: it was discovered on 2023-08-11 that, with SQLITE_DEBUG, +** this function's out-of-scope use of the sqlite3_vfs/file/io_methods +** APIs leads to triggering of assertions in the core library. Its use +** is now deprecated and VFS-specific APIs for importing files need to +** be found to replace it. sqlite3_wasm_posix_create_file() is +** suitable for the "unix" family of VFSes. +** ** Creates a new file using the I/O API of the given VFS, containing ** the given number of bytes of the given data. If the file exists, it ** is truncated to the given length and populated with the given @@ -1398,7 +1406,14 @@ int rc; sqlite3_file *pFile = 0; sqlite3_io_methods const *pIo; - const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE; + const int openFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE +#if 0 && defined(SQLITE_DEBUG) + | SQLITE_OPEN_MAIN_JOURNAL + /* ^^^^ This is for testing a horrible workaround to avoid + triggering a specific assert() in os_unix.c:unixOpen(). Please + do not enable this in real builds. */ +#endif + ; int flagsOut = 0; int fileExisted = 0; int doUnlock = 0; @@ -1464,6 +1479,34 @@ return rc; } +/** +** This function is NOT part of the sqlite3 public API. It is strictly +** for use by the sqlite project's own JS/WASM bindings. +** +** Creates or overwrites a file using the POSIX file API, +** i.e. Emscripten's virtual filesystem. Creates or truncates +** zFilename, appends pData bytes to it, and returns 0 on success or +** SQLITE_IOERR on error. +*/ +SQLITE_WASM_EXPORT +int sqlite3_wasm_posix_create_file( const char *zFilename, + const unsigned char * pData, + int nData ){ + int rc; + FILE * pFile = 0; + int fileExisted = 0; + size_t nWrote = 1; + + if( !zFilename || nData<0 || (pData==0 && nData>0) ) return SQLITE_MISUSE; + pFile = fopen(zFilename, "w"); + if( 0==pFile ) return SQLITE_IOERR; + if( nData>0 ){ + nWrote = fwrite(pData, (size_t)nData, 1, pFile); + } + fclose(pFile); + return 1==nWrote ? 0 : SQLITE_IOERR; +} + /* ** This function is NOT part of the sqlite3 public API. It is strictly ** for use by the sqlite project's own JS/WASM bindings. @@ -1760,6 +1803,118 @@ } return s; } + +/* +** For testing using SQLTester scripts. +** +** Return non-zero if string z matches glob pattern zGlob and zero if the +** pattern does not match. +** +** To repeat: +** +** zero == no match +** non-zero == match +** +** Globbing rules: +** +** '*' Matches any sequence of zero or more characters. +** +** '?' Matches exactly one character. +** +** [...] Matches one character from the enclosed list of +** characters. +** +** [^...] Matches one character not in the enclosed list. +** +** '#' Matches any sequence of one or more digits with an +** optional + or - sign in front, or a hexadecimal +** literal of the form 0x... +*/ +static int sqlite3_wasm_SQLTester_strnotglob(const char *zGlob, const char *z){ + int c, c2; + int invert; + int seen; + typedef int (*recurse_f)(const char *,const char *); + static const recurse_f recurse = sqlite3_wasm_SQLTester_strnotglob; + + while( (c = (*(zGlob++)))!=0 ){ + if( c=='*' ){ + while( (c=(*(zGlob++))) == '*' || c=='?' ){ + if( c=='?' && (*(z++))==0 ) return 0; + } + if( c==0 ){ + return 1; + }else if( c=='[' ){ + while( *z && recurse(zGlob-1,z)==0 ){ + z++; + } + return (*z)!=0; + } + while( (c2 = (*(z++)))!=0 ){ + while( c2!=c ){ + c2 = *(z++); + if( c2==0 ) return 0; + } + if( recurse(zGlob,z) ) return 1; + } + return 0; + }else if( c=='?' ){ + if( (*(z++))==0 ) return 0; + }else if( c=='[' ){ + int prior_c = 0; + seen = 0; + invert = 0; + c = *(z++); + if( c==0 ) return 0; + c2 = *(zGlob++); + if( c2=='^' ){ + invert = 1; + c2 = *(zGlob++); + } + if( c2==']' ){ + if( c==']' ) seen = 1; + c2 = *(zGlob++); + } + while( c2 && c2!=']' ){ + if( c2=='-' && zGlob[0]!=']' && zGlob[0]!=0 && prior_c>0 ){ + c2 = *(zGlob++); + if( c>=prior_c && c<=c2 ) seen = 1; + prior_c = 0; + }else{ + if( c==c2 ){ + seen = 1; + } + prior_c = c2; + } + c2 = *(zGlob++); + } + if( c2==0 || (seen ^ invert)==0 ) return 0; + }else if( c=='#' ){ + if( z[0]=='0' + && (z[1]=='x' || z[1]=='X') + && sqlite3Isxdigit(z[2]) + ){ + z += 3; + while( sqlite3Isxdigit(z[0]) ){ z++; } + }else{ + if( (z[0]=='-' || z[0]=='+') && sqlite3Isdigit(z[1]) ) z++; + if( !sqlite3Isdigit(z[0]) ) return 0; + z++; + while( sqlite3Isdigit(z[0]) ){ z++; } + } + }else{ + if( c!=(*(z++)) ) return 0; + } + } + return *z==0; +} + +SQLITE_WASM_EXPORT +int sqlite3_wasm_SQLTester_strglob(const char *zGlob, const char *z){ + return !sqlite3_wasm_SQLTester_strnotglob(zGlob, z); +} + + #endif /* SQLITE_WASM_TESTS */ #undef SQLITE_WASM_EXPORT diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-worker1.c-pp.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-worker1.c-pp.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-worker1.c-pp.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-worker1.c-pp.js 2023-11-04 14:23:58.000000000 +0000 @@ -37,7 +37,7 @@ "use strict"; { const urlParams = globalThis.location - ? new URL(self.location.href).searchParams + ? new URL(globalThis.location.href).searchParams : new URLSearchParams(); let theJs = 'sqlite3.js'; if(urlParams.has('sqlite3.dir')){ diff -Nru sqlite3-3.42.0/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js sqlite3-3.44.0-0/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js --- sqlite3-3.42.0/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 2023-11-04 14:23:58.000000000 +0000 @@ -196,10 +196,9 @@ if(1===arguments.length){ msg = arguments[0]; }else if(2===arguments.length){ - msg = { - type: arguments[0], - args: arguments[1] - }; + msg = Object.create(null); + msg.type = arguments[0]; + msg.args = arguments[1]; }else{ toss("Invalid arugments for sqlite3Worker1Promiser()-created factory."); } diff -Nru sqlite3-3.42.0/ext/wasm/common/SqliteTestUtil.js sqlite3-3.44.0-0/ext/wasm/common/SqliteTestUtil.js --- sqlite3-3.42.0/ext/wasm/common/SqliteTestUtil.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/common/SqliteTestUtil.js 2023-11-04 14:23:58.000000000 +0000 @@ -156,7 +156,6 @@ } }; - /** This is a module object for use with the emscripten-installed sqlite3InitModule() factory function. diff -Nru sqlite3-3.42.0/ext/wasm/common/testing.css sqlite3-3.44.0-0/ext/wasm/common/testing.css --- sqlite3-3.42.0/ext/wasm/common/testing.css 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/common/testing.css 2023-11-04 14:23:58.000000000 +0000 @@ -40,8 +40,41 @@ .tests-pass { background-color: green; color: white } .tests-fail { background-color: red; color: yellow } .faded { opacity: 0.5; } -.group-start { color: blue; } -.group-end { color: blue; } +.group-start { + color: blue; + background-color: skyblue; + font-weight: bold; + border-top: 1px dotted blue; + padding: 0.5em; + margin-top: 0.5em; +} +.group-end { + padding: 0.5em; + margin-bottom: 0.25em; + /*border-bottom: 1px dotted blue;*/ +} +.group-end.green { + background: lightgreen; + border-bottom: 1px dotted green; +} +.one-test-line, .skipping-group { + margin-left: 3em; +} +.skipping-test, .skipping-group { + padding: 0.25em 0.5em; + background-color: #ffff73; +} +.skipping-test { + margin-left: 6em; +} +.one-test-summary { + margin-left: 6em; +} +.full-test-summary { + padding-bottom: 0.5em; + padding-top: 0.5em; + border-top: 1px solid black; +} .input-wrapper { white-space: nowrap; display: flex; diff -Nru sqlite3-3.42.0/ext/wasm/common/whwasmutil.js sqlite3-3.44.0-0/ext/wasm/common/whwasmutil.js --- sqlite3-3.42.0/ext/wasm/common/whwasmutil.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/common/whwasmutil.js 2023-11-04 14:23:58.000000000 +0000 @@ -111,7 +111,8 @@ of `target.instance` (a WebAssembly.Module instance) and it must contain the symbols exported by the WASM module associated with this code. In an Enscripten environment it must be set to - `Module['asm']`. The exports object must contain a minimum of the + `Module['asm']` (versions <=3.1.43) or `wasmExports` (versions + >=3.1.44). The exports object must contain a minimum of the following symbols: - `memory`: a WebAssembly.Memory object representing the WASM @@ -174,7 +175,7 @@ globalThis.WhWasmUtilInstaller = function(target){ 'use strict'; if(undefined===target.bigIntEnabled){ - target.bigIntEnabled = !!self['BigInt64Array']; + target.bigIntEnabled = !!globalThis['BigInt64Array']; } /** Throws a new Error, the message of which is the concatenation of @@ -355,8 +356,8 @@ break; default: if(target.bigIntEnabled){ - if(n===self['BigUint64Array']) return c.HEAP64U; - else if(n===self['BigInt64Array']) return c.HEAP64; + if(n===globalThis['BigUint64Array']) return c.HEAP64U; + else if(n===globalThis['BigInt64Array']) return c.HEAP64; break; } } @@ -612,8 +613,6 @@ target.installFunction = (func, sig)=>__installFunction(func, sig, false); /** - EXPERIMENTAL! DO NOT USE IN CLIENT CODE! - Works exactly like installFunction() but requires that a scopedAllocPush() is active and uninstalls the given function when that alloc scope is popped via scopedAllocPop(). @@ -1179,7 +1178,7 @@ cache.scopedAlloc.splice(n,1); for(let p; (p = state.pop()); ){ if(target.functionEntry(p)){ - //console.warn("scopedAllocPop() uninstalling transient function",p); + //console.warn("scopedAllocPop() uninstalling function",p); target.uninstallFunction(p); } else target.dealloc(p); @@ -1636,6 +1635,7 @@ 'and is not intended to be invoked from', 'client-level code. Invoked with:',opt); } + this.name = opt.name || "unnamed"; this.signature = opt.signature; if(opt.contextKey instanceof Function){ this.contextKey = opt.contextKey; @@ -1656,25 +1656,11 @@ ? opt.callProxy : undefined; } - /** If true, the constructor emits a warning. The intent is that - this be set to true after bootstrapping of the higher-level - client library is complete, to warn downstream clients that - they shouldn't be relying on this implemenation detail which - does not have a stable interface. */ - static warnOnUse = false; - - /** If true, convertArg() will FuncPtrAdapter.debugOut() when it - (un)installs a function binding to/from WASM. Note that - deinstallation of bindScope=transient bindings happens - via scopedAllocPop() so will not be output. */ - static debugFuncInstall = false; - - /** Function used for debug output. */ - static debugOut = console.debug.bind(console); - - static bindScopes = [ - 'transient', 'context', 'singleton', 'permanent' - ]; + /** + Note that static class members are defined outside of the class + to work around an emcc toolchain build problem: one of the + tools in emsdk v3.1.42 does not support the static keyword. + */ /* Dummy impl. Overwritten per-instance as needed. */ contextKey(argv,argIndex){ @@ -1711,14 +1697,16 @@ exactly the 2nd and 3rd arguments are. */ convertArg(v,argv,argIndex){ - //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.signature,this.transient,v); + //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,this.signature,this.transient,v); let pair = this.singleton; if(!pair && this.isContext){ pair = this.contextMap(this.contextKey(argv,argIndex)); + //FuncPtrAdapter.debugOut(this.name, this.signature, "contextKey() =",this.contextKey(argv,argIndex), pair); } if(pair && pair[0]===v) return pair[1]; if(v instanceof Function){ /* Install a WASM binding and return its pointer. */ + //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,this.signature,this.transient,v,pair); if(this.callProxy) v = this.callProxy(v); const fp = __installFunction(v, this.signature, this.isTransient); if(FuncPtrAdapter.debugFuncInstall){ @@ -1732,7 +1720,18 @@ FuncPtrAdapter.debugOut("FuncPtrAdapter uninstalling", this, this.contextKey(argv,argIndex), '@'+pair[1], v); } - try{target.uninstallFunction(pair[1])} + try{ + /* Because the pending native call might rely on the + pointer we're replacing, e.g. as is normally the case + with sqlite3's xDestroy() methods, we don't + immediately uninstall but instead add its pointer to + the scopedAlloc stack, which will be cleared when the + xWrap() mechanism is done calling the native + function. We're relying very much here on xWrap() + having pushed an alloc scope. + */ + cache.scopedAlloc[cache.scopedAlloc.length-1].push(pair[1]); + } catch(e){/*ignored*/} } pair[0] = v; @@ -1740,13 +1739,14 @@ } return fp; }else if(target.isPtr(v) || null===v || undefined===v){ + //FuncPtrAdapter.debugOut("FuncPtrAdapter.convertArg()",this.name,this.signature,this.transient,v,pair); if(pair && pair[1] && pair[1]!==v){ /* uninstall stashed mapping and replace stashed mapping with v. */ if(FuncPtrAdapter.debugFuncInstall){ FuncPtrAdapter.debugOut("FuncPtrAdapter uninstalling", this, this.contextKey(argv,argIndex), '@'+pair[1], v); } - try{target.uninstallFunction(pair[1])} + try{ cache.scopedAlloc[cache.scopedAlloc.length-1].push(pair[1]) } catch(e){/*ignored*/} pair[0] = pair[1] = (v | 0); } @@ -1761,6 +1761,26 @@ }/*convertArg()*/ }/*FuncPtrAdapter*/; + /** If true, the constructor emits a warning. The intent is that + this be set to true after bootstrapping of the higher-level + client library is complete, to warn downstream clients that + they shouldn't be relying on this implemenation detail which + does not have a stable interface. */ + xArg.FuncPtrAdapter.warnOnUse = false; + + /** If true, convertArg() will FuncPtrAdapter.debugOut() when it + (un)installs a function binding to/from WASM. Note that + deinstallation of bindScope=transient bindings happens + via scopedAllocPop() so will not be output. */ + xArg.FuncPtrAdapter.debugFuncInstall = false; + + /** Function used for debug output. */ + xArg.FuncPtrAdapter.debugOut = console.debug.bind(console); + + xArg.FuncPtrAdapter.bindScopes = [ + 'transient', 'context', 'singleton', 'permanent' + ]; + const __xArgAdapterCheck = (t)=>xArg.get(t) || toss("Argument adapter not found:",t); diff -Nru sqlite3-3.42.0/ext/wasm/demo-123.js sqlite3-3.44.0-0/ext/wasm/demo-123.js --- sqlite3-3.42.0/ext/wasm/demo-123.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/demo-123.js 2023-11-04 14:23:58.000000000 +0000 @@ -235,10 +235,10 @@ - get change count (total or statement-local, 32- or 64-bit) - get a DB's file name - + Misc. Stmt features: - - Various forms of bind() + - Various forms of bind() - clearBindings() - reset() - Various forms of step() diff -Nru sqlite3-3.42.0/ext/wasm/demo-worker1.js sqlite3-3.44.0-0/ext/wasm/demo-worker1.js --- sqlite3-3.42.0/ext/wasm/demo-worker1.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/demo-worker1.js 2023-11-04 14:23:58.000000000 +0000 @@ -209,8 +209,8 @@ // ^^^ arbitrary query with no result columns "select a, b from t order by a desc;", "select a from t;" - // multi-statement exec only honors results from the first - // statement with result columns (regardless of whether) + // exec() only honors SELECT results from the first + // statement with result columns (regardless of whether // it has any rows). ], rowMode: 1, diff -Nru sqlite3-3.42.0/ext/wasm/demo-worker1-promiser.js sqlite3-3.44.0-0/ext/wasm/demo-worker1-promiser.js --- sqlite3-3.42.0/ext/wasm/demo-worker1-promiser.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/demo-worker1-promiser.js 2023-11-04 14:23:58.000000000 +0000 @@ -64,15 +64,17 @@ callback = msgArgs; msgArgs = undefined; } - const p = workerPromise({type: msgType, args:msgArgs}); + const p = 1 + ? workerPromise({type: msgType, args:msgArgs}) + : workerPromise(msgType, msgArgs); return callback ? p.then(callback).finally(testCount) : p; }; + let sqConfig; const runTests = async function(){ const dbFilename = '/testing2.sqlite3'; startTime = performance.now(); - let sqConfig; await wtest('config-get', (ev)=>{ const r = ev.result; log('sqlite3.config subset:', r); @@ -102,12 +104,15 @@ sql: ["create table t(a,b)", "insert into t(a,b) values(1,2),(3,4),(5,6)" ].join(';'), - multi: true, - resultRows: [], columnNames: [] + resultRows: [], columnNames: [], + countChanges: sqConfig.bigIntEnabled ? 64 : true }, function(ev){ ev = ev.result; T.assert(0===ev.resultRows.length) - .assert(0===ev.columnNames.length); + .assert(0===ev.columnNames.length) + .assert(sqConfig.bigIntEnabled + ? (3n===ev.changeCount) + : (3===ev.changeCount)); }); await wtest('exec',{ @@ -125,12 +130,14 @@ await wtest('exec',{ sql: 'select a a, b b from t order by a', resultRows: [], columnNames: [], - rowMode: 'object' + rowMode: 'object', + countChanges: true }, function(ev){ ev = ev.result; T.assert(3===ev.resultRows.length) .assert(1===ev.resultRows[0].a) .assert(6===ev.resultRows[2].b) + .assert(0===ev.changeCount); }); await wtest( @@ -143,12 +150,13 @@ await wtest('exec',{ sql:'select 1 union all select 3', - resultRows: [], + resultRows: [] }, function(ev){ ev = ev.result; T.assert(2 === ev.resultRows.length) .assert(1 === ev.resultRows[0][0]) - .assert(3 === ev.resultRows[1][0]); + .assert(3 === ev.resultRows[1][0]) + .assert(undefined === ev.changeCount); }); const resultRowTest1 = function f(ev){ @@ -218,13 +226,12 @@ }); await wtest('exec',{ - multi: true, sql:[ 'pragma foreign_keys=0;', // ^^^ arbitrary query with no result columns 'select a, b from t order by a desc; select a from t;' - // multi-exec only honors results from the first - // statement with result columns (regardless of whether) + // exec() only honors SELECT results from the first + // statement with result columns (regardless of whether // it has any rows). ], rowMode: 1, diff -Nru sqlite3-3.42.0/ext/wasm/dist.make sqlite3-3.44.0-0/ext/wasm/dist.make --- sqlite3-3.42.0/ext/wasm/dist.make 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/dist.make 2023-11-04 14:23:58.000000000 +0000 @@ -38,7 +38,7 @@ # date. Our general policy is that we want the smallest binaries for # dist zip files, so use the oz build unless there is a compelling # reason not to. -dist.build ?= qoz +dist.build ?= oz dist-dir.top := $(dist-name) dist-dir.jswasm := $(dist-dir.top)/$(notdir $(dir.dout)) diff -Nru sqlite3-3.42.0/ext/wasm/fiddle/fiddle-worker.js sqlite3-3.44.0-0/ext/wasm/fiddle/fiddle-worker.js --- sqlite3-3.42.0/ext/wasm/fiddle/fiddle-worker.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/fiddle/fiddle-worker.js 2023-11-04 14:23:58.000000000 +0000 @@ -221,7 +221,7 @@ f._(); } }; - + self.onmessage = function f(ev){ ev = ev.data; if(!f.cache){ @@ -371,12 +371,14 @@ sqlite3InitModule(fiddleModule).then((_sqlite3)=>{ sqlite3 = _sqlite3; console.warn("Installing sqlite3 module globally (in Worker)", - "for use in the dev console."); - self.sqlite3 = sqlite3; + "for use in the dev console.", sqlite3); + globalThis.sqlite3 = sqlite3; const dbVfs = sqlite3.wasm.xWrap('fiddle_db_vfs', "*", ['string']); fiddleModule.fsUnlink = (fn)=>{ return sqlite3.wasm.sqlite3_wasm_vfs_unlink(dbVfs(0), fn); }; wMsg('fiddle-ready'); - })/*then()*/; + }).catch(e=>{ + console.error("Fiddle worker init failed:",e); + }); })(); diff -Nru sqlite3-3.42.0/ext/wasm/fiddle.make sqlite3-3.44.0-0/ext/wasm/fiddle.make --- sqlite3-3.42.0/ext/wasm/fiddle.make 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/fiddle.make 2023-11-04 14:23:58.000000000 +0000 @@ -18,7 +18,7 @@ ifeq (,$(SHELL_SRC)) $(error Could not parse SHELL_SRC from $(dir.top)/Makefile.) endif -$(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl +$(dir.top)/shell.c: $(SHELL_SRC) $(dir.top)/tool/mkshellc.tcl $(sqlite3.c) $(MAKE) -C $(dir.top) shell.c # /shell.c ######################################################################## @@ -61,9 +61,9 @@ $(eval $(call call-make-pre-post,fiddle-module,vanilla)) $(fiddle-module.js): $(MAKEFILE) $(MAKEFILE.fiddle) \ $(EXPORTED_FUNCTIONS.fiddle) \ - $(fiddle.cses) $(pre-post-fiddle-module.deps.vanilla) $(fiddle.SOAP.js) + $(fiddle.cses) $(pre-post-fiddle-module-vanilla.deps) $(fiddle.SOAP.js) $(emcc.bin) -o $@ $(fiddle.emcc-flags) \ - $(pre-post-fiddle-module.flags.vanilla) \ + $(pre-post-fiddle-module-vanilla.flags) \ $(fiddle.cses) $(maybe-wasm-strip) $(fiddle-module.wasm) gzip < $@ > $@.gz diff -Nru sqlite3-3.42.0/ext/wasm/GNUmakefile sqlite3-3.44.0-0/ext/wasm/GNUmakefile --- sqlite3-3.42.0/ext/wasm/GNUmakefile 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/GNUmakefile 2023-11-04 14:23:58.000000000 +0000 @@ -18,8 +18,6 @@ # quick, q = do just a minimal build (sqlite3.js/wasm, tester1) for # faster development-mode turnaround. # -# qo2, qoz = a combination of quick+o2/oz. -# # dist = create end user deliverables. Add dist.build=oX to build # with a specific optimization level, where oX is one of the # above-listed o? or qo? target names. @@ -46,11 +44,12 @@ # $(eval), or at least centralize the setup of the numerous vars # related to each build variant $(JS_BUILD_MODES). # +default: all +#default: quick SHELL := $(shell which bash 2>/dev/null) MAKEFILE := $(lastword $(MAKEFILE_LIST)) CLEAN_FILES := DISTCLEAN_FILES := ./--dummy-- -default: all release: oz # JS_BUILD_MODES exists solely to reduce repetition in documentation # below. @@ -68,13 +67,6 @@ else $(info using emcc version [$(emcc.version)]) endif -emcc.version := $(shell "$(emcc.bin)" --version | sed -n 1p \ - | sed -e 's/^.* \([3-9][^ ]*\) .*$$/\1/;') -ifeq (,$(emcc.version)) - $(warning Cannot determine emcc version. This might unduly impact build flags.) -else - $(info using emcc version [$(emcc.version)]) -endif wasm-strip ?= $(shell which wasm-strip 2>/dev/null) ifeq (,$(filter clean,$(MAKECMDGOALS))) @@ -159,6 +151,9 @@ # bundle. # # A custom sqlite3.c must not have any spaces in its name. +# $(sqlite3.canonical.c) must point to the sqlite3.c in +# the sqlite3 canonical source tree, as that source file +# is required for certain utility and test code. sqlite3.canonical.c := $(dir.top)/sqlite3.c sqlite3.c ?= $(firstword $(wildcard $(dir.top)/sqlite3-see.c) $(sqlite3.canonical.c)) sqlite3.h := $(dir.top)/sqlite3.h @@ -184,14 +179,19 @@ -DSQLITE_OMIT_DEPRECATED \ -DSQLITE_OMIT_UTF16 \ -DSQLITE_OMIT_SHARED_CACHE \ - -DSQLITE_OMIT_WAL \ -DSQLITE_THREADSAFE=0 \ - -DSQLITE_TEMP_STORE=3 \ + -DSQLITE_TEMP_STORE=2 \ -DSQLITE_OS_KV_OPTIONAL=1 \ '-DSQLITE_DEFAULT_UNIX_VFS="unix-none"' \ -DSQLITE_USE_URI=1 \ -DSQLITE_WASM_ENABLE_C_TESTS \ -DSQLITE_C=$(sqlite3.c) +#SQLITE_OPT += -DSQLITE_DEBUG +# Enabling SQLITE_DEBUG will break sqlite3_wasm_vfs_create_file() +# (and thus sqlite3_js_vfs_create_file()). Those functions are +# deprecated and alternatives are in place, but this crash behavior +# can be used to find errant uses of sqlite3_js_vfs_create_file() +# in client code. .NOTPARALLEL: $(sqlite3.h) $(sqlite3.h): @@ -246,10 +246,10 @@ # embedding in the JS files and in building the distribution zip file. # It must NOT be in $(dir.tmp) because we need it to survive the # cleanup process for the dist build to work properly. -bin.version-info := $(dir.wasm)/version-info -$(bin.version-info): $(dir.wasm)/version-info.c $(sqlite3.h) $(MAKEFILE) - $(CC) -O0 -I$(dir $(sqlite3.c)) -o $@ $< -DISTCLEAN_FILES += $(bin.version-info) +bin.version-info := $(dir.top)/version-info +.NOTPARALLEL: $(bin.version-info) +$(bin.version-info): $(dir.tool)/version-info.c $(sqlite3.h) $(dir.top)/Makefile + $(MAKE) -C $(dir.top) version-info # bin.stripcomments is used for stripping C/C++-style comments from JS # files. The JS files contain large chunks of documentation which we @@ -379,20 +379,17 @@ sqlite3-api.jses += $(dir.api)/sqlite3-api-worker1.js sqlite3-api.jses += $(dir.api)/sqlite3-v-helper.js sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs.c-pp.js +sqlite3-api.jses += $(dir.api)/sqlite3-vfs-opfs-sahpool.c-pp.js sqlite3-api.jses += $(dir.api)/sqlite3-api-cleanup.js -# "External" API files which are part of our distribution +# SOAP.js is an external API file which is part of our distribution # but not part of the sqlite3-api.js amalgamation. SOAP.js := $(dir.api)/sqlite3-opfs-async-proxy.js -# COPY_XAPI = a $(call)able function to copy $1 to $(dir.dout), where -# $1 must be one of the "external" JS API files. -define COPY_XAPI -sqlite3-api.ext.jses += $$(dir.dout)/$$(notdir $(1)) -$$(dir.dout)/$$(notdir $(1)): $(1) $$(MAKEFILE) - cp $$< $$@ -endef -$(foreach X,$(SOAP.js),\ - $(eval $(call COPY_XAPI,$(X)))) +SOAP.js.bld := $(dir.dout)/$(notdir $(SOAP.js)) +sqlite3-api.ext.jses += $(SOAP.js.bld) +$(SOAP.js.bld): $(SOAP.js) + cp $< $@ + all quick: $(sqlite3-api.ext.jses) q: quick @@ -615,26 +612,40 @@ ######################################################################## # call-make-pre-post is a $(call)able which creates rules for -# pre-js-$(1).js. $1 = the base name of the JS file on whose behalf -# this pre-js is for (one of: sqlite3, sqlite3-wasmfs). $2 is the -# build mode: one of $(JS_BUILD_MODES). This -# sets up --[extern-][pre/post]-js flags in -# $(pre-post-$(1).flags.$(2)) and dependencies in -# $(pre-post-$(1).deps.$(2)). +# pre-js-$(1)-$(2).js. $1 = the base name of the JS file on whose +# behalf this pre-js is for (one of: sqlite3, sqlite3-wasmfs). $2 is +# the build mode: one of $(JS_BUILD_MODES). This sets up +# --[extern-][pre/post]-js flags in $(pre-post-$(1)-$(2).flags) and +# dependencies in $(pre-post-$(1)-$(2).deps). The resulting files get +# filtered using $(C-PP.FILTER). Any flags necessary for such +# filtering need to be set in $(c-pp.D.$(1)-$(2)) before $(call)ing +# this. define call-make-pre-post -pre-post-$(1).flags.$(2) ?= -$$(dir.tmp)/pre-js-$(1)-$(2).js: $$(pre-js.js.$(2)) $$(MAKEFILE) - cp $$(pre-js.js.$(2)) $$@ +pre-post-$(1)-$(2).flags ?= +pre-js.js.$(1)-$(2) := $$(dir.tmp)/pre-js.$(1)-$(2).intermediary.js +$$(eval $$(call C-PP.FILTER,$$(pre-js.js.in),$$(pre-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2)))) +post-js.js.$(1)-$(2) := $$(dir.tmp)/post-js.$(1)-$(2).js +$$(eval $$(call C-PP.FILTER,$$(post-js.js.in),$$(post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2)))) +extern-post-js.js.$(1)-$(2) := $$(dir.tmp)/extern-post-js.$(1)-$(2).js +$$(eval $$(call C-PP.FILTER,$$(extern-post-js.js.in),$$(extern-post-js.js.$(1)-$(2)),$$(c-pp.D.$(1)-$(2)))) +pre-post-common.flags.$(1)-$(2) := \ + $$(pre-post-common.flags) \ + --post-js=$$(post-js.js.$(1)-$(2)) \ + --extern-post-js=$$(extern-post-js.js.$(1)-$(2)) +pre-post-jses.$(1)-$(2).deps := $$(pre-post-jses.deps.common) \ + $$(post-js.js.$(1)-$(2)) $$(extern-post-js.js.$(1)-$(2)) +$$(dir.tmp)/pre-js-$(1)-$(2).js: $$(pre-js.js.$(1)-$(2)) $$(MAKEFILE) + cp $$(pre-js.js.$(1)-$(2)) $$@ @if [ sqlite3-wasmfs = $(1) ]; then \ echo "delete Module[xNameOfInstantiateWasm] /*for WASMFS build*/;"; \ elif [ sqlite3 != $(1) ]; then \ echo "Module[xNameOfInstantiateWasm].uri = '$(1).wasm';"; \ fi >> $$@ -pre-post-$(1).deps.$(2) := \ - $$(pre-post-jses.deps.$(2)) \ +pre-post-$(1)-$(2).deps := \ + $$(pre-post-jses.$(1)-$(2).deps) \ $$(dir.tmp)/pre-js-$(1)-$(2).js -pre-post-$(1).flags.$(2) += \ - $$(pre-post-common.flags.$(2)) \ +pre-post-$(1)-$(2).flags += \ + $$(pre-post-common.flags.$(1)-$(2)) \ --pre-js=$$(dir.tmp)/pre-js-$(1)-$(2).js endef # /post-js and pre-js @@ -645,7 +656,8 @@ # https://github.com/emscripten-core/emscripten/issues/14383 sqlite3.wasm := $(dir.dout)/sqlite3.wasm sqlite3-wasm.c := $(dir.api)/sqlite3-wasm.c -sqlite3-wasm.cses := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c) +sqlite3-wasm.cfiles := $(sqlite3-wasm.c) $(sqlite3_wasm_extra_init.c) +sqlite3-wasmfs.cfiles := $(sqlite3-wasm.cfiles) # sqlite3-wasm.o vs sqlite3-wasm.c: building against the latter # (predictably) results in a slightly faster binary. We're close # enough to the target speed requirements that the 500ms makes a @@ -655,7 +667,8 @@ # SQLITE3.xJS.EXPORT-DEFAULT is part of SQLITE3-WASMFS.xJS.RECIPE and # SETUP_LIB_BUILD_MODE, factored into a separate piece to avoid code # duplication. $1 is 1 if the build mode needs this workaround (esm, -# bundler-friendly) and 0 if not (vanilla). +# bundler-friendly, node) and 0 if not (vanilla). $2 must be empty for +# all builds except sqlite3-wasmfs.mjs, in which case it must be 1. # # Reminder for ESM builds: even if we use -sEXPORT_ES6=0, emcc _still_ # adds: @@ -669,13 +682,20 @@ # # Upstream RFE: # https://github.com/emscripten-core/emscripten/issues/18237 +# +# Maintenance reminder: Mac sed works differently than GNU sed, so +# don't use sed for this. define SQLITE3.xJS.ESM-EXPORT-DEFAULT if [ x1 = x$(1) ]; then \ - echo "Fragile workaround for an Emscripten annoyance. See SQLITE3.xJS.RECIPE."; \ - sed -i -e '0,/^export default/{/^export default/d;}' $@ || exit $$?; \ - if ! grep -q '^export default' $@; then \ - echo "Cannot find export default." 1>&2; \ - exit 1; \ + echo "Fragile workaround for emscripten/issues/18237. See SQLITE3.xJS.RECIPE."; \ + {\ + awk '/^export default/ && !f{f=1; next} 1' $@ > $@.tmp && mv $@.tmp $@; \ + } || exit $$?; \ + if [ x != x$(2) ]; then \ + if ! grep -q '^export default' $@; then \ + echo "Cannot find export default." 1>&2; \ + exit 1; \ + fi; \ fi; \ fi endef @@ -695,53 +715,57 @@ # SETUP_LIB_BUILD_MODE is a $(call)'able which sets up numerous pieces # for one of the build modes. # -# $1 = build mode name: one of $(JS_BUILD_MODES) -# $2 = 1 for ESM build mode, else 0 -# $3 = resulting sqlite-api JS/MJS file -# $4 = resulting JS/MJS file -# $5 = -D... flags for $(bin.c-pp) -# $6 = emcc -sXYZ flags (CURRENTLY UNUSED - was factored out) +# $1 = one of: sqlite3, sqlite3-wasmfs +# $2 = build mode name: one of $(JS_BUILD_MODES) +# $3 = 1 for ESM build mode, else 0 +# $4 = resulting sqlite-api JS/MJS file +# $5 = resulting JS/MJS file +# $6 = -D... flags for $(bin.c-pp) +# $7 = emcc -sXYZ flags (CURRENTLY UNUSED - was factored out) +# +# Maintenance reminder: be careful not to introduce spaces around args +# ($1, $2), otherwise string concatenation will malfunction. +# +# emcc.environment.$(2) must be set to a value for the -sENVIRONMENT flag. # -# emcc.environment.$(1) must be set to a value for the -sENVIRONMENT flag. +# $(cflags.$(1)) and $(cflags.$(1).$(2)) may be defined to append +# CFLAGS to a given build mode. +# +# $(emcc.flags.$(1)) and $(emcc.flags.$(1).$(2)) may be defined to +# append emcc-specific flags to a given build mode. define SETUP_LIB_BUILD_MODE -$(info Setting up build [$(1)]: $(4)) -c-pp.D.$(1) := $(5) -pre-js.js.$(1) := $$(dir.tmp)/pre-js.$(1).js -$$(eval $$(call C-PP.FILTER,$$(pre-js.js.in),$$(pre-js.js.$(1)),$$(c-pp.D.$(1)))) -post-js.js.$(1) := $$(dir.tmp)/post-js.$(1).js -$$(eval $$(call C-PP.FILTER,$$(post-js.js.in),$$(post-js.js.$(1)),$$(c-pp.D.$(1)))) -extern-post-js.js.$(1) := $$(dir.tmp)/extern-post-js.$(1).js -$$(eval $$(call C-PP.FILTER,$$(extern-post-js.js.in),$$(extern-post-js.js.$(1)),$$(c-pp.D.$(1)))) -pre-post-common.flags.$(1) := \ - $$(pre-post-common.flags) \ - --post-js=$$(post-js.js.$(1)) \ - --extern-post-js=$$(extern-post-js.js.$(1)) -pre-post-jses.deps.$(1) := $$(pre-post-jses.deps.common) \ - $$(post-js.js.$(1)) $$(extern-post-js.js.$(1)) -$$(eval $$(call call-make-pre-post,sqlite3,$(1))) -emcc.flags.sqlite3.$(1) := $(6) -$$(eval $$(call C-PP.FILTER, $$(sqlite3-api.js.in), $(3), $(5))) -$(4): $(3) $$(MAKEFILE) $$(sqlite3-wasm.cses) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-sqlite3.deps.$(1)) +$(info Setting up build [$(1)-$(2)]: $(5)) +c-pp.D.$(1)-$(2) := $(6) +$$(eval $$(call call-make-pre-post,$(1),$(2))) +emcc.flags.$(1).$(2) ?= +emcc.flags.$(1).$(2) += $(7) +$$(eval $$(call C-PP.FILTER, $$(sqlite3-api.js.in), $(4), $(6))) +$(5): $(4) $$(MAKEFILE) $$(sqlite3-wasm.cfiles) $$(EXPORTED_FUNCTIONS.api) $$(pre-post-$(1)-$(2).deps) @echo "Building $$@ ..." $$(emcc.bin) -o $$@ $$(emcc_opt_full) $$(emcc.flags) \ $$(emcc.jsflags) \ - -sENVIRONMENT=$$(emcc.environment.$(1)) \ - $$(pre-post-sqlite3.flags.$(1)) $$(emcc.flags.sqlite3.$(1)) \ - $$(cflags.common) $$(SQLITE_OPT) $$(cflags.wasm_extra_init) $$(sqlite3-wasm.cses) - @$$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(2)) - @case $(1) in \ + -sENVIRONMENT=$$(emcc.environment.$(2)) \ + $$(pre-post-$(1)-$(2).flags) \ + $$(emcc.flags.$(1)) $$(emcc.flags.$(1).$(2)) \ + $$(cflags.common) $$(SQLITE_OPT) \ + $$(cflags.$(1)) $$(cflags.$(1).$(2)) \ + $$(cflags.wasm_extra_init) $$(sqlite3-wasm.cfiles) + @$$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(3)) + @dotwasm=$$(basename $$@).wasm; \ + chmod -x $$$$dotwasm; \ + $(maybe-wasm-strip) $$$$dotwasm; \ + case $(2) in \ bundler-friendly|node) \ - echo "Patching $(3) for sqlite3.wasm..."; \ - rm -f $$(dir.dout)/sqlite3-$(1).wasm; \ - sed -i -e 's/sqlite3-$(1).wasm/sqlite3.wasm/g' $$@ || exit $$$$?; \ + echo "Patching $$@ for $(1).wasm..."; \ + rm -f $$$$dotwasm; \ + dotwasm=; \ + sed -i -e 's/$(1)-$(2).wasm/$(1).wasm/g' $$@ || exit $$$$?; \ ;; \ - esac - chmod -x $$(sqlite3.wasm) - $$(maybe-wasm-strip) $$(sqlite3.wasm) - @ls -la $@ $$(sqlite3.wasm) -all: $(4) -quick: $(4) -CLEAN_FILES += $(3) $(4) + esac; \ + ls -la $$$$dotwasm $$@ +all: $(5) +#quick: $(5) +CLEAN_FILES += $(4) $(5) endef # ^^^ /SETUP_LIB_BUILD_MODE ######################################################################## @@ -753,21 +777,24 @@ sqlite3-bundler-friendly.mjs := $(dir.dout)/sqlite3-bundler-friendly.mjs sqlite3-api-node.mjs := $(dir.dout)/sqlite3-api-node.mjs sqlite3-node.mjs := $(dir.dout)/sqlite3-node.mjs -# Maintenance reminder: careful not to introduce spaces around args $1, $2 -#$(info $(call SETUP_LIB_BUILD_MODE,vanilla,0, $(sqlite3-api.js), $(sqlite3.js))) -$(eval $(call SETUP_LIB_BUILD_MODE,vanilla,0, $(sqlite3-api.js), $(sqlite3.js))) -$(eval $(call SETUP_LIB_BUILD_MODE,esm,1, $(sqlite3-api.mjs), $(sqlite3.mjs), \ +#$(info $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0, $(sqlite3-api.js), $(sqlite3.js))) +$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,vanilla,0,\ + $(sqlite3-api.js), $(sqlite3.js))) +$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,esm,1,\ + $(sqlite3-api.mjs), $(sqlite3.mjs), \ -Dtarget=es6-module, -sEXPORT_ES6 -sUSE_ES6_IMPORT_META)) -$(eval $(call SETUP_LIB_BUILD_MODE,bundler-friendly,1,\ +$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,bundler-friendly,1,\ $(sqlite3-api-bundler-friendly.mjs),$(sqlite3-bundler-friendly.mjs),\ - $(c-pp.D.esm) -Dtarget=es6-bundler-friendly)) -$(eval $(call SETUP_LIB_BUILD_MODE,node,1,\ + $(c-pp.D.sqlite3-esm) -Dtarget=es6-bundler-friendly)) +$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3,node,1,\ $(sqlite3-api-node.mjs),$(sqlite3-node.mjs),\ - $(c-pp.D.bundler-friendly) -Dtarget=node)) + $(c-pp.D.sqlite3-bundler-friendly) -Dtarget=node)) # The various -D... values used by *.c-pp.js include: # # -Dtarget=es6-module: for all ESM module builds # +# -Dtarget=node: for node.js builds +# # -Dtarget=es6-module -Dtarget=es6-bundler-friendly: intended for # "bundler-friendly" ESM module build. These have some restrictions # on how URL() objects are constructed in some contexts: URLs which @@ -811,11 +838,11 @@ sqlite3-worker1-promiser-bundler-friendly.js := $(dir.dout)/sqlite3-worker1-promiser-bundler-friendly.js $(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1.js))) $(eval $(call C-PP.FILTER,$(sqlite3-worker1.js.in),$(sqlite3-worker1-bundler-friendly.js),\ - $(c-pp.D.bundler-friendly))) + $(c-pp.D.sqlite3-bundler-friendly))) $(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),$(sqlite3-worker1-promiser.js))) $(eval $(call C-PP.FILTER,$(sqlite3-worker1-promiser.js.in),\ $(sqlite3-worker1-promiser-bundler-friendly.js),\ - $(c-pp.D.bundler-friendly))) + $(c-pp.D.sqlite3-bundler-friendly))) $(sqlite3-bundler-friendly.mjs): $(sqlite3-worker1-bundler-friendly.js) \ $(sqlite3-worker1-promiser-bundler-friendly.js) $(sqlite3.js) $(sqlite3.mjs): $(sqlite3-worker1.js) $(sqlite3-worker1-promiser.js) @@ -841,7 +868,7 @@ # a regular basis with different -Ox flags and rebuilding the batch # pieces each time is an unnecessary time sink. batch: batch-runner.list -all: batch +#all: batch # end batch-runner.js ######################################################################## # Wasmified speedtest1 is our primary benchmarking tool. @@ -849,7 +876,7 @@ # emcc.speedtest1.common = emcc flags used by multiple builds of speedtest1 # emcc.speedtest1 = emcc flags used by main build of speedtest1 emcc.speedtest1.common := $(emcc_opt_full) -emcc.speedtest1 := +emcc.speedtest1 := -I. -I$(dir $(sqlite3.canonical.c)) emcc.speedtest1 += -sENVIRONMENT=web emcc.speedtest1 += -sALLOW_MEMORY_GROWTH emcc.speedtest1 += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.$(emcc.INITIAL_MEMORY)) @@ -892,22 +919,24 @@ @{ echo _wasm_main; cat $(EXPORTED_FUNCTIONS.api.main); } > $@ speedtest1.js := $(dir.dout)/speedtest1.js speedtest1.wasm := $(dir.dout)/speedtest1.wasm -cflags.speedtest1 := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM -speedtest1.cses := $(speedtest1.c) $(sqlite3-wasm.c) +emcc.flags.speedtest1-vanilla := $(cflags.common) -DSQLITE_SPEEDTEST1_WASM + +speedtest1.cfiles := $(speedtest1.c) $(sqlite3-wasm.c) $(eval $(call call-make-pre-post,speedtest1,vanilla)) -$(speedtest1.js): $(MAKEFILE) $(speedtest1.cses) \ - $(pre-post-speedtest1.deps.vanilla) \ +$(speedtest1.js): $(MAKEFILE) $(speedtest1.cfiles) \ + $(pre-post-speedtest1-vanilla.deps) \ $(EXPORTED_FUNCTIONS.speedtest1) @echo "Building $@ ..." $(emcc.bin) \ - $(emcc.speedtest1) -I$(dir $(sqlite3.canonical.c)) \ + $(emcc.speedtest1) \ $(emcc.speedtest1.common) \ - $(cflags.speedtest1) $(pre-post-speedtest1.flags.vanilla) \ + $(emcc.flags.speedtest1-vanilla) $(pre-post-speedtest1-vanilla.flags) \ $(SQLITE_OPT) \ -USQLITE_C -DSQLITE_C=$(sqlite3.canonical.c) \ $(speedtest1.exit-runtime0) \ - -o $@ $(speedtest1.cses) -lm + -o $@ $(speedtest1.cfiles) -lm $(maybe-wasm-strip) $(speedtest1.wasm) + chmod -x $(speedtest1.wasm) ls -la $@ $(speedtest1.wasm) speedtest1: $(speedtest1.js) @@ -933,13 +962,14 @@ # # To create those, we filter tester1.c-pp.js with $(bin.c-pp)... $(eval $(call C-PP.FILTER,tester1.c-pp.js,tester1.js)) -$(eval $(call C-PP.FILTER,tester1.c-pp.js,tester1.mjs,$(c-pp.D.esm))) +$(eval $(call C-PP.FILTER,tester1.c-pp.js,tester1.mjs,$(c-pp.D.sqlite3-esm))) $(eval $(call C-PP.FILTER,tester1.c-pp.html,tester1.html)) -$(eval $(call C-PP.FILTER,tester1.c-pp.html,tester1-esm.html,$(c-pp.D.esm))) +$(eval $(call C-PP.FILTER,tester1.c-pp.html,tester1-esm.html,$(c-pp.D.sqlite3-esm))) tester1: tester1.js tester1.mjs tester1.html tester1-esm.html # Note that we do not include $(sqlite3-bundler-friendly.mjs) in this # because bundlers are client-specific. all quick: tester1 +quick: $(sqlite3.js) ######################################################################## # Convenience rules to rebuild with various -Ox levels. Much @@ -959,8 +989,6 @@ $(MAKE) -e "emcc_opt=-O1 $(o-xtra)" o2: clean $(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)" -qo2: clean - $(MAKE) -j2 -e "emcc_opt=-O2 $(o-xtra)" quick o3: clean $(MAKE) -e "emcc_opt=-O3 $(o-xtra)" os: clean @@ -968,8 +996,6 @@ $(MAKE) -e "emcc_opt=-Os $(o-xtra)" oz: clean $(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)" -qoz: clean - $(MAKE) -j2 -e "emcc_opt=-Oz $(o-xtra)" quick ######################################################################## # Sub-makes... @@ -981,6 +1007,8 @@ ifneq (,$(filter wasmfs,$(MAKECMDGOALS))) wasmfs.enable ?= 1 else +# Unconditionally enable wasmfs for [dist]clean so that the wasmfs +# sub-make can clean up. wasmfs.enable ?= $(if $(filter %clean,$(MAKECMDGOALS)),1,0) endif ifeq (1,$(wasmfs.enable)) @@ -1011,8 +1039,7 @@ # Push files to public wasm-testing.sqlite.org server wasm-testing.include = *.js *.mjs *.html \ ./tests \ - batch-runner.list \ - $(dir.dout) $(dir.sql) $(dir.common) $(dir.fiddle) $(dir.jacc) + $(dir.dout) $(dir.common) $(dir.fiddle) $(dir.jacc) wasm-testing.exclude = sql/speedtest1.sql wasm-testing.dir = /jail/sites/wasm-testing wasm-testing.dest ?= wasm-testing:$(wasm-testing.dir) diff -Nru sqlite3-3.42.0/ext/wasm/index.html sqlite3-3.44.0-0/ext/wasm/index.html --- sqlite3-3.42.0/ext/wasm/index.html 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/index.html 2023-11-04 14:23:58.000000000 +0000 @@ -93,9 +93,13 @@
  • The obligatory "misc." category... @@ -103,7 +107,8 @@
  • module-symbols gives a high-level overview of the symbols exposed by the JS module.
  • -
  • batch-runner: runs batches of SQL exported from speedtest1.
  • +
  • test-opfs-vfs (same with verbose output and sanity-checking tests) is an @@ -117,18 +122,19 @@
  • - + diff -Nru sqlite3-3.42.0/ext/wasm/jaccwabyt/jaccwabyt.js sqlite3-3.44.0-0/ext/wasm/jaccwabyt/jaccwabyt.js --- sqlite3-3.42.0/ext/wasm/jaccwabyt/jaccwabyt.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/jaccwabyt/jaccwabyt.js 2023-11-04 14:23:58.000000000 +0000 @@ -60,9 +60,9 @@ memberPrefix = (config.memberPrefix || ""), memberSuffix = (config.memberSuffix || ""), bigIntEnabled = (undefined===config.bigIntEnabled - ? !!self['BigInt64Array'] : !!config.bigIntEnabled), - BigInt = self['BigInt'], - BigInt64Array = self['BigInt64Array'], + ? !!globalThis['BigInt64Array'] : !!config.bigIntEnabled), + BigInt = globalThis['BigInt'], + BigInt64Array = globalThis['BigInt64Array'], /* Undocumented (on purpose) config options: */ ptrSizeof = config.ptrSizeof || 4, ptrIR = config.ptrIR || 'i32' diff -Nru sqlite3-3.42.0/ext/wasm/module-symbols.html sqlite3-3.44.0-0/ext/wasm/module-symbols.html --- sqlite3-3.42.0/ext/wasm/module-symbols.html 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/module-symbols.html 2023-11-04 14:23:58.000000000 +0000 @@ -355,6 +355,7 @@ sqlite3_js_db_vfs: 'wasm:/api-c-style.md#sqlite3_js_db_vfs', sqlite3_js_kvvfs_clear: 'wasm:/api-c-style.md#sqlite3_js_kvvfs', sqlite3_js_kvvfs_size: 'wasm:/api-c-style.md#sqlite3_js_kvvfs', + sqlite3_js_posix_create_file: 'wasm:/api-c-style.md#sqlite3_js_posix_create_file', sqlite3_js_rc_str: 'wasm:/api-c-style.md#sqlite3_js_rc_str', sqlite3_js_vfs_create_file: 'wasm:/api-c-style.md#sqlite3_js_vfs_create_file', sqlite3_js_vfs_list: 'wasm:/api-c-style.md#sqlite3_js_vfs_list', diff -Nru sqlite3-3.42.0/ext/wasm/README.md sqlite3-3.44.0-0/ext/wasm/README.md --- sqlite3-3.42.0/ext/wasm/README.md 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/README.md 2023-11-04 14:23:58.000000000 +0000 @@ -82,7 +82,7 @@ # Testing on a remote machine that is accessed via SSH -*NB: The following are developer notes, last validated on 2022-08-18* +*NB: The following are developer notes, last validated on 2023-07-19* * Remote: Install git, emsdk, and althttpd * Use a [version of althttpd][althttpd] from @@ -93,13 +93,14 @@ * Local: `ssh -L 8180:localhost:8080 remote` * Local: Point your web-browser at http://localhost:8180/index.html -In order to enable [SharedArrayBuffers](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer), -the web-browser requires that the two extra Cross-Origin lines be present -in HTTP reply headers and that the request must come from "localhost". -Since the web-server is on a different machine from -the web-broser, the localhost requirement means that the connection must be tunneled -using SSH. +In order to enable [SharedArrayBuffer][], the web-browser requires +that the two extra Cross-Origin lines be present in HTTP reply headers +and that the request must come from "localhost" (_or_ over an SSL +connection). Since the web-server is on a different machine from the +web-broser, the localhost requirement means that the connection must +be tunneled using SSH. [emscripten]: https://emscripten.org [althttpd]: https://sqlite.org/althttpd +[SharedArrayBuffer]: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/SharedArrayBuffer diff -Nru sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs.html sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs.html --- sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs.html 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs.html 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,30 @@ + + + + + + + + + sqlite3 WASMFS/OPFS Main-thread Scratchpad + + +
    sqlite3 WASMFS/OPFS Main-thread Scratchpad
    +

    Scratchpad/test app for the WASMF/OPFS integration in the + main window thread. This page requires that the sqlite3 API have + been built with WASMFS support. If OPFS support is available then + it "should" persist a database across reloads (watch the dev console + output), otherwise it will not. +

    +

    All stuff on this page happens in the dev console.

    +
    +
    + + + diff -Nru sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs-main.html sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs-main.html --- sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs-main.html 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs-main.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,40 +0,0 @@ - - - - - - - - - sqlite3 WASMFS/OPFS Main-thread Scratchpad - - -
    sqlite3 WASMFS/OPFS Main-thread Scratchpad
    - -
    -
    -
    Initializing app...
    -
    - On a slow internet connection this may take a moment. If this - message displays for "a long time", intialization may have - failed and the JavaScript console may contain clues as to why. -
    -
    -
    Downloading...
    -
    - -
    -

    Scratchpad/test app for the WASMF/OPFS integration in the - main window thread. This page requires that the sqlite3 API have - been built with WASMFS support. If OPFS support is available then - it "should" persist a database across reloads (watch the dev console - output), otherwise it will not. -

    -

    All stuff on this page happens in the dev console.

    -
    -
    - - - - - diff -Nru sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs-main.js sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs-main.js --- sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs-main.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs-main.js 1970-01-01 00:00:00.000000000 +0000 @@ -1,70 +0,0 @@ -/* - 2022-05-22 - - The author disclaims copyright to this source code. In place of a - legal notice, here is a blessing: - - * May you do good and not evil. - * May you find forgiveness for yourself and forgive others. - * May you share freely, never taking more than you give. - - *********************************************************************** - - A basic test script for sqlite3-api.js. This file must be run in - main JS thread and sqlite3.js must have been loaded before it. -*/ -'use strict'; -(function(){ - const toss = function(...args){throw new Error(args.join(' '))}; - const log = console.log.bind(console), - warn = console.warn.bind(console), - error = console.error.bind(console); - - const stdout = log; - const stderr = error; - - const test1 = function(db){ - db.exec("create table if not exists t(a);") - .transaction(function(db){ - db.prepare("insert into t(a) values(?)") - .bind(new Date().getTime()) - .stepFinalize(); - stdout("Number of values in table t:", - db.selectValue("select count(*) from t")); - }); - }; - - const runTests = function(sqlite3){ - const capi = sqlite3.capi, - oo = sqlite3.oo1, - wasm = sqlite3.wasm; - stdout("Loaded sqlite3:",capi.sqlite3_libversion(), capi.sqlite3_sourceid()); - const persistentDir = capi.sqlite3_wasmfs_opfs_dir(); - if(persistentDir){ - stdout("Persistent storage dir:",persistentDir); - }else{ - stderr("No persistent storage available."); - } - const startTime = performance.now(); - let db; - try { - db = new oo.DB(persistentDir+'/foo.db'); - stdout("DB filename:",db.filename); - const banner1 = '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>', - banner2 = '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'; - [ - test1 - ].forEach((f)=>{ - const n = performance.now(); - stdout(banner1,"Running",f.name+"()..."); - f(db, sqlite3); - stdout(banner2,f.name+"() took ",(performance.now() - n),"ms"); - }); - }finally{ - if(db) db.close(); - } - stdout("Total test time:",(performance.now() - startTime),"ms"); - }; - - sqlite3InitModule(self.sqlite3TestModule).then(runTests); -})(); diff -Nru sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs.mjs sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs.mjs --- sqlite3-3.42.0/ext/wasm/scratchpad-wasmfs.mjs 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/scratchpad-wasmfs.mjs 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,70 @@ +/* + 2022-05-22 + + The author disclaims copyright to this source code. In place of a + legal notice, here is a blessing: + + * May you do good and not evil. + * May you find forgiveness for yourself and forgive others. + * May you share freely, never taking more than you give. + + *********************************************************************** + + A basic test script for sqlite3-api.js. This file must be run in + main JS thread and sqlite3.js must have been loaded before it. +*/ +import sqlite3InitModule from './jswasm/sqlite3-wasmfs.mjs'; +//console.log('sqlite3InitModule =',sqlite3InitModule); +const toss = function(...args){throw new Error(args.join(' '))}; +const log = console.log.bind(console), + warn = console.warn.bind(console), + error = console.error.bind(console); + +const stdout = log; +const stderr = error; + +const test1 = function(db){ + db.exec("create table if not exists t(a);") + .transaction(function(db){ + db.prepare("insert into t(a) values(?)") + .bind(new Date().getTime()) + .stepFinalize(); + stdout("Number of values in table t:", + db.selectValue("select count(*) from t")); + }); +}; + +const runTests = function(sqlite3){ + const capi = sqlite3.capi, + oo = sqlite3.oo1, + wasm = sqlite3.wasm; + stdout("Loaded module:",sqlite3); + stdout("Loaded sqlite3:",capi.sqlite3_libversion(), capi.sqlite3_sourceid()); + const persistentDir = capi.sqlite3_wasmfs_opfs_dir(); + if(persistentDir){ + stdout("Persistent storage dir:",persistentDir); + }else{ + stderr("No persistent storage available."); + } + const startTime = performance.now(); + let db; + try { + db = new oo.DB(persistentDir+'/foo.db'); + stdout("DB filename:",db.filename); + const banner1 = '>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>', + banner2 = '<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<'; + [ + test1 + ].forEach((f)=>{ + const n = performance.now(); + stdout(banner1,"Running",f.name+"()..."); + f(db, sqlite3); + stdout(banner2,f.name+"() took ",(performance.now() - n),"ms"); + }); + }finally{ + if(db) db.close(); + } + stdout("Total test time:",(performance.now() - startTime),"ms"); +}; + +sqlite3InitModule().then(runTests); diff -Nru sqlite3-3.42.0/ext/wasm/speedtest1-wasmfs.html sqlite3-3.44.0-0/ext/wasm/speedtest1-wasmfs.html --- sqlite3-3.42.0/ext/wasm/speedtest1-wasmfs.html 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/speedtest1-wasmfs.html 2023-11-04 14:23:58.000000000 +0000 @@ -10,141 +10,46 @@
    speedtest1-wasmfs.wasm
    - - -
    -
    -
    Initializing app...
    -
    - On a slow internet connection this may take a moment. If this - message displays for "a long time", intialization may have - failed and the JavaScript console may contain clues as to why. -
    -
    -
    Downloading...
    -
    - -
    -
    This page starts running the main exe when it loads, which will - block the UI until it finishes! Adding UI controls to manually configure and start it - are TODO.
    - +
    Achtung: running it with the dev tools open may drastically slow it down. For faster results, keep the dev tools closed when running it!
    -
    Output is delayed/buffered because we cannot update the UI while the - speedtest is running. Output will appear below when ready...
    - - - + diff -Nru sqlite3-3.42.0/ext/wasm/speedtest1-wasmfs.mjs sqlite3-3.44.0-0/ext/wasm/speedtest1-wasmfs.mjs --- sqlite3-3.42.0/ext/wasm/speedtest1-wasmfs.mjs 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/speedtest1-wasmfs.mjs 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,90 @@ +import sqlite3InitModule from './jswasm/speedtest1-wasmfs.mjs'; +const wMsg = (type,...args)=>{ + postMessage({type, args}); +}; +wMsg('log',"speedtest1-wasmfs starting..."); +/** + If this environment contains OPFS, this function initializes it and + returns the name of the dir on which OPFS is mounted, else it returns + an empty string. +*/ +const wasmfsDir = function f(wasmUtil,dirName="/opfs"){ + if(undefined !== f._) return f._; + if( !self.FileSystemHandle + || !self.FileSystemDirectoryHandle + || !self.FileSystemFileHandle){ + return f._ = ""; + } + try{ + if(0===wasmUtil.xCallWrapped( + 'sqlite3_wasm_init_wasmfs', 'i32', ['string'], dirName + )){ + return f._ = dirName; + }else{ + return f._ = ""; + } + }catch(e){ + // sqlite3_wasm_init_wasmfs() is not available + return f._ = ""; + } +}; +wasmfsDir._ = undefined; + +const log = (...args)=>wMsg('log',...args); +const logErr = (...args)=>wMsg('logErr',...args); + +const runTests = function(sqlite3){ + console.log("Module inited.",sqlite3); + const wasm = sqlite3.wasm; + const __unlink = wasm.xWrap("sqlite3_wasm_vfs_unlink", "int", ["*","string"]); + const unlink = (fn)=>__unlink(0,fn); + const pDir = wasmfsDir(wasm); + if(pDir) log("Persistent storage:",pDir); + else{ + logErr("Expecting persistent storage in this build."); + return; + } + const scope = wasm.scopedAllocPush(); + const dbFile = pDir+"/speedtest1.db"; + const urlParams = new URL(self.location.href).searchParams; + const argv = ["speedtest1"]; + if(urlParams.has('flags')){ + argv.push(...(urlParams.get('flags').split(','))); + let i = argv.indexOf('--vfs'); + if(i>=0) argv.splice(i,2); + }else{ + argv.push( + "--singlethread", + "--nomutex", + //"--nosync", + "--nomemstat", + "--size", "10" + ); + } + + if(argv.indexOf('--memdb')>=0){ + logErr("WARNING: --memdb flag trumps db filename."); + } + argv.push("--big-transactions"/*important for tests 410 and 510!*/, + dbFile); + //log("argv =",argv); + // These log messages are not emitted to the UI until after main() returns. Fixing that + // requires moving the main() call and related cleanup into a timeout handler. + if(pDir) unlink(dbFile); + log("Starting native app:\n ",argv.join(' ')); + log("This will take a while and the browser might warn about the runaway JS.", + "Give it time..."); + setTimeout(function(){ + if(pDir) unlink(dbFile); + wasm.xCall('wasm_main', argv.length, + wasm.scopedAllocMainArgv(argv)); + wasm.scopedAllocPop(scope); + if(pDir) unlink(dbFile); + log("Done running native main()"); + }, 25); +}/*runTests()*/; + +sqlite3InitModule({ + print: log, + printErr: logErr +}).then(runTests); diff -Nru sqlite3-3.42.0/ext/wasm/speedtest1-worker.html sqlite3-3.44.0-0/ext/wasm/speedtest1-worker.html --- sqlite3-3.42.0/ext/wasm/speedtest1-worker.html 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/speedtest1-worker.html 2023-11-04 14:23:58.000000000 +0000 @@ -171,7 +171,8 @@ const urlParams = new URL(self.location.href).searchParams; const W = new Worker( "speedtest1-worker.js?sqlite3.dir=jswasm"+ - (urlParams.has('opfs-verbose') ? '&opfs-verbose' : '') + (urlParams.has('opfs-verbose') ? '&opfs-verbose' : '')+ + (urlParams.has('opfs-disable') ? '&opfs-disable' : '') ); const mPost = function(msgType,payload){ W.postMessage({type: msgType, data: payload}); @@ -259,7 +260,7 @@ flags["--utf16be"] = "Set text encoding to UTF-16BE"; flags["--utf16le"] = "Set text encoding to UTF-16LE"; flags["--verify"] = "Run additional verification steps."; - flags["--without"] = "rowid Use WITHOUT ROWID where appropriate"; + flags["--without-rowid"] = "Use WITHOUT ROWID where appropriate"; const preselectedFlags = [ '--big-transactions', '--singlethread' @@ -267,7 +268,7 @@ if(urlParams.has('flags')){ preselectedFlags.push(...urlParams.get('flags').split(',')); } - if('opfs'!==urlParams.get('vfs')){ + if(!urlParams.get('vfs')){ preselectedFlags.push('--memdb'); } Object.keys(flags).sort().forEach(function(f){ diff -Nru sqlite3-3.42.0/ext/wasm/speedtest1-worker.js sqlite3-3.44.0-0/ext/wasm/speedtest1-worker.js --- sqlite3-3.42.0/ext/wasm/speedtest1-worker.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/speedtest1-worker.js 2023-11-04 14:23:58.000000000 +0000 @@ -5,7 +5,7 @@ if(urlParams.has('sqlite3.dir')){ speedtestJs = urlParams.get('sqlite3.dir') + '/' + speedtestJs; } - importScripts('common/whwasmutil.js', speedtestJs); + importScripts(speedtestJs); /** If this environment contains OPFS, this function initializes it and returns the name of the dir on which OPFS is mounted, else it returns @@ -48,7 +48,7 @@ const log = (...args)=>logMsg('stdout',args); const logErr = (...args)=>logMsg('stderr',args); - const runSpeedtest = function(cliFlagsArray){ + const runSpeedtest = async function(cliFlagsArray){ const scope = App.wasm.scopedAllocPush(); const dbFile = App.pDir+"/speedtest1.sqlite3"; try{ @@ -56,7 +56,28 @@ "speedtest1.wasm", ...cliFlagsArray, dbFile ]; App.logBuffer.length = 0; + const ndxSahPool = argv.indexOf('opfs-sahpool'); + const realSahName = 'opfs-sahpool-speedtest1'; + if(ndxSahPool>0){ + argv[ndxSahPool] = realSahName; + log("Updated argv for opfs-sahpool: --vfs",realSahName); + } mPost('run-start', [...argv]); + if(App.sqlite3.installOpfsSAHPoolVfs + && !App.sqlite3.$SAHPoolUtil + && ndxSahPool>0){ + log("Installing opfs-sahpool as",realSahName,"..."); + await App.sqlite3.installOpfsSAHPoolVfs({ + name: realSahName, + initialCapacity: 3, + clearOnInit: true, + verbosity: 2 + }).then(PoolUtil=>{ + log("opfs-sahpool successfully installed as",realSahName); + App.sqlite3.$SAHPoolUtil = PoolUtil; + //console.log("sqlite3.oo1.OpfsSAHPoolDb =", App.sqlite3.oo1.OpfsSAHPoolDb); + }); + } App.wasm.xCall('wasm_main', argv.length, App.wasm.scopedAllocMainArgv(argv)); }catch(e){ @@ -71,20 +92,38 @@ self.onmessage = function(msg){ msg = msg.data; switch(msg.type){ - case 'run': runSpeedtest(msg.data || []); break; + case 'run': + runSpeedtest(msg.data || []) + .catch(e=>mPost('error',e)); + break; default: logErr("Unhandled worker message type:",msg.type); break; } }; + const sahpSanityChecks = function(sqlite3){ + log("Attempting OpfsSAHPoolDb sanity checks..."); + const db = new sqlite3.oo1.OpfsSAHPoolDb('opfs-sahpoool.db'); + const fn = db.filename; + db.exec([ + 'create table t(a);', + 'insert into t(a) values(1),(2),(3);' + ]); + db.close(); + sqlite3.wasm.sqlite3_wasm_vfs_unlink(sqlite3_vfs_find("opfs-sahpool"), fn); + log("SAH sanity checks done."); + }; + const EmscriptenModule = { print: log, printErr: logErr, setStatus: (text)=>mPost('load-status',text) }; - self.sqlite3InitModule(EmscriptenModule).then((sqlite3)=>{ - const S = sqlite3; + log("Initializing speedtest1 module..."); + self.sqlite3InitModule(EmscriptenModule).then(async (sqlite3)=>{ + const S = globalThis.S = App.sqlite3 = sqlite3; + log("Loaded speedtest1 module. Setting up..."); App.vfsUnlink = function(pDb, fname){ const pVfs = S.wasm.sqlite3_wasm_db_vfs(pDb, 0); if(pVfs) S.wasm.sqlite3_wasm_vfs_unlink(pVfs, fname||0); @@ -95,5 +134,7 @@ //else log("Using transient storage."); mPost('ready',true); log("Registered VFSes:", ...S.capi.sqlite3_js_vfs_list()); + }).catch(e=>{ + logErr(e); }); })(); diff -Nru sqlite3-3.42.0/ext/wasm/SQLTester/GNUmakefile sqlite3-3.44.0-0/ext/wasm/SQLTester/GNUmakefile --- sqlite3-3.42.0/ext/wasm/SQLTester/GNUmakefile 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/SQLTester/GNUmakefile 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,55 @@ +#!/this/is/make +# +# This makefile compiles SQLTester test files into something +# we can readily import into JavaScript. +all: + +SHELL := $(shell which bash 2>/dev/null) +MAKEFILE := $(lastword $(MAKEFILE_LIST)) +CLEAN_FILES := +DISTCLEAN_FILES := ./--dummy-- *~ + +test-list.mjs := test-list.mjs +test-list.mjs.gz := $(test-list.mjs).gz +CLEAN_FILES += $(test-list.mjs) + +tests.dir := $(firstword $(wildcard tests ../../jni/src/tests)) +$(info test script dir=$(tests.dir)) + +tests.all := $(wildcard $(tests.dir)/*.test) + +bin.touint8array := ./touint8array +$(bin.touint8array): $(bin.touint8array).c $(MAKEFILE) + $(CC) -o $@ $< +CLEAN_FILES += $(bin.touint8array) + +ifneq (,$(tests.all)) +$(test-list.mjs): $(bin.touint8array) $(tests.all) $(MAKEFILE) + @{\ + echo 'export default ['; \ + sep=''; \ + for f in $(sort $(tests.all)); do \ + echo -en $$sep'{"name": "'$${f##*/}'", "content":'; \ + $(bin.touint8array) < $$f; \ + echo -n '}'; \ + sep=',\n'; \ + done; \ + echo '];'; \ + } > $@ + @echo "Created $@" +$(test-list.mjs.gz): $(test-list.mjs) + gzip -c $< > $@ +CLEAN_FILES += $(test-list.mjs.gz) +all: $(test-list.mjs.gz) +else + @echo "Cannot build $(test-list.mjs) for lack of input test files."; \ + echo "Symlink ./tests to a directory containing SQLTester-format "; \ + echo "test scripts named *.test, then try again"; \ + exit 1 +endif + +.PHONY: clean distclean +clean: + -rm -f $(CLEAN_FILES) +distclean: clean + -rm -f $(DISTCLEAN_FILES) diff -Nru sqlite3-3.42.0/ext/wasm/SQLTester/index.html sqlite3-3.44.0-0/ext/wasm/SQLTester/index.html --- sqlite3-3.42.0/ext/wasm/SQLTester/index.html 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/SQLTester/index.html 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,127 @@ + + + + + + + + + SQLTester + + + +

    SQLTester for JS/WASM

    +

    This app reads in a build-time-defined set of SQLTester test + scripts and runs them through the test suite. +

    +
    + Options + + + + + +
    +
    Test output will go here.
    + + + + diff -Nru sqlite3-3.42.0/ext/wasm/SQLTester/SQLTester.mjs sqlite3-3.44.0-0/ext/wasm/SQLTester/SQLTester.mjs --- sqlite3-3.42.0/ext/wasm/SQLTester/SQLTester.mjs 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/SQLTester/SQLTester.mjs 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,1339 @@ +/* +** 2023-08-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 contains the main application entry pointer for the JS +** implementation of the SQLTester framework. +** +** This version is not well-documented because it's a direct port of +** the Java immplementation, which is documented: in the main SQLite3 +** source tree, see ext/jni/src/org/sqlite/jni/tester/SQLite3Tester.java. +*/ + +import sqlite3ApiInit from '/jswasm/sqlite3.mjs'; + +const sqlite3 = await sqlite3ApiInit(); + +const log = (...args)=>{ + console.log('SQLTester:',...args); +}; + +/** + Try to install vfsName as the new default VFS. Once this succeeds + (returns true) then it becomes a no-op on future calls. Throws if + vfs registration as the default VFS fails but has no side effects + if vfsName is not currently registered. +*/ +const tryInstallVfs = function f(vfsName){ + if(f.vfsName) return false; + const pVfs = sqlite3.capi.sqlite3_vfs_find(vfsName); + if(pVfs){ + log("Installing",'"'+vfsName+'"',"as default VFS."); + const rc = sqlite3.capi.sqlite3_vfs_register(pVfs, 1); + if(rc){ + sqlite3.SQLite3Error.toss(rc,"While trying to register",vfsName,"vfs."); + } + f.vfsName = vfsName; + } + return !!pVfs; +}; +tryInstallVfs.vfsName = undefined; + +if( 0 && globalThis.WorkerGlobalScope ){ + // Try OPFS storage, if available... + if( 0 && sqlite3.oo1.OpfsDb ){ + /* Really slow with these tests */ + tryInstallVfs("opfs"); + } + if( sqlite3.installOpfsSAHPoolVfs ){ + await sqlite3.installOpfsSAHPoolVfs({ + clearOnInit: true, + initialCapacity: 15, + name: 'opfs-SQLTester' + }).then(pool=>{ + tryInstallVfs(pool.vfsName); + }).catch(e=>{ + log("OpfsSAHPool could not load:",e); + }); + } +} + +const wPost = (function(){ + return (('undefined'===typeof WorkerGlobalScope) + ? ()=>{} + : (type, payload)=>{ + postMessage({type, payload}); + }); +})(); +//log("WorkerGlobalScope",globalThis.WorkerGlobalScope); + +// Return a new enum entry value +const newE = ()=>Object.create(null); + +const newObj = (props)=>Object.assign(newE(), props); + +/** + Modes for how to escape (or not) column values and names from + SQLTester.execSql() to the result buffer output. +*/ +const ResultBufferMode = Object.assign(Object.create(null),{ + //! Do not append to result buffer + NONE: newE(), + //! Append output escaped. + ESCAPED: newE(), + //! Append output as-is + ASIS: newE() +}); + +/** + Modes to specify how to emit multi-row output from + SQLTester.execSql() to the result buffer. +*/ +const ResultRowMode = newObj({ + //! Keep all result rows on one line, space-separated. + ONLINE: newE(), + //! Add a newline between each result row. + NEWLINE: newE() +}); + +class SQLTesterException extends globalThis.Error { + constructor(testScript, ...args){ + if(testScript){ + super( [testScript.getOutputPrefix()+": ", ...args].join('') ); + }else{ + super( args.join('') ); + } + this.name = 'SQLTesterException'; + } + isFatal() { return false; } +} + +SQLTesterException.toss = (...args)=>{ + throw new SQLTesterException(...args); +} + +class DbException extends SQLTesterException { + constructor(testScript, pDb, rc, closeDb=false){ + super(testScript, "DB error #"+rc+": "+sqlite3.capi.sqlite3_errmsg(pDb)); + this.name = 'DbException'; + if( closeDb ) sqlite3.capi.sqlite3_close_v2(pDb); + } + isFatal() { return true; } +} + +class TestScriptFailed extends SQLTesterException { + constructor(testScript, ...args){ + super(testScript,...args); + this.name = 'TestScriptFailed'; + } + isFatal() { return true; } +} + +class UnknownCommand extends SQLTesterException { + constructor(testScript, cmdName){ + super(testScript, cmdName); + this.name = 'UnknownCommand'; + } + isFatal() { return true; } +} + +class IncompatibleDirective extends SQLTesterException { + constructor(testScript, ...args){ + super(testScript,...args); + this.name = 'IncompatibleDirective'; + } +} + +//! For throwing where an expression is required. +const toss = (errType, ...args)=>{ + throw new errType(...args); +}; + +const __utf8Decoder = new TextDecoder(); +const __utf8Encoder = new TextEncoder('utf-8'); +//! Workaround for Util.utf8Decode() +const __SAB = ('undefined'===typeof globalThis.SharedArrayBuffer) + ? function(){} : globalThis.SharedArrayBuffer; + + +/* Frequently-reused regexes. */ +const Rx = newObj({ + requiredProperties: / REQUIRED_PROPERTIES:[ \t]*(\S.*)\s*$/, + scriptModuleName: / SCRIPT_MODULE_NAME:[ \t]*(\S+)\s*$/, + mixedModuleName: / ((MIXED_)?MODULE_NAME):[ \t]*(\S+)\s*$/, + command: /^--(([a-z-]+)( .*)?)$/, + //! "Special" characters - we have to escape output if it contains any. + special: /[\x00-\x20\x22\x5c\x7b\x7d]/, + squiggly: /[{}]/ +}); + +const Util = newObj({ + toss, + + unlink: function(fn){ + return 0==sqlite3.wasm.sqlite3_wasm_vfs_unlink(0,fn); + }, + + argvToString: (list)=>{ + const m = [...list]; + m.shift() /* strip command name */; + return m.join(" ") + }, + + utf8Decode: function(arrayBuffer, begin, end){ + return __utf8Decoder.decode( + (arrayBuffer.buffer instanceof __SAB) + ? arrayBuffer.slice(begin, end) + : arrayBuffer.subarray(begin, end) + ); + }, + + utf8Encode: (str)=>__utf8Encoder.encode(str), + + strglob: sqlite3.wasm.xWrap('sqlite3_wasm_SQLTester_strglob','int', + ['string','string']) +})/*Util*/; + +class Outer { + #lnBuf = []; + #verbosity = 0; + #logger = console.log.bind(console); + + constructor(func){ + if(func) this.setFunc(func); + } + + logger(...args){ + if(args.length){ + this.#logger = args[0]; + return this; + } + return this.#logger; + } + + out(...args){ + if( this.getOutputPrefix && !this.#lnBuf.length ){ + this.#lnBuf.push(this.getOutputPrefix()); + } + this.#lnBuf.push(...args); + return this; + } + + #outlnImpl(vLevel, ...args){ + if( this.getOutputPrefix && !this.#lnBuf.length ){ + this.#lnBuf.push(this.getOutputPrefix()); + } + this.#lnBuf.push(...args,'\n'); + const msg = this.#lnBuf.join(''); + this.#lnBuf.length = 0; + this.#logger(msg); + return this; + } + + outln(...args){ + return this.#outlnImpl(0,...args); + } + + outputPrefix(){ + if( 0==arguments.length ){ + return (this.getOutputPrefix + ? (this.getOutputPrefix() ?? '') : ''); + }else{ + this.getOutputPrefix = arguments[0]; + return this; + } + } + + static #verboseLabel = ["🔈",/*"🔉",*/"🔊","📢"]; + verboseN(lvl, args){ + if( this.#verbosity>=lvl ){ + this.#outlnImpl(lvl, Outer.#verboseLabel[lvl-1],': ',...args); + } + } + verbose1(...args){ return this.verboseN(1,args); } + verbose2(...args){ return this.verboseN(2,args); } + verbose3(...args){ return this.verboseN(3,args); } + + verbosity(){ + const rc = this.#verbosity; + if(arguments.length) this.#verbosity = +arguments[0]; + return rc; + } + +}/*Outer*/ + +class SQLTester { + + //! Console output utility. + #outer = new Outer().outputPrefix( ()=>'SQLTester: ' ); + //! List of input scripts. + #aScripts = []; + //! Test input buffer. + #inputBuffer = []; + //! Test result buffer. + #resultBuffer = []; + //! Output representation of SQL NULL. + #nullView; + metrics = newObj({ + //! Total tests run + nTotalTest: 0, + //! Total test script files run + nTestFile: 0, + //! Test-case count for to the current TestScript + nTest: 0, + //! Names of scripts which were aborted. + failedScripts: [] + }); + #emitColNames = false; + //! True to keep going regardless of how a test fails. + #keepGoing = false; + #db = newObj({ + //! The list of available db handles. + list: new Array(7), + //! Index into this.list of the current db. + iCurrentDb: 0, + //! Name of the default db, re-created for each script. + initialDbName: "test.db", + //! Buffer for REQUIRED_PROPERTIES pragmas. + initSql: ['select 1;'], + //! (sqlite3*) to the current db. + currentDb: function(){ + return this.list[this.iCurrentDb]; + } + }); + + constructor(){ + this.reset(); + } + + outln(...args){ return this.#outer.outln(...args); } + out(...args){ return this.#outer.out(...args); } + outer(...args){ + if(args.length){ + this.#outer = args[0]; + return this; + } + return this.#outer; + } + verbose1(...args){ return this.#outer.verboseN(1,args); } + verbose2(...args){ return this.#outer.verboseN(2,args); } + verbose3(...args){ return this.#outer.verboseN(3,args); } + verbosity(...args){ + const rc = this.#outer.verbosity(...args); + return args.length ? this : rc; + } + setLogger(func){ + this.#outer.logger(func); + return this; + } + + incrementTestCounter(){ + ++this.metrics.nTotalTest; + ++this.metrics.nTest; + } + + reset(){ + this.clearInputBuffer(); + this.clearResultBuffer(); + this.#clearBuffer(this.#db.initSql); + this.closeAllDbs(); + this.metrics.nTest = 0; + this.#nullView = "nil"; + this.emitColNames = false; + this.#db.iCurrentDb = 0; + //this.#db.initSql.push("SELECT 1;"); + } + + appendInput(line, addNL){ + this.#inputBuffer.push(line); + if( addNL ) this.#inputBuffer.push('\n'); + } + appendResult(line, addNL){ + this.#resultBuffer.push(line); + if( addNL ) this.#resultBuffer.push('\n'); + } + appendDbInitSql(sql){ + this.#db.initSql.push(sql); + if( this.currentDb() ){ + this.execSql(null, true, ResultBufferMode.NONE, null, sql); + } + } + + #runInitSql(pDb){ + let rc = 0; + for(const sql of this.#db.initSql){ + this.#outer.verbose2("RUNNING DB INIT CODE: ",sql); + rc = this.execSql(pDb, false, ResultBufferMode.NONE, null, sql); + if( rc ) break; + } + return rc; + } + +#clearBuffer(buffer){ + buffer.length = 0; + return buffer; + } + + clearInputBuffer(){ return this.#clearBuffer(this.#inputBuffer); } + clearResultBuffer(){return this.#clearBuffer(this.#resultBuffer); } + + getInputText(){ return this.#inputBuffer.join(''); } + getResultText(){ return this.#resultBuffer.join(''); } + + #takeBuffer(buffer){ + const s = buffer.join(''); + buffer.length = 0; + return s; + } + + takeInputBuffer(){ + return this.#takeBuffer(this.#inputBuffer); + } + takeResultBuffer(){ + return this.#takeBuffer(this.#resultBuffer); + } + + nullValue(){ + return (0==arguments.length) + ? this.#nullView + : (this.#nullView = ''+arguments[0]); + } + + outputColumnNames(){ + return (0==arguments.length) + ? this.#emitColNames + : (this.#emitColNames = !!arguments[0]); + } + + currentDbId(){ + return (0==arguments.length) + ? this.#db.iCurrentDb + : (this.#affirmDbId(arguments[0]).#db.iCurrentDb = arguments[0]); + } + + #affirmDbId(id){ + if(id<0 || id>=this.#db.list.length){ + toss(SQLTesterException, "Database index ",id," is out of range."); + } + return this; + } + + currentDb(...args){ + if( 0!=args.length ){ + this.#affirmDbId(id).#db.iCurrentDb = id; + } + return this.#db.currentDb(); + } + + getDbById(id){ + return this.#affirmDbId(id).#db.list[id]; + } + + getCurrentDb(){ return this.#db.list[this.#db.iCurrentDb]; } + + + closeDb(id) { + if( 0==arguments.length ){ + id = this.#db.iCurrentDb; + } + const pDb = this.#affirmDbId(id).#db.list[id]; + if( pDb ){ + sqlite3.capi.sqlite3_close_v2(pDb); + this.#db.list[id] = null; + } + } + + closeAllDbs(){ + for(let i = 0; i 0){ + rc = this.#runInitSql(pDb); + } + if( 0!=rc ){ + sqlite3.SQLite3Error.toss( + rc, + "sqlite3 result code",rc+":", + (pDb ? sqlite3.capi.sqlite3_errmsg(pDb) + : sqlite3.capi.sqlite3_errstr(rc)) + ); + } + return this.#db.list[this.#db.iCurrentDb] = pDb; + }catch(e){ + sqlite3.capi.sqlite3_close_v2(pDb); + throw e; + } + } + + addTestScript(ts){ + if( 2===arguments.length ){ + ts = new TestScript(arguments[0], arguments[1]); + }else if(ts instanceof Uint8Array){ + ts = new TestScript('', ts); + }else if('string' === typeof arguments[1]){ + ts = new TestScript('', Util.utf8Encode(arguments[1])); + } + if( !(ts instanceof TestScript) ){ + Util.toss(SQLTesterException, "Invalid argument type for addTestScript()"); + } + this.#aScripts.push(ts); + return this; + } + + runTests(){ + const tStart = (new Date()).getTime(); + let isVerbose = this.verbosity(); + this.metrics.failedScripts.length = 0; + this.metrics.nTotalTest = 0; + this.metrics.nTestFile = 0; + for(const ts of this.#aScripts){ + this.reset(); + ++this.metrics.nTestFile; + let threw = false; + const timeStart = (new Date()).getTime(); + let msgTail = ''; + try{ + ts.run(this); + }catch(e){ + if(e instanceof SQLTesterException){ + threw = true; + this.outln("🔥EXCEPTION: ",e); + this.metrics.failedScripts.push({script: ts.filename(), message:e.toString()}); + if( this.#keepGoing ){ + this.outln("Continuing anyway because of the keep-going option."); + }else if( e.isFatal() ){ + throw e; + } + }else{ + throw e; + } + }finally{ + const timeEnd = (new Date()).getTime(); + this.out("🏁", (threw ? "❌" : "✅"), " ", + this.metrics.nTest, " test(s) in ", + (timeEnd-timeStart),"ms. "); + const mod = ts.moduleName(); + if( mod ){ + this.out( "[",mod,"] " ); + } + this.outln(ts.filename()); + } + } + const tEnd = (new Date()).getTime(); + Util.unlink(this.#db.initialDbName); + this.outln("Took ",(tEnd-tStart),"ms. Test count = ", + this.metrics.nTotalTest,", script count = ", + this.#aScripts.length,( + this.metrics.failedScripts.length + ? ", failed scripts = "+this.metrics.failedScripts.length + : "" + ) + ); + return this; + } + + #setupInitialDb(){ + if( !this.#db.list[0] ){ + Util.unlink(this.#db.initialDbName); + this.openDb(0, this.#db.initialDbName, true); + }else{ + this.#outer.outln("WARNING: setupInitialDb() was unexpectedly ", + "triggered while it is opened."); + } + } + + #escapeSqlValue(v){ + if( !v ) return "{}"; + if( !Rx.special.test(v) ){ + return v /* no escaping needed */; + } + if( !Rx.squiggly.test(v) ){ + return "{"+v+"}"; + } + const sb = ["\""]; + const n = v.length; + for(let i = 0; i < n; ++i){ + const ch = v.charAt(i); + switch(ch){ + case '\\': sb.push("\\\\"); break; + case '"': sb.push("\\\""); break; + default:{ + //verbose("CHAR ",(int)ch," ",ch," octal=",String.format("\\%03o", (int)ch)); + const ccode = ch.charCodeAt(i); + if( ccode < 32 ) sb.push('\\',ccode.toString(8),'o'); + else sb.push(ch); + break; + } + } + } + sb.append("\""); + return sb.join(''); + } + + #appendDbErr(pDb, sb, rc){ + sb.push(sqlite3.capi.sqlite3_js_rc_str(rc), ' '); + const msg = this.#escapeSqlValue(sqlite3.capi.sqlite3_errmsg(pDb)); + if( '{' === msg.charAt(0) ){ + sb.push(msg); + }else{ + sb.push('{', msg, '}'); + } + } + + #checkDbRc(pDb,rc){ + sqlite3.oo1.DB.checkRc(pDb, rc); + } + + execSql(pDb, throwOnError, appendMode, rowMode, sql){ + if( !pDb && !this.#db.list[0] ){ + this.#setupInitialDb(); + } + if( !pDb ) pDb = this.#db.currentDb(); + const wasm = sqlite3.wasm, capi = sqlite3.capi; + sql = (sql instanceof Uint8Array) + ? sql + : Util.utf8Encode(capi.sqlite3_js_sql_to_string(sql)); + const self = this; + const sb = (ResultBufferMode.NONE===appendMode) ? null : this.#resultBuffer; + let rc = 0; + wasm.scopedAllocCall(function(){ + let sqlByteLen = sql.byteLength; + const ppStmt = wasm.scopedAlloc( + /* output (sqlite3_stmt**) arg and pzTail */ + (2 * wasm.ptrSizeof) + (sqlByteLen + 1/* SQL + NUL */) + ); + const pzTail = ppStmt + wasm.ptrSizeof /* final arg to sqlite3_prepare_v2() */; + let pSql = pzTail + wasm.ptrSizeof; + const pSqlEnd = pSql + sqlByteLen; + wasm.heap8().set(sql, pSql); + wasm.poke8(pSql + sqlByteLen, 0/*NUL terminator*/); + let pos = 0, n = 1, spacing = 0; + while( pSql && wasm.peek8(pSql) ){ + wasm.pokePtr([ppStmt, pzTail], 0); + rc = capi.sqlite3_prepare_v3( + pDb, pSql, sqlByteLen, 0, ppStmt, pzTail + ); + if( 0!==rc ){ + if(throwOnError){ + throw new DbException(self, pDb, rc); + }else if( sb ){ + self.#appendDbErr(pDb, sb, rc); + } + break; + } + const pStmt = wasm.peekPtr(ppStmt); + pSql = wasm.peekPtr(pzTail); + sqlByteLen = pSqlEnd - pSql; + if(!pStmt) continue /* only whitespace or comments */; + if( sb ){ + const nCol = capi.sqlite3_column_count(pStmt); + let colName, val; + while( capi.SQLITE_ROW === (rc = capi.sqlite3_step(pStmt)) ) { + for( let i=0; i < nCol; ++i ){ + if( spacing++ > 0 ) sb.push(' '); + if( self.#emitColNames ){ + colName = capi.sqlite3_column_name(pStmt, i); + switch(appendMode){ + case ResultBufferMode.ASIS: sb.push( colName ); break; + case ResultBufferMode.ESCAPED: + sb.push( self.#escapeSqlValue(colName) ); + break; + default: + self.toss("Unhandled ResultBufferMode."); + } + sb.push(' '); + } + val = capi.sqlite3_column_text(pStmt, i); + if( null===val ){ + sb.push( self.#nullView ); + continue; + } + switch(appendMode){ + case ResultBufferMode.ASIS: sb.push( val ); break; + case ResultBufferMode.ESCAPED: + sb.push( self.#escapeSqlValue(val) ); + break; + } + }/* column loop */ + }/* row loop */ + if( ResultRowMode.NEWLINE === rowMode ){ + spacing = 0; + sb.push('\n'); + } + }else{ // no output but possibly other side effects + while( capi.SQLITE_ROW === (rc = capi.sqlite3_step(pStmt)) ) {} + } + capi.sqlite3_finalize(pStmt); + if( capi.SQLITE_ROW===rc || capi.SQLITE_DONE===rc) rc = 0; + else if( rc!=0 ){ + if( sb ){ + self.#appendDbErr(db, sb, rc); + } + break; + } + }/* SQL script loop */; + })/*scopedAllocCall()*/; + return rc; + } + +}/*SQLTester*/ + +class Command { + constructor(){ + } + + process(sqlTester,testScript,argv){ + SQLTesterException.toss("process() must be overridden"); + } + + argcCheck(testScript,argv,min,max){ + const argc = argv.length-1; + if(argc=0 && argc>max)){ + if( min==max ){ + testScript.toss(argv[0]," requires exactly ",min," argument(s)"); + }else if(max>0){ + testScript.toss(argv[0]," requires ",min,"-",max," arguments."); + }else{ + testScript.toss(argv[0]," requires at least ",min," arguments."); + } + } + } +} + +class Cursor { + src; + sb = []; + pos = 0; + //! Current line number. Starts at 0 for internal reasons and will + // line up with 1-based reality once parsing starts. + lineNo = 0 /* yes, zero */; + //! Putback value for this.pos. + putbackPos = 0; + //! Putback line number + putbackLineNo = 0; + //! Peeked-to pos, used by peekLine() and consumePeeked(). + peekedPos = 0; + //! Peeked-to line number. + peekedLineNo = 0; + + constructor(){ + } + + //! Restore parsing state to the start of the stream. + rewind(){ + this.sb.length = this.pos = this.lineNo + = this.putbackPos = this.putbackLineNo + = this.peekedPos = this.peekedLineNo = 0; + } +} + +class TestScript { + #cursor = new Cursor(); + #moduleName = null; + #filename = null; + #testCaseName = null; + #outer = new Outer().outputPrefix( ()=>this.getOutputPrefix()+': ' ); + + constructor(...args){ + let content, filename; + if( 2 == args.length ){ + filename = args[0]; + content = args[1]; + }else if( 1 == args.length ){ + if(args[0] instanceof Object){ + const o = args[0]; + filename = o.name; + content = o.content; + }else{ + content = args[0]; + } + } + if(!(content instanceof Uint8Array)){ + if('string' === typeof content){ + content = Util.utf8Encode(content); + }else if((content instanceof ArrayBuffer) + ||(content instanceof Array)){ + content = new Uint8Array(content); + }else{ + toss(Error, "Invalid content type for TestScript constructor."); + } + } + this.#filename = filename; + this.#cursor.src = content; + } + + moduleName(){ + return (0==arguments.length) + ? this.#moduleName : (this.#moduleName = arguments[0]); + } + + testCaseName(){ + return (0==arguments.length) + ? this.#testCaseName : (this.#testCaseName = arguments[0]); + } + filename(){ + return (0==arguments.length) + ? this.#filename : (this.#filename = arguments[0]); + } + + getOutputPrefix() { + let rc = "["+(this.#moduleName || '')+"]"; + if( this.#testCaseName ) rc += "["+this.#testCaseName+"]"; + if( this.#filename ) rc += '['+this.#filename+']'; + return rc + " line "+ this.#cursor.lineNo; + } + + reset(){ + this.#testCaseName = null; + this.#cursor.rewind(); + return this; + } + + toss(...args){ + throw new TestScriptFailed(this,...args); + } + + verbose1(...args){ return this.#outer.verboseN(1,args); } + verbose2(...args){ return this.#outer.verboseN(2,args); } + verbose3(...args){ return this.#outer.verboseN(3,args); } + verbosity(...args){ + const rc = this.#outer.verbosity(...args); + return args.length ? this : rc; + } + + #checkRequiredProperties(tester, props){ + if(true) return false; + let nOk = 0; + for(const rp of props){ + this.verbose2("REQUIRED_PROPERTIES: ",rp); + switch(rp){ + case "RECURSIVE_TRIGGERS": + tester.appendDbInitSql("pragma recursive_triggers=on;"); + ++nOk; + break; + case "TEMPSTORE_FILE": + /* This _assumes_ that the lib is built with SQLITE_TEMP_STORE=1 or 2, + which we just happen to know is the case */ + tester.appendDbInitSql("pragma temp_store=1;"); + ++nOk; + break; + case "TEMPSTORE_MEM": + /* This _assumes_ that the lib is built with SQLITE_TEMP_STORE=1 or 2, + which we just happen to know is the case */ + tester.appendDbInitSql("pragma temp_store=0;"); + ++nOk; + break; + case "AUTOVACUUM": + tester.appendDbInitSql("pragma auto_vacuum=full;"); + ++nOk; + break; + case "INCRVACUUM": + tester.appendDbInitSql("pragma auto_vacuum=incremental;"); + ++nOk; + default: + break; + } + } + return props.length == nOk; + } + + #checkForDirective(tester,line){ + if(line.startsWith("#")){ + throw new IncompatibleDirective(this, "C-preprocessor input: "+line); + }else if(line.startsWith("---")){ + throw new IncompatibleDirective(this, "triple-dash: ",line); + } + let m = Rx.scriptModuleName.exec(line); + if( m ){ + this.#moduleName = m[1]; + return; + } + m = Rx.requiredProperties.exec(line); + if( m ){ + const rp = m[1]; + if( !this.#checkRequiredProperties( tester, rp.split(/\s+/).filter(v=>!!v) ) ){ + throw new IncompatibleDirective(this, "REQUIRED_PROPERTIES: "+rp); + } + } + + m = Rx.mixedModuleName.exec(line); + if( m ){ + throw new IncompatibleDirective(this, m[1]+": "+m[3]); + } + if( line.indexOf("\n|")>=0 ){ + throw new IncompatibleDirective(this, "newline-pipe combination."); + } + + } + + #getCommandArgv(line){ + const m = Rx.command.exec(line); + return m ? m[1].trim().split(/\s+/) : null; + } + + + #isCommandLine(line, checkForImpl){ + let m = Rx.command.exec(line); + if( m && checkForImpl ){ + m = !!CommandDispatcher.getCommandByName(m[2]); + } + return !!m; + } + + fetchCommandBody(tester){ + const sb = []; + let line; + while( (null !== (line = this.peekLine())) ){ + this.#checkForDirective(tester, line); + if( this.#isCommandLine(line, true) ) break; + sb.push(line,"\n"); + this.consumePeeked(); + } + line = sb.join(''); + return !!line.trim() ? line : null; + } + + run(tester){ + this.reset(); + this.#outer.verbosity( tester.verbosity() ); + this.#outer.logger( tester.outer().logger() ); + let line, directive, argv = []; + while( null != (line = this.getLine()) ){ + this.verbose3("run() input line: ",line); + this.#checkForDirective(tester, line); + argv = this.#getCommandArgv(line); + if( argv ){ + this.#processCommand(tester, argv); + continue; + } + tester.appendInput(line,true); + } + return true; + } + + #processCommand(tester, argv){ + this.verbose2("processCommand(): ",argv[0], " ", Util.argvToString(argv)); + if(this.#outer.verbosity()>1){ + const input = tester.getInputText(); + this.verbose3("processCommand() input buffer = ",input); + } + CommandDispatcher.dispatch(tester, this, argv); + } + + getLine(){ + const cur = this.#cursor; + if( cur.pos==cur.src.byteLength ){ + return null/*EOF*/; + } + cur.putbackPos = cur.pos; + cur.putbackLineNo = cur.lineNo; + cur.sb.length = 0; + let b = 0, prevB = 0, i = cur.pos; + let doBreak = false; + let nChar = 0 /* number of bytes in the aChar char */; + const end = cur.src.byteLength; + for(; i < end && !doBreak; ++i){ + b = cur.src[i]; + switch( b ){ + case 13/*CR*/: continue; + case 10/*NL*/: + ++cur.lineNo; + if(cur.sb.length>0) doBreak = true; + // Else it's an empty string + break; + default:{ + /* Multi-byte chars need to be gathered up and appended at + one time so that we can get them as string objects. */ + nChar = 1; + switch( b & 0xF0 ){ + case 0xC0: nChar = 2; break; + case 0xE0: nChar = 3; break; + case 0xF0: nChar = 4; break; + default: + if( b > 127 ) this.toss("Invalid character (#"+b+")."); + break; + } + if( 1==nChar ){ + cur.sb.push(String.fromCharCode(b)); + }else{ + const aChar = [] /* multi-byte char buffer */; + for(let x = 0; (x < nChar) && (i+x < end); ++x) aChar[x] = cur.src[i+x]; + cur.sb.push( + Util.utf8Decode( new Uint8Array(aChar) ) + ); + i += nChar-1; + } + break; + } + } + } + cur.pos = i; + const rv = cur.sb.join(''); + if( i==cur.src.byteLength && 0==rv.length ){ + return null /* EOF */; + } + return rv; + }/*getLine()*/ + + /** + Fetches the next line then resets the cursor to its pre-call + state. consumePeeked() can be used to consume this peeked line + without having to re-parse it. + */ + peekLine(){ + const cur = this.#cursor; + const oldPos = cur.pos; + const oldPB = cur.putbackPos; + const oldPBL = cur.putbackLineNo; + const oldLine = cur.lineNo; + try { + return this.getLine(); + }finally{ + cur.peekedPos = cur.pos; + cur.peekedLineNo = cur.lineNo; + cur.pos = oldPos; + cur.lineNo = oldLine; + cur.putbackPos = oldPB; + cur.putbackLineNo = oldPBL; + } + } + + + /** + Only valid after calling peekLine() and before calling getLine(). + This places the cursor to the position it would have been at had + the peekLine() had been fetched with getLine(). + */ + consumePeeked(){ + const cur = this.#cursor; + cur.pos = cur.peekedPos; + cur.lineNo = cur.peekedLineNo; + } + + /** + Restores the cursor to the position it had before the previous + call to getLine(). + */ + putbackLine(){ + const cur = this.#cursor; + cur.pos = cur.putbackPos; + cur.lineNo = cur.putbackLineNo; + } + +}/*TestScript*/; + +//! --close command +class CloseDbCommand extends Command { + process(t, ts, argv){ + this.argcCheck(ts,argv,0,1); + let id; + if(argv.length>1){ + const arg = argv[1]; + if( "all" === arg ){ + t.closeAllDbs(); + return; + } + else{ + id = parseInt(arg); + } + }else{ + id = t.currentDbId(); + } + t.closeDb(id); + } +} + +//! --column-names command +class ColumnNamesCommand extends Command { + process( st, ts, argv ){ + this.argcCheck(ts,argv,1); + st.outputColumnNames( !!parseInt(argv[1]) ); + } +} + +//! --db command +class DbCommand extends Command { + process(t, ts, argv){ + this.argcCheck(ts,argv,1); + t.currentDbId( parseInt(argv[1]) ); + } +} + +//! --glob command +class GlobCommand extends Command { + #negate = false; + constructor(negate=false){ + super(); + this.#negate = negate; + } + + process(t, ts, argv){ + this.argcCheck(ts,argv,1,-1); + t.incrementTestCounter(); + const sql = t.takeInputBuffer(); + let rc = t.execSql(null, true, ResultBufferMode.ESCAPED, + ResultRowMode.ONELINE, sql); + const result = t.getResultText(); + const sArgs = Util.argvToString(argv); + //t2.verbose2(argv[0]," rc = ",rc," result buffer:\n", result,"\nargs:\n",sArgs); + const glob = Util.argvToString(argv); + rc = Util.strglob(glob, result); + if( (this.#negate && 0===rc) || (!this.#negate && 0!==rc) ){ + ts.toss(argv[0], " mismatch: ", glob," vs input: ",result); + } + } +} + +//! --notglob command +class NotGlobCommand extends GlobCommand { + constructor(){super(true);} +} + +//! --open command +class OpenDbCommand extends Command { + #createIfNeeded = false; + constructor(createIfNeeded=false){ + super(); + this.#createIfNeeded = createIfNeeded; + } + process(t, ts, argv){ + this.argcCheck(ts,argv,1); + t.openDb(argv[1], this.#createIfNeeded); + } +} + +//! --new command +class NewDbCommand extends OpenDbCommand { + constructor(){ super(true); } +} + +//! Placeholder dummy/no-op commands +class NoopCommand extends Command { + process(t, ts, argv){} +} + +//! --null command +class NullCommand extends Command { + process(st, ts, argv){ + this.argcCheck(ts,argv,1); + st.nullValue( argv[1] ); + } +} + +//! --print command +class PrintCommand extends Command { + process(st, ts, argv){ + st.out(ts.getOutputPrefix(),': '); + if( 1==argv.length ){ + st.out( st.getInputText() ); + }else{ + st.outln( Util.argvToString(argv) ); + } + } +} + +//! --result command +class ResultCommand extends Command { + #bufferMode; + constructor(resultBufferMode = ResultBufferMode.ESCAPED){ + super(); + this.#bufferMode = resultBufferMode; + } + process(t, ts, argv){ + this.argcCheck(ts,argv,0,-1); + t.incrementTestCounter(); + const sql = t.takeInputBuffer(); + //ts.verbose2(argv[0]," SQL =\n",sql); + t.execSql(null, false, this.#bufferMode, ResultRowMode.ONELINE, sql); + const result = t.getResultText().trim(); + const sArgs = argv.length>1 ? Util.argvToString(argv) : ""; + if( result !== sArgs ){ + t.outln(argv[0]," FAILED comparison. Result buffer:\n", + result,"\nExpected result:\n",sArgs); + ts.toss(argv[0]+" comparison failed."); + } + } +} + +//! --json command +class JsonCommand extends ResultCommand { + constructor(){ super(ResultBufferMode.ASIS); } +} + +//! --run command +class RunCommand extends Command { + process(t, ts, argv){ + this.argcCheck(ts,argv,0,1); + const pDb = (1==argv.length) + ? t.currentDb() : t.getDbById( parseInt(argv[1]) ); + const sql = t.takeInputBuffer(); + const rc = t.execSql(pDb, false, ResultBufferMode.NONE, + ResultRowMode.ONELINE, sql); + if( 0!==rc && t.verbosity()>0 ){ + const msg = sqlite3.capi.sqlite3_errmsg(pDb); + ts.verbose2(argv[0]," non-fatal command error #",rc,": ", + msg,"\nfor SQL:\n",sql); + } + } +} + +//! --tableresult command +class TableResultCommand extends Command { + #jsonMode; + constructor(jsonMode=false){ + super(); + this.#jsonMode = jsonMode; + } + process(t, ts, argv){ + this.argcCheck(ts,argv,0); + t.incrementTestCounter(); + let body = ts.fetchCommandBody(t); + if( null===body ) ts.toss("Missing ",argv[0]," body."); + body = body.trim(); + if( !body.endsWith("\n--end") ){ + ts.toss(argv[0], " must be terminated with --end\\n"); + }else{ + body = body.substring(0, body.length-6); + } + const globs = body.split(/\s*\n\s*/); + if( globs.length < 1 ){ + ts.toss(argv[0], " requires 1 or more ", + (this.#jsonMode ? "json snippets" : "globs"),"."); + } + const sql = t.takeInputBuffer(); + t.execSql(null, true, + this.#jsonMode ? ResultBufferMode.ASIS : ResultBufferMode.ESCAPED, + ResultRowMode.NEWLINE, sql); + const rbuf = t.getResultText().trim(); + const res = rbuf.split(/\r?\n/); + if( res.length !== globs.length ){ + ts.toss(argv[0], " failure: input has ", res.length, + " row(s) but expecting ",globs.length); + } + for(let i = 0; i < res.length; ++i){ + const glob = globs[i].replaceAll(/\s+/g," ").trim(); + //ts.verbose2(argv[0]," <<",glob,">> vs <<",res[i],">>"); + if( this.#jsonMode ){ + if( glob!==res[i] ){ + ts.toss(argv[0], " json <<",glob, ">> does not match: <<", + res[i],">>"); + } + }else if( 0!=Util.strglob(glob, res[i]) ){ + ts.toss(argv[0], " glob <<",glob,">> does not match: <<",res[i],">>"); + } + } + } +} + +//! --json-block command +class JsonBlockCommand extends TableResultCommand { + constructor(){ super(true); } +} + +//! --testcase command +class TestCaseCommand extends Command { + process(tester, script, argv){ + this.argcCheck(script, argv,1); + script.testCaseName(argv[1]); + tester.clearResultBuffer(); + tester.clearInputBuffer(); + } +} + + +//! --verbosity command +class VerbosityCommand extends Command { + process(t, ts, argv){ + this.argcCheck(ts,argv,1); + ts.verbosity( parseInt(argv[1]) ); + } +} + +class CommandDispatcher { + static map = newObj(); + + static getCommandByName(name){ + let rv = CommandDispatcher.map[name]; + if( rv ) return rv; + switch(name){ + case "close": rv = new CloseDbCommand(); break; + case "column-names": rv = new ColumnNamesCommand(); break; + case "db": rv = new DbCommand(); break; + case "glob": rv = new GlobCommand(); break; + case "json": rv = new JsonCommand(); break; + case "json-block": rv = new JsonBlockCommand(); break; + case "new": rv = new NewDbCommand(); break; + case "notglob": rv = new NotGlobCommand(); break; + case "null": rv = new NullCommand(); break; + case "oom": rv = new NoopCommand(); break; + case "open": rv = new OpenDbCommand(); break; + case "print": rv = new PrintCommand(); break; + case "result": rv = new ResultCommand(); break; + case "run": rv = new RunCommand(); break; + case "tableresult": rv = new TableResultCommand(); break; + case "testcase": rv = new TestCaseCommand(); break; + case "verbosity": rv = new VerbosityCommand(); break; + } + if( rv ){ + CommandDispatcher.map[name] = rv; + } + return rv; + } + + static dispatch(tester, testScript, argv){ + const cmd = CommandDispatcher.getCommandByName(argv[0]); + if( !cmd ){ + toss(UnknownCommand,testScript,argv[0]); + } + cmd.process(tester, testScript, argv); + } +}/*CommandDispatcher*/ + +const namespace = newObj({ + Command, + DbException, + IncompatibleDirective, + Outer, + SQLTester, + SQLTesterException, + TestScript, + TestScriptFailed, + UnknownCommand, + Util, + sqlite3 +}); + +export {namespace as default}; diff -Nru sqlite3-3.42.0/ext/wasm/SQLTester/SQLTester.run.mjs sqlite3-3.44.0-0/ext/wasm/SQLTester/SQLTester.run.mjs --- sqlite3-3.42.0/ext/wasm/SQLTester/SQLTester.run.mjs 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/SQLTester/SQLTester.run.mjs 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,148 @@ +/* +** 2023-08-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 contains a test application for SQLTester.js. +*/ +import {default as ns} from './SQLTester.mjs'; +import {default as allTests} from './test-list.mjs'; + +globalThis.sqlite3 = ns.sqlite3; +const log = function f(...args){ + console.log('SQLTester.run:',...args); + return f; +}; + +const out = function f(...args){ return f.outer.out(...args) }; +out.outer = new ns.Outer(); +out.outer.getOutputPrefix = ()=>'SQLTester.run: '; +const outln = (...args)=>{ return out.outer.outln(...args) }; + +const affirm = function(expr, msg){ + if( !expr ){ + throw new Error(arguments[1] + ? ("Assertion failed: "+arguments[1]) + : "Assertion failed"); + } +} + +let ts = new ns.TestScript('/foo.test',` +/* +** This is a comment. There are many like it but this one is mine. +** +** SCRIPT_MODULE_NAME: sanity-check-0 +** xMIXED_MODULE_NAME: mixed-module +** xMODULE_NAME: module-name +** xREQUIRED_PROPERTIES: small fast reliable +** xREQUIRED_PROPERTIES: RECURSIVE_TRIGGERS +** xREQUIRED_PROPERTIES: TEMPSTORE_FILE TEMPSTORE_MEM +** xREQUIRED_PROPERTIES: AUTOVACUUM INCRVACUUM +** +*/ +/* --verbosity 3 */ +/* ---must-fail */ +/* # must fail */ +/* --verbosity 0 */ +--print Hello, world. +--close all +--oom +--db 0 +--new my.db +--null zilch +--testcase 1.0 +SELECT 1, null; +--result 1 zilch +--glob *zil* +--notglob *ZIL* +SELECT 1, 2; +intentional error; +--run +/* ---intentional-failure */ +--testcase json-1 +SELECT json_array(1,2,3) +--json [1,2,3] +--testcase tableresult-1 + select 1, 'a'; + select 2, 'b'; +--tableresult + # [a-z] + 2 b +--end +--testcase json-block-1 + select json_array(1,2,3); + select json_object('a',1,'b',2); +--json-block + [1,2,3] + {"a":1,"b":2} +--end +--testcase col-names-on +--column-names 1 + select 1 as 'a', 2 as 'b'; +--result a 1 b 2 +--testcase col-names-off +--column-names 0 + select 1 as 'a', 2 as 'b'; +--result 1 2 +--close +--print Until next time +`); + +const sqt = new ns.SQLTester() + .setLogger(console.log.bind(console)) + .verbosity(1) + .addTestScript(ts); +sqt.outer().outputPrefix(''); + +const runTests = function(){ + try{ + if( 0 ){ + affirm( !sqt.getCurrentDb(), 'sqt.getCurrentDb()' ); + sqt.openDb('/foo.db', true); + affirm( !!sqt.getCurrentDb(),'sqt.getCurrentDb()' ); + affirm( 'zilch' !== sqt.nullValue() ); + ts.run(sqt); + affirm( 'zilch' === sqt.nullValue() ); + sqt.addTestScript(ts); + sqt.runTests(); + }else{ + for(const t of allTests){ + sqt.addTestScript( new ns.TestScript(t) ); + } + allTests.length = 0; + sqt.runTests(); + } + }finally{ + //log( "Metrics:", sqt.metrics ); + sqt.reset(); + } +}; + +if( globalThis.WorkerGlobalScope ){ + const wPost = (type,payload)=>globalThis.postMessage({type, payload}); + globalThis.onmessage = function({data}){ + switch(data.type){ + case 'run-tests':{ + try{ runTests(); } + finally{ wPost('tests-end', sqt.metrics); } + break; + } + default: + log("unhandled onmessage: ",data); + break; + } + }; + sqt.setLogger((msg)=>{ + wPost('stdout', {message: msg}); + }); + wPost('is-ready'); + //globalThis.onmessage({data:{type:'run-tests'}}); +}else{ + runTests(); +} diff -Nru sqlite3-3.42.0/ext/wasm/SQLTester/touint8array.c sqlite3-3.44.0-0/ext/wasm/SQLTester/touint8array.c --- sqlite3-3.42.0/ext/wasm/SQLTester/touint8array.c 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/SQLTester/touint8array.c 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,29 @@ +/* +** 2023-08-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 contains a tool for writing out the contents of stdin as +** a comma-separated list of numbers, one per byte. +*/ + +#include +int main(int argc, char const **argv){ + int i; + int rc = 0, colWidth = 30; + int ch; + printf("["); + for( i=0; EOF!=(ch = fgetc(stdin)); ++i ){ + if( 0!=i ) printf(","); + if( i && 0==(i%colWidth) ) puts(""); + printf("%d",ch); + } + printf("]"); + return rc; +} diff -Nru sqlite3-3.42.0/ext/wasm/tester1.c-pp.js sqlite3-3.44.0-0/ext/wasm/tester1.c-pp.js --- sqlite3-3.42.0/ext/wasm/tester1.c-pp.js 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/tester1.c-pp.js 2023-11-04 14:23:58.000000000 +0000 @@ -45,7 +45,7 @@ */ //#if target=es6-module import {default as sqlite3InitModule} from './jswasm/sqlite3.mjs'; -self.sqlite3InitModule = sqlite3InitModule; +globalThis.sqlite3InitModule = sqlite3InitModule; //#else 'use strict'; //#endif @@ -57,7 +57,7 @@ */ let logClass; /* Predicate for tests/groups. */ - const isUIThread = ()=>(self.window===self && self.document); + const isUIThread = ()=>(globalThis.window===self && globalThis.document); /* Predicate for tests/groups. */ const isWorker = ()=>!isUIThread(); /* Predicate for tests/groups. */ @@ -65,6 +65,14 @@ const haveWasmCTests = ()=>{ return !!wasm.exports.sqlite3_wasm_test_intptr; }; + const hasOpfs = ()=>{ + return globalThis.FileSystemHandle + && globalThis.FileSystemDirectoryHandle + && globalThis.FileSystemFileHandle + && globalThis.FileSystemFileHandle.prototype.createSyncAccessHandle + && navigator?.storage?.getDirectory; + }; + { const mapToString = (v)=>{ switch(typeof v){ @@ -98,6 +106,7 @@ logTarget.append(ln); }; const cbReverse = document.querySelector('#cb-log-reverse'); + //cbReverse.setAttribute('checked','checked'); const cbReverseKey = 'tester1:cb-log-reverse'; const cbReverseIt = ()=>{ logTarget.classList[cbReverse.checked ? 'add' : 'remove']('reverse'); @@ -158,8 +167,6 @@ /** Running total of the number of tests run via this API. */ counter: 0, - /* Separator line for log messages. */ - separator: '------------------------------------------------------------', /** If expr is a function, it is called and its result is returned, coerced to a bool, else expr, coerced to @@ -247,13 +254,11 @@ return this; }, run: async function(sqlite3){ - log(TestUtil.separator); logClass('group-start',"Group #"+this.number+':',this.name); - const indent = ' '; if(this.predicate){ const p = this.predicate(sqlite3); if(!p || 'string'===typeof p){ - logClass('warning',indent, + logClass(['warning','skipping-group'], "SKIPPING group:", p ? p : "predicate says to" ); return; } @@ -265,26 +270,34 @@ for(const t of this.tests){ ++i; const n = this.number+"."+i; - log(indent, n+":", t.name); + logClass('one-test-line', n+":", t.name); if(t.predicate){ const p = t.predicate(sqlite3); if(!p || 'string'===typeof p){ - logClass('warning',indent, + logClass(['warning','skipping-test'], "SKIPPING:", p ? p : "predicate says to" ); skipped.push( n+': '+t.name ); continue; } } const tc = TestUtil.counter, now = performance.now(); - await t.test.call(groupState, sqlite3); + let rc = t.test.call(groupState, sqlite3); + /*if(rc instanceof Promise){ + rc = rc.catch((e)=>{ + error("Test failure:",e); + throw e; + }); + }*/ + await rc; const then = performance.now(); runtime += then - now; - logClass('faded',indent, indent, + logClass(['faded','one-test-summary'], TestUtil.counter - tc, 'assertion(s) in', roundMs(then-now),'ms'); } - logClass('green', - "Group #"+this.number+":",(TestUtil.counter - assertCount), + logClass(['green','group-end'], + "#"+this.number+":", + (TestUtil.counter - assertCount), "assertion(s) in",roundMs(runtime),"ms"); if(0 && skipped.length){ logClass('warning',"SKIPPED test(s) in group",this.number+":",skipped); @@ -320,8 +333,7 @@ await g.run(sqlite3); runtime += performance.now() - now; } - log(TestUtil.separator); - logClass(['strong','green'], + logClass(['strong','green','full-test-summary'], "Done running tests.",TestUtil.counter,"assertions in", roundMs(runtime),'ms'); pok(); @@ -338,6 +350,11 @@ T.g = T.addGroup; T.t = T.addTest; let capi, wasm/*assigned after module init*/; + const sahPoolConfig = { + name: 'opfs-sahpool-tester1', + clearOnInit: true, + initialCapacity: 6 + }; //////////////////////////////////////////////////////////////////////// // End of infrastructure setup. Now define the tests... //////////////////////////////////////////////////////////////////////// @@ -1166,7 +1183,8 @@ try{db.checkRc(rc)} catch(e){ex = e} T.assert(ex instanceof sqlite3.SQLite3Error) - .assert(0===ex.message.indexOf("sqlite3 result code")) + .assert(capi.SQLITE_MISUSE===ex.resultCode) + .assert(0===ex.message.indexOf("SQLITE_MISUSE: sqlite3 result code")) .assert(ex.message.indexOf("Invalid SQL")>0); T.assert(db === db.checkRc(0)) .assert(db === sqlite3.oo1.DB.checkRc(db,0)) @@ -1219,6 +1237,7 @@ ); //debug("statement =",st); this.progressHandlerCount = 0; + let rc; try { T.assert(wasm.isPtr(st.pointer)) .mustThrowMatching(()=>st.pointer=1, /read-only/) @@ -1229,6 +1248,8 @@ ) === 0) .assert(!st._mayGet) .assert('a' === st.getColumnName(0)) + .mustThrowMatching(()=>st.columnCount=2, + /columnCount property is read-only/) .assert(1===st.columnCount) .assert(0===st.parameterCount) .mustThrow(()=>st.bind(1,null)) @@ -1264,10 +1285,11 @@ assert(0===capi.sqlite3_strlike("%.txt", "foo.txt", 0)). assert(0!==capi.sqlite3_strlike("%.txt", "foo.xtx", 0)); }finally{ - st.finalize(); + rc = st.finalize(); } T.assert(!st.pointer) - .assert(0===this.db.openStatementCount()); + .assert(0===this.db.openStatementCount()) + .assert(0===rc); T.mustThrowMatching(()=>new sqlite3.oo1.Stmt("hi"), function(err){ return (err instanceof sqlite3.SQLite3Error) @@ -1282,7 +1304,6 @@ if(1){ const vfsList = capi.sqlite3_js_vfs_list(); T.assert(vfsList.length>1); - //log("vfsList =",vfsList); wasm.scopedAllocCall(()=>{ const vfsArg = (v)=>wasm.xWrap.testConvertArg('sqlite3_vfs*',v); for(const v of vfsList){ @@ -1332,8 +1353,8 @@ sql:['CREATE TABLE t(a,b);', // ^^^ using TEMP TABLE breaks the db export test "INSERT INTO t(a,b) VALUES(1,2),(3,4),", - "(?,?),('blob',X'6869')"/*intentionally missing semicolon to test for - off-by-one bug in string-to-WASM conversion*/], + "(?,?)"/*intentionally missing semicolon to test for + off-by-one bug in string-to-WASM conversion*/], saveSql: list, bind: [5,6] }); @@ -1341,12 +1362,20 @@ T.assert(rc === db) .assert(2 === list.length) .assert('string'===typeof list[1]) - .assert(4===db.changes()) + .assert(3===db.changes()) .assert(this.progressHandlerCount > 0, "Expecting progress callback.") if(wasm.bigIntEnabled){ - T.assert(4n===db.changes(false,true)); + T.assert(3n===db.changes(false,true)); } + rc = db.exec({ + sql: "INSERT INTO t(a,b) values('blob',X'6869') RETURNING 13", + rowMode: 0 + }); + T.assert(Array.isArray(rc)) + .assert(1===rc.length) + .assert(13 === rc[0]) + .assert(1===db.changes()); let vals = db.selectValues('select a from t order by a limit 2'); T.assert( 2 === vals.length ) @@ -1374,9 +1403,9 @@ 3 === this._myState /* Recall that "this" is the options object. */ ).assert( + this.columnNames===colNames + ).assert( this.columnNames[0]==='a' && this.columnNames[1]==='b' - /* options.columnNames is filled out before the first - Stmt.step(). */ ).assert( (row.a%2 && row.a<6) || 'blob'===row.a ); @@ -1386,6 +1415,14 @@ .assert('a' === colNames[0]) .assert(4 === counter) .assert(4 === list.length); + colNames = []; + db.exec({ + /* Ensure that columnNames is populated for empty result sets. */ + sql: "SELECT a a, b B FROM t WHERE 0", + columnNames: colNames + }); + T.assert(2===colNames.length) + .assert('a'===colNames[0] && 'B'===colNames[1]); list.length = 0; db.exec("SELECT a a, b b FROM t",{ rowMode: 'array', @@ -1438,11 +1475,14 @@ let st = db.prepare("update t set b=:b where a='blob'"); try { + T.assert(0===st.columnCount); const ndx = st.getParamIndex(':b'); T.assert(1===ndx); - st.bindAsBlob(ndx, "ima blob").reset(true); + st.bindAsBlob(ndx, "ima blob") + /*step() skipped intentionally*/.reset(true); } finally { - st.finalize(); + T.assert(0===st.finalize()) + .assert(undefined===st.finalize()); } try { @@ -1604,8 +1644,20 @@ .assert(3===rc[1].a) .assert(4===rc[1].b); }) - //////////////////////////////////////////////////////////////////////// + .t('selectArray/Object/Values() via INSERT/UPDATE...RETURNING', function(sqlite3){ + let rc = this.db.selectObject("INSERT INTO t(a,b) VALUES(83,84) RETURNING a as AA"); + T.assert(83===rc.AA); + rc = this.db.selectArray("UPDATE T set a=85 WHERE a=83 RETURNING b as BB"); + T.assert(Array.isArray(rc)).assert(84===rc[0]); + //log("select * from t:",this.db.selectObjects("select * from t order by a")); + rc = this.db.selectValues("UPDATE T set a=a*1 RETURNING a"); + T.assert(Array.isArray(rc)) + .assert(5 === rc.length) + .assert('number'===typeof rc[0]) + .assert(rc[0]|0 === rc[0] /* is small integer */); + }) + //////////////////////////////////////////////////////////////////////// .t({ name: 'sqlite3_js_db_export()', predicate: ()=>true, @@ -1619,13 +1671,12 @@ } }/*sqlite3_js_db_export()*/) .t({ - name: 'sqlite3_js_vfs_create_file() with db in default VFS', + name: 'sqlite3_js_posix_create_file()', predicate: ()=>true, test: function(sqlite3){ const db = this.db; - const pVfs = capi.sqlite3_js_db_vfs(db); - const filename = "sqlite3_js_vfs_create_file().db"; - capi.sqlite3_js_vfs_create_file(pVfs, filename, this.dbExport); + const filename = "sqlite3_js_posix_create_file.db"; + capi.sqlite3_js_posix_create_file(filename, this.dbExport); delete this.dbExport; const db2 = new sqlite3.oo1.DB(filename,'r'); try { @@ -1634,7 +1685,7 @@ T.assert(n>0 && db2.selectValue(sql) === n); }finally{ db2.close(); - wasm.sqlite3_wasm_vfs_unlink(pVfs, filename); + wasm.sqlite3_wasm_vfs_unlink(0, filename); } } }/*sqlite3_js_vfs_create_file()*/) @@ -2579,128 +2630,6 @@ ;/* end kvvfs tests */ //////////////////////////////////////////////////////////////////////// - T.g('OPFS: Origin-Private File System', - (sqlite3)=>(sqlite3.opfs - ? true : "requires Worker thread in a compatible browser")) - .t({ - name: 'OPFS db sanity checks', - test: async function(sqlite3){ - const filename = this.opfsDbFile = 'sqlite3-tester1.db'; - const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs'); - T.assert(pVfs); - const unlink = this.opfsUnlink = - (fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)}; - unlink(); - let db = new sqlite3.oo1.OpfsDb(filename); - try { - db.exec([ - 'create table p(a);', - 'insert into p(a) values(1),(2),(3)' - ]); - T.assert(3 === db.selectValue('select count(*) from p')); - db.close(); - db = new sqlite3.oo1.OpfsDb(filename); - db.exec('insert into p(a) values(4),(5),(6)'); - T.assert(6 === db.selectValue('select count(*) from p')); - this.opfsDbExport = capi.sqlite3_js_db_export(db); - T.assert(this.opfsDbExport instanceof Uint8Array) - .assert(this.opfsDbExport.byteLength>0 - && 0===this.opfsDbExport.byteLength % 512); - }finally{ - db.close(); - unlink(); - } - } - }/*OPFS db sanity checks*/) - .t({ - name: 'OPFS export/import', - test: async function(sqlite3){ - let db; - try { - const exp = this.opfsDbExport; - delete this.opfsDbExport; - capi.sqlite3_js_vfs_create_file("opfs", this.opfsDbFile, exp); - const db = new sqlite3.oo1.OpfsDb(this.opfsDbFile); - T.assert(6 === db.selectValue('select count(*) from p')); - }finally{ - if(db) db.close(); - } - } - }/*OPFS export/import*/) - .t({ - name: 'OPFS utility APIs and sqlite3_js_vfs_create_file()', - test: async function(sqlite3){ - const filename = this.opfsDbFile; - const pVfs = this.opfsVfs; - const unlink = this.opfsUnlink; - T.assert(filename && pVfs && !!unlink); - delete this.opfsDbFile; - delete this.opfsVfs; - delete this.opfsUnlink; - unlink(); - // Sanity-test sqlite3_js_vfs_create_file()... - /************************************************************** - ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended - for client-side use. It is only for this project's own - internal use. Its APIs are subject to change or removal at - any time. - ***************************************************************/ - const opfs = sqlite3.opfs; - const fSize = 1379; - let sh; - try{ - T.assert(!(await opfs.entryExists(filename))); - capi.sqlite3_js_vfs_create_file( - pVfs, filename, null, fSize - ); - T.assert(await opfs.entryExists(filename)); - let fh = await opfs.rootDirectory.getFileHandle(filename); - sh = await fh.createSyncAccessHandle(); - T.assert(fSize === await sh.getSize()); - await sh.close(); - sh = undefined; - unlink(); - T.assert(!(await opfs.entryExists(filename))); - - const ba = new Uint8Array([1,2,3,4,5]); - capi.sqlite3_js_vfs_create_file( - "opfs", filename, ba - ); - T.assert(await opfs.entryExists(filename)); - fh = await opfs.rootDirectory.getFileHandle(filename); - sh = await fh.createSyncAccessHandle(); - T.assert(ba.byteLength === await sh.getSize()); - await sh.close(); - sh = undefined; - unlink(); - - T.mustThrowMatching(()=>{ - capi.sqlite3_js_vfs_create_file( - "no-such-vfs", filename, ba - ); - }, "SQLITE_NOTFOUND: Unknown sqlite3_vfs name: no-such-vfs"); - }finally{ - if(sh) await sh.close(); - unlink(); - } - - // Some sanity checks of the opfs utility functions... - const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12); - const aDir = testDir+'/test/dir'; - T.assert(await opfs.mkdir(aDir), "mkdir failed") - .assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists") - .assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)") - .assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed") - .assert(!(await opfs.unlink(testDir+'/test/dir')), - "delete 2b should have failed (dir already deleted)") - .assert((await opfs.unlink(testDir, true)), "delete 3 failed") - .assert(!(await opfs.entryExists(testDir)), - "entryExists(",testDir,") should have failed"); - } - }/*OPFS util sanity checks*/) - ;/* end OPFS tests */ - - //////////////////////////////////////////////////////////////////////// T.g('Hook APIs') .t({ name: "sqlite3_commit/rollback/update_hook()", @@ -2905,8 +2834,7 @@ .assert( capi.sqlite3session_enable(pSession, -1) > 0 ) .assert(undefined === db1.selectValue('select a from t where rowid=2')); }else{ - warn("sqlite3session_enable() tests disabled due to unexpected results.", - "(Possibly a tester misunderstanding, as opposed to a bug.)"); + warn("sqlite3session_enable() tests are currently disabled."); } let db1Count = db1.selectValue("select count(*) from t"); T.assert( db1Count === (testSessionEnable ? 2 : 3) ); @@ -2972,16 +2900,303 @@ ;/*end of session API group*/; //////////////////////////////////////////////////////////////////////// + T.g('OPFS: Origin-Private File System', + (sqlite3)=>(sqlite3.capi.sqlite3_vfs_find("opfs") + || 'requires "opfs" VFS')) + .t({ + name: 'OPFS db sanity checks', + test: async function(sqlite3){ + const filename = this.opfsDbFile = '/dir/sqlite3-tester1.db'; + const pVfs = this.opfsVfs = capi.sqlite3_vfs_find('opfs'); + T.assert(pVfs); + const unlink = this.opfsUnlink = + (fn=filename)=>{wasm.sqlite3_wasm_vfs_unlink(pVfs,fn)}; + unlink(); + let db = new sqlite3.oo1.OpfsDb(filename); + try { + db.exec([ + 'create table p(a);', + 'insert into p(a) values(1),(2),(3)' + ]); + T.assert(3 === db.selectValue('select count(*) from p')); + db.close(); + db = new sqlite3.oo1.OpfsDb(filename); + db.exec('insert into p(a) values(4),(5),(6)'); + T.assert(6 === db.selectValue('select count(*) from p')); + this.opfsDbExport = capi.sqlite3_js_db_export(db); + T.assert(this.opfsDbExport instanceof Uint8Array) + .assert(this.opfsDbExport.byteLength>0 + && 0===this.opfsDbExport.byteLength % 512); + }finally{ + db.close(); + unlink(); + } + } + }/*OPFS db sanity checks*/) + .t({ + name: 'OPFS import', + test: async function(sqlite3){ + let db; + try { + const exp = this.opfsDbExport; + const filename = this.opfsDbFile; + delete this.opfsDbExport; + this.opfsImportSize = await sqlite3.oo1.OpfsDb.importDb(filename, exp); + db = new sqlite3.oo1.OpfsDb(this.opfsDbFile); + T.assert(6 === db.selectValue('select count(*) from p')). + assert( this.opfsImportSize == exp.byteLength ); + db.close(); + this.opfsUnlink(filename); + T.assert(!(await sqlite3.opfs.entryExists(filename))); + // Try again with a function as an input source: + let cursor = 0; + const blockSize = 512, end = exp.byteLength; + const reader = async function(){ + if(cursor >= exp.byteLength){ + return undefined; + } + const rv = exp.subarray(cursor, cursor+blockSize>end ? end : cursor+blockSize); + cursor += blockSize; + return rv; + }; + this.opfsImportSize = await sqlite3.oo1.OpfsDb.importDb(filename, reader); + db = new sqlite3.oo1.OpfsDb(this.opfsDbFile); + T.assert(6 === db.selectValue('select count(*) from p')). + assert( this.opfsImportSize == exp.byteLength ); + }finally{ + if(db) db.close(); + } + } + }/*OPFS export/import*/) + .t({ + name: '(Internal-use) OPFS utility APIs', + test: async function(sqlite3){ + const filename = this.opfsDbFile; + const pVfs = this.opfsVfs; + const unlink = this.opfsUnlink; + T.assert(filename && pVfs && !!unlink); + delete this.opfsDbFile; + delete this.opfsVfs; + delete this.opfsUnlink; + /************************************************************** + ATTENTION CLIENT-SIDE USERS: sqlite3.opfs is NOT intended + for client-side use. It is only for this project's own + internal use. Its APIs are subject to change or removal at + any time. + ***************************************************************/ + const opfs = sqlite3.opfs; + const fSize = this.opfsImportSize; + delete this.opfsImportSize; + let sh; + try{ + T.assert(await opfs.entryExists(filename)); + const [dirHandle, filenamePart] = await opfs.getDirForFilename(filename, false); + const fh = await dirHandle.getFileHandle(filenamePart); + sh = await fh.createSyncAccessHandle(); + T.assert(fSize === await sh.getSize()); + await sh.close(); + sh = undefined; + unlink(); + T.assert(!(await opfs.entryExists(filename))); + }finally{ + if(sh) await sh.close(); + unlink(); + } + + // Some sanity checks of the opfs utility functions... + const testDir = '/sqlite3-opfs-'+opfs.randomFilename(12); + const aDir = testDir+'/test/dir'; + T.assert(await opfs.mkdir(aDir), "mkdir failed") + .assert(await opfs.mkdir(aDir), "mkdir must pass if the dir exists") + .assert(!(await opfs.unlink(testDir+'/test')), "delete 1 should have failed (dir not empty)") + .assert((await opfs.unlink(testDir+'/test/dir')), "delete 2 failed") + .assert(!(await opfs.unlink(testDir+'/test/dir')), + "delete 2b should have failed (dir already deleted)") + .assert((await opfs.unlink(testDir, true)), "delete 3 failed") + .assert(!(await opfs.entryExists(testDir)), + "entryExists(",testDir,") should have failed"); + } + }/*OPFS util sanity checks*/) + ;/* end OPFS tests */ + + //////////////////////////////////////////////////////////////////////// + T.g('OPFS SyncAccessHandle Pool VFS', + (sqlite3)=>(hasOpfs() || "requires OPFS APIs")) + .t({ + name: 'SAH sanity checks', + test: async function(sqlite3){ + T.assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name)) + .assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) < 0) + const inst = sqlite3.installOpfsSAHPoolVfs, + catcher = (e)=>{ + error("Cannot load SAH pool VFS.", + "This might not be a problem,", + "depending on the environment."); + return false; + }; + let u1, u2; + // Ensure that two immediately-consecutive installations + // resolve to the same Promise instead of triggering + // a locking error. + const P1 = inst(sahPoolConfig).then(u=>u1 = u).catch(catcher), + P2 = inst(sahPoolConfig).then(u=>u2 = u).catch(catcher); + await Promise.all([P1, P2]); + if(!(await P1)) return; + T.assert(u1 === u2) + .assert(sahPoolConfig.name === u1.vfsName) + .assert(sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name)) + .assert(u1.getCapacity() >= sahPoolConfig.initialCapacity + /* If a test fails before we get to nuke the VFS, we + can have more than the initial capacity on the next + run. */) + .assert(u1.getCapacity() + 2 === (await u2.addCapacity(2))) + .assert(2 === (await u2.reduceCapacity(2))) + .assert(sqlite3.capi.sqlite3_js_vfs_list().indexOf(sahPoolConfig.name) >= 0); + + T.assert(0 === u1.getFileCount()); + const dbName = '/foo.db'; + let db = new u1.OpfsSAHPoolDb(dbName); + T.assert(db instanceof sqlite3.oo1.DB) + .assert(1 === u1.getFileCount()); + db.exec([ + 'create table t(a);', + 'insert into t(a) values(1),(2),(3)' + ]); + T.assert(1 === u1.getFileCount()); + T.assert(3 === db.selectValue('select count(*) from t')); + db.close(); + T.assert(1 === u1.getFileCount()); + db = new u2.OpfsSAHPoolDb(dbName); + T.assert(1 === u1.getFileCount()); + db.close(); + const fileNames = u1.getFileNames(); + T.assert(1 === fileNames.length) + .assert(dbName === fileNames[0]) + .assert(1 === u1.getFileCount()) + + if(1){ // test exportFile() and importDb() + const dbytes = u1.exportFile(dbName); + T.assert(dbytes.length >= 4096); + const dbName2 = '/exported.db'; + let nWrote = u1.importDb(dbName2, dbytes); + T.assert( 2 == u1.getFileCount() ) + .assert( dbytes.byteLength == nWrote ); + let db2 = new u1.OpfsSAHPoolDb(dbName2); + T.assert(db2 instanceof sqlite3.oo1.DB) + .assert(3 === db2.selectValue('select count(*) from t')); + db2.close(); + T.assert(true === u1.unlink(dbName2)) + .assert(false === u1.unlink(dbName2)) + .assert(1 === u1.getFileCount()) + .assert(1 === u1.getFileNames().length); + // Try again with a function as an input source: + let cursor = 0; + const blockSize = 1024, end = dbytes.byteLength; + const reader = async function(){ + if(cursor >= dbytes.byteLength){ + return undefined; + } + const rv = dbytes.subarray(cursor, cursor+blockSize>end ? end : cursor+blockSize); + cursor += blockSize; + return rv; + }; + nWrote = await u1.importDb(dbName2, reader); + T.assert( 2 == u1.getFileCount() ); + db2 = new u1.OpfsSAHPoolDb(dbName2); + T.assert(db2 instanceof sqlite3.oo1.DB) + .assert(3 === db2.selectValue('select count(*) from t')); + db2.close(); + T.assert(true === u1.unlink(dbName2)) + .assert(dbytes.byteLength == nWrote); + } + + T.assert(true === u1.unlink(dbName)) + .assert(false === u1.unlink(dbName)) + .assert(0 === u1.getFileCount()) + .assert(0 === u1.getFileNames().length); + + // Demonstrate that two SAH pools can coexist so long as + // they have different names. + const conf2 = JSON.parse(JSON.stringify(sahPoolConfig)); + conf2.name += '-test2'; + const POther = await inst(conf2); + //log("Installed second SAH instance as",conf2.name); + T.assert(0 === POther.getFileCount()) + .assert(true === await POther.removeVfs()); + + if(0){ + /* Enable this block to inspect vfs's contents via the dev + console or OPFS Explorer browser extension. The + following bits will remove them. */ + return; + } + T.assert(true === await u2.removeVfs()) + .assert(false === await u1.removeVfs()) + .assert(!sqlite3.capi.sqlite3_vfs_find(sahPoolConfig.name)); + + let cErr, u3; + conf2.$testThrowInInit = new Error("Testing throwing during init."); + conf2.name = sahPoolConfig.name+'-err'; + const P3 = await inst(conf2).then(u=>u3 = u).catch((e)=>cErr=e); + T.assert(P3 === conf2.$testThrowInInit) + .assert(cErr === P3) + .assert(undefined === u3) + .assert(!sqlite3.capi.sqlite3_vfs_find(conf2.name)); + } + }/*OPFS SAH Pool sanity checks*/) + + //////////////////////////////////////////////////////////////////////// + T.g('Bug Reports') + .t({ + name: 'Delete via bound parameter in subquery', + test: function(sqlite3){ + // Testing https://sqlite.org/forum/forumpost/40ce55bdf5 + // with the exception that that post uses "external content" + // for the FTS index. + const db = new sqlite3.oo1.DB();//(':memory:','wt'); + db.exec([ + "create virtual table f using fts5 (path);", + "insert into f(path) values('abc'),('def'),('ghi');" + ]); + const fetchEm = ()=> db.exec({ + sql: "SELECT * FROM f order by path", + rowMode: 'array' + }); + const dump = function(lbl){ + let rc = fetchEm(); + log((lbl ? (lbl+' results') : ''),rc); + }; + //dump('Full fts table'); + let rc = fetchEm(); + T.assert(3===rc.length); + db.exec(` + delete from f where rowid in ( + select rowid from f where path = :path + )`, + {bind: {":path": "def"}} + ); + //dump('After deleting one entry via subquery'); + rc = fetchEm(); + T.assert(2===rc.length) + .assert('abcghi'===rc.join('')); + //log('rc =',rc); + db.close(); + } + }) + ;/*end of Bug Reports group*/; + + //////////////////////////////////////////////////////////////////////// log("Loading and initializing sqlite3 WASM module..."); if(0){ - self.sqlite3ApiConfig = { + globalThis.sqlite3ApiConfig = { debug: ()=>{}, log: ()=>{}, warn: ()=>{}, error: ()=>{} } } - if(!self.sqlite3InitModule && !isUIThread()){ +//#ifnot target=es6-module + if(!globalThis.sqlite3InitModule && !isUIThread()){ /* Vanilla worker, as opposed to an ES6 module worker */ /* If sqlite3.js is in a directory other than this script, in order @@ -2994,27 +3209,32 @@ that's not needed. URL arguments passed as part of the filename via importScripts() - are simply lost, and such scripts see the self.location of + are simply lost, and such scripts see the globalThis.location of _this_ script. */ let sqlite3Js = 'sqlite3.js'; - const urlParams = new URL(self.location.href).searchParams; + const urlParams = new URL(globalThis.location.href).searchParams; if(urlParams.has('sqlite3.dir')){ sqlite3Js = urlParams.get('sqlite3.dir') + '/' + sqlite3Js; } importScripts(sqlite3Js); } - self.sqlite3InitModule.__isUnderTest = +//#endif + globalThis.sqlite3InitModule.__isUnderTest = true /* disables certain API-internal cleanup so that we can test internal APIs from here */; - self.sqlite3InitModule({ + globalThis.sqlite3InitModule({ print: log, printErr: error - }).then(function(sqlite3){ - //console.log('sqlite3 =',sqlite3); + }).then(async function(sqlite3){ log("Done initializing WASM/JS bits. Running tests..."); sqlite3.config.warn("Installing sqlite3 bits as global S for local dev/test purposes."); - self.S = sqlite3; + globalThis.S = sqlite3; + /*await sqlite3.installOpfsSAHPoolVfs(sahPoolConfig) + .then((u)=>log("Loaded",u.vfsName,"VFS")) + .catch(e=>{ + log("Cannot install OpfsSAHPool.",e); + });*/ capi = sqlite3.capi; wasm = sqlite3.wasm; log("sqlite3 version:",capi.sqlite3_libversion(), @@ -3029,7 +3249,7 @@ }else{ logClass('warning',"sqlite3_wasm_test_...() APIs unavailable."); } + log("registered vfs list =",capi.sqlite3_js_vfs_list().join(', ')); TestUtil.runTests(sqlite3); }); })(self); - diff -Nru sqlite3-3.42.0/ext/wasm/tester1-worker.html sqlite3-3.44.0-0/ext/wasm/tester1-worker.html --- sqlite3-3.42.0/ext/wasm/tester1-worker.html 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/tester1-worker.html 2023-11-04 14:23:58.000000000 +0000 @@ -45,7 +45,7 @@ if(urlParams.has('esm')){ logHtml('warning',"Attempting to run an ES6 Worker Module, "+ "which is not supported by all browsers! "+ - "e.g. Firefox (as of 2022-12) cannot do this."); + "e.g. Firefox (as of 2023-05) cannot do this."); workerArgs.push("tester1.mjs",{type:"module"}); document.querySelectorAll('title,#color-target').forEach((e)=>{ e.innerText = "sqlite3 tester #1: ES6 Worker Module"; diff -Nru sqlite3-3.42.0/ext/wasm/version-info.c sqlite3-3.44.0-0/ext/wasm/version-info.c --- sqlite3-3.42.0/ext/wasm/version-info.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/version-info.c 1970-01-01 00:00:00.000000000 +0000 @@ -1,106 +0,0 @@ -/* -** 2022-10-16 -** -** The author disclaims copyright to this source code. In place of a -** legal notice, here is a blessing: -** -** * May you do good and not evil. -** * May you find forgiveness for yourself and forgive others. -** * May you share freely, never taking more than you give. -** -************************************************************************* -** This file simply outputs sqlite3 version information in JSON form, -** intended for embedding in the sqlite3 JS API build. -*/ -#ifdef TEST_VERSION -/*3029003 3039012*/ -#define SQLITE_VERSION "X.Y.Z" -#define SQLITE_VERSION_NUMBER TEST_VERSION -#define SQLITE_SOURCE_ID "dummy" -#else -#include "sqlite3.h" -#endif -#include -#include -static void usage(const char *zAppName){ - puts("Emits version info about the sqlite3 it is built against."); - printf("Usage: %s [--quote] --INFO-FLAG:\n\n", zAppName); - puts(" --version Emit SQLITE_VERSION (3.X.Y)"); - puts(" --version-number Emit SQLITE_VERSION_NUMBER (30XXYYZZ)"); - puts(" --download-version Emit /download.html version number (3XXYYZZ)"); - puts(" --source-id Emit SQLITE_SOURCE_ID"); - puts(" --json Emit all info in JSON form"); - puts("\nThe non-JSON formats may be modified by:\n"); - puts(" --quote Add double quotes around output."); -} - -int main(int argc, char const * const * argv){ - int fJson = 0; - int fVersion = 0; - int fVersionNumber = 0; - int fDlVersion = 0; - int dlVersion = 0; - int fSourceInfo = 0; - int fQuote = 0; - int nFlags = 0; - int i; - - for( i = 1; i < argc; ++i ){ - const char * zArg = argv[i]; - while('-'==*zArg) ++zArg; - if( 0==strcmp("version", zArg) ){ - fVersion = 1; - }else if( 0==strcmp("version-number", zArg) ){ - fVersionNumber = 1; - }else if( 0==strcmp("download-version", zArg) ){ - fDlVersion = 1; - }else if( 0==strcmp("source-id", zArg) ){ - fSourceInfo = 1; - }else if( 0==strcmp("json", zArg) ){ - fJson = 1; - }else if( 0==strcmp("quote", zArg) ){ - fQuote = 1; - --nFlags; - }else{ - printf("Unhandled flag: %s\n", argv[i]); - usage(argv[0]); - return 1; - } - ++nFlags; - } - - if( 0==nFlags ) fJson = 1; - - { - const int v = SQLITE_VERSION_NUMBER; - int ver[4] = {0,0,0,0}; - ver[0] = (v / 1000000) * 1000000; - ver[1] = v % 1000000 / 100 * 1000; - ver[2] = v % 100 * 100; - dlVersion = ver[0] + ver[1] + ver[2] + ver[3]; - } - if( fJson ){ - printf("{\"libVersion\": \"%s\", " - "\"libVersionNumber\": %d, " - "\"sourceId\": \"%s\"," - "\"downloadVersion\": %d}"/*missing newline is intentional*/, - SQLITE_VERSION, - SQLITE_VERSION_NUMBER, - SQLITE_SOURCE_ID, - dlVersion); - }else{ - if(fQuote) printf("%c", '"'); - if( fVersion ){ - printf("%s", SQLITE_VERSION); - }else if( fVersionNumber ){ - printf("%d", SQLITE_VERSION_NUMBER); - }else if( fSourceInfo ){ - printf("%s", SQLITE_SOURCE_ID); - }else if( fDlVersion ){ - printf("%d", dlVersion); - } - if(fQuote) printf("%c", '"'); - puts(""); - } - return 0; -} diff -Nru sqlite3-3.42.0/ext/wasm/wasmfs.make sqlite3-3.44.0-0/ext/wasm/wasmfs.make --- sqlite3-3.42.0/ext/wasm/wasmfs.make 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/ext/wasm/wasmfs.make 2023-11-04 14:23:58.000000000 +0000 @@ -6,14 +6,10 @@ # GNUMakefile. ######################################################################## MAKEFILE.wasmfs := $(lastword $(MAKEFILE_LIST)) +$(warning The WASMFS build is currently incomplete.) -# Maintenance reminder: these particular files cannot be built into a -# subdirectory because loading of the auxiliary -# sqlite3-wasmfs.worker.js file it creates fails if sqlite3-wasmfs.js -# is loaded from any directory other than the one in which the -# containing HTML lives. Similarly, they cannot be loaded from a -# Worker to an Emscripten quirk regarding loading nested Workers. -dir.wasmfs := $(dir.wasm) +#dir.wasmfs := $(dir.wasm) +dir.wasmfs := $(dir.dout) sqlite3-wasmfs.js := $(dir.wasmfs)/sqlite3-wasmfs.js sqlite3-wasmfs.mjs := $(dir.wasmfs)/sqlite3-wasmfs.mjs sqlite3-wasmfs.wasm := $(dir.wasmfs)/sqlite3-wasmfs.wasm @@ -28,105 +24,92 @@ cflags.sqlite3-wasmfs := cflags.sqlite3-wasmfs += -std=c99 -fPIC cflags.sqlite3-wasmfs += -pthread -cflags.sqlite3-wasmfs += $(cflags.speedtest1) -cflags.sqlite3-wasmfs += $(SQLITE_OPT) -DSQLITE_ENABLE_WASMFS +cflags.sqlite3-wasmfs += -DSQLITE_ENABLE_WASMFS ######################################################################## # emcc flags specific to building the final .js/.wasm file... -emcc.flags.sqlite3-wasmfs := -fPIC -emcc.flags.sqlite3-wasmfs += --no-entry -emcc.flags.sqlite3-wasmfs += --minify 0 -emcc.flags.sqlite3-wasmfs += -sMODULARIZE -emcc.flags.sqlite3-wasmfs += -sEXPORT_NAME=$(sqlite3.js.init-func) -emcc.flags.sqlite3-wasmfs += -sSTRICT_JS -emcc.flags.sqlite3-wasmfs += -sDYNAMIC_EXECUTION=0 -emcc.flags.sqlite3-wasmfs += -sNO_POLYFILL -emcc.flags.sqlite3-wasmfs += -sWASM_BIGINT=$(emcc.WASM_BIGINT) -emcc.flags.sqlite3-wasmfs += -sEXPORTED_FUNCTIONS=@$(abspath $(dir.api)/EXPORTED_FUNCTIONS.sqlite3-api) -emcc.flags.sqlite3-wasmfs += -sEXPORTED_RUNTIME_METHODS=FS,wasmMemory,allocateUTF8OnStack +emcc.flags.sqlite3-wasmfs := +emcc.flags.sqlite3-wasmfs += \ + -sEXPORTED_RUNTIME_METHODS=wasmMemory,allocateUTF8OnStack,stringToUTF8OnStack # wasmMemory ==> for -sIMPORTED_MEMORY - # allocateUTF8OnStack ==> wasmfs internals + # *OnStack ==> wasmfs internals (leaky abstraction) emcc.flags.sqlite3-wasmfs += -sUSE_CLOSURE_COMPILER=0 emcc.flags.sqlite3-wasmfs += -Wno-limited-postlink-optimizations # ^^^^^ it likes to warn when we have "limited optimizations" via the -g3 flag. -emcc.flags.sqlite3-wasmfs += -sALLOW_TABLE_GROWTH -emcc.flags.sqlite3-wasmfs += -sSTACK_SIZE=512KB -emcc.flags.sqlite3-wasmfs += -sGLOBAL_BASE=4096 # HYPOTHETICALLY keep func table indexes from overlapping w/ heap addr. emcc.flags.sqlite3-wasmfs += -sMEMORY64=0 -emcc.flags.sqlite3-wasmfs += -sIMPORTED_MEMORY emcc.flags.sqlite3-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128) # ^^^^ 64MB is not enough for WASMFS/OPFS test runs using batch-runner.js sqlite3-wasmfs.fsflags := -pthread -sWASMFS \ - -sPTHREAD_POOL_SIZE=2 -sENVIRONMENT=web,worker \ - -sERROR_ON_UNDEFINED_SYMBOLS=0 -sLLD_REPORT_UNDEFINED + -sPTHREAD_POOL_SIZE=1 \ + -sERROR_ON_UNDEFINED_SYMBOLS=0 -sLLD_REPORT_UNDEFINED # ^^^^^ why undefined symbols are necessary for the wasmfs build is anyone's guess. emcc.flags.sqlite3-wasmfs += $(sqlite3-wasmfs.fsflags) -#emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH +emcc.flags.sqlite3-wasmfs += -sALLOW_MEMORY_GROWTH=0 #^^^ using ALLOW_MEMORY_GROWTH produces a warning from emcc: # USE_PTHREADS + ALLOW_MEMORY_GROWTH may run non-wasm code slowly, # see https://github.com/WebAssembly/design/issues/1271 [-Wpthreads-mem-growth] # And, indeed, it runs slowly if memory is permitted to grow. -emcc.flags.sqlite3-wasmfs.vanilla := -emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META -$(eval $(call call-make-pre-js,sqlite3-wasmfs,vanilla)) -$(eval $(call call-make-pre-js,sqlite3-wasmfs,esm)) -Xemcc.flags.sqlite3-wasmfs.vanilla += \ - $(pre-post-common.flags.vanilla) \ - $(pre-post-sqlite3-wasmfs.flags.vanilla) -Xemcc.flags.sqlite3-wasmfs.esm += \ - $(pre-post-common.flags.esm) \ - $(pre-post-sqlite3-wasmfs.flags.esm) -$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(sqlite3-wasm.c) \ - $(EXPORTED_FUNCTIONS.api) $(MAKEFILE) $(MAKEFILE.wasmfs) -$(sqlite3-wasmfs.js): $(pre-post-sqlite3-wasmfs.deps.vanilla) -$(sqlite3-wasmfs.mjs): $(pre-post-sqlite3-wasmfs.deps.esm) -# SQLITE3-WASMFS.xJS.RECIPE is the wasmfs-specific counterpart -# of SQLITE3.xJS.RECIPE from the main makefile. -define SQLITE3-WASMFS.xJS.RECIPE - @echo "Building $@ ..." - $(emcc.bin) -o $@ $(emcc_opt_full) $(emcc.flags) \ - $(cflags.sqlite3-wasmfs) \ - $(emcc.flags.sqlite3-wasmfs) $(emcc.flags.sqlite3-wasmfs.$(1)) \ - $(pre-post-sqlite3-wasmfs.flags.$(1)) \ - $(sqlite3-wasm.c) - @$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,$(1)) - chmod -x $(sqlite3-wasmfs.wasm) - $(maybe-wasm-strip) $(sqlite3-wasmfs.wasm) - @ls -la $(sqlite3-wasmfs.wasm) sqlite3-wasmfs*js -endef -$(sqlite3-wasmfs.js): - $(call SQLITE3-WASMFS.xJS.RECIPE,vanilla) -$(sqlite3-wasmfs.mjs): $(sqlite3-wasmfs.js) - $(call SQLITE3-WASMFS.xJS.RECIPE,esm) -$(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.js) -wasmfs: $(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs) +#emcc.flags.sqlite3-wasmfs.vanilla := +#emcc.flags.sqlite3-wasmfs.esm := -sEXPORT_ES6 -sUSE_ES6_IMPORT_META +sqlite3-api.mjs.wasmfs := $(dir.tmp)/sqlite3-api-wasmfs.mjs +$(eval $(call SETUP_LIB_BUILD_MODE,sqlite3-wasmfs,esm,1,\ + $(sqlite3-api.mjs.wasmfs), $(sqlite3-wasmfs.mjs),\ + $(c-pp.D.sqlite3-bundler-friendly) -Dwasmfs,\ + -sEXPORT_ES6 -sUSE_ES6_IMPORT_META\ +)) +$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(MAKEFILE.wasmfs) +######################################################################## +# Build quirk: we cannot build BOTH .js and .mjs with our current +# build infrastructure because the supplemental *.worker.js files get +# generated with the name of the main module file +# ($(sqlite3-wasmfs.{js,mjs})) hard-coded in them. Thus the last one +# to get built gets the *.worker.js files mapped to it. In order to +# build both modes they would need to have distinct base names or +# output directories. "The problem" with giving them distinct base +# names is that it means that the corresponding .wasm file is also +# built/saved multiple times. +# +wasmfs.build.ext := mjs +$(sqlite3-wasmfs.js) $(sqlite3-wasmfs.mjs): $(SOAP.js.bld) +ifeq (js,$(wasmfs.build.ext)) + $(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.js) + wasmfs: $(sqlite3-wasmfs.js) +else + $(sqlite3-wasmfs.wasm): $(sqlite3-wasmfs.mjs) + wasmfs: $(sqlite3-wasmfs.mjs) +endif #all: wasmfs ######################################################################## # speedtest1 for wasmfs. -speedtest1-wasmfs.js := $(dir.wasmfs)/speedtest1-wasmfs.js -speedtest1-wasmfs.wasm := $(subst .js,.wasm,$(speedtest1-wasmfs.js)) +speedtest1-wasmfs.mjs := $(dir.wasmfs)/speedtest1-wasmfs.mjs +speedtest1-wasmfs.wasm := $(subst .mjs,.wasm,$(speedtest1-wasmfs.mjs)) emcc.flags.speedtest1-wasmfs := $(sqlite3-wasmfs.fsflags) -emcc.flags.speedtest1-wasmfs += $(SQLITE_OPT) -DSQLITE_ENABLE_WASMFS +emcc.flags.speedtest1-wasmfs += $(SQLITE_OPT) emcc.flags.speedtest1-wasmfs += -sALLOW_MEMORY_GROWTH=0 emcc.flags.speedtest1-wasmfs += -sINITIAL_MEMORY=$(emcc.INITIAL_MEMORY.128) -#$(eval $(call call-make-pre-js,speedtest1-wasmfs,vanilla)) -$(speedtest1-wasmfs.js): $(speedtest1.cses) $(sqlite3-wasmfs.js) \ +#$(eval $(call call-make-pre-js,speedtest1-wasmfs,ems)) +$(speedtest1-wasmfs.mjs): $(speedtest1.cfiles) $(sqlite3-wasmfs.js) \ $(MAKEFILE) $(MAKEFILE.wasmfs) \ - $(pre-post-sqlite3-wasmfs.deps) \ + $(pre-post-sqlite3-wasmfs-esm.deps) \ $(EXPORTED_FUNCTIONS.speedtest1) @echo "Building $@ ..." $(emcc.bin) \ - $(emcc.speedtest1.common) $(emcc.flags.speedtest1-wasmfs) \ - $(pre-post-sqlite3-wasmfs.flags.vanilla) \ + $(pre-post-sqlite3-wasmfs-esm.flags) \ + $(cflags.common) \ $(cflags.sqlite3-wasmfs) \ - -o $@ $(speedtest1.cses) -lm + $(emcc.speedtest1.common) \ + $(emcc.flags.speedtest1-vanilla) \ + $(emcc.flags.sqlite3-wasmfs) \ + $(emcc.flags.speedtest1-wasmfs) \ + -o $@ $(speedtest1.cfiles) -lm + @$(call SQLITE3.xJS.ESM-EXPORT-DEFAULT,1) $(maybe-wasm-strip) $(speedtest1-wasmfs.wasm) + chmod -x $(speedtest1-wasmfs.wasm) ls -la $@ $(speedtest1-wasmfs.wasm) -#speedtest1: $(speedtest1-wasmfs.js) -wasmfs: $(speedtest1-wasmfs.js) -CLEAN_FILES += $(speedtest1-wasmfs.js) $(speedtest1-wasmfs.wasm) \ - $(subst .js,.worker.js,$(speedtest1-wasmfs.js)) +wasmfs: $(speedtest1-wasmfs.mjs) +CLEAN_FILES += $(speedtest1-wasmfs.mjs) $(speedtest1-wasmfs.wasm) \ + $(subst .js,.worker.js,$(speedtest1-wasmfs.mjs)) # end speedtest1.js ######################################################################## diff -Nru sqlite3-3.42.0/main.mk sqlite3-3.44.0-0/main.mk --- sqlite3-3.42.0/main.mk 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/main.mk 2023-11-04 14:23:58.000000000 +0000 @@ -566,6 +566,12 @@ sourcetest: srcck1$(EXE) sqlite3.c ./srcck1 sqlite3.c +src-verify: $(TOP)/tool/src-verify.c + $(BCC) -o src-verify$(EXE) $(TOP)/tool/src-verify.c + +verify-source: ./src-verify + ./src-verify $(TOP) + fuzzershell$(EXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(TCCX) -o fuzzershell$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ $(FUZZERSHELL_OPT) $(TOP)/tool/fuzzershell.c sqlite3.c \ @@ -591,7 +597,17 @@ $(DBFUZZ2_OPTS) $(TOP)/test/dbfuzz2.c sqlite3.c $(TLIBS) $(THREADLIB) fuzzcheck$(EXE): $(FUZZSRC) sqlite3.c sqlite3.h $(FUZZDEP) - $(TCCX) -o fuzzcheck$(EXE) -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ + $(TCCX) -o $@ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ + $(FUZZSRC) sqlite3.c $(TLIBS) $(THREADLIB) + +fuzzcheck-asan$(EXE): $(FUZZSRC) sqlite3.c sqlite3.h $(FUZZDEP) + $(TCCX) -fsanitize=address -o $W -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ + -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ + $(FUZZSRC) sqlite3.c $(TLIBS) $(THREADLIB) + +fuzzcheck-ubsan$(EXE): $(FUZZSRC) sqlite3.c sqlite3.h $(FUZZDEP) + $(TCCX) -fsanitize=undefined -o $@ -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION \ -DSQLITE_ENABLE_MEMSYS5 $(FUZZCHECK_OPT) -DSQLITE_OSS_FUZZ \ $(FUZZSRC) sqlite3.c $(TLIBS) $(THREADLIB) @@ -638,7 +654,7 @@ cp fts5.c fts5.h tsrc touch target_source -sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl +sqlite3.c: target_source $(TOP)/tool/mksqlite3c.tcl src-verify tclsh $(TOP)/tool/mksqlite3c.tcl cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . @@ -650,7 +666,7 @@ sqlite3ext.h: target_source cp tsrc/sqlite3ext.h . -sqlite3.c-debug: target_source $(TOP)/tool/mksqlite3c.tcl +sqlite3.c-debug: target_source $(TOP)/tool/mksqlite3c.tcl src-verify tclsh $(TOP)/tool/mksqlite3c.tcl --linemacros=1 echo '#ifndef USE_SYSTEM_SQLITE' >tclsqlite3.c cat sqlite3.c >>tclsqlite3.c @@ -740,6 +756,7 @@ $(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/misc/zipfile.c \ $(TOP)/ext/misc/memtrace.c \ + $(TOP)/ext/misc/pcachetrace.c \ $(TOP)/ext/recover/dbdata.c \ $(TOP)/ext/recover/sqlite3recover.c \ $(TOP)/ext/recover/sqlite3recover.h \ @@ -910,11 +927,11 @@ queryplantest: testfixture$(EXE) sqlite3$(EXE) ./testfixture$(EXE) $(TOP)/test/permutations.test queryplanner $(TESTOPTS) -fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db +fuzztest: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) ./fuzzcheck$(EXE) $(FUZZDATA) ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db -valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) $(TOP)/test/sessionfuzz-data1.db +valgrindfuzz: fuzzcheck$(EXE) $(FUZZDATA) sessionfuzz$(EXE) valgrind ./fuzzcheck$(EXE) --cell-size-check --limit-mem 10M $(FUZZDATA) valgrind ./sessionfuzz run $(TOP)/test/sessionfuzz-data1.db @@ -933,6 +950,9 @@ # devtest: testfixture$(EXE) fuzztest testrunner +mdevtest: + tclsh $(TOP)/test/testrunner.tcl mdevtest + # A very quick test using only testfixture and omitting all the slower # tests. Designed to run in under 3 minutes on a workstation. # @@ -1117,3 +1137,4 @@ rm -f fts5.* fts5parse.* rm -f lsm.h lsm1.c rm -f threadtest5 + rm -f src-verify diff -Nru sqlite3-3.42.0/Makefile.in sqlite3-3.44.0-0/Makefile.in --- sqlite3-3.42.0/Makefile.in 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/Makefile.in 2023-11-04 14:23:58.000000000 +0000 @@ -57,6 +57,7 @@ # READLINE_FLAGS = -DHAVE_READLINE=@TARGET_HAVE_READLINE@ @TARGET_READLINE_INC@ READLINE_FLAGS += -DHAVE_EDITLINE=@TARGET_HAVE_EDITLINE@ +READLINE_FLAGS += -DHAVE_LINENOISE=@TARGET_HAVE_LINENOISE@ # The library that programs using readline() must link against. # @@ -599,7 +600,7 @@ SHELL_OPT += -DSQLITE_ENABLE_DBSTAT_VTAB SHELL_OPT += -DSQLITE_ENABLE_BYTECODE_VTAB SHELL_OPT += -DSQLITE_ENABLE_OFFSET_SQL_FUNC -FUZZERSHELL_OPT = +FUZZERSHELL_OPT = FUZZCHECK_OPT += -I$(TOP)/test FUZZCHECK_OPT += -I$(TOP)/ext/recover FUZZCHECK_OPT += \ @@ -690,6 +691,12 @@ sourcetest: srcck1$(BEXE) sqlite3.c ./srcck1 sqlite3.c +src-verify: $(TOP)/tool/src-verify.c + $(BCC) -o src-verify$(BEXE) $(TOP)/tool/src-verify.c + +verify-source: ./src-verify + ./src-verify $(TOP) + fuzzershell$(TEXE): $(TOP)/tool/fuzzershell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZERSHELL_OPT) \ $(TOP)/tool/fuzzershell.c sqlite3.c $(TLIBS) @@ -700,6 +707,9 @@ fuzzcheck-asan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) $(LTLINK) -o $@ -fsanitize=address $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) +fuzzcheck-ubsan$(TEXE): $(FUZZCHECK_SRC) sqlite3.c sqlite3.h $(FUZZCHECK_DEP) + $(LTLINK) -o $@ -fsanitize=undefined $(FUZZCHECK_OPT) $(FUZZCHECK_SRC) sqlite3.c $(TLIBS) + ossshell$(TEXE): $(TOP)/test/ossfuzz.c $(TOP)/test/ossshell.c sqlite3.c sqlite3.h $(LTLINK) -o $@ $(FUZZCHECK_OPT) $(TOP)/test/ossshell.c \ $(TOP)/test/ossfuzz.c sqlite3.c $(TLIBS) @@ -759,13 +769,22 @@ $(MPTEST2) --journalmode DELETE +has_tclsh84: + sh $(TOP)/tool/cktclsh.sh 8.4 $(TCLSH_CMD) + touch has_tclsh84 + +has_tclsh85: + sh $(TOP)/tool/cktclsh.sh 8.5 $(TCLSH_CMD) + touch has_tclsh85 + + # This target creates a directory named "tsrc" and fills it with # copies of all of the C source code and header files needed to # build on the target system. Some of the C source code and header # files are automatically generated. This target takes care of # all that automatic generation. # -.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl fts5.c +.target_source: $(SRC) $(TOP)/tool/vdbe-compress.tcl has_tclsh84 fts5.c rm -rf tsrc mkdir tsrc cp -f $(SRC) tsrc @@ -775,15 +794,15 @@ cp fts5.c fts5.h tsrc touch .target_source -sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl +sqlite3.c: .target_source $(TOP)/tool/mksqlite3c.tcl src-verify has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mksqlite3c.tcl $(AMALGAMATION_LINE_MACROS) cp tsrc/sqlite3ext.h . cp $(TOP)/ext/session/sqlite3session.h . -sqlite3r.h: sqlite3.h +sqlite3r.h: sqlite3.h has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) --enable-recover >sqlite3r.h -sqlite3r.c: sqlite3.c sqlite3r.h +sqlite3r.c: sqlite3.c sqlite3r.h has_tclsh84 cp $(TOP)/ext/recover/sqlite3recover.c tsrc/ cp $(TOP)/ext/recover/sqlite3recover.h tsrc/ cp $(TOP)/ext/recover/dbdata.c tsrc/ @@ -798,7 +817,7 @@ echo '#endif /* USE_SYSTEM_SQLITE */' >>tclsqlite3.c cat $(TOP)/src/tclsqlite.c >>tclsqlite3.c -sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl +sqlite3-all.c: sqlite3.c $(TOP)/tool/split-sqlite3c.tcl has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/split-sqlite3c.tcl # Rule to build the amalgamation @@ -1086,10 +1105,10 @@ # Rules to build opcodes.c and opcodes.h # -opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl +opcodes.c: opcodes.h $(TOP)/tool/mkopcodec.tcl has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mkopcodec.tcl opcodes.h >opcodes.c -opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl +opcodes.h: parse.h $(TOP)/src/vdbe.c $(TOP)/tool/mkopcodeh.tcl has_tclsh84 cat parse.h $(TOP)/src/vdbe.c | $(TCLSH_CMD) $(TOP)/tool/mkopcodeh.tcl >opcodes.h # Rules to build parse.c and parse.h - the outputs of lemon. @@ -1100,10 +1119,10 @@ cp $(TOP)/src/parse.y . ./lemon$(BEXE) $(OPT_FEATURE_FLAGS) $(OPTS) -S parse.y -sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION +sqlite3.h: $(TOP)/src/sqlite.h.in $(TOP)/manifest mksourceid$(BEXE) $(TOP)/VERSION has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mksqlite3h.tcl $(TOP) >sqlite3.h -sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION +sqlite3rc.h: $(TOP)/src/sqlite3.rc $(TOP)/VERSION has_tclsh84 echo '#ifndef SQLITE_RESOURCE_VERSION' >$@ echo -n '#define SQLITE_RESOURCE_VERSION ' >>$@ cat $(TOP)/VERSION | $(TCLSH_CMD) $(TOP)/tool/replace.tcl exact . , >>$@ @@ -1133,12 +1152,13 @@ $(TOP)/ext/expert/sqlite3expert.h \ $(TOP)/ext/misc/zipfile.c \ $(TOP)/ext/misc/memtrace.c \ + $(TOP)/ext/misc/pcachetrace.c \ $(TOP)/ext/recover/dbdata.c \ $(TOP)/ext/recover/sqlite3recover.c \ $(TOP)/ext/recover/sqlite3recover.h \ $(TOP)/src/test_windirent.c -shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl +shell.c: $(SHELL_SRC) $(TOP)/tool/mkshellc.tcl has_tclsh84 $(TCLSH_CMD) $(TOP)/tool/mkshellc.tcl >shell.c @@ -1226,7 +1246,7 @@ fts5parse.h: fts5parse.c -fts5.c: $(FTS5_SRC) +fts5.c: $(FTS5_SRC) has_tclsh84 $(TCLSH_CMD) $(TOP)/ext/fts5/tool/mkfts5c.tcl cp $(TOP)/ext/fts5/fts5.h . @@ -1260,7 +1280,7 @@ TESTFIXTURE_SRC = $(TESTSRC) $(TOP)/src/tclsqlite.c TESTFIXTURE_SRC += $(TESTFIXTURE_SRC$(USE_AMALGAMATION)) -testfixture$(TEXE): $(TESTFIXTURE_SRC) +testfixture$(TEXE): has_tclsh85 $(TESTFIXTURE_SRC) $(LTLINK) -DSQLITE_NO_SYNC=1 $(TEMP_STORE) $(TESTFIXTURE_FLAGS) \ -o $@ $(TESTFIXTURE_SRC) $(LIBTCL) $(TLIBS) @@ -1284,11 +1304,17 @@ ./testfixture$(TEXE) $(TOP)/test/full.test # Fuzz testing -fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db +# +# WARNING: When the "fuzztest" target is run by the testrunner.tcl script, +# it does not actually run this code. Instead, it schedules equivalent +# commands. Therefore, if this target is updated, then code in +# testrunner_data.tcl (search for "trd_fuzztest_data") must also be updated. +# +fuzztest: fuzzcheck$(TEXE) $(FUZZDATA) sessionfuzz$(TEXE) ./fuzzcheck$(TEXE) $(FUZZDATA) ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db -valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) $(TOP)/test/sessionfuzz-data1.db +valgrindfuzz: fuzzcheck$(TEXT) $(FUZZDATA) sessionfuzz$(TEXE) valgrind ./fuzzcheck$(TEXE) --cell-size-check --limit-mem 10M $(FUZZDATA) valgrind ./sessionfuzz$(TEXE) run $(TOP)/test/sessionfuzz-data1.db @@ -1305,11 +1331,23 @@ # Runs both fuzztest and testrunner, consecutively. # -devtest: testfixture$(TEXE) fuzztest testrunner +devtest: srctree-check testfixture$(TEXE) fuzztest testrunner + +mdevtest: srctree-check has_tclsh85 + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl mdevtest + +sdevtest: has_tclsh85 + $(TCLSH_CMD) $(TOP)/test/testrunner.tcl sdevtest + +# Validate that various generated files in the source tree +# are up-to-date. +# +srctree-check: $(TOP)/tool/srctree-check.tcl + $(TCLSH_CMD) $(TOP)/tool/srctree-check.tcl # Testing for a release # -releasetest: testfixture$(TEXE) +releasetest: srctree-check testfixture$(TEXE) ./testfixture$(TEXE) $(TOP)/test/testrunner.tcl release # Minimal testing that runs in less than 3 minutes @@ -1320,7 +1358,7 @@ # This is the common case. Run many tests that do not take too long, # including fuzzcheck, sqlite3_analyzer, and sqldiff tests. # -test: fuzztest sourcetest $(TESTPROGS) tcltest +test: srctree-check fuzztest sourcetest $(TESTPROGS) tcltest # Run a test using valgrind. This can take a really long time # because valgrind is so much slower than a native machine. @@ -1338,13 +1376,13 @@ shelltest: $(TESTPROGS) ./testfixture$(TEXT) $(TOP)/test/permutations.test shell -sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in +sqlite3_analyzer.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/spaceanal.tcl $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in has_tclsh85 $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqlite3_analyzer.c.in >sqlite3_analyzer.c sqlite3_analyzer$(TEXE): sqlite3_analyzer.c $(LTLINK) sqlite3_analyzer.c -o $@ $(LIBTCL) $(TLIBS) -sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in +sqltclsh.c: sqlite3.c $(TOP)/src/tclsqlite.c $(TOP)/tool/sqltclsh.tcl $(TOP)/ext/misc/appendvfs.c $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in has_tclsh85 $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/tool/sqltclsh.c.in >sqltclsh.c sqltclsh$(TEXE): sqltclsh.c @@ -1363,7 +1401,7 @@ $(TOP)/ext/misc/btreeinfo.c \ $(TOP)/ext/repair/sqlite3_checker.c.in -sqlite3_checker.c: $(CHECKER_DEPS) +sqlite3_checker.c: $(CHECKER_DEPS) has_tclsh85 $(TCLSH_CMD) $(TOP)/tool/mkccode.tcl $(TOP)/ext/repair/sqlite3_checker.c.in >$@ sqlite3_checker$(TEXE): sqlite3_checker.c @@ -1449,6 +1487,11 @@ snapshot-tarball: sqlite3.c sqlite3rc.h TOP=$(TOP) sh $(TOP)/tool/mkautoconfamal.sh --snapshot +# Build a ZIP archive containing various command-line tools. +# +tool-zip: testfixture sqlite3 sqldiff sqlite3_analyzer $(TOP)/tool/mktoolzip.tcl + ./testfixture $(TOP)/tool/mktoolzip.tcl + # The next two rules are used to support the "threadtest" target. Building # threadtest runs a few thread-safety tests that are implemented in C. This # target is invoked by the releasetest.tcl script. @@ -1506,6 +1549,7 @@ rm -f LogEst$(TEXE) fts3view$(TEXE) rollback-test$(TEXE) showdb$(TEXE) rm -f showjournal$(TEXE) showstat4$(TEXE) showwal$(TEXE) speedtest1$(TEXE) rm -f wordcount$(TEXE) changeset$(TEXE) + rm -f version-info$(TEXT) rm -f sqlite3.dll sqlite3.lib sqlite3.exp sqlite3.def rm -f sqlite3.c rm -f sqlite3rc.h @@ -1521,6 +1565,9 @@ rm -f dbhash dbhash.exe rm -f fts5.* fts5parse.* rm -f threadtest5 + rm -f src-verify + rm -f custom.rws + rm -f has_tclsh84 has_tclsh85 distclean: clean rm -f sqlite_cfg.h config.log config.status libtool Makefile sqlite3.pc \ @@ -1549,3 +1596,28 @@ # fiddle: sqlite3.c shell.c make -C ext/wasm fiddle emcc_opt=-Os + +# +# Spell-checking for source comments +# The sources checked are either C sources or C source templates. +# Their comments are extracted and processed through aspell using +# a custom dictionary that contains scads of odd identifiers that +# find their way into the comments. +# +# Currently, this target is setup to be "made" in-tree only. +# The output is ephemeral. Redirect it to guide spelling fixups, +# either to correct spelling or add words to tool/custom.txt. +# +./custom.rws: ./tool/custom.txt + @echo 'Updating custom dictionary from tool/custom.txt' + aspell --lang=en create master ./custom.rws < $< + +misspell: ./custom.rws has_tclsh84 + $(TCLSH_CMD) ./tool/spellsift.tcl ./src/*.c ./src/*.h ./src/*.in + +# +# tool/version-info: a utility for emitting sqlite3 version info +# in various forms. +# +version-info$(TEXE): $(TOP)/tool/version-info.c Makefile sqlite3.h + $(LTLINK) $(ST_OPT) -o $@ $(TOP)/tool/version-info.c diff -Nru sqlite3-3.42.0/Makefile.linux-gcc sqlite3-3.44.0-0/Makefile.linux-gcc --- sqlite3-3.42.0/Makefile.linux-gcc 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/Makefile.linux-gcc 2023-11-04 14:23:58.000000000 +0000 @@ -22,12 +22,6 @@ BCC = gcc -g -O0 #BCC = /opt/ancic/bin/c89 -0 -#### If the target operating system supports the "usleep()" system -# call, then define the HAVE_USLEEP macro for all C modules. -# -#USLEEP = -USLEEP = -DHAVE_USLEEP=1 - #### If you want the SQLite library to be safe for use within a # multi-threaded program, then define the following macro # appropriately: diff -Nru sqlite3-3.42.0/Makefile.msc sqlite3-3.44.0-0/Makefile.msc --- sqlite3-3.42.0/Makefile.msc 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/Makefile.msc 2023-11-04 14:23:58.000000000 +0000 @@ -52,6 +52,13 @@ USE_STDCALL = 0 !ENDIF +# Use the USE_SEH=0 option on the nmake command line to omit structured +# exception handling (SEH) support. SEH is on by default. +# +!IFNDEF USE_SEH +USE_SEH = 1 +!ENDIF + # Set this non-0 to have the shell executable link against the core dynamic # link library. # @@ -218,6 +225,12 @@ OSTRACE = 0 !ENDIF +# enable address sanitizer using ASAN=1 on the command-line. +# +!IFNDEF ASAN +ASAN = 0 +!ENDIF + # Set this to one of the following values to enable various debugging # features. Each level includes the debugging options from the previous # levels. Currently, the recognized values for DEBUG are: @@ -361,6 +374,7 @@ !IFNDEF OPT_FEATURE_FLAGS !IF $(MINIMAL_AMALGAMATION)==0 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS3=1 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_FTS5=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RTREE=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_GEOPOLY=1 OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_STMTVTAB=1 @@ -389,6 +403,14 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_RBU=1 !ENDIF +# Should structured exception handling (SEH) be enabled for WAL mode in +# the core library? It is on by default. Only omit it if the +# USE_SEH=0 option is provided on the nmake command-line. +# +!IF $(USE_SEH)==0 +OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_OMIT_SEH=1 +!ENDIF + # These are the "extended" SQLite compilation options used when compiling for # the Windows 10 platform. # @@ -877,6 +899,13 @@ !ENDIF !ENDIF + +# Address sanitizer if ASAN=1 +# +!IF $(ASAN)>0 +TCC = $(TCC) /fsanitize=address +!ENDIF + # <> # The locations of the Tcl header and library files. Also, the library that # non-stubs enabled programs using Tcl must link against. These variables @@ -1565,8 +1594,7 @@ $(TOP)\ext\rtree\test_rtreedoc.c \ $(TOP)\ext\recover\sqlite3recover.c \ $(TOP)\ext\recover\test_recover.c \ - $(TOP)\ext\recover\dbdata.c \ - fts5.c + $(TOP)\ext\recover\dbdata.c # If use of zlib is enabled, add the "zipfile.c" source file. # @@ -1582,7 +1610,8 @@ $(SRC01) \ $(SRC07) \ $(SRC10) \ - $(TOP)\ext\async\sqlite3async.c + $(TOP)\ext\async\sqlite3async.c \ + fts5.c # Header files used by all library source files. # @@ -1661,6 +1690,8 @@ SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_FTS4=1 SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_EXPLAIN_COMMENTS=1 SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_OFFSET_SQL_FUNC=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION=1 +SHELL_COMPILE_OPTS = $(SHELL_COMPILE_OPTS) -DSQLITE_ENABLE_STMT_SCANSTATUS=1 !ENDIF # <> @@ -1792,8 +1823,8 @@ /link $(SQLITE3EXEPDB) $(LDFLAGS) $(LTLINKOPTS) $(SHELL_LINK_OPTS) $(LTLIBPATHS) $(LIBRESOBJS) $(LIBREADLINE) $(LTLIBS) $(TLIBS) # <> -sqldiff.exe: $(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H) - $(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) +sqldiff.exe: $(TOP)\tool\sqldiff.c $(SQLITE3C) $(SQLITE3H) $(LIBRESOBJS) + $(LTLINK) $(NO_WARN) $(TOP)\tool\sqldiff.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) $(LIBRESOBJS) dbhash.exe: $(TOP)\tool\dbhash.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(TOP)\tool\dbhash.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -1807,6 +1838,12 @@ sourcetest: srcck1.exe $(SQLITE3C) srcck1.exe $(SQLITE3C) +src-verify.exe: $(TOP)\tool\src-verify.c + $(LTLINK) $(NO_WARN) $(TOP)\tool\src-verify.c + +verify-source: src-verify.exe + src-verify.exe $(TOP) + fuzzershell.exe: $(TOP)\tool\fuzzershell.c $(SQLITE3C) $(SQLITE3H) $(LTLINK) $(NO_WARN) $(FUZZERSHELL_COMPILE_OPTS) $(TOP)\tool\fuzzershell.c $(SQLITE3C) /link $(LDFLAGS) $(LTLINKOPTS) @@ -1870,7 +1907,7 @@ move vdbe.new tsrc\vdbe.c echo > .target_source -sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL) +sqlite3.c: .target_source sqlite3ext.h sqlite3session.h $(MKSQLITE3C_TOOL) src-verify.exe $(TCLSH_CMD) $(MKSQLITE3C_TOOL) $(MKSQLITE3C_ARGS) sqlite3-all.c: sqlite3.c $(TOP)\tool\split-sqlite3c.tcl @@ -2226,8 +2263,8 @@ $(TOP)\src\shell.c.in \ $(TOP)\ext\misc\appendvfs.c \ $(TOP)\ext\misc\completion.c \ - $(TOP)\ext\misc\base64.c \ - $(TOP)\ext\misc\base85.c \ + $(TOP)\ext\misc\base64.c \ + $(TOP)\ext\misc\base85.c \ $(TOP)\ext\misc\decimal.c \ $(TOP)\ext\misc\fileio.c \ $(TOP)\ext\misc\ieee754.c \ @@ -2238,9 +2275,10 @@ $(TOP)\ext\expert\sqlite3expert.c \ $(TOP)\ext\expert\sqlite3expert.h \ $(TOP)\ext\misc\memtrace.c \ - $(TOP)/ext/recover/dbdata.c \ - $(TOP)/ext/recover/sqlite3recover.c \ - $(TOP)/ext/recover/sqlite3recover.h \ + $(TOP)\ext\misc\pcachetrace.c \ + $(TOP)\ext\recover\dbdata.c \ + $(TOP)\ext\recover\sqlite3recover.c \ + $(TOP)\ext\recover\sqlite3recover.h \ $(TOP)\src\test_windirent.c # If use of zlib is enabled, add the "zipfile.c" source file. @@ -2432,6 +2470,9 @@ @set PATH=$(LIBTCLPATH);$(PATH) .\testfixture.exe $(TOP)\test\loadext.test $(TESTOPTS) +tool-zip: testfixture.exe sqlite3.exe sqldiff.exe sqlite3_analyzer.exe $(TOP)\tool\mktoolzip.tcl + .\testfixture.exe $(TOP)\tool\mktoolzip.tcl + coretestprogs: $(TESTPROGS) testprogs: coretestprogs srcck1.exe fuzzcheck.exe sessionfuzz.exe @@ -2484,10 +2525,13 @@ # devtest: testfixture.exe fuzztest testrunner +mdevtest: + $(TCLSH_CMD) $(TOP)\test\testrunner.tcl mdevtest + # Testing for a release # releasetest: testfixture.exe fuzztest - testfixture.exe $(TOP)/test/testrunner.tcl release + testfixture.exe $(TOP)\test\testrunner.tcl release smoketest: $(TESTPROGS) @@ -2515,14 +2559,14 @@ $(LTLINK) $(NO_WARN) $(TOP)\ext\expert\sqlite3expert.c $(TOP)\ext\expert\expert.c $(SQLITE3C) $(TLIBS) CHECKER_DEPS =\ - $(TOP)/tool/mkccode.tcl \ + $(TOP)\tool\mkccode.tcl \ sqlite3.c \ - $(TOP)/src/tclsqlite.c \ - $(TOP)/ext/repair/sqlite3_checker.tcl \ - $(TOP)/ext/repair/checkindex.c \ - $(TOP)/ext/repair/checkfreelist.c \ - $(TOP)/ext/misc/btreeinfo.c \ - $(TOP)/ext/repair/sqlite3_checker.c.in + $(TOP)\src\tclsqlite.c \ + $(TOP)\ext\repair\sqlite3_checker.tcl \ + $(TOP)\ext\repair\checkindex.c \ + $(TOP)\ext\repair\checkfreelist.c \ + $(TOP)\ext\misc\btreeinfo.c \ + $(TOP)\ext\repair\sqlite3_checker.c.in sqlite3_checker.c: $(CHECKER_DEPS) $(TCLSH_CMD) $(TOP)\tool\mkccode.tcl $(TOP)\ext\repair\sqlite3_checker.c.in > $@ @@ -2661,4 +2705,5 @@ del /Q showshm.exe sqlite3_checker.* sqlite3_expert.exe 2>NUL del /Q fts5.* fts5parse.* 2>NUL del /Q lsm.h lsm1.c 2>NUL + del /q src-verify.exe 2>NUL # <> diff -Nru sqlite3-3.42.0/manifest sqlite3-3.44.0-0/manifest --- sqlite3-3.42.0/manifest 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/manifest 2023-11-04 14:23:58.000000000 +0000 @@ -1,28 +1,28 @@ -C Version\s3.42.0 -D 2023-05-16T12:36:15.536 +C Update\sthe\sversion\snumber\sto\s3.44.1 +D 2023-11-02T11:14:43.644 F .fossil-settings/empty-dirs dbb81e8fc0401ac46a1491ab34a7f2c7c0452f2f06b54ebb845d024ca8283ef1 F .fossil-settings/ignore-glob 35175cdfcf539b2318cb04a9901442804be81cd677d8b889fcc9149c21f239ea F LICENSE.md df5091916dbb40e6e9686186587125e1b2ff51f022cc334e886c19a0e9982724 -F Makefile.in 764f2e3e8fb4ae1c8dfe03e65b2b3b01bd1fc57edf78ec2cab3a1301e90e1905 -F Makefile.linux-gcc f609543700659711fbd230eced1f01353117621dccae7b9fb70daa64236c5241 -F Makefile.msc ce7bea7931e1ef96b0f44c0362074a8bb62e61a0e7cfdb05afebd928adaacc2b -F README.md e05bd8fcb45da04ab045c37f79a98654e8aa3b3b8f302cfbba80a0d510df75f7 -F VERSION 17f95ae2fdf21f0e9575eb0b0511ea63f15d71dfff431b21c2b4adbfa70cfbbf +F Makefile.in 8b59912fc1538f96a08555605c5886cdcc733696ae7f22e374b2a4752196ca20 +F Makefile.linux-gcc f3842a0b1efbfbb74ac0ef60e56b301836d05b4d867d014f714fa750048f1ab6 +F Makefile.msc f0cf219350d9af4fba411b4f6306dce2adc897484e8f446de1fb4f40de674d00 +F README.md 963d30019abf0cc06b263cd2824bce022893f3f93a531758f6f04ff2194a16a8 +F VERSION ac9b892c8f54be4e11be490d721ae6a22b0ba83f1a4b247cdda14d82b4d941cc F aclocal.m4 a5c22d164aff7ed549d53a90fa56d56955281f50 F art/sqlite370.eps aa97a671332b432a54e1d74ff5e8775be34200c2 F art/sqlite370.ico af56c1d00fee7cd4753e8631ed60703ed0fc6e90 F art/sqlite370.jpg d512473dae7e378a67e28ff96a34da7cb331def2 F autoconf/INSTALL 83e4a25da9fd053c7b3665eaaaf7919707915903 -F autoconf/Makefile.am a8d1d24affe52ebf8d7ddcf91aa973fa0316618ab95bb68c87cabf8faf527dc8 +F autoconf/Makefile.am adedc1324b6a87fdd1265ddd336d2fb7d4f36a0e77b86ea553ae7cc4ea239347 F autoconf/Makefile.fallback 22fe523eb36dfce31e0f6349f782eb084e86a5620b2b0b4f84a2d6133f53f5ac -F autoconf/Makefile.msc 20366d19fbfc3fceecce95344a2114069eaab4fc22e4f02430da167a1e2ddf04 +F autoconf/Makefile.msc 34f8c222846db1b354720c8a78a4fa7dec9176ea447c0fffdf442b7f74e8b1df F autoconf/README.first 6c4f34fe115ff55d4e8dbfa3cecf04a0188292f7 F autoconf/README.txt 42cfd21d0b19dc7d5d85fb5c405c5f3c6a4c923021c39128f6ba685355d8fd56 F autoconf/configure.ac ec7fa914c5e74ff212fe879f9bb6918e1234497e05facfb641f30c4d5893b277 F autoconf/tea/Makefile.in 106a96f2f745d41a0f6193f1de98d7355830b65d45032c18cd7c90295ec24196 F autoconf/tea/README 3e9a3c060f29a44344ab50aec506f4db903fb873 F autoconf/tea/aclocal.m4 52c47aac44ce0ddb1f918b6993e8beb8eee88f43 -F autoconf/tea/configure.ac e6a7f2abf7a94b5dae00713ad6b3bebc59b878e2705607589830792c61d2ca38 +F autoconf/tea/configure.ac 177be8ff061879dd603bad0b7f15dc34ac93d4052f627e107d03975edeaa1b17 F autoconf/tea/doc/sqlite3.n e1fe45d4f5286ee3d0ccc877aca2a0def488e9bb F autoconf/tea/license.terms 13bd403c9610fd2b76ece0ab50c4c5eda933d523 F autoconf/tea/pkgIndex.tcl.in b9eb6dd37f64e08e637d576b3c83259814b9cddd78bec4af2e5abfc6c5c750ce @@ -33,13 +33,15 @@ F autoconf/tea/win/rules.vc c511f222b80064096b705dbeb97060ee1d6b6d63 F config.guess 883205ddf25b46f10c181818bf42c09da9888884af96f79e1719264345053bd6 F config.sub c2d0260f17f3e4bc0b6808fccf1b291cb5e9126c14fc5890efc77b9fd0175559 -F configure 2f2c090e0a1d051bb53741f0c961f5ebb24507a4f599d686ad6d7ff236144609 x -F configure.ac 4654d32ac0a0d0b48f1e1e79bdc3d777b723cf2f63c33eb1d7c4ed8b435938e8 +F configure 145d7e0db3131586a88c262d59bb943b2f98fcf66a7b7f2008a41925c84485ea x +F configure.ac de31fea7d975bb7ebafbe0e2190a855cc80d48558bf0c9a6578a1836daf1cd3a F contrib/sqlitecon.tcl 210a913ad63f9f991070821e599d600bd913e0ad F doc/F2FS.txt c1d4a0ae9711cfe0e1d8b019d154f1c29e0d3abfe820787ba1e9ed7691160fcd +F doc/compile-for-windows.md 922ba580d210a1f1bd3ef9d0413121556f9b5714fb5c01e664d980f85fa4ac8c F doc/json-enhancements.md e356fc834781f1f1aa22ee300027a270b2c960122468499bf347bb123ce1ea4f -F doc/lemon.html d2862dbef72496e87f7996f37e814b146848190a742c12161d13fd15346051b0 +F doc/lemon.html 44a53a1d2b42d7751f7b2f478efb23c978e258d794bfd172442307a755b9fa44 F doc/pager-invariants.txt 27fed9a70ddad2088750c4a2b493b63853da2710 +F doc/testrunner.md 2434864be2219d4f0b6ffc99d0a2172d531c4ca4345340776f67ad4edd90dc90 F doc/trusted-schema.md 33625008620e879c7bcfbbfa079587612c434fa094d338b08242288d358c3e8a F doc/vdbesort-memory.md 4da2639c14cd24a31e0af694b1a8dd37eaf277aff3867e9a8cc14046bc49df56 F doc/vfs-shm.txt e101f27ea02a8387ce46a05be2b1a902a021d37a @@ -50,33 +52,33 @@ F ext/async/sqlite3async.h 46b47c79357b97ad85d20d2795942c0020dc20c532114a49808287f04aa5309a F ext/expert/README.md b321c2762bb93c18ea102d5a5f7753a4b8bac646cb392b3b437f633caf2020c3 F ext/expert/expert.c d548d603a4cc9e61f446cc179c120c6713511c413f82a4a32b1e1e69d3f086a4 -F ext/expert/expert1.test 95b00567ce0775126a1b788af2d055255014714ecfddc97913864d2f9266e583 -F ext/expert/sqlite3expert.c a912efbad597eafdb0ce934ebc11039f3190b2d479685d89184e107f65d856e1 +F ext/expert/expert1.test 0dd5cb096d66bed593e33053a3b364f6ef52ed72064bf5cf298364636dbf3cd6 +F ext/expert/sqlite3expert.c 90446bb1183429308c68ceb23e00cb8252f43b8886cf5efa3fc7e833b5fa24c8 F ext/expert/sqlite3expert.h ca81efc2679a92373a13a3e76a6138d0310e32be53d6c3bfaedabd158ea8969b F ext/expert/test_expert.c d56c194b769bdc90cf829a14c9ecbc1edca9c850b837a4d0b13be14095c32a72 F ext/fts3/README.content b9078d0843a094d86af0d48dffbff13c906702b4c3558012e67b9c7cc3bf59ee F ext/fts3/README.syntax a19711dc5458c20734b8e485e75fb1981ec2427a F ext/fts3/README.tokenizers b92bdeb8b46503f0dd301d364efc5ef59ef9fa8e2758b8e742f39fa93a2e422d F ext/fts3/README.txt 8c18f41574404623b76917b9da66fcb0ab38328d -F ext/fts3/fts3.c 66d2ced306ac88c39c00d81184f2c60f338696af6ae8cc26ed7c361b157b09f7 +F ext/fts3/fts3.c d01dfb641fc04efeeadcb94d7a8342eb07d71c1a3a3852ec8ab5e64c1fcdfff9 F ext/fts3/fts3.h 3a10a0af180d502cecc50df77b1b22df142817fe -F ext/fts3/fts3Int.h e573c6d881f7238d77cc3fd2396cbb9b2fe13efef7d2ad295a155151c4e7efbd -F ext/fts3/fts3_aux.c f0dc9bd98582615b7750218899bd0c729879b6bbf94d1be57ca1833ff49afc6f +F ext/fts3/fts3Int.h be688580701d41340de73384e3acc8c55be12a438583207444bd5e20f9ef426c +F ext/fts3/fts3_aux.c 7eab82a9cf0830f6551ba3abfdbe73ed39e322a4d3940ee82fbf723674ecd9f3 F ext/fts3/fts3_expr.c 903bfb9433109fffb10e910d7066c49cbf8eeae316adc93f0499c4da7dfc932a F ext/fts3/fts3_hash.c 8b6e31bfb0844c27dc6092c2620bdb1fca17ed613072db057d96952c6bdb48b7 F ext/fts3/fts3_hash.h 39cf6874dc239d6b4e30479b1975fe5b22a3caaf F ext/fts3/fts3_icu.c 305ce7fb6036484085b5556a9c8e62acdc7763f0f4cdf5fd538212a9f3720116 F ext/fts3/fts3_porter.c e19807ce0ae31c1c6e9898e89ecc93183d7ec224ea101af039722a4f49e5f2b8 F ext/fts3/fts3_snippet.c 4d6523e3eddeb7b46e7a82b3476a0a86a0c04821e0e2b8dd40f45ee28057cb13 -F ext/fts3/fts3_term.c f45a1e7c6ef464abb1231245d123dae12266b69e05cc56e14045b76591ae92d1 +F ext/fts3/fts3_term.c 845f0e2456b1be42f7f1bec1da1dfc05bc347531eff90775ffc6698902c281de F ext/fts3/fts3_test.c d8d7b2734f894e8a489987447658e374cdd3a3bc8575c401decf1911cb7c6454 -F ext/fts3/fts3_tokenize_vtab.c a95feda3590f3c3e17672fe35b67ea6112471aeea4c07ef7744a6606b66549aa +F ext/fts3/fts3_tokenize_vtab.c 7fd9ef364f257b97218b9c331f2378e307375c592f70fd541f714e747d944962 F ext/fts3/fts3_tokenizer.c 6d8fc150c48238955d5182bf661498db0dd473c8a2a80e00c16994a646fa96e7 F ext/fts3/fts3_tokenizer.h 64c6ef6c5272c51ebe60fc607a896e84288fcbc3 F ext/fts3/fts3_tokenizer1.c c1de4ae28356ad98ccb8b2e3388a7fdcce7607b5523738c9afb6275dab765154 F ext/fts3/fts3_unicode.c de426ff05c1c2e7bce161cf6b706638419c3a1d9c2667de9cb9dc0458c18e226 F ext/fts3/fts3_unicode2.c 416eb7e1e81142703520d284b768ca2751d40e31fa912cae24ba74860532bf0f -F ext/fts3/fts3_write.c 33d2d0db4dd4e7a7a7e9a7f790414293277f9e7682a2fd9d61c713bfc37cd8b6 +F ext/fts3/fts3_write.c 5bb4721330ca589f906e72bb824dd4080b313c6d4c4231fa541e9db32dc67982 F ext/fts3/fts3speed.tcl b54caf6a18d38174f1a6e84219950d85e98bb1e9 F ext/fts3/tool/fts3cov.sh c331d006359456cf6f8f953e37f2b9c7d568f3863f00bb5f7eb87fea4ac01b73 F ext/fts3/tool/fts3view.c 413c346399159df81f86c4928b7c4a455caab73bfbc8cd68f950f632e5751674 @@ -85,27 +87,27 @@ F ext/fts3/unicode/mkunicode.tcl d5aebf022fa4577ee8cdf27468f0d847879993959101f6dbd6348ef0cfc324a7 F ext/fts3/unicode/parseunicode.tcl a981bd6466d12dd17967515801c3ff23f74a281be1a03cf1e6f52a6959fc77eb F ext/fts5/extract_api_docs.tcl a36e54ec777172ddd3f9a88daf593b00848368e0 -F ext/fts5/fts5.h c132a9323f22a972c4c93a8d5a3d901113a6e612faf30ca8e695788438c5ca2a -F ext/fts5/fts5Int.h ed48a096418ff4a7c02ac9bd1e8d40c46de21b79a132b8b08d3f32233703de7d -F ext/fts5/fts5_aux.c 572d5ec92ba7301df2fea3258576332f2f4d2dfd66d8263afd157d9deceac480 +F ext/fts5/fts5.h 05501612cc655504c5dce8ba765ab621d50fc478490089beaa0d75e00b23e520 +F ext/fts5/fts5Int.h 78a63cc0795186cde5384816a9403a68c65774b35d952e05b81a1b4b158e07c8 +F ext/fts5/fts5_aux.c 35c4101613eff86902877a4dedd9400b07922e412cbdd637b45041dce2fd5388 F ext/fts5/fts5_buffer.c 3001fbabb585d6de52947b44b455235072b741038391f830d6b729225eeaf6a5 -F ext/fts5/fts5_config.c 051056a9052f5d3a4d1c695f996fd364f920e341f136c60ab2c04aa7e267113f -F ext/fts5/fts5_expr.c 58fb8ceddfb1cefcd54510f9f2f33c220ef9d1b3fa77462111f5ae2a825ab7b1 -F ext/fts5/fts5_hash.c d4fb70940359f2120ccd1de7ffe64cc3efe65de9e8995b822cd536ff64c96982 -F ext/fts5/fts5_index.c de3cdae2e0056594aad97a728be5c43b6d7a6cdc7e9cc16f197892b2d8689c21 -F ext/fts5/fts5_main.c b4dba04a36aaf9b8e8cef0100b6dbb422cc74753eacc11d6401cac7a87c0f38d -F ext/fts5/fts5_storage.c 76c6085239eb44424004c022e9da17a5ecd5aaec859fba90ad47d3b08f4c8082 +F ext/fts5/fts5_config.c 054359543566cbff1ba65a188330660a5457299513ac71c53b3a07d934c7b081 +F ext/fts5/fts5_expr.c bd3b81ce669c4104e34ffe66570af1999a317b142c15fccb112de9fb0caa57a6 +F ext/fts5/fts5_hash.c 65e7707bc8774706574346d18c20218facf87de3599b995963c3e6d6809f203d +F ext/fts5/fts5_index.c 730c9c32ada18ce1eb7ff847b36507f4b005d88d47af7b47db521e695a8ea4c7 +F ext/fts5/fts5_main.c a07ed863b8bd9e6fefb62db2fd40a3518eb30a5f7dcfda5be915dd2db45efa2f +F ext/fts5/fts5_storage.c 5d10b9bdcce5b90656cad13c7d12ad4148677d4b9e3fca0481fca56d6601426d F ext/fts5/fts5_tcl.c b1445cbe69908c411df8084a10b2485500ac70a9c747cdc8cda175a3da59d8ae F ext/fts5/fts5_test_mi.c 08c11ec968148d4cb4119d96d819f8c1f329812c568bac3684f5464be177d3ee -F ext/fts5/fts5_test_tok.c a2bed8edb25f6432e8cdb62aad5916935c19dba8dac2b8324950cfff397e25ff +F ext/fts5/fts5_test_tok.c 3cb0a9b508b30d17ef025ccddd26ae3dc8ddffbe76c057616e59a9aa85d36f3b F ext/fts5/fts5_tokenize.c 5e251efb0f1af99a25ed50010ba6b1ad1250aca5921af1988fdcabe5ebc3cb43 F ext/fts5/fts5_unicode2.c eca63dbc797f8ff0572e97caf4631389c0ab900d6364861b915bdd4735973f00 F ext/fts5/fts5_varint.c e64d2113f6e1bfee0032972cffc1207b77af63319746951bf1d09885d1dadf80 -F ext/fts5/fts5_vocab.c 12138e84616b56218532e3e8feb1d3e0e7ae845e33408dbe911df520424dc9d6 +F ext/fts5/fts5_vocab.c aed56169ae5c1aa9b8189c779ffeef04ed516d3c712c06914e6d91a6759f4e4a F ext/fts5/fts5parse.y eb526940f892ade5693f22ffd6c4f2702543a9059942772526eac1fde256bb05 F ext/fts5/mkportersteps.tcl 5acf962d2e0074f701620bb5308155fa1e4a63ba F ext/fts5/test/fts5_common.tcl a9de9c2209cc4e7ae3c753e783504e67206c6c1467d08f209cd0c5923d3e8d8b -F ext/fts5/test/fts5aa.test 5bd43427b7d08ce2e19c488a26534be450538b9232d4d5305049e8de236e9aa9 +F ext/fts5/test/fts5aa.test ba5158eba7d61359becdfca895ef471072c7bf7b20e5e60dcb4d024c8419c926 F ext/fts5/test/fts5ab.test bd932720c748383277456b81f91bc00453de2174f9762cd05f95d0495dc50390 F ext/fts5/test/fts5ac.test a7aa7e1fefc6e1918aa4d3111d5c44a09177168e962c5fd2cca9620de8a7ed6d F ext/fts5/test/fts5ad.test e8cf959dfcd57c8e46d6f5f25665686f3b6627130a9a981371dafdf6482790de @@ -119,8 +121,9 @@ F ext/fts5/test/fts5al.test 00c4c1c6a1366b73aa48ce2068c634520867c3cf7f5d1676ebbb775ee1f35734 F ext/fts5/test/fts5alter.test 5565f7e4605512b69171ac18ca84398603f9f6456dbe377beeca97e83cc242cd F ext/fts5/test/fts5auto.test 78989e6527ce69c9eddbef7392fea5c10b0010cd2b2ae68eec7bc869c471e691 -F ext/fts5/test/fts5aux.test ebf6f2ff7cb556e83f66991b7f12bff016d3c83d4eab36704b649dd6b1437318 +F ext/fts5/test/fts5aux.test 3f194345fcd581f49f7fbb2e5495400efcc7d2835b77816328d8283c942f41b8 F ext/fts5/test/fts5auxdata.test eacc97ff04892f1a5f3d4df5a73f8bcbc3955ea1d12c9f24137eb1fc079e7611 +F ext/fts5/test/fts5bigid.test 2860854c2561a57594192b00c33a29f91cb85e25f3d6c03b5c2b8f62708f39dd F ext/fts5/test/fts5bigpl.test 6466c89b38439f0aba26ac09e232a6b963f29b1cbe1304f6a664fe1e7a8f5fd3 F ext/fts5/test/fts5bigtok.test 541119e616c637caea925a8c028c37c2c29e94383e00aa2f9198d530724b6e36 F ext/fts5/test/fts5cat.test daba0b80659460b0cb60bd1f40b402478a761fe7ea414c3c94c2be25568cc33a @@ -128,23 +131,28 @@ F ext/fts5/test/fts5colset.test 7031ce84fb4d312df5a99fc4e7b324e660ccb513c97eccdef469bfd52d3d0f8f F ext/fts5/test/fts5columnsize.test 45459ce4dd9fd853b6044cdc9674921bff89e3d840f348ca8c1630f9edbf5482 F ext/fts5/test/fts5config.test 60094712debc59286c59aef0e6cf511c37d866802776a825ce437d26afe0817f -F ext/fts5/test/fts5conflict.test 655925678e630d3cdf145d18725a558971806416f453ac8410ca8c04d934238d +F ext/fts5/test/fts5conflict.test bf6030a77dbb1bedfcc42e589ed7980846c995765d77460551e448b56d741244 F ext/fts5/test/fts5connect.test 08030168fc96fc278fa81f28654fb7e90566f33aff269c073e19b3ae9126b2f4 -F ext/fts5/test/fts5content.test 213506436fb2c87567b8e31f6d43ab30aab99354cec74ed679f22aad0cdbf283 -F ext/fts5/test/fts5corrupt.test 77ae6f41a7eba10620efb921cf7dbe218b0ef232b04519deb43581cb17a57ebe -F ext/fts5/test/fts5corrupt2.test 7453752ba12ce91690c469a6449d412561cc604b1dec994e16ab132952e7805f +F ext/fts5/test/fts5content.test 219a4e49386b9b197b9b7cadca97ea10ddff858ecd8b763a1cb8bb07575afc2a +F ext/fts5/test/fts5contentless.test 1cd1237894eeff11feb1ff8180044eac0b17dde22c181f7a722f2dcbfdb3377c +F ext/fts5/test/fts5contentless2.test 14c83bdacf8230f5f7ca74ecf2926b87d8a7cb788a69ce9937020428ac4fe192 +F ext/fts5/test/fts5contentless3.test 353d871c5ea08992aed3e2ebda0b1bdc35116cd24fe330fe7cf05be1e2b49fd7 +F ext/fts5/test/fts5contentless4.test dd33ead36b048c9447b81ec358bd4a27166c49ffaac65a54e95eabf59f338947 +F ext/fts5/test/fts5contentless5.test 96041cbf5ef781a68a5d0f0d18a88030c47a52b156b17876ed6ce36e80e27a7e +F ext/fts5/test/fts5corrupt.test b6d4034b682bb3387bc44c510c71b3c67d4349e4df139490fc0b69e6a972b99f +F ext/fts5/test/fts5corrupt2.test 99e7e23a58b4d89eb7167c6de1669cbc595cd3c79ab333e0eb56405473319e77 F ext/fts5/test/fts5corrupt3.test 7da9895dafa404efd20728f66ff4b94399788bdc042c36fe2689801bba2ccd78 F ext/fts5/test/fts5corrupt4.test f4c08e2182a48d8b70975fd869ee5391855c06d8a0ff87b6a2529e7c5a88a1d3 -F ext/fts5/test/fts5corrupt5.test 550d0884c14424f9acad051a741f1dd99ec9342277d938e91ff3daf9123d1209 +F ext/fts5/test/fts5corrupt5.test eb6ba5ca28ef7c4c6b01e850d388cdb3dacc8c4c2f383f79d0a98128257742b4 F ext/fts5/test/fts5corrupt6.test bf8eeae07825b088b9665d9d8e4accbd8dc9bf3cb85b6c64cf6c9e18ccc420a4 -F ext/fts5/test/fts5corrupt7.test f3e68673af2514e31dd67a2ed163f7f597252ab683dec155b8db0cdc0b668342 +F ext/fts5/test/fts5corrupt7.test 80ad7f683a8bda2404731bb77e8c3dbbb620c1f6cc583cca8239f6accd6338c0 F ext/fts5/test/fts5delete.test 619295b20dbc1d840b403ee07c878f52378849c3c02e44f2ee143b3e978a0aa7 F ext/fts5/test/fts5detail.test 54015e9c43ec4ba542cfb93268abdf280e0300f350efd08ee411284b03595cc4 F ext/fts5/test/fts5determin.test 1b77879b2ae818b5b71c859e534ee334dac088b7cf3ff3bf76a2c82b1c788d11 F ext/fts5/test/fts5dlidx.test b90852c55881b29dbac6380b274de27beae623ac4b6d567c6c8fb9cdc315a86e F ext/fts5/test/fts5doclist.test faa9e9cc3c0645fa6203667cb5f007c359447c6ee66753f71a58175c2497cacd F ext/fts5/test/fts5ea.test b01e3a18cdfabbff8104a96a5242a06a68a998a0 -F ext/fts5/test/fts5eb.test a973baadac524dbbb4ad9b0e99030e12cabde2c6b28e0ac437298007b642cd12 +F ext/fts5/test/fts5eb.test 5f0a86e9fe4715912e6bfa556368aae96d13c61a481373f24daa40429d5d5ca1 F ext/fts5/test/fts5fault1.test d28a65caee75db6897c3cf1358c5230d3bb2a3bf7fb31062c19c7e5382b3d2bd F ext/fts5/test/fts5fault2.test 69c8fdbef830cd0d450908d4504d5bb86609e255af99c421c20a0756251fe344 F ext/fts5/test/fts5fault3.test da2f9e3e56ff5740d68ebdd6877c97089e7ed28ddff28a0da87a6afea27e5522 @@ -158,11 +166,13 @@ F ext/fts5/test/fts5faultB.test d606bdb8e81aaeb6f41de3fc9fc7ae315733f0903fbff05cf54f5b045b729ab5 F ext/fts5/test/fts5faultD.test e7ed7895abfe6bc98a5e853826f6b74956e7ba7f594f1860bbf9e504b9647996 F ext/fts5/test/fts5faultE.test 844586ce71dab4be85bb86880e87b624d089f851654cd22e4710c77eb8ce7075 +F ext/fts5/test/fts5faultF.test 4abef99f86e99d9f0c6460dd68c586a766b6b9f1f660ada55bf2e8266bd1bbc1 +F ext/fts5/test/fts5faultG.test 340e59d2c2c1c7c379224f3968ee8d09b0f64bf56c5194217d1ded887b9d47c4 F ext/fts5/test/fts5first.test 3fcf2365c00a15fc9704233674789a3b95131d12de18a9b996159f6909dc8079 F ext/fts5/test/fts5full.test e1701a112354e0ff9a1fdffb0c940c576530c33732ee20ac5e8361777070d717 F ext/fts5/test/fts5fuzz1.test 238d8c45f3b81342aa384de3e581ff2fa330bf922a7b69e484bbc06051a1080e F ext/fts5/test/fts5hash.test dc7bc7e0cdeb42cfce31294ad2f8fcf43192bfd0145bb7f3ecc5465d8c72696f -F ext/fts5/test/fts5integrity.test 62147a1e85405b986691177e0312be5a64ec9e67b17994e83892d9afa6247600 +F ext/fts5/test/fts5integrity.test 0d249d351163e17e2227aa9850e68193f88a7813d16cc7d51287e554bf915b3d F ext/fts5/test/fts5interrupt.test 09613247b273a99889808ef852898177e671406fe71fdde7ea00e78ea283d227 F ext/fts5/test/fts5lastrowid.test be98fe3e03235296585b72daad7aed5717ba0062bae5e5c18dd6e04e194c6b28 F ext/fts5/test/fts5leftjoin.test c0b4cafb9661379e576dc4405c0891d8fcc2782680740513c4d1fc114b43d4ad @@ -170,13 +180,14 @@ F ext/fts5/test/fts5matchinfo.test 10c9a6f7fe61fb132299c4183c012770b10c4d5c2f2edb6df0b6607f683d737a F ext/fts5/test/fts5merge.test e92a8db28b45931e7a9c7b1bbd36101692759d00274df74d83fd29d25d53b3a6 F ext/fts5/test/fts5merge2.test 3ebad1a59d6ad3fb66eff6523a09e95dc6367cbefb3cd73196801dea0425c8e2 -F ext/fts5/test/fts5misc.test 416ec0ffbc79320a0760ec32d6684866e3ccd3fbce09f9bcd62d9aee4c666b43 +F ext/fts5/test/fts5misc.test 5ca82f2a5ee016b0842043155d1382f98a34d0d86b2791165a44d7807f6e0f54 F ext/fts5/test/fts5multi.test a15bc91cdb717492e6e1b66fec1c356cb57386b980c7ba5af1915f97fe878581 F ext/fts5/test/fts5multiclient.test 5ff811c028d6108045ffef737f1e9f05028af2458e456c0937c1d1b8dea56d45 F ext/fts5/test/fts5near.test 211477940142d733ac04fad97cb24095513ab2507073a99c2765c3ddd2ef58bd F ext/fts5/test/fts5onepass.test f9b7d9b2c334900c6542a869760290e2ab5382af8fbd618834bf1fcc3e7b84da F ext/fts5/test/fts5optimize.test 36a752d24c818792032e4ff502936fc9cc5ef938721696396fdc79214b2717f1 -F ext/fts5/test/fts5optimize2.test c7c97693abe8a2cb572acfb1f252d78f03d3984094cfc5eb2285a76d8a702a92 +F ext/fts5/test/fts5optimize2.test 93e742c36b487d8874621360af5b1ce4d39b04fb9e71ce9bc34015c5fc811785 +F ext/fts5/test/fts5optimize3.test bf9c91bb927d0fb2b9a06318a217a0419183ac5913842e062c7e0b98ea5d0fca F ext/fts5/test/fts5phrase.test 13e5d8e9083077b3d9c74315b3c92ec723cc6eb37c8155e0bfe1bba00559f07b F ext/fts5/test/fts5plan.test b65cfcca9ddd6fdaa118c61e17aeec8e8433bc5b6bb307abd116514f79c49c5a F ext/fts5/test/fts5porter.test 8d08010c28527db66bc3feebd2b8767504aaeb9b101a986342fa7833d49d0d15 @@ -184,27 +195,28 @@ F ext/fts5/test/fts5prefix.test a0fa67b06650f2deaa7bf27745899d94e0fb547ad9ecbd08bfad98c04912c056 F ext/fts5/test/fts5prefix2.test 3847ce46f70b82d61c6095103a9d7c53f2952c40a4704157bc079c04d9c8b18b F ext/fts5/test/fts5query.test ac363b17a442620bb0780e93c24f16a5f963dfe2f23dc85647b869efcfada728 -F ext/fts5/test/fts5rank.test c9fd4a1e36b4fa92d572ec13d846469b97da249d1c2f7fd3ee7e017ce46f2416 +F ext/fts5/test/fts5rank.test 30f29e278cd7fb8831ba4f082feb74d8eb90c463bf07113ae200afc2b467ef32 F ext/fts5/test/fts5rebuild.test 55d6f17715cddbf825680dd6551efbc72ed916d8cf1cde40a46fc5d785b451e7 F ext/fts5/test/fts5restart.test 835ecc8f449e3919f72509ab58056d0cedca40d1fe04108ccf8ac4c2ba41f415 F ext/fts5/test/fts5rowid.test b8790ec170a8dc1942a15aef3db926a5f3061b1ff171013003d8297203a20ad6 -F ext/fts5/test/fts5savepoint.test fc02929f238d02a22df4172625704e029f7c1e0e92e332d654375690f8e6e43f -F ext/fts5/test/fts5secure.test 214a561519d1b1817f146efd1057e2a97cc896e75c2accc77157d874154bda64 +F ext/fts5/test/fts5savepoint.test 050796b24929325cdbbb2fbfe2794816ae95d298e940ae15032200c2f4a73725 +F ext/fts5/test/fts5secure.test a02f771742fb2b1b9bdcb4bf523bcf2d0aa1ff597831d40fe3e72aaa6d0ec40f F ext/fts5/test/fts5secure2.test 2e961d7eef939f294c56b5d895cac7f1c3a60b934ee2cfd5e5e620bdf1ba6bbc F ext/fts5/test/fts5secure3.test c7e1080a6912f2a3ac68f2e05b88b72a99de38543509b2bbf427cac5c9c1c610 F ext/fts5/test/fts5secure4.test 0d10a80590c07891478700af7793b232962042677432b9846cf7fc8337b67c97 F ext/fts5/test/fts5secure5.test c07a68ced5951567ac116c22f2d2aafae497e47fe9fcb6a335c22f9c7a4f2c3a -F ext/fts5/test/fts5secure6.test 7a959d834be6725c641b3c3b38ef86570ea671216ad803e054e4fdff33a72ce2 +F ext/fts5/test/fts5secure6.test 74bf04733cc523bccca519bb03d3b4e2ed6f6e3db7c59bf6be82c88a0ac857fd +F ext/fts5/test/fts5secure7.test fd03d0868d64340a1db8615b02e5508fea409de13910114e4f19eaefc120777a F ext/fts5/test/fts5securefault.test dbca2b6a1c16700017f5051138991b705410889933f2a37c57ae8a23b296b10b F ext/fts5/test/fts5simple.test a298670508c1458b88ce6030440f26a30673931884eb5f4094ac1773b3ba217b F ext/fts5/test/fts5simple2.test 258a1b0c590409bfa5271e872c79572b319d2a56554d0585f68f146a0da603f0 F ext/fts5/test/fts5simple3.test d5c74a9d3ca71bd5dd5cacb7c55b86ea12cdddfc8b1910e3de2995206898380f F ext/fts5/test/fts5synonym.test 1651815b8008de170e8e600dcacc17521d765482ea8f074ae82cfa870d8bb7fb -F ext/fts5/test/fts5synonym2.test b54cce5c34ec08ed616f646635538ae82e34a0e28f947ec60b6fadbc4b3fb17a +F ext/fts5/test/fts5synonym2.test 8f891fc49cc1e8daed727051e77e1f42849c784a6a54bef82564761b2cb3e016 F ext/fts5/test/fts5tok1.test 1f7817499f5971450d8c4a652114b3d833393c8134e32422d0af27884ffe9cef F ext/fts5/test/fts5tok2.test dcacb32d4a2a3f0dd3215d4a3987f78ae4be21a2 F ext/fts5/test/fts5tokenizer.test ac3c9112b263a639fb0508ae73a3ee886bf4866d2153771a8e8a20c721305a43 -F ext/fts5/test/fts5trigram.test c76acc1913a06182e791a0dfdae285b9cdd67327a1a35b34cabf0a6aa09cf05e +F ext/fts5/test/fts5trigram.test 6c4e37864f3e7d90673db5563d9736d7e40080ab94d10ebdffa94c1b77941da0 F ext/fts5/test/fts5ubsan.test 783d5a8d13ebfa169e634940228db54540780e3ba7a87ad1e4510e61440bf64b F ext/fts5/test/fts5umlaut.test a42fe2fe6387c40c49ab27ccbd070e1ae38e07f38d05926482cc0bccac9ad602 F ext/fts5/test/fts5unicode.test 17056f4efe6b0a5d4f41fdf7a7dc9af2873004562eaa899d40633b93dc95f5a9 @@ -224,6 +236,71 @@ F ext/icu/README.txt 7ab7ced8ae78e3a645b57e78570ff589d4c672b71370f5aa9e1cd7024f400fc9 F ext/icu/icu.c c074519b46baa484bb5396c7e01e051034da8884bad1a1cb7f09bbe6be3f0282 F ext/icu/sqliteicu.h fa373836ed5a1ee7478bdf8a1650689294e41d0c89c1daab26e9ae78a32075a8 +F ext/jni/GNUmakefile 5c3ac326bf3853486ebe0d70819abc790cc65c412182ce4ebd5012b008d9b059 +F ext/jni/README.md ef9ac115e97704ea995d743b4a8334e23c659e5534c3b64065a5405256d5f2f4 +F ext/jni/jar-dist.make 030aaa4ae71dd86e4ec5e7c1e6cd86f9dfa47c4592c070d2e35157e42498e1fa +F ext/jni/src/c/sqlite3-jni.c 6f6df9657989e9ca2cfdcc2fe9a71c279de56d5c941adfd09a0f24256de35c8f +F ext/jni/src/c/sqlite3-jni.h b4c413a0d0c734683da1049cfcf89e35ae2719759d0656ec0f8c57188f18cab8 +F ext/jni/src/org/sqlite/jni/annotation/NotNull.java a99341e88154e70447596b1af6a27c586317df41a7e0f246fd41370cd7b723b2 +F ext/jni/src/org/sqlite/jni/annotation/Nullable.java 0b1879852707f752512d4db9d7edd0d8db2f0c2612316ce1c832715e012ff6ba +F ext/jni/src/org/sqlite/jni/annotation/package-info.java 977b374aed9d5853cbf3438ba3b0940abfa2ea4574f702a2448ee143b98ac3ca +F ext/jni/src/org/sqlite/jni/capi/AbstractCollationCallback.java 1afa90d3f236f79cc7fcd2497e111992644f7596fbc8e8bcf7f1908ae00acd6c +F ext/jni/src/org/sqlite/jni/capi/AggregateFunction.java bc29e986c866c2ddbbb9f935f5b7264c1c1026864e50a4a735192864f75e37c0 +F ext/jni/src/org/sqlite/jni/capi/AuthorizerCallback.java 7ed409d5449684616cc924534e22ff6b07d361f12ad904b69ecb10e0568a8013 +F ext/jni/src/org/sqlite/jni/capi/AutoExtensionCallback.java 74cc4998a73d6563542ecb90804a3c4f4e828cb4bd69e61226d1a51f4646e759 +F ext/jni/src/org/sqlite/jni/capi/BusyHandlerCallback.java 7b8e19810c42b0ad21a04b5d8c804b32ee5905d137148703f16a75b612c380ca +F ext/jni/src/org/sqlite/jni/capi/CApi.java bccb442ca81cd4decb1adae99006a60b7a9f54e5153842e738c01104e97d1de0 +F ext/jni/src/org/sqlite/jni/capi/CallbackProxy.java 0bfd6e56e8265c2f05c9207665707285534d78f8466ef0e0430c65677f00943d +F ext/jni/src/org/sqlite/jni/capi/CollationCallback.java e29bcfc540fdd343e2f5cca4d27235113f2886acb13380686756d5cabdfd065a +F ext/jni/src/org/sqlite/jni/capi/CollationNeededCallback.java f81cf10b79c52f9b2e9247d523d29ae48863935f60420eae35f257c38c80ce95 +F ext/jni/src/org/sqlite/jni/capi/CommitHookCallback.java 29c002f3c638cc80f7db1594564a262d1beb32637824c3dca2d60a224d1f71d7 +F ext/jni/src/org/sqlite/jni/capi/ConfigLogCallback.java b995ca412f59b631803b93aa5b3684fce62e335d1e123207084c054abfd488d4 +F ext/jni/src/org/sqlite/jni/capi/ConfigSqllogCallback.java 701f2e4d8bdeb27cfbeeb56315d15b13d8752b0fdbca705f31bd4366c58d8a33 +F ext/jni/src/org/sqlite/jni/capi/NativePointerHolder.java b7036dcb1ef1b39f1f36ac605dde0ff1a24a9a01ade6aa1a605039443e089a61 +F ext/jni/src/org/sqlite/jni/capi/OutputPointer.java 68f60aec7aeb5cd4e5fb83449037f668c63cb99f682ee1036cc226d0cbd909b9 +F ext/jni/src/org/sqlite/jni/capi/PrepareMultiCallback.java aca8f9fa72e3b6602bc9a7dd3ae9f5b2808103fbbee9b2749dc96c19cdc261a1 +F ext/jni/src/org/sqlite/jni/capi/PreupdateHookCallback.java 819d938e26208adde17ca4b7ddde1d8cd6915b6ab7b708249a9787beca6bd6b6 +F ext/jni/src/org/sqlite/jni/capi/ProgressHandlerCallback.java 01bc0c238eed2d5f93c73522cb7849a445cc9098c2ed1e78248fa20ed1cfde5b +F ext/jni/src/org/sqlite/jni/capi/ResultCode.java 8141171f1bcf9f46eef303b9d3c5dc2537a25ad1628f3638398d8a60cacefa7f +F ext/jni/src/org/sqlite/jni/capi/RollbackHookCallback.java 105e324d09c207100485e7667ad172e64322c62426bb49b547e9b0dc9c33f5f0 +F ext/jni/src/org/sqlite/jni/capi/SQLFunction.java fef556adbc3624292423083a648bdf97fa8a4f6b3b6577c9660dd7bd6a6d3c4a +F ext/jni/src/org/sqlite/jni/capi/SQLTester.java 09bee15aa0eedac68d767ae21d9a6a62a31ade59182a3ccbf036d6463d9e30b1 +F ext/jni/src/org/sqlite/jni/capi/ScalarFunction.java 93b9700fca4c68075ccab12fe0fbbc76c91cafc9f368e835b9bd7cd7732c8615 +F ext/jni/src/org/sqlite/jni/capi/TableColumnMetadata.java addf120e0e76e5be1ff2260daa7ce305ff9b5fafd64153a7a28e9d8f000a815f +F ext/jni/src/org/sqlite/jni/capi/Tester1.java ca195521b6bda3e0cd00e76bb71ec8060d1fab76a2f13b1af9feea40789f44bb +F ext/jni/src/org/sqlite/jni/capi/TraceV2Callback.java 0a25e117a0daae3394a77f24713e36d7b44c67d6e6d30e9e1d56a63442eef723 +F ext/jni/src/org/sqlite/jni/capi/UpdateHookCallback.java 2766b8526bbffc4f1045f70e79f1bc1b1efe1c3e95ca06cdb8a7391032dda3b4 +F ext/jni/src/org/sqlite/jni/capi/ValueHolder.java 9f9e151f1da017b706c0ee5f40f4c86b54e773d6ae4339723e0cc85a456251ab +F ext/jni/src/org/sqlite/jni/capi/WindowFunction.java caf4396f91b2567904cf94bc538a069fd62260d975bd037d15a02a890ed1ef9e +F ext/jni/src/org/sqlite/jni/capi/XDestroyCallback.java f3abb8dd7381f53ebba909437090caf68200f06717b8a7d6aa96fa3e8133117d +F ext/jni/src/org/sqlite/jni/capi/package-info.java 08ff986a65d2be9162442c82d28a65ce431d826f188520717c2ecb1484d0a50e +F ext/jni/src/org/sqlite/jni/capi/sqlite3.java 4010bbebc5bf44e2044e610786088cdee7dc155da2b333c0551492ff1cedf33b +F ext/jni/src/org/sqlite/jni/capi/sqlite3_backup.java 6742b431cd4d77e8000c1f92ec66265a58414c86bf3b0b5fbcb1164e08477227 +F ext/jni/src/org/sqlite/jni/capi/sqlite3_blob.java f204ab6ab1263e119fe43730141a00662d80972129a5351dfb11aae5d282df36 +F ext/jni/src/org/sqlite/jni/capi/sqlite3_context.java f0ef982009c335c4393ffcb68051809ca1711e4f47bcb8d1d46952f22c01bc22 +F ext/jni/src/org/sqlite/jni/capi/sqlite3_stmt.java ff579621e9bd5ffbc6b2ef9f996c12db4df6e0c8cc5697c91273e5fca279fcf8 +F ext/jni/src/org/sqlite/jni/capi/sqlite3_value.java e1d62a257c13504b46d39d5c21c49cf157ad73fda00cc5f34c931aa008c37049 +F ext/jni/src/org/sqlite/jni/fts5/Fts5.java e94681023785f1eff5399f0ddc82f46b035977d350f14838db659236ebdf6b41 +F ext/jni/src/org/sqlite/jni/fts5/Fts5Context.java 338637e6e5a2cc385d962b220f3c1f475cc371d12ae43d18ef27327b6e6225f7 +F ext/jni/src/org/sqlite/jni/fts5/Fts5ExtensionApi.java 7da0fbb5728f7c056a43e6407f13dd0c7c9c445221267786a109b987f5fc8a9d +F ext/jni/src/org/sqlite/jni/fts5/Fts5PhraseIter.java 28045042d593a1f1b9b80d54ec77cbf1d8a1bc95e442eceefa9a3a6f56600b0e +F ext/jni/src/org/sqlite/jni/fts5/Fts5Tokenizer.java 3c8f677ffb85b8782f865d6fcbc16200b3375d0e3c29ed541a494fde3011bf49 +F ext/jni/src/org/sqlite/jni/fts5/TesterFts5.java eaee4d641229a098eb704b96a45c9a23c6514dc39009d3611e265bab33834deb +F ext/jni/src/org/sqlite/jni/fts5/XTokenizeCallback.java 1efd1220ea328a32f2d2a1b16c735864159e929480f71daad4de9d5944839167 +F ext/jni/src/org/sqlite/jni/fts5/fts5_api.java a8e88c3783d21cec51b0748568a96653fead88f8f4953376178d9c7385b197ea +F ext/jni/src/org/sqlite/jni/fts5/fts5_extension_function.java 9e2b954d210d572552b28aca523b272fae14bd41e318921b22f65b728d5bf978 +F ext/jni/src/org/sqlite/jni/fts5/fts5_tokenizer.java 92bdaa3893bd684533004d64ade23d329843f809cd0d0f4f1a2856da6e6b4d90 +F ext/jni/src/org/sqlite/jni/test-script-interpreter.md f9f25126127045d051e918fe59004a1485311c50a13edbf18c79a6ff9160030e +F ext/jni/src/org/sqlite/jni/wrapper1/AggregateFunction.java 5ad99bd74c85f56bbef324d9ec29b4048f4620547c9a80093d8586c3557f9f9a +F ext/jni/src/org/sqlite/jni/wrapper1/ScalarFunction.java 43c43adfb7866098aadaaca1620028a6ec82d5193149970019b1cce9eb59fb03 +F ext/jni/src/org/sqlite/jni/wrapper1/SqlFunction.java 004394eeb944baa56e36cd7ae69ba6d4a52b52db3c49439db16e98270b861421 +F ext/jni/src/org/sqlite/jni/wrapper1/Sqlite.java a9ddc6a9e8c113168cc67592ae24c0e56d30dd06226eeab012f2761a0889d7bb +F ext/jni/src/org/sqlite/jni/wrapper1/SqliteException.java 1386f7b753134fc12253ce2fbbc448ba8c970567fac01a3356cb672e14408d73 +F ext/jni/src/org/sqlite/jni/wrapper1/Tester2.java c24b510ebe801c30533cc62efdf69a4a5e2da9ec4b49f8d403f2060693f060a0 +F ext/jni/src/org/sqlite/jni/wrapper1/ValueHolder.java 7b89a7391f771692c5b83b0a5b86266abe8d59f1c77d7a0eccc9b79f259d79af +F ext/jni/src/tests/000-000-sanity.test c3427a0e0ac84d7cbe4c95fdc1cd4b61f9ddcf43443408f3000139478c4dc745 +F ext/jni/src/tests/000-001-ignored.test e17e874c6ab3c437f1293d88093cf06286083b65bf162317f91bbfd92f961b70 +F ext/jni/src/tests/900-001-fts.test bf0ce17a8d082773450e91f2388f5bbb2dfa316d0b676c313c637a91198090f0 F ext/lsm1/Makefile a553b728bba6c11201b795188c5708915cc4290f02b7df6ba7e8c4c943fd5cd9 F ext/lsm1/Makefile.msc f8c878b467232226de288da320e1ac71c131f5ec91e08b21f502303347260013 F ext/lsm1/lsm-test/README 87ea529d2abe615e856d4714bfe8bb185e6c2771b8612aa6298588b7b43e6f86 @@ -264,69 +341,70 @@ F ext/lsm1/lsm_tree.c 682679d7ef2b8b6f2fe77aeb532c8d29695bca671c220b0abac77069de5fb9fb F ext/lsm1/lsm_unix.c 11e0a5c19d754a4e1d93dfad06de8cc201f10f886b8e61a4c599ed34e334fc24 F ext/lsm1/lsm_varint.c fe134ad7b2db1ecd99b6a155d2f3625cfd497730e227ae18892452e457b73327 -F ext/lsm1/lsm_vtab.c e57aa3eb456bf2b98064014027e097c9402d6dec7b59564ddbfa1c0ead8f96c5 +F ext/lsm1/lsm_vtab.c 0bc7d2702150e9d5513118f23fdb5d7f3642884e6c0dde332da08b016857887a F ext/lsm1/lsm_win32.c 0a4acbd7e8d136dd3a5753f0a9e7a9802263a9d96cef3278cf120bcaa724db7c F ext/lsm1/test/lsm1_common.tcl 5ed4bab07c93be2e4f300ebe46007ecf4b3e20bc5fbe1dedaf04a8774a6d8d82 F ext/lsm1/test/lsm1_simple.test a04d08e8661ae6fc53786c67f0bd102c6692f003e859dde03ed9ac3f12e066e5 F ext/lsm1/tool/mklsm1c.tcl f31561bbee5349f0a554d1ad7236ac1991fc09176626f529f6078e07335398b0 F ext/misc/README.md d6dd0fe1d8af77040216798a6a2b0c46c73054d2f0ea544fbbcdccf6f238c240 -F ext/misc/amatch.c e3ad5532799cee9a97647f483f67f43b38796b84b5a8c60594fe782a4338f358 +F ext/misc/amatch.c 5001711cbecdd57b288cb613386789f3034e5beb58fbe0c79f2b3d643ffd4e03 F ext/misc/anycollseq.c 5ffdfde9829eeac52219136ad6aa7cd9a4edb3b15f4f2532de52f4a22525eddb F ext/misc/appendvfs.c 9642c7a194a2a25dca7ad3e36af24a0a46d7702168c4ad7e59c9f9b0e16a3824 F ext/misc/base64.c a71b131e50300c654a66c469a25b62874481f3d1cb3beb56aca9a68edd812e0d F ext/misc/base85.c 073054111988db593ef5fdb87ab8c459df1ea0c3aaaddf0f5bfa3d72b7e6280a F ext/misc/basexx.c 89ad6b76558efbceb627afd5e2ef1d84b2e96d9aaf9b7ecb20e3d00b51be6fcf F ext/misc/blobio.c a867c4c4617f6ec223a307ebfe0eabb45e0992f74dd47722b96f3e631c0edb2a -F ext/misc/btreeinfo.c d28ce349b40054eaa9473e835837bad7a71deec33ba13e39f963d50933bfa0f9 -F ext/misc/carray.c 0ba03f1e6647785d4e05b51be567f5652f06941314ff9d3d3763900aa353b6b5 +F ext/misc/btreeinfo.c cb952620eedf5c0b7625b678f0f08e54d2ec0011d4e50efda5ebdc97f3df7d04 +F ext/misc/carray.c 34fac63770971611c5285de0a9f0ac67d504eaf66be891f637add9290f1c76a5 F ext/misc/carray.h 503209952ccf2431c7fd899ebb92bf46bf7635b38aace42ec8aa1b8d7b6e98a5 F ext/misc/cksumvfs.c 9224e33cc0cb6aa61ff1d7d7b8fd6fe56beca9f9c47954fa4ae0a69bef608f69 -F ext/misc/closure.c dbfd8543b2a017ae6b1a5843986b22ddf99ff126ec9634a2f4047cd14c85c243 -F ext/misc/completion.c 6dafd7f4348eecc7be9e920d4b419d1fb2af75d938cd9c59a20cfe8beb2f22b9 +F ext/misc/closure.c 0e04f52d93e678dd6f950f195f365992edf3c380df246f3d80425cba4c13891e +F ext/misc/completion.c ef78835483b43ac18c96be312b90b615d8368189909be03513ab7a9338131298 F ext/misc/compress.c 3354c77a7c8e86e07d849916000cdac451ed96500bfb5bd83b20eb61eee012c9 -F ext/misc/csv.c ca8d6dafc5469639de81937cb66ae2e6b358542aba94c4f791910d355a8e7f73 +F ext/misc/csv.c 575c2c05fba0a451586a4d42c2c81e711780c41e797126f198d8d9e0a308dcdb F ext/misc/dbdump.c b8592f6f2da292c62991a13864a60d6c573c47a9cc58362131b9e6a64f823e01 -F ext/misc/decimal.c 57d85fa20a5a74d3b0dfc78ab7934ae6c9f5aa8eed915faa2b5246bec87ddc6d +F ext/misc/decimal.c 172cf81a8634e6a0f0bedaf71a8372fee63348cf5a3c4e1b78bb233c35889fdc F ext/misc/eval.c 04bc9aada78c888394204b4ed996ab834b99726fb59603b0ee3ed6e049755dc1 -F ext/misc/explain.c 0086fab288d4352ea638cf40ac382aad3b0dc5e845a1ea829a694c015fd970fe -F ext/misc/fileio.c 4e7f7cd30de8df4820c552f14af3c9ca451c5ffe1f2e7bef34d598a12ebfb720 -F ext/misc/fossildelta.c 1240b2d3e52eab1d50c160c7fe1902a9bd210e052dc209200a750bbf885402d5 -F ext/misc/fuzzer.c eae560134f66333e9e1ca4c8ffea75df42056e2ce8456734565dbe1c2a92bf3d -F ext/misc/ieee754.c 984d51fe23e956484ec1049df6f5257002e3ab338cabceb39761c2e80ad10bf4 -F ext/misc/memstat.c 3017a0832c645c0f8c773435620d663855f04690172316bd127270d1a7523d4d +F ext/misc/explain.c 606100185fb90d6a1eade1ed0414d53503c86820d8956a06e3b0a56291894f2b +F ext/misc/fileio.c d88e60f63557d76d4e38acffda5556b2ab42e98f5d830897f22aba65930d975c +F ext/misc/fossildelta.c 8c026e086e406e2b69947f1856fa3b848fff5379962276430d10085b8756b05a +F ext/misc/fuzzer.c 8b28acf1a7e95d50e332bdd47e792ff27054ad99d3f9bc2e91273814d4b31a5a +F ext/misc/ieee754.c 62a90978204d2c956d5036eb89e548e736ca5fac0e965912867ddd7bb833256d +F ext/misc/memstat.c 5b284b78be431c1f5fa154b18eade2407e42c65ed32ec9e9fbf195d114778d7d F ext/misc/memtrace.c 7c0d115d2ef716ad0ba632c91e05bd119cb16c1aedf3bec9f06196ead2d5537b F ext/misc/memvfs.c 7dffa8cc89c7f2d73da4bd4ccea1bcbd2bd283e3bb4cea398df7c372a197291b -F ext/misc/mmapwarm.c 347caa99915fb254e8949ec131667b7fae99e2a9ce91bd468efb6dc372d9b7a9 +F ext/misc/mmapwarm.c a81af4aaec00f24f308e2f4c19bf1d88f3ac3ce848c36daa7a4cd38145c4080d F ext/misc/nextchar.c 7877914c2a80c2f181dd04c3dbef550dfb54c93495dc03da2403b5dd58f34edd F ext/misc/noop.c 81efe4cad9ec740e64388b14281cb983e6e2c223fed43eb77ab3e34946e0c1ab F ext/misc/normalize.c bd84355c118e297522aba74de34a4fd286fc775524e0499b14473918d09ea61f +F ext/misc/pcachetrace.c f4227ce03fb16aa8d6f321b72dd051097419d7a028a9853af048bee7645cb405 F ext/misc/percentile.c b9086e223d583bdaf8cb73c98a6539d501a2fc4282654adbfea576453d82e691 -F ext/misc/prefixes.c 0f4f8cff5aebc00a7e3ac4021fd59cfe1a8e17c800ceaf592859ecb9cbc38196 -F ext/misc/qpvtab.c 09738419e25f603a35c0ac8bd0a04daab794f48d08a9bc07a6085b9057b99009 +F ext/misc/prefixes.c 82645f79229877afab08c8b08ca1e7fa31921280906b90a61c294e4f540cd2a6 +F ext/misc/qpvtab.c fc189e127f68f791af90a487f4460ec91539a716daf45a0c357e963fd47cc06c F ext/misc/randomjson.c 7dd13664155319d47b9facc0d8dbf45e13062966a47168e54e3f26d48240d7ea F ext/misc/regexp.c 4bdd0045912f81c84908bd535ec5ad3b1c8540b4287c70ab84070963624047db F ext/misc/remember.c add730f0f7e7436cd15ea3fd6a90fd83c3f706ab44169f7f048438b7d6baa69c F ext/misc/rot13.c 51ac5f51e9d5fd811db58a9c23c628ad5f333c173f1fc53c8491a3603d38556c F ext/misc/scrub.c 2a44b0d44c69584c0580ad2553f6290a307a49df4668941d2812135bfb96a946 -F ext/misc/series.c d4001360b2b05a831bbad378e131bd585b29499482e3f2557e86dbd3e2367f25 +F ext/misc/series.c 80692f675de989629ee20796f75010ce87ca826cb383131040e84f7e1bea5d7a F ext/misc/sha1.c 4011aef176616872b2a0d5bccf0ecfb1f7ce3fe5c3d107f3a8e949d8e1e3f08d F ext/misc/shathree.c 543af7ce71d391cd3a9ab6924a6a1124efc63211fd0f2e240dc4b56077ba88ac F ext/misc/showauth.c 732578f0fe4ce42d577e1c86dc89dd14a006ab52 -F ext/misc/spellfix.c 94df9bbfa514a563c1484f684a2df3d128a2f7209a84ca3ca100c68a0163e29f +F ext/misc/spellfix.c c0aa7b80d6df45f7da59d912b38752bcac1af53a5766966160e6c5cdd397dbea F ext/misc/sqlar.c 53e7d48f68d699a24f1a92e68e71eca8b3a9ff991fe9588c2a05bde103c6e7b7 -F ext/misc/stmt.c bc30d60d55e70d0133f10ac6103fe9336543f673740b73946f98758a2bb16dd7 -F ext/misc/templatevtab.c 8a16a91a5ceaccfcbd6aaaa56d46828806e460dd194965b3f77bf38f14b942c4 +F ext/misc/stmt.c b090086cd6bd6281c21271d38d576eeffe662f0e6b67536352ce32bbaa438321 +F ext/misc/templatevtab.c 10f15b165b95423ddef593bc5dcb915ec4eb5e0f1066d585e5435a368b8bc22b F ext/misc/totype.c fa4aedeb07f66169005dffa8de3b0a2b621779fd44f85c103228a42afa71853b F ext/misc/uint.c 053fed3bce2e89583afcd4bf804d75d659879bbcedac74d0fa9ed548839a030b -F ext/misc/unionvtab.c 36237f0607ca954ac13a4a0e2d2ac40c33bc6e032a5f55f431713061ef1625f9 +F ext/misc/unionvtab.c 716d385256d5fb4beea31b0efede640807e423e85c9784d21d22f0cce010a785 F ext/misc/urifuncs.c f71360d14fa9e7626b563f1f781c6148109462741c5235ac63ae0f8917b9c751 F ext/misc/uuid.c 5bb2264c1b64d163efa46509544fd7500cb8769cb7c16dd52052da8d961505cf F ext/misc/vfslog.c 3932ab932eeb2601dbc4447cb14d445aaa9fbe43b863ef5f014401c3420afd20 -F ext/misc/vfsstat.c 474d08efc697b8eba300082cb1eb74a5f0f3df31ed257db1cb07e72ab0e53dfb -F ext/misc/vtablog.c 5538acd0c8ddaae372331bee11608d76973436b77d6a91e8635cfc9432fba5ae +F ext/misc/vfsstat.c a85df08654743922a19410d7b1e3111de41bb7cd07d20dd16eda4e2b808d269d +F ext/misc/vtablog.c f2c9d41afe00b51b2c8307b79f508eb0c2dcd57bae074807944e73376fcf15b7 F ext/misc/vtshim.c 1976e6dd68dd0d64508c91a6dfab8e75f8aaf6cd -F ext/misc/wholenumber.c a838d1bea913c514ff316c69695efbb49ea3b8cb37d22afc57f73b6b010b4546 -F ext/misc/zipfile.c b1f36004c19fb5f949fb166fc4ab88e96a86f66629e9ddb4736a45b63fc3d553 +F ext/misc/wholenumber.c 0fa0c082676b7868bf2fa918e911133f2b349bcdceabd1198bba5f65b4fc0668 +F ext/misc/zipfile.c 64cb3d98b6316586e6056d182051aa9d28fdedfbf4b908e6b7a7d70209b1db11 F ext/misc/zorder.c b0ff58fa643afa1d846786d51ea8d5c4b6b35aa0254ab5a82617db92f3adda64 F ext/rbu/rbu.c 801450b24eaf14440d8fd20385aacc751d5c9d6123398df41b1b5aa804bf4ce8 F ext/rbu/rbu1.test 25870dd7db7eb5597e2b4d6e29e7a7e095abf332660f67d89959552ce8f8f255 @@ -375,13 +453,13 @@ F ext/rbu/sqlite3rbu.c d4ddf8f0e93772556e452a6c2814063cf47efb760a0834391a9d0cd9859fa4b9 F ext/rbu/sqlite3rbu.h 9d923eb135c5d04aa6afd7c39ca47b0d1d0707c100e02f19fdde6a494e414304 F ext/rbu/test_rbu.c ee6ede75147bc081fe9bc3931e6b206277418d14d3fbceea6fdc6216d9b47055 -F ext/recover/dbdata.c 31d580785cf14eb3c20ed6fbb421a10a66569858f837928e6b326088c38d4c72 +F ext/recover/dbdata.c fc7147a68422cbbbaa481ee92ae1752cc25f5a24302bece1c70dcb76345bd736 F ext/recover/recover1.test c484d01502239f11b61f23c1cee9f5dd19fa17617f8974e42e74d64639c524cf F ext/recover/recover_common.tcl a61306c1eb45c0c3fc45652c35b2d4ec19729e340bdf65a272ce4c229cefd85a F ext/recover/recoverbuild.test c74170e0f7b02456af41838afeb5353fdb985a48cc2331d661bbabbca7c6b8e3 F ext/recover/recoverclobber.test 3ba6c0c373c5c63d17e82eced64c05c57ccaf26c1abe1ca7141334022a79f32e F ext/recover/recovercorrupt.test 64c081ad1200ae77b447da99eb724785d6bf71715f394543dc7689642e92bf49 -F ext/recover/recovercorrupt2.test 74bef7dd2d7dd4856f3da21be6e213d27da44827e0f5f0946ca0325b46d163ed +F ext/recover/recovercorrupt2.test b9b974f006340a1300b5a7e687bd6097c5238498181c6f92d87406a77ece430b F ext/recover/recoverfault.test 9d9f88eeb222615a25e7514f234c950d46bee20d24cd8db49d8fff8d650dcfe1 F ext/recover/recoverfault2.test 730e7371bcda769554d15460cb23126abba1be8eca9539ccabf63623e7bb7e09 F ext/recover/recoverold.test 68db3d6f85dd2b98e785b6c4da4f5eea4bbe52ccf6674d9a94c7506dc92596aa @@ -389,12 +467,12 @@ F ext/recover/recoverrowid.test f948bf4024a5f41b0e21b8af80c60564c5b5d78c05a8d64fc00787715ff9f45f F ext/recover/recoverslowidx.test 5205a9742dd9490ee99950dabb622307355ef1662dea6a3a21030057bfd81411 F ext/recover/recoversql.test e66d01f95302a223bcd3fd42b5ee58dc2b53d70afa90b0d00e41e4b8eab20486 -F ext/recover/sqlite3recover.c b3813090c97df34858bab8ece4e8c49d9e2f56ba2b9bb019f57f44bc234b3c6d +F ext/recover/sqlite3recover.c e6eb20c469bcdb96f297f2241860bccabf9f036bfa7f3d47bcc6ca1191b108dc F ext/recover/sqlite3recover.h 011c799f02deb70ab685916f6f538e6bb32c4e0025e79bfd0e24ff9c74820959 F ext/recover/test_recover.c 1a34e2d04533d919a30ae4d5caeb1643f6684e9ccd7597ca27721d8af81f4ade F ext/repair/README.md 92f5e8aae749a4dae14f02eea8e1bb42d4db2b6ce5e83dbcdd6b1446997e0c15 F ext/repair/checkfreelist.c e21f06995ff4efdc1622dcceaea4dcba2caa83ca2f31a1607b98a8509168a996 -F ext/repair/checkindex.c 4383e4469c21e5b9ae321d0d63cec53e981af9d7a6564be6374f0eeb93dfc890 +F ext/repair/checkindex.c af5c66463f51462d8a6f796b2c44ef8cfa1116bbdc35a15da07c67a705388bfd F ext/repair/sqlite3_checker.c.in 445118c5f7fea958b36fba1b2c464283e60ed4842039ddee3265f1698115ebf7 F ext/repair/sqlite3_checker.tcl a9a2caa9660567257c177a91124d8c0dccdfa341e25c51e6da7f1fd9e601eafa F ext/repair/test/README.md 34b2f542cf5be7bffe479242b33ee3492cea30711e447cc4a1a86cb5915f419e @@ -402,19 +480,19 @@ F ext/repair/test/checkindex01.test b530f141413b587c9eb78ff734de6bb79bc3515c335096108c12c01bddbadcec F ext/repair/test/test.tcl 686d76d888dffd021f64260abf29a55c57b2cedfa7fc69150b42b1d6119aac3c F ext/rtree/README 6315c0d73ebf0ec40dedb5aa0e942bc8b54e3761 -F ext/rtree/geopoly.c 971e0b5bd9adaf0811feb8c0842a310811159da10319eb0e74fdb42bf26b99ca -F ext/rtree/rtree.c 925888f7672b326fc2a29b3a212ec3ae4aa2331507ecccfaf7f0ac0335020330 +F ext/rtree/geopoly.c 0dd4775e896cee6067979d67aff7c998e75c2c9d9cd8d62a1a790c09cde7adca +F ext/rtree/rtree.c 2e1452a9338fe4db057fa677277bed86b65c667ed48b9b59144adae99f85a7cb F ext/rtree/rtree.h 4a690463901cb5e6127cf05eb8e642f127012fd5003830dbc974eca5802d9412 -F ext/rtree/rtree1.test d47f58832145fcfed9067bc457ca8664962196c4566c17a1ebd679367db55d11 +F ext/rtree/rtree1.test 2b5b8c719c6a4abe377f57766f428a49af36a93061cb146cccfdc3b30000c0a4 F ext/rtree/rtree2.test 9d9deddbb16fd0c30c36e6b4fdc3ee3132d765567f0f9432ee71e1303d32603d F ext/rtree/rtree3.test 272594f88c344e973864008bbe4c71fd3a41a264c097d568593ee7886d83d409 F ext/rtree/rtree4.test 304de65d484540111b896827e4261815e5dca4ce28eeecd58be648cd73452c4b F ext/rtree/rtree5.test 49c9041d713d54560b315c2c7ef7207ee287eba1b20f8266968a06f2e55d3142 F ext/rtree/rtree6.test 2f5ffc69670395c1a84fad7924e2d49e82a25460c5293fb1e54e1aa906f04945 F ext/rtree/rtree7.test c8fb2e555b128dd0f0bdb520c61380014f497f8a23c40f2e820acc9f9e4fdce5 -F ext/rtree/rtree8.test 2d99006a1386663978c9e1df167554671e4f711c419175b39f332719deb1ce0e +F ext/rtree/rtree8.test 4da84c7f328bbdca15052fa13da6e8b8d426433347bf75fc85574c2f5a411a02 F ext/rtree/rtree9.test fd3c9384ef8aabbc127b3878764070398f136eebc551cd20484b570f2cc1956a -F ext/rtree/rtreeA.test a7fd235d8194115fa2e14d300337931eb2e960fe8a46cdfb66add2206412ea41 +F ext/rtree/rtreeA.test 14e67fccc5b41efbad7ea99d21d11aaa66d2067da7d5b296ee86e4de64391d82 F ext/rtree/rtreeB.test 4cec297f8e5c588654bbf3c6ed0903f10612be8a2878055dd25faf8c71758bc9 F ext/rtree/rtreeC.test 2978b194d09b13e106bdb0e1c5b408b9d42eb338c1082bf43c87ef43bd626147 F ext/rtree/rtreeD.test fe46aa7f012e137bd58294409b16c0d43976c3bb92c8f710481e577c4a1100dc @@ -424,14 +502,14 @@ F ext/rtree/rtreeH.test 0885151ee8429242625600ae47142cca935332c70a06737f35af53a7bd7aaf90 F ext/rtree/rtreeI.test 608e77f7fde9be5a12eae316baef640fffaafcfa90a3d67443e78123e19c4ca4 F ext/rtree/rtree_perf.tcl 6c18c1f23cd48e0f948930c98dfdd37dfccb5195 -F ext/rtree/rtree_util.tcl db734b4c5e75fed6acc56d9701f2235345acfdec750b5fc7b587936f5f6bceed -F ext/rtree/rtreecheck.test 4e859a9cd49d2353ff10c122f72183ec37b400e35d2b0349b2e9696649b6a00e +F ext/rtree/rtree_util.tcl 202ca70df1f0645ef9d5a2170e62d378a28098d9407f0569e85c9c1cf1bd020a +F ext/rtree/rtreecheck.test 934546ad9b563e090ee0c5cbdc69ad014189ad76e5df7320526797a9a345661f F ext/rtree/rtreecirc.test aec664eb21ae943aeb344191407afff5d392d3ae9d12b9a112ced0d9c5de298e F ext/rtree/rtreeconnect.test 225ad3fcb483d36cbee423a25052a6bbae762c9576ae9268332360c68c170d3d -F ext/rtree/rtreedoc.test 27a5703cb1200f6f69051de68da546cef3dfdcf59be73afadfc50b9f9c9960d9 +F ext/rtree/rtreedoc.test d633982d61542f3bc0a0a2df0382a02cc699ac56cbda01130cde6da44a228490 F ext/rtree/rtreedoc2.test 194ebb7d561452dcdc10bf03f44e30c082c2f0c14efeb07f5e02c7daf8284d93 F ext/rtree/rtreedoc3.test 555a878c4d79c4e37fa439a1c3b02ee65d3ebaf75d9e8d96a9c55d66db3efbf8 -F ext/rtree/rtreefuzz001.test 0fc793f67897c250c5fde96cefee455a5e2fb92f4feeabde5b85ea02040790ee +F ext/rtree/rtreefuzz001.test 44f680a23dbe00d1061dbde381d711119099846d166580c4381e402b9d62cb74 F ext/rtree/sqlite3rtree.h 03c8db3261e435fbddcfc961471795cbf12b24e03001d0015b2636b0f3881373 F ext/rtree/test_rtreedoc.c de76b3472bc74b788d079342fdede22ff598796dd3d97acffe46e09228af83a3 F ext/rtree/tkt3363.test 142ab96eded44a3615ec79fba98c7bde7d0f96de @@ -443,7 +521,7 @@ F ext/session/changesetfuzz1.test 2e1b90d888fbf0eea5e1bd2f1e527a48cc85f8e0ff75df1ec4e320b21f580b3a F ext/session/session1.test e94f764fbfb672147c0ef7026b195988133b371dc8cf9e52423eba6cad69717e F ext/session/session2.test ee83bb973b9ce17ccce4db931cdcdae65eb40bbb22089b2fe6aa4f6be3b9303f -F ext/session/session3.test ce9ce3dfa489473987f899e9f6a0f2db9bde3479 +F ext/session/session3.test 2cc1629cfb880243aec1a7251145e07b78411d851b39b2aa1390704550db8e6a F ext/session/session4.test 6778997065b44d99c51ff9cece047ff9244a32856b328735ae27ddef68979c40 F ext/session/session5.test 716bc6fafd625ce60dfa62ae128971628c1a1169 F ext/session/session6.test 35279f2ec45448cd2e24a61688219dc6cf7871757716063acf4a8b5455e1e926 @@ -459,13 +537,16 @@ F ext/session/sessionH.test 71bbff6b1abb2c4ac62b84dee53273c37e0b21e5fde3aed80929403e091ef859 F ext/session/session_common.tcl e5598096425486b363718e2cda48ee85d660c96b4f8ea9d9d7a4c3ef514769da F ext/session/session_speed_test.c dcf0ef58d76b70c8fbd9eab3be77cf9deb8bc1638fed8be518b62d6cbdef88b3 +F ext/session/sessionalter.test 460bdac2832a550519f6bc32e5db2c0cee94f335870aaf25a3a403a81ab20e17 F ext/session/sessionat.test 00c8badb35e43a2f12a716d2734a44d614ff62361979b6b85419035bc04b45ee F ext/session/sessionbig.test 47c381e7acfabeef17d98519a3080d69151723354d220afa2053852182ca7adf F ext/session/sessiondiff.test ad13dd65664bae26744e1f18eb3cbd5588349b7e9118851d8f9364248d67bcec F ext/session/sessionfault.test 573bf027fb870d57bd4e7cf50822a3e4b17b2b923407438747aaa918dec57a09 F ext/session/sessionfault2.test b0d6a7c1d7398a7e800d84657404909c7d385965ea8576dc79ed344c46fbf41c +F ext/session/sessionfault3.test 7c7547202775de268f3fe6f074c4d0d165151829710b4e64f90d4a01645ba9e7 F ext/session/sessioninvert.test 04075517a9497a80d39c495ba6b44f3982c7371129b89e2c52219819bc105a25 F ext/session/sessionmem.test f2a735db84a3e9e19f571033b725b0b2daf847f3f28b1da55a0c1a4e74f1de09 +F ext/session/sessionnoact.test 506526a5fe29421ecc50d371774ef1bb04cbd9d906a8a468f0556cdbde184c22 F ext/session/sessionnoop.test a9366a36a95ef85f8a3687856ebef46983df399541174cb1ede2ee53b8011bc7 F ext/session/sessionnoop2.test de4672dce88464396ec9f30ed08c6c01643a69c53ae540fadbbf6d30642d64e8 F ext/session/sessionrebase.test 702378bdcb5062f1106e74457beca8797d09c113a81768734a58b197b5b334e2 @@ -473,90 +554,94 @@ F ext/session/sessionsize.test 8fcf4685993c3dbaa46a24183940ab9f5aa9ed0d23e5fb63bfffbdb56134b795 F ext/session/sessionstat1.test b039e38e2ba83767b464baf39b297cc0b1cc6f3292255cb467ea7e12d0d0280c F ext/session/sessionwor.test 6fd9a2256442cebde5b2284936ae9e0d54bde692d0f5fd009ecef8511f4cf3fc -F ext/session/sqlite3session.c e50a9218ee360db0a25298adc6614162d80ebe65d3f6a5b0a021e0902f6536a1 -F ext/session/sqlite3session.h 653e9d49c4edae231df8a4c8d69c2145195aedb32462d4b44229dbee7d2680fb -F ext/session/test_session.c 5285482f83cd92b4c1fe12fcf88210566a18312f4f2aa110f6399dae46aeccbb +F ext/session/sqlite3session.c 7b0f9bf6479aebd49e5f34cdaeb1479cde843cf5189bca6f32db4f36c130b414 +F ext/session/sqlite3session.h 4cf19a51975746d7cff2fdd74db8b769c570958e1c3639ac150d824ac1553b3e +F ext/session/test_session.c 7b94ad945cd4afe6c73ee935aeb3d44b4446186e1729362af616c7695a5283d9 F ext/userauth/sqlite3userauth.h 7f3ea8c4686db8e40b0a0e7a8e0b00fac13aa7a3 F ext/userauth/user-auth.txt e6641021a9210364665fe625d067617d03f27b04 F ext/userauth/userauth.c 7f00cded7dcaa5d47f54539b290a43d2e59f4b1eb5f447545fa865f002fc80cb F ext/wasm/EXPORTED_FUNCTIONS.fiddle.in 27450c8b8c70875a260aca55435ec927068b34cef801a96205adb81bdcefc65c -F ext/wasm/GNUmakefile 38700d5074af690f004e4e5f3533164ab49693b9d0832929c4ecf97a0bc09494 +F ext/wasm/GNUmakefile 0e362f3fc04eab6628cbe4f1e35f4ab4a200881f6b5f753b27fb45eabeddd9d2 F ext/wasm/README-dist.txt 6382cb9548076fca472fb3330bbdba3a55c1ea0b180ff9253f084f07ff383576 -F ext/wasm/README.md ef39861aa21632fdbca0bdd469f78f0096f6449a720f3f39642594af503030e9 +F ext/wasm/README.md a8a2962c3aebdf8d2104a9102e336c5554e78fc6072746e5daf9c61514e7d193 +F ext/wasm/SQLTester/GNUmakefile e0794f676d55819951bbfae45cc5e8d7818dc460492dc317ce7f0d2eca15caff +F ext/wasm/SQLTester/SQLTester.mjs ec2f6ba63a0f2f0562941a0fb8e46b7dc55589711513f1952349785966edfe50 +F ext/wasm/SQLTester/SQLTester.run.mjs c72b7fe2072d05992f7a3d8c6a1d34e95712513ceabe40849784e24e41c84638 +F ext/wasm/SQLTester/index.html 3f8a016df0776be76605abf20e815ecaafbe055abac0e1fe5ea080e7846b760d +F ext/wasm/SQLTester/touint8array.c 2d5ece04ec1393a6a60c4bf96385bda5e1a10ad49f3038b96460fc5e5aa7e536 F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-api d6a5078f48a5301ed17b9a30331075d9b2506e1360c1f0dee0c7816c10acd9ab F ext/wasm/api/EXPORTED_FUNCTIONS.sqlite3-see fb29e62082a658f0d81102488414d422c393c4b20cc2f685b216bc566237957b F ext/wasm/api/EXPORTED_RUNTIME_METHODS.sqlite3-api 1ec3c73e7d66e95529c3c64ac3de2470b0e9e7fbf7a5b41261c367cf4f1b7287 -F ext/wasm/api/README.md 77a2f1f2fc60a35def7455dffc8d3f2c56385d6ac5c6cecc60fa938252ea2c54 -F ext/wasm/api/extern-post-js.c-pp.js 393ab78b807da94096eae1a68bfddb999a2299936a185d910162fe87a57a9a3a +F ext/wasm/api/README.md 5eb44fa02e9c693a1884a3692428647894b0380b24bca120866b7a24c8786134 +F ext/wasm/api/extern-post-js.c-pp.js c4154a7f90c2d7e51fd6738273908152036c3457fdc0b6523f1be3ef51105aac F ext/wasm/api/extern-pre-js.js cc61c09c7a24a07dbecb4c352453c3985170cec12b4e7e7e7a4d11d43c5c8f41 F ext/wasm/api/post-js-footer.js cd0a8ec768501d9bd45d325ab0442037fb0e33d1f3b4f08902f15c34720ee4a1 F ext/wasm/api/post-js-header.js 47b6b281f39ad59fa6e8b658308cd98ea292c286a68407b35ff3ed9cfd281a62 F ext/wasm/api/pre-js.c-pp.js ad906703f7429590f2fbf5e6498513bf727a1a4f0ebfa057afb08161d7511219 -F ext/wasm/api/sqlite3-api-cleanup.js cc21e3486da748463e02bbe51e2464c6ac136587cdfd5aa00cd0b5385f6ca808 -F ext/wasm/api/sqlite3-api-glue.js f1b2dcb944de5138bb5bd9a1559d2e76a4f3ec25260963d709e8237476688803 -F ext/wasm/api/sqlite3-api-oo1.js 2691a34a741015127b210954a1b9586764d3ff0c8a20f00fd15c00f339ecc79f -F ext/wasm/api/sqlite3-api-prologue.js 17f4ec398ba34c5c666fea8e8c4eb82064a35b302f2f2eb355283cd8d3f68ed5 -F ext/wasm/api/sqlite3-api-worker1.js 40a5b1813fcbe789f23ae196c833432c8c83e7054d660194ddfc51eab1c5b9bf +F ext/wasm/api/sqlite3-api-cleanup.js d235ad237df6954145404305040991c72ef8b1881715d2a650dda7b3c2576d0e +F ext/wasm/api/sqlite3-api-glue.js 26aedfb27915f4f316f6eac84078443e4f0d2dfe5f012310014923ed4b77b2b6 +F ext/wasm/api/sqlite3-api-oo1.js 9678dc4d9a5d39632b6ffe6ea94a023119260815bf32f265bf5f6c36c9516db8 +F ext/wasm/api/sqlite3-api-prologue.js 9aeba7b45cf41b3a26d34d7fb2525633cd1adfc544888c1ea8dbb077496f4ce9 +F ext/wasm/api/sqlite3-api-worker1.js f941382f21006b4a817754184e2661b0a63ce650201f3419cd60f4758b6fd60e F ext/wasm/api/sqlite3-license-version-header.js 0c807a421f0187e778dc1078f10d2994b915123c1223fe752b60afdcd1263f89 -F ext/wasm/api/sqlite3-opfs-async-proxy.js 70914ae97784d3028150bbf252e07a423056c42cc345903c81b5fae661ce512f -F ext/wasm/api/sqlite3-v-helper.js e5c202a9ecde9ef818536d3f5faf26c03a1a9f5192b1ddea8bdabf30d75ef487 -F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 89640e4874a60cb2d973306b272384ffb45c7915375c7bb0355c7586f88dc39c -F ext/wasm/api/sqlite3-wasi.h 25356084cfe0d40458a902afb465df8c21fc4152c1d0a59b563a3fba59a068f9 -F ext/wasm/api/sqlite3-wasm.c 12a096d8e58a0af0589142bae5a3c27a0c7e19846755a1a37d2c206352fbedda -F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js 2710a06a59620c6bf7ce298ab1fb6c9ce825b9f9379728b74c486db6613beecc -F ext/wasm/api/sqlite3-worker1.c-pp.js da509469755035e919c015deea41b4514b5e84c12a1332e6cc8d42cb2cc1fb75 +F ext/wasm/api/sqlite3-opfs-async-proxy.js 8cf8a897726f14071fae6be6648125162b256dfb4f96555b865dbb7a6b65e379 +F ext/wasm/api/sqlite3-v-helper.js 7daa0eab0a513a25b05e9abae7b5beaaa39209b3ed12f86aeae9ef8d2719ed25 +F ext/wasm/api/sqlite3-vfs-opfs-sahpool.c-pp.js 595953994aa3ae2287c889c4da39ab3d6f17b6461ecf4bec334b7a3faafddb02 +F ext/wasm/api/sqlite3-vfs-opfs.c-pp.js 46c4afa6c50d7369252c104f274ad977a97e91ccfafc38b400fe36e90bdda88e +F ext/wasm/api/sqlite3-wasm.c 038de1b6d40b2cc0f41a143a0451db60b2a6f1b5bc06de67da255c54ea1661b7 +F ext/wasm/api/sqlite3-worker1-promiser.c-pp.js bc06df0d599e625bde6a10a394e326dc68da9ff07fa5404354580f81566e591f +F ext/wasm/api/sqlite3-worker1.c-pp.js a541112aa51e16705f13a99bb943c64efe178aa28c86704a955f8fd9afe4ba37 F ext/wasm/batch-runner.html 4deeed44fe41496dc6898d9fb17938ea3291f40f4bfb977e29d0cef96fbbe4c8 F ext/wasm/batch-runner.js 0dad6a02ad796f1003d3b7048947d275c4d6277f63767b8e685c27df8fdac93e F ext/wasm/c-pp.c 6d80d8569d85713effe8b0818a3cf51dc779e3f0bf8dc88771b8998552ee25b4 -F ext/wasm/common/SqliteTestUtil.js d8bf97ecb0705a2299765c8fc9e11b1a5ac7f10988bbf375a6558b7ca287067b +F ext/wasm/common/SqliteTestUtil.js 7adaeffef757d8708418dc9190f72df22367b531831775804b31598b44f6aa51 F ext/wasm/common/emscripten.css 11bd104b6c0d597c67d40cc8ecc0a60dae2b965151e3b6a37fa5708bac3acd15 -F ext/wasm/common/testing.css 0ff15602a3ab2bad8aef2c3bd120c7ee3fd1c2054ad2ace7e214187ae68d926f -F ext/wasm/common/whwasmutil.js 749a1f81f85835e9a384e9706f2a955a7158f2b8cc9da33f41105cac7775a305 +F ext/wasm/common/testing.css e97549bab24126c24e0daabfe2de9bb478fb0a69fdb2ddd0a73a992c091aad6f +F ext/wasm/common/whwasmutil.js 4c64594eecc7af4ae64259e95a71ba2a7edf118881aaff0bba86d0c7164e78e4 F ext/wasm/demo-123-worker.html a0b58d9caef098a626a1a1db567076fca4245e8d60ba94557ede8684350a81ed F ext/wasm/demo-123.html 8c70a412ce386bd3796534257935eb1e3ea5c581e5d5aea0490b8232e570a508 -F ext/wasm/demo-123.js ebae30756585bca655b4ab2553ec9236a87c23ad24fc8652115dcedb06d28df6 +F ext/wasm/demo-123.js 38aa8faec4d0ace1c973bc8a7a1533584463ebeecd4c420daa7d9687beeb9cb5 F ext/wasm/demo-jsstorage.html 409c4be4af5f207fb2877160724b91b33ea36a3cd8c204e8da1acb828ffe588e F ext/wasm/demo-jsstorage.js 44e3ae7ec2483b6c511384c3c290beb6f305c721186bcf5398ca4e00004a06b8 F ext/wasm/demo-worker1-promiser.html 1de7c248c7c2cfd4a5783d2aa154bce62d74c6de98ab22f5786620b3354ed15f -F ext/wasm/demo-worker1-promiser.js 51b02509a109e82f623fb4c900c8b48b9a77cc13fbd038396f9a083b86593ae3 +F ext/wasm/demo-worker1-promiser.js 5e5c7d7c91cd7aae9cc733afd02569ba9c6928292db413b550e8b842f4b75e87 F ext/wasm/demo-worker1.html 2c178c1890a2beb5a5fecb1453e796d067a4b8d3d2a04d65ca2eb1ab2c68ef5d -F ext/wasm/demo-worker1.js 2c7794d8bc4ab9ecf9cdc2c15de940b11a006942226e441ea41edd458dfc0a26 -F ext/wasm/dist.make 451fb1b732257849f6e898d2a862512a0401500ed369ef53bdfeddf9c77bc3b9 +F ext/wasm/demo-worker1.js 836bece8615b17b1b572584f7b15912236a5947fe8c68b98d2737d7e287447ef +F ext/wasm/dist.make 3a851858aad72e246a5d9c5aaf6b6a144305f1bf898ac1846760ea7bab95c9a3 F ext/wasm/example_extra_init.c 2347cd69d19d839ef4e5e77b7855103a7fe3ef2af86f2e8c95839afd8b05862f -F ext/wasm/fiddle.make dbe36b90b8907ae28ecb9c0e9fd8389dbdaecf117ea4fb2ea33864bdfa498a94 +F ext/wasm/fiddle.make fa2ba6e90457ba2a71cb745f200d409caf773076df75ae5b177cc225d7627a11 F ext/wasm/fiddle/emscripten.css 3d253a6fdb8983a2ac983855bfbdd4b6fa1ff267c28d69513dd6ef1f289ada3f -F ext/wasm/fiddle/fiddle-worker.js 163d6139a93fab4bcb72064923df050d4e7c0ff0d8aa061ce8776a6e75da8a10 +F ext/wasm/fiddle/fiddle-worker.js e0153f9af6500805c6f09c0b3cfdb7d857e9d6863dbee9d50d1628fccf5f4b4d F ext/wasm/fiddle/fiddle.js 974b995119ac443685d7d94d3b3c58c6a36540e9eb3fed7069d5653284071715 F ext/wasm/fiddle/index.html 5daf54e8f3d7777cbb1ca4f93affe28858dbfff25841cb4ab81d694efed28ec2 F ext/wasm/index-dist.html 22379774f0ad4edcaaa8cf9c674c82e794cc557719a8addabed74eb8069d412e -F ext/wasm/index.html dd900891844caebd9cadbddd704f66bd841d7c12fd69ce5af490e2c10fb49f45 -F ext/wasm/jaccwabyt/jaccwabyt.js 8287c0537fa0750414edbe75ce64668a81c8716df5ec4c3e6bb4f11bd1c36031 +F ext/wasm/index.html 4e7847b909f4ae0da8c829b150b79454050e53b3658431f138636257729cd42b +F ext/wasm/jaccwabyt/jaccwabyt.js 1264710db3cfbcb6887d95665b7aeba60c1126eaef789ca4cf1a4a17d5bc7f54 F ext/wasm/jaccwabyt/jaccwabyt.md 37911f00db12cbcca73aa1ed72594430365f30aafae2fa9c886961de74e5e0eb -F ext/wasm/module-symbols.html 841de62fc198988b8330e238c260e70ec93028b096e1a1234db31b187a899d10 -F ext/wasm/scratchpad-wasmfs-main.html 20cf6f1a8f368e70d01e8c17200e3eaa90f1c8e1029186d836d14b83845fbe06 -F ext/wasm/scratchpad-wasmfs-main.js 4c140457f4d6da9d646a49addd91edb6e9ad1643c6c48e3258b5bce24725dc18 -F ext/wasm/speedtest1-wasmfs.html 7a301f4f5b6ad4f5d37fd6e7ca03a2f5d5547fd289da60a39075a93d7646d354 -F ext/wasm/speedtest1-worker.html 82869822e641c1bef3ec0cd2d7d2b6a42d0b4f68a7b160fb2e1dd0b523940a9b -F ext/wasm/speedtest1-worker.js 13b57c4a41729678a1194014afec2bd5b94435dcfc8d1039dfa9a533ac819ee1 +F ext/wasm/module-symbols.html dc476b403369b26a1a23773e13b80f41b9a49f0825e81435fe3600a7cfbbe337 +F ext/wasm/scratchpad-wasmfs.html a3d7388f3c4b263676b58b526846e9d02dfcb4014ff29d3a5040935286af5b96 +F ext/wasm/scratchpad-wasmfs.mjs 66034b9256b218de59248aad796760a1584c1dd842231505895eff00dbd57c63 +F ext/wasm/speedtest1-wasmfs.html 0e9d335a9b5b5fafe6e1bc8dc0f0ca7e22e6eb916682a2d7c36218bb7d67379d +F ext/wasm/speedtest1-wasmfs.mjs ac5cadbf4ffe69e9eaac8b45e8523f030521e02bb67d654c6eb5236d9c456cbe +F ext/wasm/speedtest1-worker.html e33e2064bda572c0c3ebaec7306c35aa758d9d27e245d67e807f8cc4a9351cc5 +F ext/wasm/speedtest1-worker.js 315d26198c46be7c85e26fda15d80ef882424276abde25ffd8b026fb02a35d8c F ext/wasm/speedtest1.html ff048b4a623aa192e83e143e48f1ce2a899846dd42c023fdedc8772b6e3f07da F ext/wasm/split-speedtest1-script.sh a3e271938d4d14ee49105eb05567c6a69ba4c1f1293583ad5af0cd3a3779e205 x F ext/wasm/sql/000-mandelbrot.sql 775337a4b80938ac8146aedf88808282f04d02d983d82675bd63d9c2d97a15f0 F ext/wasm/sql/001-sudoku.sql 35b7cb7239ba5d5f193bc05ec379bcf66891bce6f2a5b3879f2f78d0917299b5 F ext/wasm/test-opfs-vfs.html 1f2d672f3f3fce810dfd48a8d56914aba22e45c6834e262555e685bce3da8c3f F ext/wasm/test-opfs-vfs.js f09266873e1a34d9bdb6d3981ec8c9e382f31f215c9fd2f9016d2394b8ae9b7b -F ext/wasm/tester1-worker.html 258d08f1ba9cc2d455958751e26be833893cf9ff7853e9436e593e1f778a386b +F ext/wasm/tester1-worker.html ebc4b820a128963afce328ecf63ab200bd923309eb939f4110510ab449e9814c F ext/wasm/tester1.c-pp.html 1c1bc78b858af2019e663b1a31e76657b73dc24bede28ca92fbe917c3a972af2 -F ext/wasm/tester1.c-pp.js 587a18db0f794c594eb0fade37c92af3e2370501576bb08dafd8ed7d009b6516 +F ext/wasm/tester1.c-pp.js fb20d9e1c308ea34a29d8afdda1a6c5edc406241b5560fa23c19c14747ee41bc F ext/wasm/tests/opfs/concurrency/index.html 0802373d57034d51835ff6041cda438c7a982deea6079efd98098d3e42fbcbc1 F ext/wasm/tests/opfs/concurrency/test.js a98016113eaf71e81ddbf71655aa29b0fed9a8b79a3cdd3620d1658eb1cc9a5d F ext/wasm/tests/opfs/concurrency/worker.js 0a8c1a3e6ebb38aabbee24f122693f1fb29d599948915c76906681bb7da1d3d2 -F ext/wasm/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5 -F ext/wasm/wasmfs.make cf9a68162d92ca2bcb0b9528b244cb36d5cc2d84ccc9c2d398461927d6e75aea +F ext/wasm/wasmfs.make 8a4955882aaa0783b3f60a9484a1f0f3d8b6f775c0fcd17c082f31966f1bc16a F install-sh 9d4de14ab9fb0facae2f48780b874848cbf2f895 x F ltmain.sh 3ff0879076df340d2e23ae905484d8c15d5fdea8 F magic.txt 5ade0bc977aa135e79e3faaea894d5671b26107cc91e70783aa7dc83f22f3ba0 -F main.mk ac6b13f8ecc43f377e9912380ea4cf366051d7f784cf61c8886e03e1cf0fbefa -F mkso.sh fd21c06b063bb16a5d25deea1752c2da6ac3ed83 +F main.mk 51fd5fc8565007266e6bfd9e299199c752b171707a667b8914a204b38258e1b1 F mptest/config01.test 3c6adcbc50b991866855f1977ff172eb6d901271 F mptest/config02.test 4415dfe36c48785f751e16e32c20b077c28ae504 F mptest/crash01.test 61e61469e257df0850df4293d7d4d6c2af301421 @@ -565,182 +650,183 @@ F mptest/multiwrite01.test dab5c5f8f9534971efce679152c5146da265222d F spec.template 86a4a43b99ebb3e75e6b9a735d5fd293a24e90ca F sqlite.pc.in 42b7bf0d02e08b9e77734a47798d1a55a9e0716b -F sqlite3.1 fc7ad8990fc8409983309bb80de8c811a7506786 +F sqlite3.1 acdff36db796e2d00225b911d3047d580cd136547298435426ce9d40347973cc F sqlite3.pc.in 48fed132e7cb71ab676105d2a4dc77127d8c1f3a F sqlite_cfg.h.in baf2e409c63d4e7a765e17769b6ff17c5a82bbd9cbf1e284fd2e4cefaff3fcf2 -F src/alter.c 482c534877fbb543f8295992cde925df55443febac5db5438d5aaba6f78c4940 -F src/analyze.c a1f3061af16c99f73aed0362160176c31a6452de1b02ada1d68f6839f2a37df0 +F src/alter.c 30c2333b8bb3af71e4eb9adeadee8aa20edb15917ed44b8422e5cd15f3dfcddc +F src/analyze.c d4cc28738c29e009640ec20ebb6936ba6fcefff0d11aa93398d9bb9a5ead6c1f F src/attach.c cc9d00d30da916ff656038211410ccf04ed784b7564639b9b61d1839ed69fd39 -F src/auth.c f4fa91b6a90bbc8e0d0f738aa284551739c9543a367071f55574681e0f24f8cf +F src/auth.c 19b7ccacae3dfba23fc6f1d0af68134fa216e9040e53b0681b4715445ea030b4 F src/backup.c 5c97e8023aab1ce14a42387eb3ae00ba5a0644569e3476f38661fa6f824c3523 -F src/bitvec.c 7c849aac407230278445cb069bebc5f89bf2ddd87c5ed9459b070a9175707b3d -F src/btmutex.c 6ffb0a22c19e2f9110be0964d0731d2ef1c67b5f7fabfbaeb7b9dabc4b7740ca -F src/btree.c ecaaf8d57cd8b5f4e3167bd59cf61cef031b4b2ee606e6afa11b96a60a14f9ef -F src/btree.h aa354b9bad4120af71e214666b35132712b8f2ec11869cb2315c52c81fad45cc -F src/btreeInt.h b900603c8956bdeb313841f9b67bdeceef32c64d962d35477c07ec25e8cf0f9b -F src/build.c 7a7217f75f202eff03617ca447bb9c3bc07d5af49da1d3cff2b1a88e8e394686 +F src/bitvec.c 9eac5f42c11914d5ef00a75605bb205e934f435c579687f985f1f8b0995c8645 +F src/btmutex.c 79a43670447eacc651519a429f6ece9fd638563cf95b469d6891185ddae2b522 +F src/btree.c f3b09c5414de3a11db73e11e1d66f4c5e53c9e89876ff3b531a887ab656ca303 x +F src/btree.h 03e3356f5208bcab8eed4e094240fdac4a7f9f5ddf5e91045ce589f67d47c240 +F src/btreeInt.h ef12a72b708677e48d6bc8dcd66fed25434740568b89e2cfa368093cfc5b9d15 +F src/build.c 189e4517d67f09f0a3e0d8e1faa6e2ef0c2e95f6ac82e33c912cb7efa2a359cc F src/callback.c db3a45e376deff6a16c0058163fe0ae2b73a2945f3f408ca32cf74960b28d490 F src/complete.c a3634ab1e687055cd002e11b8f43eb75c17da23e -F src/ctime.c 20507cc0b0a6c19cd882fcd0eaeda32ae6a4229fb4b024cfdf3183043d9b703d -F src/date.c aca9e0c08b400b21238b609aea7c09585396cd770985cf8f475560f69222dad3 -F src/dbpage.c f3eea5f7ec47e09ee7da40f42b25092ecbe961fc59566b8e5f705f34335b2387 -F src/dbstat.c ec92074baa61d883de58c945162d9e666c13cd7cf3a23bc38b4d1c4d0b2c2bef -F src/delete.c a9c6d3f51c0a31e9b831e0a0580a98d702904b42d216fee530940e40dec34873 -F src/expr.c 941fe758212c6cf0007c6d7daf5368e11c199376ace9b3018494296e18a27eac +F src/ctime.c 23331529e654be40ca97d171cbbffe9b3d4c71cc53b78fe5501230675952da8b +F src/date.c eebc54a00e888d3c56147779e9f361b77d62fd69ff2008c5373946aa1ba1d574 +F src/dbpage.c 80e46e1df623ec40486da7a5086cb723b0275a6e2a7b01d9f9b5da0f04ba2782 +F src/dbstat.c 3b677254d512fcafd4d0b341bf267b38b235ccfddbef24f9154e19360fa22e43 +F src/delete.c cb766727c78e715f9fb7ec8a7d03658ed2a3016343ca687acfcec9083cdca500 +F src/expr.c 433f12e1237524482b0b2681c07da3cd54ddada2a625237cecde419f3e3a2553 F src/fault.c 460f3e55994363812d9d60844b2a6de88826e007 -F src/fkey.c 03c134cc8bffe54835f742ddea0b72ebfc8f6b32773d175c71b8afeea6cb5c83 -F src/func.c 03e6b501f3056d0ba398bda17df938b2b566aa0b3ca7e1942a3cd1925d04ec36 -F src/global.c bd0892ade7289f6e20bff44c07d06371f2ff9b53cea359e7854b9b72f65adc30 -F src/hash.c c6af5f96a7a76d000f07c5402c48c318c2566beecdee9e78b9d9f60ce7119565 +F src/fkey.c a47610f0a5c6cb0ad79f8fcef039c01833dec0c751bb695f28dc0ec6a4c3ba00 +F src/func.c 472f6dcfa39cf54f89a6aec76c79c225fb880a6c14469c15d361331662b9bf43 +F src/global.c 29f56a330ed9d1b5cd9b79ac0ca36f97ac3afc730ff8bfa987b0db9e559d684d +F src/hash.c 9ee4269fb1d6632a6fecfb9479c93a1f29271bddbbaf215dd60420bcb80c7220 F src/hash.h 3340ab6e1d13e725571d7cee6d3e3135f0779a7d8e76a9ce0a85971fa3953c51 -F src/hwtime.h b638809e083b601b618df877b2e89cb87c2a47a01f4def10be4c4ebb54664ac7 +F src/hwtime.h f9c2dfb84dce7acf95ce6d289e46f5f9d3d1afd328e53da8f8e9008e3b3caae6 F src/in-operator.md 10cd8f4bcd225a32518407c2fb2484089112fd71 -F src/insert.c a8de1db43335fc4946370a7a7e47d89975ad678ddb15078a150e993ba2fb37d4 -F src/json.c 39b1c7527f3111923e65f168a87b03b591f12a41400a63d05c119794bee36620 +F src/insert.c 3f0a94082d978bbdd33c38fefea15346c6c6bffb70bc645a71dc0f1f87dd3276 +F src/json.c d69c6e28ff7b602877bda68cd20583b8487c059759aa4d154dd21b3fd99c6238 F src/legacy.c d7874bc885906868cd51e6c2156698f2754f02d9eee1bae2d687323c3ca8e5aa -F src/loadext.c be5af440f3192c58681b5d43167dbca3ccbfce394d89faa22378a14264781136 -F src/main.c 035be2e9ba2a0fc1701a8ab1880af3001a968a24556433538a6c073558ee4341 -F src/malloc.c 47b82c5daad557d9b963e3873e99c22570fb470719082c6658bf64e3012f7d23 +F src/loadext.c 7432c944ff197046d67a1207790a1b13eec4548c85a9457eb0896bb3641dfb36 +F src/main.c e1bc8864834697503d370d94613be945d05ca1c5ebdda43e7d5c8ee8c48d433c +F src/malloc.c f016922435dc7d1f1f5083a03338a3e91f8c67ce2c5bdcfa4cdef62e612f5fcc F src/mem0.c 6a55ebe57c46ca1a7d98da93aaa07f99f1059645 -F src/mem1.c c12a42539b1ba105e3707d0e628ad70e611040d8f5e38cf942cee30c867083de +F src/mem1.c 3bb59158c38e05f6270e761a9f435bf19827a264c13d1631c58b84bdc96d73b2 F src/mem2.c c8bfc9446fd0798bddd495eb5d9dbafa7d4b7287d8c22d50a83ac9daa26d8a75 F src/mem3.c 30301196cace2a085cbedee1326a49f4b26deff0af68774ca82c1f7c06fda4f6 F src/mem5.c b7da5c10a726aacacc9ad7cdcb0667deec643e117591cc69cf9b4b9e7f3e96ff F src/memdb.c 559c42e61eb70cd6d4bc692b042497133c6d96c09a3d514d92f3dac72268e223 F src/memjournal.c c283c6c95d940eb9dc70f1863eef3ee40382dbd35e5a1108026e7817c206e8a0 F src/msvc.h 80b35f95d93bf996ccb3e498535255f2ef1118c78764719a7cd15ab4106ccac9 -F src/mutex.c 5e3409715552348732e97b9194abe92fdfcd934cfb681df4ba0ab87ac6c18d25 +F src/mutex.c 1b4c7e5e3621b510e0c18397210be27cd54c8084141144fbbafd003fde948e88 F src/mutex.h a7b2293c48db5f27007c3bdb21d438873637d12658f5a0bf8ad025bb96803c4a F src/mutex_noop.c 9d4309c075ba9cc7249e19412d3d62f7f94839c4 -F src/mutex_unix.c dd2b3f1cc1863079bc1349ac0fec395a500090c4fe4e11ab775310a49f2f956d -F src/mutex_w32.c caa50e1c0258ac4443f52e00fe8aaea73b6d0728bd8856bedfff822cae418541 -F src/notify.c 89a97dc854c3aa62ad5f384ef50c5a4a11d70fcc69f86de3e991573421130ed6 -F src/os.c 81c9c1c52eab711e27e33fd51fe5788488d3a02bc1a71439857abbee5d0d2c97 +F src/mutex_unix.c f7ee5a2061a4c11815a2bf4fc0e2bfa6fb8d9dc89390eb613ca0cec32fc9a3d1 +F src/mutex_w32.c 38b56d0bc8d54c17c20cbaaad3719b0c36b92fd07a7e34360d0c6a18d5589912 +F src/notify.c 57c2d1a2805d6dee32acd5d250d928ab94e02d76369ae057dee7d445fd64e878 +F src/os.c 509452169d5ea739723e213b8e2481cf0e587f0e88579a912d200db5269f5f6d F src/os.h 1ff5ae51d339d0e30d8a9d814f4b8f8e448169304d83a7ed9db66a65732f3e63 F src/os_common.h 6c0eb8dd40ef3e12fe585a13e709710267a258e2c8dd1c40b1948a1d14582e06 F src/os_kv.c 4d39e1f1c180b11162c6dc4aa8ad34053873a639bac6baae23272fc03349986a F src/os_setup.h 6011ad7af5db4e05155f385eb3a9b4470688de6f65d6166b8956e58a3d872107 -F src/os_unix.c 1b3ddb7814c4bf37f494c04d2ab30c1ced5b2c927267e1930ce7cd388787a96d -F src/os_win.c 2b2411279f7b24f927591561303fc5871845732df42641cbf695c23640b16975 +F src/os_unix.c cb116fde9e3ca3c1bbfdf89d6928f776a2a34da168e2667426523a4db353b271 +F src/os_win.c 4a50a154aeebc66a1f8fb79c1ff6dd5fe3d005556533361e0d460d41cb6a45a8 F src/os_win.h 7b073010f1451abe501be30d12f6bc599824944a -F src/pager.c 45e2ef5e9eb5cc0138bcc32b5d2299479be80b206f621873f59149dfb517f496 -F src/pager.h f82e9844166e1585f5786837ddc7709966138ced17f568c16af7ccf946c2baa3 -F src/parse.y 146f9a1db7db5ef4299c6897d335e5abed348c2626190d2877d45ffa210fd4ca -F src/pcache.c 8ee13acccfd9accbf0af94910b7323dd7f7d55300d92ddafcf40e34fcc8e21be +F src/pager.c 699aab8dfc88056d796b03b40c0ab979040d58dfc3ae9db207f1be91e4880bbf +F src/pager.h f4d33fec8052603758792045493423b8871a996da2d0973927b7d36cd6070473 +F src/parse.y 020d80386eb216ec9520549106353c517d2bbc89be28752ffdca649a9eaf56ec +F src/pcache.c 040b165f30622a21b7a9a77c6f2e4877a32fb7f22d4c7f0d2a6fa6833a156a75 F src/pcache.h 1497ce1b823cf00094bb0cf3bac37b345937e6f910890c626b16512316d3abf5 -F src/pcache1.c dee95e3cd2b61e6512dc814c5ab76d5eb36f0bfc9441dbb4260fccc0d12bbddc -F src/pragma.c 26ed2cfdc5c12aa1c707178635709684960288cacc9cff9d491a38ff10e395f1 +F src/pcache1.c 602acb23c471bb8d557a6f0083cc2be641d6cafcafa19e481eba7ef4c9ca0f00 +F src/pragma.c b3b4ad9c0298d63098a067acca613c21a5f56b4d176d5842922bcd0b07b7164e F src/pragma.h e690a356c18e98414d2e870ea791c1be1545a714ba623719deb63f7f226d8bb7 -F src/prepare.c 6350675966bd0e7ac3a464af9dbfe26db6f0d4237f4e1f1acdb17b12ad371e6e -F src/printf.c b9320cdbeca0b336c3f139fd36dd121e4167dd62b35fbe9ccaa9bab44c0af38d +F src/prepare.c bde74add20fc0e8ce0c4e937a1f70a36d17413afe4f71d3e103f5cb74b17c8d9 +F src/printf.c 9da63b9ae1c14789bcae12840f5d800fd9302500cd2d62733fac77f0041b4750 F src/random.c 606b00941a1d7dd09c381d3279a058d771f406c5213c9932bbd93d5587be4b9c -F src/resolve.c 3e53e02ce87c9582bd7e7d22f13f4094a271678d9dc72820fa257a2abb5e4032 -F src/rowset.c ba9515a922af32abe1f7d39406b9d35730ed65efab9443dc5702693b60854c92 -F src/select.c 738c3a3d6929f8be66c319bad17f6b297bd60a4eb14006075c48a28487dc7786 -F src/shell.c.in 52836b4002a2cad8095b451f0c39a6542c23a231eb0ed5e39387bc8b1f7aaa9e -F src/sqlite.h.in c14a4471fcd897a03631ac7ad3d05505e895e7b6419ec5b96cae9bc4df7a9fc6 +F src/resolve.c 31229276a8eb5b5de1428cd2d80f6f1cf8ffc5248be25e47cf575df12f1b8f23 +F src/rowset.c 8432130e6c344b3401a8874c3cb49fefe6873fec593294de077afea2dce5ec97 +F src/select.c a19daa26e95f7245106a31f288b2f50c72d1f2cc156703f04c8c91450e111515 +F src/shell.c.in aebfbedaa7706d2c73ab7366a19fc8bc40ea68b70d2529f7feef54e6eb077ea2 +F src/sqlite.h.in ef0e41e83ad1ac0dcc9ec9939bf541a44b1c5de821bee2d6c61754c3252f3276 F src/sqlite3.rc 5121c9e10c3964d5755191c80dd1180c122fc3a8 -F src/sqlite3ext.h da473ce2b3d0ae407a6300c4a164589b9a6bfdbec9462688a8593ff16f3bb6e4 -F src/sqliteInt.h a3ced8b9ebc573189c87b69f24bf10d2b9cd3cefefaae52623a2fa79e6fdd408 -F src/sqliteLimit.h d7323ffea5208c6af2734574bae933ca8ed2ab728083caa117c9738581a31657 +F src/sqlite3ext.h 3f046c04ea3595d6bfda99b781926b17e672fd6d27da2ba6d8d8fc39981dcb54 +F src/sqliteInt.h 567e317f8631883897b7d3da43fce778b7c30dd0dd7f714558c9725fc1c1196c +F src/sqliteLimit.h 33b1c9baba578d34efe7dfdb43193b366111cdf41476b1e82699e14c11ee1fb6 F src/status.c 160c445d7d28c984a0eae38c144f6419311ed3eace59b44ac6dafc20db4af749 F src/table.c 0f141b58a16de7e2fbe81c308379e7279f4c6b50eb08efeec5892794a0ba30d1 -F src/tclsqlite.c 8522a04fb9c84faa1d80354430ae0ee9349727a3a4b32e3cfe39b9be8324cabd -F src/test1.c 8eab61fb2813aa212d97ab188e85fc9ca7b89d9ff5ff05d59d9aa0c491a6c721 -F src/test2.c 827446e259a3b7ab949da1542953edda7b5117982576d3e6f1c24a0dd20a5cef -F src/test3.c 61798bb0d38b915067a8c8e03f5a534b431181f802659a6616f9b4ff7d872644 +F src/tclsqlite.c ecbc3c99c0d0c3ed122a913f143026c26d38d57f33e06bb71185dd5c1efe37cd +F src/test1.c f9620e8f0d0fa4edb239201a732c4dd1562f0cdd9741955c89332d49e14a5edd +F src/test2.c 54520d0565ef2b9bf0f8f1dcac43dc4d06baf4ffe13d10905f8d8c3ad3e4b9ab +F src/test3.c e5178558c41ff53236ae0271e9acb3d6885a94981d2eb939536ee6474598840e F src/test4.c 4533b76419e7feb41b40582554663ed3cd77aaa54e135cf76b3205098cd6e664 F src/test5.c 328aae2c010c57a9829d255dc099d6899311672d -F src/test6.c ae73a3a42bbc982fb9e301b84d30bda65a307be48c6dff20aba1461e17a9b0ce -F src/test8.c 0c856d6ff6b0d2ff6696addc467a15ed17c6910f14475302cd5b3b4e54406161 +F src/test6.c e53bc69dc3cb3815fb74df74f38159ec05ba6dd5273216062e26bc797f925530 +F src/test8.c 303c2e3bcf7795e888810a7ef03809602b851f0ebec8d6e06a429ed85cafd9a2 F src/test9.c 12e5ba554d2d1cbe0158f6ab3f7ffcd7a86ee4e5 F src/test_async.c 195ab49da082053fdb0f949c114b806a49ca770a F src/test_autoext.c 915d245e736652a219a907909bb6710f0d587871 F src/test_backup.c bf5da90c9926df0a4b941f2d92825a01bbe090a0 -F src/test_bestindex.c 68c62586d2ae9f032903fe53be743657d0c2aac0a850b880938b668e1161d516 +F src/test_bestindex.c f6af1e41cb7901edafb065a8198e4a0192dd42432b642d038965be5e628dec12 F src/test_blob.c ae4a0620b478548afb67963095a7417cd06a4ec0a56adb453542203bfdcb31ce F src/test_btree.c 8b2dc8b8848cf3a4db93f11578f075e82252a274 -F src/test_config.c 8264637b06a3c1f0727c88d1ea32dcf7986b9e7e358a970cae87cdac8a5b2708 +F src/test_config.c f0cc1f517deaa96dd384822ae2bb91534fa56aa458528b439830d709941d3932 F src/test_delete.c e2fe07646dff6300b48d49b2fee2fe192ed389e834dd635e3b3bac0ce0bf9f8f F src/test_demovfs.c 38a459d1c78fd9afa770445b224c485e079018d6ac07332ff9bd07b54d2b8ce9 -F src/test_devsym.c aff2255ea290d7718da08af30cdf18e470ff7325a5eff63e0057b1496ed66593 -F src/test_fs.c ba1e1dc18fd3159fdba0b9c4256f14032159785320dfbd6776eb9973cb75d480 +F src/test_devsym.c 649434ed34d0b03fbd5a6b42df80f0f9a7e53f94dd1710aad5dd8831e91c4e86 +F src/test_fs.c 56cc17e4fdc57efa61695026e2ba96e910b17060d7ee01d775ec048791522e2f F src/test_func.c 24df3a346c012b1fc9e1001d346db6054deb426db0a7437e92490630e71c9b0a F src/test_hexio.c 9478e56a0f08e07841a014a93b20e4ba2709ab56d039d1ca8020e26846aa19bd -F src/test_init.c 4413c211a94b62157ca4c145b3f27c497f03c664 -F src/test_intarray.c 39b4181662a0f33a427748d87218e7578d913e683dc27eab7098bb41617cac71 -F src/test_intarray.h d57ae92f420cda25e22790dac474d60961bd0c500cbaa3338a05152d4a669ef7 +F src/test_init.c f2cc4774b7c9140f76e45ecbb2ae219f68e3acbbe248c0179db666a70eae9f08 +F src/test_intarray.c 26ffba666beb658d73cd925d9b4fb56913a3ca9aaeac122b3691436abb192b92 +F src/test_intarray.h 6c3534641108cd1bea517a8e117dcba237081310a29a4c35bd2190caa8972293 F src/test_journal.c a0b9709b2f12b1ec819eea8a1176f283bca6d688a6d4a502bd6fd79786f4e287 F src/test_loadext.c 337056bae59f80b9eb00ba82088b39d0f4fe6dfd F src/test_malloc.c 21121ea85b49ec0bdb69995847cef9036ef9beca3ce63bbb776e4ea2ecc44b97 -F src/test_md5.c 7268e1e8c399d4a5e181b64ac20e1e6f3bc4dd9fc87abac02db145a3d951fa8c -F src/test_multiplex.c d8bc260a57c2028946a9bce9918d24e69e44cebd71ac6be240aa5b6b75e2b369 -F src/test_multiplex.h 5436d03f2d0501d04f3ed50a75819e190495b635 -F src/test_mutex.c abf486e91bd65e2448027d4bb505e7cce6ba110e1afb9bd348d1996961cadf0d +F src/test_md5.c 0472c86d561f7f9e4ff94080100c2783196f50e583bb83375b759450c5b81802 +F src/test_multiplex.c 70479161239d65af2a231550b270e9d11ece717ad7bf0e13ef42206586e9dd7f +F src/test_multiplex.h f0ff5b6f4462bfd46dac165d6375b9530d08089b7bcbe75e88e0926110db5363 +F src/test_mutex.c cd5bac43f2fd168f43c4326b1febe0966439217fac52afb270a6b8215f94cb40 F src/test_onefile.c f31e52e891c5fef6709b9fcef54ce660648a34172423a9cbdf4cbce3ba0049f4 -F src/test_osinst.c d341f9d7613e007c8c3f7eba6cd307230047506aa8f97858c1fd21f5069616bd -F src/test_pcache.c a5cd24730cb43c5b18629043314548c9169abb00 -F src/test_quota.c 6cb9297115b551f433a9ad1741817a9831abed99 +F src/test_osinst.c 8e11faf10f5d4df10d3450ecee0b8f4cfa2b62e0f341fafbeb480a08cefeaec4 +F src/test_pcache.c 3960cd2c1350adc992c4bf7adcfb0d1ac0574733012bd1a5f94e195928577599 +F src/test_quota.c ea44c05f29b995bdb71c55eb0c602604884e55681d59b7736e604bbcc68b0464 F src/test_quota.h 2a8ad1952d1d2ca9af0ce0465e56e6c023b5e15d F src/test_rtree.c 671f3fae50ff116ef2e32a3bf1fe21b5615b4b7b -F src/test_schema.c f5d6067dfc2f2845c4dd56df63e66ee826fb23877855c785f75cc2ca83fd0c1b +F src/test_schema.c cbfd7a9a9b6b40d4377d0c76a6c5b2a58387385977f26edab4e77eb5f90a14ce F src/test_sqllog.c 540feaea7280cd5f926168aee9deb1065ae136d0bbbe7361e2ef3541783e187a F src/test_superlock.c 4839644b9201da822f181c5bc406c0b2385f672e F src/test_syscall.c 9fdb13b1df05e639808d44fcb8f6064aaded32b6565c00b215cfd05a060d1aca F src/test_tclsh.c 3ff5d188a72f00807425954ea3b493dfd3a4b890ecc6700ea83bad2fd1332ecf -F src/test_tclvar.c 33ff42149494a39c5fbb0df3d25d6fafb2f668888e41c0688d07273dcb268dfc +F src/test_tclvar.c 3273f9d59395b336e381b53cfc68ec6ebdaada4e93106a2e976ffb0550504e1c F src/test_thread.c 7ddcf0c8b79fa3c1d172f82f322302c963d923cdb503c6171f3c8081586d0b01 F src/test_vdbecov.c f60c6f135ec42c0de013a1d5136777aa328a776d33277f92abac648930453d43 F src/test_vfs.c 193c18da3dbf62a0e33ae7a240bbef938a50846672ee947664512b77d853fe81 -F src/test_vfstrace.c bab9594adc976cbe696ff3970728830b4c5ed698 +F src/test_vfstrace.c a2ea82df2ed8927e9eba49bdba1aa1aeb1dcb13dbf6558cff036da813031de9a F src/test_windirent.c a895e2c068a06644eef91a7f0a32182445a893b9a0f33d0cdb4283dca2486ac1 -F src/test_windirent.h 90dfbe95442c9762357fe128dc7ae3dc199d006de93eb33ba3972e0a90484215 +F src/test_windirent.h da2e5b73c32d09905fbdd00f27cd802212a32a58ead882736fe4f5eb775ebc50 F src/test_window.c cdae419fdcea5bad6dcd9368c685abdad6deb59e9fc8b84b153de513d394ba3f F src/test_wsd.c 41cadfd9d97fe8e3e4e44f61a4a8ccd6f7ca8fe9 F src/threads.c 4ae07fa022a3dc7c5beb373cf744a85d3c5c6c3c -F src/tokenize.c 1305797eab3542a0896b552c6e7669c972c1468e11e92b370533c1f37a37082b -F src/treeview.c fccf3b8c517c1f55cb380c1522febe6921fcb2bd800c16c78cab571d0eb0ccbd -F src/trigger.c ad6ab9452715fa9a8075442e15196022275b414b9141b566af8cdb7a1605f2b0 -F src/update.c 3f4fb5ad7c9b48d7911974d6579192bb3a6c27f46140b6cbb9139cc8a77b8691 -F src/upsert.c 5303dc6c518fa7d4b280ec65170f465c7a70b7ac2b22491598f6d0b4875b3145 +F src/tokenize.c 23d9f4539880b40226254ad9072f4ecf12eb1902e62aea47aac29928afafcfd5 +F src/treeview.c 62fafcd31eea60b718f8daf448116b7b19f90134ebc6c20777ddbb07f56a3d28 +F src/trigger.c 0905b96b04bb6658509f711a8207287f1315cdbc3df1a1b13ba6483c8e341c81 +F src/update.c 6904814dd62a7a93bbb86d9f1419c7f134a9119582645854ab02b36b676d9f92 +F src/upsert.c fa125a8d3410ce9a97b02cb50f7ae68a2476c405c76aa692d3acf6b8586e9242 F src/utf.c ee39565f0843775cc2c81135751ddd93eceb91a673ea2c57f61c76f288b041a0 -F src/util.c d4bcb560471cd94e6e17d448311f8d5bf81a7e5276295a53501058ef1b95dd1a -F src/vacuum.c 84ce7f01f8a7a08748e107a441db83bcec13970190ddcb0c9ff522adbc1c23fd -F src/vdbe.c fedd2dfa5165256c8e372f2ae9454c4a82cf60ce79a04dff80a86ab2116ea15a -F src/vdbe.h 637ae853b7d42ae3951034cc63ab7c8af837861f79504cdb5399552fcd89a884 -F src/vdbeInt.h a4147a4ddf613cb1bcb555ace9e9e74a9c099d65facd88155f191b1fb4d74cfb -F src/vdbeapi.c b4982cde547054c4f7341198db3c3008a48e1eb028f757601bf5bf2fc026cbcf -F src/vdbeaux.c 6ee48db408d4c297a363f1e31145c09793a580e7c508bb36063dd017d67117a2 -F src/vdbeblob.c 2516697b3ee8154eb8915f29466fb5d4f1ae39ee8b755ea909cefaf57ec5e2ce -F src/vdbemem.c 1cac4028c0dabbf1f3259f107440e2780e05ac9fe419e9709e6eb4e166ba714b -F src/vdbesort.c 43756031ca7430f7aec3ef904824a7883c4ede783e51f280d99b9b65c0796e35 +F src/util.c b22cc9f203a8c0b9ee5338a67f8860347d14845864c10248bebe84518a781677 +F src/vacuum.c 604fcdaebe76f3497c855afcbf91b8fa5046b32de3045bab89cc008d68e40104 +F src/vdbe.c 14479441337135eed8e290fb1d4abb7db657d93217a3b1ea8a2f031d3895536a +F src/vdbe.h 41485521f68e9437fdb7ec4a90f9d86ab294e9bb8281e33b235915e29122cfc0 +F src/vdbeInt.h 949669dfd8a41550d27dcb905b494f2ccde9a2e6c1b0b04daa1227e2e74c2b2c +F src/vdbeapi.c fe654b1f54e1feebcaed6c2ae3ed035cc65bfeb9a1169bed866abc42bfc63ff6 +F src/vdbeaux.c dffcf79e7e415fcd6e4c8ac1ec7124cae5257018443adf09551c807655b04993 +F src/vdbeblob.c 13f9287b55b6356b4b1845410382d6bede203ceb29ef69388a4a3d007ffacbe5 +F src/vdbemem.c c936e9002af4993b84c4eb7133d6b1190efe46d391cc86117ecd67ba17b1a04b +F src/vdbesort.c 237840ca1947511fa59bd4e18b9eeae93f2af2468c34d2427b059f896230a547 F src/vdbetrace.c fe0bc29ebd4e02c8bc5c1945f1d2e6be5927ec12c06d89b03ef2a4def34bf823 -F src/vdbevtab.c aae4bd769410eb7e1d02c42613eec961d514459b1c3c1c63cfc84e92a137daac -F src/vtab.c 4758a96d36c9a120848386ae603b1ab32a4876e0a1faf81bfcfb524455e583dc +F src/vdbevtab.c 2143db7db0ceed69b21422581f434baffc507a08d831565193a7a02882a1b6a7 +F src/vtab.c 154725ebecd3bc02f7fbd7ad3974334f73fff76e02a964e828e48a7c5fb7efff F src/vxworks.h d2988f4e5a61a4dfe82c6524dd3d6e4f2ce3cdb9 -F src/wal.c 7a65f64bfe4a783c5e2df73ffb0efc383dec934dee9e3ac706b2eeb3631d17ac -F src/wal.h c3aa7825bfa2fe0d85bef2db94655f99870a285778baa36307c0a16da32b226a -F src/walker.c f890a3298418d7cba3b69b8803594fdc484ea241206a8dfa99db6dd36f8cbb3b -F src/where.c b74a83b4c8f65b218c5c1c8d9122433f85ee1300fd9263ba1697d0e1040eeb36 -F src/whereInt.h e25203e5bfee149f5f1225ae0166cfb4f1e65490c998a024249e98bb0647377c -F src/wherecode.c b300db0bcd84ad6c2642bf3f509f92fad7b7d697b9856b64dd66d692d184d054 -F src/whereexpr.c 22cf19b0ececeaf838daed1039c5231a8778784eba5ad67b991442a23473fd3f -F src/window.c e075ea85bea322e30e361fa6e69eddba74f461e99e2a564dc09973f8a1fb27d9 +F src/wal.c 01e051a1e713d9eabdb25df38602837cec8f4c2cae448ce2cf6accc87af903e9 +F src/wal.h ba252daaa94f889f4b2c17c027e823d9be47ce39da1d3799886bbd51f0490452 +F src/walker.c 7c7ea0115345851c3da4e04e2e239a29983b61fb5b038b94eede6aba462640e2 +F src/where.c 313ce81270d2a414672370e1ee74e65949ad620519193d4cac2986d073cbc8a0 +F src/whereInt.h 4b38c5889514e3aead3f27d0ee9a26e47c3f150efc59e2a8b4e3bc8835e4d7a1 +F src/wherecode.c 5d77db30a2a3dd532492ae882de114edba2fae672622056b1c7fd61f5917a8f1 +F src/whereexpr.c dc5096eca5ed503999be3bdee8a90c51361289a678d396a220912e9cb73b3c00 +F src/window.c ad21e2b73ec75acc79dde2576c573f54a338b0c49e9de847ce984f9b9595b5e2 F test/8_3_names.test ebbb5cd36741350040fd28b432ceadf495be25b2 F test/affinity2.test ce1aafc86e110685b324e9a763eab4f2a73f737842ec3b687bd965867de90627 F test/affinity3.test f094773025eddf31135c7ad4cde722b7696f8eb07b97511f98585addf2a510a9 F test/aggerror.test a867e273ef9e3d7919f03ef4f0e8c0d2767944f2 F test/aggfault.test 777f269d0da5b0c2524c7ff6d99ae9a93db4f1b1839a914dd2a12e3035c29829 -F test/aggnested.test 7269d07ac879fce161cb26c8fabe65cba5715742fac8a1fccac570dcdaf28f00 +F test/aggnested.test 2e738bfe2980df301a782f6e7bbf9459266f64f7e72f58f3b5c843bf897c568c +F test/aggorderby.test e6b98dbbf3ababa96892435d387de2dcf602ef02c2b848d2d817473066f154ba F test/alias.test 4529fbc152f190268a15f9384a5651bbbabc9d87 F test/all.test 2ecb8bbd52416642e41c9081182a8df05d42c75637afd4488aace78cc4b69e13 -F test/alter.test 313073774ab5c3f2ef1d3f0d03757c9d3a81284ae7e1b4a6ca34db088f886896 +F test/alter.test 403a7f8842457044a994d0ffb42963d6e84fcfbf5e8f54556063b25d966cd454 F test/alter2.test a966ccfcddf9ce0a4e0e6ff1aca9e6e7948e0e242cd7e43fc091948521807687 F test/alter3.test ffc4ab29ce78a3517a66afd69b2730667e3471622509c283b2bd4c46f680fba3 F test/alter4.test 716caa071dd8a3c6d57225778d15d3c3cbf5e34b2e84ae44199aeb2bbf50a707 F test/alterauth.test 63442ba61ceb0c1eeb63aac1f4f5cebfa509d352276059d27106ae256bafc959 F test/alterauth2.test 48967abae0494d9a300d1c92473d99fcb66edfcc23579c89322f033f49410adc -F test/altercol.test 8465ca659c2c55a359cf16cc261df4fcb5c45a5f104a50827c337ae66c09dc15 +F test/altercol.test 29fed774747777fbbaacdd865b4413ed2d0844a4c824f8af531b5c7d4a832087 F test/altercorrupt.test 2e1d705342cf9d7de884518ddbb053fd52d7e60d2b8869b7b63b2fda68435c12 F test/alterdropcol.test a653a3945f964d26845ec0cd0a8e74189f46de3119a984c5bc45457da392612e F test/alterdropcol2.test 527fce683b200d620f560f666c44ae33e22728e990a10a48a543280dfd4b4d41 @@ -748,14 +834,14 @@ F test/alterlegacy.test f38c6d06cda39e1f7b955bbce57f2e3ef5b7cb566d3d1234502093e228c15811 F test/altermalloc.test 167a47de41b5c638f5f5c6efb59784002b196fff70f98d9b4ed3cd74a3fb80c9 F test/altermalloc2.test 17fb3724c4b004c469c27dc4ef181608aa644555fbd3f3236767584f73747c81 -F test/altermalloc3.test 8531b3086f0a7889f43971a579a8c81832d5123f4703d8c86b89ba1136c63b9a -F test/alterqf.test ff6c6f881485c29ed699b8ef4774864ca1b0c01a6c08f5cdd624a008e4b40fca +F test/altermalloc3.test 8040e486368403f2fdd6fc3998258b499bd4cc2f3ddbb5f8f874cd436f076e81 +F test/alterqf.test 8ec03d776de9c391daa0078ea8f838903bdcfb11dfae4ba3576b48436834ccba F test/altertab.test 8a2712f9076da5012a002d0b5cc0a421398a5bf61c25bab41b77c427586a7a27 F test/altertab2.test 62597b6fd08feaba1b6bfe7d31dac6117c67e06dc9ce9c478a3abe75b5926de0 F test/altertab3.test 6c432fbb9963e0bd6549bf1422f6861d744ee5a80cb3298564e81e556481df16 -F test/altertrig.test fb5951d21a2c954be3b8a8cf8e10b5c0fa20687c53fd67d63cea88d08dd058d5 +F test/altertrig.test aacc980b657354fe2d3d4d3a004f07d04ccc1a93e5ef82d68a79088c274ddc6b F test/amatch1.test b5ae7065f042b7f4c1c922933f4700add50cdb9f -F test/analyze.test 547bb700f903107b38611b014ca645d6b5bb819f5210d7bf39c40802aafeb7d7 +F test/analyze.test 2fb21d7d64748636384e6cb8998dbf83968caf644c07fcb4f76c18f2e7ede94b F test/analyze3.test 03f4b3d794760cf15da2d85a52df9bae300e51c8fefe9c36cfae1f86dc10d23f F test/analyze4.test 68bd069f3ac7ac1e652ddd9f04f57d5606ddb4208450f5297005db7aa0dd707d F test/analyze5.test fa5131952303ac4146aba101b116b9c8cb89e2637531c334a6df7f7d19dddc0d @@ -774,7 +860,7 @@ F test/async3.test d73a062002376d7edc1fe3edff493edbec1fc2f7 F test/async4.test 1787e3952128aa10238bf39945126de7ca23685a F test/async5.test 383ab533fdb9f7ad228cc99ee66e1acb34cc0dc0 -F test/atof1.test 1f24a6f16e44892848298bd8e488159d4a60cf47be003d32747a136103c9bbac +F test/atof1.test f2765d7fdc1348ae58b279d096d301a208e46da623213877b2ba580dc2768975 F test/atomic.test 065a453dde33c77ff586d91ccaa6ed419829d492dbb1a5694b8a09f3f9d7d061 F test/atomic2.test b6863b4aa552543874f80b42fb3063f1c8c2e3d8e56b6562f00a3cc347b5c1da F test/atrc.c c388fac43dbba05c804432a7135ae688b32e8f25818e9994ffba4b64cf60c27c @@ -791,7 +877,7 @@ F test/autoindex1.test d34caffb0384003ee28eae87679214c029e9be4b332d9649a79e0b94ab70502c F test/autoindex2.test 12ef578928102baaa0dc23ad397601a2f4ecb0df F test/autoindex3.test dcd6b2f8bed2be67b131e2e671f892e971d934e24fd00988952d0e0a67e24aa7 -F test/autoindex4.test 5df39313526b6f22a26bd119bbd97ca69f28386ab3c671fc10568d921c41eb08 +F test/autoindex4.test 3c2105e9172920e26f950ba3c5823e4972190e022c1e6f260ba476b0af24c593 F test/autoindex5.test 2ee94f033b87ca0160e08d81034c507aff8e230df2627f0304fa309b2fee19a3 F test/autovacuum.test 00671369bbf96c6a49989a9425f5b78b94075d6a4b031e5e00000c2c32f365df F test/autovacuum2.test 76f7eb4fe6a6bf6d33a196a7141dba98886d2fb53a268d7feca285d5da4759d7 @@ -817,8 +903,9 @@ F test/bestindex6.test 16942535b551273f3ad9df8d7cc4b7f22b1fcd8882714358859eb049a6f99dd4 F test/bestindex7.test f094c669a6400777f4d2ddc3ed28e39169f1adb5be3d59b55f22ccf8c414b71e F test/bestindex8.test 333ad8c6a554b885a49b68c019166eda92b05f493a92b36b0acdf7f766d04dad -F test/bestindex9.test bf2eb8556e8d5c00ef3ee18c521751cd03c1b55454b6e7683b4c6742e3131b23 -F test/bestindexA.test dd7b7439a46169b45d0305c4cbbb14fc20c7044acc2055c767d2f838b3479c3f +F test/bestindex9.test 1a4b93db117fd8abe74ae9be982f86aa72f01e60cd4ac541e6ede39673a451a0 +F test/bestindexA.test e1b5def6b190797cacf008e6815ffb78fb30261999030d60a728d572eef44c7f +F test/bestindexB.test 328b97b69cd1a20928d5997f9ecb04d2e00f1d18e19ab27f9e9adb44d7bc51ce F test/between.test b9a65fb065391980119e8a781a7409d3fcf059d89968279c750e190a9a1d5263 F test/bigfile.test aa74f4e5db51c8e54a1d9de9fa65d01d1eb20b59 F test/bigfile2.test 1b489a3a39ae90c7f027b79110d6b4e1dbc71bfc @@ -856,8 +943,8 @@ F test/carray01.test 23ed7074307c4a829ba5ff2970993a9d87db7c5cdbbe1a2cbef672d0df6d6e31 F test/cast.test af2286fdd28f3470b7dcad23977282b8cc117747ad55acff74a770dad3b19398 F test/cffault.test 9d6b20606afe712374952eec4f8fd74b1a8097ef -F test/changes.test 9dd8e597d84072122fc8a4fcdea837f4a54a461e6e536053ea984303e8ca937b -F test/changes2.test d222c0cbf5ab0ac4d7c180594e486c1bf20b2098d33e56ce33b8e12eba6823b9 +F test/changes.test 4377d202a487f66fc2822c1bf57c46798c8b2caf7446f4f701723b1dbb6b86f6 +F test/changes2.test 07949edcc732af28cb54276bfb7d99723bccc1e905a423648bf57ac5cb0dc792 F test/check.test 56e4ed457e9f8683b9fc56f5b964f461f6e8a8dd5a13f3d495408215d66419ed F test/checkfault.test da6cb3d50247169efcb20bdf57863a3ccfa1d27d9e55cd324f0680096970f014 F test/chunksize.test 427d87791743486cbf0c3b8c625002f3255cb3a89c6eba655a98923b1387b760 @@ -883,7 +970,7 @@ F test/conflict3.test 81865d9599609aca394fb3b9cd5f561d4729ea5b176bece3644f6ecb540f88ac F test/contrib01.test 2a1cbc0f2f48955d7d073f725765da6fbceda6b4 F test/corrupt.test d7cb0300e4a297147b6a05e92a1684bc8973635c3bcaa3d66e983c9cbdbf47a3 -F test/corrupt2.test 6e0c1e1c2ff4bedde4bc73f16250d74ae5b3d9ece086640ce88b9a94620ba993 +F test/corrupt2.test 9745c55b3ff2d84d9b6dc4f7365f91a99e70d90f3127ebc97ff0549c418e4d3d F test/corrupt3.test 6a982535d52c8165654cbc79a043cfd0bf02495a5efbf4754295e056fc548539 F test/corrupt4.test b5ae41607e8d17d9c1f3e94fdb572ce061ed3beeebdb46fb3a348181b8c8a097 F test/corrupt5.test 387be3250795e2a86e6234745558b80efb248a357d0cd8e53bce75c7463f545d @@ -902,7 +989,7 @@ F test/corruptI.test 9d8cbf6214e492abe9e822e759b9751ae336cec0a6fe3ff3b37bfbd8ff9c22ca F test/corruptJ.test 4d5ccc4bf959464229a836d60142831ef76a5aa4 F test/corruptK.test 5b4212fe346699831c5ad559a62c54e11c0611bdde1ea8423a091f9c01aa32af -F test/corruptL.test b42978028afc5eefc8b51d8d7cd6a9344ba7362d7ed4511ee2070f56e06d5a1c +F test/corruptL.test 504d90502d9993440226edc355d2275524b89064ea3df5ee5c27f7028ec59d07 F test/corruptM.test 7d574320e08c1b36caa3e47262061f186367d593a7e305d35f15289cc2c3e067 F test/corruptN.test 7c099d153a554001b4fb829c799b01f2ea6276cbc32479131e0db0da4efd9cc4 F test/cost.test b11cdbf9f11ffe8ef99c9881bf390e61fe92baf2182bad1dbe6de59a7295c576 @@ -926,19 +1013,20 @@ F test/cursorhint.test 05cf0febe5c5f8a31f199401fd1c9322249e753950d55f26f9d5aca61408a270 F test/cursorhint2.test 6f3aa9cb19e7418967a10ec6905209bcbb5968054da855fc36c8beee9ae9c42f F test/dataversion1.test 6e5e86ac681f0782e766ebcb56c019ae001522d114e0e111e5ebf68ccf2a7bb8 -F test/date.test 1d44557f668298b10d3335b22ab8feb133267b67ec4d85538908fe4dfebd2611 +F test/date.test c0d17cdfd89395bc78087b131e3538d96f864b5029c335318011accc7c0d0934 F test/date2.test 7e12ec14aaf4d5e6294b4ba140445b0eca06ea50062a9c3a69c4ee13d0b6f8b1 F test/date3.test a1b77abf05c6772fe5ca2337cac1398892f2a41e62bce7e6be0f4a08a0e64ae5 +F test/date4.test 8aeb3de5b5e9fda968baa9357e4c0fae573724b7904943410195a19e96e31b6a F test/dbdata.test 042f49acff3438f940eeba5868d3af080ae64ddf26ae78f80c92bec3ca7d8603 F test/dbfuzz.c 73047c920d6210e5912c87cdffd9a1c281d4252e -F test/dbfuzz001.test 55e1a3504f8dea84155e09912fe3b1c3ad77e0b1a938ec42ca03b8e51b321e30 +F test/dbfuzz001.test 6c9a4622029d69dc38926f115864b055cb2f39badd25ec22cbfb130c8ba8e9c3 F test/dbfuzz2-seed1.db e6225c6f3d7b63f9c5b6867146a5f329d997ab105bee64644dc2b3a2f2aebaee F test/dbfuzz2.c 4b3c12de4d98b1b2d908ab03d217d4619e47c8b23d5e67f8a6f2b1bdee7cae23 F test/dbpage.test fce29035c7566fd7835ec0f19422cb4b9c6944ce0e1b936ff8452443f92e887d -F test/dbpagefault.test d9111a62f3601d3efc6841ace3940181937342d245f92a1cca6cba8206d4f58a +F test/dbpagefault.test 35f06cfb2ef100a9b19d25754e8141b9cba9b7daabd4c60fa5af93fcce884435 F test/dbstatus.test 4a4221a883025ffd39696b3d1b3910b928fb097d77e671351acb35f3aed42759 F test/dbstatus2.test f5fe0afed3fa45e57cfa70d1147606c20d2ba23feac78e9a172f2fe8ab5b78ef -F test/decimal.test fcf403fd5585f47342234e153c4a4338cd737b8e0884ac66fc484df47dbcf1a7 +F test/decimal.test ef731887b43ee32ef86e1c8fddb61a40789f988332c029c601dcf2c319277e9e F test/default.test 9687cfb16717e4b8238c191697c98be88c0b16e568dd5368cd9284154097ef50 F test/delete.test 2686e1c98d552ef37d79ad55b17b93fe96fad9737786917ce3839767f734c48f F test/delete2.test 3a03f2cca1f9a67ec469915cb8babd6485db43fa @@ -951,7 +1039,7 @@ F test/diskfull.test 106391384780753ea6896b7b4f005d10e9866b6e F test/distinct.test 691c9e850b0d0b56b66e7e235453198cb4cf0760e324b7403d3c5abbeab0a014 F test/distinct2.test bb71cc7b5e58e895787f9910a788c254f679928d324732d063fe9bc202ecbe71 -F test/distinctagg.test 14ec5026e684eddd414c61c08692b43773e224ac92efbed6ec08c6994bc39723 +F test/distinctagg.test ad2b4cf1483cd4cf24867dfafbfa0abb61184d92085fcc9784cea0592b278d64 F test/e_blobbytes.test 4c01dfe4f12087b92b20705a3fdfded45dc4ed16d5a211fed4e1d2786ba68a52 F test/e_blobclose.test 692fc02a058476c2222a63d97e3f3b2b809c1842e5525ded7f854d540ac2e075 F test/e_blobopen.test 29f6055ee453b8e679fe9570c4d3acfedbef821622c5dad16875148c5952ef50 @@ -961,13 +1049,13 @@ F test/e_delete.test ab39084f26ae1f033c940b70ebdbbd523dc4962e F test/e_droptrigger.test 235c610f8bf8ec44513e222b9085c7e49fad65ad0c1975ac2577109dd06fd8fa F test/e_dropview.test 74e405df7fa0f762e0c9445b166fe03955856532e2bb234c372f7c51228d75e7 -F test/e_expr.test 27e905ed17266c745bffe65f56b809c13ae6e225e56aeda1aaec926b32439286 +F test/e_expr.test b950818a48269506d75a41c819003bd77a0893bc4a4f2fdee191bc74109c1a87 F test/e_fkey.test feeba6238aeff9d809fb6236b351da8df4ae9bda89e088e54526b31a0cbfeec5 F test/e_fts3.test 17ba7c373aba4d4f5696ba147ee23fd1a1ef70782af050e03e262ca187c5ee07 F test/e_insert.test f02f7f17852b2163732c6611d193f84fc67bc641fb4882c77a464076e5eba80e F test/e_reindex.test 2b0e29344497d9a8a999453a003cb476b6b1d2eef2d6c120f83c2d3a429f3164 F test/e_resolve.test a61751c368b109db73df0f20fc75fb47e166b1d8 -F test/e_select.test 89fa483f68d868f1be3d6f56180ed42d979979c266e051bf8b5e66a251e6b44a +F test/e_select.test 327a15f14068bbd6f647cedc67210f8680fcb2f05e481a0a855fccd2abfa1292 F test/e_select2.test aceb80ab927d46fba5ce7586ebabf23e2bb0604f F test/e_totalchanges.test c927f7499dc3aa28b9b556b7d6d115a2f0fe41f012b128d16bf1f3b30e9b41e4 F test/e_update.test f46c2554d915c9197548681e8d8c33a267e84528 @@ -1000,7 +1088,7 @@ F test/filefmt.test f393e80c4b8d493b7a7f8f3809a8425bbf4292af1f5140f01cb1427798a2bbd4 F test/filter1.test 590f8ba9a0cd0823b80d89ac75c5ce72276189cef9225d2436adaf1ee87f3727 F test/filter2.tcl 44e525497ce07382915f01bd29ffd0fa49dab3adb87253b5e5103ba8f93393e8 -F test/filter2.test 485cf95d1f6d6ceee5632201ca52a71868599836f430cdee42e5f7f14666e30a +F test/filter2.test 3cc20eaea2ea1ab245197cc4a62468deb460b78f5aa9bd7d5d3353c2fe569bae F test/filterfault.test c08fb491d698e8df6c122c98f7db1c65ffcfcad2c1ab0e07fa8a5be1b34eaa8b F test/fkey1.test e563bcb4cb108ce3f40363cda4f84009dc89a39e2973076e5057ba99fca35378 F test/fkey2.test 1063d65e5923c054cfb8f0555a92a3ae0fa8c067275a33ee1715bd856cdb304c @@ -1013,41 +1101,9 @@ F test/fkey_malloc.test 594a7ea1fbab553c036c70813cd8bd9407d63749 F test/fordelete.test ba98f14446b310f9c9d935b97ec748753d0144a28b356ba30d1f4f6958fdde5c F test/format4.test eeae341953db8b6bda7f549044797c3278a6cc345d11ada81471671b654f8ef4 +F test/fp-speed-1.c ca95152d579530c967240ead1387dc1208052d310dfa22bc9ebded56d4e6c026 +F test/fpconv1.test d5d8aa0c427533006c112fb1957cdd1ea68c1d0709470dabb9ca02c2e4c06ad8 F test/fts-9fd058691.test 78b887e30ae6816df0e1fed6259de4b5a64ad33c -F test/fts1a.test 46090311f85da51bb33bd5ce84f7948359c6d8d7 -F test/fts1b.test 5d8a01aefbecc8b7442b36c94c05eb7a845462d5 -F test/fts1c.test 85a525ce7428907469b4cce13d5563ce542ce64c -F test/fts1d.test a73deace5c18df4a549b12908bade4f05dcf1a2f -F test/fts1e.test 77244843e925560b5a0b70069c3e7ab62f181ed2 -F test/fts1f.test 2d6cb10d8b7a4e6edc321bbdb3982f1f48774714 -F test/fts1i.test 6bfe08cdfdced063a39a50c8601da65e6274d879 -F test/fts1j.test e3797475796043a161e348c46a309664cac83f7f -F test/fts1k.test 65d3b41487b9f738d11b0f00eca375c0ca6bd970 -F test/fts1l.test 15c119ed2362b2b28d5300c0540a6a43eab66c36 -F test/fts1m.test 2d9ca67b095d49f037a914087cc0a61e89da4f0c -F test/fts1n.test a2317dcd27b1d087ee3878b30e0a59c593c98b7a -F test/fts1o.test d1554caede42bba2c82fe613bcc921856c196b752449ead0470fac52a20fd3b8 -F test/fts1porter.test d86e9c3e0c7f8ff95add6582b4b585fb4e02b96d -F test/fts2.test e3fb95f96a650411574efc136f3fb10eef479ed7 -F test/fts2a.test 473a5c8b473a4e21a8e3fddaed1e59666e0c6ab7 -F test/fts2b.test 964abc0236c849c07ca1ae496bb25c268ae94816 -F test/fts2c.test ffb5a35230ac72c4354535c547965ce6824537c0 -F test/fts2d.test b7eaa671ca9a16997f3e5b158ee777ae21052b0b -F test/fts2e.test 2da13dbc2d009105f42196845c1e1ce136c03d38 -F test/fts2f.test cf84096235991709c1e61caa389632aa0a4f976d -F test/fts2g.test 3d26fe171bda6133ebf5a380731d70eaa2ef2f6f73d79769cf8946e622b6d597 -F test/fts2h.test 223af921323b409d4b5b18ff4e51619541b174bb -F test/fts2i.test 1b22451d1f13f7c509baec620dc3a4a754885dd6 -F test/fts2j.test 298fa1670aa21cd445b282d139b70c72e7ade12b -F test/fts2k.test c7ebf4a4937594aa07459e3e1bca1251c1be8659 -F test/fts2l.test 3333336621524cf7d60bb62d6ef6ab69647866ed -F test/fts2m.test 4b30142ead6f3ed076e880a2a464064c5ad58c51 -F test/fts2n.test 12b9c5352128cebd1c6b8395e43788d4b09087c2 -F test/fts2o.test 4054ac7433eb5440f1b1d200cfa449342dc4aabd991759139813e17c73e5bf9a -F test/fts2p.test 4b48c35c91e6a7dbf5ac8d1e5691823cc999aafb -F test/fts2q.test b2fbbe038b7a31a52a6079b215e71226d8c6a682 -F test/fts2r.test b154c30b63061d8725e320fba1a39e2201cadd5e -F test/fts2token.test d8070b241a15ff13592a9ae4a8b7c171af6f445a F test/fts3.test 672a040ea57036fb4b6fdc09027c18d7d24ab654 F test/fts3_common.tcl dffad248f9ce090800e272017d2898005c28ee6314fc1dd5550643a02666907a F test/fts3aa.test 814d60a1ba30b4a71d8f9306a6564bc7b636dd6efacd2ad80306f9b23ef3ebee @@ -1072,11 +1128,11 @@ F test/fts3b.test c15c4a9d04e210d0be67e54ce6a87b927168fbf9c1e3faec8c1a732c366fd491 F test/fts3c.test fc723a9cf10b397fdfc2b32e73c53c8b1ec02958 F test/fts3comp1.test a0f5b16a2df44dd0b15751787130af2183167c0c -F test/fts3conf.test c84bbaec81281c1788aa545ac6e78a6bd6cde2bdbbce2da261690e3659f5a76b +F test/fts3conf.test c9cd45433b6787d48a43e84949aa2eb8b3b3d242bac7276731c1476290d31f29 F test/fts3corrupt.test 6732477c5ace050c5758a40a8b5706c8c0cccd416b9c558e0e15224805a40e57 F test/fts3corrupt2.test e318f0676e5e78d5a4b702637e2bb25265954c08a1b1e4aaf93c7880bb0c67d0 F test/fts3corrupt3.test 0d5b69a0998b4adf868cc301fc78f3d0707745f1d984ce044c205cdb764b491f -F test/fts3corrupt4.test 589e043d1114ea02c83530e459ef5c2d6adce63094e72826ed3bceb02e795116 +F test/fts3corrupt4.test 48bd57baed9654e511709a02dbef2d22ee54c012ad466e8648f0f825233faa08 F test/fts3corrupt5.test 0549f85ec4bd22e992f645f13c59b99d652f2f5e643dac75568bfd23a6db7ed5 F test/fts3corrupt6.test f417c910254f32c0bc9ead7affa991a1d5aec35b3b32a183ffb05eea78289525 F test/fts3cov.test 7eacdbefd756cfa4dc2241974e3db2834e9b372ca215880e00032222f32194cf @@ -1095,8 +1151,9 @@ F test/fts3f.test 8c438d5e1cab526b0021988fb1dc70cf3597b006a33ffd6c955ee89929077fe3 F test/fts3fault.test f4e1342acfe6d216a001490e8cd52afac1f9ffe4a11bbcdcb296129a45c5df45 F test/fts3fault2.test 7b2741e5095367238380b0fcdb837f36c24484c7a5f353659b387df63cf039ec +F test/fts3fault3.test 4a39a1618546776255dc1de306213b600aef87eca589ca8428a70c00fd11961b F test/fts3first.test dbdedd20914c8d539aa3206c9b34a23775644641 -F test/fts3fuzz001.test e3c7b0ce9b04cc02281dcc96812a277f02df03cd7dc082055d87e11eb18aaf56 +F test/fts3fuzz001.test c78afcd8ad712ea0b8d2ed50851a8aab3bc9dc52c64a536291e07112f519357c F test/fts3join.test 1a4d786539b2b79a41c28ef2ac22cacd92a8ee830249b68a7dee4a020848e3bb F test/fts3malloc.test b0e4c133b8d61d4f6d112d8110f8320e9e453ef6 F test/fts3matchinfo.test aa66cc50615578b30f6df9984819ae5b702511cf8a94251ec7c594096a703a4a @@ -1117,15 +1174,16 @@ F test/fts3tok_err.test 52273cd193b9036282f7bacb43da78c6be87418d F test/fts3varint.test 0b84a3fd4eba8a39f3687523804d18f3b322e6d4539a55bf342079c3614f2ada F test/fts4aa.test 0e6bfd6a81695a39b23e448dda25d864e63dda75bde6949c45ddc95426c6c3f5 -F test/fts4check.test 6259f856604445d7b684c9b306b2efb6346834c3f50e8fc4a59a2ca6d5319ad0 +F test/fts4check.test f0ea5e5581951d8ef7a341eea14486daf6c5f516a2f3273b0d5e8cb8a6cd3bd2 F test/fts4content.test 73bbb123420d2c46ef2fb3b24761e9acdb78b0877179d3a5d7d57aada08066f6 F test/fts4docid.test e33c383cfbdff0284685604d256f347a18fdbf01 F test/fts4growth.test 289833c34ad45a5e6e6133b53b6a71647231fb89d36ddcb8d9c87211b6721d7f F test/fts4growth2.test 13ad4e76451af6e6906c95cdc725d01b00044269 F test/fts4incr.test 4e353a0bd886ea984e56fce9e77724fc923b8d0d -F test/fts4langid.test 89e623218935507bca69d076ca254a7a8969dfc681c282b6374feaea8c7de784 +F test/fts4intck1.test 43774c641fdf6607c6ee90c3db8af065a37434d55d6eaf13bafe515e8b0c5729 +F test/fts4langid.test 4be912f42454998e239a2e877600263e0394afbaba03e06cedcc5a08693a345a F test/fts4lastrowid.test 185835895948d5325c7710649824042373b2203149abe8024a9319d25234dfd7 -F test/fts4merge.test e2b2ec21e287d54ec09824ccfb41e66896eeca568fc818ba0e0eb2efd94c35d2 +F test/fts4merge.test 57d093660a5093ae6e9fbd2d17592a88b45bbd66db2703c4b640b28828dbe38b F test/fts4merge2.test 5faa558d1b672f82b847d2a337465fa745e46891 F test/fts4merge3.test 8d9ccb4a3d41c4c617a149d6c4b13ad02de797d0 F test/fts4merge4.test 66fce89934cd9508cbdc67de486558c34912ffb2e8ffe5c9a1bbb9b8a4408ba7 @@ -1140,7 +1198,7 @@ F test/fts4unicode.test 82a9c16b68ba2f358a856226bb2ee02f81583797bc4744061c54401bf1a0f4c9 F test/fts4upfrom.test f25835162c989dffd5e2ef91ec24c4848cc9973093e2d492d1c7b32afac1b49d F test/full.test 6b3c8fb43c6beab6b95438c1675374b95fab245d -F test/func.test 4be8bed4be235e333f1e0ea31e32f5be3c9f456c30780363e7fcb15e3ff3e6bc +F test/func.test 3a29323b640c0552f6e9f1577407ced3a68e7d8c0bc04b61dd6040fa593a3a02 F test/func2.test 772d66227e4e6684b86053302e2d74a2500e1e0f F test/func3.test 600a632c305a88f3946d38f9a51efe145c989b2e13bd2b2a488db47fe76bab6a F test/func4.test 2285fb5792d593fef442358763f0fd9de806eda47dbc7a5934df57ffdc484c31 @@ -1148,6 +1206,7 @@ F test/func6.test 9cc9b1f43b435af34fe1416eb1e318c8920448ea7a6962f2121972f5215cb9b0 F test/func7.test adbfc910385a6ffd15dc47be3c619ef070c542fcb7488964badb17b2d9a4d080 F test/func8.test c4e2ecacf9f16e47a245e7a25fbabcc7e78f9c7c41a80f158527cdfdc6dd299d +F test/func9.test b32d313f679aa9698d52f39519d301c3941823cb72b4e23406c210eadd82c824 F test/fuzz-oss1.test 514dcabb24687818ea949fa6760229eaacad74ca70157743ef36d35bbe01ffb0 F test/fuzz.test 4608c1310cff4c3014a84bcced6278139743e080046e5f6784b0de7b069371d8 F test/fuzz2.test 76dc35b32b6d6f965259508508abce75a6c4d7e1 @@ -1155,21 +1214,21 @@ F test/fuzz4.test c229bcdb45518a89e1d208a21343e061503460ac69fae1539320a89f572eb634 F test/fuzz_common.tcl b7197de6ed1ee8250a4f82d67876f4561b42ee8cbbfc6160dcb66331bad3f830 F test/fuzz_malloc.test f348276e732e814802e39f042b1f6da6362a610af73a528d8f76898fde6b22f2 -F test/fuzzcheck.c 0d90cee9fd7ebecdfbdbe5bdc6fad92fa32410c48ccad747cd9e0ac603b9130c +F test/fuzzcheck.c 69b8549e112fb815931a8c14c7955a0c407ae91a79356eecb82458384f2cb989 F test/fuzzdata1.db 3e86d9cf5aea68ddb8e27c02d7dfdaa226347426c7eb814918e4d95475bf8517 F test/fuzzdata2.db 128b3feeb78918d075c9b14b48610145a0dd4c8d6f1ca7c2870c7e425f5bf31f F test/fuzzdata3.db c6586d3e3cef0fbc18108f9bb649aa77bfc38aba F test/fuzzdata4.db b502c7d5498261715812dd8b3c2005bad08b3a26e6489414bd13926cd3e42ed2 F test/fuzzdata5.db e35f64af17ec48926481cfaf3b3855e436bd40d1cfe2d59a9474cb4b748a52a5 -F test/fuzzdata6.db 92a80e4afc172c24f662a10a612d188fb272de4a9bd19e017927c95f737de6d7 +F test/fuzzdata6.db b8725a5f5cf7a3b7241a9038e57ca7e7cc8c3f4d86b44bd770617bda245ab2b0 F test/fuzzdata7.db 0166b56fd7a6b9636a1d60ef0a060f86ddaecf99400a666bb6e5bbd7199ad1f2 -F test/fuzzdata8.db f6c2f2af4deaaae0ddb3310d509c2659990794aa653dc501b80a0534c3493f80 +F test/fuzzdata8.db 4a53b6d077c6a5c23b609d8d3ac66996fa55ba3f8d02f9b6efdd0214a767a35a F test/fuzzer1.test 3d4c4b7e547aba5e5511a2991e3e3d07166cfbb8 F test/fuzzer2.test a85ef814ce071293bce1ad8dffa217cbbaad4c14 F test/fuzzerfault.test f64c4aef4c9e9edf1d6dc0d3f1e65dcc81e67c996403c88d14f09b74807a42bc F test/fuzzinvariants.c b34530e8431f2cf3591eff588fc7684d6fdef466916fb46141c8c5374a3d8099 -F test/gcfault.test dd28c228a38976d6336a3fc42d7e5f1ad060cb8c -F test/gencol1.test aef8b0670abd4b1ae4cae786b15a43758d86f6cd9f12b381d45d96bb51e597c9 +F test/gcfault.test 4ea410ac161e685f17b19e1f606f58514a2850e806c65b846d05f60d436c5b0d +F test/gencol1.test e169bdfa11c7ed5e9f322a98a7db3afe9e66235750b68c923efee8e1876b46ec F test/genesis.tcl 1e2e2e8e5cc4058549a154ff1892fe5c9de19f98 F test/having.test a89236dd8d55aa50c4805f82ac9daf64d477a44d712d8209c118978d0ca21ec9 F test/hexlit.test 4a6a5f46e3c65c4bf1fa06f5dd5a9507a5627751 @@ -1205,6 +1264,7 @@ F test/index7.test b238344318e0b4e42126717f6554f0e7dfd0b39cecad4b736039b43e1e3b6eb3 F test/index8.test caa097735c91dbc23d8a402f5e63a2a03c83840ba3928733ed7f9a03f8a912a3 F test/index9.test 2ac891806a4136ef3e91280477e23114e67575207dc331e6797fa0ed9379f997 +F test/indexA.test 11d84f6995e6e5b9d8315953fb1b6d29772ee7c7803ee9112715e7e4dd3e4974 F test/indexedby.test f21eca4f7a6ffe14c8500a7ad6cd53166666c99e5ccd311842a28bc94a195fe0 F test/indexexpr1.test 62558b1cfd7ccbe7bc015849cc6d1a13ef124e80cbd5b3a98dc66c3c9cce0cf4 F test/indexexpr2.test 1c382e81ef996d8ae8b834a74f2a9013dddf59214c32201d7c8a656d739f999a @@ -1235,41 +1295,41 @@ F test/join2.test 8561fe82ce434ac96de91544072e578dc2cadddf2d9bc9cd802f866a9b92502e F test/join3.test 6f0c774ff1ba0489e6c88a3e77b9d3528fb4fda0 F test/join4.test 1a352e4e267114444c29266ce79e941af5885916 -F test/join5.test 91f1f4c7d81fd87b58e9ba7cf4a2b5d39e3583b4f8e498a162722a60259c5208 +F test/join5.test 7cc3f3595bb41e60f3f96d5cb6dd8cfcbc31212f0136bba6fc081c082994a94a F test/join6.test f809c025fa253f9e150c0e9afd4cef8813257bceeb6f46e04041228c9403cc2c F test/join7.test 2268dcbb54b724391dda3748ea95c60d960607ffeed67885675998e7117697f6 F test/join8.test d384d63985e3991c404afccadaf3efd1cdf9cd72680167f80e3cb80b95c18c68 F test/join9.test 9056ddd3b0c0f4f9d658f4521038d9a37dc23ead8ca9a505d0b0db2b6a471e05 -F test/joinA.test 7eab225dc1c1ab258a5e62513a4ed7cabbd3db971d59d5d92f4fb6fa14c12f6a +F test/joinA.test 6ac4efdbb1eb9ca398162c5bc5623a757803b04bb4d76453c8563a0bdc2f73bd F test/joinB.test 1b2ba3fc8568b49411787fccbf540570c148e9b6a53a30f80691cb6268098ded F test/joinC.test 1f1a602c2127f55f136e2cbd3bf2d26546614bf8cffe5902ec1ac9c07f87f207 F test/joinD.test 2ce62e7353a0702ca5e70008faf319c1d4686aa19fba34275c6d1da0e960be28 F test/joinE.test d5d182f3812771e2c0d97c9dcf5dbe4c41c8e21c82560e59358731c4a3981d6b F test/joinF.test 53dd66158806823ea680dd7543b5406af151b5aafa5cd06a7f3231cd94938127 -F test/joinH.test 705157cf9b9b7c207caf960812a7d0e4dc1dd45aa5fb2b563f12df59088645f3 +F test/joinH.test 84198ea42bf78b79fe399c0567218cd6df36c50c6dd27d9c4aab221acaad929e F test/journal1.test c7b768041b7f494471531e17abc2f4f5ebf9e5096984f43ed17c4eb80ba34497 F test/journal2.test 9dac6b4ba0ca79c3b21446bbae993a462c2397c4 F test/journal3.test 7c3cf23ffc77db06601c1fcfc9743de8441cb77db9d1aa931863d94f5ffa140e F test/jrnlmode.test 9b5bc01dac22223cb60ec2d5f97acf568d73820794386de5634dcadbea9e1946 F test/jrnlmode2.test 8759a1d4657c064637f8b079592651530db738419e1d649c6df7048cd724363d F test/jrnlmode3.test 556b447a05be0e0963f4311e95ab1632b11c9eaa -F test/json/README.md 506af1f54574b524106acb50d1a341ab5ddfa6d83fe25095007892b07e663e85 +F test/json/README.md 63e3e589e1df8fd3cc1588ba1faaff659214003f8b77a15af5c6452b35e30ee2 F test/json/json-generator.tcl dc0dd0f393800c98658fc4c47eaa6af29d4e17527380cd28656fb261bddc8a3f -F test/json/json-q1.txt 335a7c8ab291d354f33b7decc9559e99a2823d4142291c4be7aa339a631f3c2d +F test/json/json-q1.txt 65f9d1cdcc4cffa9823fb73ed936aae5658700cd001fde448f68bfb91c807307 F test/json/json-speed-check.sh 8b7babf530faa58bd59d6d362cec8e9036a68c5457ff46f3b1f1511d21af6737 x -F test/json101.test 94126d4291d4a00e45f6988ce885c410de69243490e46e70e9946cb6e6f9ea02 -F test/json102.test 13dc9e7b7f359ecb861e02f9bd7019f7342a63d1c354273b0a8f3904050560a8 +F test/json101.test bc05d2476fd6f7ead31ec05b43d1b24b2b193ae112fd8f0d2ed56d9a904f9fa5 +F test/json102.test 4c69694773a470f1fda34e5f4ba24920b35184fb66050b450fc2ef9ab5ad310b F test/json103.test 53df87f83a4e5fa0c0a56eb29ff6c94055c6eb919f33316d62161a8880112dbe F test/json104.test 1b844a70cddcfa2e4cd81a5db0657b2e61e7f00868310f24f56a9ba0114348c1 F test/json105.test 11670a4387f4308ae0318cadcbd6a918ea7edcd19fbafde020720a073952675d F test/json501.test f71710f60fa45b19dc336fbaac9e8362f70f80cf81badefdb845ed3f7c7c2ccc F test/json502.test 98c38e3c4573841028a1381dfb81d4c3f9b105d39668167da10d055e503f6d0b F test/keyword1.test 37ef6bba5d2ed5b07ecdd6810571de2956599dff -F test/kvtest.c feb4358fb022da8ebd098c45811f2f6507688bb6c43aa72b3e840df19026317b +F test/kvtest.c 6e0228409ea7ca0497dad503fbd109badb5e59545d131014b6aaac68b56f484a F test/lastinsert.test 42e948fd6442f07d60acbd15d33fb86473e0ef63 F test/laststmtchanges.test ae613f53819206b3222771828d024154d51db200 F test/lemon-test01.y 58b764610fd934e189ffbb0bbfa33d171b9cb06019b55bdc04d090d6767e11d7 -F test/like.test 5fe0bc37f307aef0a453ce2de4632bdfc0759448f0421c39f6d53caefe905fac +F test/like.test 242ee7f5d08a031144c0daf63bbd7e7710c847ccf387a83347e0b61b3aa69526 F test/like2.test d3be15fefee3e02fc88942a9b98f26c5339bbdef7783c90023c092c4955fe3d3 F test/like3.test a76e5938fadbe6d32807284c796bafd869974a961057bc5fc5a28e06de98745c F test/limit.test 350f5d03c29e7dff9a2cde016f84f8d368d40bcd02fa2b2a52fa10c4bf3cbfaf @@ -1315,9 +1375,9 @@ F test/mem5.test c6460fba403c5703141348cd90de1c294188c68f F test/memdb.test c1f2a343ad14398d5d6debda6ea33e80d0dafcc7 F test/memdb1.test 2c4e9cc10d21c6bf4e217d72b7f6b8ba9b2605971bb2c5e6df76018e189f98f5 -F test/memdb2.test 7789975b96b0726032a22c1afc026592c7ff175bf05be11f1d640791541a77ea +F test/memdb2.test 4ba1fc09e2f51df80d148a540e4a3fa66d0462e91167b27497084de4d1f6b5b4 F test/memjournal.test 70f3a00c7f84ee2978ad14e831231caa1e7f23915a2c54b4f775a021d5740c6c -F test/memjournal2.test 6b9083cfaab9a3281ec545c3da2487999e8025fb7501bbae10f713f80c56454c +F test/memjournal2.test dbc2c5cb5f7b38950f4f6dc3e73fcecf0fcbed3fc32c7ce913bba164d288da1e F test/memleak.test 10b9c6c57e19fc68c32941495e9ba1c50123f6e2 F test/memsubsys1.test 86b8158752af9188ed5b32a30674a1ef71183e6bc4e6808e815cd658ca9058a6 F test/memsubsys2.test 774b93cb09ca50d1b759bb7c645baa2a9ce172edc3a3da67d5150a26a9fc2a08 @@ -1346,7 +1406,7 @@ F test/multiplex2.test 580ca5817c7edbe4cc68fa150609c9473393003a F test/multiplex3.test fac575e0b1b852025575a6a8357701d80933e98b5d2fe6d35ddaa68f92f6a1f7 F test/multiplex4.test e8ae4c4bd70606a5727743241f13b5701990abe4 -F test/mutex1.test 4d7ecb155ae5ba9ca6f1817c1c74d51b5bb284d7f599de1859a9f2c9a1ca0d38 +F test/mutex1.test 42cb5e244c3a77bb0ef2b967e06fa5e7ba7d32d90a9b20bed98f6f5ede185a25 F test/mutex2.test bfeaeac2e73095b2ac32285d2756e3a65e681660 F test/nan.test 437d40e6d0778b050d7750726c0cbd2c9936b81962926e8f8c48ca698f00f4d1 F test/nockpt.test 8c43b25af63b0bd620cf1b003529e37b6f1dc53bd22690e96a1bd73f78dde53a @@ -1393,9 +1453,9 @@ F test/parser1.test 6ccdf5e459a5dc4673d3273dc311a7e9742ca952dd0551a6a6320d27035ce4b3 F test/pcache.test c8acbedd3b6fd0f9a7ca887a83b11d24a007972b F test/pcache2.test af7f3deb1a819f77a6d0d81534e97d1cf62cd442 -F test/pendingrace.test cbdf0f74bc939fb43cebad64dda7a0b5a3941a10b7e9cc2b596ff3e423a18156 +F test/pendingrace.test 6aa33756b950c4529f79c4f3817a9a1e4025bd0d9961571a05c0279bd183d9c6 F test/percentile.test 4243af26b8f3f4555abe166f723715a1f74c77ff -F test/permutations.test 8bd6b6db541e2a7f9bb894be99ef5c00526b23762c4a00c574e1cba697495125 +F test/permutations.test f7caf8dd5c7b1da74842a48df116f7f193399c656d4ffc805cd0d9658568c675 F test/pg_common.tcl 3b27542224db1e713ae387459b5d117c836a5f6e328846922993b6d2b7640d9f F test/pragma.test 57a36226218c03cfb381019fe43234b2cefbd8a1f12825514f906a17ccf7991e F test/pragma2.test e5d5c176360c321344249354c0c16aec46214c9f @@ -1411,7 +1471,7 @@ F test/pushdown.test 1495a09837a1cedfc0adf07ba42dc6b83be05a2c15de331b67c39a0e22078238 F test/queryonly.test 5f653159e0f552f0552d43259890c1089391dcca F test/quick.test 1681febc928d686362d50057c642f77a02c62e57 -F test/quickcheck.test f86b25b33455af0189b4d3fe7bd6e553115e80b2d7ec9bbe9a6b37fce0881bfe +F test/quickcheck.test a4b7e878cd97e46108291c409b0bf8214f29e18fddd68a42bc5c1375ad1fb80a F test/quota-glob.test 32901e9eed6705d68ca3faee2a06b73b57cb3c26 F test/quota.test bfb269ce81ea52f593f9648316cd5013d766dd2a F test/quota2.test 7dc12e08b11cbc4c16c9ba2aa2e040ea8d8ab4b8 @@ -1424,7 +1484,7 @@ F test/regexp1.test 8f2a8bc1569666e29a4cee6c1a666cd224eb6d50e2470d1dc1df995170f3e0f1 F test/regexp2.test 55ed41da802b0e284ac7e2fe944be3948f93ff25abbca0361a609acfed1368b5 F test/reindex.test cd9d6021729910ece82267b4f5e1b5ac2911a7566c43b43c176a6a4732e2118d -F test/releasetest_data.tcl b550dd1b122a9c969df794d05ea272df535f10ff1a245062e7ba080822378016 +F test/releasetest_data.tcl 80ef3941bf7ad136f4dc3d8960786f10a4f488797238171bdd757cc6eb4c3efa F test/resetdb.test 54c06f18bc832ac6d6319e5ab23d5c8dd49fdbeec7c696d791682a8006bd5fc3 F test/resolver01.test f4022acafda7f4d40eca94dbf16bc5fc4ac30ceb F test/returning1.test db532cde29d6aebbc48c6ddc3149b30476f8e69ca7a2c4b53986c7635e6fd8ec @@ -1432,7 +1492,7 @@ F test/rollback.test 06680159bc6746d0f26276e339e3ae2f951c64812468308838e0a3362d911eaa F test/rollback2.test 3f3a4e20401825017df7e7671e9f31b6de5fae5620c2b9b49917f52f8c160a8f F test/rollbackfault.test 0e646aeab8840c399cfbfa43daab46fd609cf04a -F test/round1.test 1bb32cf3fc505eed9e86b5e523d07e15d4428189665524587512fbcc85d114bb +F test/round1.test 29c3c9039936ed024d672f003c4d35ee11c14c0acb75c5f7d6188ff16190cfd4 F test/rowallock.test 3f88ec6819489d0b2341c7a7528ae17c053ab7cc F test/rowhash.test 0bc1d31415e4575d10cacf31e1a66b5cc0f8be81 F test/rowid.test e29025be95baf6b32f0d5edef59a7633028325896a98f1caa8019559ca910350 @@ -1444,8 +1504,8 @@ F test/rowvalue6.test d19b54feb604d5601f8614b15e214e0774c01087 F test/rowvalue7.test c1cbdbf407029db01f87764097c6ac02a1c5a37efd2776eff32a9cdfdf6f2dba F test/rowvalue8.test 5900eddad9e2c3c2e26f1a95f74aafc1232ee5e0 -F test/rowvalue9.test 138252b53b835208a5712e01595403a0ae32b4bc58284d9fe6bea10e58203fe4 -F test/rowvalueA.test 51f79b6098c193f838168752c9640f4eae6c63346bf64b5bed4f4e22fe2c71d0 +F test/rowvalue9.test 7499a8fd7ca3a3f0e19d94e135355439aa2b596f86b775ca8de79672da2ca378 +F test/rowvalueA.test be8d6ad8b476eb24c151bb20bfd487e0d50c5e99618b7b0e656035069d2fc2cf F test/rowvaluefault.test 963ae9cdaed30a85a29668dd514e639f3556cae903ee9f172ea972d511c54fff F test/rowvaluevtab.test cd9747bb3f308086944c07968f547ad6b05022e698d80b9ffbdfe09ce0b8da6f F test/rtree.test 0c8d9dd458d6824e59683c19ab2ffa9ef946f798 @@ -1458,7 +1518,7 @@ F test/savepoint7.test cde525ea3075283eb950cdcdefe23ead4f700daa F test/savepointfault.test f044eac64b59f09746c7020ee261734de82bf9b2 F test/scanstatus.test b249328caf4d317e71058006872b8012598a5fa045b30bf24a81eeff650ab49e -F test/scanstatus2.test 9a00becb1d60d168944f8e2f3585d44d46123aa95c5c7c25563309e1f15f924d +F test/scanstatus2.test 317670daf7f3eef48a9598cb7800ba8eccab51949cf52bca3f7da3b83a0c1c8c F test/schema.test 5dd11c96ba64744de955315d2e4f8992e447533690153b93377dffb2a5ef5431 F test/schema2.test 906408621ea881fdb496d878b1822572a34e32c5 F test/schema3.test 8ed4ae66e082cdd8b1b1f22d8549e1e7a0db4527a8e6ee8b6193053ee1e5c9ce @@ -1471,7 +1531,7 @@ F test/seekscan1.test 31af16e3bb3203d153aea320939c5da97ec44705c2710d153c06a01397d45b09 F test/select1.test 692e84cfa29c405854c69e8a4027183d64c22952866a123fabbce741a379e889 F test/select2.test 352480e0e9c66eda9c3044e412abdf5be0215b56 -F test/select3.test 8d04b66df7475275a65f7e4a786d6a724c30bd9929f8ae5bd59c8d3d6e75e6cd +F test/select3.test 180223af31e1ca5537dd395ef9708ae18e651a233777fd366fd0d75469fc19c6 F test/select4.test f0684d3da3bccacbe2a1ebadf6fb49d9df6f53acb4c6ebc228a88d0d6054cc7b F test/select5.test 8afc5e5dcdebc2be54472e73ebd9cd1adef1225fd15d37a1c62f969159f390ae F test/select6.test 9b2fb4ffedf52e1b5703cfcae1212e7a4a063f014c0458d78d29aca3db766d1f @@ -1485,10 +1545,10 @@ F test/selectE.test a8730ca330fcf40ace158f134f4fe0eb00c7edbf F test/selectF.test 21c94e6438f76537b72532fa9fd4710cdd455fc3 F test/selectG.test 089f7d3d7e6db91566f00b036cb353107a2cca6220eb1cb264085a836dae8840 -F test/selectH.test 88237ded5925adfb3f27fdafb5428c2ffc4d61e313bceb854e225ffc3ef0d206 +F test/selectH.test 0b54599f1917d99568c9b929df22ec6261ed7b6d2f02a46b5945ef81b7871aac F test/session.test 78fa2365e93d3663a6e933f86e7afc395adf18be F test/sessionfuzz-data1.db 1f8d5def831f19b1c74571037f0d53a588ea49a6c4ca2a028fc0c27ef896dbcb -F test/sessionfuzz.c 5eef09af01eeff6f20250ae4c0112c2e576e4d2f2026cc9a49dc5be6886fa6ee +F test/sessionfuzz.c 666b47e177c7b25f01ba645d41fb9131d2d54ae673f0d81c08f5af2b3e6ecbda F test/shared.test f022874d9d299fe913529dc10f52ad5a386e4e7ff709270b9b1111b3a0f3420a F test/shared2.test 03eb4a8d372e290107d34b6ce1809919a698e879 F test/shared3.test f8cd07c1a2b7cdb315c01671a0b2f8e3830b11ef31da6baa9a9cd8da88965403 @@ -1501,8 +1561,8 @@ F test/sharedB.test 1a84863d7a2204e0d42f2e1606577c5e92e4473fa37ea0f5bdf829e4bf8ee707 F test/shared_err.test 32634e404a3317eeb94abc7a099c556a346fdb8fb3858dbe222a4cbb8926a939 F test/sharedlock.test 5ede3c37439067c43b0198f580fd374ebf15d304 -F test/shell1.test 300b77328aaafb9f3e7a53a26e4162fbf92181d92251d259ff105a2275ff998d -F test/shell2.test 09a202f57e7cd99788537f763e0845796a173fcea06a0d199a08d69446fe1daf +F test/shell1.test 2191c892d8256b1b6cccb4fca894cfc2e748450cf422e6ec80a320a0d538b6df +F test/shell2.test 35226c070a8c7f64fd016dfac2a0db2a40f709b3131f61daacd9dad61536c9cb F test/shell3.test 91febeac0412812bf6370abb8ed72700e32bf8f9878849414518f662dfd55e8a F test/shell4.test 9abd0c12a7e20a4c49e84d5be208d2124fa6c09e728f56f1f4bee0f02853935f F test/shell5.test c8b6c54f26ec537f8558273d7ed293ca3725ef42e6b12b8f151718628bd1473b @@ -1523,12 +1583,12 @@ F test/snapshot2.test 8d6ff5dd9cc503f6e12d408a30409c3f9c653507b24408d9cd7195931c89bc54 F test/snapshot3.test 8744313270c55f6e18574283553d3c5c5fe4c5970585663613a0e75c151e599b F test/snapshot4.test d4e9347ef2fcabc491fc893506c7bbaf334da3be111d6eb4f3a97cc623b78322 -F test/snapshot_fault.test f6c5ef7cb93bf92fbb4e864ecc5c87df7d3a250064838822db5b4d3a5563ede4 +F test/snapshot_fault.test 129234ceb9b26a0e1000e8563a16e790f5c1412354e70749cbd78c3d5d07d60a F test/snapshot_up.test a0a29c4cf33475fcef07c3f8e64af795e24ab91b4cc68295863402a393cdd41c F test/soak.test 18944cf21b94a7fe0df02016a6ee1e9632bc4e8d095a0cb49d95e15d5cca2d5c F test/softheap1.test 843cd84db9891b2d01b9ab64cef3e9020f98d087 F test/sort.test f86751134159abb5e5fd4381a0d7038c91013638cd1e3fa1d7850901f6df6196 -F test/sort2.test cc23b7c19d684657559e8a55b02f7fcee03851d0 +F test/sort2.test 2f8c66402a03adebe77ce7aafca129fbf32df27d6c9b8f7a9f1b958e39f56da8 F test/sort3.test 1480ed7c4c157682542224e05e3b75faf4a149e5 F test/sort4.test cca6f4b0b5255882645bbbe346a6a9f4a5c7b6a18513a6a7bf4ac1c4761ddc19 F test/sort5.test 6b43ae0e2169b5ceed441844492e55ba7f1ae0790528395ddf7888ab3094525d @@ -1542,23 +1602,23 @@ F test/speed4.test abc0ad3399dcf9703abed2fff8705e4f8e416715 F test/speed4p.explain 6b5f104ebeb34a038b2f714150f51d01143e59aa F test/speed4p.test 377a0c48e5a92e0b11c1c5ebb1bc9d83a7312c922bc0cb05970ef5d6a96d1f0c -F test/speedtest1.c 9703465daf778dd90bad7adadc1d2ee205ec90a79437cababab0a4111190f0c8 +F test/speedtest1.c f9505ad6f9c2c3c488a370a2d193e9603a030e51126ef3ecfeb056d21f0e7ad5 F test/spellfix.test 951a6405d49d1a23d6b78027d3877b4a33eeb8221dcab5704b499755bb4f552e F test/spellfix2.test dfc8f519a3fc204cb2dfa8b4f29821ae90f6f8c3 F test/spellfix3.test 0f9efaaa502a0e0a09848028518a6fb096c8ad33 F test/spellfix4.test 51c7c26514ade169855c66bcf130bd5acfb4d7fd090cc624645ab275ae6a41fb -F test/sqldiff1.test 182058e09c7082de5c6a470ff9c291337bbeb650052c2cc68fbb3d7e25861d91 +F test/sqldiff1.test 1b7ab4f312442c5cc6b3a5f299fa8ca051416d1dd173cb1126fd51bf64f2c3fb F test/sqllimits1.test b28e5cc8d337aaf290614d96a47e8fbfb720bb7ad35620c9d5432996fd413ac4 F test/sqllog.test 6af6cb0b09f4e44e1917e06ce85be7670302517a F test/startup.c 1beb5ca66fcc0fce95c3444db9d1674f90fc605499a574ae2434dcfc10d22805 F test/stat.test 123212a20ceb496893d5254a5f6c76442ce549fdc08d1702d8288a2bbaac8408 -F test/statfault.test 55f86055f9cd7b2d962a621b8a04215c1cebd4eaaecde92d279442327fe648a0 +F test/statfault.test 064f43379e4992b5221b7d9ac887c313b3191f85cce605d78e416fc4045da64e F test/stmt.test 54ed2cc0764bf3e48a058331813c3dbd19fc1d0827c3d8369914a5d8f564ec75 F test/stmtvtab1.test 6873dfb24f8e79cbb5b799b95c2e4349060eb7a3b811982749a84b359468e2d5 F test/strict1.test 4d2b492152b984fd7e8196d23eb88e2ccb0ef9e46ca2f96c2ce7147ceef9d168 F test/strict2.test b22c7a98b5000aef937f1990776497f0e979b1a23bc4f63e2d53b00e59b20070 F test/subjournal.test 8d4e2572c0ee9a15549f0d8e40863161295107e52f07a3e8012a2e1fdd093c49 -F test/subquery.test 3a1a5b600b8d4f504d2a2c61f33db820983dba94a0ef3e4aedca8f0165eaecb8 +F test/subquery.test 312c5d26304b0e93a56ba2cb9d4480b8a1c8217e3b2b8f8be2bfb0b2458ac3a7 F test/subquery2.test 90cf944b9de8204569cf656028391e4af1ccc8c0cc02d4ef38ee3be8de1ffb12 F test/subselect.test 0966aa8e720224dbd6a5e769a3ec2a723e332303 F test/substr.test a673e3763e247e9b5e497a6cacbaf3da2bd8ec8921c0677145c109f2e633f36b @@ -1575,7 +1635,7 @@ F test/syscall.test a39d9a36f852ae6e4800f861bc2f2e83f68bbc2112d9399931ecfadeabd2d69d F test/sysfault.test c9f2b0d8d677558f74de750c75e12a5454719d04 F test/tabfunc01.test 54f27eacd054aa528a8b6e3331192c484104f30aaee351ad035f2b39a00f87c4 -F test/table.test eb3463b7add9f16a5bb836badf118cf391b809d09fdccd1f79684600d07ec132 +F test/table.test 7862a00b58b5541511a26757ea9c5c7c3f8298766e98aa099deec703d9c0a8e0 F test/tableapi.test ecbcc29c4ab62c1912c3717c48ea5c5e59f7d64e4a91034e6148bd2b82f177f4 F test/tableopts.test dba698ba97251017b7c80d738c198d39ab747930 F test/tclsqlite.test ad0bbd92edabe64cc91d990a0748142fe5ab962d74ac71fa3bfa94d50d2f4c87 @@ -1587,8 +1647,8 @@ F test/temptable3.test d11a0974e52b347e45ee54ef1923c91ed91e4637 F test/temptrigger.test 38f0ca479b1822d3117069e014daabcaacefffcc F test/tester.tcl 68454ef88508c196d19e8694daa27bff7107a91857799eaa12f417188ae53ede -F test/testrunner.tcl 59490f189cac99b16b0376d0cc0a7ecfb753a84b89c9f4c361af337d88db53ac -F test/testrunner_data.tcl 8169c68654ac8906833b8a6aadca973358a441ebf88270dd05c153e5f96f76b8 +F test/testrunner.tcl 14c8b8ece841b1dd17516a0dc9c7ad9b5f4d4db7987974d3fdf66ae56b2a71fa +F test/testrunner_data.tcl 7f73f93634d32dafc857ed491b840f371113d09fde6a8bfb9e47b938d47b8c85 F test/thread001.test a0985c117eab62c0c65526e9fa5d1360dd1cac5b03bde223902763274ce21899 F test/thread002.test c24c83408e35ba5a952a3638b7ac03ccdf1ce4409289c54a050ac4c5f1de7502 F test/thread003.test ee4c9efc3b86a6a2767516a37bd64251272560a7 @@ -1596,7 +1656,7 @@ F test/thread005.test 50d10b5684399676174bd96c94ad4250b1a2c8b6 F test/thread1.test df115faa10a4ba1d456e9d4d9ec165016903eae4 F test/thread2.test f35d2106452b77523b3a2b7d1dcde2e5ee8f9e46 -F test/thread3.test 5f53b6a8e7391d8653116fd0bee4f9774efee4410e039990821de39c6b4375a9 +F test/thread3.test a12656a56cdf67acb6a2ff7638826c6d6a645f79909d86df521045ad31cf547d F test/thread_common.tcl 334639cadcb9f912bf82aa73f49efd5282e6cadd F test/threadtest1.c 6029d9c5567db28e6dc908a0c63099c3ba6c383b F test/threadtest2.c a70a8e94bef23339d34226eb9521015ef99f4df8 @@ -1604,6 +1664,7 @@ F test/threadtest4.c c1e67136ceb6c7ec8184e56ac61db28f96bd2925 F test/threadtest5.c 9b4d782c58d8915d7e955ff8051f3d03628bda0d33b82971ea8c0f2f2808c421 F test/time-wordcount.sh 8e0b0f8109367827ad5d58f5cc849705731e4b90 +F test/timediff1.test d982b2b5f1b22f58380c5db94ea5b17518d50ad0c55583cf0ecfa0b176e20888 F test/tkt-02a8e81d44.test 6c80d9c7514e2a42d4918bf87bf6bc54f379110c F test/tkt-18458b1a.test 6a62cb1ee50fa3c620da59e3a6f531eb38fceaf7e2166203816b724524e6f1d6 F test/tkt-26ff0c2d1e.test c15bec890c4d226c0da2f35ff30f9e84c169cfef90e73a8cb5cec11d723dfa96 @@ -1653,7 +1714,7 @@ F test/tkt-bdc6bbbb38.test fc38bb09bdd440e3513a1f5f98fc60a075182d7d F test/tkt-c48d99d690.test ba61977d62ab612fc515b3c488a6fbd6464a2447 F test/tkt-c694113d5.test 82c461924ada5c14866c47e85535b0b0923ba16a2e907e370061a5ca77f65d77 -F test/tkt-cbd054fa6b.test 708475ef4d730a6853512c8ce363bcbd3becf0e26826e1f4cd46e2f52ff38edf +F test/tkt-cbd054fa6b.test 6ec9f1a5721fba74a83397683c50f472df68a0a749d193a537264eda3ad6d113 F test/tkt-d11f09d36e.test d999b548fef885d1d1afa49a0e8544ecf436869d F test/tkt-d635236375.test 9d37e988b47d87505bc9445be0ca447002df5d09 F test/tkt-d82e3f3721.test bcc0dfba658d15bab30fd4a9320c9e35d214ce30 @@ -1758,7 +1819,7 @@ F test/trans3.test 91a100e5412b488e22a655fe423a14c26403ab94 F test/transitive1.test f8ee983600b33d167da1885657f064aec404e1c0d0bc8765fdf163f4c749237a F test/trigger1.test 02cc64dc98278816c1c1ed8e472e18db8edbad88f37018bf46223e9614831963 -F test/trigger2.test 6e35bd7321c49e63d540aee980eb95dec63e1d1caca175224101045bcc80871f +F test/trigger2.test 30fcb3a6aa6782020d47968735ee6086ed795f73a7affa9406c8d5a36e7b5265 F test/trigger3.test aa640bb2bbb03edd5ff69c055117ea088f121945 F test/trigger4.test 74700b76ebf3947b2f7a92405141eb2cf2a5d359 F test/trigger5.test 619391a3e9fc194081d22cefd830d811e7badf83 @@ -1784,7 +1845,7 @@ F test/types.test bf816ce73c7dfcfe26b700c19f97ef4050d194ff F test/types2.test 1aeb81976841a91eef292723649b5c4fe3bc3cac F test/types3.test 99e009491a54f4dc02c06bdbc0c5eea56ae3e25a -F test/unhex.test 47b547f4b35e4f6525ecac7c7839bd3ae4eb4613d4e8932592eff55da83308f1 +F test/unhex.test b7f1b806207cb77fa31c3e434fe92fba524464e3e9356809bfcc28f15af1a8b7 F test/unionall.test eb9afa030897af75fd2f0dd28354ef63c8a5897b6c76aa1f15acae61a12eabcf F test/unionall2.test 71e8fa08d5699d50dc9f9dc0c9799c2e7a6bb7931a330d369307a4df7f157fa1 F test/unionallfault.test 652bfbb630e6c43135965dc1e8f0a9a791da83aec885d626a632fe1909c56f73 @@ -1794,15 +1855,15 @@ F test/unique2.test 3674e9f2a3f1fbbfd4772ac74b7a97090d0f77d2 F test/unixexcl.test d936ba2b06794018e136418addd59a2354eeae97 F test/unordered.test 0edaf3411d300693bca595897c5201421c6c5ec787990a1dfe2f7f60ae93f1e2 -F test/update.test 90772ede84cfc779fc3d31884a84ec4c74deb501eeb09a1c6c91c03d8e94c0d8 +F test/update.test 85d3f46d0863033370bd881b1097f5694369a8730e53c5f85d96f32b7b310b47 F test/update2.test 67455bc61fcbcf96923c45b3bc4f87bc72be7d67575ad35f134906148c7b06d3 F test/upfrom1.tcl 8859d9d437f03b44174c4524a7a734a391fd4526fcff65be08285dafc9dc9041 F test/upfrom1.test 8cb06689e99cd707d884faa16da0e8eb26ff658bb01c47ddf72fadade666e6e1 F test/upfrom2.test 66f3ebf721b3cebd922faee5c386bf244f816d416b57c000753ff51af62328a1 F test/upfrom3.test 6130f24ebf97f5ea865e5d2a14a2d543fe5428a62e87cc60f62d875e45c1f5f0 -F test/upfrom4.test 1cd82e9423e02b1f63d069e8665c6c3932ec424fd0043d033cc0ba99abf33236 +F test/upfrom4.test 78f742a6577c91a7a55c64edb8811004e7c6aa99b8d57b2320f70a918c357807 F test/upfromfault.test 3a10075a0043f0c4fad6614b2c371f88a8ba5a4acab68b907438413865d6a8d6 -F test/upsert1.test b0ae2f58680c5205b4bc1cdeed3c3d444057c506f6c44494fa3eac60731d68a2 +F test/upsert1.test a512e2f884d3a36159fce2e45108c236f78ae38e35bda55f4050db580ceb25d3 F test/upsert2.test 720e94d09f7362a282bc69b3c6b83d51daeaaf0440eb4920a08b86518b8c7496 F test/upsert3.test 88d7d590a1948a9cb6eac1b54b0642f67a9f35a1fc0f19b200e97d5d39e3179c F test/upsert4.test 25d2a1da92f149331ae0c51ca6e3eee78189577585eab92de149900d62994fa5 @@ -1812,7 +1873,7 @@ F test/uri2.test 9d3ba7a53ee167572d53a298ee4a5d38ec4a8fb7 F test/userauth01.test e740a2697a7b40d7c5003a7d7edaee16acd349a9 F test/utf16align.test 9fde0bb5d3a821594aa68c6829ab9c5453a084384137ebb9f6153e2d678039da -F test/vacuum-into.test e0e3406845be4cf1b44db354179e5d9437e38bc267e4ac8e8dc617f9c3c903ab +F test/vacuum-into.test 35dc6f79b563f91c61822f61797363e97fed1bf28f1f722688b98d43f1980d76 F test/vacuum.test ce91c39f7f91a4273bf620efad21086b5aa6ef1d F test/vacuum2.test 9fd45ce6ce29f5614c249e03938d3567c06a9e772d4f155949f8eafe2d8af520 F test/vacuum3.test d9d9a04ee58c485b94694fd4f68cffaba49c32234fdefe1ac1a622c5e17d4ce3 @@ -1825,7 +1886,7 @@ F test/view.test d4c4281e1679245829db35597817282f60dc513fc39cc5439078f009bd118487 F test/view2.test db32c8138b5b556f610b35dfddd38c5a58a292f07fda5281eedb0851b2672679 F test/view3.test ad8a8290ee2b55ff6ce66c9ef1ce3f1e47926273a3814e1c425293e128a95456 -F test/vt02.c f4a357c8180d71120ca2b466a8df48d9c40fc50873694840327d9647450485f3 +F test/vt02.c 5b44ac67b1a283fedecf2d6e2ceda61e7a157f01d44dcb4490dcb1e87d057060 F test/vtab1.test 09a72330d0f31eda2ffaa828b06a6b917fb86250ee72de0301570af725774c07 F test/vtab2.test 14d4ab26cee13ba6cf5c5601b158e4f57552d3b055cdd9406cf7f711e9c84082 F test/vtab3.test b45f47d20f225ccc9c28dc915d92740c2dee311e @@ -1882,6 +1943,7 @@ F test/walro.test cb438d05ba0d191f10b688e39c4f0cd5b71569a1d1f4440e5bdf3c6880e08c20 F test/walro2.test 33955a6fd874dd9724005e17f77fef89d334b3171454a1256fe4941a96766cdc F test/walrofault.test c70cb6e308c443867701856cce92ad8288cd99488fa52afab77cca6cfd51af68 +F test/walseh1.test bae700eb99519b6d5cd3f893c04759accc5a59c391d4189fe4dd6995a533442b F test/walsetlk.test 34c901443b31ab720afc463f5b236c86ca5c4134402573dce91aa0761de8db5a F test/walshared.test 42e3808582504878af237ea02c42ca793e8a0efaa19df7df26ac573370dbc7a3 F test/walslow.test c05c68d4dc2700a982f89133ce103a1a84cc285f @@ -1895,7 +1957,7 @@ F test/where4.test 4a371bfcc607f41d233701bdec33ac2972908ba8 F test/where5.test fdf66f96d29a064b63eb543e28da4dfdccd81ad2 F test/where6.test 5da5a98cec820d488e82708301b96cb8c18a258b -F test/where7.test 1c1bf436bf31b913d4764a2b62ac6e98b9681e5c7ae2b562605592a56b7e946b +F test/where7.test 15041c7a5838f3bac98f3fb933709674a0b59367664e88fafaf105ff7416eb07 F test/where8.test 461ca40265ed996a6305da99bb024b0e41602bb586acf544c08f95922358e49f F test/where9.test 2db942671a002621eff4f713e347bb25243295f79d8990297cd160bebcfde3f7 F test/whereA.test 9d1077b117f1b68d5f739d94f36956c36cf995eb87bb19b77b2e81af020edd20 @@ -1914,17 +1976,17 @@ F test/wherefault.test 6cf2a9c5712952d463d3f45ebee7f6caf400984df51a195d884cfb7eb0e837a7 F test/wherelfault.test 9012e4ef5259058b771606616bd007af5d154e64cc25fa9fd4170f6411db44e3 F test/wherelimit.test afb46397c6d7e964e6e294ba3569864a0c570fe3807afc634236c2b752372f31 -F test/wherelimit2.test 657a3f24aadee62d058c5091ea682dc4af4b95ffe32f137155be49799a58e721 +F test/wherelimit2.test b9e4bfe7b4d7c2f85f99cf2bd2c51369378d04b1f3d1b60557423752003bfd90 F test/widetab1.test c296a98e123762de79917350e45fa33fdf88577a2571eb3a64c8bf7e44ef74d1 F test/win32heap.test 10fd891266bd00af68671e702317726375e5407561d859be1aa04696f2aeee74 F test/win32lock.test e0924eb8daac02bf80e9da88930747bd44dd9b230b7759fed927b1655b467c9c F test/win32longpath.test 4baffc3acb2e5188a5e3a895b2b543ed09e62f7c72d713c1feebf76222fe9976 F test/win32nolock.test ac4f08811a562e45a5755e661f45ca85892bdbbc -F test/window1.test 5ba48e9d33231e6ef16f21426bade9ccc52abf65a10587bff90a6c14fe174594 +F test/window1.test ccfeaf116afc6a8f748a8122a4f1ee6b69e6bbc5acee61197d3c17167338b100 F test/window2.tcl 492c125fa550cda1dd3555768a2303b3effbeceee215293adf8871efc25f1476 F test/window2.test e466a88bd626d66edc3d352d7d7e1d5531e0079b549ba44efb029d1fbff9fd3c F test/window3.tcl acea6e86a4324a210fd608d06741010ca83ded9fde438341cb978c49928faf03 -F test/window3.test e9959a993c8a71e96433be8daaa1827d78b8921e4f12debd7bdbeb3c856ef3cb +F test/window3.test 330733bcca73aba4ddae7a1011f2a2120ef7a0c68d8155854e08677417b8dbd0 F test/window4.tcl 6f85307eb67242b654d051f7da32a996a66aee039a09c5ae358541aa61720742 F test/window4.test fbead87f681400ac07ef3555e0488b544a47d35491f8bf09a7474b6f76ce9b4e F test/window5.test d328dd18221217c49c144181975eea17339eaeaf0e9aa558cee3afb84652821e @@ -1945,7 +2007,7 @@ F test/windowpushd.test d8895d08870b7226f7693665bd292eb177e62ca06799184957b3ca7dc03067df F test/with1.test b93833890e5d2a368e78747f124503a0159aa029b98e9ed4795ebf630b2efd3d F test/with2.test a1df41b987198383b9b70bf5e5fda390582e46398653858dbc6ceb24253b28df -F test/with3.test fe15975c0b53c9098a757902a908e3f8d6d80ce47c5363ac600f28a79ef8c0ca +F test/with3.test e30369ea27aa27eb1bda4c5e510c8a9f782c8afd2ab99d1a02b8a7f25a5d3e65 F test/with4.test 257be66c0c67fee1defbbac0f685c3465e2cad037f21ce65f23f86084f198205 F test/with5.test 6248213c41fab36290b5b73aa3f937309dfba337004d9d8434c3fabc8c7d4be8 F test/with6.test e097a03e5c898a8cd8f3a2d6a994ec510ea4376b5d484c2b669a41001e7758c8 @@ -1969,9 +2031,11 @@ F tool/GetTclKit.bat d84033c6a93dfe735d247f48ba00292a1cc284dcf69963e5e672444e04534bbf F tool/Replace.cs 02c67258801c2fb5f63231e0ac0f220b4b36ba91 F tool/build-all-msvc.bat c817b716e0edeecaf265a6775b63e5f45c34a6544f1d4114a222701ed5ac79ab x -F tool/build-shell.sh 950f47c6174f1eea171319438b93ba67ff5bf367 +F tool/build-shell.sh f193b5e3eb4afcb4abbf96bf1475be6cfb74763ee2e50c82bc7ca105e8a136c5 F tool/cg_anno.tcl c1f875f5a4c9caca3d59937b16aff716f8b1883935f1b4c9ae23124705bc8099 x F tool/checkSpacing.c 810e51703529a204fc4e1eb060e9ab663e3c06d2 +F tool/cktclsh.sh 6075eef9c6b9ba4b38fef2ca2a66d25f2311bd3c610498d18a9b01f861629cca +F tool/custom.txt 6cdf298f43e1db4bb91406d14777669b8fb1df790837823fa6754c4308decc27 F tool/dbhash.c 5da0c61032d23d74f2ab84ffc5740f0e8abec94f2c45c0b4306be7eb3ae96df0 F tool/dbtotxt.c ca48d34eaca6d6b6e4bd6a7be2b72caf34475869054240244c60fa7e69a518d6 F tool/dbtotxt.md c9a57af8739957ef36d2cfad5c4b1443ff3688ed33e4901ee200c8b651f43f3c @@ -1980,23 +2044,23 @@ F tool/extract.c 054069d81b095fbdc189a6f5d4466e40380505e2 F tool/fast_vacuum.c c129ae2924a48310c7b766810391da9e8fda532b9f6bd3f9a9e3a799a1b42af9 F tool/fragck.tcl 5265a95126abcf6ab357f7efa544787e5963f439 -F tool/fuzzershell.c e1d90a03ca790d7c331c2aae08ca46ff435f1ae1faa6cb9cc48f4687c18fdc6e +F tool/fuzzershell.c 41480c8a1e4749351f381431ecfdfceba645396c5d836f8d26b51a33c4a21b33 F tool/genfkey.README cf68fddd4643bbe3ff8e31b8b6d8b0a1b85e20f4 F tool/genfkey.test b6afd7b825d797a1e1274f519ab5695373552ecad5cd373530c63533638a5a4f F tool/getlock.c f4c39b651370156cae979501a7b156bdba50e7ce F tool/index_usage.c f62a0c701b2c7ff2f3e21d206f093c123f222dbf07136a10ffd1ca15a5c706c5 F tool/kvtest-speed.sh 4761a9c4b3530907562314d7757995787f7aef8f -F tool/lemon.c ea5c8589c7749e9bd32ba10432aeeed3c16e215de72a12ada2bc707884837149 +F tool/lemon.c 19e368bc8e97ff4071115119a7911ca3b0c56eba7926d8ada8b4a86fcc69a176 F tool/lempar.c 57478ea48420da05faa873c6d1616321caa5464644588c97fbe8e0ea04450748 F tool/libvers.c caafc3b689638a1d88d44bc5f526c2278760d9b9 F tool/loadfts.c c3c64e4d5e90e8ba41159232c2189dba4be7b862 F tool/logest.c c34e5944318415de513d29a6098df247a9618c96d83c38d4abd88641fe46e669 F tool/max-limits.c cbb635fbb37ae4d05f240bfb5b5270bb63c54439 F tool/merge-test.tcl de76b62f2de2a92d4c1ca4f976bce0aea6899e0229e250479b229b2a1914b176 -F tool/mkautoconfamal.sh f62353eb6c06ab264da027fd4507d09914433dbdcab9cb011cdc18016f1ab3b8 +F tool/mkautoconfamal.sh cbdcf993fa83dccbef7fb77b39cdeb31ef9f77d9d88c9e343b58d35ca3898a6a F tool/mkccode.tcl 86463e68ce9c15d3041610fedd285ce32a5cf7a58fc88b3202b8b76837650dbe x -F tool/mkctimec.tcl 38e3db33210a200aae791635125052a643a27aa0619a0debf19aa9c55e1b2dde x -F tool/mkkeywordhash.c 9822bd1f58a70e5f84179df3045bba4791df69180e991bec88662703f2e93761 +F tool/mkctimec.tcl 372452e24267dfe1b496eec3992d10c6e5e7d7870a152560cdcfe5404bc8cc04 x +F tool/mkkeywordhash.c b9faa0ae7e14e4dbbcd951cddd786bf46b8a65bb07b129ba8c0cfade723aaffd F tool/mkmsvcmin.tcl 8897d515ef7f94772322db95a3b6fce6c614d84fe0bdd06ba5a1c786351d5a1d F tool/mkopcodec.tcl 33d20791e191df43209b77d37f0ff0904620b28465cca6990cf8d60da61a07ef F tool/mkopcodeh.tcl 769d9e6a8b462323150dc13a8539d6064664b72974f7894befe2491cc73e05cd @@ -2006,9 +2070,10 @@ F tool/mksourceid.c 36aa8020014aed0836fd13c51d6dc9219b0df1761d6b5f58ff5b616211b079b9 F tool/mkspeedsql.tcl a1a334d288f7adfe6e996f2e712becf076745c97 F tool/mksqlite3c-noext.tcl 4f7cfef5152b0c91920355cbfc1d608a4ad242cb819f1aea07f6d0274f584a7f -F tool/mksqlite3c.tcl eb47021591b1ad4a6862e2cb5625f1ac67ec1e0c6db5ba3953c069c635284cf5 +F tool/mksqlite3c.tcl 2c760ab786cb509b47f00c96fea82994866cb99f5e046df81c768288f57897b4 F tool/mksqlite3h.tcl d391cff7cad0a372ee1406faee9ccc7dad9cb80a0c95cae0f73d10dd26e06762 F tool/mksqlite3internalh.tcl eb994013e833359137eb53a55acdad0b5ae1049b +F tool/mktoolzip.tcl c7a9b685f5131d755e7d941cec50cee7f34178b9e34c9a89811eeb08617f8423 F tool/mkvsix.tcl b9e0777a213c23156b6542842c238479e496ebf5 F tool/offsets.c 8ed2b344d33f06e71366a9b93ccedaa38c096cc1dbd4c3c26ad08c6115285845 F tool/omittest-msvc.tcl d6b8f501ac1d7798c4126065030f89812379012cad98a1735d6d7221492abc08 @@ -2019,26 +2084,29 @@ F tool/restore_jrnl.tcl 6957a34f8f1f0f8285e07536225ec3b292a9024a F tool/rollback-test.c 9fc98427d1e23e84429d7e6d07d9094fbdec65a5 F tool/run-speed-test.sh f95d19fd669b68c4c38b6b475242841d47c66076 -F tool/showdb.c 495a43b759ae37a0c4561a557a70090cb79b8c1601204e5a77e8b5360e65a954 +F tool/showdb.c 0f74b54cc67076c76cba9b2b7f54d3e05b78d130c70ffc394eb84c5b41bab017 F tool/showjournal.c 5bad7ae8784a43d2b270d953060423b8bd480818 F tool/showlocks.c 9cc5e66d4ebbf2d194f39db2527ece92077e86ae627ddd233ee48e16e8142564 F tool/showshm.c a0ab6ec32dd1f11218ca2a4018f8fb875b59414801ab8ceed8b2e69b7b45a809 F tool/showstat4.c 0682ebea7abf4d3657f53c4a243f2e7eab48eab344ed36a94bb75dcd19a5c2a1 -F tool/showwal.c 65ecabae3a2dcff4116301d5a8dbb8c4964814da1b2aff6d85c806a88b71fa4e +F tool/showwal.c 11eca547980a066b081f512636151233350ac679f29ecf4ebfce7f4530230b3d F tool/soak1.tcl 8d407956e1a45b485a8e072470a3e629a27037fe -F tool/spaceanal.tcl 1b5be34c6223cb1af06da2a10fb77863eb869b1962d055820b0a11cf2336ab45 -F tool/speed-check.sh c24c30cddd0ecb6d1d0775411d22f7619f55fa696a305487645e27b1b8fc05a2 +F tool/spaceanal.tcl 70c87c04cfd2e77b3e6f21c33ca768296aa8f67d4ab4874786ac8fbb28433477 +F tool/speed-check.sh 72dc85b2c0484af971ee3e7d10775f72b4e771e27e162c2099b3bf25517c25fb F tool/speedtest.tcl 06c76698485ccf597b9e7dbb1ac70706eb873355 F tool/speedtest16.c ecb6542862151c3e6509bbc00509b234562ae81e F tool/speedtest2.tcl ee2149167303ba8e95af97873c575c3e0fab58ff F tool/speedtest8.c 2902c46588c40b55661e471d7a86e4dd71a18224 F tool/speedtest8inst1.c 7ce07da76b5e745783e703a834417d725b7d45fd +F tool/spellsift.tcl 52b4b04dc4333c7ab024f09d9d66ed6b6f7c6eb00b38497a09f338fa55d40618 x F tool/split-sqlite3c.tcl 5aa60643afca558bc732b1444ae81a522326f91e1dc5665b369c54f09e20de60 -F tool/sqldiff.c 4f967c199c5f93eec64978e3a625d6c07fb1162212b1d48f65740d9eb4607eee +F tool/sqldiff.c fcccbc07da942b4534d0c769e9fcc21c67cbd7086ddc1c8f13372c40a83d4634 F tool/sqlite3_analyzer.c.in f88615bf33098945e0a42f17733f472083d150b58bdaaa5555a7129d0a51621c F tool/sqltclsh.c.in 1bcc2e9da58fadf17b0bf6a50e68c1159e602ce057210b655d50bad5aaaef898 F tool/sqltclsh.tcl 862f4cf1418df5e1315b5db3b5ebe88969e2a784525af5fbf9596592f14ed848 +F tool/src-verify.c 41c586dee84d0b190ad13e0282ed83d4a65ec9fefde9adf4943efdf6558eea7f F tool/srcck1.c 371de5363b70154012955544f86fdee8f6e5326f +F tool/srctree-check.tcl cef630bc4ff21a460d72479c43a42bf1c1ed61897659305c35c8d72e91bcb176 F tool/stack_usage.tcl f8e71b92cdb099a147dad572375595eae55eca43 F tool/stripccomments.c 20b8aabc4694d0d4af5566e42da1f1a03aff057689370326e9269a9ddcffdc37 F tool/symbols-mingw.sh 4dbcea7e74768305384c9fd2ed2b41bbf9f0414d @@ -2046,8 +2114,9 @@ F tool/varint.c 5d94cb5003db9dbbcbcc5df08d66f16071aee003 F tool/vdbe-compress.tcl 1dcb7632e57cf57105248029e6e162fddaf6c0fccb3bb9e6215603752c5a2d4a F tool/vdbe_profile.tcl 3ac5a4a9449f4baf77059358ea050db3e34395ccf59c5464d29b91746d5b961e +F tool/version-info.c 3b36468a90faf1bbd59c65fd0eb66522d9f941eedd364fabccd72273503ae7d5 F tool/warnings-clang.sh bbf6a1e685e534c92ec2bfba5b1745f34fb6f0bc2a362850723a9ee87c1b31a7 -F tool/warnings.sh ab651bb82586c43ff8b560beceac959735bf917b44c5e0f67ba3426e474f29f8 +F tool/warnings.sh 49a486c5069de041aedcbde4de178293e0463ae9918ecad7539eedf0ec77a139 F tool/win/sqlite.vsix deb315d026cc8400325c5863eef847784a219a2f F vsixtest/App.xaml b76d3b48860e7454775c47ea38ffea9c4abe3e85 F vsixtest/App.xaml.cpp 41158ee43269820136fa3bba00c0bd91b26cc38b650ee392aec2a8d823e54318 @@ -2070,10 +2139,8 @@ F vsixtest/vsixtest.vcxproj.data 2ed517e100c66dc455b492e1a33350c1b20fbcdc F vsixtest/vsixtest.vcxproj.filters 37e51ffedcdb064aad6ff33b6148725226cd608e F vsixtest/vsixtest_TemporaryKey.pfx e5b1b036facdb453873e7084e1cae9102ccc67a0 -P 4254f086419892634c80b0b915e14edea365adc6a45bcc75eecba889da274ac3 -R 5363a07f3e1462ec2f4570a33edb7167 -T +sym-release * -T +sym-version-3.42.0 * +P c8bf4f7a6a4c4f0f8cd21de25918f4d96f6831a145af4fb63e4b5984f79613b2 +R 2ea6650cd2adb393438e9ddbbc8346b3 U drh -Z 0ee8e0816fa6ac728bed7565aed4ec35 +Z ab15481ff7b37ad473e850b646604348 # Remove this line to create a well-formed Fossil manifest. diff -Nru sqlite3-3.42.0/manifest.uuid sqlite3-3.44.0-0/manifest.uuid --- sqlite3-3.42.0/manifest.uuid 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/manifest.uuid 2023-11-04 14:23:58.000000000 +0000 @@ -1 +1 @@ -831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0 +34f23c3d0d080fef82e3515ecb74257f68878c74fb0bdceac176a004aa1a84e9 \ No newline at end of file diff -Nru sqlite3-3.42.0/mkso.sh sqlite3-3.44.0-0/mkso.sh --- sqlite3-3.42.0/mkso.sh 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/mkso.sh 1970-01-01 00:00:00.000000000 +0000 @@ -1,32 +0,0 @@ -#!/bin/sh -# -# This script is used to compile SQLite into a shared library on Linux. -# -# Two separate shared libraries are generated. "sqlite3.so" is the core -# library. "tclsqlite3.so" contains the TCL bindings and is the -# library that is loaded into TCL in order to run SQLite. -# -make target_source -cd tsrc -rm shell.c -TCLDIR=/home/drh/tcltk/846/linux/846linux -TCLSTUBLIB=$TCLDIR/libtclstub8.4g.a -OPTS='-DUSE_TCL_STUBS=1 -DNDEBUG=1 -DHAVE_DLOPEN=1' -OPTS="$OPTS -DSQLITE_THREADSAFE=1" -OPTS="$OPTS -DSQLITE_ENABLE_FTS3=1" -OPTS="$OPTS -DSQLITE_ENABLE_COLUMN_METADATA=1" -for i in *.c; do - if test $i != 'keywordhash.c'; then - CMD="cc -fPIC $OPTS -O2 -I. -I$TCLDIR -c $i" - echo $CMD - $CMD - fi -done -echo gcc -shared *.o $TCLSTUBLIB -o tclsqlite3.so -gcc -shared *.o $TCLSTUBLIB -o tclsqlite3.so -strip tclsqlite3.so -rm tclsqlite.c tclsqlite.o -echo gcc -shared *.o -o sqlite3.so -gcc -shared *.o -o sqlite3.so -strip sqlite3.so -cd .. diff -Nru sqlite3-3.42.0/README.md sqlite3-3.44.0-0/README.md --- sqlite3-3.42.0/README.md 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/README.md 2023-11-04 14:23:58.000000000 +0000 @@ -25,7 +25,28 @@ verify its integrity, there are hints on how to do that in the [Verifying Code Authenticity](#vauth) section below. -## Obtaining The Code +## Contacting The SQLite Developers + +The preferred way to ask questions or make comments about SQLite or to +report bugs against SQLite is to visit the +[SQLite Forum](https://sqlite.org/forum) at . +Anonymous postings are permitted. + +If you think you have found a bug that has security implications and +you do not want to report it on the public forum, you can send a private +email to drh at sqlite dot org. + +## Public Domain + +The SQLite source code is in the public domain. See + for details. + +Because SQLite is in the public domain, we do not normally accept pull +requests, because if we did take a pull request, the changes in that +pull request might carry a copyright and the SQLite source code would +then no longer be fully in the public domain. + +## Obtaining The SQLite Source Code If you do not want to use Fossil, you can download tarballs or ZIP archives or [SQLite archives](https://sqlite.org/cli.html#sqlar) as follows: @@ -82,9 +103,9 @@ mkdir bld ;# Build will occur in a sibling directory cd bld ;# Change to the build directory ../sqlite/configure ;# Run the configure script - make ;# Run the makefile. + make ;# Builds the "sqlite3" command-line tool make sqlite3.c ;# Build the "amalgamation" source file - make test ;# Run some tests (requires Tcl) + make devtest ;# Run some tests (requires Tcl) See the makefile for additional targets. @@ -94,32 +115,33 @@ can copy and edit to suit your needs. Comments on the generic makefile show what changes are needed. -## Using MSVC for Windows systems +## Compiling for Windows Using MSVC On Windows, all applicable build products can be compiled with MSVC. -First open the command prompt window associated with the desired compiler -version (e.g. "Developer Command Prompt for VS2013"). Next, use NMAKE -with the provided "Makefile.msc" to build one of the supported targets. - -For example, from the parent directory of the source subtree named "sqlite": - - mkdir bld - cd bld - nmake /f ..\sqlite\Makefile.msc TOP=..\sqlite - nmake /f ..\sqlite\Makefile.msc sqlite3.c TOP=..\sqlite - nmake /f ..\sqlite\Makefile.msc sqlite3.dll TOP=..\sqlite - nmake /f ..\sqlite\Makefile.msc sqlite3.exe TOP=..\sqlite - nmake /f ..\sqlite\Makefile.msc test TOP=..\sqlite - -There are several build options that can be set via the NMAKE command -line. For example, to build for WinRT, simply add "FOR_WINRT=1" argument -to the "sqlite3.dll" command line above. When debugging into the SQLite -code, adding the "DEBUG=1" argument to one of the above command lines is -recommended. - -SQLite does not require [Tcl](http://www.tcl.tk/) to run, but a Tcl installation -is required by the makefiles (including those for MSVC). SQLite contains -a lot of generated code and Tcl is used to do much of that code generation. +You will also need a working installation of TCL. +See the [compile-for-windows.md](doc/compile-for-windows.md) document for +additional information about how to install MSVC and TCL and configure your +build environment. + +If you want to run tests, you need to let SQLite know the location of your +TCL library, using a command like this: + + set TCLDIR=c:\Tcl + +SQLite uses "tclsh.exe" as part of the build process, and so that utility +program will need to be somewhere on your %PATH%. The finished SQLite library +does not contain any TCL code, but it does use TCL to help with the build process +and to run tests. + +Build using Makefile.msc. Example: + + nmake /f Makefile.msc + nmake /f Makefile.msc sqlite3.c + nmake /f Makefile.msc devtest + nmake /f Makefile.msc releasetest + +There are many other makefile targets. See comments in Makefile.msc for +details. ## Source Code Tour @@ -290,16 +312,13 @@ is not part of the core SQLite library. But as most of the tests in this repository are written in Tcl, the Tcl language bindings are important. - * **test*.c** - Files in the src/ folder that begin with "test" go into + * **test\*.c** - Files in the src/ folder that begin with "test" go into building the "testfixture.exe" program. The testfixture.exe program is an enhanced Tcl shell. The testfixture.exe program runs scripts in the test/ folder to validate the core SQLite code. The testfixture program (and some other test programs too) is built and run when you type "make test". - * **ext/misc/json1.c** - This file implements the various JSON functions - that are built into SQLite. - There are many other source files. Each has a succinct header comment that describes its purpose and role within the larger system. @@ -307,8 +326,8 @@ ## Verifying Code Authenticity The `manifest` file at the root directory of the source tree -contains either a SHA3-256 hash (for newer files) or a SHA1 hash (for -older files) for every source file in the repository. +contains either a SHA3-256 hash or a SHA1 hash +for every source file in the repository. The name of the version of the entire source tree is just the SHA3-256 hash of the `manifest` file itself, possibly with the last line of that file omitted if the last line begins with @@ -316,14 +335,25 @@ The `manifest.uuid` file should contain the SHA3-256 hash of the `manifest` file. If all of the above hash comparisons are correct, then you can be confident that your source tree is authentic and unadulterated. +Details on the format for the `manifest` files are available +[on the Fossil website](https://fossil-scm.org/fossil/doc/trunk/www/fileformat.wiki#manifest). + +The process of checking source code authenticity is automated by the +makefile: + +> make verify-source + +Or on windows: + +> nmake /f Makefile.msc verify-source -The format of the `manifest` file should be mostly self-explanatory, but -if you want details, they are available -[here](https://fossil-scm.org/fossil/doc/trunk/www/fileformat.wiki#manifest). +Using the makefile to verify source integrity is good for detecting +accidental changes to the source tree, but malicious changes could be +hidden by also modifying the makefiles. ## Contacts -The main SQLite website is [http://www.sqlite.org/](http://www.sqlite.org/) +The main SQLite website is [http:/sqlite.org/](http://sqlite.org/) with geographically distributed backups at [http://www2.sqlite.org/](http://www2.sqlite.org) and [http://www3.sqlite.org/](http://www3.sqlite.org). diff -Nru sqlite3-3.42.0/sqlite3.1 sqlite3-3.44.0-0/sqlite3.1 --- sqlite3-3.42.0/sqlite3.1 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/sqlite3.1 2023-11-04 14:23:58.000000000 +0000 @@ -2,7 +2,7 @@ .\" First parameter, NAME, should be all caps .\" Second parameter, SECTION, should be 1-8, maybe w/ subsection .\" other parameters are allowed: see man(7), man(1) -.TH SQLITE3 1 "Fri Oct 31 10:41:31 EDT 2014" +.TH SQLITE3 1 "Fri Aug 11 23:50:12 CET 2023" .\" Please adjust this date whenever revising the manpage. .\" .\" Some roff macros, for reference: @@ -49,9 +49,9 @@ $ .B sqlite3 mydata.db .br -SQLite version 3.8.8 +SQLite version 3.43.0 2023-08-11 17:45:23 .br -Enter ".help" for instructions +Enter ".help" for usage hints. .br sqlite> .B create table memos(text, priority INTEGER); @@ -108,141 +108,13 @@ .B .help .nf .tr %. -%backup ?DB? FILE Backup DB (default "main") to FILE -%bail on|off Stop after hitting an error. Default OFF -%clone NEWDB Clone data into NEWDB from the existing database -%databases List names and files of attached databases -%dump ?TABLE? ... Dump the database in an SQL text format - If TABLE specified, only dump tables matching - LIKE pattern TABLE. -%echo on|off Turn command echo on or off -%eqp on|off Enable or disable automatic EXPLAIN QUERY PLAN -%exit Exit this program -%explain ?on|off? Turn output mode suitable for EXPLAIN on or off. - With no args, it turns EXPLAIN on. -%fullschema Show schema and the content of sqlite_stat tables -%headers on|off Turn display of headers on or off -%help Show this message -%import FILE TABLE Import data from FILE into TABLE -%indices ?TABLE? Show names of all indices - If TABLE specified, only show indices for tables - matching LIKE pattern TABLE. -%load FILE ?ENTRY? Load an extension library -%log FILE|off Turn logging on or off. FILE can be stderr/stdout -%mode MODE ?TABLE? Set output mode where MODE is one of: - csv Comma-separated values - column Left-aligned columns. (See .width) - html HTML code - insert SQL insert statements for TABLE - line One value per line - list Values delimited by .separator string - tabs Tab-separated values - tcl TCL list elements -%nullvalue STRING Use STRING in place of NULL values -%once FILENAME Output for the next SQL command only to FILENAME -%open ?FILENAME? Close existing database and reopen FILENAME -%output ?FILENAME? Send output to FILENAME or stdout -%print STRING... Print literal STRING -%prompt MAIN CONTINUE Replace the standard prompts -%quit Exit this program -%read FILENAME Execute SQL in FILENAME -%restore ?DB? FILE Restore content of DB (default "main") from FILE -%save FILE Write in-memory database into FILE -%schema ?TABLE? Show the CREATE statements - If TABLE specified, only show tables matching - LIKE pattern TABLE. -%separator STRING ?NL? Change separator used by output mode and .import - NL is the end-of-line mark for CSV -%shell CMD ARGS... Run CMD ARGS... in a system shell -%show Show the current values for various settings -%stats on|off Turn stats on or off -%system CMD ARGS... Run CMD ARGS... in a system shell -%tables ?TABLE? List names of tables - If TABLE specified, only list tables matching - LIKE pattern TABLE. -%timeout MS Try opening locked tables for MS milliseconds -%timer on|off Turn SQL timer on or off -%trace FILE|off Output each SQL statement as it is run -%vfsname ?AUX? Print the name of the VFS stack -%width NUM1 NUM2 ... Set column widths for "column" mode - Negative values right-justify -sqlite> +... .sp .fi -.SH OPTIONS -.B sqlite3 -has the following options: -.TP -.B \-bail -Stop after hitting an error. -.TP -.B \-batch -Force batch I/O. -.TP -.B \-column -Query results will be displayed in a table like form, using -whitespace characters to separate the columns and align the -output. -.TP -.BI \-cmd\ command -run -.I command -before reading stdin -.TP -.B \-csv -Set output mode to CSV (comma separated values). -.TP -.B \-echo -Print commands before execution. -.TP -.BI \-init\ file -Read and execute commands from -.I file -, which can contain a mix of SQL statements and meta-commands. -.TP -.B \-[no]header -Turn headers on or off. -.TP -.B \-help -Show help on options and exit. -.TP -.B \-html -Query results will be output as simple HTML tables. -.TP -.B \-interactive -Force interactive I/O. -.TP -.B \-line -Query results will be displayed with one value per line, rows -separated by a blank line. Designed to be easily parsed by -scripts or other programs -.TP -.B \-list -Query results will be displayed with the separator (|, by default) -character between each field value. The default. -.TP -.BI \-mmap\ N -Set default mmap size to -.I N -\. -.TP -.BI \-nullvalue\ string -Set string used to represent NULL values. Default is '' -(empty string). -.TP -.BI \-separator\ separator -Set output field separator. Default is '|'. -.TP -.B \-stats -Print memory stats before each finalize. -.TP -.B \-version -Show SQLite version. -.TP -.BI \-vfs\ name -Use -.I name -as the default VFS. + +The available commands differ by version and build options, so they +are not listed here. Please refer to your local copy for all available +options. .SH INIT FILE @@ -265,22 +137,25 @@ .sp .fi -o If the file +o If the file +.B ${XDG_CONFIG_HOME}/sqlite3/sqliterc +or .B ~/.sqliterc -exists, it is processed first. -can be found in the user's home directory, it is -read and processed. It should generally only contain meta-commands. +exists, the first of those to be found is processed during startup. +It should generally only contain meta-commands. o If the -init option is present, the specified file is processed. o All other command line options are processed. .SH SEE ALSO -http://www.sqlite.org/cli.html +https://sqlite.org/cli.html +.br +https://sqlite.org/fiddle (a WebAssembly build of the CLI app) .br The sqlite3-doc package. .SH AUTHOR This manual page was originally written by Andreas Rottmann , for the Debian GNU/Linux system (but may be used -by others). It was subsequently revised by Bill Bumgarner and -further updated by Laszlo Boszormenyi . +by others). It was subsequently revised by Bill Bumgarner , +Laszlo Boszormenyi , and the sqlite3 developers. diff -Nru sqlite3-3.42.0/src/alter.c sqlite3-3.44.0-0/src/alter.c --- sqlite3-3.42.0/src/alter.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/alter.c 2023-11-04 14:23:58.000000000 +0000 @@ -58,7 +58,7 @@ int bNoDQS /* Do not allow DQS in the schema */ ){ pParse->colNamesSet = 1; - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "SELECT 1 " "FROM \"%w\"." LEGACY_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" @@ -69,7 +69,7 @@ ); if( bTemp==0 ){ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "SELECT 1 " "FROM temp." LEGACY_SCHEMA_TABLE " " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" @@ -82,20 +82,20 @@ /* ** Generate VM code to replace any double-quoted strings (but not double-quoted -** identifiers) within the "sql" column of the sqlite_schema table in +** identifiers) within the "sql" column of the sqlite_schema table in ** database zDb with their single-quoted equivalents. If argument bTemp is ** not true, similarly update all SQL statements in the sqlite_schema table ** of the temp db. */ static void renameFixQuotes(Parse *pParse, const char *zDb, int bTemp){ - sqlite3NestedParse(pParse, - "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE + sqlite3NestedParse(pParse, + "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET sql = sqlite_rename_quotefix(%Q, sql)" "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" " AND sql NOT LIKE 'create virtual%%'" , zDb, zDb ); if( bTemp==0 ){ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE temp." LEGACY_SCHEMA_TABLE " SET sql = sqlite_rename_quotefix('temp', sql)" "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X'" @@ -118,8 +118,8 @@ } /* -** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" -** command. +** Generate code to implement the "ALTER TABLE xxx RENAME TO yyy" +** command. */ void sqlite3AlterRenameTable( Parse *pParse, /* Parser context. */ @@ -129,7 +129,7 @@ int iDb; /* Database that contains the table */ char *zDb; /* Name of database iDb */ Table *pTab; /* Table being renamed */ - char *zName = 0; /* NULL-terminated version of pName */ + char *zName = 0; /* NULL-terminated version of pName */ sqlite3 *db = pParse->db; /* Database connection */ int nTabName; /* Number of UTF-8 characters in zTabName */ const char *zTabName; /* Original name of the table */ @@ -156,7 +156,7 @@ || sqlite3FindIndex(db, zName, zDb) || sqlite3IsShadowTableOf(db, pTab, zName) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "there is already another table or index with this name: %s", zName); goto exit_rename_table; } @@ -199,7 +199,7 @@ /* Begin a transaction for database iDb. Then modify the schema cookie ** (since the ALTER TABLE modifies the schema). Call sqlite3MayAbort(), - ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the + ** as the scalar functions (e.g. sqlite_rename_table()) invoked by the ** nested SQL may raise an exception. */ v = sqlite3GetVdbe(pParse); if( v==0 ){ @@ -213,7 +213,7 @@ /* Rewrite all CREATE TABLE, INDEX, TRIGGER or VIEW statements in ** the schema to use the new table name. */ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, %d) " "WHERE (type!='index' OR tbl_name=%Q COLLATE nocase)" @@ -233,14 +233,14 @@ "'sqlite_autoindex_' || %Q || substr(name,%d+18) " "ELSE name END " "WHERE tbl_name=%Q COLLATE nocase AND " - "(type='table' OR type='index' OR type='trigger');", + "(type='table' OR type='index' OR type='trigger');", zDb, - zName, zName, zName, + zName, zName, zName, nTabName, zTabName ); #ifndef SQLITE_OMIT_AUTOINCREMENT - /* If the sqlite_sequence table exists in this database, then update + /* If the sqlite_sequence table exists in this database, then update ** it with the new table name. */ if( sqlite3FindTable(db, "sqlite_sequence", zDb) ){ @@ -251,10 +251,10 @@ #endif /* If the table being renamed is not itself part of the temp database, - ** edit view and trigger definitions within the temp database + ** edit view and trigger definitions within the temp database ** as required. */ if( iDb!=1 ){ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE sqlite_temp_schema SET " "sql = sqlite_rename_table(%Q, type, name, sql, %Q, %Q, 1), " "tbl_name = " @@ -361,7 +361,7 @@ return; } if( (pCol->colFlags & COLFLAG_GENERATED)==0 ){ - /* If the default value for the new column was specified with a + /* If the default value for the new column was specified with a ** literal NULL, then set pDflt to 0. This simplifies checking ** for an SQL NULL default below. */ @@ -414,11 +414,11 @@ ** have to use printf() to translate between these units: */ assert( IsOrdinaryTable(pTab) ); assert( IsOrdinaryTable(pNew) ); - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = printf('%%.%ds, ',sql) || %Q" " || substr(sql,1+length(printf('%%.%ds',sql))) " - "WHERE type = 'table' AND name = %Q", + "WHERE type = 'table' AND name = %Q", zDb, pNew->u.tab.addColOffset, zCol, pNew->u.tab.addColOffset, zTab ); @@ -446,14 +446,19 @@ /* Verify that constraints are still satisfied */ if( pNew->pCheck!=0 || (pCol->notNull && (pCol->colFlags & COLFLAG_GENERATED)!=0) + || (pTab->tabFlags & TF_Strict)!=0 ){ sqlite3NestedParse(pParse, "SELECT CASE WHEN quick_check GLOB 'CHECK*'" " THEN raise(ABORT,'CHECK constraint failed')" + " WHEN quick_check GLOB 'non-* value in*'" + " THEN raise(ABORT,'type mismatch on DEFAULT')" " ELSE raise(ABORT,'NOT NULL constraint failed')" " END" " FROM pragma_quick_check(%Q,%Q)" - " WHERE quick_check GLOB 'CHECK*' OR quick_check GLOB 'NULL*'", + " WHERE quick_check GLOB 'CHECK*'" + " OR quick_check GLOB 'NULL*'" + " OR quick_check GLOB 'non-* value in*'", zTab, zDb ); } @@ -462,14 +467,14 @@ /* ** This function is called by the parser after the table-name in -** an "ALTER TABLE ADD" statement is parsed. Argument +** an "ALTER TABLE ADD" statement is parsed. Argument ** pSrc is the full-name of the table being altered. ** ** This routine makes a (partial) copy of the Table structure ** for the table being altered and sets Parse.pNewTable to point ** to it. Routines called by the parser as the column definition -** is parsed (i.e. sqlite3AddColumn()) add the new Column data to -** the copy. The copy of the Table structure is deleted by tokenize.c +** is parsed (i.e. sqlite3AddColumn()) add the new Column data to +** the copy. The copy of the Table structure is deleted by tokenize.c ** after parsing is finished. ** ** Routine sqlite3AlterFinishAddColumn() will be called to complete @@ -542,7 +547,7 @@ pNew->u.tab.pDfltList = sqlite3ExprListDup(db, pTab->u.tab.pDfltList, 0); pNew->pSchema = db->aDb[iDb].pSchema; pNew->u.tab.addColOffset = pTab->u.tab.addColOffset; - pNew->nTabRef = 1; + assert( pNew->nTabRef==1 ); exit_begin_add_column: sqlite3SrcListDelete(db, pSrc); @@ -571,7 +576,7 @@ } #endif if( zType ){ - sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"", + sqlite3ErrorMsg(pParse, "cannot %s %s \"%s\"", (bDrop ? "drop column from" : "rename columns of"), zType, pTab->zName ); @@ -611,7 +616,7 @@ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_rename_column; if( SQLITE_OK!=isRealTable(pParse, pTab, 0) ) goto exit_rename_column; - /* Which schema holds the table to be altered */ + /* Which schema holds the table to be altered */ iSchema = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iSchema>=0 ); zDb = db->aDb[iSchema].zDbSName; @@ -648,7 +653,7 @@ if( !zNew ) goto exit_rename_column; assert( pNew->n>0 ); bQuote = sqlite3Isquote(pNew->z[0]); - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, %d) " "WHERE name NOT LIKE 'sqliteX_%%' ESCAPE 'X' " @@ -658,7 +663,7 @@ pTab->zName ); - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE temp." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_rename_column(sql, type, name, %Q, %Q, %d, %Q, %d, 1) " "WHERE type IN ('trigger', 'view')", @@ -708,7 +713,7 @@ RenameToken *pList; /* List of tokens to overwrite */ int nList; /* Number of tokens in pList */ int iCol; /* Index of column being renamed */ - Table *pTab; /* Table being ALTERed */ + Table *pTab; /* Table being ALTERed */ const char *zOld; /* Old column name */ }; @@ -716,14 +721,14 @@ /* ** This function is only for debugging. It performs two tasks: ** -** 1. Checks that pointer pPtr does not already appear in the +** 1. Checks that pointer pPtr does not already appear in the ** rename-token list. ** ** 2. Dereferences each pointer in the rename-token list. ** ** The second is most effective when debugging under valgrind or -** address-sanitizer or similar. If any of these pointers no longer -** point to valid objects, an exception is raised by the memory-checking +** address-sanitizer or similar. If any of these pointers no longer +** point to valid objects, an exception is raised by the memory-checking ** tool. ** ** The point of this is to prevent comparisons of invalid pointer values. @@ -918,7 +923,7 @@ } /* -** Remove all nodes that are part of expression-list pEList from the +** Remove all nodes that are part of expression-list pEList from the ** rename list. */ void sqlite3RenameExprlistUnmap(Parse *pParse, ExprList *pEList){ @@ -959,8 +964,8 @@ ** the list maintained by the RenameCtx object. */ static RenameToken *renameTokenFind( - Parse *pParse, - struct RenameCtx *pCtx, + Parse *pParse, + struct RenameCtx *pCtx, const void *pPtr ){ RenameToken **pp; @@ -1008,12 +1013,12 @@ */ static int renameColumnExprCb(Walker *pWalker, Expr *pExpr){ RenameCtx *p = pWalker->u.pRename; - if( pExpr->op==TK_TRIGGER - && pExpr->iColumn==p->iCol + if( pExpr->op==TK_TRIGGER + && pExpr->iColumn==p->iCol && pWalker->pParse->pTriggerTab==p->pTab ){ renameTokenFind(pWalker->pParse, p, (void*)pExpr); - }else if( pExpr->op==TK_COLUMN + }else if( pExpr->op==TK_COLUMN && pExpr->iColumn==p->iCol && ALWAYS(ExprUseYTab(pExpr)) && p->pTab==pExpr->y.pTab @@ -1047,14 +1052,14 @@ } /* -** An error occured while parsing or otherwise processing a database +** 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, + sqlite3_context *pCtx, const char *zWhen, sqlite3_value *pType, sqlite3_value *pObject, @@ -1064,7 +1069,7 @@ const char *zN = (const char*)sqlite3_value_text(pObject); char *zErr; - zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s", + zErr = sqlite3MPrintf(pParse->db, "error in %s %s%s%s: %s", zT, zN, (zWhen[0] ? " " : ""), zWhen, pParse->zErrMsg ); @@ -1074,14 +1079,14 @@ /* ** For each name in the the expression-list pEList (i.e. each -** pEList->a[i].zName) that matches the string in zOld, extract the +** pEList->a[i].zName) that matches the string in zOld, extract the ** corresponding rename-token from Parse object pParse and add it ** to the RenameCtx pCtx. */ static void renameColumnElistNames( - Parse *pParse, - RenameCtx *pCtx, - const ExprList *pEList, + Parse *pParse, + RenameCtx *pCtx, + const ExprList *pEList, const char *zOld ){ if( pEList ){ @@ -1099,14 +1104,14 @@ } /* -** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) -** that matches the string in zOld, extract the corresponding rename-token +** For each name in the the id-list pIdList (i.e. each pIdList->a[i].zName) +** that matches the string in zOld, extract the corresponding rename-token ** from Parse object pParse and add it to the RenameCtx pCtx. */ static void renameColumnIdlistNames( - Parse *pParse, - RenameCtx *pCtx, - const IdList *pIdList, + Parse *pParse, + RenameCtx *pCtx, + const IdList *pIdList, const char *zOld ){ if( pIdList ){ @@ -1147,7 +1152,7 @@ p->nQueryLoop = 1; rc = sqlite3RunParser(p, zSql); if( db->mallocFailed ) rc = SQLITE_NOMEM; - if( rc==SQLITE_OK + if( rc==SQLITE_OK && NEVER(p->pNewTable==0 && p->pNewIndex==0 && p->pNewTrigger==0) ){ rc = SQLITE_CORRUPT_BKPT; @@ -1196,8 +1201,8 @@ char *zBuf2 = 0; if( zNew ){ - /* Set zQuot to point to a buffer containing a quoted copy of the - ** identifier zNew. If the corresponding identifier in the original + /* Set zQuot to point to a buffer containing a quoted copy of the + ** identifier zNew. If the corresponding identifier in the original ** ALTER TABLE statement was quoted (bQuote==1), then set zNew to ** point to zQuot so that all substitutions are made using the ** quoted version of the new column name. */ @@ -1220,7 +1225,7 @@ /* At this point pRename->pList contains a list of RenameToken objects ** corresponding to all tokens in the input SQL that must be replaced - ** with the new column name, or with single-quoted versions of themselves. + ** with the new column name, or with single-quoted versions of themselves. ** All that remains is to construct and return the edited SQL string. */ if( zOut ){ int nOut = nSql; @@ -1259,7 +1264,7 @@ iOff = pBest->t.z - zSql; if( pBest->t.n!=nReplace ){ - memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], + memmove(&zOut[iOff + nReplace], &zOut[iOff + pBest->t.n], nOut - (iOff + pBest->t.n) ); nOut += nReplace - pBest->t.n; @@ -1294,7 +1299,7 @@ /* ** Resolve all symbols in the trigger at pParse->pNewTrigger, assuming -** it was read from the schema of database zDb. Return SQLITE_OK if +** it was read from the schema of database zDb. Return SQLITE_OK if ** successful. Otherwise, return an SQLite error code and leave an error ** message in the Parse object. */ @@ -1308,7 +1313,7 @@ memset(&sNC, 0, sizeof(sNC)); sNC.pParse = pParse; assert( pNew->pTabSchema ); - pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, + pParse->pTriggerTab = sqlite3FindTable(db, pNew->table, db->aDb[sqlite3SchemaToIndex(db, pNew->pTabSchema)].zDbSName ); pParse->eTriggerOp = pNew->op; @@ -1601,7 +1606,7 @@ if( rc!=SQLITE_OK ) goto renameColumnFunc_done; for(pStep=sParse.pNewTrigger->step_list; pStep; pStep=pStep->pNext){ - if( pStep->zTarget ){ + if( pStep->zTarget ){ Table *pTarget = sqlite3LocateTable(&sParse, 0, pStep->zTarget, zDb); if( pTarget==pTab ){ if( pStep->pUpsert ){ @@ -1647,7 +1652,7 @@ } /* -** Walker expression callback used by "RENAME TABLE". +** Walker expression callback used by "RENAME TABLE". */ static int renameTableExprCb(Walker *pWalker, Expr *pExpr){ RenameCtx *p = pWalker->u.pRename; @@ -1661,7 +1666,7 @@ } /* -** Walker select callback used by "RENAME TABLE". +** Walker select callback used by "RENAME TABLE". */ static int renameTableSelectCb(Walker *pWalker, Select *pSelect){ int i; @@ -1691,7 +1696,7 @@ /* ** This C function implements an SQL user function that is used by SQL code ** generated by the ALTER TABLE ... RENAME command to modify the definition -** of any foreign key constraints that use the table being renamed as the +** of any foreign key constraints that use the table being renamed as the ** parent table. It is passed three arguments: ** ** 0: The database containing the table being renamed. @@ -1805,7 +1810,7 @@ else{ Trigger *pTrigger = sParse.pNewTrigger; TriggerStep *pStep; - if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) + if( 0==sqlite3_stricmp(sParse.pNewTrigger->table, zOld) && sCtx.pTab->pSchema==pTrigger->pTabSchema ){ renameTokenFind(&sParse, &sCtx, sParse.pNewTrigger->table); @@ -1881,12 +1886,12 @@ ** ** CREATE TABLE t1(a, b, c); ** -** SELECT sqlite_rename_quotefix('main', +** SELECT sqlite_rename_quotefix('main', ** 'CREATE VIEW v1 AS SELECT "a", "string" FROM t1' ** ); ** ** returns the string: -** +** ** CREATE VIEW v1 AS SELECT "a", 'string' FROM t1 ** ** If there is a error in the input SQL, then raise an error, except @@ -1942,8 +1947,8 @@ sqlite3WalkExprList(&sWalker, sParse.pNewTable->pCheck); #ifndef SQLITE_OMIT_GENERATED_COLUMNS for(i=0; inCol; i++){ - sqlite3WalkExpr(&sWalker, - sqlite3ColumnExpr(sParse.pNewTable, + sqlite3WalkExpr(&sWalker, + sqlite3ColumnExpr(sParse.pNewTable, &sParse.pNewTable->aCol[i])); } #endif /* SQLITE_OMIT_GENERATED_COLUMNS */ @@ -1960,7 +1965,7 @@ #endif /* SQLITE_OMIT_TRIGGER */ } - if( rc==SQLITE_OK ){ + if( rc==SQLITE_OK ){ rc = renameEditSql(context, &sCtx, zInput, 0, 0); } renameTokenFree(db, sCtx.pList); @@ -2071,7 +2076,7 @@ /* ** The implementation of internal UDF sqlite_drop_column(). -** +** ** Arguments: ** ** argv[0]: An integer - the index of the schema containing the table @@ -2107,7 +2112,7 @@ rc = renameParseSql(&sParse, zDb, db, zSql, iSchema==1); if( rc!=SQLITE_OK ) goto drop_column_done; pTab = sParse.pNewTable; - if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){ + if( pTab==0 || pTab->nCol==1 || iCol>=pTab->nCol ){ /* This can happen if the sqlite_schema table is corrupt */ rc = SQLITE_CORRUPT_BKPT; goto drop_column_done; @@ -2139,7 +2144,7 @@ } /* -** This function is called by the parser upon parsing an +** This function is called by the parser upon parsing an ** ** ALTER TABLE pSrc DROP COLUMN pName ** @@ -2161,7 +2166,7 @@ pTab = sqlite3LocateTableItem(pParse, 0, &pSrc->a[0]); if( !pTab ) goto exit_drop_column; - /* Make sure this is not an attempt to ALTER a view, virtual table or + /* Make sure this is not an attempt to ALTER a view, virtual table or ** system table. */ if( SQLITE_OK!=isAlterableTable(pParse, pTab) ) goto exit_drop_column; if( SQLITE_OK!=isRealTable(pParse, pTab, 1) ) goto exit_drop_column; @@ -2178,10 +2183,10 @@ goto exit_drop_column; } - /* Do not allow the user to drop a PRIMARY KEY column or a column + /* Do not allow the user to drop a PRIMARY KEY column or a column ** constrained by a UNIQUE constraint. */ if( pTab->aCol[iCol].colFlags & (COLFLAG_PRIMKEY|COLFLAG_UNIQUE) ){ - sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", + sqlite3ErrorMsg(pParse, "cannot drop %s column: \"%s\"", (pTab->aCol[iCol].colFlags&COLFLAG_PRIMKEY) ? "PRIMARY KEY" : "UNIQUE", zCol ); @@ -2206,7 +2211,7 @@ #endif renameTestSchema(pParse, zDb, iDb==1, "", 0); renameFixQuotes(pParse, zDb, iDb==1); - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE \"%w\"." LEGACY_SCHEMA_TABLE " SET " "sql = sqlite_drop_column(%d, sql, %d) " "WHERE (type=='table' AND tbl_name=%Q COLLATE nocase)" diff -Nru sqlite3-3.42.0/src/analyze.c sqlite3-3.44.0-0/src/analyze.c --- sqlite3-3.42.0/src/analyze.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/analyze.c 2023-11-04 14:23:58.000000000 +0000 @@ -1849,14 +1849,15 @@ decodeIntArray((char*)sqlite3_column_text(pStmt,2),nCol,pSample->anLt,0,0); decodeIntArray((char*)sqlite3_column_text(pStmt,3),nCol,pSample->anDLt,0,0); - /* Take a copy of the sample. Add two 0x00 bytes the end of the buffer. + /* Take a copy of the sample. Add 8 extra 0x00 bytes the end of the buffer. ** This is in case the sample record is corrupted. In that case, the ** sqlite3VdbeRecordCompare() may read up to two varints past the ** end of the allocated buffer before it realizes it is dealing with - ** a corrupt record. Adding the two 0x00 bytes prevents this from causing + ** a corrupt record. Or it might try to read a large integer from the + ** buffer. In any case, eight 0x00 bytes prevents this from causing ** a buffer overread. */ pSample->n = sqlite3_column_bytes(pStmt, 4); - pSample->p = sqlite3DbMallocZero(db, pSample->n + 2); + pSample->p = sqlite3DbMallocZero(db, pSample->n + 8); if( pSample->p==0 ){ sqlite3_finalize(pStmt); return SQLITE_NOMEM_BKPT; diff -Nru sqlite3-3.42.0/src/auth.c sqlite3-3.44.0-0/src/auth.c --- sqlite3-3.42.0/src/auth.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/auth.c 2023-11-04 14:23:58.000000000 +0000 @@ -204,7 +204,7 @@ sqlite3 *db = pParse->db; int rc; - /* Don't do any authorization checks if the database is initialising + /* 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 ); diff -Nru sqlite3-3.42.0/src/bitvec.c sqlite3-3.44.0-0/src/bitvec.c --- sqlite3-3.42.0/src/bitvec.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/bitvec.c 2023-11-04 14:23:58.000000000 +0000 @@ -17,8 +17,8 @@ ** property. Usually only a few pages are meet either condition. ** So the bitmap is usually sparse and has low cardinality. ** But sometimes (for example when during a DROP of a large table) most -** or all of the pages in a database can get journalled. In those cases, -** the bitmap becomes dense with high cardinality. The algorithm needs +** or all of the pages in a database can get journalled. In those cases, +** the bitmap becomes dense with high cardinality. The algorithm needs ** to handle both cases well. ** ** The size of the bitmap is fixed when the object is created. @@ -39,13 +39,13 @@ /* Size of the Bitvec structure in bytes. */ #define BITVEC_SZ 512 -/* Round the union size down to the nearest pointer boundary, since that's how +/* Round the union size down to the nearest pointer boundary, since that's how ** it will be aligned within the Bitvec struct. */ #define BITVEC_USIZE \ (((BITVEC_SZ-(3*sizeof(u32)))/sizeof(Bitvec*))*sizeof(Bitvec*)) -/* Type of the array "element" for the bitmap representation. -** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. +/* Type of the array "element" for the bitmap representation. +** Should be a power of 2, and ideally, evenly divide into BITVEC_USIZE. ** Setting this to the "natural word" size of your CPU may improve ** performance. */ #define BITVEC_TELEM u8 @@ -58,12 +58,12 @@ /* Number of u32 values in hash table. */ #define BITVEC_NINT (BITVEC_USIZE/sizeof(u32)) -/* Maximum number of entries in hash table before +/* Maximum number of entries in hash table before ** sub-dividing and re-hashing. */ #define BITVEC_MXHASH (BITVEC_NINT/2) /* Hashing function for the aHash representation. -** Empirical testing showed that the *37 multiplier -** (an arbitrary prime)in the hash function provided +** Empirical testing showed that the *37 multiplier +** (an arbitrary prime)in the hash function provided ** no fewer collisions than the no-op *1. */ #define BITVEC_HASH(X) (((X)*1)%BITVEC_NINT) @@ -109,7 +109,7 @@ /* ** Create a new bitmap object able to handle bits between 0 and iSize, -** inclusive. Return a pointer to the new object. Return NULL if +** inclusive. Return a pointer to the new object. Return NULL if ** malloc fails. */ Bitvec *sqlite3BitvecCreate(u32 iSize){ @@ -188,7 +188,7 @@ h = BITVEC_HASH(i++); /* if there wasn't a hash collision, and this doesn't */ /* completely fill the hash, then just add it without */ - /* worring about sub-dividing and re-hashing. */ + /* worrying about sub-dividing and re-hashing. */ if( !p->u.aHash[h] ){ if (p->nSet<(BITVEC_NINT-1)) { goto bitvec_set_end; @@ -365,7 +365,7 @@ break; } case 3: - case 4: + case 4: default: { nx = 2; sqlite3_randomness(sizeof(i), &i); diff -Nru sqlite3-3.42.0/src/btmutex.c sqlite3-3.44.0-0/src/btmutex.c --- sqlite3-3.42.0/src/btmutex.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/btmutex.c 2023-11-04 14:23:58.000000000 +0000 @@ -178,7 +178,7 @@ ** ** There is a corresponding leave-all procedures. ** -** Enter the mutexes in accending order by BtShared pointer address +** 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. diff -Nru sqlite3-3.42.0/src/btree.c sqlite3-3.44.0-0/src/btree.c --- sqlite3-3.42.0/src/btree.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/btree.c 2023-11-04 14:23:58.000000000 +0000 @@ -51,7 +51,7 @@ #define BTALLOC_LE 2 /* Allocate any page <= the parameter */ /* -** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not +** Macro IfNotOmitAV(x) returns (x) if SQLITE_OMIT_AUTOVACUUM is not ** defined, or 0 if it is. For example: ** ** bIncrVacuum = IfNotOmitAV(pBtShared->incrVacuum); @@ -66,7 +66,7 @@ /* ** A list of BtShared objects that are eligible for participation ** in shared cache. This variable has file scope during normal builds, -** but the test harness needs to access it so we make it global for +** but the test harness needs to access it so we make it global for ** test builds. ** ** Access to this variable is protected by SQLITE_MUTEX_STATIC_MAIN. @@ -101,7 +101,7 @@ ** manipulate entries in the BtShared.pLock linked list used to store ** shared-cache table level locks. If the library is compiled with the ** shared-cache feature disabled, then there is only ever one user - ** of each BtShared structure and so this locking is not necessary. + ** of each BtShared structure and so this locking is not necessary. ** So define the lock related functions as no-ops. */ #define querySharedCacheTableLock(a,b,c) SQLITE_OK @@ -157,15 +157,15 @@ /* **** This function is only used as part of an assert() statement. *** ** -** Check to see if pBtree holds the required locks to read or write to the +** Check to see if pBtree holds the required locks to read or write to the ** table with root page iRoot. Return 1 if it does and 0 if not. ** -** For example, when writing to a table with root-page iRoot via +** For example, when writing to a table with root-page iRoot via ** Btree connection pBtree: ** ** assert( hasSharedCacheTableLock(pBtree, iRoot, 0, WRITE_LOCK) ); ** -** When writing to an index that resides in a sharable database, the +** When writing to an index that resides in a sharable database, the ** caller should have first obtained a lock specifying the root page of ** the corresponding table. This makes things a bit more complicated, ** as this module treats each table as a separate structure. To determine @@ -187,7 +187,7 @@ BtLock *pLock; /* If this database is not shareable, or if the client is reading - ** and has the read-uncommitted flag set, then no lock is required. + ** and has the read-uncommitted flag set, then no lock is required. ** Return true immediately. */ if( (pBtree->sharable==0) @@ -229,13 +229,13 @@ iTab = iRoot; } - /* Search for the required lock. Either a write-lock on root-page iTab, a + /* Search for the required lock. Either a write-lock on root-page iTab, a ** write-lock on the schema table, or (if the client is reading) a ** read-lock on iTab will suffice. Return 1 if any of these are found. */ for(pLock=pBtree->pBt->pLock; pLock; pLock=pLock->pNext){ - if( pLock->pBtree==pBtree + if( pLock->pBtree==pBtree && (pLock->iTable==iTab || (pLock->eLock==WRITE_LOCK && pLock->iTable==1)) - && pLock->eLock>=eLockType + && pLock->eLock>=eLockType ){ return 1; } @@ -268,7 +268,7 @@ static int hasReadConflicts(Btree *pBtree, Pgno iRoot){ BtCursor *p; for(p=pBtree->pBt->pCursor; p; p=p->pNext){ - if( p->pgnoRoot==iRoot + if( p->pgnoRoot==iRoot && p->pBtree!=pBtree && 0==(p->pBtree->db->flags & SQLITE_ReadUncommit) ){ @@ -280,7 +280,7 @@ #endif /* #ifdef SQLITE_DEBUG */ /* -** Query to see if Btree handle p may obtain a lock of type eLock +** Query to see if Btree handle p may obtain a lock of type eLock ** (READ_LOCK or WRITE_LOCK) on the table with root-page iTab. Return ** SQLITE_OK if the lock may be obtained (by calling ** setSharedCacheTableLock()), or SQLITE_LOCKED if not. @@ -293,14 +293,14 @@ assert( eLock==READ_LOCK || eLock==WRITE_LOCK ); assert( p->db!=0 ); assert( !(p->db->flags&SQLITE_ReadUncommit)||eLock==WRITE_LOCK||iTab==1 ); - + /* If requesting a write-lock, then the Btree must have an open write - ** transaction on this file. And, obviously, for this to be so there + ** transaction on this file. And, obviously, for this to be so there ** must be an open write transaction on the file itself. */ assert( eLock==READ_LOCK || (p==pBt->pWriter && p->inTrans==TRANS_WRITE) ); assert( eLock==READ_LOCK || pBt->inTransaction==TRANS_WRITE ); - + /* This routine is a no-op if the shared-cache is not enabled */ if( !p->sharable ){ return SQLITE_OK; @@ -315,7 +315,7 @@ } for(pIter=pBt->pLock; pIter; pIter=pIter->pNext){ - /* The condition (pIter->eLock!=eLock) in the following if(...) + /* The condition (pIter->eLock!=eLock) in the following if(...) ** statement is a simplification of: ** ** (eLock==WRITE_LOCK || pIter->eLock==WRITE_LOCK) @@ -342,7 +342,7 @@ #ifndef SQLITE_OMIT_SHARED_CACHE /* ** Add a lock on the table with root-page iTable to the shared-btree used -** by Btree handle p. Parameter eLock must be either READ_LOCK or +** by Btree handle p. Parameter eLock must be either READ_LOCK or ** WRITE_LOCK. ** ** This function assumes the following: @@ -354,7 +354,7 @@ ** with the requested lock (i.e. querySharedCacheTableLock() has ** already been called and returned SQLITE_OK). ** -** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM +** SQLITE_OK is returned if the lock is added successfully. SQLITE_NOMEM ** is returned if a malloc attempt fails. */ static int setSharedCacheTableLock(Btree *p, Pgno iTable, u8 eLock){ @@ -368,11 +368,11 @@ /* A connection with the read-uncommitted flag set will never try to ** obtain a read-lock using this function. The only read-lock obtained - ** by a connection in read-uncommitted mode is on the sqlite_schema + ** by a connection in read-uncommitted mode is on the sqlite_schema ** table, and that lock is obtained in BtreeBeginTrans(). */ assert( 0==(p->db->flags&SQLITE_ReadUncommit) || eLock==WRITE_LOCK ); - /* This function should only be called on a sharable b-tree after it + /* This function should only be called on a sharable b-tree after it ** has been determined that no other b-tree holds a conflicting lock. */ assert( p->sharable ); assert( SQLITE_OK==querySharedCacheTableLock(p, iTable, eLock) ); @@ -417,7 +417,7 @@ ** Release all the table locks (locks obtained via calls to ** the setSharedCacheTableLock() procedure) held by Btree object p. ** -** This function assumes that Btree p has an open read or write +** This function assumes that Btree p has an open read or write ** transaction. If it does not, then the BTS_PENDING flag ** may be incorrectly cleared. */ @@ -449,7 +449,7 @@ pBt->pWriter = 0; pBt->btsFlags &= ~(BTS_EXCLUSIVE|BTS_PENDING); }else if( pBt->nTransaction==2 ){ - /* This function is called when Btree p is concluding its + /* This function is called when Btree p is concluding its ** transaction. If there currently exists a writer, and p is not ** that writer, then the number of locks held by connections other ** than the writer must be about to drop to zero. In this case @@ -495,7 +495,7 @@ } /* Verify that the cursor and the BtShared agree about what is the current -** database connetion. This is important in shared-cache mode. If the database +** database connetion. 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() @@ -566,8 +566,8 @@ #endif /* SQLITE_OMIT_INCRBLOB */ /* -** Set bit pgno of the BtShared.pHasContent bitvec. This is called -** when a page that previously contained data becomes a free-list leaf +** Set bit pgno of the BtShared.pHasContent bitvec. This is called +** when a page that previously contained data becomes a free-list leaf ** page. ** ** The BtShared.pHasContent bitvec exists to work around an obscure @@ -593,7 +593,7 @@ ** may be lost. In the event of a rollback, it may not be possible ** to restore the database to its original configuration. ** -** The solution is the BtShared.pHasContent bitvec. Whenever a page is +** The solution is the BtShared.pHasContent bitvec. Whenever a page is ** moved to become a free-list leaf page, the corresponding bit is ** set in the bitvec. Whenever a leaf page is extracted from the free-list, ** optimization 2 above is omitted if the corresponding bit is already @@ -654,13 +654,13 @@ ** The cursor passed as the only argument must point to a valid entry ** when this function is called (i.e. have eState==CURSOR_VALID). This ** function saves the current cursor key in variables pCur->nKey and -** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error +** pCur->pKey. SQLITE_OK is returned if successful or an SQLite error ** code otherwise. ** ** If the cursor is open on an intkey table, then the integer key ** (the rowid) is stored in pCur->nKey and pCur->pKey is left set to -** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is -** set to point to a malloced buffer pCur->nKey bytes in size containing +** NULL. If the cursor is open on a non-intkey table, then pCur->pKey is +** set to point to a malloced buffer pCur->nKey bytes in size containing ** the key. */ static int saveCursorKey(BtCursor *pCur){ @@ -676,8 +676,8 @@ /* For an index btree, save the complete key content. It is possible ** that the current key is corrupt. In that case, it is possible that ** the sqlite3VdbeRecordUnpack() function may overread the buffer by - ** up to the size of 1 varint plus 1 8-byte value when the cursor - ** position is restored. Hence the 17 bytes of padding allocated + ** up to the size of 1 varint plus 1 8-byte value when the cursor + ** position is restored. Hence the 17 bytes of padding allocated ** below. */ void *pKey; pCur->nKey = sqlite3BtreePayloadSize(pCur); @@ -699,11 +699,11 @@ } /* -** Save the current cursor position in the variables BtCursor.nKey +** Save the current cursor position in the variables BtCursor.nKey ** and BtCursor.pKey. The cursor's state is set to CURSOR_REQUIRESEEK. ** ** The caller must ensure that the cursor is valid (has eState==CURSOR_VALID) -** prior to calling this routine. +** prior to calling this routine. */ static int saveCursorPosition(BtCursor *pCur){ int rc; @@ -742,7 +742,7 @@ ** routine is called just before cursor pExcept is used to modify the ** table, for example in BtreeDelete() or BtreeInsert(). ** -** If there are two or more cursors on the same btree, then all such +** If there are two or more cursors on the same btree, then all such ** cursors should have their BTCF_Multiple flag set. The btreeCursor() ** routine enforces that rule. This routine only needs to be called in ** the uncommon case when pExpect has the BTCF_Multiple flag set. @@ -840,9 +840,9 @@ /* ** Restore the cursor to the position it was in (or as close to as possible) -** when saveCursorPosition() was called. Note that this call deletes the +** when saveCursorPosition() was called. Note that this call deletes the ** saved position info stored by saveCursorPosition(), so there can be -** at most one effective restoreCursorPosition() call after each +** at most one effective restoreCursorPosition() call after each ** saveCursorPosition(). */ static int btreeRestoreCursorPosition(BtCursor *pCur){ @@ -910,7 +910,7 @@ /* ** 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). +** 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. *pDifferntRow is the row the cursor @@ -992,7 +992,7 @@ if( pgno<2 ) return 0; nPagesPerMapPage = (pBt->usableSize/5)+1; iPtrMap = (pgno-2)/nPagesPerMapPage; - ret = (iPtrMap*nPagesPerMapPage) + 2; + ret = (iPtrMap*nPagesPerMapPage) + 2; if( ret==PENDING_BYTE_PAGE(pBt) ){ ret++; } @@ -1480,7 +1480,7 @@ }while( *(pIter)>=0x80 && pIterxParseCell(pPage, pCell, &info); if( info.nLocalaDataEnd, pCell, pCell+info.nLocal) ){ + if( SQLITE_OVERFLOW(pSrc->aDataEnd, pCell, pCell+info.nLocal) ){ testcase( pSrc!=pPage ); *pRC = SQLITE_CORRUPT_BKPT; return; @@ -1589,7 +1589,7 @@ /* This block handles pages with two or fewer free blocks and nMaxFrag ** or fewer fragmented bytes. In this case it is faster to move the ** two (or one) blocks of cells using memmove() and add the required - ** offsets to each pointer in the cell-pointer array than it is to + ** offsets to each pointer in the cell-pointer array than it is to ** reconstruct the entire page. */ if( (int)data[hdr+7]<=nMaxFrag ){ int iFree = get2byte(&data[hdr+1]); @@ -1634,7 +1634,7 @@ iCellStart = get2byte(&data[hdr+5]); if( nCell>0 ){ temp = sqlite3PagerTempSpace(pPage->pBt->pPager); - memcpy(&temp[iCellStart], &data[iCellStart], usableSize - iCellStart); + memcpy(temp, data, usableSize); src = temp; for(i=0; ipDbPage) ); assert( pPage->pBt ); assert( sqlite3_mutex_held(pPage->pBt->mutex) ); @@ -1858,7 +1858,7 @@ ** ** 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 encrouch into the reserved bytes +** 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. */ @@ -1881,7 +1881,7 @@ assert( iSize>=4 ); /* Minimum cell size is 4 */ assert( CORRUPT_DB || iStart<=pPage->pBt->usableSize-4 ); - /* The list of freeblocks must be in ascending order. Find the + /* The list of freeblocks must be in ascending order. Find the ** spot on the list where iStart should be inserted. */ hdr = pPage->hdrOffset; @@ -1900,7 +1900,7 @@ return SQLITE_CORRUPT_PAGE(pPage); } assert( iFreeBlk>iPtr || iFreeBlk==0 || CORRUPT_DB ); - + /* At this point: ** iFreeBlk: First freeblock after iStart, or zero if none ** iPtr: The address of a pointer to iFreeBlk @@ -1917,7 +1917,7 @@ iSize = iEnd - iStart; iFreeBlk = get2byte(&data[iFreeBlk]); } - + /* If iPtr is another freeblock (that is, if iPtr is not the freelist ** pointer in the page header) then check to see if iStart should be ** coalesced onto the end of iPtr. @@ -2075,7 +2075,7 @@ /* EVIDENCE-OF: R-55530-52930 In a well-formed b-tree page, there will ** always be at least one cell before the first freeblock. */ - return SQLITE_CORRUPT_PAGE(pPage); + return SQLITE_CORRUPT_PAGE(pPage); } while( 1 ){ if( pc>iCellLast ){ @@ -2114,7 +2114,7 @@ /* ** Do additional sanity check after btreeInitPage() if -** PRAGMA cell_size_check=ON +** PRAGMA cell_size_check=ON */ static SQLITE_NOINLINE int btreeCellSizeCheck(MemPage *pPage){ int iCellFirst; /* First allowable cell or freeblock offset */ @@ -2152,7 +2152,7 @@ ** Initialize the auxiliary information for a disk block. ** ** Return SQLITE_OK on success. If we see that the page does -** not contain a well-formed database page, then return +** not contain a well-formed database page, then return ** SQLITE_CORRUPT. Note that a return of SQLITE_OK does not ** guarantee that the page is well-formed. It only shows that ** we failed to detect any corruption. @@ -2257,7 +2257,7 @@ pPage->hdrOffset = pgno==1 ? 100 : 0; } assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); - return pPage; + return pPage; } /* @@ -2317,68 +2317,41 @@ /* ** Get a page from the pager and initialize it. -** -** If pCur!=0 then the page is being fetched as part of a moveToChild() -** call. Do additional sanity checking on the page in this case. -** And if the fetch fails, this routine must decrement pCur->iPage. -** -** The page is fetched as read-write unless pCur is not NULL and is -** a read-only cursor. -** -** If an error occurs, then *ppPage is undefined. It -** may remain unchanged, or it may be set to an invalid value. */ static int getAndInitPage( BtShared *pBt, /* The database file */ Pgno pgno, /* Number of the page to get */ MemPage **ppPage, /* Write the page pointer here */ - BtCursor *pCur, /* Cursor to receive the page, or NULL */ int bReadOnly /* True for a read-only page */ ){ int rc; DbPage *pDbPage; + MemPage *pPage; assert( sqlite3_mutex_held(pBt->mutex) ); - assert( pCur==0 || ppPage==&pCur->pPage ); - assert( pCur==0 || bReadOnly==pCur->curPagerFlags ); - assert( pCur==0 || pCur->iPage>0 ); if( pgno>btreePagecount(pBt) ){ - rc = SQLITE_CORRUPT_BKPT; - goto getAndInitPage_error1; + *ppPage = 0; + return SQLITE_CORRUPT_BKPT; } rc = sqlite3PagerGet(pBt->pPager, pgno, (DbPage**)&pDbPage, bReadOnly); if( rc ){ - goto getAndInitPage_error1; + *ppPage = 0; + return rc; } - *ppPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); - if( (*ppPage)->isInit==0 ){ + pPage = (MemPage*)sqlite3PagerGetExtra(pDbPage); + if( pPage->isInit==0 ){ btreePageFromDbPage(pDbPage, pgno, pBt); - rc = btreeInitPage(*ppPage); + rc = btreeInitPage(pPage); if( rc!=SQLITE_OK ){ - goto getAndInitPage_error2; + releasePage(pPage); + *ppPage = 0; + return rc; } } - assert( (*ppPage)->pgno==pgno || CORRUPT_DB ); - assert( (*ppPage)->aData==sqlite3PagerGetData(pDbPage) ); - - /* If obtaining a child page for a cursor, we must verify that the page is - ** compatible with the root page. */ - if( pCur && ((*ppPage)->nCell<1 || (*ppPage)->intKey!=pCur->curIntKey) ){ - rc = SQLITE_CORRUPT_PGNO(pgno); - goto getAndInitPage_error2; - } + assert( pPage->pgno==pgno || CORRUPT_DB ); + assert( pPage->aData==sqlite3PagerGetData(pDbPage) ); + *ppPage = pPage; return SQLITE_OK; - -getAndInitPage_error2: - releasePage(*ppPage); -getAndInitPage_error1: - if( pCur ){ - pCur->iPage--; - pCur->pPage = pCur->apPage[pCur->iPage]; - } - testcase( pgno==0 ); - assert( pgno!=0 || rc!=SQLITE_OK ); - return rc; } /* @@ -2461,7 +2434,7 @@ ** call to btreeInitPage() will likely return SQLITE_CORRUPT. ** But no harm is done by this. And it is very important that ** btreeInitPage() be called on every btree page so we make - ** the call for every page that comes in for re-initing. */ + ** the call for every page that comes in for re-initializing. */ btreeInitPage(pPage); } } @@ -2479,11 +2452,11 @@ /* ** Open a database file. -** +** ** zFilename is the name of the database file. If zFilename is NULL ** then an ephemeral database is created. The ephemeral database might ** be exclusively in memory, or it might use a disk-based memory cache. -** Either way, the ephemeral database will be automatically deleted +** Either way, the ephemeral database will be automatically deleted ** when sqlite3BtreeClose() is called. ** ** If zFilename is ":memory:" then an in-memory database is created @@ -2516,7 +2489,7 @@ /* True if opening an ephemeral, temporary database */ const int isTempDb = zFilename==0 || zFilename[0]==0; - /* Set the variable isMemdb to true for an in-memory database, or + /* Set the variable isMemdb to true for an in-memory database, or ** false for a file-based database. */ #ifdef SQLITE_OMIT_MEMORYDB @@ -2639,7 +2612,10 @@ assert( sizeof(u32)==4 ); assert( sizeof(u16)==2 ); assert( sizeof(Pgno)==4 ); - + + /* Suppress false-positive compiler warning from PVS-Studio */ + memset(&zDbHeader[16], 0, 8); + pBt = sqlite3MallocZero( sizeof(*pBt) ); if( pBt==0 ){ rc = SQLITE_NOMEM_BKPT; @@ -2658,7 +2634,7 @@ pBt->db = db; sqlite3PagerSetBusyHandler(pBt->pPager, btreeInvokeBusyHandler, pBt); p->pBt = pBt; - + pBt->pCursor = 0; pBt->pPage1 = 0; if( sqlite3PagerIsreadonly(pBt->pPager) ) pBt->btsFlags |= BTS_READ_ONLY; @@ -2702,7 +2678,7 @@ if( rc ) goto btree_open_out; pBt->usableSize = pBt->pageSize - nReserve; assert( (pBt->pageSize & 7)==0 ); /* 8-byte alignment of pageSize */ - + #if !defined(SQLITE_OMIT_SHARED_CACHE) && !defined(SQLITE_OMIT_DISKIO) /* Add the new BtShared object to the linked list sharable BtShareds. */ @@ -2831,7 +2807,7 @@ } /* -** Make sure pBt->pTmpSpace points to an allocation of +** Make sure pBt->pTmpSpace points to an allocation of ** MX_CELL_SIZE(pBt) bytes with a 4-byte prefix for a left-child ** pointer. */ @@ -2856,7 +2832,7 @@ ** 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 unitialized + ** 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. ** @@ -2911,7 +2887,7 @@ sqlite3BtreeLeave(p); /* If there are still other outstanding references to the shared-btree - ** structure, return now. The remainder of this procedure cleans + ** structure, return now. The remainder of this procedure cleans ** up the shared-btree. */ assert( p->wantToLock==0 && p->locked==0 ); @@ -3017,7 +2993,7 @@ /* ** Change the default pages size and the number of reserved bytes per page. -** Or, if the page size has already been fixed, return SQLITE_READONLY +** Or, if the page size has already been fixed, return SQLITE_READONLY ** without changing anything. ** ** The page size must be a power of 2 between 512 and 65536. If the page @@ -3077,7 +3053,7 @@ ** held. ** ** This is useful in one special case in the backup API code where it is -** known that the shared b-tree mutex is held, but the mutex on the +** known that the shared b-tree mutex is held, but the mutex on the ** database handle that owns *p is not. In this case if sqlite3BtreeEnter() ** were to be called, it might collide with some other operation on the ** database handle that owns *p, causing undefined behavior. @@ -3091,7 +3067,7 @@ /* ** Return the number of bytes of space at the end of every page that -** are intentually left unused. This is the "reserved" space that is +** 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 @@ -3157,7 +3133,7 @@ /* ** Change the 'auto-vacuum' property of the database. If the 'autoVacuum' ** parameter is non-zero, then auto-vacuum mode is enabled. If zero, it -** is disabled. The default value for the auto-vacuum property is +** is disabled. The default value for the auto-vacuum property is ** determined by the SQLITE_DEFAULT_AUTOVACUUM macro. */ int sqlite3BtreeSetAutoVacuum(Btree *p, int autoVacuum){ @@ -3181,7 +3157,7 @@ } /* -** Return the value of the 'auto-vacuum' property. If auto-vacuum is +** Return the value of the 'auto-vacuum' property. If auto-vacuum is ** enabled 1 is returned. Otherwise 0. */ int sqlite3BtreeGetAutoVacuum(Btree *p){ @@ -3213,9 +3189,9 @@ Db *pDb; if( (db=pBt->db)!=0 && (pDb=db->aDb)!=0 ){ while( pDb->pBt==0 || pDb->pBt->pBt!=pBt ){ pDb++; } - if( pDb->bSyncSet==0 - && pDb->safety_level!=safety_level - && pDb!=&db->aDb[1] + if( pDb->bSyncSet==0 + && pDb->safety_level!=safety_level + && pDb!=&db->aDb[1] ){ pDb->safety_level = safety_level; sqlite3PagerSetFlags(pBt->pPager, @@ -3238,7 +3214,7 @@ ** SQLITE_OK is returned on success. If the file is not a ** well-formed database file, then SQLITE_CORRUPT is returned. ** SQLITE_BUSY is returned if the database is locked. SQLITE_NOMEM -** is returned if we run out of memory. +** is returned if we run out of memory. */ static int lockBtree(BtShared *pBt){ int rc; /* Result code from subfunctions */ @@ -3254,7 +3230,7 @@ if( rc!=SQLITE_OK ) return rc; /* Do some checking to help insure the file we opened really is - ** a valid database file. + ** a valid database file. */ nPage = get4byte(28+(u8*)pPage1->aData); sqlite3PagerPagecount(pBt->pPager, (int*)&nPageFile); @@ -3292,7 +3268,7 @@ } /* If the read version is set to 2, this database should be accessed - ** in WAL mode. If the log is not already open, open it now. Then + ** in WAL mode. If the log is not already open, open it now. Then ** return SQLITE_OK and return without populating BtShared.pPage1. ** The caller detects this and calls this function again. This is ** required as the version of page 1 currently in the page1 buffer @@ -3333,16 +3309,15 @@ /* EVIDENCE-OF: R-25008-21688 The size of a page is a power of two ** between 512 and 65536 inclusive. */ if( ((pageSize-1)&pageSize)!=0 - || pageSize>SQLITE_MAX_PAGE_SIZE - || pageSize<=256 + || pageSize>SQLITE_MAX_PAGE_SIZE + || pageSize<=256 ){ goto page1_init_failed; } - pBt->btsFlags |= BTS_PAGESIZE_FIXED; assert( (pageSize & 7)==0 ); /* EVIDENCE-OF: R-59310-51205 The "reserved space" size in the 1-byte ** integer at offset 20 is the number of bytes of space at the end of - ** each page to reserve for extensions. + ** each page to reserve for extensions. ** ** EVIDENCE-OF: R-37497-42412 The size of the reserved region is ** determined by the one-byte unsigned integer found at an offset of 20 @@ -3358,6 +3333,7 @@ releasePageOne(pPage1); pBt->usableSize = usableSize; pBt->pageSize = pageSize; + pBt->btsFlags |= BTS_PAGESIZE_FIXED; freeTempSpace(pBt); rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize, pageSize-usableSize); @@ -3377,6 +3353,7 @@ if( usableSize<480 ){ goto page1_init_failed; } + pBt->btsFlags |= BTS_PAGESIZE_FIXED; pBt->pageSize = pageSize; pBt->usableSize = usableSize; #ifndef SQLITE_OMIT_AUTOVACUUM @@ -3436,7 +3413,7 @@ int r = 0; for(pCur=pBt->pCursor; pCur; pCur=pCur->pNext){ if( (wrOnly==0 || (pCur->curFlags & BTCF_WriteFlag)!=0) - && pCur->eState!=CURSOR_FAULT ) r++; + && pCur->eState!=CURSOR_FAULT ) r++; } return r; } @@ -3445,7 +3422,7 @@ /* ** If there are no outstanding cursors and we are not in the middle ** of a transaction but there is a read lock on the database, then -** this routine unrefs the first page of the database file which +** this routine unrefs the first page of the database file which ** has the effect of releasing the read lock. ** ** If there is a transaction in progress, this routine is a no-op. @@ -3529,8 +3506,8 @@ ** upgraded to exclusive by calling this routine a second time - the ** exclusivity flag only works for a new transaction. ** -** A write-transaction must be started before attempting any -** changes to the database. None of the following routines +** A write-transaction must be started before attempting any +** changes to the database. None of the following routines ** will work unless a transaction is started first: ** ** sqlite3BtreeCreateTable() @@ -3544,7 +3521,7 @@ ** If an initial attempt to acquire the lock fails because of lock contention ** and the database was previously unlocked, then invoke the busy handler ** if there is one. But if there was previously a read-lock, do not -** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is +** invoke the busy handler - just return SQLITE_BUSY. SQLITE_BUSY is ** returned when there is already a read-lock in order to avoid a deadlock. ** ** Suppose there are two processes A and B. A has a read lock and B has @@ -3555,7 +3532,11 @@ ** when A already has a read lock, we encourage A to give up and let B ** proceed. */ -int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ +static SQLITE_NOINLINE int btreeBeginTrans( + Btree *p, /* The btree in which to start the transaction */ + int wrflag, /* True to start a write transaction */ + int *pSchemaVersion /* Put schema version number here, if not NULL */ +){ BtShared *pBt = p->pBt; Pager *pPager = pBt->pPager; int rc = SQLITE_OK; @@ -3572,8 +3553,8 @@ } assert( pBt->inTransaction==TRANS_WRITE || IfNotOmitAV(pBt->bDoTruncate)==0 ); - if( (p->db->flags & SQLITE_ResetDatabase) - && sqlite3PagerIsreadonly(pPager)==0 + if( (p->db->flags & SQLITE_ResetDatabase) + && sqlite3PagerIsreadonly(pPager)==0 ){ pBt->btsFlags &= ~BTS_READ_ONLY; } @@ -3587,7 +3568,7 @@ #ifndef SQLITE_OMIT_SHARED_CACHE { sqlite3 *pBlock = 0; - /* If another database handle has already opened a write transaction + /* If another database handle has already opened a write transaction ** on this shared-btree structure and a second write transaction is ** requested, return SQLITE_LOCKED. */ @@ -3612,8 +3593,8 @@ } #endif - /* Any read-only or read-write transaction implies a read-lock on - ** page 1. So if some other shared-cache client already has a write-lock + /* Any read-only or read-write transaction implies a read-lock on + ** page 1. So if some other shared-cache client already has a write-lock ** on page 1, the transaction cannot be opened. */ rc = querySharedCacheTableLock(p, SCHEMA_ROOT, READ_LOCK); if( SQLITE_OK!=rc ) goto trans_begun; @@ -3636,7 +3617,7 @@ /* Call lockBtree() until either pBt->pPage1 is populated or ** lockBtree() returns something other than SQLITE_OK. lockBtree() ** may return SQLITE_OK but leave pBt->pPage1 set to 0 if after - ** reading page 1 it discovers that the page-size of the database + ** reading page 1 it discovers that the page-size of the database ** file is not pBt->pageSize. In this case lockBtree() will update ** pBt->pageSize to the page-size of the file on disk. */ @@ -3657,7 +3638,7 @@ } } } - + if( rc!=SQLITE_OK ){ (void)sqlite3PagerWalWriteLock(pPager, 0); unlockBtreeIfUnused(pBt); @@ -3696,7 +3677,7 @@ /* If the db-size header field is incorrect (as it may be if an old ** client has been writing the database file), update it now. Doing - ** this sooner rather than later means the database size can safely + ** this sooner rather than later means the database size can safely ** re-read the database size from page 1 if a savepoint or transaction ** rollback occurs within the transaction. */ @@ -3727,6 +3708,28 @@ sqlite3BtreeLeave(p); return rc; } +int sqlite3BtreeBeginTrans(Btree *p, int wrflag, int *pSchemaVersion){ + BtShared *pBt; + if( p->sharable + || p->inTrans==TRANS_NONE + || (p->inTrans==TRANS_READ && wrflag!=0) + ){ + return btreeBeginTrans(p,wrflag,pSchemaVersion); + } + pBt = p->pBt; + if( pSchemaVersion ){ + *pSchemaVersion = get4byte(&pBt->pPage1->aData[40]); + } + if( wrflag ){ + /* This call makes sure that the pager has the correct number of + ** open savepoints. If the second parameter is greater than 0 and + ** the sub-journal is not already open, then it will be opened here. + */ + return sqlite3PagerOpenSavepoint(pBt->pPager, p->db->nSavepoint); + }else{ + return SQLITE_OK; + } +} #ifndef SQLITE_OMIT_AUTOVACUUM @@ -3771,7 +3774,7 @@ ** that it points to iTo. Parameter eType describes the type of pointer to ** be modified, as follows: ** -** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child +** PTRMAP_BTREE: pPage is a btree-page. The pointer points at a child ** page of pPage. ** ** PTRMAP_OVERFLOW1: pPage is a btree-page. The pointer points at an overflow @@ -3822,9 +3825,9 @@ } } } - + if( i==nCell ){ - if( eType!=PTRMAP_BTREE || + if( eType!=PTRMAP_BTREE || get4byte(&pPage->aData[pPage->hdrOffset+8])!=iFrom ){ return SQLITE_CORRUPT_PAGE(pPage); } @@ -3836,11 +3839,11 @@ /* -** Move the open database page pDbPage to location iFreePage in the +** Move the open database page pDbPage to location iFreePage in the ** database. The pDbPage reference remains valid. ** ** The isCommit flag indicates that there is no need to remember that -** the journal needs to be sync()ed before database page pDbPage->pgno +** the journal needs to be sync()ed before database page pDbPage->pgno ** can be written to. The caller has already promised not to write to that ** page. */ @@ -3857,14 +3860,14 @@ Pager *pPager = pBt->pPager; int rc; - assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || + assert( eType==PTRMAP_OVERFLOW2 || eType==PTRMAP_OVERFLOW1 || eType==PTRMAP_BTREE || eType==PTRMAP_ROOTPAGE ); assert( sqlite3_mutex_held(pBt->mutex) ); assert( pDbPage->pBt==pBt ); if( iDbPage<3 ) return SQLITE_CORRUPT_BKPT; /* Move page iDbPage from its current location to page number iFreePage */ - TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n", + TRACE(("AUTOVACUUM: Moving %u to free page %u (ptr page %u type %u)\n", iDbPage, iFreePage, iPtrPage, eType)); rc = sqlite3PagerMovepage(pPager, pDbPage->pDbPage, iFreePage, isCommit); if( rc!=SQLITE_OK ){ @@ -3923,19 +3926,19 @@ /* ** Perform a single step of an incremental-vacuum. If successful, return -** SQLITE_OK. If there is no work to do (and therefore no point in -** calling this function again), return SQLITE_DONE. Or, if an error +** SQLITE_OK. If there is no work to do (and therefore no point in +** calling this function again), return SQLITE_DONE. Or, if an error ** occurs, return some other error code. ** -** More specifically, this function attempts to re-organize the database so +** More specifically, this function attempts to re-organize the database so ** that the last page of the file currently in use is no longer in use. ** ** Parameter nFin is the number of pages that this database would contain ** were this function called until it returns SQLITE_DONE. ** -** If the bCommit parameter is non-zero, this function assumes that the -** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE -** or an error. bCommit is passed true for an auto-vacuum-on-commit +** If the bCommit parameter is non-zero, this function assumes that the +** caller will keep calling incrVacuumStep() until it returns SQLITE_DONE +** or an error. bCommit is passed true for an auto-vacuum-on-commit ** operation, or false for an incremental vacuum. */ static int incrVacuumStep(BtShared *pBt, Pgno nFin, Pgno iLastPg, int bCommit){ @@ -3966,7 +3969,7 @@ if( bCommit==0 ){ /* Remove the page from the files free-list. This is not required ** if bCommit is non-zero. In that case, the free-list will be - ** truncated to zero after this function returns, so it doesn't + ** truncated to zero after this function returns, so it doesn't ** matter if it still contains some garbage entries. */ Pgno iFreePg; @@ -4015,7 +4018,7 @@ } }while( bCommit && iFreePg>nFin ); assert( iFreePgpBt; + pBt = p->pBt; pPager = pBt->pPager; VVA_ONLY( nRef = sqlite3PagerRefcount(pPager); ) @@ -4204,7 +4207,7 @@ ** ** Otherwise, sync the database file for the btree pBt. zSuperJrnl points to ** the name of a super-journal file that should be written into the -** individual journal file, or is NULL, indicating no super-journal file +** individual journal file, or is NULL, indicating no super-journal file ** (single database transaction). ** ** When this is called, the super-journal should already have been @@ -4255,8 +4258,8 @@ downgradeAllSharedCacheTableLocks(p); p->inTrans = TRANS_READ; }else{ - /* If the handle had any kind of transaction open, decrement the - ** transaction count of the shared btree. If the transaction count + /* If the handle had any kind of transaction open, decrement the + ** transaction count of the shared btree. If the transaction count ** reaches 0, set the shared state to TRANS_NONE. The unlockBtreeIfUnused() ** call below will unlock the pager. */ if( p->inTrans!=TRANS_NONE ){ @@ -4267,7 +4270,7 @@ } } - /* Set the current transaction state to TRANS_NONE and unlock the + /* Set the current transaction state to TRANS_NONE and unlock the ** pager if this call closed the only read or write transaction. */ p->inTrans = TRANS_NONE; unlockBtreeIfUnused(pBt); @@ -4288,12 +4291,12 @@ ** the rollback journal (which causes the transaction to commit) and ** drop locks. ** -** Normally, if an error occurs while the pager layer is attempting to +** Normally, if an error occurs while the pager layer is attempting to ** finalize the underlying journal file, this function returns an error and ** the upper layer will attempt a rollback. However, if the second argument -** is non-zero then this b-tree transaction is part of a multi-file -** transaction. In this case, the transaction has already been committed -** (by deleting a super-journal file) and the caller will ignore this +** is non-zero then this b-tree transaction is part of a multi-file +** transaction. In this case, the transaction has already been committed +** (by deleting a super-journal file) and the caller will ignore this ** functions return code. So, even if an error occurs in the pager layer, ** reset the b-tree objects internal state to indicate that the write ** transaction has been closed. This is quite safe, as the pager will have @@ -4308,7 +4311,7 @@ sqlite3BtreeEnter(p); btreeIntegrity(p); - /* If the handle has a write-transaction open, commit the shared-btrees + /* If the handle has a write-transaction open, commit the shared-btrees ** transaction and set the shared state to TRANS_READ. */ if( p->inTrans==TRANS_WRITE ){ @@ -4357,15 +4360,15 @@ ** ** This routine gets called when a rollback occurs. If the writeOnly ** flag is true, then only write-cursors need be tripped - read-only -** cursors save their current positions so that they may continue -** following the rollback. Or, if writeOnly is false, all cursors are +** cursors save their current positions so that they may continue +** following the rollback. Or, if writeOnly is false, all cursors are ** tripped. In general, writeOnly is false if the transaction being ** rolled back modified the database schema. In this case b-tree root ** pages may be moved or deleted from the database altogether, making ** it unsafe for read cursors to continue. ** -** If the writeOnly flag is true and an error is encountered while -** saving the current position of a read-only cursor, all cursors, +** If the writeOnly flag is true and an error is encountered while +** saving the current position of a read-only cursor, all cursors, ** including all read-cursors are tripped. ** ** SQLITE_OK is returned if successful, or if an error occurs while @@ -4471,8 +4474,8 @@ /* ** Start a statement subtransaction. The subtransaction can be rolled -** back independently of the main transaction. You must start a transaction -** before starting a subtransaction. The subtransaction is ended automatically +** back independently of the main transaction. You must start a transaction +** before starting a subtransaction. The subtransaction is ended automatically ** if the main transaction commits or rolls back. ** ** Statement subtransactions are used around individual SQL statements @@ -4509,11 +4512,11 @@ /* ** The second argument to this function, op, is always SAVEPOINT_ROLLBACK ** or SAVEPOINT_RELEASE. This function either releases or rolls back the -** savepoint identified by parameter iSavepoint, depending on the value +** savepoint identified by parameter iSavepoint, depending on the value ** of op. ** ** Normally, iSavepoint is greater than or equal to zero. However, if op is -** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the +** SAVEPOINT_ROLLBACK, then iSavepoint may also be -1. In this case the ** contents of the entire transaction are rolled back. This is different ** from a normal transaction rollback, as no locks are released and the ** transaction remains open. @@ -4538,7 +4541,7 @@ rc = newDatabase(pBt); btreeSetNPage(pBt, pBt->pPage1); - /* pBt->nPage might be zero if the database was corrupt when + /* pBt->nPage might be zero if the database was corrupt when ** the transaction was started. Otherwise, it must be at least 1. */ assert( CORRUPT_DB || pBt->nPage>0 ); } @@ -4576,10 +4579,10 @@ ** is set. If FORDELETE is set, that is a hint to the implementation that ** this cursor will only be used to seek to and delete entries of an index ** as part of a larger DELETE statement. The FORDELETE hint is not used by -** this implementation. But in a hypothetical alternative storage engine +** this implementation. But in a hypothetical alternative storage engine ** in which index entries are automatically deleted when corresponding table ** rows are deleted, the FORDELETE flag is a hint that all SEEK and DELETE -** operations on this cursor can be no-ops and all READ operations can +** operations on this cursor can be no-ops and all READ operations can ** return a null row (2-bytes: 0x01 0x00). ** ** No checking is done to make sure that page iTable really is the @@ -4600,14 +4603,14 @@ BtCursor *pX; /* Looping over other all cursors */ assert( sqlite3BtreeHoldsMutex(p) ); - assert( wrFlag==0 - || wrFlag==BTREE_WRCSR - || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) + assert( wrFlag==0 + || wrFlag==BTREE_WRCSR + || wrFlag==(BTREE_WRCSR|BTREE_FORDELETE) ); - /* The following assert statements verify that if this is a sharable - ** b-tree database, the connection is holding the required table locks, - ** and that no other connection has any open cursor that conflicts with + /* The following assert statements verify that if this is a sharable + ** b-tree database, the connection is holding the required table locks, + ** and that no other connection has any open cursor that conflicts with ** this lock. The iTable<1 term disables the check for corrupt schemas. */ assert( hasSharedCacheTableLock(p, iTable, pKeyInfo!=0, (wrFlag?2:1)) || iTable<1 ); @@ -4822,7 +4825,6 @@ pCur->curFlags &= ~BTCF_Pinned; } -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC /* ** Return the offset into the database file for the start of the ** payload to which the cursor is pointing. @@ -4834,7 +4836,6 @@ return (i64)pCur->pBt->pageSize*((i64)pCur->pPage->pgno - 1) + (i64)(pCur->info.pPayload - pCur->pPage->aData); } -#endif /* SQLITE_ENABLE_OFFSET_SQL_FUNC */ /* ** Return the number of bytes of payload for the entry that pCur is @@ -4860,7 +4861,7 @@ ** 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 datrabase. +** corrupt database. ** ** The current implementation merely returns the size of the underlying ** database file. @@ -4873,15 +4874,15 @@ /* ** Given the page number of an overflow page in the database (parameter -** ovfl), this function finds the page number of the next page in the +** ovfl), this function finds the page number of the next page in the ** linked list of overflow pages. If possible, it uses the auto-vacuum -** pointer-map data instead of reading the content of page ovfl to do so. +** pointer-map data instead of reading the content of page ovfl to do so. ** ** If an error occurs an SQLite error code is returned. Otherwise: ** -** The page number of the next overflow page in the linked list is -** written to *pPgnoNext. If page ovfl is the last page in its linked -** list, *pPgnoNext is set to zero. +** The page number of the next overflow page in the linked list is +** written to *pPgnoNext. If page ovfl is the last page in its linked +** list, *pPgnoNext is set to zero. ** ** If ppPage is not NULL, and a reference to the MemPage object corresponding ** to page number pOvfl was obtained, then *ppPage is set to point to that @@ -4905,9 +4906,9 @@ #ifndef SQLITE_OMIT_AUTOVACUUM /* Try to find the next page in the overflow list using the - ** autovacuum pointer-map pages. Guess that the next page in - ** the overflow list is page number (ovfl+1). If that guess turns - ** out to be wrong, fall back to loading the data of page + ** autovacuum pointer-map pages. Guess that the next page in + ** the overflow list is page number (ovfl+1). If that guess turns + ** out to be wrong, fall back to loading the data of page ** number ovfl to determine the next page number. */ if( pBt->autoVacuum ){ @@ -4995,8 +4996,8 @@ ** ** If the current cursor entry uses one or more overflow pages ** this function may allocate space for and lazily populate -** the overflow page-list cache array (BtCursor.aOverflow). -** Subsequent calls use this cache to make seeking to the supplied offset +** the overflow page-list cache array (BtCursor.aOverflow). +** Subsequent calls use this cache to make seeking to the supplied offset ** more efficient. ** ** Once an overflow page-list cache has been allocated, it must be @@ -5012,7 +5013,7 @@ BtCursor *pCur, /* Cursor pointing to entry to read from */ u32 offset, /* Begin reading this far into payload */ u32 amt, /* Read this many bytes */ - unsigned char *pBuf, /* Write the bytes into this buffer */ + unsigned char *pBuf, /* Write the bytes into this buffer */ int eOp /* zero to read. non-zero to write. */ ){ unsigned char *aPayload; @@ -5066,7 +5067,7 @@ Pgno nextPage; nextPage = get4byte(&aPayload[pCur->info.nLocal]); - + /* If the BtCursor.aOverflow[] has not been allocated, allocate it now. ** ** The aOverflow[] array is sized at one entry for each overflow page @@ -5138,12 +5139,12 @@ #ifdef SQLITE_DIRECT_OVERFLOW_READ /* If all the following are true: ** - ** 1) this is a read operation, and + ** 1) this is a read operation, and ** 2) data is required from the start of this overflow page, and ** 3) there are no dirty pages in the page-cache ** 4) the database is file-backed, and ** 5) the page is not in the WAL file - ** 6) at least 4 bytes have already been read into the output buffer + ** 6) at least 4 bytes have already been read into the output buffer ** ** then data can be read directly from the database file into the ** output buffer, bypassing the page-cache altogether. This speeds @@ -5250,7 +5251,7 @@ #endif /* SQLITE_OMIT_INCRBLOB */ /* -** Return a pointer to payload information from the entry that the +** Return a pointer to payload information from the entry that the ** pCur cursor is pointing to. The pointer is to the beginning of ** the key if index btrees (pPage->intKey==0) and is the data for ** table btrees (pPage->intKey==1). The number of bytes of available @@ -5322,6 +5323,7 @@ ** vice-versa). */ static int moveToChild(BtCursor *pCur, u32 newPgno){ + int rc; assert( cursorOwnsBtShared(pCur) ); assert( pCur->eState==CURSOR_VALID ); assert( pCur->iPageapPage[pCur->iPage] = pCur->pPage; pCur->ix = 0; pCur->iPage++; - return getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur, - pCur->curPagerFlags); + rc = getAndInitPage(pCur->pBt, newPgno, &pCur->pPage, pCur->curPagerFlags); + assert( pCur->pPage!=0 || rc!=SQLITE_OK ); + if( rc==SQLITE_OK + && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) + ){ + releasePage(pCur->pPage); + rc = SQLITE_CORRUPT_PGNO(newPgno); + } + if( rc ){ + pCur->pPage = pCur->apPage[--pCur->iPage]; + } + return rc; } #ifdef SQLITE_DEBUG /* -** Page pParent is an internal (non-leaf) tree page. This function +** Page pParent is an internal (non-leaf) tree page. This function ** asserts that page number iChild is the left-child if the iIdx'th ** cell in page pParent. Or, if iIdx is equal to the total number of ** cells in pParent, that page number iChild is the right-child of @@ -5358,7 +5370,7 @@ } } #else -# define assertParentIndex(x,y,z) +# define assertParentIndex(x,y,z) #endif /* @@ -5376,8 +5388,8 @@ assert( pCur->iPage>0 ); assert( pCur->pPage ); assertParentIndex( - pCur->apPage[pCur->iPage-1], - pCur->aiIdx[pCur->iPage-1], + pCur->apPage[pCur->iPage-1], + pCur->aiIdx[pCur->iPage-1], pCur->pPage->pgno ); testcase( pCur->aiIdx[pCur->iPage-1] > pCur->apPage[pCur->iPage-1]->nCell ); @@ -5394,19 +5406,19 @@ ** ** If the table has a virtual root page, then the cursor is moved to point ** to the virtual root page instead of the actual root page. A table has a -** virtual root page when the actual root page contains no cells and a +** virtual root page when the actual root page contains no cells and a ** single child page. This can only happen with the table rooted at page 1. ** -** If the b-tree structure is empty, the cursor state is set to +** If the b-tree structure is empty, the cursor state is set to ** CURSOR_INVALID and this routine returns SQLITE_EMPTY. Otherwise, ** the cursor is set to point to the first cell located on the root ** (or virtual root) page and the cursor state is set to CURSOR_VALID. ** ** If this function returns successfully, it may be assumed that the -** page-header flags indicate that the [virtual] root-page is the expected +** page-header flags indicate that the [virtual] root-page is the expected ** kind of b-tree page (i.e. if when opening the cursor the caller did not ** specify a KeyInfo structure the flags byte is set to 0x05 or 0x0D, -** indicating a table b-tree, or if the caller did specify a KeyInfo +** indicating a table b-tree, or if the caller did specify a KeyInfo ** structure the flags byte is set to 0x02 or 0x0A, indicating an index ** b-tree). */ @@ -5443,7 +5455,7 @@ sqlite3BtreeClearCursor(pCur); } rc = getAndInitPage(pCur->pBt, pCur->pgnoRoot, &pCur->pPage, - 0, pCur->curPagerFlags); + pCur->curPagerFlags); if( rc!=SQLITE_OK ){ pCur->eState = CURSOR_INVALID; return rc; @@ -5457,19 +5469,19 @@ /* If pCur->pKeyInfo is not NULL, then the caller that opened this cursor ** expected to open it on an index b-tree. Otherwise, if pKeyInfo is ** NULL, the caller expects a table b-tree. If this is not the case, - ** return an SQLITE_CORRUPT error. + ** return an SQLITE_CORRUPT error. ** ** Earlier versions of SQLite assumed that this test could not fail ** if the root page was already loaded when this function was called (i.e. - ** if pCur->iPage>=0). But this is not so if the database is corrupted - ** in such a way that page pRoot is linked into a second b-tree table + ** if pCur->iPage>=0). But this is not so if the database is corrupted + ** in such a way that page pRoot is linked into a second b-tree table ** (or the freelist). */ assert( pRoot->intKey==1 || pRoot->intKey==0 ); if( pRoot->isInit==0 || (pCur->pKeyInfo==0)!=pRoot->intKey ){ return SQLITE_CORRUPT_PAGE(pCur->pPage); } -skip_init: +skip_init: pCur->ix = 0; pCur->info.nSize = 0; pCur->curFlags &= ~(BTCF_AtLast|BTCF_ValidNKey|BTCF_ValidOvfl); @@ -5555,7 +5567,7 @@ *pRes = 0; rc = moveToLeftmost(pCur); }else if( rc==SQLITE_EMPTY ){ - assert( pCur->pgnoRoot==0 || pCur->pPage->nCell==0 ); + assert( pCur->pgnoRoot==0 || (pCur->pPage!=0 && pCur->pPage->nCell==0) ); *pRes = 1; rc = SQLITE_OK; } @@ -5591,7 +5603,7 @@ /* If the cursor already points to the last entry, this is a no-op. */ if( CURSOR_VALID==pCur->eState && (pCur->curFlags & BTCF_AtLast)!=0 ){ #ifdef SQLITE_DEBUG - /* This block serves to assert() that the cursor really does point + /* This block serves to assert() that the cursor really does point ** to the last entry in the b-tree. */ int ii; for(ii=0; iiiPage; ii++){ @@ -5617,7 +5629,7 @@ ** before or after the key. ** ** An integer is written into *pRes which is the result of -** comparing the key with the entry to which the cursor is +** comparing the key with the entry to which the cursor is ** pointing. The meaning of the integer written into ** *pRes is as follows: ** @@ -5660,7 +5672,7 @@ /* 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 slowely */ + ** is still obtained without this case, only a little more slowly. */ if( pCur->info.nKey+1==intKey ){ *pRes = 0; rc = sqlite3BtreeNext(pCur, 0); @@ -5807,10 +5819,10 @@ ** b-tree page. */ testcase( pCell+nCell+1==pPage->aDataEnd ); c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); - }else if( !(pCell[1] & 0x80) + }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal ){ - /* The record-size field is a 2 byte varint and the record + /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ testcase( pCell+nCell+2==pPage->aDataEnd ); c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); @@ -5845,7 +5857,7 @@ ** before or after the key. ** ** An integer is written into *pRes which is the result of -** comparing the key with the entry to which the cursor is +** comparing the key with the entry to which the cursor is ** pointing. The meaning of the integer written into ** *pRes is as follows: ** @@ -5860,7 +5872,7 @@ ** is larger than pIdxKey. ** ** The pIdxKey->eqSeen field is set to 1 if there -** exists an entry in the table that exactly matches pIdxKey. +** exists an entry in the table that exactly matches pIdxKey. */ int sqlite3BtreeIndexMoveto( BtCursor *pCur, /* The cursor to be moved */ @@ -5881,8 +5893,8 @@ xRecordCompare = sqlite3VdbeFindCompare(pIdxKey); pIdxKey->errCode = 0; - assert( pIdxKey->default_rc==1 - || pIdxKey->default_rc==0 + assert( pIdxKey->default_rc==1 + || pIdxKey->default_rc==0 || pIdxKey->default_rc==-1 ); @@ -5910,7 +5922,7 @@ *pRes = c; return SQLITE_OK; /* Cursor already pointing at the correct spot */ } - if( pCur->iPage>0 + if( pCur->iPage>0 && indexCellCompare(pCur, 0, pIdxKey, xRecordCompare)<=0 && pIdxKey->errCode==SQLITE_OK ){ @@ -5964,9 +5976,9 @@ /* The maximum supported page-size is 65536 bytes. This means that ** the maximum number of record bytes stored on an index B-Tree ** page is less than 16384 bytes and may be stored as a 2-byte - ** varint. This information is used to attempt to avoid parsing - ** the entire cell by checking for the cases where the record is - ** stored entirely within the b-tree page by inspecting the first + ** varint. This information is used to attempt to avoid parsing + ** the entire cell by checking for the cases where the record is + ** stored entirely within the b-tree page by inspecting the first ** 2 bytes of the cell. */ nCell = pCell[0]; @@ -5976,10 +5988,10 @@ ** b-tree page. */ testcase( pCell+nCell+1==pPage->aDataEnd ); c = xRecordCompare(nCell, (void*)&pCell[1], pIdxKey); - }else if( !(pCell[1] & 0x80) + }else if( !(pCell[1] & 0x80) && (nCell = ((nCell&0x7f)<<7) + pCell[1])<=pPage->maxLocal ){ - /* The record-size field is a 2 byte varint and the record + /* The record-size field is a 2 byte varint and the record ** fits entirely on the main b-tree page. */ testcase( pCell+nCell+2==pPage->aDataEnd ); c = xRecordCompare(nCell, (void*)&pCell[2], pIdxKey); @@ -5987,10 +5999,10 @@ /* The record flows over onto one or more overflow pages. In ** this case the whole cell needs to be parsed, a buffer allocated ** and accessPayload() used to retrieve the record into the - ** buffer before VdbeRecordCompare() can be called. + ** buffer before VdbeRecordCompare() can be called. ** ** If the record is corrupt, the xRecordCompare routine may read - ** up to two varints past the end of the buffer. An extra 18 + ** up to two varints past the end of the buffer. An extra 18 ** bytes of padding is allocated at the end of the buffer in ** case this happens. */ void *pCellKey; @@ -6022,7 +6034,7 @@ c = sqlite3VdbeRecordCompare(nCell, pCellKey, pIdxKey); sqlite3_free(pCellKey); } - assert( + assert( (pIdxKey->errCode!=SQLITE_CORRUPT || c==0) && (pIdxKey->errCode!=SQLITE_NOMEM || pCur->pBtree->db->mallocFailed) ); @@ -6056,10 +6068,36 @@ }else{ chldPg = get4byte(findCell(pPage, lwr)); } - pCur->ix = (u16)lwr; - rc = moveToChild(pCur, chldPg); - if( rc ) break; - } + + /* This block is similar to an in-lined version of: + ** + ** pCur->ix = (u16)lwr; + ** rc = moveToChild(pCur, chldPg); + ** if( rc ) break; + */ + pCur->info.nSize = 0; + pCur->curFlags &= ~(BTCF_ValidNKey|BTCF_ValidOvfl); + if( pCur->iPage>=(BTCURSOR_MAX_DEPTH-1) ){ + return SQLITE_CORRUPT_BKPT; + } + pCur->aiIdx[pCur->iPage] = (u16)lwr; + pCur->apPage[pCur->iPage] = pCur->pPage; + pCur->ix = 0; + pCur->iPage++; + rc = getAndInitPage(pCur->pBt, chldPg, &pCur->pPage, pCur->curPagerFlags); + if( rc==SQLITE_OK + && (pCur->pPage->nCell<1 || pCur->pPage->intKey!=pCur->curIntKey) + ){ + releasePage(pCur->pPage); + rc = SQLITE_CORRUPT_PGNO(chldPg); + } + if( rc ){ + pCur->pPage = pCur->apPage[--pCur->iPage]; + break; + } + /* + ***** End of in-lined moveToChild() call */ + } moveto_index_finish: pCur->info.nSize = 0; assert( (pCur->curFlags & BTCF_ValidOvfl)==0 ); @@ -6084,7 +6122,7 @@ /* ** Return an estimate for the number of rows in the table that pCur is -** pointing to. Return a negative number if no estimate is currently +** pointing to. Return a negative number if no estimate is currently ** available. */ i64 sqlite3BtreeRowCountEst(BtCursor *pCur){ @@ -6108,7 +6146,7 @@ } /* -** Advance the cursor to the next entry in the database. +** Advance the cursor to the next entry in the database. ** Return value: ** ** SQLITE_OK success @@ -6297,7 +6335,7 @@ ** SQLITE_OK is returned on success. Any other return value indicates ** an error. *ppPage is set to NULL in the event of an error. ** -** If the "nearby" parameter is not 0, then an effort is made to +** If the "nearby" parameter is not 0, then an effort is made to ** locate a page close to the page number "nearby". This can be used in an ** attempt to keep related pages close to each other in the database file, ** which in turn can make database access faster. @@ -6339,7 +6377,7 @@ Pgno iTrunk; u8 searchList = 0; /* If the free-list must be searched for 'nearby' */ u32 nSearch = 0; /* Count of the number of search attempts */ - + /* If eMode==BTALLOC_EXACT and a query of the pointer-map ** shows that the page 'nearby' is somewhere on the free-list, then ** the entire-list will be searched for that page. @@ -6402,8 +6440,8 @@ ** is the number of leaf page pointers to follow. */ k = get4byte(&pTrunk->aData[4]); if( k==0 && !searchList ){ - /* The trunk has no leaves and the list is not being searched. - ** So extract the trunk page itself and use it as the newly + /* The trunk has no leaves and the list is not being searched. + ** So extract the trunk page itself and use it as the newly ** allocated page */ assert( pPrevTrunk==0 ); rc = sqlite3PagerWrite(pTrunk->pDbPage); @@ -6420,8 +6458,8 @@ rc = SQLITE_CORRUPT_PGNO(iTrunk); goto end_allocate_page; #ifndef SQLITE_OMIT_AUTOVACUUM - }else if( searchList - && (nearby==iTrunk || (iTrunkaData[0], &pTrunk->aData[0], 4); } }else{ - /* The trunk page is required by the caller but it contains + /* The trunk page is required by the caller but it contains ** pointers to free-list leaves. The first leaf becomes a trunk ** page in this case. */ MemPage *pNewTrunk; Pgno iNewTrunk = get4byte(&pTrunk->aData[8]); - if( iNewTrunk>mxPage ){ + if( iNewTrunk>mxPage ){ rc = SQLITE_CORRUPT_PGNO(iTrunk); goto end_allocate_page; } @@ -6520,8 +6558,8 @@ goto end_allocate_page; } testcase( iPage==mxPage ); - if( !searchList - || (iPage==nearby || (iPagepPage1; /* Local reference to page 1 */ MemPage *pPage; /* Page being freed. May be NULL. */ int rc; /* Return Code */ @@ -6740,7 +6778,7 @@ /* If control flows to this point, then it was not possible to add the ** the page being freed as a leaf page of the first trunk in the free-list. - ** Possibly because the free-list is empty, or possibly because the + ** Possibly because the free-list is empty, or possibly because the ** first trunk in the free-list is full. Either way, the page being freed ** will become the new first trunk page in the free-list. */ @@ -6797,15 +6835,15 @@ assert( pBt->usableSize > 4 ); ovflPageSize = pBt->usableSize - 4; nOvfl = (pInfo->nPayload - pInfo->nLocal + ovflPageSize - 1)/ovflPageSize; - assert( nOvfl>0 || + assert( nOvfl>0 || (CORRUPT_DB && (pInfo->nPayload + ovflPageSize)btreePagecount(pBt) ){ - /* 0 is not a legal page number and page 1 cannot be an - ** overflow page. Therefore if ovflPgno<2 or past the end of the + /* 0 is not a legal page number and page 1 cannot be an + ** overflow page. Therefore if ovflPgno<2 or past the end of the ** file the database must be corrupt. */ return SQLITE_CORRUPT_BKPT; } @@ -6817,11 +6855,11 @@ if( ( pOvfl || ((pOvfl = btreePageLookup(pBt, ovflPgno))!=0) ) && sqlite3PagerPageRefcount(pOvfl->pDbPage)!=1 ){ - /* There is no reason any cursor should have an outstanding reference + /* There is no reason any cursor should have an outstanding reference ** to an overflow page belonging to a cell that is being deleted/updated. - ** So if there exists more than one reference to this page, then it - ** must not really be an overflow page and the database must be corrupt. - ** It is helpful to detect this before calling freePage2(), as + ** So if there exists more than one reference to this page, then it + ** must not really be an overflow page and the database must be corrupt. + ** It is helpful to detect this before calling freePage2(), as ** freePage2() may zero the page contents if secure-delete mode is ** enabled. If this 'overflow' page happens to be a page that the ** caller is iterating through or using in some other way, this @@ -6843,7 +6881,7 @@ /* Call xParseCell to compute the size of a cell. If the cell contains ** overflow, then invoke cellClearOverflow to clear out that overflow. -** STore the result code (SQLITE_OK or some error code) in rc. +** Store the result code (SQLITE_OK or some error code) in rc. ** ** Implemented as macro to force inlining for performance. */ @@ -6907,7 +6945,7 @@ pSrc = pX->pKey; nHeader += putVarint32(&pCell[nHeader], nPayload); } - + /* Fill in the payload */ pPayload = &pCell[nHeader]; if( nPayload<=pPage->maxLocal ){ @@ -6998,8 +7036,8 @@ if( pBt->autoVacuum ){ do{ pgnoOvfl++; - } while( - PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) + } while( + PTRMAP_ISPAGE(pBt, pgnoOvfl) || pgnoOvfl==PENDING_BYTE_PAGE(pBt) ); } #endif @@ -7007,9 +7045,9 @@ #ifndef SQLITE_OMIT_AUTOVACUUM /* If the database supports auto-vacuum, and the second or subsequent ** overflow page is being allocated, add an entry to the pointer-map - ** for that page now. + ** for that page now. ** - ** If this is the first overflow page, then write a partial entry + ** If this is the first overflow page, then write a partial entry ** to the pointer-map. If we write nothing to this pointer-map slot, ** then the optimistic overflow chain processing in clearCell() ** may misinterpret the uninitialized values and delete the @@ -7110,8 +7148,8 @@ ** will not fit, then make a copy of the cell content into pTemp if ** pTemp is not null. Regardless of pTemp, allocate a new entry ** in pPage->apOvfl[] and make it point to the cell content (either -** in pTemp or the original pCell) and also record its index. -** Allocating a new entry in pPage->aCell[] implies that +** in pTemp or the original pCell) and also record its index. +** Allocating a new entry in pPage->aCell[] implies that ** pPage->nOverflow is incremented. ** ** The insertCellFast() routine below works exactly the same as @@ -7423,16 +7461,16 @@ } /* -** Array apCell[] contains pointers to nCell b-tree page cells. The +** Array apCell[] contains pointers to nCell b-tree page cells. The ** szCell[] array contains the size in bytes of each cell. This function ** replaces the current contents of page pPg with the contents of the cell ** array. ** ** Some of the cells in apCell[] may currently be stored in pPg. This -** function works around problems caused by this by making a copy of any +** function works around problems caused by this by making a copy of any ** such cells before overwriting the page data. ** -** The MemPage.nFree field is invalidated by this function. It is the +** The MemPage.nFree field is invalidated by this function. It is the ** responsibility of the caller to set it correctly. */ static int rebuildPage( @@ -7454,12 +7492,13 @@ int k; /* Current slot in pCArray->apEnd[] */ u8 *pSrcEnd; /* Current pCArray->apEnd[k] value */ + assert( nCell>0 ); assert( i(u32)usableSize) ){ j = 0; } + if( j>(u32)usableSize ){ j = 0; } memcpy(&pTmp[j], &aData[j], usableSize - j); - for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kixNx[k]<=i; k++){} pSrcEnd = pCArray->apEnd[k]; pData = pEnd; @@ -7514,7 +7553,7 @@ ** cell in the array. It is the responsibility of the caller to ensure ** that it is safe to overwrite this part of the cell-pointer array. ** -** When this function is called, *ppData points to the start of the +** When this function is called, *ppData points to the start of the ** content area on page pPg. If the size of the content area is extended, ** *ppData is updated to point to the new start of the content area ** before returning. @@ -7522,7 +7561,7 @@ ** Finally, argument pBegin points to the byte immediately following the ** end of the space required by this page for the cell-pointer area (for ** all cells - not just those inserted by the current call). If the content -** area must be extended to before this point in order to accomodate all +** area must be extended to before this point in order to accommodate all ** cells in apCell[], then the cells do not fit and non-zero is returned. */ static int pageInsertArray( @@ -7542,7 +7581,7 @@ u8 *pEnd; /* Maximum extent of cell data */ assert( CORRUPT_DB || pPg->hdrOffset==0 ); /* Never called on page 1 */ if( iEnd<=iFirst ) return 0; - for(k=0; pCArray->ixNx[k]<=i && ALWAYS(kixNx[k]<=i ; k++){} pEnd = pCArray->apEnd[k]; while( 1 /*Exit by break*/ ){ int sz, rc; @@ -7760,6 +7799,7 @@ return SQLITE_OK; editpage_fail: /* Unable to edit this page. Rebuild it from scratch instead. */ + if( nNew<1 ) return SQLITE_CORRUPT_BKPT; populateCellCache(pCArray, iNew, nNew); return rebuildPage(pCArray, iNew, nNew, pPg); } @@ -7798,12 +7838,12 @@ assert( sqlite3_mutex_held(pPage->pBt->mutex) ); assert( sqlite3PagerIswriteable(pParent->pDbPage) ); assert( pPage->nOverflow==1 ); - + if( pPage->nCell==0 ) return SQLITE_CORRUPT_BKPT; /* dbfuzz001.test */ assert( pPage->nFree>=0 ); assert( pParent->nFree>=0 ); - /* Allocate a new page. This page will become the right-sibling of + /* Allocate a new page. This page will become the right-sibling of ** pPage. Make the parent page writable, so that the new divider cell ** may be inserted. If both these operations are successful, proceed. */ @@ -7834,10 +7874,10 @@ 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 + ** 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 thh code below. + ** 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. @@ -7848,14 +7888,14 @@ ptrmapPutOvflPtr(pNew, pNew, pCell, &rc); } } - + /* Create a divider cell to insert into pParent. The divider cell ** consists of a 4-byte page number (the page number of pPage) and ** a variable length key value (which must be the same value as the ** largest key on pPage). ** - ** To find the largest key value on pPage, first find the right-most - ** cell on pPage. The first two fields of this cell are the + ** To find the largest key value on pPage, first find the right-most + ** cell on pPage. The first two fields of this cell are the ** record-length (a variable length integer at most 32-bits in size) ** and the key value (a variable length integer, may have any value). ** The first of the while(...) loops below skips over the record-length @@ -7876,7 +7916,7 @@ /* Set the right-child pointer of pParent to point to the new page. */ put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew); - + /* Release the reference to the new page. */ releasePage(pNew); } @@ -7888,7 +7928,7 @@ #if 0 /* ** This function does not contribute anything to the operation of SQLite. -** it is sometimes activated temporarily while debugging code responsible +** it is sometimes activated temporarily while debugging code responsible ** for setting pointer-map entries. */ static int ptrmapCheckPages(MemPage **apPage, int nPage){ @@ -7903,7 +7943,7 @@ for(j=0; jnCell; j++){ CellInfo info; u8 *z; - + z = findCell(pPage, j); pPage->xParseCell(pPage, z, &info); if( info.nLocalpgno==1) ? 100 : 0); int rc; int iData; - - + + assert( pFrom->isInit ); assert( pFrom->nFree>=iToHdr ); assert( get2byte(&aFrom[iFromHdr+5]) <= (int)pBt->usableSize ); - + /* Copy the b-tree node content from page pFrom to page pTo. */ iData = get2byte(&aFrom[iFromHdr+5]); memcpy(&aTo[iData], &aFrom[iData], pBt->usableSize-iData); memcpy(&aTo[iToHdr], &aFrom[iFromHdr], pFrom->cellOffset + 2*pFrom->nCell); - + /* Reinitialize page pTo so that the contents of the MemPage structure ** match the new data. The initialization of pTo can actually fail under - ** fairly obscure circumstances, even though it is a copy of initialized + ** fairly obscure circumstances, even though it is a copy of initialized ** page pFrom. */ pTo->isInit = 0; @@ -7976,7 +8016,7 @@ *pRC = rc; return; } - + /* If this is an auto-vacuum database, update the pointer-map entries ** for any b-tree or overflow pages that pTo now contains the pointers to. */ @@ -7991,13 +8031,13 @@ ** (hereafter "the page") and up to 2 siblings so that all pages have about the ** same amount of free space. Usually a single sibling on either side of the ** page are used in the balancing, though both siblings might come from one -** side if the page is the first or last child of its parent. If the page +** side if the page is the first or last child of its parent. If the page ** has fewer than 2 siblings (something which can only happen if the page ** is a root page or a child of a root page) then all available siblings ** participate in the balancing. ** -** The number of siblings of the page might be increased or decreased by -** one or two in an effort to keep pages nearly full but not over full. +** The number of siblings of the page might be increased or decreased by +** one or two in an effort to keep pages nearly full but not over full. ** ** Note that when this routine is called, some of the cells on the page ** might not actually be stored in MemPage.aData[]. This can happen @@ -8008,7 +8048,7 @@ ** inserted into or removed from the parent page (pParent). Doing so ** may cause the parent page to become overfull or underfull. If this ** happens, it is the responsibility of the caller to invoke the correct -** balancing routine to fix this problem (see the balance() routine). +** balancing routine to fix this problem (see the balance() routine). ** ** If this routine fails for any reason, it might leave the database ** in a corrupted state. So if this routine fails, the database should @@ -8023,7 +8063,7 @@ ** of the page-size, the aOvflSpace[] buffer is guaranteed to be large ** enough for all overflow cells. ** -** If aOvflSpace is set to a null pointer, this function returns +** If aOvflSpace is set to a null pointer, this function returns ** SQLITE_NOMEM. */ static int balance_nonroot( @@ -8067,7 +8107,7 @@ assert( sqlite3PagerIswriteable(pParent->pDbPage) ); /* At this point pParent may have at most one overflow cell. And if - ** this overflow cell is present, it must be the cell with + ** this overflow cell is present, it must be the cell with ** index iParentIdx. This scenario comes about when this function ** is called (indirectly) from sqlite3BtreeDelete(). */ @@ -8079,11 +8119,11 @@ } assert( pParent->nFree>=0 ); - /* Find the sibling pages to balance. Also locate the cells in pParent - ** that divide the siblings. An attempt is made to find NN siblings on - ** either side of pPage. More siblings are taken from one side, however, + /* Find the sibling pages to balance. Also locate the cells in pParent + ** that divide the siblings. An attempt is made to find NN siblings on + ** either side of pPage. More siblings are taken from one side, however, ** if there are fewer than NN siblings on the other side. If pParent - ** has NB or fewer children then all children of pParent are taken. + ** has NB or fewer children then all children of pParent are taken. ** ** This loop also drops the divider cells from the parent page. This ** way, the remainder of the function does not have to deal with any @@ -8095,7 +8135,7 @@ nxDiv = 0; }else{ assert( bBulk==0 || bBulk==1 ); - if( iParentIdx==0 ){ + if( iParentIdx==0 ){ nxDiv = 0; }else if( iParentIdx==i ){ nxDiv = i-2+bBulk; @@ -8113,7 +8153,7 @@ pgno = get4byte(pRight); while( 1 ){ if( rc==SQLITE_OK ){ - rc = getAndInitPage(pBt, pgno, &apOld[i], 0, 0); + rc = getAndInitPage(pBt, pgno, &apOld[i], 0); } if( rc ){ memset(apOld, 0, (i+1)*sizeof(MemPage*)); @@ -8144,7 +8184,7 @@ ** This is safe because dropping a cell only overwrites the first ** four bytes of it, and this function does not need the first ** four bytes of the divider cell. So the pointer is safe to use - ** later on. + ** later on. ** ** But not if we are in secure-delete mode. In secure-delete mode, ** the dropCell() routine will overwrite the entire cell with zeroes. @@ -8307,7 +8347,7 @@ ** Figure out the number of pages needed to hold all b.nCell cells. ** Store this number in "k". Also compute szNew[] which is the total ** size of all cells on the i-th page and cntNew[] which is the index - ** in b.apCell[] of the cell that divides page i from page i+1. + ** in b.apCell[] of the cell that divides page i from page i+1. ** cntNew[k] should equal b.nCell. ** ** Values computed by this block: @@ -8317,7 +8357,7 @@ ** cntNew[i]: Index in b.apCell[] and b.szCell[] for the first cell to ** the right of the i-th sibling page. ** usableSpace: Number of bytes of space available on each sibling. - ** + ** */ usableSpace = pBt->usableSize - 12 + leafCorrection; for(i=k=0; i0), or ** (2) pPage is a virtual root page. A virtual root page is when @@ -8478,15 +8518,15 @@ } /* - ** Reassign page numbers so that the new pages are in ascending order. + ** Reassign page numbers so that the new pages are in ascending order. ** This helps to keep entries in the disk file in order so that a scan - ** of the table is closer to a linear scan through the file. That in turn + ** of the table is closer to a linear scan through the file. That in turn ** helps the operating system to deliver pages from the disk more rapidly. ** ** An O(N*N) sort algorithm is used, but since N is never more than NB+2 ** (5), that is not a performance concern. ** - ** When NB==3, this one optimization makes the database about 25% faster + ** When NB==3, this one optimization makes the database about 25% faster ** for large insertions and deletions. */ for(i=0; ipgno); /* If the sibling pages are not leaves, ensure that the right-child pointer - ** of the right-most new sibling page is set to the value that was + ** of the right-most new sibling page is set to the value that was ** originally in the same field of the right-most old sibling page. */ if( (pageFlags & PTF_LEAF)==0 && nOld!=nNew ){ MemPage *pOld = (nNew>nOld ? apNew : apOld)[nOld-1]; memcpy(&apNew[nNew-1]->aData[8], &pOld->aData[8], 4); } - /* Make any required updates to pointer map entries associated with + /* Make any required updates to pointer map entries associated with ** cells stored on sibling pages following the balance operation. Pointer ** map entries associated with divider cells are set by the insertCell() ** routine. The associated pointer map entries are: @@ -8556,9 +8596,9 @@ ** b) if the sibling pages are not leaves, the child page associated ** with the cell. ** - ** If the sibling pages are not leaves, then the pointer map entry - ** associated with the right-child of each sibling may also need to be - ** updated. This happens below, after the sibling pages have been + ** If the sibling pages are not leaves, then the pointer map entry + ** associated with the right-child of each sibling may also need to be + ** updated. This happens below, after the sibling pages have been ** populated, not here. */ if( ISAUTOVACUUM(pBt) ){ @@ -8583,7 +8623,7 @@ } /* Cell pCell is destined for new sibling page pNew. Originally, it - ** was either part of sibling page iOld (possibly an overflow cell), + ** was either part of sibling page iOld (possibly an overflow cell), ** or else the divider cell to the left of sibling page iOld. So, ** if sibling page iOld had the same page number as pNew, and if ** pCell really was a part of sibling page iOld (not a divider or @@ -8620,9 +8660,9 @@ if( !pNew->leaf ){ memcpy(&pNew->aData[8], pCell, 4); }else if( leafData ){ - /* If the tree is a leaf-data tree, and the siblings are leaves, - ** then there is no divider cell in b.apCell[]. Instead, the divider - ** cell consists of the integer key for the right-most cell of + /* If the tree is a leaf-data tree, and the siblings are leaves, + ** then there is no divider cell in b.apCell[]. Instead, the divider + ** cell consists of the integer key for the right-most cell of ** the sibling-page assembled above only. */ CellInfo info; @@ -8635,9 +8675,9 @@ pCell -= 4; /* Obscure case for non-leaf-data trees: If the cell at pCell was ** previously stored on a leaf node, and its reported size was 4 - ** bytes, then it may actually be smaller than this + ** bytes, then it may actually be smaller than this ** (see btreeParseCellPtr(), 4 bytes is the minimum size of - ** any cell). But it is important to pass the correct size to + ** any cell). But it is important to pass the correct size to ** insertCell(), so reparse the cell now. ** ** This can only happen for b-trees used to evaluate "IN (SELECT ...)" @@ -8652,9 +8692,9 @@ iOvflSpace += sz; assert( sz<=pBt->maxLocal+23 ); assert( iOvflSpace <= (int)pBt->pageSize ); - for(k=0; b.ixNx[k]<=j && ALWAYS(k=0 && iPg=1 || i>=0 ); + assert( iPg=0 /* On the upwards pass, or... */ || cntOld[iPg-1]>=cntNew[iPg-1] /* Condition (1) is true */ @@ -8735,8 +8777,8 @@ ** b-tree structure by one. This is described as the "balance-shallower" ** sub-algorithm in some documentation. ** - ** If this is an auto-vacuum database, the call to copyNodeContent() - ** sets all pointer-map entries corresponding to database image pages + ** If this is an auto-vacuum database, the call to copyNodeContent() + ** sets all pointer-map entries corresponding to database image pages ** for which the pointer is stored within the content being copied. ** ** It is critical that the child page be defragmented before being @@ -8747,7 +8789,7 @@ assert( nNew==1 || CORRUPT_DB ); rc = defragmentPage(apNew[0], -1); testcase( rc!=SQLITE_OK ); - assert( apNew[0]->nFree == + assert( apNew[0]->nFree == (get2byteNotZero(&apNew[0]->aData[5]) - apNew[0]->cellOffset - apNew[0]->nCell*2) || rc!=SQLITE_OK @@ -8777,7 +8819,7 @@ #if 0 if( ISAUTOVACUUM(pBt) && rc==SQLITE_OK && apNew[0]->isInit ){ /* The ptrmapCheckPages() contains assert() statements that verify that - ** all pointer map pages are set correctly. This is helpful while + ** all pointer map pages are set correctly. This is helpful while ** debugging. This is usually disabled because a corrupt database may ** cause an assert() statement to fail. */ ptrmapCheckPages(apNew, nNew); @@ -8807,15 +8849,15 @@ ** ** A new child page is allocated and the contents of the current root ** page, including overflow cells, are copied into the child. The root -** page is then overwritten to make it an empty page with the right-child +** page is then overwritten to make it an empty page with the right-child ** pointer pointing to the new page. ** -** Before returning, all pointer-map entries corresponding to pages +** Before returning, all pointer-map entries corresponding to pages ** that the new child-page now contains pointers to are updated. The ** entry corresponding to the new right-child pointer of the root ** page is also updated. ** -** If successful, *ppChild is set to contain a reference to the child +** If successful, *ppChild is set to contain a reference to the child ** page and SQLITE_OK is returned. In this case the caller is required ** to call releasePage() on *ppChild exactly once. If an error occurs, ** an error code is returned and *ppChild is set to 0. @@ -8829,7 +8871,7 @@ assert( pRoot->nOverflow>0 ); assert( sqlite3_mutex_held(pBt->mutex) ); - /* Make pRoot, the root page of the b-tree, writable. Allocate a new + /* Make pRoot, the root page of the b-tree, writable. Allocate a new ** page that will become the new right-child of pPage. Copy the contents ** of the node stored on pRoot into the new child page. */ @@ -8894,7 +8936,7 @@ /* ** The page that pCur currently points to has just been modified in ** some way. This function figures out if this modification means the -** tree needs to be balanced, and if so calls the appropriate balancing +** tree needs to be balanced, and if so calls the appropriate balancing ** routine. Balancing routines are: ** ** balance_quick() @@ -8926,7 +8968,7 @@ ** balance_deeper() function to create a new child for the root-page ** and copy the current contents of the root-page to it. The ** next iteration of the do-loop will balance the child page. - */ + */ assert( balance_deeper_called==0 ); VVA_ONLY( balance_deeper_called++ ); rc = balance_deeper(pPage, &pCur->apPage[1]); @@ -8943,7 +8985,7 @@ } }else if( sqlite3PagerPageRefcount(pPage->pDbPage)>1 ){ /* The page being written is not a root page, and there is currently - ** more than one reference to it. This only happens if the page is one + ** more than one reference to it. This only happens if the page is one ** of its own ancestor pages. Corruption. */ rc = SQLITE_CORRUPT_BKPT; }else{ @@ -8965,17 +9007,17 @@ /* Call balance_quick() to create a new sibling of pPage on which ** to store the overflow cell. balance_quick() inserts a new cell ** into pParent, which may cause pParent overflow. If this - ** happens, the next iteration of the do-loop will balance pParent + ** happens, the next iteration of the do-loop will balance pParent ** use either balance_nonroot() or balance_deeper(). Until this ** happens, the overflow cell is stored in the aBalanceQuickSpace[] - ** buffer. + ** buffer. ** ** The purpose of the following assert() is to check that only a ** single call to balance_quick() is made for each call to this ** function. If this were not verified, a subtle bug involving reuse ** of the aBalanceQuickSpace[] might sneak in. */ - assert( balance_quick_called==0 ); + assert( balance_quick_called==0 ); VVA_ONLY( balance_quick_called++ ); rc = balance_quick(pParent, pPage, aBalanceQuickSpace); }else @@ -8986,15 +9028,15 @@ ** modifying the contents of pParent, which may cause pParent to ** become overfull or underfull. The next iteration of the do-loop ** will balance the parent page to correct this. - ** + ** ** If the parent page becomes overfull, the overflow cell or cells - ** are stored in the pSpace buffer allocated immediately below. + ** are stored in the pSpace buffer allocated immediately below. ** A subsequent iteration of the do-loop will deal with this by ** calling balance_nonroot() (balance_deeper() may be called first, ** but it doesn't deal with overflow cells - just moves them to a - ** different page). Once this subsequent call to balance_nonroot() + ** different page). Once this subsequent call to balance_nonroot() ** has completed, it is safe to release the pSpace buffer used by - ** the previous call, as the overflow cell data will have been + ** the previous call, as the overflow cell data will have been ** copied either into the body of a database page or into the new ** pSpace buffer passed to the latter call to balance_nonroot(). */ @@ -9002,9 +9044,9 @@ rc = balance_nonroot(pParent, iIdx, pSpace, iPage==1, pCur->hints&BTREE_BULKLOAD); if( pFree ){ - /* If pFree is not NULL, it points to the pSpace buffer used + /* If pFree is not NULL, it points to the pSpace buffer used ** by a previous call to balance_nonroot(). Its contents are - ** now stored either on real database pages or within the + ** now stored either on real database pages or within the ** new pSpace buffer, so it may be safely freed here. */ sqlite3PageFree(pFree); } @@ -9044,7 +9086,7 @@ ){ int nData = pX->nData - iOffset; if( nData<=0 ){ - /* Overwritting with zeros */ + /* Overwriting with zeros */ int i; for(i=0; ipData to write */ @@ -9123,7 +9165,7 @@ if( rc ) return rc; iOffset += ovflPageSize; }while( iOffsetpKeyInfo==0 ){ assert( pX->pKey==0 ); - /* If this is an insert into a table b-tree, invalidate any incrblob + /* If this is an insert into a table b-tree, invalidate any incrblob ** cursors open on the row being replaced */ if( p->hasIncrblobCur ){ invalidateIncrblobCursors(p, pCur->pgnoRoot, pX->nKey, 0); } - /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing ** to a row with the same key as the new entry being inserted. */ #ifdef SQLITE_DEBUG @@ -9284,14 +9326,14 @@ ** to an adjacent cell. Move the cursor so that it is pointing either ** to the cell to be overwritten or an adjacent cell. */ - rc = sqlite3BtreeTableMoveto(pCur, pX->nKey, + rc = sqlite3BtreeTableMoveto(pCur, pX->nKey, (flags & BTREE_APPEND)!=0, &loc); if( rc ) return rc; } }else{ /* This is an index or a WITHOUT ROWID table */ - /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing + /* If BTREE_SAVEPOSITION is set, the cursor must already be pointing ** to a row with the same key as the new entry being inserted. */ assert( (flags & BTREE_SAVEPOSITION)==0 || loc==0 ); @@ -9311,7 +9353,7 @@ r.eqSeen = 0; rc = sqlite3BtreeIndexMoveto(pCur, &r, &loc); }else{ - rc = btreeMoveto(pCur, pX->pKey, pX->nKey, + rc = btreeMoveto(pCur, pX->pKey, pX->nKey, (flags & BTREE_APPEND)!=0, &loc); } if( rc ) return rc; @@ -9332,7 +9374,7 @@ } } } - assert( pCur->eState==CURSOR_VALID + assert( pCur->eState==CURSOR_VALID || (pCur->eState==CURSOR_INVALID && loc) || CORRUPT_DB ); pPage = pCur->pPage; @@ -9393,14 +9435,14 @@ BTREE_CLEAR_CELL(rc, pPage, oldCell, info); testcase( pCur->curFlags & BTCF_ValidOvfl ); invalidateOverflowCache(pCur); - if( info.nSize==szNew && info.nLocal==info.nPayload + if( info.nSize==szNew && info.nLocal==info.nPayload && (!ISAUTOVACUUM(p->pBt) || szNewminLocal) ){ /* Overwrite the old cell with the new if they are the same size. ** We could also try to do this if the old cell is smaller, then add ** the leftover space to the free list. But experiments show that ** doing that is no faster then skipping this optimization and just - ** calling dropCell() and insertCell(). + ** calling dropCell() and insertCell(). ** ** This optimization cannot be used on an autovacuum database if the ** new entry uses overflow pages, as the insertCell() call below is @@ -9428,7 +9470,7 @@ assert( pPage->nOverflow==0 || rc==SQLITE_OK ); assert( rc!=SQLITE_OK || pPage->nCell>0 || pPage->nOverflow>0 ); - /* If no error has occurred and pPage has an overflow cell, call balance() + /* If no error has occurred and pPage has an overflow cell, call balance() ** to redistribute the cells within the tree. Since balance() may move ** the cursor, zero the BtCursor.info.nSize and BTCF_ValidNKey ** variables. @@ -9454,7 +9496,7 @@ rc = balance(pCur); /* Must make sure nOverflow is reset to zero even if the balance() - ** fails. Internal data structure corruption will result otherwise. + ** fails. Internal data structure corruption will result otherwise. ** Also, set the cursor state to invalid. This stops saveCursorPosition() ** from trying to save the current position of the cursor. */ pCur->pPage->nOverflow = 0; @@ -9534,14 +9576,14 @@ pPgnoOut = &aOut[nOut]; pBt->nPreformatSize += 4; } - + if( nRem>nIn ){ if( aIn+nIn+4>pSrc->pPage->aDataEnd ){ return SQLITE_CORRUPT_BKPT; } ovflIn = get4byte(&pSrc->info.pPayload[nIn]); } - + do { nRem -= nOut; do{ @@ -9566,7 +9608,7 @@ } } }while( rc==SQLITE_OK && nOut>0 ); - + if( rc==SQLITE_OK && nRem>0 && ALWAYS(pPgnoOut) ){ Pgno pgnoNew; MemPage *pNew = 0; @@ -9585,7 +9627,7 @@ } } }while( nRem>0 && rc==SQLITE_OK ); - + releasePage(pPageOut); sqlite3PagerUnref(pPageIn); return rc; @@ -9593,7 +9635,7 @@ } /* -** Delete the entry that the cursor is pointing to. +** Delete the entry that the cursor is pointing to. ** ** If the BTREE_SAVEPOSITION bit of the flags parameter is zero, then ** the cursor is left pointing at an arbitrary location after the delete. @@ -9611,12 +9653,12 @@ */ int sqlite3BtreeDelete(BtCursor *pCur, u8 flags){ Btree *p = pCur->pBtree; - BtShared *pBt = p->pBt; + BtShared *pBt = p->pBt; int rc; /* Return code */ MemPage *pPage; /* Page to delete cell from */ unsigned char *pCell; /* Pointer to cell to delete */ int iCellIdx; /* Index of cell to delete */ - int iCellDepth; /* Depth of node containing pCell */ + int iCellDepth; /* Depth of node containing pCell */ CellInfo info; /* Size of the cell being deleted */ u8 bPreserve; /* Keep cursor valid. 2 for CURSOR_SKIPNEXT */ @@ -9655,8 +9697,8 @@ /* If the BTREE_SAVEPOSITION bit is on, then the cursor position must ** be preserved following this delete operation. If the current delete ** will cause a b-tree rebalance, then this is done by saving the cursor - ** key and leaving the cursor in CURSOR_REQUIRESEEK state before - ** returning. + ** key and leaving the cursor in CURSOR_REQUIRESEEK state before + ** returning. ** ** If the current delete will not cause a rebalance, then the cursor ** will be left in CURSOR_SKIPNEXT state pointing to the entry immediately @@ -9670,7 +9712,7 @@ */ bPreserve = (flags & BTREE_SAVEPOSITION)!=0; if( bPreserve ){ - if( !pPage->leaf + if( !pPage->leaf || (pPage->nFree+pPage->xCellSize(pPage,pCell)+2) > (int)(pBt->usableSize*2/3) || pPage->nCell==1 /* See dbfuzz001.test for a test case */ @@ -9766,7 +9808,7 @@ ** on the leaf node first. If the balance proceeds far enough up the ** tree that we can be sure that any problem in the internal node has ** been corrected, so be it. Otherwise, after balancing the leaf node, - ** walk the cursor up the tree to the internal node and balance it as + ** walk the cursor up the tree to the internal node and balance it as ** well. */ assert( pCur->pPage->nOverflow==0 ); assert( pCur->pPage->nFree>=0 ); @@ -9827,7 +9869,7 @@ MemPage *pRoot; Pgno pgnoRoot; int rc; - int ptfFlags; /* Page-type flage for the root page of new table */ + int ptfFlags; /* Page-type flags for the root page of new table */ assert( sqlite3BtreeHoldsMutex(p) ); assert( pBt->inTransaction==TRANS_WRITE ); @@ -9930,7 +9972,7 @@ } }else{ pRoot = pPageMove; - } + } /* Update the pointer-map and meta-data with the new root-page number. */ ptrmapPut(pBt, pgnoRoot, PTRMAP_ROOTPAGE, 0, &rc); @@ -9996,9 +10038,9 @@ if( pgno>btreePagecount(pBt) ){ return SQLITE_CORRUPT_BKPT; } - rc = getAndInitPage(pBt, pgno, &pPage, 0, 0); + rc = getAndInitPage(pBt, pgno, &pPage, 0); if( rc ) return rc; - if( (pBt->openFlags & BTREE_SINGLE)==0 + if( (pBt->openFlags & BTREE_SINGLE)==0 && sqlite3PagerPageRefcount(pPage->pDbPage) != (1 + (pgno==1)) ){ rc = SQLITE_CORRUPT_BKPT; @@ -10085,12 +10127,12 @@ ** cursors on the table. ** ** If AUTOVACUUM is enabled and the page at iTable is not the last -** root page in the database file, then the last root page +** root page in the database file, then the last root page ** in the database file is moved into the slot formerly occupied by ** iTable and that last slot formerly occupied by the last root page ** is added to the freelist instead of iTable. In this say, all ** root pages are kept at the beginning of the database file, which -** is necessary for AUTOVACUUM to work right. *piMoved is set to the +** is necessary for AUTOVACUUM to work right. *piMoved is set to the ** page number that used to be the last root page in the file before ** the move. If no page gets moved, *piMoved is set to 0. ** The last root page is recorded in meta[3] and the value of @@ -10128,7 +10170,7 @@ if( iTable==maxRootPgno ){ /* If the table being dropped is the table with the largest root-page - ** number in the database, put the root page on the free list. + ** number in the database, put the root page on the free list. */ freePage(pPage, &rc); releasePage(pPage); @@ -10137,7 +10179,7 @@ } }else{ /* The table being dropped does not have the largest root-page - ** number in the database. So move the page that does into the + ** number in the database. So move the page that does into the ** gap left by the deleted root-page. */ MemPage *pMove; @@ -10179,7 +10221,7 @@ releasePage(pPage); } #endif - return rc; + return rc; } int sqlite3BtreeDropTable(Btree *p, int iTable, int *piMoved){ int rc; @@ -10198,7 +10240,7 @@ ** is the number of free pages currently in the database. Meta[1] ** through meta[15] are available for use by higher layers. Meta[0] ** is read-only, the others are read/write. -** +** ** The schema layer numbers meta values differently. At the schema ** layer (and the SetCookie and ReadCookie opcodes) the number of ** free pages is not visible. So Cookie[0] is the same as Meta[1]. @@ -10268,7 +10310,7 @@ ** The first argument, pCur, is a cursor opened on some b-tree. Count the ** number of entries in the b-tree and write the result to *pnEntry. ** -** SQLITE_OK is returned if the operation is successfully executed. +** SQLITE_OK is returned if the operation is successfully executed. ** Otherwise, if an error is encountered (i.e. an IO error or database ** corruption) an SQLite error code is returned. */ @@ -10283,13 +10325,13 @@ } /* Unless an error occurs, the following loop runs one iteration for each - ** page in the B-Tree structure (not including overflow pages). + ** page in the B-Tree structure (not including overflow pages). */ while( rc==SQLITE_OK && !AtomicLoad(&db->u1.isInterrupted) ){ int iIdx; /* Index of child node in parent */ MemPage *pPage; /* Current page of the b-tree */ - /* If this is a leaf page or the tree is not an int-key tree, then + /* If this is a leaf page or the tree is not an int-key tree, then ** this page contains countable entries. Increment the entry counter ** accordingly. */ @@ -10298,7 +10340,7 @@ nEntry += pPage->nCell; } - /* pPage is a leaf node. This loop navigates the cursor so that it + /* pPage is a leaf node. This loop navigates the cursor so that it ** points to the first interior cell that it points to the parent of ** the next page in the tree that has not yet been visited. The ** pCur->aiIdx[pCur->iPage] value is set to the index of the parent cell @@ -10322,7 +10364,7 @@ pPage = pCur->pPage; } - /* Descend to the child node of the cell that the cursor currently + /* Descend to the child node of the cell that the cursor currently ** points at. This is the right-child if (iIdx==pPage->nCell). */ iIdx = pCur->ix; @@ -10417,7 +10459,8 @@ ** corresponds to page iPg is already set. */ static int getPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); return (pCheck->aPgRef[iPg/8] & (1 << (iPg & 0x07))); } @@ -10425,7 +10468,8 @@ ** Set the bit in the IntegrityCk.aPgRef[] array that corresponds to page iPg. */ static void setPageReferenced(IntegrityCk *pCheck, Pgno iPg){ - assert( iPg<=pCheck->nPage && sizeof(pCheck->aPgRef[0])==1 ); + assert( pCheck->aPgRef!=0 ); + assert( iPg<=pCheck->nCkPage && sizeof(pCheck->aPgRef[0])==1 ); pCheck->aPgRef[iPg/8] |= (1 << (iPg & 0x07)); } @@ -10439,7 +10483,7 @@ ** Also check that the page number is in bounds. */ static int checkRef(IntegrityCk *pCheck, Pgno iPage){ - if( iPage>pCheck->nPage || iPage==0 ){ + if( iPage>pCheck->nCkPage || iPage==0 ){ checkAppendMsg(pCheck, "invalid page number %u", iPage); return 1; } @@ -10453,7 +10497,7 @@ #ifndef SQLITE_OMIT_AUTOVACUUM /* -** Check that the entry in the pointer-map for page iChild maps to +** Check that the entry in the pointer-map for page iChild maps to ** page iParent, pointer type ptrType. If not, append an error message ** to pCheck. */ @@ -10476,7 +10520,7 @@ if( ePtrmapType!=eType || iPtrmapParent!=iParent ){ checkAppendMsg(pCheck, - "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)", + "Bad ptr map entry key=%u expected=(%u,%u) got=(%u,%u)", iChild, eType, iParent, ePtrmapType, iPtrmapParent); } } @@ -10571,7 +10615,7 @@ ** property. ** ** This heap is used for cell overlap and coverage testing. Each u32 -** entry represents the span of a cell or freeblock on a btree page. +** entry represents the span of a cell or freeblock on a btree page. ** The upper 16 bits are the index of the first byte of a range and the ** lower 16 bits are the index of the last byte of that range. */ @@ -10603,7 +10647,7 @@ aHeap[j] = x; i = j; } - return 1; + return 1; } #ifndef SQLITE_OMIT_INTEGRITY_CHECK @@ -10611,7 +10655,7 @@ ** Do various sanity checks on a single page of a tree. Return ** the tree depth. Root pages return 0. Parents of root pages ** return 1, and so forth. -** +** ** These checks are done: ** ** 1. Make sure that cells and freeblocks do not overlap @@ -10662,10 +10706,11 @@ if( iPage==0 ) return 0; if( checkRef(pCheck, iPage) ) return 0; pCheck->zPfx = "Tree %u page %u: "; - pCheck->v0 = pCheck->v1 = iPage; + pCheck->v1 = iPage; if( (rc = btreeGetPage(pBt, iPage, &pPage, 0))!=0 ){ checkAppendMsg(pCheck, "unable to get the page. error code=%d", rc); + if( rc==SQLITE_IOERR_NOMEM ) pCheck->rc = SQLITE_NOMEM; goto end_of_check; } @@ -10811,7 +10856,7 @@ ** ** EVIDENCE-OF: R-20690-50594 The second field of the b-tree page header ** is the offset of the first freeblock, or zero if there are no - ** freeblocks on the page. + ** freeblocks on the page. */ i = get2byte(&data[hdr+1]); while( i>0 ){ @@ -10831,13 +10876,13 @@ assert( (u32)j<=usableSize-4 ); /* Enforced by btreeComputeFreeSpace() */ i = j; } - /* Analyze the min-heap looking for overlap between cells and/or + /* Analyze the min-heap looking for overlap between cells and/or ** freeblocks, and counting the number of untracked bytes in nFrag. - ** + ** ** Each min-heap entry is of the form: (start_address<<16)|end_address. ** There is an implied first entry the covers the page header, the cell ** pointer index, and the gap between the cell pointer index and the start - ** of cell content. + ** of cell content. ** ** The loop below pulls entries from the min-heap in order and compares ** the start_address against the previous end_address. If there is an @@ -10936,15 +10981,15 @@ sCheck.db = db; sCheck.pBt = pBt; sCheck.pPager = pBt->pPager; - sCheck.nPage = btreePagecount(sCheck.pBt); + sCheck.nCkPage = btreePagecount(sCheck.pBt); sCheck.mxErr = mxErr; sqlite3StrAccumInit(&sCheck.errMsg, 0, zErr, sizeof(zErr), SQLITE_MAX_LENGTH); sCheck.errMsg.printfFlags = SQLITE_PRINTF_INTERNAL; - if( sCheck.nPage==0 ){ + if( sCheck.nCkPage==0 ){ goto integrity_ck_cleanup; } - sCheck.aPgRef = sqlite3MallocZero((sCheck.nPage / 8)+ 1); + sCheck.aPgRef = sqlite3MallocZero((sCheck.nCkPage / 8)+ 1); if( !sCheck.aPgRef ){ checkOom(&sCheck); goto integrity_ck_cleanup; @@ -10956,7 +11001,7 @@ } i = PENDING_BYTE_PAGE(pBt); - if( i<=sCheck.nPage ) setPageReferenced(&sCheck, i); + if( i<=sCheck.nCkPage ) setPageReferenced(&sCheck, i); /* Check the integrity of the freelist */ @@ -10999,6 +11044,7 @@ checkPtrmap(&sCheck, aRoot[i], PTRMAP_ROOTPAGE, 0); } #endif + sCheck.v0 = aRoot[i]; checkTreePage(&sCheck, aRoot[i], ¬Used, LARGEST_INT64); } pBt->db->flags = savedDbFlags; @@ -11006,7 +11052,7 @@ /* Make sure every page in the file is referenced */ if( !bPartial ){ - for(i=1; i<=sCheck.nPage && sCheck.mxErr; i++){ + for(i=1; i<=sCheck.nCkPage && sCheck.mxErr; i++){ #ifdef SQLITE_OMIT_AUTOVACUUM if( getPageReferenced(&sCheck, i)==0 ){ checkAppendMsg(&sCheck, "Page %u: never used", i); @@ -11015,11 +11061,11 @@ /* If the database supports auto-vacuum, make sure no tables contain ** references to pointer-map pages. */ - if( getPageReferenced(&sCheck, i)==0 && + if( getPageReferenced(&sCheck, i)==0 && (PTRMAP_PAGENO(pBt, i)!=i || !pBt->autoVacuum) ){ checkAppendMsg(&sCheck, "Page %u: never used", i); } - if( getPageReferenced(&sCheck, i)!=0 && + if( getPageReferenced(&sCheck, i)!=0 && (PTRMAP_PAGENO(pBt, i)==i && pBt->autoVacuum) ){ checkAppendMsg(&sCheck, "Page %u: pointer map referenced", i); } @@ -11084,7 +11130,7 @@ /* ** Run a checkpoint on the Btree passed as the first argument. ** -** Return SQLITE_LOCKED if this or any other connection has an open +** Return SQLITE_LOCKED if this or any other connection has an open ** transaction on the shared-cache the argument Btree is connected to. ** ** Parameter eMode is one of SQLITE_CHECKPOINT_PASSIVE, FULL or RESTART. @@ -11117,20 +11163,20 @@ /* ** This function returns a pointer to a blob of memory associated with ** a single shared-btree. The memory is used by client code for its own -** purposes (for example, to store a high-level schema associated with +** purposes (for example, to store a high-level schema associated with ** the shared-btree). The btree layer manages reference counting issues. ** ** The first time this is called on a shared-btree, nBytes bytes of memory -** are allocated, zeroed, and returned to the caller. For each subsequent +** are allocated, zeroed, and returned to the caller. For each subsequent ** call the nBytes parameter is ignored and a pointer to the same blob -** of memory returned. +** of memory returned. ** ** If the nBytes parameter is 0 and the blob of memory has not yet been ** allocated, a null pointer is returned. If the blob has already been ** allocated, it is returned as normal. ** -** Just before the shared-btree is closed, the function passed as the -** xFree argument when the memory allocation was made is invoked on the +** Just before the shared-btree is closed, the function passed as the +** xFree argument when the memory allocation was made is invoked on the ** blob of allocated memory. The xFree function should not call sqlite3_free() ** on the memory, the btree layer does that. */ @@ -11146,8 +11192,8 @@ } /* -** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared -** btree as the argument handle holds an exclusive lock on the +** Return SQLITE_LOCKED_SHAREDCACHE if another user of the same shared +** btree as the argument handle holds an exclusive lock on the ** sqlite_schema table. Otherwise SQLITE_OK. */ int sqlite3BtreeSchemaLocked(Btree *p){ @@ -11188,11 +11234,11 @@ #ifndef SQLITE_OMIT_INCRBLOB /* -** Argument pCsr must be a cursor opened for writing on an -** INTKEY table currently pointing at a valid table entry. +** Argument pCsr must be a cursor opened for writing on an +** INTKEY table currently pointing at a valid table entry. ** This function modifies the data stored as part of that entry. ** -** Only the data content may only be modified, it is not possible to +** Only the data content may only be modified, it is not possible to ** change the length of the data stored. If this function is called with ** parameters that attempt to write past the end of the existing data, ** no modifications are made and SQLITE_CORRUPT is returned. @@ -11223,7 +11269,7 @@ VVA_ONLY(rc =) saveAllCursors(pCsr->pBt, pCsr->pgnoRoot, pCsr); assert( rc==SQLITE_OK ); - /* Check some assumptions: + /* Check some assumptions: ** (a) the cursor is open for writing, ** (b) there is a read/write transaction open, ** (c) the connection holds a write-lock on the table (if required), @@ -11242,7 +11288,7 @@ return accessPayload(pCsr, offset, amt, (unsigned char *)z, 1); } -/* +/* ** Mark this cursor as an incremental blob cursor. */ void sqlite3BtreeIncrblobCursor(BtCursor *pCur){ @@ -11252,14 +11298,14 @@ #endif /* -** Set both the "read version" (single byte at byte offset 18) and +** Set both the "read version" (single byte at byte offset 18) and ** "write version" (single byte at byte offset 19) fields in the database ** header to iVersion. */ int sqlite3BtreeSetVersion(Btree *pBtree, int iVersion){ BtShared *pBt = pBtree->pBt; int rc; /* Return code */ - + assert( iVersion==1 || iVersion==2 ); /* If setting the version fields to 1, do not automatically open the @@ -11328,7 +11374,7 @@ /* ** Return the number of connections to the BtShared object accessed by -** the Btree handle passed as the only argument. For private caches +** the Btree handle passed as the only argument. For private caches ** this is always 1. For shared caches it may be 1 or greater. */ int sqlite3BtreeConnectionCount(Btree *p){ diff -Nru sqlite3-3.42.0/src/btree.h sqlite3-3.44.0-0/src/btree.h --- sqlite3-3.42.0/src/btree.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/btree.h 2023-11-04 14:23:58.000000000 +0000 @@ -321,9 +321,7 @@ i64 sqlite3BtreeIntegerKey(BtCursor*); void sqlite3BtreeCursorPin(BtCursor*); void sqlite3BtreeCursorUnpin(BtCursor*); -#ifdef SQLITE_ENABLE_OFFSET_SQL_FUNC i64 sqlite3BtreeOffset(BtCursor*); -#endif int sqlite3BtreePayload(BtCursor*, u32 offset, u32 amt, void*); const void *sqlite3BtreePayloadFetch(BtCursor*, u32 *pAmt); u32 sqlite3BtreePayloadSize(BtCursor*); diff -Nru sqlite3-3.42.0/src/btreeInt.h sqlite3-3.44.0-0/src/btreeInt.h --- sqlite3-3.42.0/src/btreeInt.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/btreeInt.h 2023-11-04 14:23:58.000000000 +0000 @@ -180,7 +180,7 @@ ** 0x81 0x00 becomes 0x00000080 ** 0x82 0x00 becomes 0x00000100 ** 0x80 0x7f becomes 0x0000007f -** 0x8a 0x91 0xd1 0xac 0x78 becomes 0x12345678 +** 0x81 0x91 0xd1 0xac 0x78 becomes 0x12345678 ** 0x81 0x81 0x81 0x81 0x01 becomes 0x10204081 ** ** Variable length integers are used for rowids and to hold the number of @@ -263,7 +263,7 @@ ** 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 allocats an +** 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.) ** @@ -695,7 +695,7 @@ BtShared *pBt; /* The tree being checked out */ Pager *pPager; /* The associated pager. Also accessible by pBt->pPager */ u8 *aPgRef; /* 1 bit per page in the db (see above) */ - Pgno nPage; /* Number of pages in the database */ + Pgno nCkPage; /* Pages in the database. 0 for partial check */ int mxErr; /* Stop accumulating errors when this reaches zero */ int nErr; /* Number of messages written to zErrMsg so far */ int rc; /* SQLITE_OK, SQLITE_NOMEM, or SQLITE_INTERRUPT */ @@ -719,7 +719,7 @@ /* ** get2byteAligned(), unlike get2byte(), requires that its argument point to a -** two-byte aligned address. get2bytea() is only used for accessing the +** two-byte aligned address. get2byteAligned() is only used for accessing the ** cell addresses in a btree header. */ #if SQLITE_BYTEORDER==4321 diff -Nru sqlite3-3.42.0/src/build.c sqlite3-3.44.0-0/src/build.c --- sqlite3-3.42.0/src/build.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/build.c 2023-11-04 14:23:58.000000000 +0000 @@ -37,7 +37,7 @@ }; /* -** Record the fact that we want to lock a table at run-time. +** Record the fact that we want to lock a table at run-time. ** ** The table to be locked has root page iTab and is found in database iDb. ** A read or a write lock can be taken depending on isWritelock. @@ -100,7 +100,7 @@ */ static void codeTableLocks(Parse *pParse){ int i; - Vdbe *pVdbe = pParse->pVdbe; + Vdbe *pVdbe = pParse->pVdbe; assert( pVdbe!=0 ); for(i=0; inTableLock; i++){ @@ -164,7 +164,7 @@ v = sqlite3GetVdbe(pParse); if( v==0 ) pParse->rc = SQLITE_ERROR; } - assert( !pParse->isMultiWrite + assert( !pParse->isMultiWrite || sqlite3VdbeAssertMayAbort(v, pParse->mayAbort)); if( v ){ if( pParse->bReturning ){ @@ -234,29 +234,26 @@ pParse->nVtabLock = 0; #endif - /* Once all the cookies have been verified and transactions opened, - ** obtain the required table-locks. This is a no-op unless the +#ifndef SQLITE_OMIT_SHARED_CACHE + /* Once all the cookies have been verified and transactions opened, + ** obtain the required table-locks. This is a no-op unless the ** shared-cache feature is enabled. */ - codeTableLocks(pParse); + if( pParse->nTableLock ) codeTableLocks(pParse); +#endif /* Initialize any AUTOINCREMENT data structures required. */ - sqlite3AutoincrementBegin(pParse); + if( pParse->pAinc ) sqlite3AutoincrementBegin(pParse); - /* Code constant expressions that where factored out of inner loops. - ** - ** The pConstExpr list might also contain expressions that we simply - ** want to keep around until the Parse object is deleted. Such - ** expressions have iConstExprReg==0. Do not generate code for - ** those expressions, of course. + /* Code constant expressions that were factored out of inner loops. */ if( pParse->pConstExpr ){ ExprList *pEL = pParse->pConstExpr; pParse->okConstFactor = 0; for(i=0; inExpr; i++){ - int iReg = pEL->a[i].u.iConstExprReg; - sqlite3ExprCode(pParse, pEL->a[i].pExpr, iReg); + assert( pEL->a[i].u.iConstExprReg>0 ); + sqlite3ExprCode(pParse, pEL->a[i].pExpr, pEL->a[i].u.iConstExprReg); } } @@ -386,7 +383,7 @@ || sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 || sqlite3StrICmp(zName+7, &LEGACY_SCHEMA_TABLE[7])==0 ){ - p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, LEGACY_TEMP_SCHEMA_TABLE); } }else{ @@ -413,7 +410,7 @@ if( sqlite3StrICmp(zName+7, &PREFERRED_SCHEMA_TABLE[7])==0 ){ p = sqlite3HashFind(&db->aDb[0].pSchema->tblHash, LEGACY_SCHEMA_TABLE); }else if( sqlite3StrICmp(zName+7, &PREFERRED_TEMP_SCHEMA_TABLE[7])==0 ){ - p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, + p = sqlite3HashFind(&db->aDb[1].pSchema->tblHash, LEGACY_TEMP_SCHEMA_TABLE); } } @@ -442,7 +439,7 @@ /* Read the database schema. If an error occurs, leave an error message ** and code in pParse and return NULL. */ - if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 + if( (db->mDbFlags & DBFLAG_SchemaKnownOk)==0 && SQLITE_OK!=sqlite3ReadSchema(pParse) ){ return 0; @@ -495,7 +492,7 @@ ** sqlite3FixSrcList() for details. */ Table *sqlite3LocateTableItem( - Parse *pParse, + Parse *pParse, u32 flags, SrcItem *p ){ @@ -527,7 +524,7 @@ } /* -** Locate the in-memory structure that describes +** Locate the in-memory structure that describes ** a particular index given the name of that index ** and the name of the database that contains the index. ** Return NULL if not found. @@ -755,7 +752,7 @@ } /* -** Return the collating squence name for a column +** Return the collating sequence name for a column */ const char *sqlite3ColumnColl(Column *pCol){ const char *z; @@ -802,10 +799,10 @@ ** ** This routine just deletes the data structure. It does not unlink ** the table data structure from the hash table. But it does destroy -** memory structures of the indices and foreign keys associated with +** memory structures of the indices and foreign keys associated with ** the table. ** -** The db parameter is optional. It is needed if the Table object +** The db parameter is optional. It is needed if the Table object ** contains lookaside memory. (Table objects in the schema do not use ** lookaside memory, but some ephemeral Table objects do.) Or the ** db parameter can be used with db->pnBytesFreed to measure the memory @@ -817,7 +814,7 @@ #ifdef SQLITE_DEBUG /* Record the number of outstanding lookaside allocations in schema Tables ** prior to doing any free() operations. Since schema Tables do not use - ** lookaside, this number should not change. + ** lookaside, this number should not change. ** ** If malloc has already failed, it may be that it failed while allocating ** a Table object that was going to be marked ephemeral. So do not check @@ -835,7 +832,7 @@ assert( pIndex->pSchema==pTable->pSchema || (IsVirtual(pTable) && pIndex->idxType!=SQLITE_IDXTYPE_APPDEF) ); if( db->pnBytesFreed==0 && !IsVirtual(pTable) ){ - char *zName = pIndex->zName; + char *zName = pIndex->zName; TESTONLY ( Index *pOld = ) sqlite3HashInsert( &pIndex->pSchema->idxHash, zName, 0 ); @@ -957,7 +954,7 @@ /* ** The token *pName contains the name of a database (either "main" or ** "temp" or the name of an attached db). This routine returns the -** index of the named database in db->aDb[], or -1 if the named db +** index of the named database in db->aDb[], or -1 if the named db ** does not exist. */ int sqlite3FindDb(sqlite3 *db, Token *pName){ @@ -973,7 +970,7 @@ ** pName1 and pName2. If the table name was fully qualified, for example: ** ** CREATE TABLE xxx.yyy (...); -** +** ** Then pName1 is set to "xxx" and pName2 "yyy". On the other hand if ** the table name is not fully qualified, i.e.: ** @@ -1127,7 +1124,7 @@ ** The storage column number (0,1,2,....) is the index of the value ** as it appears in the record on disk. Or, if the input column is ** the N-th virtual column (zero-based) then the storage number is -** the number of non-virtual columns in the table plus N. +** the number of non-virtual columns in the table plus N. ** ** The true column number is the index (0,1,2,...) of the column in ** the CREATE TABLE statement. @@ -1235,7 +1232,7 @@ iDb = sqlite3TwoPartName(pParse, pName1, pName2, &pName); if( iDb<0 ) return; if( !OMIT_TEMPDB && isTemp && pName2->n>0 && iDb!=1 ){ - /* If creating a temp table, the name may not be qualified. Unless + /* If creating a temp table, the name may not be qualified. Unless ** the database name is "temp" anyway. */ sqlite3ErrorMsg(pParse, "temporary table name must be unqualified"); return; @@ -1326,7 +1323,7 @@ ** the schema table. Note in particular that we must go ahead ** and allocate the record number for the table entry now. Before any ** PRIMARY KEY or UNIQUE keywords are parsed. Those keywords will cause - ** indices to be created and the table record must come before the + ** indices to be created and the table record must come before the ** indices. Hence, the record number for the table must be allocated ** now. */ @@ -1344,7 +1341,7 @@ } #endif - /* If the file format and encoding in the database have not been set, + /* If the file format and encoding in the database have not been set, ** set them now. */ reg1 = pParse->regRowid = ++pParse->nMem; @@ -1411,19 +1408,12 @@ #endif /* -** Name of the special TEMP trigger used to implement RETURNING. The -** name begins with "sqlite_" so that it is guaranteed not to collide -** with any application-generated triggers. -*/ -#define RETURNING_TRIGGER_NAME "sqlite_returning" - -/* ** Clean up the data structures associated with the RETURNING clause. */ static void sqlite3DeleteReturning(sqlite3 *db, Returning *pRet){ Hash *pHash; pHash = &(db->aDb[1].pSchema->trigHash); - sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, 0); + sqlite3HashInsert(pHash, pRet->zName, 0); sqlite3ExprListDelete(db, pRet->pReturnEL); sqlite3DbFree(db, pRet); } @@ -1466,7 +1456,9 @@ (void(*)(sqlite3*,void*))sqlite3DeleteReturning, pRet); testcase( pParse->earlyCleanup ); if( db->mallocFailed ) return; - pRet->retTrig.zName = RETURNING_TRIGGER_NAME; + sqlite3_snprintf(sizeof(pRet->zName), pRet->zName, + "sqlite_returning_%p", pParse); + pRet->retTrig.zName = pRet->zName; pRet->retTrig.op = TK_RETURNING; pRet->retTrig.tr_tm = TRIGGER_AFTER; pRet->retTrig.bReturning = 1; @@ -1477,9 +1469,9 @@ pRet->retTStep.pTrig = &pRet->retTrig; pRet->retTStep.pExprList = pList; pHash = &(db->aDb[1].pSchema->trigHash); - assert( sqlite3HashFind(pHash, RETURNING_TRIGGER_NAME)==0 + assert( sqlite3HashFind(pHash, pRet->zName)==0 || pParse->nErr || pParse->ifNotExists ); - if( sqlite3HashInsert(pHash, RETURNING_TRIGGER_NAME, &pRet->retTrig) + if( sqlite3HashInsert(pHash, pRet->zName, &pRet->retTrig) ==&pRet->retTrig ){ sqlite3OomFault(db); } @@ -1513,7 +1505,7 @@ } if( !IN_RENAME_OBJECT ) sqlite3DequoteToken(&sName); - /* Because keywords GENERATE ALWAYS can be converted into indentifiers + /* Because keywords GENERATE ALWAYS can be converted into identifiers ** by the parser, we can sometimes end up with a typename that ends ** with "generated always". Check for this case and omit the surplus ** text. */ @@ -1573,7 +1565,7 @@ pCol->zCnName = z; pCol->hName = hName; sqlite3ColumnPropertiesFromName(p, pCol); - + if( sType.n==0 ){ /* If there is no type specified, columns have the default affinity ** 'BLOB' with a default size of 4 bytes. */ @@ -1632,11 +1624,11 @@ ** Scan the column type name zType (length nType) and return the ** associated affinity type. ** -** This routine does a case-independent search of zType for the +** This routine does a case-independent search of zType for the ** substrings in the following table. If one of the substrings is ** found, the corresponding affinity is returned. If zType contains -** more than one of the substrings, entries toward the top of -** the table take priority. For example, if zType is 'BLOBINT', +** more than one of the substrings, entries toward the top of +** the table take priority. For example, if zType is 'BLOBINT', ** SQLITE_AFF_INTEGER is returned. ** ** Substring | Affinity @@ -1734,7 +1726,7 @@ Parse *pParse, /* Parsing context */ Expr *pExpr, /* The parsed expression of the default value */ const char *zStart, /* Start of the default value text */ - const char *zEnd /* First character past end of defaut value text */ + const char *zEnd /* First character past end of default value text */ ){ Table *p; Column *pCol; @@ -1775,7 +1767,7 @@ /* ** Backwards Compatibility Hack: -** +** ** Historical versions of SQLite accepted strings as column names in ** indexes and PRIMARY KEY constraints and in UNIQUE constraints. Example: ** @@ -1809,11 +1801,11 @@ sqlite3ErrorMsg(pParse, "generated columns cannot be part of the PRIMARY KEY"); } -#endif +#endif } /* -** Designate the PRIMARY KEY for the table. pList is a list of names +** Designate the PRIMARY KEY for the table. pList is a list of names ** of columns that form the primary key. If pList is NULL, then the ** most recently added column of the table is the primary key. ** @@ -1843,7 +1835,7 @@ int nTerm; if( pTab==0 ) goto primary_key_exit; if( pTab->tabFlags & TF_HasPrimaryKey ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "table \"%s\" has more than one primary key", pTab->zName); goto primary_key_exit; } @@ -1928,7 +1920,7 @@ while( sqlite3Isspace(zEnd[-1]) ){ zEnd--; } t.z = zStart; t.n = (int)(zEnd - t.z); - sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1); + sqlite3ExprListSetName(pParse, pTab->pCheck, &t, 1); } }else #endif @@ -1956,7 +1948,7 @@ if( sqlite3LocateCollSeq(pParse, zColl) ){ Index *pIdx; sqlite3ColumnSetColl(db, &p->aCol[i], zColl); - + /* If the column is declared as " PRIMARY KEY COLLATE ", ** then an index may have been created on this column before the ** collation type was added. Correct this if it is the case. @@ -2054,7 +2046,7 @@ sqlite3 *db = pParse->db; Vdbe *v = pParse->pVdbe; assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); - sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, + sqlite3VdbeAddOp3(v, OP_SetCookie, iDb, BTREE_SCHEMA_VERSION, (int)(1+(unsigned)db->aDb[iDb].pSchema->schema_cookie)); } @@ -2075,14 +2067,14 @@ } /* -** The first parameter is a pointer to an output buffer. The second +** The first parameter is a pointer to an output buffer. The second ** parameter is a pointer to an integer that contains the offset at ** which to write into the output buffer. This function copies the ** nul-terminated string pointed to by the third parameter, zSignedIdent, ** to the specified offset in the buffer and updates *pIdx to refer ** to the first byte after the last byte written before returning. -** -** If the string zSignedIdent consists entirely of alpha-numeric +** +** If the string zSignedIdent consists entirely of alphanumeric ** characters, does not begin with a digit and is not an SQL keyword, ** then it is copied to the output buffer exactly as it is. Otherwise, ** it is quoted using double-quotes. @@ -2125,7 +2117,7 @@ n += identLength(pCol->zCnName) + 5; } n += identLength(p->zName); - if( n<50 ){ + if( n<50 ){ zSep = ""; zSep2 = ","; zEnd = ")"; @@ -2168,7 +2160,7 @@ testcase( pCol->affinity==SQLITE_AFF_INTEGER ); testcase( pCol->affinity==SQLITE_AFF_REAL ); testcase( pCol->affinity==SQLITE_AFF_FLEXNUM ); - + zType = azType[pCol->affinity - SQLITE_AFF_BLOB]; len = sqlite3Strlen30(zType); assert( pCol->affinity==SQLITE_AFF_BLOB @@ -2234,7 +2226,7 @@ for(i=0; inColumn; i++){ i16 x = pIdx->aiColumn[i]; assert( xpTable->nCol ); - wIndex += x<0 ? 1 : aCol[pIdx->aiColumn[i]].szEst; + wIndex += x<0 ? 1 : aCol[x].szEst; } pIdx->szIdxRow = sqlite3LogEst(wIndex*4); } @@ -2277,7 +2269,7 @@ assert( j!=XN_ROWID && j!=XN_EXPR ); for(i=0; iaiColumn[i]>=0 || j>=0 ); - if( pIdx->aiColumn[i]==j + if( pIdx->aiColumn[i]==j && sqlite3StrICmp(pIdx->azColl[i], pPk->azColl[iCol])==0 ){ return 1; @@ -2329,7 +2321,7 @@ ** Changes include: ** ** (1) Set all columns of the PRIMARY KEY schema object to be NOT NULL. -** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY +** (2) Convert P3 parameter of the OP_CreateBtree from BTREE_INTKEY ** into BTREE_BLOBKEY. ** (3) Bypass the creation of the sqlite_schema table entry ** for the PRIMARY KEY as the primary key index is now @@ -2377,13 +2369,13 @@ } /* Locate the PRIMARY KEY index. Or, if this table was originally - ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. + ** an INTEGER PRIMARY KEY table, create a new PRIMARY KEY index. */ if( pTab->iPKey>=0 ){ ExprList *pList; Token ipkToken; sqlite3TokenInit(&ipkToken, pTab->aCol[pTab->iPKey].zCnName); - pList = sqlite3ExprListAppend(pParse, 0, + pList = sqlite3ExprListAppend(pParse, 0, sqlite3ExprAlloc(db, TK_ID, &ipkToken, 0)); if( pList==0 ){ pTab->tabFlags &= ~TF_WithoutRowid; @@ -2622,7 +2614,7 @@ ** the sqlite_schema table. We do not want to create it again. ** ** If the pSelect argument is not NULL, it means that this routine -** was called to create a table generated from a +** was called to create a table generated from a ** "CREATE TABLE ... AS SELECT ..." statement. The column names of ** the new table will match the result set of the SELECT. */ @@ -2701,7 +2693,7 @@ pCol->notNull = OE_Abort; p->tabFlags |= TF_HasNotNull; } - } + } } assert( (p->tabFlags & TF_HasPrimaryKey)==0 @@ -2758,7 +2750,7 @@ ** tree that have been allocated from lookaside memory, which is ** illegal in a schema and will lead to errors or heap corruption ** when the database connection closes. */ - sqlite3ColumnSetExpr(pParse, p, &p->aCol[ii], + sqlite3ColumnSetExpr(pParse, p, &p->aCol[ii], sqlite3ExprAlloc(db, TK_NULL, 0, 0)); } }else{ @@ -2796,7 +2788,7 @@ sqlite3VdbeAddOp1(v, OP_Close, 0); - /* + /* ** Initialize zType for the new view or table. */ if( IsOrdinaryTable(p) ){ @@ -2880,12 +2872,12 @@ Token *pEnd2 = tabOpts ? &pParse->sLastToken : pEnd; n = (int)(pEnd2->z - pParse->sNameToken.z); if( pEnd2->z[0]!=';' ) n += pEnd2->n; - zStmt = sqlite3MPrintf(db, + zStmt = sqlite3MPrintf(db, "CREATE %s %.*s", zType2, n, pParse->sNameToken.z ); } - /* A slot for the record has already been allocated in the + /* A slot for the record has already been allocated in the ** schema table. We just need to update that slot with all ** the information we've collected. */ @@ -2923,6 +2915,17 @@ /* Reparse everything to update our internal data structures */ sqlite3VdbeAddParseSchemaOp(v, iDb, sqlite3MPrintf(db, "tbl_name='%q' AND type!='trigger'", p->zName),0); + + /* Test for cycles in generated columns and illegal expressions + ** in CHECK constraints and in DEFAULT clauses. */ + if( p->tabFlags & TF_HasGenerated ){ + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "SELECT*FROM\"%w\".\"%w\"", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); + } + sqlite3VdbeAddOp4(v, OP_SqlExec, 1, 0, 0, + sqlite3MPrintf(db, "PRAGMA \"%w\".integrity_check(%Q)", + db->aDb[iDb].zDbSName, p->zName), P4_DYNAMIC); } /* Add the table to the in-memory representation of the database. @@ -3100,7 +3103,7 @@ ** Actually, the error above is now caught prior to reaching this point. ** But the following test is still important as it does come up ** in the following: - ** + ** ** CREATE TABLE main.ex1(a); ** CREATE TEMP VIEW ex1 AS SELECT a FROM ex1; ** SELECT * FROM temp.ex1; @@ -3148,7 +3151,7 @@ ** normally holds CHECK constraints on an ordinary table, but for ** a VIEW it holds the list of column names. */ - sqlite3ColumnsFromExprList(pParse, pTable->pCheck, + sqlite3ColumnsFromExprList(pParse, pTable->pCheck, &pTable->nCol, &pTable->aCol); if( pParse->nErr==0 && pTable->nCol==pSel->pEList->nExpr @@ -3181,7 +3184,7 @@ sqlite3DeleteColumnNames(db, pTable); } #endif /* SQLITE_OMIT_VIEW */ - return nErr; + return nErr; } int sqlite3ViewGetColumnNames(Parse *pParse, Table *pTable){ assert( pTable!=0 ); @@ -3220,7 +3223,7 @@ ** on tables and/or indices that are the process of being deleted. ** If you are unlucky, one of those deleted indices or tables might ** have the same rootpage number as the real table or index that is -** being moved. So we cannot stop searching after the first match +** being moved. So we cannot stop searching after the first match ** because the first match might be for one of the deleted indices ** or tables and not the table/index that is actually being moved. ** We must continue looping until all tables and indices with @@ -3257,7 +3260,7 @@ ** Also write code to modify the sqlite_schema table and internal schema ** if a root-page of another table is moved by the btree-layer whilst ** erasing iTable (this can happen with an auto-vacuum database). -*/ +*/ static void destroyRootPage(Parse *pParse, int iTable, int iDb){ Vdbe *v = sqlite3GetVdbe(pParse); int r1 = sqlite3GetTempReg(pParse); @@ -3274,7 +3277,7 @@ ** is in register NNN. See grammar rules associated with the TK_REGISTER ** token for additional information. */ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "UPDATE %Q." LEGACY_SCHEMA_TABLE " SET rootpage=%d WHERE #%d AND rootpage=#%d", pParse->db->aDb[iDb].zDbSName, iTable, r1, r1); @@ -3291,7 +3294,7 @@ static void destroyTable(Parse *pParse, Table *pTab){ /* If the database may be auto-vacuum capable (if SQLITE_OMIT_AUTOVACUUM ** is not defined), then it is important to call OP_Destroy on the - ** table and index root-pages in order, starting with the numerically + ** table and index root-pages in order, starting with the numerically ** largest root-page number. This guarantees that none of the root-pages ** to be destroyed is relocated by an earlier OP_Destroy. i.e. if the ** following were coded: @@ -3301,7 +3304,7 @@ ** OP_Destroy 5 0 ** ** and root page 5 happened to be the largest root-page number in the - ** database, then root page 5 would be moved to page 4 by the + ** database, then root page 5 would be moved to page 4 by the ** "OP_Destroy 4 0" opcode. The subsequent "OP_Destroy 5 0" would hit ** a free-list page. */ @@ -3382,7 +3385,7 @@ */ pTrigger = sqlite3TriggerList(pParse, pTab); while( pTrigger ){ - assert( pTrigger->pSchema==pTab->pSchema || + assert( pTrigger->pSchema==pTab->pSchema || pTrigger->pSchema==db->aDb[1].pSchema ); sqlite3DropTriggerPtr(pParse, pTrigger); pTrigger = pTrigger->pNext; @@ -3409,7 +3412,7 @@ ** created in the temp database that refers to a table in another ** database. */ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "DELETE FROM %Q." LEGACY_SCHEMA_TABLE " WHERE tbl_name=%Q and type!='trigger'", pDb->zDbSName, pTab->zName); @@ -3660,8 +3663,8 @@ } } if( j>=p->nCol ){ - sqlite3ErrorMsg(pParse, - "unknown column \"%s\" in foreign key definition", + sqlite3ErrorMsg(pParse, + "unknown column \"%s\" in foreign key definition", pFromCol->a[i].zEName); goto fk_end; } @@ -3687,7 +3690,7 @@ pFKey->aAction[1] = (u8)((flags >> 8 ) & 0xff); /* ON UPDATE action */ assert( sqlite3SchemaMutexHeld(db, 0, p->pSchema) ); - pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, + pNextTo = (FKey *)sqlite3HashInsert(&p->pSchema->fkeyHash, pFKey->zTo, (void *)pFKey ); if( pNextTo==pFKey ){ @@ -3796,7 +3799,7 @@ sqlite3VdbeAddOp2(v, OP_Next, iTab, addr1+1); VdbeCoverage(v); sqlite3VdbeJumpHere(v, addr1); if( memRootPage<0 ) sqlite3VdbeAddOp2(v, OP_Clear, tnum, iDb); - sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, (int)tnum, iDb, + sqlite3VdbeAddOp4(v, OP_OpenWrite, iIdx, (int)tnum, iDb, (char *)pKey, P4_KEYINFO); sqlite3VdbeChangeP5(v, OPFLAG_BULKCSR|((memRootPage>=0)?OPFLAG_P2ISREG:0)); @@ -3815,7 +3818,7 @@ ** user function that throws an exception when it is evaluated. But the ** overhead of adding a statement journal to a CREATE INDEX statement is ** very small (since most of the pages written do not contain content that - ** needs to be restored if the statement aborts), so we call + ** needs to be restored if the statement aborts), so we call ** sqlite3MayAbort() for all CREATE INDEX statements. */ sqlite3MayAbort(pParse); addr2 = sqlite3VdbeCurrentAddr(v); @@ -3888,7 +3891,7 @@ for(i=0; inExpr; i++){ if( pList->a[i].fg.bNulls ){ u8 sf = pList->a[i].fg.sortFlags; - sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", + sqlite3ErrorMsg(pParse, "unsupported use of NULLS %s", (sf==0 || sf==3) ? "FIRST" : "LAST" ); return 1; @@ -3899,8 +3902,8 @@ } /* -** Create a new index for an SQL table. pName1.pName2 is the name of the index -** and pTblList is the name of the table that is to be indexed. Both will +** Create a new index for an SQL table. pName1.pName2 is the name of the index +** and pTblList is the name of the table that is to be indexed. Both will ** be NULL for a primary key or an index that is created to satisfy a ** UNIQUE constraint. If pTable and pIndex are NULL, use pParse->pNewTable ** as the table to be indexed. pParse->pNewTable is a table that is @@ -3908,7 +3911,7 @@ ** ** pList is a list of columns to be indexed. pList will be NULL if this ** is a primary key or unique-constraint on the most recent column added -** to the table currently under construction. +** to the table currently under construction. */ void sqlite3CreateIndex( Parse *pParse, /* All information about this parse */ @@ -3960,7 +3963,7 @@ */ if( pTblName!=0 ){ - /* Use the two-part index name to determine the database + /* Use the two-part index name to determine the database ** to search for the table. 'Fix' the table name to this db ** before looking up the table. */ @@ -3972,7 +3975,7 @@ #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 initialising a database schema. + ** if initializing a database schema. */ if( !db->init.busy ){ pTab = sqlite3SrcListLookup(pParse, pTblName); @@ -3992,7 +3995,7 @@ assert( db->mallocFailed==0 || pTab==0 ); if( pTab==0 ) goto exit_create_index; if( iDb==1 && db->aDb[iDb].pSchema!=pTab->pSchema ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot create a TEMP index on non-TEMP table \"%s\"", pTab->zName); goto exit_create_index; @@ -4008,7 +4011,7 @@ pDb = &db->aDb[iDb]; assert( pTab!=0 ); - if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 + if( sqlite3StrNICmp(pTab->zName, "sqlite_", 7)==0 && db->init.busy==0 && pTblName!=0 #if SQLITE_USER_AUTHENTICATION @@ -4033,7 +4036,7 @@ /* ** Find the name of the index. Make sure there is not already another - ** index or table with the same name. + ** index or table with the same name. ** ** Exception: If we are reading the names of permanent indices from the ** sqlite_schema table (because some other process changed the schema) and @@ -4133,8 +4136,8 @@ } } - /* - ** Allocate the index structure. + /* + ** Allocate the index structure. */ nName = sqlite3Strlen30(zName); nExtraCol = pPk ? pPk->nKeyCol : 1; @@ -4255,7 +4258,7 @@ int x = pPk->aiColumn[j]; assert( x>=0 ); if( isDupColumn(pIndex, pIndex->nKeyCol, pPk, j) ){ - pIndex->nColumn--; + pIndex->nColumn--; }else{ testcase( hasColumn(pIndex->aiColumn,pIndex->nKeyCol,x) ); pIndex->aiColumn[i] = x; @@ -4274,7 +4277,7 @@ /* If this index contains every column of its table, then mark ** it as a covering index */ - assert( HasRowid(pTab) + assert( HasRowid(pTab) || pTab->iPKey<0 || sqlite3TableColumnToIndex(pIndex, pTab->iPKey)>=0 ); recomputeColumnsNotIndexed(pIndex); if( pTblName!=0 && pIndex->nColumn>=pTab->nCol ){ @@ -4330,13 +4333,13 @@ if( pIdx->onError!=pIndex->onError ){ /* This constraint creates the same index as a previous ** constraint specified somewhere in the CREATE TABLE statement. - ** However the ON CONFLICT clauses are different. If both this + ** However the ON CONFLICT clauses are different. If both this ** constraint and the previous equivalent constraint have explicit ** ON CONFLICT clauses this is an error. Otherwise, use the ** explicitly specified behavior for the index. */ if( !(pIdx->onError==OE_Default || pIndex->onError==OE_Default) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "conflicting ON CONFLICT clauses specified", 0); } if( pIdx->onError==OE_Default ){ @@ -4357,7 +4360,7 @@ if( !IN_RENAME_OBJECT ){ /* Link the new Index structure to its table and to the other - ** in-memory database structures. + ** in-memory database structures. */ assert( pParse->nErr==0 ); if( db->init.busy ){ @@ -4372,7 +4375,7 @@ goto exit_create_index; } } - p = sqlite3HashInsert(&pIndex->pSchema->idxHash, + p = sqlite3HashInsert(&pIndex->pSchema->idxHash, pIndex->zName, pIndex); if( p ){ assert( p==pIndex ); /* Malloc must have failed */ @@ -4406,9 +4409,9 @@ sqlite3BeginWriteOperation(pParse, 1, iDb); /* Create the rootpage for the index using CreateIndex. But before - ** doing so, code a Noop instruction and store its address in - ** Index.tnum. This is required in case this index is actually a - ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In + ** doing so, code a Noop instruction and store its address in + ** Index.tnum. This is required in case this index is actually a + ** PRIMARY KEY and the table is actually a WITHOUT ROWID table. In ** that case the convertToWithoutRowidTable() routine will replace ** the Noop with a Goto to jump over the VDBE code generated below. */ pIndex->tnum = (Pgno)sqlite3VdbeAddOp0(v, OP_Noop); @@ -4432,7 +4435,7 @@ /* Add an entry in sqlite_schema for this index */ - sqlite3NestedParse(pParse, + sqlite3NestedParse(pParse, "INSERT INTO %Q." LEGACY_SCHEMA_TABLE " VALUES('index',%Q,%Q,#%d,%Q);", db->aDb[iDb].zDbSName, pIndex->zName, @@ -4534,7 +4537,7 @@ /* Indexes with default row estimates should not have stat1 data */ assert( !pIdx->hasStat1 ); - /* Set the first entry (number of rows in the index) to the estimated + /* Set the first entry (number of rows in the index) to the estimated ** number of rows in the table, or half the number of rows in the table ** for a partial index. ** @@ -4830,7 +4833,7 @@ ** database name prefix. Like this: "database.table". The pDatabase ** points to the table name and the pTable points to the database name. ** The SrcList.a[].zName field is filled with the table name which might -** come from pTable (if pDatabase is NULL) or from pDatabase. +** come from pTable (if pDatabase is NULL) or from pDatabase. ** SrcList.a[].zDatabase is filled with the database name from pTable, ** or with NULL if no database is specified. ** @@ -4964,7 +4967,7 @@ SrcItem *pItem; sqlite3 *db = pParse->db; if( !p && pOnUsing!=0 && (pOnUsing->pOn || pOnUsing->pUsing) ){ - sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", + sqlite3ErrorMsg(pParse, "a JOIN clause is required before %s", (pOnUsing->pOn ? "ON" : "USING") ); goto append_from_error; @@ -5011,7 +5014,7 @@ } /* -** Add an INDEXED BY or NOT INDEXED clause to the most recently added +** Add an INDEXED BY or NOT INDEXED clause to the most recently added ** element of the source-list passed as the second argument. */ void sqlite3SrcListIndexedBy(Parse *pParse, SrcList *p, Token *pIndexedBy){ @@ -5024,7 +5027,7 @@ assert( pItem->fg.isIndexedBy==0 ); assert( pItem->fg.isTabFunc==0 ); if( pIndexedBy->n==1 && !pIndexedBy->z ){ - /* A "NOT INDEXED" clause was supplied. See parse.y + /* A "NOT INDEXED" clause was supplied. See parse.y ** construct "indexed_opt" for details. */ pItem->fg.notIndexed = 1; }else{ @@ -5039,7 +5042,7 @@ ** Append the contents of SrcList p2 to SrcList p1 and return the resulting ** SrcList. Or, if an error occurs, return NULL. In all cases, p1 and p2 ** are deleted by this function. -*/ +*/ SrcList *sqlite3SrcListAppendList(Parse *pParse, SrcList *p1, SrcList *p2){ assert( p1 && p1->nSrc==1 ); if( p2 ){ @@ -5165,7 +5168,7 @@ assert( pParse->db!=0 ); assert( eType==TK_COMMIT || eType==TK_END || eType==TK_ROLLBACK ); isRollback = eType==TK_ROLLBACK; - if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, + if( sqlite3AuthCheck(pParse, SQLITE_TRANSACTION, isRollback ? "ROLLBACK" : "COMMIT", 0, 0) ){ return; } @@ -5177,7 +5180,7 @@ /* ** This function is called by the parser when it parses a command to create, -** release or rollback an SQL savepoint. +** release or rollback an SQL savepoint. */ void sqlite3Savepoint(Parse *pParse, int op, Token *pName){ char *zName = sqlite3NameFromToken(pParse->db, pName); @@ -5204,7 +5207,7 @@ if( db->aDb[1].pBt==0 && !pParse->explain ){ int rc; Btree *pBt; - static const int flags = + static const int flags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | @@ -5252,7 +5255,7 @@ /* -** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each +** If argument zDb is NULL, then call sqlite3CodeVerifySchema() for each ** attached database. Otherwise, invoke it for the database named zDb only. */ void sqlite3CodeVerifyNamedSchema(Parse *pParse, const char *zDb){ @@ -5298,9 +5301,9 @@ pToplevel->isMultiWrite = 1; } -/* +/* ** The code generator calls this routine if is discovers that it is -** possible to abort a statement prior to completion. In order to +** possible to abort a statement prior to completion. In order to ** perform this abort without corrupting the database, we need to make ** sure that the statement is protected by a statement transaction. ** @@ -5309,7 +5312,7 @@ ** such that the abort must occur after the multiwrite. This makes ** some statements involving the REPLACE conflict resolution algorithm ** go a little faster. But taking advantage of this time dependency -** makes it more difficult to prove that the code is correct (in +** makes it more difficult to prove that the code is correct (in ** particular, it prevents us from writing an effective ** implementation of sqlite3AssertMayAbort()) and so we have chosen ** to take the safe route and skip the optimization. @@ -5356,7 +5359,7 @@ StrAccum errMsg; Table *pTab = pIdx->pTable; - sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, + sqlite3StrAccumInit(&errMsg, pParse->db, 0, 0, pParse->db->aLimit[SQLITE_LIMIT_LENGTH]); if( pIdx->aColExpr ){ sqlite3_str_appendf(&errMsg, "index '%q'", pIdx->zName); @@ -5372,8 +5375,8 @@ } } zErr = sqlite3StrAccumFinish(&errMsg); - sqlite3HaltConstraint(pParse, - IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY + sqlite3HaltConstraint(pParse, + IsPrimaryKeyIndex(pIdx) ? SQLITE_CONSTRAINT_PRIMARYKEY : SQLITE_CONSTRAINT_UNIQUE, onError, zErr, P4_DYNAMIC, P5_ConstraintUnique); } @@ -5385,7 +5388,7 @@ void sqlite3RowidConstraint( Parse *pParse, /* Parsing context */ int onError, /* Conflict resolution algorithm */ - Table *pTab /* The table with the non-unique rowid */ + Table *pTab /* The table with the non-unique rowid */ ){ char *zMsg; int rc; @@ -5627,9 +5630,9 @@ sqlite3DbFree(db, pCte); } -/* -** This routine is invoked once per CTE by the parser while parsing a -** WITH clause. The CTE described by teh third argument is added to +/* +** This routine is invoked once per CTE by the parser while parsing a +** WITH clause. The CTE described by the third argument is added to ** the WITH clause of the second argument. If the second argument is ** NULL, then a new WITH argument is created. */ diff -Nru sqlite3-3.42.0/src/ctime.c sqlite3-3.44.0-0/src/ctime.c --- sqlite3-3.42.0/src/ctime.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/ctime.c 2023-11-04 14:23:58.000000000 +0000 @@ -60,9 +60,6 @@ #ifdef SQLITE_4_BYTE_ALIGNED_MALLOC "4_BYTE_ALIGNED_MALLOC", #endif -#ifdef SQLITE_64BIT_STATS - "64BIT_STATS", -#endif #ifdef SQLITE_ALLOW_COVERING_INDEX_SCAN # if SQLITE_ALLOW_COVERING_INDEX_SCAN != 1 "ALLOW_COVERING_INDEX_SCAN=" CTIMEOPT_VAL(SQLITE_ALLOW_COVERING_INDEX_SCAN), @@ -358,6 +355,9 @@ #ifdef SQLITE_EXPLAIN_ESTIMATED_ROWS "EXPLAIN_ESTIMATED_ROWS", #endif +#ifdef SQLITE_EXTRA_AUTOEXT + "EXTRA_AUTOEXT=" CTIMEOPT_VAL(SQLITE_EXTRA_AUTOEXT), +#endif #ifdef SQLITE_EXTRA_IFNULLROW "EXTRA_IFNULLROW", #endif @@ -399,6 +399,9 @@ #ifdef SQLITE_INTEGRITY_CHECK_ERROR_MAX "INTEGRITY_CHECK_ERROR_MAX=" CTIMEOPT_VAL(SQLITE_INTEGRITY_CHECK_ERROR_MAX), #endif +#ifdef SQLITE_LEGACY_JSON_VALID + "LEGACY_JSON_VALID", +#endif #ifdef SQLITE_LIKE_DOESNT_MATCH_BLOBS "LIKE_DOESNT_MATCH_BLOBS", #endif @@ -636,6 +639,9 @@ #ifdef SQLITE_OMIT_SCHEMA_VERSION_PRAGMAS "OMIT_SCHEMA_VERSION_PRAGMAS", #endif +#ifdef SQLITE_OMIT_SEH + "OMIT_SEH", +#endif #ifdef SQLITE_OMIT_SHARED_CACHE "OMIT_SHARED_CACHE", #endif diff -Nru sqlite3-3.42.0/src/date.c sqlite3-3.44.0-0/src/date.c --- sqlite3-3.42.0/src/date.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/date.c 2023-11-04 14:23:58.000000000 +0000 @@ -110,8 +110,8 @@ */ static int getDigits(const char *zDate, const char *zFormat, ...){ /* The aMx[] array translates the 3rd character of each format - ** spec into a max size: a b c d e f */ - static const u16 aMx[] = { 12, 14, 24, 31, 59, 9999 }; + ** spec into a max size: a b c d e f */ + static const u16 aMx[] = { 12, 14, 24, 31, 59, 14712 }; va_list ap; int cnt = 0; char nextC; @@ -452,17 +452,14 @@ ** Compute the Hour, Minute, and Seconds from the julian day number. */ static void computeHMS(DateTime *p){ - int s; + int day_ms, day_min; /* milliseconds, minutes into the day */ if( p->validHMS ) return; computeJD(p); - s = (int)((p->iJD + 43200000) % 86400000); - p->s = s/1000.0; - s = (int)p->s; - p->s -= s; - p->h = s/3600; - s -= p->h*3600; - p->m = s/60; - p->s += s - p->m*60; + day_ms = (int)((p->iJD + 43200000) % 86400000); + p->s = (day_ms % 60000)/1000.0; + day_min = day_ms/60000; + p->m = day_min % 60; + p->h = day_min / 60; p->rawS = 0; p->validHMS = 1; } @@ -642,6 +639,25 @@ }; /* +** If the DateTime p is raw number, try to figure out if it is +** a julian day number of a unix timestamp. Set the p value +** appropriately. +*/ +static void autoAdjustDate(DateTime *p){ + if( !p->rawS || p->validJD ){ + p->rawS = 0; + }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ + && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ + ){ + double r = p->s*1000.0 + 210866760000000.0; + clearYMD_HMS_TZ(p); + p->iJD = (sqlite3_int64)(r + 0.5); + p->validJD = 1; + p->rawS = 0; + } +} + +/* ** Process a modifier to a date-time stamp. The modifiers are ** as follows: ** @@ -684,19 +700,8 @@ */ if( sqlite3_stricmp(z, "auto")==0 ){ if( idx>1 ) return 1; /* IMP: R-33611-57934 */ - if( !p->rawS || p->validJD ){ - rc = 0; - p->rawS = 0; - }else if( p->s>=-21086676*(i64)10000 /* -4713-11-24 12:00:00 */ - && p->s<=(25340230*(i64)10000)+799 /* 9999-12-31 23:59:59 */ - ){ - r = p->s*1000.0 + 210866760000000.0; - clearYMD_HMS_TZ(p); - p->iJD = (sqlite3_int64)(r + 0.5); - p->validJD = 1; - p->rawS = 0; - rc = 0; - } + autoAdjustDate(p); + rc = 0; } break; } @@ -862,18 +867,73 @@ case '9': { double rRounder; int i; - for(n=1; z[n] && z[n]!=':' && !sqlite3Isspace(z[n]); n++){} + int Y,M,D,h,m,x; + const char *z2 = z; + char z0 = z[0]; + for(n=1; z[n]; n++){ + if( z[n]==':' ) break; + if( sqlite3Isspace(z[n]) ) break; + if( z[n]=='-' ){ + if( n==5 && getDigits(&z[1], "40f", &Y)==1 ) break; + if( n==6 && getDigits(&z[1], "50f", &Y)==1 ) break; + } + } if( sqlite3AtoF(z, &r, n, SQLITE_UTF8)<=0 ){ - rc = 1; + assert( rc==1 ); break; } - if( z[n]==':' ){ + if( z[n]=='-' ){ + /* A modifier of the form (+|-)YYYY-MM-DD adds or subtracts the + ** specified number of years, months, and days. MM is limited to + ** the range 0-11 and DD is limited to 0-30. + */ + if( z0!='+' && z0!='-' ) break; /* Must start with +/- */ + if( n==5 ){ + if( getDigits(&z[1], "40f-20a-20d", &Y, &M, &D)!=3 ) break; + }else{ + assert( n==6 ); + if( getDigits(&z[1], "50f-20a-20d", &Y, &M, &D)!=3 ) break; + z++; + } + if( M>=12 ) break; /* M range 0..11 */ + if( D>=31 ) break; /* D range 0..30 */ + computeYMD_HMS(p); + p->validJD = 0; + if( z0=='-' ){ + p->Y -= Y; + p->M -= M; + D = -D; + }else{ + p->Y += Y; + p->M += M; + } + x = p->M>0 ? (p->M-1)/12 : (p->M-12)/12; + p->Y += x; + p->M -= x*12; + computeJD(p); + p->validHMS = 0; + p->validYMD = 0; + p->iJD += (i64)D*86400000; + if( z[11]==0 ){ + rc = 0; + break; + } + if( sqlite3Isspace(z[11]) + && getDigits(&z[12], "20c:20e", &h, &m)==2 + ){ + z2 = &z[12]; + n = 2; + }else{ + break; + } + } + if( z2[n]==':' ){ /* A modifier of the form (+|-)HH:MM:SS.FFF adds (or subtracts) the ** specified number of hours, minutes, seconds, and fractional seconds ** to the time. The ".FFF" may be omitted. The ":SS.FFF" may be ** omitted. */ - const char *z2 = z; + DateTime tx; sqlite3_int64 day; if( !sqlite3Isdigit(*z2) ) z2++; @@ -883,7 +943,7 @@ tx.iJD -= 43200000; day = tx.iJD/86400000; tx.iJD -= day*86400000; - if( z[0]=='-' ) tx.iJD = -tx.iJD; + if( z0=='-' ) tx.iJD = -tx.iJD; computeJD(p); clearYMD_HMS_TZ(p); p->iJD += tx.iJD; @@ -899,7 +959,7 @@ if( n>10 || n<3 ) break; if( sqlite3UpperToLower[(u8)z[n-1]]=='s' ) n--; computeJD(p); - rc = 1; + assert( rc==1 ); rRounder = r<0 ? -0.5 : +0.5; for(i=0; iM += (int)r; @@ -1067,7 +1126,7 @@ zBuf[16] = '0' + (x.m)%10; zBuf[17] = ':'; if( x.useSubsec ){ - s = (int)1000.0*x.s; + s = (int)(1000.0*x.s + 0.5); zBuf[18] = '0' + (s/10000)%10; zBuf[19] = '0' + (s/1000)%10; zBuf[20] = '.'; @@ -1114,7 +1173,7 @@ zBuf[4] = '0' + (x.m)%10; zBuf[5] = ':'; if( x.useSubsec ){ - s = (int)1000.0*x.s; + s = (int)(1000.0*x.s + 0.5); zBuf[6] = '0' + (s/10000)%10; zBuf[7] = '0' + (s/1000)%10; zBuf[8] = '.'; @@ -1185,7 +1244,7 @@ ** %M minute 00-59 ** %s seconds since 1970-01-01 ** %S seconds 00-59 -** %w day of week 0-6 sunday==0 +** %w day of week 0-6 Sunday==0 ** %W week of year 00-53 ** %Y year 0000-9999 ** %% % @@ -1211,13 +1270,16 @@ computeJD(&x); computeYMD_HMS(&x); for(i=j=0; zFmt[i]; i++){ + char cf; if( zFmt[i]!='%' ) continue; if( j12 ) h -= 12; + if( h==0 ) h = 12; + sqlite3_str_appendf(&sRes, cf=='I' ? "%02d" : "%2d", h); break; } case 'W': /* Fall thru */ @@ -1239,7 +1314,7 @@ y.D = 1; computeJD(&y); nDay = (int)((x.iJD-y.iJD+43200000)/86400000); - if( zFmt[i]=='W' ){ + if( cf=='W' ){ int wd; /* 0=Monday, 1=Tuesday, ... 6=Sunday */ wd = (int)(((x.iJD+43200000)/86400000)%7); sqlite3_str_appendf(&sRes,"%02d",(nDay+7-wd)/7); @@ -1260,6 +1335,19 @@ sqlite3_str_appendf(&sRes,"%02d",x.m); break; } + case 'p': /* Fall thru */ + case 'P': { + if( x.h>=12 ){ + sqlite3_str_append(&sRes, cf=='p' ? "PM" : "pm", 2); + }else{ + sqlite3_str_append(&sRes, cf=='p' ? "AM" : "am", 2); + } + break; + } + case 'R': { + sqlite3_str_appendf(&sRes, "%02d:%02d", x.h, x.m); + break; + } case 's': { if( x.useSubsec ){ sqlite3_str_appendf(&sRes,"%.3f", @@ -1274,9 +1362,15 @@ sqlite3_str_appendf(&sRes,"%02d",(int)x.s); break; } + case 'T': { + sqlite3_str_appendf(&sRes,"%02d:%02d:%02d", x.h, x.m, (int)x.s); + break; + } + case 'u': /* Fall thru */ case 'w': { - sqlite3_str_appendchar(&sRes, 1, - (char)(((x.iJD+129600000)/86400000) % 7) + '0'); + char c = (char)(((x.iJD+129600000)/86400000) % 7) + '0'; + if( c=='0' && cf=='u' ) c = '7'; + sqlite3_str_appendchar(&sRes, 1, c); break; } case 'Y': { @@ -1326,6 +1420,117 @@ } /* +** timediff(DATE1, DATE2) +** +** Return the amount of time that must be added to DATE2 in order to +** convert it into DATE2. The time difference format is: +** +** +YYYY-MM-DD HH:MM:SS.SSS +** +** The initial "+" becomes "-" if DATE1 occurs before DATE2. For +** date/time values A and B, the following invariant should hold: +** +** datetime(A) == (datetime(B, timediff(A,B)) +** +** Both DATE arguments must be either a julian day number, or an +** ISO-8601 string. The unix timestamps are not supported by this +** routine. +*/ +static void timediffFunc( + sqlite3_context *context, + int NotUsed1, + sqlite3_value **argv +){ + char sign; + int Y, M; + DateTime d1, d2; + sqlite3_str sRes; + UNUSED_PARAMETER(NotUsed1); + if( isDate(context, 1, &argv[0], &d1) ) return; + if( isDate(context, 1, &argv[1], &d2) ) return; + computeYMD_HMS(&d1); + computeYMD_HMS(&d2); + if( d1.iJD>=d2.iJD ){ + sign = '+'; + Y = d1.Y - d2.Y; + if( Y ){ + d2.Y = d1.Y; + d2.validJD = 0; + computeJD(&d2); + } + M = d1.M - d2.M; + if( M<0 ){ + Y--; + M += 12; + } + if( M!=0 ){ + d2.M = d1.M; + d2.validJD = 0; + computeJD(&d2); + } + while( d1.iJDd2.iJD ){ + M--; + if( M<0 ){ + M = 11; + Y--; + } + d2.M++; + if( d2.M>12 ){ + d2.M = 1; + d2.Y++; + } + d2.validJD = 0; + computeJD(&d2); + } + d1.iJD = d2.iJD - d1.iJD; + d1.iJD += (u64)1486995408 * (u64)100000; + } + d1.validYMD = 0; + d1.validHMS = 0; + d1.validTZ = 0; + computeYMD_HMS(&d1); + sqlite3StrAccumInit(&sRes, 0, 0, 0, 100); + sqlite3_str_appendf(&sRes, "%c%04d-%02d-%02d %02d:%02d:%06.3f", + sign, Y, M, d1.D-1, d1.h, d1.m, d1.s); + sqlite3ResultStrAccum(context, &sRes); +} + + +/* ** current_timestamp() ** ** This function returns the same value as datetime('now'). @@ -1399,6 +1604,7 @@ PURE_DATE(time, -1, 0, 0, timeFunc ), PURE_DATE(datetime, -1, 0, 0, datetimeFunc ), PURE_DATE(strftime, -1, 0, 0, strftimeFunc ), + PURE_DATE(timediff, 2, 0, 0, timediffFunc ), DFUNCTION(current_time, 0, 0, 0, ctimeFunc ), DFUNCTION(current_timestamp, 0, 0, 0, ctimestampFunc), DFUNCTION(current_date, 0, 0, 0, cdateFunc ), diff -Nru sqlite3-3.42.0/src/dbpage.c sqlite3-3.44.0-0/src/dbpage.c --- sqlite3-3.42.0/src/dbpage.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/dbpage.c 2023-11-04 14:23:58.000000000 +0000 @@ -425,7 +425,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "sqlite_dbpage", &dbpage_module, 0); } diff -Nru sqlite3-3.42.0/src/dbstat.c sqlite3-3.44.0-0/src/dbstat.c --- sqlite3-3.42.0/src/dbstat.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/dbstat.c 2023-11-04 14:23:58.000000000 +0000 @@ -895,7 +895,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; return sqlite3_create_module(db, "dbstat", &dbstat_module, 0); } diff -Nru sqlite3-3.42.0/src/delete.c sqlite3-3.44.0-0/src/delete.c --- sqlite3-3.42.0/src/delete.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/delete.c 2023-11-04 14:23:58.000000000 +0000 @@ -19,7 +19,7 @@ ** (as in the FROM clause of a SELECT statement) in this case it contains ** the name of a single table, as one might find in an INSERT, DELETE, ** or UPDATE statement. Look up that table in the symbol table and -** return a pointer. Set an error message and return NULL if the table +** return a pointer. Set an error message and return NULL if the table ** name is not found or if any other error occurs. ** ** The following fields are initialized appropriate in pSrc: @@ -33,8 +33,9 @@ Table *pTab; assert( pItem && pSrc->nSrc>=1 ); pTab = sqlite3LocateTableItem(pParse, 0, pItem); - sqlite3DeleteTable(pParse->db, pItem->pTab); + if( pItem->pTab ) sqlite3DeleteTable(pParse->db, pItem->pTab); pItem->pTab = pTab; + pItem->fg.notCte = 1; if( pTab ){ pTab->nTabRef++; if( pItem->fg.isIndexedBy && sqlite3IndexedByLookup(pParse, pItem) ){ @@ -44,7 +45,7 @@ return pTab; } -/* Generate byte-code that will report the number of rows modified +/* Generate byte-code that will report the number of rows modified ** by a DELETE, INSERT, or UPDATE statement. */ void sqlite3CodeChangeCount(Vdbe *v, int regCounter, const char *zColName){ @@ -66,7 +67,7 @@ ** the table is not SQLITE_VTAB_INNOCUOUS. ** ** 3) It is a system table (i.e. sqlite_schema), this call is not -** part of a nested parse and writable_schema pragma has not +** part of a nested parse and writable_schema pragma has not ** been specified ** ** 4) The table is a shadow table, the database connection is in @@ -85,7 +86,7 @@ ** virtual tables if PRAGMA trusted_schema=ON. */ if( pParse->pToplevel!=0 - && pTab->u.vtab.p->eVtabRisk > + && pTab->u.vtab.p->eVtabRisk > ((pParse->db->flags & SQLITE_TrustedSchema)!=0) ){ sqlite3ErrorMsg(pParse, "unsafe use of virtual table \"%s\"", @@ -108,7 +109,7 @@ } /* -** Check to make sure the given table is writable. +** Check to make sure the given table is writable. ** ** If pTab is not writable -> generate an error message and return 1. ** If pTab is writable but other errors have occurred -> return 1. @@ -120,7 +121,7 @@ return 1; } #ifndef SQLITE_OMIT_VIEW - if( IsView(pTab) + if( IsView(pTab) && (pTrigger==0 || (pTrigger->bReturning && pTrigger->pNext==0)) ){ sqlite3ErrorMsg(pParse,"cannot modify %s because it is a view",pTab->zName); @@ -159,7 +160,7 @@ assert( pFrom->a[0].fg.isUsing==0 ); assert( pFrom->a[0].u3.pOn==0 ); } - pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, + pSel = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, pOrderBy, SF_IncludeHidden, pLimit); sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur); sqlite3Select(pParse, pSel, &dest); @@ -187,7 +188,7 @@ sqlite3 *db = pParse->db; Expr *pLhs = NULL; /* LHS of IN(SELECT...) operator */ Expr *pInClause = NULL; /* WHERE rowid IN ( select ) */ - ExprList *pEList = NULL; /* Expression list contaning only pSelectRowid */ + ExprList *pEList = NULL; /* Expression list containing only pSelectRowid*/ SrcList *pSelectSrc = NULL; /* SELECT rowid FROM x ... (dup of pSrc) */ Select *pSelect = NULL; /* Complete SELECT tree */ Table *pTab; @@ -208,11 +209,11 @@ return pWhere; } - /* Generate a select expression tree to enforce the limit/offset + /* Generate a select expression tree to enforce the limit/offset ** term for the DELETE or UPDATE statement. For example: ** DELETE FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** becomes: - ** DELETE FROM table_a WHERE rowid IN ( + ** DELETE FROM table_a WHERE rowid IN ( ** SELECT rowid FROM table_a WHERE col1=1 ORDER BY col2 LIMIT 1 OFFSET 1 ** ); */ @@ -225,14 +226,20 @@ ); }else{ Index *pPk = sqlite3PrimaryKeyIndex(pTab); + assert( pPk!=0 ); + assert( pPk->nKeyCol>=1 ); if( pPk->nKeyCol==1 ){ - const char *zName = pTab->aCol[pPk->aiColumn[0]].zCnName; + const char *zName; + assert( pPk->aiColumn[0]>=0 && pPk->aiColumn[0]nCol ); + zName = pTab->aCol[pPk->aiColumn[0]].zCnName; pLhs = sqlite3Expr(db, TK_ID, zName); pEList = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_ID, zName)); }else{ int i; for(i=0; inKeyCol; i++){ - Expr *p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); + Expr *p; + assert( pPk->aiColumn[i]>=0 && pPk->aiColumn[i]nCol ); + p = sqlite3Expr(db, TK_ID, pTab->aCol[pPk->aiColumn[i]].zCnName); pEList = sqlite3ExprListAppend(pParse, pEList, p); } pLhs = sqlite3PExpr(pParse, TK_VECTOR, 0, 0); @@ -257,11 +264,11 @@ } /* generate the SELECT expression tree. */ - pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, + pSelect = sqlite3SelectNew(pParse, pEList, pSelectSrc, pWhere, 0 ,0, pOrderBy,0,pLimit ); - /* now generate the new WHERE rowid IN clause for the DELETE/UDPATE */ + /* now generate the new WHERE rowid IN clause for the DELETE/UPDATE */ pInClause = sqlite3PExpr(pParse, TK_IN, pLhs, 0); sqlite3PExprAddSelect(pParse, pInClause, pSelect); return pInClause; @@ -313,7 +320,7 @@ int addrEphOpen = 0; /* Instruction to open the Ephemeral table */ int bComplex; /* True if there are triggers or FKs or ** subqueries in the WHERE clause */ - + #ifndef SQLITE_OMIT_TRIGGER int isView; /* True if attempting to delete from a view */ Trigger *pTrigger; /* List of table triggers, if required */ @@ -381,7 +388,7 @@ } iDb = sqlite3SchemaToIndex(db, pTab->pSchema); assert( iDbnDb ); - rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, + rcauth = sqlite3AuthCheck(pParse, SQLITE_DELETE, pTab->zName, 0, db->aDb[iDb].zDbSName); assert( rcauth==SQLITE_OK || rcauth==SQLITE_DENY || rcauth==SQLITE_IGNORE ); if( rcauth==SQLITE_DENY ){ @@ -417,7 +424,7 @@ */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( isView ){ - sqlite3MaterializeView(pParse, pTab, + sqlite3MaterializeView(pParse, pTab, pWhere, pOrderBy, pLimit, iTabCur ); iDataCur = iIdxCur = iTabCur; @@ -450,7 +457,7 @@ #ifndef SQLITE_OMIT_TRUNCATE_OPTIMIZATION /* Special case: A DELETE without a WHERE clause deletes everything. ** It is easier just to erase the whole table. Prior to version 3.6.5, - ** this optimization caused the row change count (the value returned by + ** this optimization caused the row change count (the value returned by ** API function sqlite3_count_changes) to be set incorrectly. ** ** The "rcauth==SQLITE_OK" terms is the @@ -490,7 +497,7 @@ if( HasRowid(pTab) ){ /* For a rowid table, initialize the RowSet to an empty set */ pPk = 0; - nPk = 1; + assert( nPk==1 ); iRowSet = ++pParse->nMem; sqlite3VdbeAddOp2(v, OP_Null, 0, iRowSet); }else{ @@ -505,7 +512,7 @@ addrEphOpen = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, iEphCur, nPk); sqlite3VdbeSetP4KeyInfo(pParse, pPk); } - + /* Construct a query to find the rowid or primary key for every row ** to be deleted, based on the WHERE clause. Set variable eOnePass ** to indicate the strategy used to implement this delete: @@ -518,17 +525,18 @@ if( pWInfo==0 ) goto delete_from_cleanup; eOnePass = sqlite3WhereOkOnePass(pWInfo, aiCurOnePass); assert( IsVirtual(pTab)==0 || eOnePass!=ONEPASS_MULTI ); - assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF ); + assert( IsVirtual(pTab) || bComplex || eOnePass!=ONEPASS_OFF + || OptimizationDisabled(db, SQLITE_OnePass) ); if( eOnePass!=ONEPASS_SINGLE ) sqlite3MultiWrite(pParse); if( sqlite3WhereUsesDeferredSeek(pWInfo) ){ sqlite3VdbeAddOp1(v, OP_FinishSeek, iTabCur); } - + /* Keep track of the number of rows to be deleted */ if( memCnt ){ sqlite3VdbeAddOp2(v, OP_AddImm, memCnt, 1); } - + /* Extract the rowid or primary key for the current row */ if( pPk ){ for(i=0; inMem; sqlite3ExprCodeGetColumnOfTable(v, pTab, iTabCur, -1, iKey); } - + if( eOnePass!=ONEPASS_OFF ){ /* For ONEPASS, no need to store the rowid/primary-key. There is only ** one, so just keep it in its register(s) and fall through to the @@ -573,10 +581,10 @@ } sqlite3WhereEnd(pWInfo); } - - /* Unless this is a view, open cursors for the table we are + + /* Unless this is a view, open cursors for the table we are ** deleting from and all its indices. If this is a view, then the - ** only effect this statement has is to fire the INSTEAD OF + ** only effect this statement has is to fire the INSTEAD OF ** triggers. */ if( !isView ){ @@ -593,7 +601,7 @@ sqlite3VdbeJumpHereOrPopInst(v, iAddrOnce); } } - + /* Set up a loop over the rowids/primary-keys that were found in the ** where-clause loop above. */ @@ -616,8 +624,8 @@ addrLoop = sqlite3VdbeAddOp3(v, OP_RowSetRead, iRowSet, 0, iKey); VdbeCoverage(v); assert( nKey==1 ); - } - + } + /* Delete the row */ #ifndef SQLITE_OMIT_VIRTUALTABLE if( IsVirtual(pTab) ){ @@ -640,7 +648,7 @@ sqlite3GenerateRowDelete(pParse, pTab, pTrigger, iDataCur, iIdxCur, iKey, nKey, count, OE_Default, eOnePass, aiCurOnePass[1]); } - + /* End of the loop over all rowids/primary-keys. */ if( eOnePass!=ONEPASS_OFF ){ sqlite3VdbeResolveLabel(v, addrBypass); @@ -651,7 +659,7 @@ }else{ sqlite3VdbeGoto(v, addrLoop); sqlite3VdbeJumpHere(v, addrLoop); - } + } } /* End non-truncate path */ /* Update the sqlite_sequence table by storing the content of the @@ -662,7 +670,7 @@ sqlite3AutoincrementEnd(pParse); } - /* Return the number of rows that were deleted. If this routine is + /* Return the number of rows that were deleted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ @@ -674,7 +682,7 @@ sqlite3AuthContextPop(&sContext); sqlite3SrcListDelete(db, pTabList); sqlite3ExprDelete(db, pWhere); -#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) sqlite3ExprListDelete(db, pOrderBy); sqlite3ExprDelete(db, pLimit); #endif @@ -719,7 +727,7 @@ ** and nPk before reading from it. ** ** If eMode is ONEPASS_MULTI, then this call is being made as part -** of a ONEPASS delete that affects multiple rows. In this case, if +** of a ONEPASS delete that affects multiple rows. In this case, if ** iIdxNoSeek is a valid cursor number (>=0) and is not the same as ** iDataCur, then its position should be preserved following the delete ** operation. Or, if iIdxNoSeek is not a valid cursor number, the @@ -755,7 +763,7 @@ VdbeModuleComment((v, "BEGIN: GenRowDel(%d,%d,%d,%d)", iDataCur, iIdxCur, iPk, (int)nPk)); - /* Seek cursor iCur to the row to delete. If this row no longer exists + /* Seek cursor iCur to the row to delete. If this row no longer exists ** (this can happen if a trigger program has already deleted it), do ** not attempt to delete it or fire any DELETE triggers. */ iLabel = sqlite3VdbeMakeLabel(pParse); @@ -765,7 +773,7 @@ VdbeCoverageIf(v, opSeek==OP_NotExists); VdbeCoverageIf(v, opSeek==OP_NotFound); } - + /* If there are any triggers to fire, allocate a range of registers to ** use for the old.* references in the triggers. */ if( sqlite3FkRequired(pParse, pTab, 0, 0) || pTrigger ){ @@ -782,7 +790,7 @@ iOld = pParse->nMem+1; pParse->nMem += (1 + pTab->nCol); - /* Populate the OLD.* pseudo-table register array. These values will be + /* Populate the OLD.* pseudo-table register array. These values will be ** used by any BEFORE and AFTER triggers that exist. */ sqlite3VdbeAddOp2(v, OP_Copy, iPk, iOld); for(iCol=0; iColnCol; iCol++){ @@ -796,11 +804,11 @@ /* Invoke BEFORE DELETE trigger programs. */ addrStart = sqlite3VdbeCurrentAddr(v); - sqlite3CodeRowTrigger(pParse, pTrigger, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_DELETE, 0, TRIGGER_BEFORE, pTab, iOld, onconf, iLabel ); - /* If any BEFORE triggers were coded, then seek the cursor to the + /* If any BEFORE triggers were coded, then seek the cursor to the ** row to be deleted again. It may be that the BEFORE triggers moved ** the cursor or already deleted the row that the cursor was ** pointing to. @@ -817,21 +825,21 @@ } /* Do FK processing. This call checks that any FK constraints that - ** refer to this table (i.e. constraints attached to other tables) + ** refer to this table (i.e. constraints attached to other tables) ** are not violated by deleting this row. */ sqlite3FkCheck(pParse, pTab, iOld, 0, 0, 0); } /* Delete the index and table entries. Skip this step if pTab is really ** a view (in which case the only effect of the DELETE statement is to - ** fire the INSTEAD OF triggers). + ** fire the INSTEAD OF triggers). ** ** If variable 'count' is non-zero, then this OP_Delete instruction should ** invoke the update-hook. The pre-update-hook, on the other hand should ** be invoked unless table pTab is a system table. The difference is that - ** the update-hook is not invoked for rows removed by REPLACE, but the + ** the update-hook is not invoked for rows removed by REPLACE, but the ** pre-update-hook is. - */ + */ if( !IsView(pTab) ){ u8 p5 = 0; sqlite3GenerateRowIndexDelete(pParse, pTab, iDataCur, iIdxCur,0,iIdxNoSeek); @@ -851,16 +859,18 @@ /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key - ** to the row just deleted. */ + ** to the row just deleted. */ sqlite3FkActions(pParse, pTab, 0, iOld, 0, 0); /* Invoke AFTER DELETE trigger programs. */ - sqlite3CodeRowTrigger(pParse, pTrigger, - TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel - ); + if( pTrigger ){ + sqlite3CodeRowTrigger(pParse, pTrigger, + TK_DELETE, 0, TRIGGER_AFTER, pTab, iOld, onconf, iLabel + ); + } /* Jump here if the row had already been deleted before any BEFORE - ** trigger programs were invoked. Or if a trigger program throws a + ** trigger programs were invoked. Or if a trigger program throws a ** RAISE(IGNORE) exception. */ sqlite3VdbeResolveLabel(v, iLabel); VdbeModuleComment((v, "END: GenRowDel()")); @@ -945,7 +955,7 @@ ** its key into the same sequence of registers and if pPrior and pIdx share ** a column in common, then the register corresponding to that column already ** holds the correct value and the loading of that register is skipped. -** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK +** This optimization is helpful when doing a DELETE or an INTEGRITY_CHECK ** on a table with multiple indices, and especially with the ROWID or ** PRIMARY KEY columns of the index. */ @@ -968,7 +978,7 @@ if( pIdx->pPartIdxWhere ){ *piPartIdxLabel = sqlite3VdbeMakeLabel(pParse); pParse->iSelfTab = iDataCur + 1; - sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, + sqlite3ExprIfFalseDup(pParse, pIdx->pPartIdxWhere, *piPartIdxLabel, SQLITE_JUMPIFNULL); pParse->iSelfTab = 0; pPrior = 0; /* Ticket a9efb42811fa41ee 2019-11-02; diff -Nru sqlite3-3.42.0/src/expr.c sqlite3-3.44.0-0/src/expr.c --- sqlite3-3.42.0/src/expr.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/expr.c 2023-11-04 14:23:58.000000000 +0000 @@ -30,7 +30,7 @@ ** Return the 'affinity' of the expression pExpr if any. ** ** If pExpr is a column, a reference to a column via an 'AS' alias, -** or a sub-select with a column as the return value, then the +** or a sub-select with a column as the return value, then the ** affinity of that column is returned. Otherwise, 0x00 is returned, ** indicating no affinity for the expression. ** @@ -67,6 +67,7 @@ if( op==TK_SELECT_COLUMN ){ assert( pExpr->pLeft!=0 && ExprUseXSelect(pExpr->pLeft) ); assert( pExpr->iColumn < pExpr->iTable ); + assert( pExpr->iColumn >= 0 ); assert( pExpr->iTable==pExpr->pLeft->x.pSelect->pEList->nExpr ); return sqlite3ExprAffinity( pExpr->pLeft->x.pSelect->pEList->a[pExpr->iColumn].pExpr @@ -201,7 +202,7 @@ while( pExpr && ExprHasProperty(pExpr, EP_Skip) ){ assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; - } + } return pExpr; } @@ -221,7 +222,7 @@ assert( pExpr->op==TK_COLLATE ); pExpr = pExpr->pLeft; } - } + } return pExpr; } @@ -246,7 +247,7 @@ while( p ){ int op = p->op; if( op==TK_REGISTER ) op = p->op2; - if( (op==TK_AGG_COLUMN && p->y.pTab!=0) + if( (op==TK_AGG_COLUMN && p->y.pTab!=0) || op==TK_COLUMN || op==TK_TRIGGER ){ int j; @@ -294,7 +295,7 @@ break; } } - if( sqlite3CheckCollSeq(pParse, pColl) ){ + if( sqlite3CheckCollSeq(pParse, pColl) ){ pColl = 0; } return pColl; @@ -303,7 +304,7 @@ /* ** Return the collation sequence for the expression pExpr. If ** there is no defined collating sequence, return a pointer to the -** defautl collation sequence. +** default collation sequence. ** ** See also: sqlite3ExprCollSeq() ** @@ -414,8 +415,8 @@ ** it is not considered. */ CollSeq *sqlite3BinaryCompareCollSeq( - Parse *pParse, - const Expr *pLeft, + Parse *pParse, + const Expr *pLeft, const Expr *pRight ){ CollSeq *pColl; @@ -433,7 +434,7 @@ return pColl; } -/* Expresssion p is a comparison operator. Return a collation sequence +/* Expression p is a comparison operator. Return a collation sequence ** appropriate for the comparison operator. ** ** This is normally just a wrapper around sqlite3BinaryCompareCollSeq(). @@ -493,7 +494,7 @@ } /* -** If the expression passed as the only argument is of type TK_VECTOR +** If the expression passed as the only argument is of type TK_VECTOR ** return the number of expressions in the vector. Or, if the expression ** is a sub-select, return the number of columns in the sub-select. For ** any other type of expression, return 1. @@ -547,7 +548,7 @@ ** sqlite3ExprCode() will generate all necessary code to compute ** the iField-th column of the vector expression pVector. ** -** It is ok for pVector to be a scalar (as long as iField==0). +** It is ok for pVector to be a scalar (as long as iField==0). ** In that case, this routine works like sqlite3ExprDup(). ** ** The caller owns the returned Expr object and is responsible for @@ -590,6 +591,7 @@ */ pRet = sqlite3PExpr(pParse, TK_SELECT_COLUMN, 0, 0); if( pRet ){ + ExprSetProperty(pRet, EP_FullSize); pRet->iTable = nField; pRet->iColumn = iField; pRet->pLeft = pVector; @@ -613,7 +615,7 @@ /* ** If expression pExpr is of type TK_SELECT, generate code to evaluate -** it. Return the register in which the result is stored (or, if the +** it. Return the register in which the result is stored (or, if the ** sub-select returns more than one column, the first in an array ** of registers in which the result is stored). ** @@ -635,10 +637,10 @@ ** the register number of a register that contains the value of ** element iField of the vector. ** -** If pVector is a TK_SELECT expression, then code for it must have +** If pVector is a TK_SELECT expression, then code for it must have ** already been generated using the exprCodeSubselect() routine. In this ** case parameter regSelect should be the first in an array of registers -** containing the results of the sub-select. +** containing the results of the sub-select. ** ** If pVector is of type TK_VECTOR, then code for the requested field ** is generated. In this case (*pRegFree) may be set to the number of @@ -710,10 +712,10 @@ sqlite3ErrorMsg(pParse, "row value misused"); return; } - assert( pExpr->op==TK_EQ || pExpr->op==TK_NE - || pExpr->op==TK_IS || pExpr->op==TK_ISNOT - || pExpr->op==TK_LT || pExpr->op==TK_GT - || pExpr->op==TK_LE || pExpr->op==TK_GE + assert( pExpr->op==TK_EQ || pExpr->op==TK_NE + || pExpr->op==TK_IS || pExpr->op==TK_ISNOT + || pExpr->op==TK_LT || pExpr->op==TK_GT + || pExpr->op==TK_LE || pExpr->op==TK_GE ); assert( pExpr->op==op || (pExpr->op==TK_IS && op==TK_EQ) || (pExpr->op==TK_ISNOT && op==TK_NE) ); @@ -730,7 +732,7 @@ sqlite3VdbeAddOp2(v, OP_Integer, 1, dest); for(i=0; 1 /*Loop exits by "break"*/; i++){ int regFree1 = 0, regFree2 = 0; - Expr *pL = 0, *pR = 0; + Expr *pL = 0, *pR = 0; int r1, r2; assert( i>=0 && idb->aLimit[SQLITE_LIMIT_EXPR_DEPTH]; if( nHeight>mxHeight ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Expression tree is too large (maximum depth %d)", mxHeight ); rc = SQLITE_ERROR; @@ -829,10 +831,10 @@ } /* -** Set the Expr.nHeight variable in the structure passed as an -** argument. An expression with no children, Expr.pList or +** Set the Expr.nHeight variable in the structure passed as an +** argument. An expression with no children, Expr.pList or ** Expr.pSelect member has a height of 1. Any other expression -** has a height equal to the maximum height of any other +** has a height equal to the maximum height of any other ** referenced Expr plus one. ** ** Also propagate EP_Propagate flags up from Expr.x.pList to Expr.flags, @@ -858,7 +860,7 @@ ** leave an error in pParse. ** ** Also propagate all EP_Propagate flags from the Expr.x.pList into -** Expr.flags. +** Expr.flags. */ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ if( pParse->nErr ) return; @@ -878,7 +880,7 @@ #else /* ABOVE: Height enforcement enabled. BELOW: Height enforcement off */ /* ** Propagate all EP_Propagate flags from the Expr.x.pList into -** Expr.flags. +** Expr.flags. */ void sqlite3ExprSetHeightAndFlags(Parse *pParse, Expr *p){ if( pParse->nErr ) return; @@ -890,6 +892,15 @@ #endif /* SQLITE_MAX_EXPR_DEPTH>0 */ /* +** Set the error offset for an Expr node, if possible. +*/ +void sqlite3ExprSetErrorOffset(Expr *pExpr, int iOfst){ + if( pExpr==0 ) return; + if( NEVER(ExprUseWJoin(pExpr)) ) return; + pExpr->w.iOfst = iOfst; +} + +/* ** This routine is the core allocator for Expr nodes. ** ** Construct a new expression node and return a pointer to it. Memory @@ -948,7 +959,7 @@ } #if SQLITE_MAX_EXPR_DEPTH>0 pNew->nHeight = 1; -#endif +#endif } return pNew; } @@ -1054,7 +1065,7 @@ /* ** Expression list pEList is a list of vector values. This function ** converts the contents of pEList to a VALUES(...) Select statement -** returning 1 row for each element of the list. For example, the +** returning 1 row for each element of the list. For example, the ** expression list: ** ** ( (1,2), (3,4) (5,6) ) @@ -1085,7 +1096,7 @@ nExprElem = 1; } if( nExprElem!=nElem ){ - sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d", + sqlite3ErrorMsg(pParse, "IN(...) element has %d term%s - expected %d", nExprElem, nExprElem>1?"s":"", nElem ); break; @@ -1125,7 +1136,7 @@ return pLeft; }else{ u32 f = pLeft->flags | pRight->flags; - if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse + if( (f&(EP_OuterON|EP_InnerON|EP_IsFalse))==EP_IsFalse && !IN_RENAME_OBJECT ){ sqlite3ExprDeferredDelete(pParse, pLeft); @@ -1157,7 +1168,7 @@ } assert( !ExprHasProperty(pNew, EP_InnerON|EP_OuterON) ); pNew->w.iOfst = (int)(pToken->z - pParse->zTail); - if( pList + if( pList && pList->nExpr > pParse->db->aLimit[SQLITE_LIMIT_FUNCTION_ARG] && !pParse->nested ){ @@ -1172,6 +1183,69 @@ } /* +** Report an error when attempting to use an ORDER BY clause within +** the arguments of a non-aggregate function. +*/ +void sqlite3ExprOrderByAggregateError(Parse *pParse, Expr *p){ + sqlite3ErrorMsg(pParse, + "ORDER BY may not be used with non-aggregate %#T()", p + ); +} + +/* +** Attach an ORDER BY clause to a function call. +** +** functionname( arguments ORDER BY sortlist ) +** \_____________________/ \______/ +** pExpr pOrderBy +** +** The ORDER BY clause is inserted into a new Expr node of type TK_ORDER +** and added to the Expr.pLeft field of the parent TK_FUNCTION node. +*/ +void sqlite3ExprAddFunctionOrderBy( + Parse *pParse, /* Parsing context */ + Expr *pExpr, /* The function call to which ORDER BY is to be added */ + ExprList *pOrderBy /* The ORDER BY clause to add */ +){ + Expr *pOB; + sqlite3 *db = pParse->db; + if( NEVER(pOrderBy==0) ){ + assert( db->mallocFailed ); + return; + } + if( pExpr==0 ){ + assert( db->mallocFailed ); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + assert( pExpr->op==TK_FUNCTION ); + assert( pExpr->pLeft==0 ); + assert( ExprUseXList(pExpr) ); + if( pExpr->x.pList==0 || NEVER(pExpr->x.pList->nExpr==0) ){ + /* Ignore ORDER BY on zero-argument aggregates */ + sqlite3ParserAddCleanup(pParse, + (void(*)(sqlite3*,void*))sqlite3ExprListDelete, + pOrderBy); + return; + } + if( IsWindowFunc(pExpr) ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + sqlite3ExprListDelete(db, pOrderBy); + return; + } + + pOB = sqlite3ExprAlloc(db, TK_ORDER, 0, 0); + if( pOB==0 ){ + sqlite3ExprListDelete(db, pOrderBy); + return; + } + pOB->x.pList = pOrderBy; + assert( ExprUseXList(pOB) ); + pExpr->pLeft = pOB; + ExprSetProperty(pOB, EP_FullSize); +} + +/* ** Check to see if a function is usable according to current access ** rules: ** @@ -1196,7 +1270,7 @@ /* Functions prohibited in triggers and views if: ** (1) tagged with SQLITE_DIRECTONLY ** (2) not tagged with SQLITE_INNOCUOUS (which means it - ** is tagged with SQLITE_FUNC_UNSAFE) and + ** is tagged with SQLITE_FUNC_UNSAFE) and ** SQLITE_DBCONFIG_TRUSTED_SCHEMA is off (meaning ** that the schema is possibly tainted). */ @@ -1207,7 +1281,7 @@ /* ** Assign a variable number to an expression that encodes a wildcard -** in the original SQL statement. +** in the original SQL statement. ** ** Wildcards consisting of a single "?" are assigned the next sequential ** variable number. @@ -1349,7 +1423,7 @@ /* ** Arrange to cause pExpr to be deleted when the pParse is deleted. ** This is similar to sqlite3ExprDelete() except that the delete is -** deferred untilthe pParse is deleted. +** deferred until the pParse is deleted. ** ** The pExpr might be deleted immediately on an OOM error. ** @@ -1375,7 +1449,7 @@ } /* -** Return the number of bytes allocated for the expression structure +** Return the number of bytes allocated for the expression structure ** passed as the first argument. This is always one of EXPR_FULLSIZE, ** EXPR_REDUCEDSIZE or EXPR_TOKENONLYSIZE. */ @@ -1390,14 +1464,14 @@ ** to store a copy of an expression or expression tree. They differ in ** how much of the tree is measured. ** -** dupedExprStructSize() Size of only the Expr structure +** dupedExprStructSize() Size of only the Expr structure ** dupedExprNodeSize() Size of Expr + space for token ** dupedExprSize() Expr + token + subtree components ** *************************************************************************** ** -** The dupedExprStructSize() function returns two values OR-ed together: -** (1) the space required for a copy of the Expr structure only and +** The dupedExprStructSize() function returns two values OR-ed together: +** (1) the space required for a copy of the Expr structure only and ** (2) the EP_xxx flags that indicate what the structure size should be. ** The return values is always one of: ** @@ -1424,15 +1498,11 @@ assert( flags==EXPRDUP_REDUCE || flags==0 ); /* Only one flag value allowed */ assert( EXPR_FULLSIZE<=0xfff ); assert( (0xfff & (EP_Reduced|EP_TokenOnly))==0 ); - if( 0==flags || p->op==TK_SELECT_COLUMN -#ifndef SQLITE_OMIT_WINDOWFUNC - || ExprHasProperty(p, EP_WinFunc) -#endif - ){ + if( 0==flags || ExprHasProperty(p, EP_FullSize) ){ nSize = EXPR_FULLSIZE; }else{ assert( !ExprHasProperty(p, EP_TokenOnly|EP_Reduced) ); - assert( !ExprHasProperty(p, EP_OuterON) ); + assert( !ExprHasProperty(p, EP_OuterON) ); assert( !ExprHasVVAProperty(p, EP_NoReduce) ); if( p->pLeft || p->x.pList ){ nSize = EXPR_REDUCEDSIZE | EP_Reduced; @@ -1445,7 +1515,7 @@ } /* -** This function returns the space in bytes required to store the copy +** This function returns the space in bytes required to store the copy ** of the Expr structure and a copy of the Expr.u.zToken string (if that ** string is defined.) */ @@ -1458,57 +1528,94 @@ } /* -** Return the number of bytes required to create a duplicate of the -** expression passed as the first argument. The second argument is a -** mask containing EXPRDUP_XXX flags. +** Return the number of bytes required to create a duplicate of the +** expression passed as the first argument. ** ** The value returned includes space to create a copy of the Expr struct ** itself and the buffer referred to by Expr.u.zToken, if any. ** -** If the EXPRDUP_REDUCE flag is set, then the return value includes -** space to duplicate all Expr nodes in the tree formed by Expr.pLeft -** and Expr.pRight variables (but not for any structures pointed to or -** descended from the Expr.x.pList or Expr.x.pSelect variables). +** The return value includes space to duplicate all Expr nodes in the +** tree formed by Expr.pLeft and Expr.pRight, but not any other +** substructure such as Expr.x.pList, Expr.x.pSelect, and Expr.y.pWin. */ -static int dupedExprSize(const Expr *p, int flags){ - int nByte = 0; - if( p ){ - nByte = dupedExprNodeSize(p, flags); - if( flags&EXPRDUP_REDUCE ){ - nByte += dupedExprSize(p->pLeft, flags) + dupedExprSize(p->pRight, flags); - } - } +static int dupedExprSize(const Expr *p){ + int nByte; + assert( p!=0 ); + nByte = dupedExprNodeSize(p, EXPRDUP_REDUCE); + if( p->pLeft ) nByte += dupedExprSize(p->pLeft); + if( p->pRight ) nByte += dupedExprSize(p->pRight); + assert( nByte==ROUND8(nByte) ); return nByte; } /* -** This function is similar to sqlite3ExprDup(), except that if pzBuffer -** is not NULL then *pzBuffer is assumed to point to a buffer large enough -** to store the copy of expression p, the copies of p->u.zToken -** (if applicable), and the copies of the p->pLeft and p->pRight expressions, -** if any. Before returning, *pzBuffer is set to the first byte past the -** portion of the buffer copied into by this function. -*/ -static Expr *exprDup(sqlite3 *db, const Expr *p, int dupFlags, u8 **pzBuffer){ +** An EdupBuf is a memory allocation used to stored multiple Expr objects +** together with their Expr.zToken content. This is used to help implement +** compression while doing sqlite3ExprDup(). The top-level Expr does the +** allocation for itself and many of its decendents, then passes an instance +** of the structure down into exprDup() so that they decendents can have +** access to that memory. +*/ +typedef struct EdupBuf EdupBuf; +struct EdupBuf { + u8 *zAlloc; /* Memory space available for storage */ +#ifdef SQLITE_DEBUG + u8 *zEnd; /* First byte past the end of memory */ +#endif +}; + +/* +** This function is similar to sqlite3ExprDup(), except that if pEdupBuf +** is not NULL then it points to memory that can be used to store a copy +** of the input Expr p together with its p->u.zToken (if any). pEdupBuf +** is updated with the new buffer tail prior to returning. +*/ +static Expr *exprDup( + sqlite3 *db, /* Database connection (for memory allocation) */ + const Expr *p, /* Expr tree to be duplicated */ + int dupFlags, /* EXPRDUP_REDUCE for compression. 0 if not */ + EdupBuf *pEdupBuf /* Preallocated storage space, or NULL */ +){ Expr *pNew; /* Value to return */ - u8 *zAlloc; /* Memory space from which to build Expr object */ + EdupBuf sEdupBuf; /* Memory space from which to build Expr object */ u32 staticFlag; /* EP_Static if space not obtained from malloc */ + int nToken = -1; /* Space needed for p->u.zToken. -1 means unknown */ assert( db!=0 ); assert( p ); assert( dupFlags==0 || dupFlags==EXPRDUP_REDUCE ); - assert( pzBuffer==0 || dupFlags==EXPRDUP_REDUCE ); + assert( pEdupBuf==0 || dupFlags==EXPRDUP_REDUCE ); /* Figure out where to write the new Expr structure. */ - if( pzBuffer ){ - zAlloc = *pzBuffer; + if( pEdupBuf ){ + sEdupBuf.zAlloc = pEdupBuf->zAlloc; +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = pEdupBuf->zEnd; +#endif staticFlag = EP_Static; - assert( zAlloc!=0 ); + assert( sEdupBuf.zAlloc!=0 ); + assert( dupFlags==EXPRDUP_REDUCE ); }else{ - zAlloc = sqlite3DbMallocRawNN(db, dupedExprSize(p, dupFlags)); + int nAlloc; + if( dupFlags ){ + nAlloc = dupedExprSize(p); + }else if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30NN(p->u.zToken)+1; + nAlloc = ROUND8(EXPR_FULLSIZE + nToken); + }else{ + nToken = 0; + nAlloc = ROUND8(EXPR_FULLSIZE); + } + assert( nAlloc==ROUND8(nAlloc) ); + sEdupBuf.zAlloc = sqlite3DbMallocRawNN(db, nAlloc); +#ifdef SQLITE_DEBUG + sEdupBuf.zEnd = sEdupBuf.zAlloc ? sEdupBuf.zAlloc+nAlloc : 0; +#endif + staticFlag = 0; } - pNew = (Expr *)zAlloc; + pNew = (Expr *)sEdupBuf.zAlloc; + assert( EIGHT_BYTE_ALIGNMENT(pNew) ); if( pNew ){ /* Set nNewSize to the size allocated for the structure pointed to @@ -1517,22 +1624,27 @@ ** by the copy of the p->u.zToken string (if any). */ const unsigned nStructSize = dupedExprStructSize(p, dupFlags); - const int nNewSize = nStructSize & 0xfff; - int nToken; - if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ - nToken = sqlite3Strlen30(p->u.zToken) + 1; - }else{ - nToken = 0; + int nNewSize = nStructSize & 0xfff; + if( nToken<0 ){ + if( !ExprHasProperty(p, EP_IntValue) && p->u.zToken ){ + nToken = sqlite3Strlen30(p->u.zToken) + 1; + }else{ + nToken = 0; + } } if( dupFlags ){ + assert( (int)(sEdupBuf.zEnd - sEdupBuf.zAlloc) >= nNewSize+nToken ); assert( ExprHasProperty(p, EP_Reduced)==0 ); - memcpy(zAlloc, p, nNewSize); + memcpy(sEdupBuf.zAlloc, p, nNewSize); }else{ u32 nSize = (u32)exprStructSize(p); - memcpy(zAlloc, p, nSize); - if( nSize= + (int)EXPR_FULLSIZE+nToken ); + memcpy(sEdupBuf.zAlloc, p, nSize); + if( nSizeu.zToken string, if any. */ - if( nToken ){ - char *zToken = pNew->u.zToken = (char*)&zAlloc[nNewSize]; + assert( nToken>=0 ); + if( nToken>0 ){ + char *zToken = pNew->u.zToken = (char*)&sEdupBuf.zAlloc[nNewSize]; memcpy(zToken, p->u.zToken, nToken); + nNewSize += nToken; } + sEdupBuf.zAlloc += ROUND8(nNewSize); + + if( ((p->flags|pNew->flags)&(EP_TokenOnly|EP_Leaf))==0 ){ - if( 0==((p->flags|pNew->flags) & (EP_TokenOnly|EP_Leaf)) ){ /* Fill in the pNew->x.pSelect or pNew->x.pList member. */ if( ExprUseXSelect(p) ){ pNew->x.pSelect = sqlite3SelectDup(db, p->x.pSelect, dupFlags); }else{ - pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, dupFlags); + pNew->x.pList = sqlite3ExprListDup(db, p->x.pList, + p->op!=TK_ORDER ? dupFlags : 0); } - } - /* Fill in pNew->pLeft and pNew->pRight. */ - if( ExprHasProperty(pNew, EP_Reduced|EP_TokenOnly|EP_WinFunc) ){ - zAlloc += dupedExprNodeSize(p, dupFlags); - if( !ExprHasProperty(pNew, EP_TokenOnly|EP_Leaf) ){ - pNew->pLeft = p->pLeft ? - exprDup(db, p->pLeft, EXPRDUP_REDUCE, &zAlloc) : 0; - pNew->pRight = p->pRight ? - exprDup(db, p->pRight, EXPRDUP_REDUCE, &zAlloc) : 0; - } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(p, EP_WinFunc) ){ pNew->y.pWin = sqlite3WindowDup(db, pNew, p->y.pWin); assert( ExprHasProperty(pNew, EP_WinFunc) ); } #endif /* SQLITE_OMIT_WINDOWFUNC */ - if( pzBuffer ){ - *pzBuffer = zAlloc; - } - }else{ - if( !ExprHasProperty(p, EP_TokenOnly|EP_Leaf) ){ - if( pNew->op==TK_SELECT_COLUMN ){ + + /* Fill in pNew->pLeft and pNew->pRight. */ + if( dupFlags ){ + if( p->op==TK_SELECT_COLUMN ){ + pNew->pLeft = p->pLeft; + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); + }else{ + pNew->pLeft = p->pLeft ? + exprDup(db, p->pLeft, EXPRDUP_REDUCE, &sEdupBuf) : 0; + } + pNew->pRight = p->pRight ? + exprDup(db, p->pRight, EXPRDUP_REDUCE, &sEdupBuf) : 0; + }else{ + if( p->op==TK_SELECT_COLUMN ){ pNew->pLeft = p->pLeft; - assert( p->pRight==0 || p->pRight==p->pLeft - || ExprHasProperty(p->pLeft, EP_Subquery) ); + assert( p->pRight==0 + || p->pRight==p->pLeft + || ExprHasProperty(p->pLeft, EP_Subquery) ); }else{ pNew->pLeft = sqlite3ExprDup(db, p->pLeft, 0); } @@ -1590,11 +1708,13 @@ } } } + if( pEdupBuf ) memcpy(pEdupBuf, &sEdupBuf, sizeof(sEdupBuf)); + assert( sEdupBuf.zAlloc <= sEdupBuf.zEnd ); return pNew; } /* -** Create and return a deep copy of the object passed as the second +** Create and return a deep copy of the object passed as the second ** argument. If an OOM condition is encountered, NULL is returned ** and the db->mallocFailed flag set. */ @@ -1661,7 +1781,7 @@ ** without effecting the originals. ** ** The expression list, ID, and source lists return by sqlite3ExprListDup(), -** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded +** sqlite3IdListDup(), and sqlite3SrcListDup() can not be further expanded ** by subsequent calls to sqlite*ListAppend() routines. ** ** Any tables that the SrcList might point to are not duplicated. @@ -1694,9 +1814,9 @@ Expr *pOldExpr = pOldItem->pExpr; Expr *pNewExpr; pItem->pExpr = sqlite3ExprDup(db, pOldExpr, flags); - if( pOldExpr + if( pOldExpr && pOldExpr->op==TK_SELECT_COLUMN - && (pNewExpr = pItem->pExpr)!=0 + && (pNewExpr = pItem->pExpr)!=0 ){ if( pNewExpr->pRight ){ pPriorSelectColOld = pOldExpr->pRight; @@ -1721,7 +1841,7 @@ /* ** If cursors, triggers, views and subqueries are all omitted from -** the build, then none of the following routines, except for +** the build, then none of the following routines, except for ** sqlite3SelectDup(), can be called. sqlite3SelectDup() is sometimes ** called with a NULL argument. */ @@ -1757,7 +1877,7 @@ pNewItem->u2.pCteUse->nUse++; } if( pNewItem->fg.isTabFunc ){ - pNewItem->u1.pFuncArg = + pNewItem->u1.pFuncArg = sqlite3ExprListDup(db, pOldItem->u1.pFuncArg, flags); } pTab = pNewItem->pTab = pOldItem->pTab; @@ -1854,11 +1974,7 @@ ** initially NULL, then create a new expression list. ** ** The pList argument must be either NULL or a pointer to an ExprList -** obtained from a prior call to sqlite3ExprListAppend(). This routine -** may not be used with an ExprList obtained from sqlite3ExprListDup(). -** Reason: This routine assumes that the number of slots in pList->a[] -** is a power of two. That is true for sqlite3ExprListAppend() returns -** but is not necessarily true from the return value of sqlite3ExprListDup(). +** obtained from a prior call to sqlite3ExprListAppend(). ** ** If a memory allocation error occurs, the entire list is freed and ** NULL is returned. If non-NULL is returned, then it is guaranteed @@ -1892,7 +2008,7 @@ struct ExprList_item *pItem; ExprList *pNew; pList->nAlloc *= 2; - pNew = sqlite3DbRealloc(db, pList, + pNew = sqlite3DbRealloc(db, pList, sizeof(*pList)+(pList->nAlloc-1)*sizeof(pList->a[0])); if( pNew==0 ){ sqlite3ExprListDelete(db, pList); @@ -1950,8 +2066,8 @@ if( NEVER(pColumns==0) ) goto vector_append_error; if( pExpr==0 ) goto vector_append_error; - /* If the RHS is a vector, then we can immediately check to see that - ** the size of the RHS and LHS match. But if the RHS is a SELECT, + /* If the RHS is a vector, then we can immediately check to see that + ** the size of the RHS and LHS match. But if the RHS is a SELECT, ** wildcards ("*") in the result set of the SELECT must be expanded before ** we can do the size check, so defer the size check until code generation. */ @@ -1977,7 +2093,7 @@ Expr *pFirst = pList->a[iFirst].pExpr; assert( pFirst!=0 ); assert( pFirst->op==TK_SELECT_COLUMN ); - + /* Store the SELECT statement in pRight so it will be deleted when ** sqlite3ExprListDelete() is called */ pFirst->pRight = pExpr; @@ -2003,13 +2119,13 @@ assert( p->nExpr>0 ); assert( SQLITE_SO_UNDEFINED<0 && SQLITE_SO_ASC==0 && SQLITE_SO_DESC>0 ); - assert( iSortOrder==SQLITE_SO_UNDEFINED - || iSortOrder==SQLITE_SO_ASC - || iSortOrder==SQLITE_SO_DESC + assert( iSortOrder==SQLITE_SO_UNDEFINED + || iSortOrder==SQLITE_SO_ASC + || iSortOrder==SQLITE_SO_DESC ); - assert( eNulls==SQLITE_SO_UNDEFINED - || eNulls==SQLITE_SO_ASC - || eNulls==SQLITE_SO_DESC + assert( eNulls==SQLITE_SO_UNDEFINED + || eNulls==SQLITE_SO_ASC + || eNulls==SQLITE_SO_DESC ); pItem = &p->a[p->nExpr-1]; @@ -2191,7 +2307,7 @@ ** and 0 if it is FALSE. */ int sqlite3ExprTruthValue(const Expr *pExpr){ - pExpr = sqlite3ExprSkipCollate((Expr*)pExpr); + pExpr = sqlite3ExprSkipCollateAndLikely((Expr*)pExpr); assert( pExpr->op==TK_TRUEFALSE ); assert( !ExprHasProperty(pExpr, EP_IntValue) ); assert( sqlite3StrICmp(pExpr->u.zToken,"true")==0 @@ -2248,7 +2364,7 @@ ** when parsing an existing schema out of the sqlite_schema table and 4 ** when processing a new CREATE TABLE statement. A bound parameter raises ** an error for new statements, but is silently converted -** to NULL for existing schemas. This allows sqlite_schema tables that +** to NULL for existing schemas. This allows sqlite_schema tables that ** contain a bound parameter because they were generated by older versions ** of SQLite to be parsed by newer versions of SQLite without raising a ** malformed schema error. @@ -2480,7 +2596,7 @@ /* ** Walk the expression tree passed as the first argument. Return non-zero -** if the expression consists entirely of constants or copies of terms +** if the expression consists entirely of constants or copies of terms ** in pGroupBy that sort with the BINARY collation sequence. ** ** This routine is used to determine if a term of the HAVING clause can @@ -2510,7 +2626,7 @@ /* ** Walk an expression tree for the DEFAULT field of a column definition -** in a CREATE TABLE statement. Return non-zero if the expression is +** in a CREATE TABLE statement. Return non-zero if the expression is ** acceptable for use as a DEFAULT. That is to say, return non-zero if ** the expression is constant or a function call with constant arguments. ** Return and 0 if there are any variables. @@ -2594,7 +2710,7 @@ ** Return FALSE if there is no chance that the expression can be NULL. ** ** If the expression might be NULL or if the expression is too complex -** to tell return TRUE. +** to tell return TRUE. ** ** This routine is used as an optimization, to skip OP_IsNull opcodes ** when we know that a value cannot be NULL. Hence, a false positive @@ -2685,7 +2801,28 @@ } /* -** pX is the RHS of an IN operator. If pX is a SELECT statement +** Return a pointer to a buffer containing a usable rowid alias for table +** pTab. An alias is usable if there is not an explicit user-defined column +** of the same name. +*/ +const char *sqlite3RowidAlias(Table *pTab){ + const char *azOpt[] = {"_ROWID_", "ROWID", "OID"}; + int ii; + assert( VisibleRowid(pTab) ); + for(ii=0; iinCol; iCol++){ + if( sqlite3_stricmp(azOpt[ii], pTab->aCol[iCol].zCnName)==0 ) break; + } + if( iCol==pTab->nCol ){ + return azOpt[ii]; + } + } + return 0; +} + +/* +** pX is the RHS of an IN operator. If pX is a SELECT statement ** that can be simplified to a direct table access, then return ** a pointer to the SELECT statement. If pX is not a SELECT statement, ** or if the SELECT statement needs to be materialized into a transient @@ -2751,7 +2888,7 @@ #ifndef SQLITE_OMIT_SUBQUERY /* -** The argument is an IN operator with a list (not a subquery) on the +** The argument is an IN operator with a list (not a subquery) on the ** right-hand side. Return TRUE if that list is constant. */ static int sqlite3InRhsIsConstant(Expr *pIn){ @@ -2784,7 +2921,7 @@ ** 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 epheremal table. +** populated ephemeral table. ** IN_INDEX_NOOP - No cursor was allocated. The IN operator must be ** implemented as a sequence of comparisons. ** @@ -2797,7 +2934,7 @@ ** an ephemeral table might need to be generated from the RHS and then ** pX->iTable made to point to the ephemeral table instead of an ** existing table. In this case, the creation and initialization of the -** ephmeral table might be put inside of a subroutine, the EP_Subrtn flag +** ephemeral table might be put inside of a subroutine, the EP_Subrtn flag ** will be set on pX and the pX->y.sub fields will be set to show where ** the subroutine is coded. ** @@ -2809,13 +2946,13 @@ ** ** When IN_INDEX_LOOP is used (and the b-tree will be used to iterate ** through the set members) then the b-tree must not contain duplicates. -** An epheremal table will be created unless the selected columns are guaranteed +** 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 epheremal table must -** be used unless is a single INTEGER PRIMARY KEY column or an +** 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 is a single INTEGER PRIMARY KEY column or an ** index can be found with the specified as its left-most. ** ** If the IN_INDEX_NOOP_OK and IN_INDEX_MEMBERSHIP are both set and @@ -2827,7 +2964,7 @@ ** ** When the b-tree is being used for membership tests, the calling function ** might need to know whether or not the RHS side of the IN operator -** contains a NULL. If prRhsHasNull is not a NULL pointer and +** contains a NULL. If prRhsHasNull is not a NULL pointer and ** if there is any chance that the (...) might contain a NULL value at ** runtime, then a register is allocated and the register number written ** to *prRhsHasNull. If there is no chance that the (...) contains a @@ -2868,9 +3005,9 @@ mustBeUnique = (inFlags & IN_INDEX_LOOP)!=0; iTab = pParse->nTab++; - /* If the RHS of this IN(...) operator is a SELECT, and if it matters + /* If the RHS of this IN(...) operator is a SELECT, and if it matters ** whether or not the SELECT result contains NULL values, check whether - ** or not NULL is actually possible (it may not be, for example, due + ** or not NULL is actually possible (it may not be, for example, due ** to NOT NULL constraints in the schema). If no NULL values are possible, ** set prRhsHasNull to 0 before continuing. */ if( prRhsHasNull && ExprUseXSelect(pX) ){ @@ -2885,7 +3022,7 @@ } /* Check to see if an existing table or index can be used to - ** satisfy the query. This is preferable to generating a new + ** satisfy the query. This is preferable to generating a new ** ephemeral table. */ if( pParse->nErr==0 && (p = isCandidateForInOpt(pX))!=0 ){ sqlite3 *db = pParse->db; /* Database connection */ @@ -2921,7 +3058,7 @@ int affinity_ok = 1; int i; - /* Check that the affinity that will be used to perform each + /* Check that the affinity that will be used to perform each ** comparison is the same as the affinity of each column in table ** on the RHS of the IN operator. If it not, it is not possible to ** use any index of the RHS table. */ @@ -2966,14 +3103,14 @@ continue; /* This index is not unique over the IN RHS columns */ } } - + colUsed = 0; /* Columns of index used so far */ for(i=0; ipLeft, i); Expr *pRhs = pEList->a[i].pExpr; CollSeq *pReq = sqlite3BinaryCompareCollSeq(pParse, pLhs, pRhs); int j; - + for(j=0; jaiColumn[j]!=pRhs->iColumn ) continue; assert( pIdx->azColl[j] ); @@ -2988,7 +3125,7 @@ colUsed |= mCol; if( aiMap ) aiMap[i] = j; } - + assert( i==nExpr || colUsed!=(MASKBIT(nExpr)-1) ); if( colUsed==(MASKBIT(nExpr)-1) ){ /* If we reach this point, that means the index pIdx is usable */ @@ -3000,11 +3137,11 @@ VdbeComment((v, "%s", pIdx->zName)); assert( IN_INDEX_INDEX_DESC == IN_INDEX_INDEX_ASC+1 ); eType = IN_INDEX_INDEX_ASC + pIdx->aSortOrder[0]; - + if( prRhsHasNull ){ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK i64 mask = (1<nMem; @@ -3068,8 +3205,8 @@ #ifndef SQLITE_OMIT_SUBQUERY /* -** Argument pExpr is an (?, ?...) IN(...) expression. This -** function allocates and returns a nul-terminated string containing +** Argument pExpr is an (?, ?...) IN(...) expression. This +** function allocates and returns a nul-terminated string containing ** the affinities to be used for each column of the comparison. ** ** It is the responsibility of the caller to ensure that the returned @@ -3102,11 +3239,11 @@ #ifndef SQLITE_OMIT_SUBQUERY /* -** Load the Parse object passed as the first argument with an error +** Load the Parse object passed as the first argument with an error ** message of the form: ** ** "sub-select returns N columns - expected M" -*/ +*/ void sqlite3SubselectError(Parse *pParse, int nActual, int nExpect){ if( pParse->nErr==0 ){ const char *zFmt = "sub-select returns %d columns - expected %d"; @@ -3117,7 +3254,7 @@ /* ** Expression pExpr is a vector that has been used in a context where -** it is not permitted. If pExpr is a sub-select vector, this routine +** it is not permitted. If pExpr is a sub-select vector, this routine ** loads the Parse object with a message of the form: ** ** "sub-select returns N columns - expected 1" @@ -3125,7 +3262,7 @@ ** Or, if it is a regular scalar vector: ** ** "row value misused" -*/ +*/ void sqlite3VectorErrorMsg(Parse *pParse, Expr *pExpr){ #ifndef SQLITE_OMIT_SUBQUERY if( ExprUseXSelect(pExpr) ){ @@ -3147,7 +3284,7 @@ ** 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 ephermeral table is returned. The first time the ephemeral +** 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. @@ -3188,7 +3325,7 @@ if( !ExprHasProperty(pExpr, EP_VarSelect) && pParse->iSelfTab==0 ){ /* Reuse of the RHS is allowed */ /* If this routine has already been coded, but the previous code - ** might not have been invoked yet, so invoke it now as a subroutine. + ** might not have been invoked yet, so invoke it now as a subroutine. */ if( ExprHasProperty(pExpr, EP_Subrtn) ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); @@ -3265,7 +3402,7 @@ if( rc ){ sqlite3KeyInfoUnref(pKeyInfo); return; - } + } assert( pKeyInfo!=0 ); /* OOM will cause exit after sqlite3Select() */ assert( pEList!=0 ); assert( pEList->nExpr>0 ); @@ -3354,7 +3491,7 @@ ** ** The pExpr parameter is the SELECT or EXISTS operator to be coded. ** -** Return the register that holds the result. For a multi-column SELECT, +** Return the register that holds the result. For a multi-column SELECT, ** the result is stored in a contiguous array of registers and the ** return value is the register of the left-most result column. ** Return 0 if an error occurs. @@ -3411,7 +3548,7 @@ if( !ExprHasProperty(pExpr, EP_VarSelect) ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } - + /* For a SELECT, generate code to put the values for all columns of ** the first row into an array of registers and return the index of ** the first register. @@ -3419,7 +3556,7 @@ ** If this is an EXISTS, write an integer 0 (not exists) or 1 (exists) ** into a register and return that register number. ** - ** In both cases, the query is augmented with "LIMIT 1". Any + ** In both cases, the query is augmented with "LIMIT 1". Any ** preexisting limit is discarded in place of the new LIMIT 1. */ ExplainQueryPlan2(addrExplain, (pParse, 1, "%sSCALAR SUBQUERY %d", @@ -3483,9 +3620,9 @@ #ifndef SQLITE_OMIT_SUBQUERY /* -** Expr pIn is an IN(...) expression. This function checks that the -** sub-select on the RHS of the IN() operator has the same number of -** columns as the vector on the LHS. Or, if the RHS of the IN() is not +** Expr pIn is an IN(...) expression. This function checks that the +** sub-select on the RHS of the IN() operator has the same number of +** columns as the vector on the LHS. Or, if the RHS of the IN() is not ** a sub-query, that the LHS is a vector of size 1. */ int sqlite3ExprCheckIN(Parse *pParse, Expr *pIn){ @@ -3510,18 +3647,18 @@ ** x IN (SELECT ...) ** x IN (value, value, ...) ** -** The left-hand side (LHS) is a scalar or vector expression. The +** The left-hand side (LHS) is a scalar or vector expression. The ** right-hand side (RHS) is an array of zero or more scalar values, or a ** subquery. If the RHS is a subquery, the number of result columns must ** match the number of columns in the vector on the LHS. If the RHS is -** a list of values, the LHS must be a scalar. +** a list of values, the LHS must be a scalar. ** ** The IN operator is true if the LHS value is contained within the RHS. -** The result is false if the LHS is definitely not in the RHS. The -** result is NULL if the presence of the LHS in the RHS cannot be +** The result is false if the LHS is definitely not in the RHS. The +** result is NULL if the presence of the LHS in the RHS cannot be ** determined due to NULLs. ** -** This routine generates code that jumps to destIfFalse if the LHS is not +** This routine generates code that jumps to destIfFalse if the LHS is not ** contained within the RHS. If due to NULLs we cannot determine if the LHS ** is contained in the RHS then jump to destIfNull. If the LHS is contained ** within the RHS then fall through. @@ -3550,7 +3687,7 @@ int destStep6 = 0; /* Start of code for Step 6 */ int addrTruthOp; /* Address of opcode that determines the IN is true */ int destNotNull; /* Jump here if a comparison is not true in step 6 */ - int addrTop; /* Top of the step-6 loop */ + int addrTop; /* Top of the step-6 loop */ int iTab = 0; /* Index to use */ u8 okConstFactor = pParse->okConstFactor; @@ -3577,7 +3714,7 @@ aiMap, &iTab); assert( pParse->nErr || nVector==1 || eType==IN_INDEX_EPH - || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC + || eType==IN_INDEX_INDEX_ASC || eType==IN_INDEX_INDEX_DESC ); #ifdef SQLITE_DEBUG /* Confirm that aiMap[] contains nVector integer values between 0 and @@ -3589,8 +3726,8 @@ } #endif - /* Code the LHS, the from " IN (...)". If the LHS is a - ** vector, then it is stored in an array of nVector registers starting + /* Code the LHS, the from " IN (...)". If the LHS is a + ** vector, then it is stored in an array of nVector registers starting ** at r1. ** ** sqlite3FindInIndex() might have reordered the fields of the LHS vector @@ -3722,7 +3859,7 @@ } /* Step 5. If we do not care about the difference between NULL and - ** FALSE, then just return false. + ** FALSE, then just return false. */ if( destIfFalse==destIfNull ) sqlite3VdbeGoto(v, destIfFalse); @@ -3783,7 +3920,7 @@ ** Generate an instruction that will put the floating point ** value described by z[0..n-1] into register iMem. ** -** The z[] string will probably not be zero-terminated. But the +** The z[] string will probably not be zero-terminated. But the ** z[n] character is guaranteed to be something that does not look ** like the continuation of the number. */ @@ -3948,7 +4085,7 @@ /* ** Generate code that will extract the iColumn-th column from -** table pTab and store the column value in register iReg. +** table pTab and store the column value in register iReg. ** ** There must be an open cursor to pTab in iTable when this routine ** is called. If iColumn<0 then code is generated that extracts the rowid. @@ -3962,10 +4099,13 @@ u8 p5 /* P5 value for OP_Column + FLAGS */ ){ assert( pParse->pVdbe!=0 ); + assert( (p5 & (OPFLAG_NOCHNG|OPFLAG_TYPEOFARG|OPFLAG_LENGTHARG))==p5 ); + assert( IsVirtual(pTab) || (p5 & OPFLAG_NOCHNG)==0 ); sqlite3ExprCodeGetColumnOfTable(pParse->pVdbe, pTab, iTable, iColumn, iReg); if( p5 ){ VdbeOp *pOp = sqlite3VdbeGetLastOp(pParse->pVdbe); if( pOp->opcode==OP_Column ) pOp->p5 = p5; + if( pOp->opcode==OP_VColumn ) pOp->p5 = (p5 & OPFLAG_NOCHNG); } return iReg; } @@ -3994,7 +4134,7 @@ /* ** Evaluate an expression (either a vector or a scalar expression) and store -** the result in continguous temporary registers. Return the index of +** 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 @@ -4034,7 +4174,7 @@ */ static void setDoNotMergeFlagOnCopy(Vdbe *v){ if( sqlite3VdbeGetLastOp(v)->opcode==OP_Copy ){ - sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergable */ + sqlite3VdbeChangeP5(v, 1); /* Tag trailing OP_Copy as not mergeable */ } } @@ -4091,7 +4231,7 @@ break; } #endif - default: { + default: { /* The UNLIKELY() function is a no-op. The result is the value ** of the first argument. */ @@ -4108,7 +4248,7 @@ case INLINEFUNC_expr_compare: { /* Compare two expressions using sqlite3ExprCompare() */ assert( nFarg==2 ); - sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprCompare(0,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), target); break; @@ -4117,20 +4257,20 @@ case INLINEFUNC_expr_implies_expr: { /* Compare two expressions using sqlite3ExprImpliesExpr() */ assert( nFarg==2 ); - sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3VdbeAddOp2(v, OP_Integer, sqlite3ExprImpliesExpr(pParse,pFarg->a[0].pExpr, pFarg->a[1].pExpr,-1), target); break; } case INLINEFUNC_implies_nonnull_row: { - /* REsult of sqlite3ExprImpliesNonNullRow() */ + /* Result of sqlite3ExprImpliesNonNullRow() */ Expr *pA1; assert( nFarg==2 ); pA1 = pFarg->a[1].pExpr; if( pA1->op==TK_COLUMN ){ - sqlite3VdbeAddOp2(v, OP_Integer, - sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable), + sqlite3VdbeAddOp2(v, OP_Integer, + sqlite3ExprImpliesNonNullRow(pFarg->a[0].pExpr,pA1->iTable,1), target); }else{ sqlite3VdbeAddOp2(v, OP_Null, 0, target); @@ -4219,6 +4359,41 @@ /* +** Expresion pExpr is guaranteed to be a TK_COLUMN or equivalent. This +** function checks the Parse.pIdxPartExpr list to see if this column +** can be replaced with a constant value. If so, it generates code to +** put the constant value in a register (ideally, but not necessarily, +** register iTarget) and returns the register number. +** +** Or, if the TK_COLUMN cannot be replaced by a constant, zero is +** returned. +*/ +static int exprPartidxExprLookup(Parse *pParse, Expr *pExpr, int iTarget){ + IndexedExpr *p; + for(p=pParse->pIdxPartExpr; p; p=p->pIENext){ + if( pExpr->iColumn==p->iIdxCol && pExpr->iTable==p->iDataCur ){ + Vdbe *v = pParse->pVdbe; + int addr = 0; + int ret; + + if( p->bMaybeNullRow ){ + addr = sqlite3VdbeAddOp1(v, OP_IfNullRow, p->iIdxCur); + } + ret = sqlite3ExprCodeTarget(pParse, p->pExpr, iTarget); + sqlite3VdbeAddOp4(pParse->pVdbe, OP_Affinity, ret, 1, 0, + (const char*)&p->aff, 1); + if( addr ){ + sqlite3VdbeJumpHere(v, addr); + sqlite3VdbeChangeP3(v, addr, ret); + } + return ret; + } + } + return 0; +} + + +/* ** Generate code into the current Vdbe to evaluate the given ** expression. Attempt to store the results in register "target". ** Return the register where results are stored. @@ -4245,7 +4420,7 @@ expr_code_doover: if( pExpr==0 ){ op = TK_NULL; - }else if( pParse->pIdxEpr!=0 + }else if( pParse->pIdxEpr!=0 && !ExprHasProperty(pExpr, EP_Leaf) && (r1 = sqlite3IndexedExprLookup(pParse, pExpr, target))>=0 ){ @@ -4254,6 +4429,7 @@ assert( !ExprHasVVAProperty(pExpr,EP_Immutable) ); op = pExpr->op; } + assert( op!=TK_ORDER ); switch( op ){ case TK_AGG_COLUMN: { AggInfo *pAggInfo = pExpr->pAggInfo; @@ -4267,7 +4443,7 @@ #ifdef SQLITE_VDBE_COVERAGE /* Verify that the OP_Null above is exercised by tests ** tag-20230325-2 */ - sqlite3VdbeAddOp2(v, OP_NotNull, target, 1); + sqlite3VdbeAddOp3(v, OP_NotNull, target, 1, 20230325); VdbeCoverageNeverTaken(v); #endif break; @@ -4284,7 +4460,7 @@ }else if( pCol->iColumn<0 ){ VdbeComment((v,"%s.rowid",pTab->zName)); }else{ - VdbeComment((v,"%s.%s", + VdbeComment((v,"%s.%s", pTab->zName, pTab->aCol[pCol->iColumn].zCnName)); if( pTab->aCol[pCol->iColumn].affinity==SQLITE_AFF_REAL ){ sqlite3VdbeAddOp1(v, OP_RealAffinity, target); @@ -4306,7 +4482,7 @@ if( ExprHasProperty(pExpr, EP_FixedCol) ){ /* This COLUMN expression is really a constant due to WHERE clause ** constraints, and that constant is coded by the pExpr->pLeft - ** expresssion. However, make sure the constant has the correct + ** expression. However, make sure the constant has the correct ** datatype by applying the Affinity of the table column to the ** constant. */ @@ -4375,6 +4551,11 @@ iTab = pParse->iSelfTab - 1; } } + else if( pParse->pIdxPartExpr + && 0!=(r1 = exprPartidxExprLookup(pParse, pExpr, target)) + ){ + return r1; + } assert( ExprUseYTab(pExpr) ); assert( pExpr->y.pTab!=0 ); iReg = sqlite3ExprCodeGetColumn(pParse, pExpr->y.pTab, @@ -4501,7 +4682,7 @@ case TK_BITOR: case TK_SLASH: case TK_LSHIFT: - case TK_RSHIFT: + case TK_RSHIFT: case TK_CONCAT: { assert( TK_AND==OP_And ); testcase( op==TK_AND ); assert( TK_OR==OP_Or ); testcase( op==TK_OR ); @@ -4632,7 +4813,7 @@ sqlite3ErrorMsg(pParse, "unknown function: %#T()", pExpr); break; } - if( pDef->funcFlags & SQLITE_FUNC_INLINE ){ + if( (pDef->funcFlags & SQLITE_FUNC_INLINE)!=0 && ALWAYS(pFarg!=0) ){ assert( (pDef->funcFlags & SQLITE_FUNC_UNSAFE)==0 ); assert( (pDef->funcFlags & SQLITE_FUNC_DIRECT)==0 ); return exprCodeInlineFunction(pParse, pFarg, @@ -4658,10 +4839,10 @@ r1 = sqlite3GetTempRange(pParse, nFarg); } - /* For length() and typeof() functions with a column argument, + /* For length() and typeof() and octet_length() functions, ** set the P5 parameter to the OP_Column opcode to OPFLAG_LENGTHARG - ** or OPFLAG_TYPEOFARG respectively, to avoid unnecessary data - ** loading. + ** or OPFLAG_TYPEOFARG or OPFLAG_BYTELENARG respectively, to avoid + ** unnecessary data loading. */ if( (pDef->funcFlags & (SQLITE_FUNC_LENGTH|SQLITE_FUNC_TYPEOF))!=0 ){ u8 exprOp; @@ -4671,14 +4852,16 @@ if( exprOp==TK_COLUMN || exprOp==TK_AGG_COLUMN ){ assert( SQLITE_FUNC_LENGTH==OPFLAG_LENGTHARG ); assert( SQLITE_FUNC_TYPEOF==OPFLAG_TYPEOFARG ); - testcase( pDef->funcFlags & OPFLAG_LENGTHARG ); - pFarg->a[0].pExpr->op2 = - pDef->funcFlags & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG); + assert( SQLITE_FUNC_BYTELEN==OPFLAG_BYTELENARG ); + assert( (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG)==OPFLAG_BYTELENARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_LENGTHARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_TYPEOFARG ); + testcase( (pDef->funcFlags & OPFLAG_BYTELENARG)==OPFLAG_BYTELENARG); + pFarg->a[0].pExpr->op2 = pDef->funcFlags & OPFLAG_BYTELENARG; } } - sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, - SQLITE_ECEL_DUP|SQLITE_ECEL_FACTOR); + sqlite3ExprCodeExprList(pParse, pFarg, r1, 0, SQLITE_ECEL_FACTOR); }else{ r1 = 0; } @@ -4691,7 +4874,7 @@ ** see if it is a column in a virtual table. This is done because ** the left operand of infix functions (the operand we want to ** control overloading) ends up as the second argument to the - ** function. The expression "A glob B" is equivalent to + ** function. The expression "A glob B" is equivalent to ** "glob(B,A). We want to use the A in "A glob B" to test ** for function overloading. But we use the B term in "glob(B,A)". */ @@ -4702,7 +4885,7 @@ } #endif if( pDef->funcFlags & SQLITE_FUNC_NEEDCOLL ){ - if( !pColl ) pColl = db->pDfltColl; + if( !pColl ) pColl = db->pDfltColl; sqlite3VdbeAddOp4(v, OP_CollSeq, 0, 0, 0, (char *)pColl, P4_COLLSEQ); } sqlite3VdbeAddFunctionCall(pParse, constMask, r1, target, nFarg, @@ -4810,7 +4993,7 @@ ** ** The expression is implemented using an OP_Param opcode. The p1 ** parameter is set to 0 for an old.rowid reference, or to (i+1) - ** to reference another column of the old.* pseudo-table, where + ** to reference another column of the old.* pseudo-table, where ** i is the index of the column. For a new.rowid reference, p1 is ** set to (n+1), where n is the number of columns in each pseudo-table. ** For a reference to any other column in the new.* pseudo-table, p1 @@ -4824,7 +5007,7 @@ ** ** p1==0 -> old.rowid p1==3 -> new.rowid ** p1==1 -> old.a p1==4 -> new.a - ** p1==2 -> old.b p1==5 -> new.b + ** p1==2 -> old.b p1==5 -> new.b */ Table *pTab; int iCol; @@ -4833,7 +5016,7 @@ assert( ExprUseYTab(pExpr) ); pTab = pExpr->y.pTab; iCol = pExpr->iColumn; - p1 = pExpr->iTable * (pTab->nCol+1) + 1 + p1 = pExpr->iTable * (pTab->nCol+1) + 1 + sqlite3TableColumnToStorage(pTab, iCol); assert( pExpr->iTable==0 || pExpr->iTable==1 ); @@ -4991,7 +5174,7 @@ } #ifndef SQLITE_OMIT_TRIGGER case TK_RAISE: { - assert( pExpr->affExpr==OE_Rollback + assert( pExpr->affExpr==OE_Rollback || pExpr->affExpr==OE_Abort || pExpr->affExpr==OE_Fail || pExpr->affExpr==OE_Ignore @@ -5033,9 +5216,9 @@ ** once. If no functions are involved, then factor the code out and put it at ** the end of the prepared statement in the initialization section. ** -** If regDest>=0 then the result is always stored in that register and the -** result is not reusable. If regDest<0 then this routine is free to -** store the value whereever it wants. The register where the expression +** If regDest>0 then the result is always stored in that register and the +** result is not reusable. If regDest<0 then this routine is free to +** store the value wherever it wants. The register where the expression ** is stored is returned. When regDest<0, two identical expressions might ** code to the same register, if they do not contain function calls and hence ** are factored out into the initialization section at the end of the @@ -5048,6 +5231,7 @@ ){ ExprList *p; assert( ConstFactorOk(pParse) ); + assert( regDest!=0 ); p = pParse->pConstExpr; if( regDest<0 && p ){ struct ExprList_item *pItem; @@ -5255,7 +5439,7 @@ ** ** x BETWEEN y AND z ** -** The above is equivalent to +** The above is equivalent to ** ** x>=y AND x<=z ** @@ -5473,7 +5657,7 @@ } } sqlite3ReleaseTempReg(pParse, regFree1); - sqlite3ReleaseTempReg(pParse, regFree2); + sqlite3ReleaseTempReg(pParse, regFree2); } /* @@ -5634,7 +5818,7 @@ } #endif default: { - default_expr: + default_expr: if( ExprAlwaysFalse(pExpr) ){ sqlite3VdbeGoto(v, dest); }else if( ExprAlwaysTrue(pExpr) ){ @@ -5688,7 +5872,7 @@ int res = 0; int iVar; sqlite3_value *pL, *pR = 0; - + sqlite3ValueFromExpr(pParse->db, pExpr, SQLITE_UTF8, SQLITE_AFF_BLOB, &pR); if( pR ){ iVar = pVar->iColumn; @@ -5730,9 +5914,9 @@ ** an incorrect 0 or 1 could lead to a malfunction. ** ** If pParse is not NULL then TK_VARIABLE terms in pA with bindings in -** pParse->pReprepare can be matched against literals in pB. The +** pParse->pReprepare can be matched against literals in pB. The ** pParse->pVdbe->expmask bitmask is updated for each variable referenced. -** If pParse is NULL (the normal case) then any TK_VARIABLE term in +** If pParse is NULL (the normal case) then any TK_VARIABLE term in ** Argument pParse should normally be NULL. If it is not NULL and pA or ** pB causes a return value of 2. */ @@ -5763,7 +5947,7 @@ if( pB->op==TK_COLLATE && sqlite3ExprCompare(pParse, pA,pB->pLeft,iTab)<2 ){ return 1; } - if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN + if( pA->op==TK_AGG_COLUMN && pB->op==TK_COLUMN && pB->iTable<0 && pA->iTable==iTab ){ /* fall through */ @@ -5791,7 +5975,7 @@ return 0; }else if( pA->op==TK_COLLATE ){ if( sqlite3_stricmp(pA->u.zToken,pB->u.zToken)!=0 ) return 2; - }else + }else if( pB->u.zToken!=0 && pA->op!=TK_COLUMN && pA->op!=TK_AGG_COLUMN @@ -5824,7 +6008,7 @@ /* ** Compare two ExprList objects. Return 0 if they are identical, 1 -** if they are certainly different, or 2 if it is not possible to +** if they are certainly different, or 2 if it is not possible to ** determine if they are identical or not. ** ** If any subelement of pB has Expr.iTable==(-1) then it is allowed @@ -5912,8 +6096,8 @@ case TK_MINUS: case TK_BITOR: case TK_LSHIFT: - case TK_RSHIFT: - case TK_CONCAT: + case TK_RSHIFT: + case TK_CONCAT: seenNot = 1; /* no break */ deliberate_fall_through case TK_STAR: @@ -5953,14 +6137,14 @@ ** 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 Reuslt: 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 +** 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 +** modified to record which bound variables are referenced. If pParse ** is NULL, then false will be returned if pE1 contains any bound variables. ** ** When in doubt, return false. Returning true might give a performance @@ -5990,11 +6174,29 @@ return 0; } +/* This is a helper function to impliesNotNullRow(). In this routine, +** set pWalker->eCode to one only if *both* of the input expressions +** separately have the implies-not-null-row property. +*/ +static void bothImplyNotNullRow(Walker *pWalker, Expr *pE1, Expr *pE2){ + if( pWalker->eCode==0 ){ + sqlite3WalkExpr(pWalker, pE1); + if( pWalker->eCode ){ + pWalker->eCode = 0; + sqlite3WalkExpr(pWalker, pE2); + } + } +} + /* ** This is the Expr node callback for sqlite3ExprImpliesNonNullRow(). ** If the expression node requires that the table at pWalker->iCur ** have one or more non-NULL column, then set pWalker->eCode to 1 and abort. ** +** pWalker->mWFlags is non-zero if this inquiry is being undertaking on +** behalf of a RIGHT JOIN (or FULL JOIN). That makes a difference when +** evaluating terms in the ON clause of an inner join. +** ** This routine controls an optimization. False positives (setting ** pWalker->eCode to 1 when it should not be) are deadly, but false-negatives ** (never setting pWalker->eCode) is a harmless missed optimization. @@ -6003,28 +6205,33 @@ testcase( pExpr->op==TK_AGG_COLUMN ); testcase( pExpr->op==TK_AGG_FUNCTION ); if( ExprHasProperty(pExpr, EP_OuterON) ) return WRC_Prune; + if( ExprHasProperty(pExpr, EP_InnerON) && pWalker->mWFlags ){ + /* If iCur is used in an inner-join ON clause to the left of a + ** RIGHT JOIN, that does *not* mean that the table must be non-null. + ** But it is difficult to check for that condition precisely. + ** To keep things simple, any use of iCur from any inner-join is + ** ignored while attempting to simplify a RIGHT JOIN. */ + return WRC_Prune; + } switch( pExpr->op ){ case TK_ISNOT: case TK_ISNULL: case TK_NOTNULL: case TK_IS: - case TK_OR: case TK_VECTOR: - case TK_CASE: - case TK_IN: case TK_FUNCTION: case TK_TRUTH: + case TK_CASE: testcase( pExpr->op==TK_ISNOT ); testcase( pExpr->op==TK_ISNULL ); testcase( pExpr->op==TK_NOTNULL ); testcase( pExpr->op==TK_IS ); - testcase( pExpr->op==TK_OR ); testcase( pExpr->op==TK_VECTOR ); - testcase( pExpr->op==TK_CASE ); - testcase( pExpr->op==TK_IN ); testcase( pExpr->op==TK_FUNCTION ); testcase( pExpr->op==TK_TRUTH ); + testcase( pExpr->op==TK_CASE ); return WRC_Prune; + case TK_COLUMN: if( pWalker->u.iCur==pExpr->iTable ){ pWalker->eCode = 1; @@ -6032,21 +6239,38 @@ } return WRC_Prune; + case TK_OR: case TK_AND: - if( pWalker->eCode==0 ){ + /* Both sides of an AND or OR must separately imply non-null-row. + ** Consider these cases: + ** 1. NOT (x AND y) + ** 2. x OR y + ** If only one of x or y is non-null-row, then the overall expression + ** can be true if the other arm is false (case 1) or true (case 2). + */ + testcase( pExpr->op==TK_OR ); + testcase( pExpr->op==TK_AND ); + bothImplyNotNullRow(pWalker, pExpr->pLeft, pExpr->pRight); + return WRC_Prune; + + case TK_IN: + /* Beware of "x NOT IN ()" and "x NOT IN (SELECT 1 WHERE false)", + ** both of which can be true. But apart from these cases, if + ** the left-hand side of the IN is NULL then the IN itself will be + ** NULL. */ + if( ExprUseXList(pExpr) && ALWAYS(pExpr->x.pList->nExpr>0) ){ sqlite3WalkExpr(pWalker, pExpr->pLeft); - if( pWalker->eCode ){ - pWalker->eCode = 0; - sqlite3WalkExpr(pWalker, pExpr->pRight); - } } return WRC_Prune; case TK_BETWEEN: - if( sqlite3WalkExpr(pWalker, pExpr->pLeft)==WRC_Abort ){ - assert( pWalker->eCode ); - return WRC_Abort; - } + /* In "x NOT BETWEEN y AND z" either x must be non-null-row or else + ** both y and z must be non-null row */ + assert( ExprUseXList(pExpr) ); + assert( pExpr->x.pList->nExpr==2 ); + sqlite3WalkExpr(pWalker, pExpr->pLeft); + bothImplyNotNullRow(pWalker, pExpr->x.pList->a[0].pExpr, + pExpr->x.pList->a[1].pExpr); return WRC_Prune; /* Virtual tables are allowed to use constraints like x=NULL. So @@ -6108,7 +6332,7 @@ ** be non-NULL, then the LEFT JOIN can be safely converted into an ** ordinary join. */ -int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab){ +int sqlite3ExprImpliesNonNullRow(Expr *p, int iTab, int isRJ){ Walker w; p = sqlite3ExprSkipCollateAndLikely(p); if( p==0 ) return 0; @@ -6116,7 +6340,7 @@ p = p->pLeft; }else{ while( p->op==TK_AND ){ - if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab) ) return 1; + if( sqlite3ExprImpliesNonNullRow(p->pLeft, iTab, isRJ) ) return 1; p = p->pRight; } } @@ -6124,6 +6348,7 @@ w.xSelectCallback = 0; w.xSelectCallback2 = 0; w.eCode = 0; + w.mWFlags = isRJ!=0; w.u.iCur = iTab; sqlite3WalkExpr(&w, p); return w.eCode; @@ -6142,7 +6367,7 @@ }; /* -** Check to see if there are references to columns in table +** Check to see if there are references to columns in table ** pWalker->u.pIdxCover->iCur can be satisfied using the index ** pWalker->u.pIdxCover->pIdx. */ @@ -6184,7 +6409,7 @@ } -/* Structure used to pass information throught the Walker in order to +/* Structure used to pass information throughout the Walker in order to ** implement sqlite3ReferencesSrcList(). */ struct RefSrcList { @@ -6232,7 +6457,7 @@ } /* This is the Walker EXPR callback for sqlite3ReferencesSrcList(). -** +** ** Set the 0x01 bit of pWalker->eCode if there is a reference to any ** of the tables shown in RefSrcList.pRef. ** @@ -6291,6 +6516,12 @@ assert( pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3WalkExprList(&w, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + assert( pExpr->pLeft->x.pList!=0 ); + sqlite3WalkExprList(&w, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC if( ExprHasProperty(pExpr, EP_WinFunc) ){ sqlite3WalkExpr(&w, pExpr->y.pWin->pFilter); @@ -6377,7 +6608,7 @@ &i ); return i; -} +} /* ** Add a new element to the pAggInfo->aFunc[] array. Return the index of @@ -6386,7 +6617,7 @@ static int addAggInfoFunc(sqlite3 *db, AggInfo *pInfo){ int i; pInfo->aFunc = sqlite3ArrayAllocate( - db, + db, pInfo->aFunc, sizeof(pInfo->aFunc[0]), &pInfo->nFunc, @@ -6397,10 +6628,10 @@ /* ** Search the AggInfo object for an aCol[] entry that has iTable and iColumn. -** Return the index in aCol[] of the entry that describes that column. +** Return the index in aCol[] of the entry that describes that column. ** ** If no prior entry is found, create a new one and return -1. The -** new column will have an idex of pAggInfo->nColumn-1. +** new column will have an index of pAggInfo->nColumn-1. */ static void findOrCreateAggInfoColumn( Parse *pParse, /* Parsing context */ @@ -6413,6 +6644,7 @@ assert( pAggInfo->iFirstReg==0 ); pCol = pAggInfo->aCol; for(k=0; knColumn; k++, pCol++){ + if( pCol->pCExpr==pExpr ) return; if( pCol->iTable==pExpr->iTable && pCol->iColumn==pExpr->iColumn && pExpr->op!=TK_IF_NULL_ROW @@ -6538,7 +6770,7 @@ if( (pNC->ncFlags & NC_InAggFunc)==0 && pWalker->walkerDepth==pExpr->op2 ){ - /* Check to see if pExpr is a duplicate of another aggregate + /* Check to see if pExpr is a duplicate of another aggregate ** function that is already in the pAggInfo structure */ struct AggInfo_func *pItem = pAggInfo->aFunc; @@ -6554,14 +6786,42 @@ u8 enc = ENC(pParse->db); i = addAggInfoFunc(pParse->db, pAggInfo); if( i>=0 ){ + int nArg; assert( !ExprHasProperty(pExpr, EP_xIsSelect) ); pItem = &pAggInfo->aFunc[i]; pItem->pFExpr = pExpr; assert( ExprUseUToken(pExpr) ); + nArg = pExpr->x.pList ? pExpr->x.pList->nExpr : 0; pItem->pFunc = sqlite3FindFunction(pParse->db, - pExpr->u.zToken, - pExpr->x.pList ? pExpr->x.pList->nExpr : 0, enc, 0); - if( pExpr->flags & EP_Distinct ){ + pExpr->u.zToken, nArg, enc, 0); + assert( pItem->bOBUnique==0 ); + if( pExpr->pLeft + && (pItem->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL)==0 + ){ + /* The NEEDCOLL test above causes any ORDER BY clause on + ** aggregate min() or max() to be ignored. */ + ExprList *pOBList; + assert( nArg>0 ); + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + pItem->iOBTab = pParse->nTab++; + pOBList = pExpr->pLeft->x.pList; + assert( pOBList->nExpr>0 ); + assert( pItem->bOBUnique==0 ); + if( pOBList->nExpr==1 + && nArg==1 + && sqlite3ExprCompare(0,pOBList->a[0].pExpr, + pExpr->x.pList->a[0].pExpr,0)==0 + ){ + pItem->bOBPayload = 0; + pItem->bOBUnique = ExprHasProperty(pExpr, EP_Distinct); + }else{ + pItem->bOBPayload = 1; + } + }else{ + pItem->iOBTab = -1; + } + if( ExprHasProperty(pExpr, EP_Distinct) && !pItem->bOBUnique ){ pItem->iDistinct = pParse->nTab++; }else{ pItem->iDistinct = -1; diff -Nru sqlite3-3.42.0/src/fkey.c sqlite3-3.44.0-0/src/fkey.c --- sqlite3-3.42.0/src/fkey.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/fkey.c 2023-11-04 14:23:58.000000000 +0000 @@ -858,6 +858,7 @@ if( (p==pFKey->apTrigger[0] && pFKey->aAction[0]==OE_SetNull) || (p==pFKey->apTrigger[1] && pFKey->aAction[1]==OE_SetNull) ){ + assert( (pTop->db->flags & SQLITE_FkNoAction)==0 ); return 1; } } @@ -1052,6 +1053,8 @@ } if( regOld!=0 ){ int eAction = pFKey->aAction[aChange!=0]; + if( (db->flags & SQLITE_FkNoAction) ) eAction = OE_None; + fkScanChildren(pParse, pSrc, pTab, pIdx, pFKey, aiCol, regOld, 1); /* If this is a deferred FK constraint, or a CASCADE or SET NULL ** action applies, then any foreign key violations caused by @@ -1167,7 +1170,11 @@ /* Check if any parent key columns are being modified. */ for(p=sqlite3FkReferences(pTab); p; p=p->pNextTo){ if( fkParentIsModified(pTab, p, aChange, chngRowid) ){ - if( p->aAction[1]!=OE_None ) return 2; + if( (pParse->db->flags & SQLITE_FkNoAction)==0 + && p->aAction[1]!=OE_None + ){ + return 2; + } bHaveFK = 1; } } @@ -1217,6 +1224,7 @@ int iAction = (pChanges!=0); /* 1 for UPDATE, 0 for DELETE */ action = pFKey->aAction[iAction]; + if( (db->flags & SQLITE_FkNoAction) ) action = OE_None; if( action==OE_Restrict && (db->flags & SQLITE_DeferFKs) ){ return 0; } @@ -1448,9 +1456,8 @@ if( pFKey->pPrevTo ){ pFKey->pPrevTo->pNextTo = pFKey->pNextTo; }else{ - void *p = (void *)pFKey->pNextTo; - const char *z = (p ? pFKey->pNextTo->zTo : pFKey->zTo); - sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, p); + const char *z = (pFKey->pNextTo ? pFKey->pNextTo->zTo : pFKey->zTo); + sqlite3HashInsert(&pTab->pSchema->fkeyHash, z, pFKey->pNextTo); } if( pFKey->pNextTo ){ pFKey->pNextTo->pPrevTo = pFKey->pPrevTo; diff -Nru sqlite3-3.42.0/src/func.c sqlite3-3.44.0-0/src/func.c --- sqlite3-3.42.0/src/func.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/func.c 2023-11-04 14:23:58.000000000 +0000 @@ -150,10 +150,46 @@ } /* +** Implementation of the octet_length() function +*/ +static void bytelengthFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + assert( argc==1 ); + UNUSED_PARAMETER(argc); + switch( sqlite3_value_type(argv[0]) ){ + case SQLITE_BLOB: { + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); + break; + } + case SQLITE_INTEGER: + case SQLITE_FLOAT: { + i64 m = sqlite3_context_db_handle(context)->enc<=SQLITE_UTF8 ? 1 : 2; + sqlite3_result_int64(context, sqlite3_value_bytes(argv[0])*m); + break; + } + case SQLITE_TEXT: { + if( sqlite3_value_encoding(argv[0])<=SQLITE_UTF8 ){ + sqlite3_result_int(context, sqlite3_value_bytes(argv[0])); + }else{ + sqlite3_result_int(context, sqlite3_value_bytes16(argv[0])); + } + break; + } + default: { + sqlite3_result_null(context); + break; + } + } +} + +/* ** Implementation of the abs() function. ** ** IMP: R-23979-26855 The abs(X) function returns the absolute value of -** the numeric argument X. +** the numeric argument X. */ static void absFunc(sqlite3_context *context, int argc, sqlite3_value **argv){ assert( argc==1 ); @@ -170,7 +206,7 @@ return; } iVal = -iVal; - } + } sqlite3_result_int64(context, iVal); break; } @@ -422,10 +458,10 @@ */ if( r<-4503599627370496.0 || r>+4503599627370496.0 ){ /* The value has no fractional part so there is nothing to round */ - }else if( n==0 ){ + }else if( n==0 ){ r = (double)((sqlite_int64)(r+(r<0?-0.5:+0.5))); }else{ - zBuf = sqlite3_mprintf("%.*f",n,r); + zBuf = sqlite3_mprintf("%!.*f",n,r); if( zBuf==0 ){ sqlite3_result_error_nomem(context); return; @@ -515,7 +551,7 @@ #define noopFunc versionFunc /* Substitute function - never called */ /* -** Implementation of random(). Return a random integer. +** Implementation of random(). Return a random integer. */ static void randomFunc( sqlite3_context *context, @@ -526,11 +562,11 @@ UNUSED_PARAMETER2(NotUsed, NotUsed2); sqlite3_randomness(sizeof(r), &r); if( r<0 ){ - /* We need to prevent a random number of 0x8000000000000000 + /* We need to prevent a random number of 0x8000000000000000 ** (or -9223372036854775808) since when you do abs() of that ** number of you get the same value back again. To do this ** in a way that is testable, mask the sign bit off of negative - ** values, resulting in a positive value. Then take the + ** values, resulting in a positive value. Then take the ** 2s complement of that positive value. The end result can ** therefore be no less than -9223372036854775807. */ @@ -568,8 +604,8 @@ ** value is the same as the sqlite3_last_insert_rowid() API function. */ static void last_insert_rowid( - sqlite3_context *context, - int NotUsed, + sqlite3_context *context, + int NotUsed, sqlite3_value **NotUsed2 ){ sqlite3 *db = sqlite3_context_db_handle(context); @@ -625,7 +661,7 @@ /* ** For LIKE and GLOB matching on EBCDIC machines, assume that every -** character is exactly one byte in size. Also, provde the Utf8Read() +** 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. */ @@ -677,7 +713,7 @@ ** it the last character in the list. ** ** Like matching rules: -** +** ** '%' Matches any sequence of zero or more characters ** *** '_' Matches any one character @@ -700,13 +736,13 @@ u32 matchAll = pInfo->matchAll; /* "*" or "%" */ u8 noCase = pInfo->noCase; /* True if uppercase==lowercase */ const u8 *zEscaped = 0; /* One past the last escaped input char */ - + while( (c = Utf8Read(zPattern))!=0 ){ if( c==matchAll ){ /* Match "*" */ /* Skip over multiple "*" characters in the pattern. If there ** are also "?" characters, skip those as well, but consume a ** single character of the input string for each "?" skipped */ - while( (c=Utf8Read(zPattern)) == matchAll + while( (c=Utf8Read(zPattern)) == matchAll || (c == matchOne && matchOne!=0) ){ if( c==matchOne && sqlite3Utf8Read(&zString)==0 ){ return SQLITE_NOWILDCARDMATCH; @@ -858,7 +894,7 @@ /* ** Implementation of the like() SQL function. This function implements -** the build-in LIKE operator. The first argument to the function is the +** the built-in LIKE operator. The first argument to the function is the ** pattern and the second argument is the string. So, the SQL statements: ** ** A LIKE B @@ -869,8 +905,8 @@ ** the GLOB operator. */ static void likeFunc( - sqlite3_context *context, - int argc, + sqlite3_context *context, + int argc, sqlite3_value **argv ){ const unsigned char *zA, *zB; @@ -909,7 +945,7 @@ const unsigned char *zEsc = sqlite3_value_text(argv[2]); if( zEsc==0 ) return; if( sqlite3Utf8CharLen((char*)zEsc, -1)!=1 ){ - sqlite3_result_error(context, + sqlite3_result_error(context, "ESCAPE expression must be a single character", -1); return; } @@ -1022,8 +1058,8 @@ #endif /* SQLITE_OMIT_COMPILEOPTION_DIAGS */ /* -** Implementation of the sqlite_compileoption_get() function. -** The result is a string that identifies the compiler options +** Implementation of the sqlite_compileoption_get() function. +** The result is a string that identifies the compiler options ** used to build SQLite. */ #ifndef SQLITE_OMIT_COMPILEOPTION_DIAGS @@ -1047,7 +1083,7 @@ ** digits. */ static const char hexdigits[] = { '0', '1', '2', '3', '4', '5', '6', '7', - '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' + '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' }; /* @@ -1114,7 +1150,7 @@ } /* -** Implementation of the QUOTE() function. +** Implementation of the QUOTE() function. ** ** The quote(X) function returns the text of an SQL literal which is the ** value of its argument suitable for inclusion into an SQL statement. @@ -1140,7 +1176,7 @@ /* ** The unicode() function. Return the integer unicode code-point value -** for the first character of the input string. +** for the first character of the input string. */ static void unicodeFunc( sqlite3_context *context, @@ -1191,6 +1227,7 @@ *zOut++ = 0x80 + (u8)(c & 0x3F); } \ } + *zOut = 0; sqlite3_result_text64(context, (char*)z, zOut-z, sqlite3_free, SQLITE_UTF8); } @@ -1219,7 +1256,8 @@ *(z++) = hexdigits[c&0xf]; } *z = 0; - sqlite3_result_text(context, zHex, n*2, sqlite3_free); + sqlite3_result_text64(context, zHex, (u64)(z-zHex), + sqlite3_free, SQLITE_UTF8); } } @@ -1244,12 +1282,12 @@ ** decoded and returned as a blob. ** ** If there is only a single argument, then it must consist only of an -** even number of hexadeximal digits. Otherwise, return NULL. +** even number of hexadecimal digits. Otherwise, return NULL. ** ** Or, if there is a second argument, then any character that appears in ** the second argument is also allowed to appear between pairs of hexadecimal ** digits in the first argument. If any other character appears in the -** first argument, or if one of the allowed characters appears between +** first argument, or if one of the allowed characters appears between ** two hexadecimal digits that make up a single byte, NULL is returned. ** ** The following expressions are all true: @@ -1386,7 +1424,7 @@ if( zOut==0 ){ return; } - loopLimit = nStr - nPattern; + loopLimit = nStr - nPattern; cntExpand = 0; for(i=j=0; i<=loopLimit; i++){ if( zStr[i]!=zPattern[0] || memcmp(&zStr[i], zPattern, nPattern) ){ @@ -1468,7 +1506,7 @@ SQLITE_SKIP_UTF8(z); } if( nChar>0 ){ - azChar = contextMalloc(context, + azChar = contextMalloc(context, ((i64)nChar)*(sizeof(char*)+sizeof(unsigned))); if( azChar==0 ){ return; @@ -1513,6 +1551,81 @@ sqlite3_result_text(context, (char*)zIn, nIn, SQLITE_TRANSIENT); } +/* The core implementation of the CONCAT(...) and CONCAT_WS(SEP,...) +** functions. +** +** Return a string value that is the concatenation of all non-null +** entries in argv[]. Use zSep as the separator. +*/ +static void concatFuncCore( + sqlite3_context *context, + int argc, + sqlite3_value **argv, + int nSep, + const char *zSep +){ + i64 j, k, n = 0; + int i; + char *z; + for(i=0; i0 ){ + const char *v = (const char*)sqlite3_value_text(argv[i]); + if( v!=0 ){ + if( j>0 && nSep>0 ){ + memcpy(&z[j], zSep, nSep); + j += nSep; + } + memcpy(&z[j], v, k); + j += k; + } + } + } + z[j] = 0; + assert( j<=n ); + sqlite3_result_text64(context, z, j, sqlite3_free, SQLITE_UTF8); +} + +/* +** The CONCAT(...) function. Generate a string result that is the +** concatentation of all non-null arguments. +*/ +static void concatFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + concatFuncCore(context, argc, argv, 0, ""); +} + +/* +** The CONCAT_WS(separator, ...) function. +** +** Generate a string that is the concatenation of 2nd through the Nth +** argument. Use the first argument (which must be non-NULL) as the +** separator. +*/ +static void concatwsFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + int nSep = sqlite3_value_bytes(argv[0]); + const char *zSep = (const char*)sqlite3_value_text(argv[0]); + if( zSep==0 ) return; + concatFuncCore(context, argc-1, argv+1, nSep, zSep); +} + #ifdef SQLITE_ENABLE_UNKNOWN_SQL_FUNCTION /* @@ -1546,7 +1659,7 @@ ** Compute the soundex encoding of a word. ** ** IMP: R-59782-00072 The soundex(X) function returns a string that is the -** soundex encoding of the string X. +** soundex encoding of the string X. */ static void soundexFunc( sqlite3_context *context, @@ -1634,14 +1747,69 @@ */ typedef struct SumCtx SumCtx; struct SumCtx { - double rSum; /* Floating point sum */ - i64 iSum; /* Integer sum */ + double rSum; /* Running sum as as a double */ + double rErr; /* Error term for Kahan-Babushka-Neumaier summation */ + i64 iSum; /* Running sum as a signed integer */ i64 cnt; /* Number of elements summed */ - u8 overflow; /* True if integer overflow seen */ - u8 approx; /* True if non-integer value was input to the sum */ + u8 approx; /* True if any non-integer value was input to the sum */ + u8 ovrfl; /* Integer overflow seen */ }; /* +** Do one step of the Kahan-Babushka-Neumaier summation. +** +** https://en.wikipedia.org/wiki/Kahan_summation_algorithm +** +** Variables are marked "volatile" to defeat c89 x86 floating point +** optimizations can mess up this algorithm. +*/ +static void kahanBabuskaNeumaierStep( + volatile SumCtx *pSum, + volatile double r +){ + volatile double s = pSum->rSum; + volatile double t = s + r; + if( fabs(s) > fabs(r) ){ + pSum->rErr += (s - t) + r; + }else{ + pSum->rErr += (r - t) + s; + } + pSum->rSum = t; +} + +/* +** Add a (possibly large) integer to the running sum. +*/ +static void kahanBabuskaNeumaierStepInt64(volatile SumCtx *pSum, i64 iVal){ + if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ + i64 iBig, iSm; + iSm = iVal % 16384; + iBig = iVal - iSm; + kahanBabuskaNeumaierStep(pSum, iBig); + kahanBabuskaNeumaierStep(pSum, iSm); + }else{ + kahanBabuskaNeumaierStep(pSum, (double)iVal); + } +} + +/* +** Initialize the Kahan-Babaska-Neumaier sum from a 64-bit integer +*/ +static void kahanBabuskaNeumaierInit( + volatile SumCtx *p, + i64 iVal +){ + if( iVal<=-4503599627370496LL || iVal>=+4503599627370496LL ){ + i64 iSm = iVal % 16384; + p->rSum = (double)(iVal - iSm); + p->rErr = (double)iSm; + }else{ + p->rSum = (double)iVal; + p->rErr = 0.0; + } +} + +/* ** Routines used to compute the sum, average, and total. ** ** The SUM() function follows the (broken) SQL standard which means @@ -1660,15 +1828,29 @@ type = sqlite3_value_numeric_type(argv[0]); if( p && type!=SQLITE_NULL ){ p->cnt++; - if( type==SQLITE_INTEGER ){ - i64 v = sqlite3_value_int64(argv[0]); - p->rSum += v; - if( (p->approx|p->overflow)==0 && sqlite3AddInt64(&p->iSum, v) ){ - p->approx = p->overflow = 1; + if( p->approx==0 ){ + if( type!=SQLITE_INTEGER ){ + kahanBabuskaNeumaierInit(p, p->iSum); + p->approx = 1; + kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); + }else{ + i64 x = p->iSum; + if( sqlite3AddInt64(&x, sqlite3_value_int64(argv[0]))==0 ){ + p->iSum = x; + }else{ + p->ovrfl = 1; + kahanBabuskaNeumaierInit(p, p->iSum); + p->approx = 1; + kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); + } } }else{ - p->rSum += sqlite3_value_double(argv[0]); - p->approx = 1; + if( type==SQLITE_INTEGER ){ + kahanBabuskaNeumaierStepInt64(p, sqlite3_value_int64(argv[0])); + }else{ + p->ovrfl = 0; + kahanBabuskaNeumaierStep(p, sqlite3_value_double(argv[0])); + } } } } @@ -1685,13 +1867,18 @@ if( ALWAYS(p) && type!=SQLITE_NULL ){ assert( p->cnt>0 ); p->cnt--; - assert( type==SQLITE_INTEGER || p->approx ); - if( type==SQLITE_INTEGER && p->approx==0 ){ - i64 v = sqlite3_value_int64(argv[0]); - p->rSum -= v; - p->iSum -= v; + if( !p->approx ){ + p->iSum -= sqlite3_value_int64(argv[0]); + }else if( type==SQLITE_INTEGER ){ + i64 iVal = sqlite3_value_int64(argv[0]); + if( iVal!=SMALLEST_INT64 ){ + kahanBabuskaNeumaierStepInt64(p, -iVal); + }else{ + kahanBabuskaNeumaierStepInt64(p, LARGEST_INT64); + kahanBabuskaNeumaierStepInt64(p, 1); + } }else{ - p->rSum -= sqlite3_value_double(argv[0]); + kahanBabuskaNeumaierStep(p, -sqlite3_value_double(argv[0])); } } } @@ -1702,10 +1889,14 @@ SumCtx *p; p = sqlite3_aggregate_context(context, 0); if( p && p->cnt>0 ){ - if( p->overflow ){ - sqlite3_result_error(context,"integer overflow",-1); - }else if( p->approx ){ - sqlite3_result_double(context, p->rSum); + if( p->approx ){ + if( p->ovrfl ){ + sqlite3_result_error(context,"integer overflow",-1); + }else if( !sqlite3IsNaN(p->rErr) ){ + sqlite3_result_double(context, p->rSum+p->rErr); + }else{ + sqlite3_result_double(context, p->rSum); + } }else{ sqlite3_result_int64(context, p->iSum); } @@ -1715,14 +1906,29 @@ SumCtx *p; p = sqlite3_aggregate_context(context, 0); if( p && p->cnt>0 ){ - sqlite3_result_double(context, p->rSum/(double)p->cnt); + double r; + if( p->approx ){ + r = p->rSum; + if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; + }else{ + r = (double)(p->iSum); + } + sqlite3_result_double(context, r/(double)p->cnt); } } static void totalFinalize(sqlite3_context *context){ SumCtx *p; + double r = 0.0; p = sqlite3_aggregate_context(context, 0); - /* (double)0 In case of SQLITE_OMIT_FLOATING_POINT... */ - sqlite3_result_double(context, p ? p->rSum : (double)0); + if( p ){ + if( p->approx ){ + r = p->rSum; + if( !sqlite3IsNaN(p->rErr) ) r += p->rErr; + }else{ + r = (double)(p->iSum); + } + } + sqlite3_result_double(context, r); } /* @@ -1749,13 +1955,13 @@ #ifndef SQLITE_OMIT_DEPRECATED /* The sqlite3_aggregate_count() function is deprecated. But just to make - ** sure it still operates correctly, verify that its count agrees with our + ** sure it still operates correctly, verify that its count agrees with our ** internal count when using count(*) and when the total count can be ** expressed as a 32-bit integer. */ assert( argc==1 || p==0 || p->n>0x7fffffff || p->bInverse || p->n==sqlite3_aggregate_count(context) ); #endif -} +} static void countFinalize(sqlite3_context *context){ CountCtx *p; p = sqlite3_aggregate_context(context, 0); @@ -1772,7 +1978,7 @@ p->bInverse = 1; #endif } -} +} #else # define countInverse 0 #endif /* SQLITE_OMIT_WINDOWFUNC */ @@ -1781,8 +1987,8 @@ ** Routines to implement min() and max() aggregate functions. */ static void minmaxStep( - sqlite3_context *context, - int NotUsed, + sqlite3_context *context, + int NotUsed, sqlite3_value **argv ){ Mem *pArg = (Mem *)argv[0]; @@ -1841,6 +2047,7 @@ /* ** group_concat(EXPR, ?SEPARATOR?) +** string_agg(EXPR, SEPARATOR) ** ** The SEPARATOR goes before the EXPR string. This is tragic. The ** groupConcatInverse() implementation would have been easier if the @@ -1944,7 +2151,7 @@ if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; pGCC = (GroupConcatCtx*)sqlite3_aggregate_context(context, sizeof(*pGCC)); /* pGCC is always non-NULL since groupConcatStep() will have always - ** run frist to initialize it */ + ** run first to initialize it */ if( ALWAYS(pGCC) ){ int nVS; /* Must call sqlite3_value_text() to convert the argument into text prior @@ -1999,7 +2206,7 @@ sqlite3_result_error_toobig(context); }else if( pAccum->accError==SQLITE_NOMEM ){ sqlite3_result_error_nomem(context); - }else{ + }else{ const char *zText = sqlite3_str_value(pAccum); sqlite3_result_text(context, zText, pAccum->nChar, SQLITE_TRANSIENT); } @@ -2028,8 +2235,10 @@ ** sensitive. */ void sqlite3RegisterLikeFunctions(sqlite3 *db, int caseSensitive){ + FuncDef *pDef; struct compareInfo *pInfo; int flags; + int nArg; if( caseSensitive ){ pInfo = (struct compareInfo*)&likeInfoAlt; flags = SQLITE_FUNC_LIKE | SQLITE_FUNC_CASE; @@ -2037,17 +2246,20 @@ pInfo = (struct compareInfo*)&likeInfoNorm; flags = SQLITE_FUNC_LIKE; } - sqlite3CreateFunc(db, "like", 2, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); - sqlite3CreateFunc(db, "like", 3, SQLITE_UTF8, pInfo, likeFunc, 0, 0, 0, 0, 0); - sqlite3FindFunction(db, "like", 2, SQLITE_UTF8, 0)->funcFlags |= flags; - sqlite3FindFunction(db, "like", 3, SQLITE_UTF8, 0)->funcFlags |= flags; + for(nArg=2; nArg<=3; nArg++){ + sqlite3CreateFunc(db, "like", nArg, SQLITE_UTF8, pInfo, likeFunc, + 0, 0, 0, 0, 0); + pDef = sqlite3FindFunction(db, "like", nArg, SQLITE_UTF8, 0); + pDef->funcFlags |= flags; + pDef->funcFlags &= ~SQLITE_FUNC_UNSAFE; + } } /* ** pExpr points to an expression which implements a function. If ** it is appropriate to apply the LIKE optimization to that function ** then set aWc[0] through aWc[2] to the wildcard characters and the -** escape character and then return TRUE. If the function is not a +** escape character and then return TRUE. If the function is not a ** LIKE-style function then return FALSE. ** ** The expression "a LIKE b ESCAPE c" is only considered a valid LIKE @@ -2312,6 +2524,37 @@ sqlite3_result_int(context, x<0.0 ? -1 : x>0.0 ? +1 : 0); } +#ifdef SQLITE_DEBUG +/* +** Implementation of fpdecode(x,y,z) function. +** +** x is a real number that is to be decoded. y is the precision. +** z is the maximum real precision. +*/ +static void fpdecodeFunc( + sqlite3_context *context, + int argc, + sqlite3_value **argv +){ + FpDecode s; + double x; + int y, z; + char zBuf[100]; + UNUSED_PARAMETER(argc); + assert( argc==3 ); + x = sqlite3_value_double(argv[0]); + y = sqlite3_value_int(argv[1]); + z = sqlite3_value_int(argv[2]); + sqlite3FpDecode(&s, x, y, z); + if( s.isSpecial==2 ){ + sqlite3_snprintf(sizeof(zBuf), zBuf, "NaN"); + }else{ + sqlite3_snprintf(sizeof(zBuf), zBuf, "%c%.*s/%d", s.sign, s.n, s.z, s.iDP); + } + sqlite3_result_text(context, zBuf, -1, SQLITE_TRANSIENT); +} +#endif /* SQLITE_DEBUG */ + /* ** All of the FuncDef structures in the aBuiltinFunc[] array above ** to the global function hash table. This occurs at start-time (as @@ -2376,12 +2619,16 @@ FUNCTION2(typeof, 1, 0, 0, typeofFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(subtype, 1, 0, 0, subtypeFunc, SQLITE_FUNC_TYPEOF), FUNCTION2(length, 1, 0, 0, lengthFunc, SQLITE_FUNC_LENGTH), + FUNCTION2(octet_length, 1, 0, 0, bytelengthFunc,SQLITE_FUNC_BYTELEN), FUNCTION(instr, 2, 0, 0, instrFunc ), FUNCTION(printf, -1, 0, 0, printfFunc ), FUNCTION(format, -1, 0, 0, printfFunc ), FUNCTION(unicode, 1, 0, 0, unicodeFunc ), FUNCTION(char, -1, 0, 0, charFunc ), FUNCTION(abs, 1, 0, 0, absFunc ), +#ifdef SQLITE_DEBUG + FUNCTION(fpdecode, 3, 0, 0, fpdecodeFunc ), +#endif #ifndef SQLITE_OMIT_FLOATING_POINT FUNCTION(round, 1, 0, 0, roundFunc ), FUNCTION(round, 2, 0, 0, roundFunc ), @@ -2391,6 +2638,11 @@ FUNCTION(hex, 1, 0, 0, hexFunc ), FUNCTION(unhex, 1, 0, 0, unhexFunc ), FUNCTION(unhex, 2, 0, 0, unhexFunc ), + FUNCTION(concat, -1, 0, 0, concatFunc ), + FUNCTION(concat, 0, 0, 0, 0 ), + FUNCTION(concat_ws, -1, 0, 0, concatwsFunc ), + FUNCTION(concat_ws, 0, 0, 0, 0 ), + FUNCTION(concat_ws, 1, 0, 0, 0 ), INLINE_FUNC(ifnull, 2, INLINEFUNC_coalesce, 0 ), VFUNCTION(random, 0, 0, 0, randomFunc ), VFUNCTION(randomblob, 1, 0, 0, randomBlob ), @@ -2411,16 +2663,18 @@ WAGGREGATE(sum, 1,0,0, sumStep, sumFinalize, sumFinalize, sumInverse, 0), WAGGREGATE(total, 1,0,0, sumStep,totalFinalize,totalFinalize,sumInverse, 0), WAGGREGATE(avg, 1,0,0, sumStep, avgFinalize, avgFinalize, sumInverse, 0), - WAGGREGATE(count, 0,0,0, countStep, + WAGGREGATE(count, 0,0,0, countStep, countFinalize, countFinalize, countInverse, SQLITE_FUNC_COUNT|SQLITE_FUNC_ANYORDER ), - WAGGREGATE(count, 1,0,0, countStep, + WAGGREGATE(count, 1,0,0, countStep, countFinalize, countFinalize, countInverse, SQLITE_FUNC_ANYORDER ), - WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, + WAGGREGATE(group_concat, 1, 0, 0, groupConcatStep, + groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), + WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), - WAGGREGATE(group_concat, 2, 0, 0, groupConcatStep, + WAGGREGATE(string_agg, 2, 0, 0, groupConcatStep, groupConcatFinalize, groupConcatValue, groupConcatInverse, 0), - + LIKEFUNC(glob, 2, &globInfo, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), #ifdef SQLITE_CASE_SENSITIVE_LIKE LIKEFUNC(like, 2, &likeInfoAlt, SQLITE_FUNC_LIKE|SQLITE_FUNC_CASE), diff -Nru sqlite3-3.42.0/src/global.c sqlite3-3.44.0-0/src/global.c --- sqlite3-3.42.0/src/global.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/global.c 2023-11-04 14:23:58.000000000 +0000 @@ -243,6 +243,7 @@ SQLITE_ALLOW_COVERING_INDEX_SCAN, /* bUseCis */ 0, /* bSmallMalloc */ 1, /* bExtraSchemaChecks */ + sizeof(LONGDOUBLE_TYPE)>8, /* bUseLongDouble */ 0x7ffffffe, /* mxStrlen */ 0, /* neverCorrupt */ SQLITE_DEFAULT_LOOKASIDE, /* szLookaside, nLookaside */ diff -Nru sqlite3-3.42.0/src/hash.c sqlite3-3.44.0-0/src/hash.c --- sqlite3-3.42.0/src/hash.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/hash.c 2023-11-04 14:23:58.000000000 +0000 @@ -97,7 +97,7 @@ } -/* Resize the hash table so that it cantains "new_size" buckets. +/* Resize the hash table so that it contains "new_size" buckets. ** ** The hash table might fail to resize if sqlite3_malloc() fails or ** if the new size is the same as the prior size. diff -Nru sqlite3-3.42.0/src/hwtime.h sqlite3-3.44.0-0/src/hwtime.h --- sqlite3-3.42.0/src/hwtime.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/hwtime.h 2023-11-04 14:23:58.000000000 +0000 @@ -17,7 +17,7 @@ #define SQLITE_HWTIME_H /* -** The following routine only works on pentium-class (or newer) processors. +** The following routine only works on Pentium-class (or newer) processors. ** It uses the RDTSC opcode to read the cycle count value out of the ** processor and returns that value. This can be used for high-res ** profiling. diff -Nru sqlite3-3.42.0/src/insert.c sqlite3-3.44.0-0/src/insert.c --- sqlite3-3.42.0/src/insert.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/insert.c 2023-11-04 14:23:58.000000000 +0000 @@ -15,7 +15,7 @@ #include "sqliteInt.h" /* -** Generate code that will +** Generate code that will ** ** (1) acquire a lock for table pTab then ** (2) open pTab as cursor iCur. @@ -35,8 +35,10 @@ assert( pParse->pVdbe!=0 ); v = pParse->pVdbe; assert( opcode==OP_OpenWrite || opcode==OP_OpenRead ); - sqlite3TableLock(pParse, iDb, pTab->tnum, - (opcode==OP_OpenWrite)?1:0, pTab->zName); + if( !pParse->db->noSharedCache ){ + sqlite3TableLock(pParse, iDb, pTab->tnum, + (opcode==OP_OpenWrite)?1:0, pTab->zName); + } if( HasRowid(pTab) ){ sqlite3VdbeAddOp4Int(v, opcode, iCur, pTab->tnum, iDb, pTab->nNVCol); VdbeComment((v, "%s", pTab->zName)); @@ -52,7 +54,7 @@ /* ** Return a pointer to the column affinity string associated with index -** pIdx. A column affinity string has one character for each column in +** pIdx. A column affinity string has one character for each column in ** the table, according to the affinity of the column: ** ** Character Column affinity @@ -131,7 +133,7 @@ zColAff[j--] = 0; }while( j>=0 && zColAff[j]<=SQLITE_AFF_BLOB ); } - return zColAff; + return zColAff; } /* @@ -165,7 +167,7 @@ ** For STRICT tables: ** ------------------ ** -** Generate an appropropriate OP_TypeCheck opcode that will verify the +** Generate an appropriate OP_TypeCheck opcode that will verify the ** datatypes against the column definitions in pTab. If iReg==0, that ** means an OP_MakeRecord opcode has already been generated and should be ** the last opcode generated. The new OP_TypeCheck needs to be inserted @@ -220,9 +222,9 @@ /* ** Return non-zero if the table pTab in database iDb or any of its indices -** have been opened at any point in the VDBE program. This is used to see if -** a statement of the form "INSERT INTO SELECT ..." can -** run without using a temporary table for the results of the SELECT. +** have been opened at any point in the VDBE program. This is used to see if +** a statement of the form "INSERT INTO SELECT ..." can +** run without using a temporary table for the results of the SELECT. */ static int readsTable(Parse *p, int iDb, Table *pTab){ Vdbe *v = sqlite3GetVdbe(p); @@ -450,7 +452,7 @@ /* ** This routine generates code that will initialize all of the -** register used by the autoincrement tracker. +** register used by the autoincrement tracker. */ void sqlite3AutoincrementBegin(Parse *pParse){ AutoincInfo *p; /* Information about an AUTOINCREMENT */ @@ -479,7 +481,7 @@ /* 8 */ {OP_Goto, 0, 11, 0}, /* 9 */ {OP_Next, 0, 2, 0}, /* 10 */ {OP_Integer, 0, 0, 0}, - /* 11 */ {OP_Close, 0, 0, 0} + /* 11 */ {OP_Close, 0, 0, 0} }; VdbeOp *aOp; pDb = &db->aDb[p->iDb]; @@ -817,7 +819,7 @@ ** ** This is the 2nd template. */ - if( pColumn==0 + if( pColumn==0 && pSelect!=0 && pTrigger==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) @@ -845,7 +847,7 @@ regData = regRowid+1; /* If the INSERT statement included an IDLIST term, then make sure - ** all elements of the IDLIST really are columns of the table and + ** all elements of the IDLIST really are columns of the table and ** remember the column indices. ** ** If the table has an INTEGER PRIMARY KEY column and that column @@ -880,7 +882,7 @@ } #ifndef SQLITE_OMIT_GENERATED_COLUMNS if( pTab->aCol[j].colFlags & (COLFLAG_STORED|COLFLAG_VIRTUAL) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot INSERT into generated column \"%s\"", pTab->aCol[j].zCnName); goto insert_cleanup; @@ -937,7 +939,7 @@ ** the destination table (template 3). ** ** A temp table must be used if the table being updated is also one - ** of the tables being read by the SELECT statement. Also use a + ** of the tables being read by the SELECT statement. Also use a ** temp table in the case of row triggers. */ if( pTrigger || readsTable(pParse, iDb, pTab) ){ @@ -973,7 +975,7 @@ sqlite3ReleaseTempReg(pParse, regTempRowid); } }else{ - /* This is the case if the data for the INSERT is coming from a + /* This is the case if the data for the INSERT is coming from a ** single-row VALUES clause */ NameContext sNC; @@ -992,7 +994,7 @@ } /* If there is no IDLIST term but the table has an integer primary - ** key, the set the ipkColumn variable to the integer primary key + ** key, the set the ipkColumn variable to the integer primary key ** column index in the original table definition. */ if( pColumn==0 && nColumn>0 ){ @@ -1023,7 +1025,7 @@ } } if( nColumn!=(pTab->nCol-nHidden) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "table %S has %d columns but %d values were supplied", pTabList->a, pTab->nCol-nHidden, nColumn); goto insert_cleanup; @@ -1033,7 +1035,7 @@ sqlite3ErrorMsg(pParse, "%d values for %d columns", nColumn, pColumn->nId); goto insert_cleanup; } - + /* Initialize the count of rows to be inserted */ if( (db->flags & SQLITE_CountRows)!=0 @@ -1168,7 +1170,7 @@ }else if( pColumn==0 ){ /* Hidden columns that are not explicitly named in the INSERT ** get there default value */ - sqlite3ExprCodeFactorable(pParse, + sqlite3ExprCodeFactorable(pParse, sqlite3ColumnExpr(pTab, &pTab->aCol[i]), iRegStore); continue; @@ -1180,7 +1182,7 @@ if( j>=pColumn->nId ){ /* A column not named in the insert column list gets its ** default value */ - sqlite3ExprCodeFactorable(pParse, + sqlite3ExprCodeFactorable(pParse, sqlite3ColumnExpr(pTab, &pTab->aCol[i]), iRegStore); continue; @@ -1188,7 +1190,7 @@ k = j; }else if( nColumn==0 ){ /* This is INSERT INTO ... DEFAULT VALUES. Load the default value. */ - sqlite3ExprCodeFactorable(pParse, + sqlite3ExprCodeFactorable(pParse, sqlite3ColumnExpr(pTab, &pTab->aCol[i]), iRegStore); continue; @@ -1197,7 +1199,7 @@ } if( useTempTable ){ - sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); + sqlite3VdbeAddOp3(v, OP_Column, srcTab, k, iRegStore); }else if( pSelect ){ if( regFromSelect!=regData ){ sqlite3VdbeAddOp2(v, OP_SCopy, regFromSelect+k, iRegStore); @@ -1268,7 +1270,7 @@ } /* Fire BEFORE or INSTEAD OF triggers */ - sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_BEFORE, pTab, regCols-pTab->nCol-1, onError, endOfLoop); sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol+1); @@ -1353,7 +1355,7 @@ ** constraints or (b) there are no triggers and this table is not a ** parent table in a foreign key constraint. It is safe to set the ** flag in the second case as if any REPLACE constraint is hit, an - ** OP_Delete or OP_IdxDelete instruction will be executed on each + ** OP_Delete or OP_IdxDelete instruction will be executed on each ** cursor that is disturbed. And these instructions both clear the ** VdbeCursor.seekResult variable, disabling the OPFLAG_USESEEKRESULT ** functionality. */ @@ -1379,7 +1381,7 @@ if( pTrigger ){ /* Code AFTER triggers */ - sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_INSERT, 0, TRIGGER_AFTER, pTab, regData-2-pTab->nCol, onError, endOfLoop); } @@ -1417,7 +1419,7 @@ } /* - ** Return the number of rows inserted. If this routine is + ** Return the number of rows inserted. If this routine is ** generating code because of a call to sqlite3NestedParse(), do not ** invoke the callback function. */ @@ -1448,7 +1450,7 @@ #endif /* -** Meanings of bits in of pWalker->eCode for +** Meanings of bits in of pWalker->eCode for ** sqlite3ExprReferencesUpdatedColumn() */ #define CKCNSTRNT_COLUMN 0x01 /* CHECK constraint uses a changing column */ @@ -1457,7 +1459,7 @@ /* This is the Walker callback from sqlite3ExprReferencesUpdatedColumn(). * Set bit 0x01 of pWalker->eCode if pWalker->eCode to 0 and if this ** expression node references any of the -** columns that are being modifed by an UPDATE statement. +** columns that are being modified by an UPDATE statement. */ static int checkConstraintExprNode(Walker *pWalker, Expr *pExpr){ if( pExpr->op==TK_COLUMN ){ @@ -1529,7 +1531,7 @@ union { struct { /* Use this object for eType==0: A Index.pNext list */ Index *pIdx; /* The current Index */ - } lx; + } lx; struct { /* Use this object for eType==1; Array of IndexListTerm */ int nIdx; /* Size of the array */ IndexListTerm *aIdx; /* Array of IndexListTerms */ @@ -1573,7 +1575,7 @@ return pIter->u.lx.pIdx; } } - + /* ** Generate code to do constraint checks prior to an INSERT or an UPDATE ** on table pTab. @@ -1680,7 +1682,7 @@ int *aiChng, /* column i is unchanged if aiChng[i]<0 */ Upsert *pUpsert /* ON CONFLICT clauses, if any. NULL otherwise */ ){ - Vdbe *v; /* VDBE under constrution */ + Vdbe *v; /* VDBE under construction */ Index *pIdx; /* Pointer to one of the indices */ Index *pPk = 0; /* The PRIMARY KEY index for WITHOUT ROWID tables */ sqlite3 *db; /* Database connection */ @@ -1712,9 +1714,9 @@ assert( v!=0 ); assert( !IsView(pTab) ); /* This table is not a VIEW */ nCol = pTab->nCol; - + /* pPk is the PRIMARY KEY index for WITHOUT ROWID tables and NULL for - ** normal rowid tables. nPkField is the number of key fields in the + ** normal rowid tables. nPkField is the number of key fields in the ** pPk index or 1 for a rowid table. In other words, nPkField is the ** number of fields in the true primary key of the table. */ if( HasRowid(pTab) ){ @@ -2091,10 +2093,10 @@ ** the triggers and remove both the table and index b-tree entries. ** ** Otherwise, if there are no triggers or the recursive-triggers - ** flag is not set, but the table has one or more indexes, call - ** GenerateRowIndexDelete(). This removes the index b-tree entries - ** only. The table b-tree entry will be replaced by the new entry - ** when it is inserted. + ** flag is not set, but the table has one or more indexes, call + ** GenerateRowIndexDelete(). This removes the index b-tree entries + ** only. The table b-tree entry will be replaced by the new entry + ** when it is inserted. ** ** If either GenerateRowDelete() or GenerateRowIndexDelete() is called, ** also invoke MultiWrite() to indicate that this VDBE may require @@ -2163,7 +2165,7 @@ pIdx; pIdx = indexIteratorNext(&sIdxIter, &ix) ){ - int regIdx; /* Range of registers hold conent for pIdx */ + int regIdx; /* Range of registers holding 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 */ @@ -2226,7 +2228,7 @@ #endif sqlite3VdbeReleaseRegisters(pParse, regIdx, pIdx->nColumn, 0, 0); - /* In an UPDATE operation, if this index is the PRIMARY KEY index + /* In an UPDATE operation, if this index is the PRIMARY KEY index ** of a WITHOUT ROWID table and there has been no change the ** primary key, then no collision is possible. The collision detection ** logic below can all be skipped. */ @@ -2237,7 +2239,7 @@ /* Find out what action to take in case there is a uniqueness conflict */ onError = pIdx->onError; - if( onError==OE_None ){ + if( onError==OE_None ){ sqlite3VdbeResolveLabel(v, addrUniqueOk); continue; /* pIdx is not a UNIQUE index */ } @@ -2283,7 +2285,7 @@ /* Check to see if the new index entry will be unique */ sqlite3VdbeVerifyAbortable(v, onError); - addrConflictCk = + addrConflictCk = sqlite3VdbeAddOp4Int(v, OP_NoConflict, iThisCur, addrUniqueOk, regIdx, pIdx->nKeyCol); VdbeCoverage(v); @@ -2313,7 +2315,7 @@ } } if( isUpdate ){ - /* If currently processing the PRIMARY KEY of a WITHOUT ROWID + /* If currently processing the PRIMARY KEY of a WITHOUT ROWID ** table, only conflict if the new PRIMARY KEY values are actually ** different from the old. See TH3 withoutrowid04.test. ** @@ -2323,7 +2325,7 @@ int addrJump = sqlite3VdbeCurrentAddr(v)+pPk->nKeyCol; int op = OP_Ne; int regCmp = (IsPrimaryKeyIndex(pIdx) ? regIdx : regR); - + for(i=0; inKeyCol; i++){ char *p4 = (char*)sqlite3LocateCollSeq(pParse, pPk->azColl[i]); x = pPk->aiColumn[i]; @@ -2333,7 +2335,7 @@ op = OP_Eq; } x = sqlite3TableColumnToStorage(pTab, x); - sqlite3VdbeAddOp4(v, op, + sqlite3VdbeAddOp4(v, op, regOldData+1+x, addrJump, regCmp+i, p4, P4_COLLSEQ ); sqlite3VdbeChangeP5(v, SQLITE_NOTNULL); @@ -2443,7 +2445,7 @@ } sqlite3VdbeResolveLabel(v, addrUniqueOk); if( regR!=regIdx ) sqlite3ReleaseTempRange(pParse, regR, nPkField); - if( pUpsertClause + if( pUpsertClause && upsertIpkReturn && sqlite3UpsertNextIsIPK(pUpsertClause) ){ @@ -2658,6 +2660,8 @@ assert( op==OP_OpenRead || op==OP_OpenWrite ); assert( op==OP_OpenWrite || p5==0 ); + assert( piDataCur!=0 ); + assert( piIdxCur!=0 ); if( IsVirtual(pTab) ){ /* This routine is a no-op for virtual tables. Leave the output ** variables *piDataCur and *piIdxCur set to illegal cursor numbers @@ -2670,18 +2674,18 @@ assert( v!=0 ); if( iBase<0 ) iBase = pParse->nTab; iDataCur = iBase++; - if( piDataCur ) *piDataCur = iDataCur; + *piDataCur = iDataCur; if( HasRowid(pTab) && (aToOpen==0 || aToOpen[0]) ){ sqlite3OpenTable(pParse, iDataCur, iDb, pTab, op); - }else{ + }else if( pParse->db->noSharedCache==0 ){ sqlite3TableLock(pParse, iDb, pTab->tnum, op==OP_OpenWrite, pTab->zName); } - if( piIdxCur ) *piIdxCur = iBase; + *piIdxCur = iBase; for(i=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, i++){ int iIdxCur = iBase++; assert( pIdx->pSchema==pTab->pSchema ); if( IsPrimaryKeyIndex(pIdx) && !HasRowid(pTab) ){ - if( piDataCur ) *piDataCur = iIdxCur; + *piDataCur = iIdxCur; p5 = 0; } if( aToOpen==0 || aToOpen[i+1] ){ @@ -2760,7 +2764,7 @@ ** ** INSERT INTO tab1 SELECT * FROM tab2; ** -** The xfer optimization transfers raw records from tab2 over to tab1. +** The xfer optimization transfers raw records from tab2 over to tab1. ** Columns are not decoded and reassembled, which greatly improves ** performance. Raw index records are transferred in the same way. ** @@ -2888,8 +2892,8 @@ Column *pDestCol = &pDest->aCol[i]; Column *pSrcCol = &pSrc->aCol[i]; #ifdef SQLITE_ENABLE_HIDDEN_COLUMNS - if( (db->mDbFlags & DBFLAG_Vacuum)==0 - && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && (pDestCol->colFlags | pSrcCol->colFlags) & COLFLAG_HIDDEN ){ return 0; /* Neither table may have __hidden__ columns */ } @@ -2906,7 +2910,7 @@ ** ** Nevertheless, this is a useful notational shorthand to tell SQLite ** to do a bulk transfer all of the content from t1 over to t2. - ** + ** ** We could, in theory, disable this (except for internal use by the ** VACUUM command where it is actually needed). But why do that? It ** seems harmless enough, and provides a useful service. @@ -2932,7 +2936,7 @@ if( pDestCol->affinity!=pSrcCol->affinity ){ return 0; /* Affinity must be the same on all columns */ } - if( sqlite3_stricmp(sqlite3ColumnColl(pDestCol), + if( sqlite3_stricmp(sqlite3ColumnColl(pDestCol), sqlite3ColumnColl(pSrcCol))!=0 ){ return 0; /* Collating sequence must be the same on all columns */ } @@ -2947,7 +2951,7 @@ assert( pDestExpr==0 || !ExprHasProperty(pDestExpr, EP_IntValue) ); assert( pSrcExpr==0 || pSrcExpr->op==TK_SPAN ); assert( pSrcExpr==0 || !ExprHasProperty(pSrcExpr, EP_IntValue) ); - if( (pDestExpr==0)!=(pSrcExpr==0) + if( (pDestExpr==0)!=(pSrcExpr==0) || (pDestExpr!=0 && strcmp(pDestExpr->u.zToken, pSrcExpr->u.zToken)!=0) ){ @@ -2979,9 +2983,9 @@ } #endif #ifndef SQLITE_OMIT_FOREIGN_KEY - /* Disallow the transfer optimization if the destination table constains + /* 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 + ** 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] @@ -3030,7 +3034,7 @@ ** (If the destination is not initially empty, the rowid fields ** of index entries might need to change.) ** - ** (2) The destination has a unique index. (The xfer optimization + ** (2) The destination has a unique index. (The xfer optimization ** is unable to test uniqueness.) ** ** (3) onError is something other than OE_Abort and OE_Rollback. @@ -3106,14 +3110,14 @@ /* This INSERT command is part of a VACUUM operation, which guarantees ** that the destination table is empty. If all indexed columns use ** collation sequence BINARY, then it can also be assumed that the - ** index will be populated by inserting keys in strictly sorted + ** index will be populated by inserting keys in strictly sorted ** order. In this case, instead of seeking within the b-tree as part ** of every OP_IdxInsert opcode, an OP_SeekEnd is added before the - ** OP_IdxInsert to seek to the point within the b-tree where each key + ** OP_IdxInsert to seek to the point within the b-tree where each key ** should be inserted. This is faster. ** ** If any of the indexed columns use a collation sequence other than - ** BINARY, this optimization is disabled. This is because the user + ** BINARY, this optimization is disabled. This is because the user ** might change the definition of a collation sequence and then run ** a VACUUM command. In that case keys may not be written in strictly ** sorted order. */ @@ -3131,9 +3135,9 @@ } if( idxInsFlags!=(OPFLAG_USESEEKRESULT|OPFLAG_PREFORMAT) ){ sqlite3VdbeAddOp3(v, OP_RowData, iSrc, regData, 1); - if( (db->mDbFlags & DBFLAG_Vacuum)==0 - && !HasRowid(pDest) - && IsPrimaryKeyIndex(pDestIdx) + if( (db->mDbFlags & DBFLAG_Vacuum)==0 + && !HasRowid(pDest) + && IsPrimaryKeyIndex(pDestIdx) ){ codeWithoutRowidPreupdate(pParse, pDest, iDest, regData); } diff -Nru sqlite3-3.42.0/src/json.c sqlite3-3.44.0-0/src/json.c --- sqlite3-3.42.0/src/json.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/json.c 2023-11-04 14:23:58.000000000 +0000 @@ -30,25 +30,51 @@ ** increase for the parser. (Ubuntu14.10 gcc 4.8.4 x64 with -Os). */ static const char jsonIsSpace[] = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }; #define fast_isspace(x) (jsonIsSpace[(unsigned char)x]) +/* +** Characters that are special to JSON. Control charaters, +** '"' and '\\'. +*/ +static const char jsonIsOk[256] = { + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 1, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 +}; + + #if !defined(SQLITE_DEBUG) && !defined(SQLITE_COVERAGE_TEST) # define VVA(X) #else @@ -59,6 +85,7 @@ typedef struct JsonString JsonString; typedef struct JsonNode JsonNode; typedef struct JsonParse JsonParse; +typedef struct JsonCleanup JsonCleanup; /* An instance of this object represents a JSON string ** under construction. Really, this is a generic string accumulator @@ -74,16 +101,26 @@ char zSpace[100]; /* Initial static space */ }; +/* A deferred cleanup task. A list of JsonCleanup objects might be +** run when the JsonParse object is destroyed. +*/ +struct JsonCleanup { + JsonCleanup *pJCNext; /* Next in a list */ + void (*xOp)(void*); /* Routine to run */ + void *pArg; /* Argument to xOp() */ +}; + /* JSON type values */ -#define JSON_NULL 0 -#define JSON_TRUE 1 -#define JSON_FALSE 2 -#define JSON_INT 3 -#define JSON_REAL 4 -#define JSON_STRING 5 -#define JSON_ARRAY 6 -#define JSON_OBJECT 7 +#define JSON_SUBST 0 /* Special edit node. Uses u.iPrev */ +#define JSON_NULL 1 +#define JSON_TRUE 2 +#define JSON_FALSE 3 +#define JSON_INT 4 +#define JSON_REAL 5 +#define JSON_STRING 6 +#define JSON_ARRAY 7 +#define JSON_OBJECT 8 /* The "subtype" set for JSON values */ #define JSON_SUBTYPE 74 /* Ascii for "J" */ @@ -92,52 +129,87 @@ ** Names of the various JSON types: */ static const char * const jsonType[] = { + "subst", "null", "true", "false", "integer", "real", "text", "array", "object" }; /* Bit values for the JsonNode.jnFlag field */ -#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ -#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ -#define JNODE_REMOVE 0x04 /* Do not output */ -#define JNODE_REPLACE 0x08 /* Replace with JsonNode.u.iReplace */ -#define JNODE_PATCH 0x10 /* Patch with JsonNode.u.pPatch */ -#define JNODE_APPEND 0x20 /* More ARRAY/OBJECT entries at u.iAppend */ -#define JNODE_LABEL 0x40 /* Is a label of an object */ -#define JNODE_JSON5 0x80 /* Node contains JSON5 enhancements */ +#define JNODE_RAW 0x01 /* Content is raw, not JSON encoded */ +#define JNODE_ESCAPE 0x02 /* Content is text with \ escapes */ +#define JNODE_REMOVE 0x04 /* Do not output */ +#define JNODE_REPLACE 0x08 /* Target of a JSON_SUBST node */ +#define JNODE_APPEND 0x10 /* More ARRAY/OBJECT entries at u.iAppend */ +#define JNODE_LABEL 0x20 /* Is a label of an object */ +#define JNODE_JSON5 0x40 /* Node contains JSON5 enhancements */ -/* A single node of parsed JSON +/* A single node of parsed JSON. An array of these nodes describes +** a parse of JSON + edits. +** +** Use the json_parse() SQL function (available when compiled with +** -DSQLITE_DEBUG) to see a dump of complete JsonParse objects, including +** a complete listing and decoding of the array of JsonNodes. */ struct JsonNode { u8 eType; /* One of the JSON_ type values */ u8 jnFlags; /* JNODE flags */ u8 eU; /* Which union element to use */ - u32 n; /* Bytes of content, or number of sub-nodes */ + u32 n; /* Bytes of content for INT, REAL or STRING + ** Number of sub-nodes for ARRAY and OBJECT + ** Node that SUBST applies to */ union { const char *zJContent; /* 1: Content for INT, REAL, and STRING */ u32 iAppend; /* 2: More terms for ARRAY and OBJECT */ u32 iKey; /* 3: Key for ARRAY objects in json_tree() */ - u32 iReplace; /* 4: Replacement content for JNODE_REPLACE */ - JsonNode *pPatch; /* 5: Node chain of patch for JNODE_PATCH */ + u32 iPrev; /* 4: Previous SUBST node, or 0 */ } u; }; -/* A completely parsed JSON string + +/* A parsed and possibly edited JSON string. Lifecycle: +** +** 1. JSON comes in and is parsed into an array aNode[]. The original +** JSON text is stored in zJson. +** +** 2. Zero or more changes are made (via json_remove() or json_replace() +** or similar) to the aNode[] array. +** +** 3. A new, edited and mimified JSON string is generated from aNode +** and stored in zAlt. The JsonParse object always owns zAlt. +** +** Step 1 always happens. Step 2 and 3 may or may not happen, depending +** on the operation. +** +** aNode[].u.zJContent entries typically point into zJson. Hence zJson +** must remain valid for the lifespan of the parse. For edits, +** aNode[].u.zJContent might point to malloced space other than zJson. +** Entries in pClup are responsible for freeing that extra malloced space. +** +** When walking the parse tree in aNode[], edits are ignored if useMod is +** false. */ struct JsonParse { u32 nNode; /* Number of slots of aNode[] used */ u32 nAlloc; /* Number of slots of aNode[] allocated */ JsonNode *aNode; /* Array of nodes containing the parse */ - const char *zJson; /* Original JSON string */ + char *zJson; /* Original JSON string (before edits) */ + char *zAlt; /* Revised and/or mimified JSON */ u32 *aUp; /* Index of parent of each node */ + JsonCleanup *pClup;/* Cleanup operations prior to freeing this object */ u16 iDepth; /* Nesting depth */ u8 nErr; /* Number of errors seen */ u8 oom; /* Set to true if out of memory */ + u8 bJsonIsRCStr; /* True if zJson is an RCStr */ u8 hasNonstd; /* True if input uses non-standard features like JSON5 */ + u8 useMod; /* Actually use the edits contain inside aNode */ + u8 hasMod; /* aNode contains edits from the original zJson */ + u32 nJPRef; /* Number of references to this object */ int nJson; /* Length of the zJson string in bytes */ + int nAlt; /* Length of alternative JSON string zAlt, in bytes */ u32 iErr; /* Error location in zJson[] */ - u32 iHold; /* Replace cache line with the lowest iHold value */ + u32 iSubst; /* Last JSON_SUBST entry in aNode[] */ + u32 iHold; /* Age of this entry in the cache for LRU replacement */ }; /* @@ -170,17 +242,15 @@ jsonZero(p); } - /* Free all allocated memory and reset the JsonString object back to its ** initial state. */ static void jsonReset(JsonString *p){ - if( !p->bStatic ) sqlite3_free(p->zBuf); + if( !p->bStatic ) sqlite3RCStrUnref(p->zBuf); jsonZero(p); } - -/* Report an out-of-memory (OOM) condition +/* Report an out-of-memory (OOM) condition */ static void jsonOom(JsonString *p){ p->bErr = 1; @@ -196,7 +266,7 @@ char *zNew; if( p->bStatic ){ if( p->bErr ) return 1; - zNew = sqlite3_malloc64(nTotal); + zNew = sqlite3RCStrNew(nTotal); if( zNew==0 ){ jsonOom(p); return SQLITE_NOMEM; @@ -205,12 +275,12 @@ p->zBuf = zNew; p->bStatic = 0; }else{ - zNew = sqlite3_realloc64(p->zBuf, nTotal); - if( zNew==0 ){ - jsonOom(p); + p->zBuf = sqlite3RCStrResize(p->zBuf, nTotal); + if( p->zBuf==0 ){ + p->bErr = 1; + jsonZero(p); return SQLITE_NOMEM; } - p->zBuf = zNew; } p->nAlloc = nTotal; return SQLITE_OK; @@ -218,12 +288,35 @@ /* Append N bytes from zIn onto the end of the JsonString string. */ -static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ - if( N==0 ) return; - if( (N+p->nUsed >= p->nAlloc) && jsonGrow(p,N)!=0 ) return; +static SQLITE_NOINLINE void jsonAppendExpand( + JsonString *p, + const char *zIn, + u32 N +){ + assert( N>0 ); + if( jsonGrow(p,N) ) return; memcpy(p->zBuf+p->nUsed, zIn, N); p->nUsed += N; } +static void jsonAppendRaw(JsonString *p, const char *zIn, u32 N){ + if( N==0 ) return; + if( N+p->nUsed >= p->nAlloc ){ + jsonAppendExpand(p,zIn,N); + }else{ + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; + } +} +static void jsonAppendRawNZ(JsonString *p, const char *zIn, u32 N){ + assert( N>0 ); + if( N+p->nUsed >= p->nAlloc ){ + jsonAppendExpand(p,zIn,N); + }else{ + memcpy(p->zBuf+p->nUsed, zIn, N); + p->nUsed += N; + } +} + /* Append formatted text (not to exceed N bytes) to the JsonString. */ @@ -238,10 +331,35 @@ /* Append a single character */ -static void jsonAppendChar(JsonString *p, char c){ - if( p->nUsed>=p->nAlloc && jsonGrow(p,1)!=0 ) return; +static SQLITE_NOINLINE void jsonAppendCharExpand(JsonString *p, char c){ + if( jsonGrow(p,1) ) return; p->zBuf[p->nUsed++] = c; } +static void jsonAppendChar(JsonString *p, char c){ + if( p->nUsed>=p->nAlloc ){ + jsonAppendCharExpand(p,c); + }else{ + p->zBuf[p->nUsed++] = c; + } +} + +/* Try to force the string to be a zero-terminated RCStr string. +** +** Return true on success. Return false if an OOM prevents this +** from happening. +*/ +static int jsonForceRCStr(JsonString *p){ + jsonAppendChar(p, 0); + if( p->bErr ) return 0; + p->nUsed--; + if( p->bStatic==0 ) return 1; + p->nAlloc = 0; + p->nUsed++; + jsonGrow(p, p->nUsed); + p->nUsed--; + return p->bStatic==0; +} + /* Append a comma separator to the output buffer, if the previous ** character is not '[' or '{'. @@ -250,7 +368,8 @@ char c; if( p->nUsed==0 ) return; c = p->zBuf[p->nUsed-1]; - if( c!='[' && c!='{' ) jsonAppendChar(p, ','); + if( c=='[' || c=='{' ) return; + jsonAppendChar(p, ','); } /* Append the N-byte string in zIn to the end of the JsonString string @@ -264,11 +383,16 @@ p->zBuf[p->nUsed++] = '"'; for(i=0; izBuf[p->nUsed++] = c; + }else if( c=='"' || c=='\\' ){ json_simple_escape: if( (p->nUsed+N+3-i > p->nAlloc) && jsonGrow(p,N+3-i)!=0 ) return; p->zBuf[p->nUsed++] = '\\'; - }else if( c<=0x1f ){ + p->zBuf[p->nUsed++] = c; + }else if( c=='\'' ){ + p->zBuf[p->nUsed++] = c; + }else{ static const char aSpecial[] = { 0, 0, 0, 0, 0, 0, 0, 0, 'b', 't', 'n', 0, 'f', 'r', 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 @@ -279,6 +403,7 @@ assert( aSpecial['\n']=='n' ); assert( aSpecial['\r']=='r' ); assert( aSpecial['\t']=='t' ); + assert( c>=0 && czBuf[p->nUsed++] = 'u'; p->zBuf[p->nUsed++] = '0'; p->zBuf[p->nUsed++] = '0'; - p->zBuf[p->nUsed++] = '0' + (c>>4); - c = "0123456789abcdef"[c&0xf]; + p->zBuf[p->nUsed++] = "0123456789abcdef"[c>>4]; + p->zBuf[p->nUsed++] = "0123456789abcdef"[c&0xf]; } - p->zBuf[p->nUsed++] = c; } p->zBuf[p->nUsed++] = '"'; assert( p->nUsednAlloc ); @@ -310,10 +434,10 @@ while( N>0 ){ for(i=0; i0 ){ - jsonAppendRaw(p, zIn, i); + jsonAppendRawNZ(p, zIn, i); zIn += i; N -= i; - if( N==0 ) break; + if( N==0 ) break; } assert( zIn[0]=='\\' ); switch( (u8)zIn[1] ){ @@ -321,16 +445,16 @@ jsonAppendChar(p, '\''); break; case 'v': - jsonAppendRaw(p, "\\u0009", 6); + jsonAppendRawNZ(p, "\\u0009", 6); break; case 'x': - jsonAppendRaw(p, "\\u00", 4); - jsonAppendRaw(p, &zIn[2], 2); + jsonAppendRawNZ(p, "\\u00", 4); + jsonAppendRawNZ(p, &zIn[2], 2); zIn += 2; N -= 2; break; case '0': - jsonAppendRaw(p, "\\u0000", 6); + jsonAppendRawNZ(p, "\\u0000", 6); break; case '\r': if( zIn[2]=='\n' ){ @@ -348,7 +472,7 @@ N -= 2; break; default: - jsonAppendRaw(p, zIn, 2); + jsonAppendRawNZ(p, zIn, 2); break; } zIn += 2; @@ -378,11 +502,12 @@ jsonPrintf(100,p,"%lld",i); }else{ assert( rc==2 ); - jsonAppendRaw(p, "9.0e999", 7); + jsonAppendRawNZ(p, "9.0e999", 7); } return; } - jsonAppendRaw(p, zIn, N); + assert( N>0 ); + jsonAppendRawNZ(p, zIn, N); } /* @@ -414,14 +539,14 @@ } } if( N>0 ){ - jsonAppendRaw(p, zIn, N); + jsonAppendRawNZ(p, zIn, N); } } /* -** Append a function parameter value to the JSON string under +** Append a function parameter value to the JSON string under ** construction. */ static void jsonAppendValue( @@ -430,7 +555,7 @@ ){ switch( sqlite3_value_type(pValue) ){ case SQLITE_NULL: { - jsonAppendRaw(p, "null", 4); + jsonAppendRawNZ(p, "null", 4); break; } case SQLITE_FLOAT: { @@ -466,15 +591,25 @@ /* Make the JSON in p the result of the SQL function. +** +** The JSON string is reset. */ static void jsonResult(JsonString *p){ if( p->bErr==0 ){ - sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, - p->bStatic ? SQLITE_TRANSIENT : sqlite3_free, - SQLITE_UTF8); - jsonZero(p); + if( p->bStatic ){ + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + SQLITE_TRANSIENT, SQLITE_UTF8); + }else if( jsonForceRCStr(p) ){ + sqlite3RCStrRef(p->zBuf); + sqlite3_result_text64(p->pCtx, p->zBuf, p->nUsed, + sqlite3RCStrUnref, + SQLITE_UTF8); + } } - assert( p->bStatic ); + if( p->bErr==1 ){ + sqlite3_result_error_nomem(p->pCtx); + } + jsonReset(p); } /************************************************************************** @@ -499,20 +634,73 @@ ** delete the JsonParse object itself. */ static void jsonParseReset(JsonParse *pParse){ - sqlite3_free(pParse->aNode); - pParse->aNode = 0; + while( pParse->pClup ){ + JsonCleanup *pTask = pParse->pClup; + pParse->pClup = pTask->pJCNext; + pTask->xOp(pTask->pArg); + sqlite3_free(pTask); + } + assert( pParse->nJPRef<=1 ); + if( pParse->aNode ){ + sqlite3_free(pParse->aNode); + pParse->aNode = 0; + } pParse->nNode = 0; pParse->nAlloc = 0; - sqlite3_free(pParse->aUp); - pParse->aUp = 0; + if( pParse->aUp ){ + sqlite3_free(pParse->aUp); + pParse->aUp = 0; + } + if( pParse->bJsonIsRCStr ){ + sqlite3RCStrUnref(pParse->zJson); + pParse->zJson = 0; + pParse->bJsonIsRCStr = 0; + } + if( pParse->zAlt ){ + sqlite3RCStrUnref(pParse->zAlt); + pParse->zAlt = 0; + } } /* ** Free a JsonParse object that was obtained from sqlite3_malloc(). +** +** Note that destroying JsonParse might call sqlite3RCStrUnref() to +** destroy the zJson value. The RCStr object might recursively invoke +** JsonParse to destroy this pParse object again. Take care to ensure +** that this recursive destructor sequence terminates harmlessly. */ static void jsonParseFree(JsonParse *pParse){ - jsonParseReset(pParse); - sqlite3_free(pParse); + if( pParse->nJPRef>1 ){ + pParse->nJPRef--; + }else{ + jsonParseReset(pParse); + sqlite3_free(pParse); + } +} + +/* +** Add a cleanup task to the JsonParse object. +** +** If an OOM occurs, the cleanup operation happens immediately +** and this function returns SQLITE_NOMEM. +*/ +static int jsonParseAddCleanup( + JsonParse *pParse, /* Add the cleanup task to this parser */ + void(*xOp)(void*), /* The cleanup task */ + void *pArg /* Argument to the cleanup */ +){ + JsonCleanup *pTask = sqlite3_malloc64( sizeof(*pTask) ); + if( pTask==0 ){ + pParse->oom = 1; + xOp(pArg); + return SQLITE_ERROR; + } + pTask->pJCNext = pParse->pClup; + pParse->pClup = pTask; + pTask->xOp = xOp; + pTask->pArg = pArg; + return SQLITE_OK; } /* @@ -521,32 +709,38 @@ ** the number of JsonNode objects that are encoded. */ static void jsonRenderNode( + JsonParse *pParse, /* the complete parse of the JSON */ JsonNode *pNode, /* The node to render */ - JsonString *pOut, /* Write JSON here */ - sqlite3_value **aReplace /* Replacement values */ + JsonString *pOut /* Write JSON here */ ){ assert( pNode!=0 ); - if( pNode->jnFlags & (JNODE_REPLACE|JNODE_PATCH) ){ - if( (pNode->jnFlags & JNODE_REPLACE)!=0 && ALWAYS(aReplace!=0) ){ - assert( pNode->eU==4 ); - jsonAppendValue(pOut, aReplace[pNode->u.iReplace]); - return; + while( (pNode->jnFlags & JNODE_REPLACE)!=0 && pParse->useMod ){ + u32 idx = (u32)(pNode - pParse->aNode); + u32 i = pParse->iSubst; + while( 1 /*exit-by-break*/ ){ + assert( inNode ); + assert( pParse->aNode[i].eType==JSON_SUBST ); + assert( pParse->aNode[i].eU==4 ); + assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ + pNode = &pParse->aNode[i+1]; + break; + } + i = pParse->aNode[i].u.iPrev; } - assert( pNode->eU==5 ); - pNode = pNode->u.pPatch; } switch( pNode->eType ){ default: { assert( pNode->eType==JSON_NULL ); - jsonAppendRaw(pOut, "null", 4); + jsonAppendRawNZ(pOut, "null", 4); break; } case JSON_TRUE: { - jsonAppendRaw(pOut, "true", 4); + jsonAppendRawNZ(pOut, "true", 4); break; } case JSON_FALSE: { - jsonAppendRaw(pOut, "false", 5); + jsonAppendRawNZ(pOut, "false", 5); break; } case JSON_STRING: { @@ -562,7 +756,8 @@ }else if( pNode->jnFlags & JNODE_JSON5 ){ jsonAppendNormalizedString(pOut, pNode->u.zJContent, pNode->n); }else{ - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); + assert( pNode->n>0 ); + jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); } break; } @@ -571,7 +766,8 @@ if( pNode->jnFlags & JNODE_JSON5 ){ jsonAppendNormalizedReal(pOut, pNode->u.zJContent, pNode->n); }else{ - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); + assert( pNode->n>0 ); + jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); } break; } @@ -580,7 +776,8 @@ if( pNode->jnFlags & JNODE_JSON5 ){ jsonAppendNormalizedInt(pOut, pNode->u.zJContent, pNode->n); }else{ - jsonAppendRaw(pOut, pNode->u.zJContent, pNode->n); + assert( pNode->n>0 ); + jsonAppendRawNZ(pOut, pNode->u.zJContent, pNode->n); } break; } @@ -589,15 +786,16 @@ jsonAppendChar(pOut, '['); for(;;){ while( j<=pNode->n ){ - if( (pNode[j].jnFlags & JNODE_REMOVE)==0 ){ + if( (pNode[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ jsonAppendSeparator(pOut); - jsonRenderNode(&pNode[j], pOut, aReplace); + jsonRenderNode(pParse, &pNode[j], pOut); } j += jsonNodeSize(&pNode[j]); } if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + if( pParse->useMod==0 ) break; assert( pNode->eU==2 ); - pNode = &pNode[pNode->u.iAppend]; + pNode = &pParse->aNode[pNode->u.iAppend]; j = 1; } jsonAppendChar(pOut, ']'); @@ -608,17 +806,18 @@ jsonAppendChar(pOut, '{'); for(;;){ while( j<=pNode->n ){ - if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 ){ + if( (pNode[j+1].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ){ jsonAppendSeparator(pOut); - jsonRenderNode(&pNode[j], pOut, aReplace); + jsonRenderNode(pParse, &pNode[j], pOut); jsonAppendChar(pOut, ':'); - jsonRenderNode(&pNode[j+1], pOut, aReplace); + jsonRenderNode(pParse, &pNode[j+1], pOut); } j += 1 + jsonNodeSize(&pNode[j+1]); } if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + if( pParse->useMod==0 ) break; assert( pNode->eU==2 ); - pNode = &pNode[pNode->u.iAppend]; + pNode = &pParse->aNode[pNode->u.iAppend]; j = 1; } jsonAppendChar(pOut, '}'); @@ -628,18 +827,29 @@ } /* -** Return a JsonNode and all its descendents as a JSON string. +** Return a JsonNode and all its descendants as a JSON string. */ static void jsonReturnJson( + JsonParse *pParse, /* The complete JSON */ JsonNode *pNode, /* Node to return */ sqlite3_context *pCtx, /* Return value for this function */ - sqlite3_value **aReplace /* Array of replacement values */ + int bGenerateAlt /* Also store the rendered text in zAlt */ ){ JsonString s; - jsonInit(&s, pCtx); - jsonRenderNode(pNode, &s, aReplace); - jsonResult(&s); - sqlite3_result_subtype(pCtx, JSON_SUBTYPE); + if( pParse->oom ){ + sqlite3_result_error_nomem(pCtx); + return; + } + if( pParse->nErr==0 ){ + jsonInit(&s, pCtx); + jsonRenderNode(pParse, pNode, &s); + if( bGenerateAlt && pParse->zAlt==0 && jsonForceRCStr(&s) ){ + pParse->zAlt = sqlite3RCStrRef(s.zBuf); + pParse->nAlt = s.nUsed; + } + jsonResult(&s); + sqlite3_result_subtype(pCtx, JSON_SUBTYPE); + } } /* @@ -677,9 +887,9 @@ ** Make the JsonNode the return value of the function. */ static void jsonReturn( + JsonParse *pParse, /* Complete JSON parse tree */ JsonNode *pNode, /* Node to return */ - sqlite3_context *pCtx, /* Return value for this function */ - sqlite3_value **aReplace /* Array of replacement values */ + sqlite3_context *pCtx /* Return value for this function */ ){ switch( pNode->eType ){ default: { @@ -700,8 +910,7 @@ int rc; int bNeg = 0; const char *z; - - + assert( pNode->eU==1 ); z = pNode->u.zJContent; if( z[0]=='-' ){ z++; bNeg = 1; } @@ -826,7 +1035,7 @@ } case JSON_ARRAY: case JSON_OBJECT: { - jsonReturnJson(pNode, pCtx, aReplace); + jsonReturnJson(pParse, pNode, pCtx, 0); break; } } @@ -848,6 +1057,12 @@ #endif +/* +** Add a single node to pParse->aNode after first expanding the +** size of the aNode array. Return the index of the new node. +** +** If an OOM error occurs, set pParse->oom and return -1. +*/ static JSON_NOINLINE int jsonParseAddNodeExpand( JsonParse *pParse, /* Append the node to this object */ u32 eType, /* Node type */ @@ -864,7 +1079,7 @@ pParse->oom = 1; return -1; } - pParse->nAlloc = nNew; + pParse->nAlloc = sqlite3_msize(pNew)/sizeof(JsonNode); pParse->aNode = pNew; assert( pParse->nNodenAlloc ); return jsonParseAddNode(pParse, eType, n, zContent); @@ -882,10 +1097,13 @@ const char *zContent /* Content */ ){ JsonNode *p; - if( pParse->aNode==0 || pParse->nNode>=pParse->nAlloc ){ + assert( pParse->aNode!=0 || pParse->nNode>=pParse->nAlloc ); + if( pParse->nNode>=pParse->nAlloc ){ return jsonParseAddNodeExpand(pParse, eType, n, zContent); } + assert( pParse->aNode!=0 ); p = &pParse->aNode[pParse->nNode]; + assert( p!=0 ); p->eType = (u8)(eType & 0xff); p->jnFlags = (u8)(eType >> 8); VVA( p->eU = zContent ? 1 : 0 ); @@ -895,6 +1113,52 @@ } /* +** Add an array of new nodes to the current pParse->aNode array. +** Return the index of the first node added. +** +** If an OOM error occurs, set pParse->oom. +*/ +static void jsonParseAddNodeArray( + JsonParse *pParse, /* Append the node to this object */ + JsonNode *aNode, /* Array of nodes to add */ + u32 nNode /* Number of elements in aNew */ +){ + assert( aNode!=0 ); + assert( nNode>=1 ); + if( pParse->nNode + nNode > pParse->nAlloc ){ + u32 nNew = pParse->nNode + nNode; + JsonNode *aNew = sqlite3_realloc64(pParse->aNode, nNew*sizeof(JsonNode)); + if( aNew==0 ){ + pParse->oom = 1; + return; + } + pParse->nAlloc = sqlite3_msize(aNew)/sizeof(JsonNode); + pParse->aNode = aNew; + } + memcpy(&pParse->aNode[pParse->nNode], aNode, nNode*sizeof(JsonNode)); + pParse->nNode += nNode; +} + +/* +** Add a new JSON_SUBST node. The node immediately following +** this new node will be the substitute content for iNode. +*/ +static int jsonParseAddSubstNode( + JsonParse *pParse, /* Add the JSON_SUBST here */ + u32 iNode /* References this node */ +){ + int idx = jsonParseAddNode(pParse, JSON_SUBST, iNode, 0); + if( pParse->oom ) return -1; + pParse->aNode[iNode].jnFlags |= JNODE_REPLACE; + pParse->aNode[idx].eU = 4; + pParse->aNode[idx].u.iPrev = pParse->iSubst; + pParse->iSubst = idx; + pParse->hasMod = 1; + pParse->useMod = 1; + return idx; +} + +/* ** Return true if z[] begins with 2 (or more) hexadecimal digits */ static int jsonIs2Hex(const char *z){ @@ -1060,7 +1324,7 @@ ** ** Special return values: ** -** 0 End if input +** 0 End of input ** -1 Syntax error ** -2 '}' seen ** -3 ']' seen @@ -1235,15 +1499,12 @@ jnFlags = 0; parse_string: cDelim = z[i]; - j = i+1; - for(;;){ + for(j=i+1; 1; j++){ + if( jsonIsOk[(unsigned char)z[j]] ) continue; c = z[j]; - if( (c & ~0x1f)==0 ){ - /* Control characters are not allowed in strings */ - pParse->iErr = j; - return -1; - } - if( c=='\\' ){ + if( c==cDelim ){ + break; + }else if( c=='\\' ){ c = z[++j]; if( c=='"' || c=='\\' || c=='/' || c=='b' || c=='f' || c=='n' || c=='r' || c=='t' @@ -1263,10 +1524,11 @@ pParse->iErr = j; return -1; } - }else if( c==cDelim ){ - break; + }else if( c<=0x1f ){ + /* Control characters are not allowed in strings */ + pParse->iErr = j; + return -1; } - j++; } jsonParseAddNode(pParse, JSON_STRING | (jnFlags<<8), j+1-i, &z[i]); return j+1; @@ -1502,20 +1764,18 @@ /* ** Parse a complete JSON string. Return 0 on success or non-zero if there -** are any errors. If an error occurs, free all memory associated with -** pParse. +** are any errors. If an error occurs, free all memory held by pParse, +** but not pParse itself. ** -** pParse is uninitialized when this routine is called. +** pParse must be initialized to an empty parse object prior to calling +** this routine. */ static int jsonParse( JsonParse *pParse, /* Initialize and fill this JsonParse object */ - sqlite3_context *pCtx, /* Report errors here */ - const char *zJson /* Input JSON text to be parsed */ + sqlite3_context *pCtx /* Report errors here */ ){ int i; - memset(pParse, 0, sizeof(*pParse)); - if( zJson==0 ) return 1; - pParse->zJson = zJson; + const char *zJson = pParse->zJson; i = jsonParseValue(pParse, 0); if( pParse->oom ) i = -1; if( i>0 ){ @@ -1544,6 +1804,7 @@ return 0; } + /* Mark node i of pParse as being a child of iParent. Call recursively ** to fill in all the descendants of node i. */ @@ -1593,35 +1854,49 @@ #define JSON_CACHE_SZ 4 /* Max number of cache entries */ /* -** Obtain a complete parse of the JSON found in the first argument -** of the argv array. Use the sqlite3_get_auxdata() cache for this -** parse if it is available. If the cache is not available or if it -** is no longer valid, parse the JSON again and return the new parse, -** and also register the new parse so that it will be available for +** Obtain a complete parse of the JSON found in the pJson argument +** +** Use the sqlite3_get_auxdata() cache to find a preexisting parse +** if it is available. If the cache is not available or if it +** is no longer valid, parse the JSON again and return the new parse. +** Also register the new parse so that it will be available for ** future sqlite3_get_auxdata() calls. ** ** If an error occurs and pErrCtx!=0 then report the error on pErrCtx ** and return NULL. ** -** If an error occurs and pErrCtx==0 then return the Parse object with -** JsonParse.nErr non-zero. If the caller invokes this routine with -** pErrCtx==0 and it gets back a JsonParse with nErr!=0, then the caller -** is responsible for invoking jsonParseFree() on the returned value. -** But the caller may invoke jsonParseFree() *only* if pParse->nErr!=0. +** The returned pointer (if it is not NULL) is owned by the cache in +** most cases, not the caller. The caller does NOT need to invoke +** jsonParseFree(), in most cases. +** +** Except, if an error occurs and pErrCtx==0 then return the JsonParse +** object with JsonParse.nErr non-zero and the caller will own the JsonParse +** object. In that case, it will be the responsibility of the caller to +** invoke jsonParseFree(). To summarize: +** +** pErrCtx!=0 || p->nErr==0 ==> Return value p is owned by the +** cache. Call does not need to +** free it. +** +** pErrCtx==0 && p->nErr!=0 ==> Return value is owned by the caller +** and so the caller must free it. */ static JsonParse *jsonParseCached( - sqlite3_context *pCtx, - sqlite3_value **argv, - sqlite3_context *pErrCtx + sqlite3_context *pCtx, /* Context to use for cache search */ + sqlite3_value *pJson, /* Function param containing JSON text */ + sqlite3_context *pErrCtx, /* Write parse errors here if not NULL */ + int bUnedited /* No prior edits allowed */ ){ - const char *zJson = (const char*)sqlite3_value_text(argv[0]); - int nJson = sqlite3_value_bytes(argv[0]); + char *zJson = (char*)sqlite3_value_text(pJson); + int nJson = sqlite3_value_bytes(pJson); JsonParse *p; JsonParse *pMatch = 0; int iKey; int iMinKey = 0; u32 iMinHold = 0xffffffff; u32 iMaxHold = 0; + int bJsonRCStr; + if( zJson==0 ) return 0; for(iKey=0; iKeynJson==nJson - && memcmp(p->zJson,zJson,nJson)==0 + && (p->hasMod==0 || bUnedited==0) + && (p->zJson==zJson || memcmp(p->zJson,zJson,nJson)==0) + ){ + p->nErr = 0; + p->useMod = 0; + pMatch = p; + }else + if( pMatch==0 + && p->zAlt!=0 + && bUnedited==0 + && p->nAlt==nJson + && memcmp(p->zAlt, zJson, nJson)==0 ){ p->nErr = 0; + p->useMod = 1; pMatch = p; }else if( p->iHoldiHold; @@ -1644,28 +1931,44 @@ } } if( pMatch ){ + /* The input JSON text was found in the cache. Use the preexisting + ** parse of this JSON */ pMatch->nErr = 0; pMatch->iHold = iMaxHold+1; + assert( pMatch->nJPRef>0 ); /* pMatch is owned by the cache */ return pMatch; } - p = sqlite3_malloc64( sizeof(*p) + nJson + 1 ); + + /* The input JSON was not found anywhere in the cache. We will need + ** to parse it ourselves and generate a new JsonParse object. + */ + bJsonRCStr = sqlite3ValueIsOfClass(pJson,sqlite3RCStrUnref); + p = sqlite3_malloc64( sizeof(*p) + (bJsonRCStr ? 0 : nJson+1) ); if( p==0 ){ sqlite3_result_error_nomem(pCtx); return 0; } memset(p, 0, sizeof(*p)); - p->zJson = (char*)&p[1]; - memcpy((char*)p->zJson, zJson, nJson+1); - if( jsonParse(p, pErrCtx, p->zJson) ){ + if( bJsonRCStr ){ + p->zJson = sqlite3RCStrRef(zJson); + p->bJsonIsRCStr = 1; + }else{ + p->zJson = (char*)&p[1]; + memcpy(p->zJson, zJson, nJson+1); + } + p->nJPRef = 1; + if( jsonParse(p, pErrCtx) ){ if( pErrCtx==0 ){ p->nErr = 1; + assert( p->nJPRef==1 ); /* Caller will own the new JsonParse object p */ return p; } - sqlite3_free(p); + jsonParseFree(p); return 0; } p->nJson = nJson; p->iHold = iMaxHold+1; + /* Transfer ownership of the new JsonParse to the cache */ sqlite3_set_auxdata(pCtx, JSON_CACHE_ID+iMinKey, p, (void(*)(void*))jsonParseFree); return (JsonParse*)sqlite3_get_auxdata(pCtx, JSON_CACHE_ID+iMinKey); @@ -1716,9 +2019,31 @@ ){ u32 i, j, nKey; const char *zKey; - JsonNode *pRoot = &pParse->aNode[iRoot]; + JsonNode *pRoot; + if( pParse->oom ) return 0; + pRoot = &pParse->aNode[iRoot]; + if( pRoot->jnFlags & (JNODE_REPLACE|JNODE_REMOVE) && pParse->useMod ){ + while( (pRoot->jnFlags & JNODE_REPLACE)!=0 ){ + u32 idx = (u32)(pRoot - pParse->aNode); + i = pParse->iSubst; + while( 1 /*exit-by-break*/ ){ + assert( inNode ); + assert( pParse->aNode[i].eType==JSON_SUBST ); + assert( pParse->aNode[i].eU==4 ); + assert( pParse->aNode[i].u.iPrevaNode[i].n==idx ){ + pRoot = &pParse->aNode[i+1]; + iRoot = i+1; + break; + } + i = pParse->aNode[i].u.iPrev; + } + } + if( pRoot->jnFlags & JNODE_REMOVE ){ + return 0; + } + } if( zPath[0]==0 ) return pRoot; - if( pRoot->jnFlags & JNODE_REPLACE ) return 0; if( zPath[0]=='.' ){ if( pRoot->eType!=JSON_OBJECT ) return 0; zPath++; @@ -1752,14 +2077,16 @@ j += jsonNodeSize(&pRoot[j]); } if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + if( pParse->useMod==0 ) break; assert( pRoot->eU==2 ); - iRoot += pRoot->u.iAppend; + iRoot = pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; j = 1; } if( pApnd ){ u32 iStart, iLabel; JsonNode *pNode; + assert( pParse->useMod ); iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); iLabel = jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); zPath += i; @@ -1768,7 +2095,7 @@ if( pNode ){ pRoot = &pParse->aNode[iRoot]; assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart - iRoot; + pRoot->u.iAppend = iStart; pRoot->jnFlags |= JNODE_APPEND; VVA( pRoot->eU = 2 ); pParse->aNode[iLabel].jnFlags |= JNODE_RAW; @@ -1789,12 +2116,13 @@ if( pRoot->eType!=JSON_ARRAY ) return 0; for(;;){ while( j<=pBase->n ){ - if( (pBase[j].jnFlags & JNODE_REMOVE)==0 ) i++; + if( (pBase[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i++; j += jsonNodeSize(&pBase[j]); } if( (pBase->jnFlags & JNODE_APPEND)==0 ) break; + if( pParse->useMod==0 ) break; assert( pBase->eU==2 ); - iBase += pBase->u.iAppend; + iBase = pBase->u.iAppend; pBase = &pParse->aNode[iBase]; j = 1; } @@ -1822,13 +2150,17 @@ zPath += j + 1; j = 1; for(;;){ - while( j<=pRoot->n && (i>0 || (pRoot[j].jnFlags & JNODE_REMOVE)!=0) ){ - if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 ) i--; + while( j<=pRoot->n + && (i>0 || ((pRoot[j].jnFlags & JNODE_REMOVE)!=0 && pParse->useMod)) + ){ + if( (pRoot[j].jnFlags & JNODE_REMOVE)==0 || pParse->useMod==0 ) i--; j += jsonNodeSize(&pRoot[j]); } + if( i==0 && j<=pRoot->n ) break; if( (pRoot->jnFlags & JNODE_APPEND)==0 ) break; + if( pParse->useMod==0 ) break; assert( pRoot->eU==2 ); - iRoot += pRoot->u.iAppend; + iRoot = pRoot->u.iAppend; pRoot = &pParse->aNode[iRoot]; j = 1; } @@ -1838,13 +2170,14 @@ if( i==0 && pApnd ){ u32 iStart; JsonNode *pNode; + assert( pParse->useMod ); iStart = jsonParseAddNode(pParse, JSON_ARRAY, 1, 0); pNode = jsonLookupAppend(pParse, zPath, pApnd, pzErr); if( pParse->oom ) return 0; if( pNode ){ pRoot = &pParse->aNode[iRoot]; assert( pRoot->eU==0 ); - pRoot->u.iAppend = iStart - iRoot; + pRoot->u.iAppend = iStart; pRoot->jnFlags |= JNODE_APPEND; VVA( pRoot->eU = 2 ); } @@ -1944,7 +2277,7 @@ char *zMsg = sqlite3_mprintf("json_%s() needs an odd number of arguments", zFuncName); sqlite3_result_error(pCtx, zMsg, -1); - sqlite3_free(zMsg); + sqlite3_free(zMsg); } /* @@ -1971,47 +2304,90 @@ ** SQL functions used for testing and debugging ****************************************************************************/ +#if SQLITE_DEBUG +/* +** Print N node entries. +*/ +static void jsonDebugPrintNodeEntries( + JsonNode *aNode, /* First node entry to print */ + int N /* Number of node entries to print */ +){ + int i; + for(i=0; iaNode, p->nNode); +} +static void jsonDebugPrintNode(JsonNode *pNode){ + jsonDebugPrintNodeEntries(pNode, jsonNodeSize(pNode)); +} +#else + /* The usual case */ +# define jsonDebugPrintNode(X) +# define jsonDebugPrintParse(X) +#endif + #ifdef SQLITE_DEBUG /* -** The json_parse(JSON) function returns a string which describes -** a parse of the JSON provided. Or it returns NULL if JSON is not -** well-formed. +** SQL function: json_parse(JSON) +** +** Parse JSON using jsonParseCached(). Then print a dump of that +** parse on standard output. Return the mimified JSON result, just +** like the json() function. */ static void jsonParseFunc( sqlite3_context *ctx, int argc, sqlite3_value **argv ){ - JsonString s; /* Output string - not real JSON */ - JsonParse x; /* The parse */ - u32 i; + JsonParse *p; /* The parse */ assert( argc==1 ); - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - jsonParseFindParents(&x); - jsonInit(&s, ctx); - for(i=0; inNode); + printf("nAlloc = %u\n", p->nAlloc); + printf("nJson = %d\n", p->nJson); + printf("nAlt = %d\n", p->nAlt); + printf("nErr = %u\n", p->nErr); + printf("oom = %u\n", p->oom); + printf("hasNonstd = %u\n", p->hasNonstd); + printf("useMod = %u\n", p->useMod); + printf("hasMod = %u\n", p->hasMod); + printf("nJPRef = %u\n", p->nJPRef); + printf("iSubst = %u\n", p->iSubst); + printf("iHold = %u\n", p->iHold); + jsonDebugPrintNodeEntries(p->aNode, p->nNode); + jsonReturnJson(p, p->aNode, ctx, 1); } /* @@ -2035,7 +2411,7 @@ /* ** Implementation of the json_QUOTE(VALUE) function. Return a JSON value -** corresponding to the SQL value input. Mostly this means putting +** corresponding to the SQL value input. Mostly this means putting ** double-quotes around strings and returning the unquoted string "null" ** when given a NULL input. */ @@ -2082,7 +2458,7 @@ ** json_array_length(JSON) ** json_array_length(JSON, PATH) ** -** Return the number of elements in the top-level JSON array. +** Return the number of elements in the top-level JSON array. ** Return 0 if the input is not a well-formed JSON array. */ static void jsonArrayLengthFunc( @@ -2095,7 +2471,7 @@ u32 i; JsonNode *pNode; - p = jsonParseCached(ctx, argv, ctx); + p = jsonParseCached(ctx, argv[0], ctx, 0); if( p==0 ) return; assert( p->nNode ); if( argc==2 ){ @@ -2108,9 +2484,16 @@ return; } if( pNode->eType==JSON_ARRAY ){ - assert( (pNode->jnFlags & JNODE_APPEND)==0 ); - for(i=1; i<=pNode->n; n++){ - i += jsonNodeSize(&pNode[i]); + while( 1 /*exit-by-break*/ ){ + i = 1; + while( i<=pNode->n ){ + if( (pNode[i].jnFlags & JNODE_REMOVE)==0 ) n++; + i += jsonNodeSize(&pNode[i]); + } + if( (pNode->jnFlags & JNODE_APPEND)==0 ) break; + if( p->useMod==0 ) break; + assert( pNode->eU==2 ); + pNode = &p->aNode[pNode->u.iAppend]; } } sqlite3_result_int64(ctx, n); @@ -2157,7 +2540,7 @@ JsonString jx; if( argc<2 ) return; - p = jsonParseCached(ctx, argv, ctx); + p = jsonParseCached(ctx, argv[0], ctx, 0); if( p==0 ) return; if( argc==2 ){ /* With a single PATH argument */ @@ -2175,11 +2558,11 @@ */ jsonInit(&jx, ctx); if( sqlite3Isdigit(zPath[0]) ){ - jsonAppendRaw(&jx, "$[", 2); + jsonAppendRawNZ(&jx, "$[", 2); jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); - jsonAppendRaw(&jx, "]", 2); + jsonAppendRawNZ(&jx, "]", 2); }else{ - jsonAppendRaw(&jx, "$.", 1 + (zPath[0]!='[')); + jsonAppendRawNZ(&jx, "$.", 1 + (zPath[0]!='[')); jsonAppendRaw(&jx, zPath, (int)strlen(zPath)); jsonAppendChar(&jx, 0); } @@ -2190,15 +2573,15 @@ } if( pNode ){ if( flags & JSON_JSON ){ - jsonReturnJson(pNode, ctx, 0); + jsonReturnJson(p, pNode, ctx, 0); }else{ - jsonReturn(pNode, ctx, 0); + jsonReturn(p, pNode, ctx); sqlite3_result_subtype(ctx, 0); } } }else{ pNode = jsonLookup(p, zPath, 0, ctx); - if( p->nErr==0 && pNode ) jsonReturn(pNode, ctx, 0); + if( p->nErr==0 && pNode ) jsonReturn(p, pNode, ctx); } }else{ /* Two or more PATH arguments results in a JSON array with each @@ -2212,9 +2595,9 @@ if( p->nErr ) break; jsonAppendSeparator(&jx); if( pNode ){ - jsonRenderNode(pNode, &jx, 0); + jsonRenderNode(p, pNode, &jx); }else{ - jsonAppendRaw(&jx, "null", 4); + jsonAppendRawNZ(&jx, "null", 4); } } if( i==argc ){ @@ -2259,45 +2642,38 @@ assert( pTarget[j].eType==JSON_STRING ); assert( pTarget[j].jnFlags & JNODE_LABEL ); if( jsonSameLabel(&pPatch[i], &pTarget[j]) ){ - if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_PATCH) ) break; + if( pTarget[j+1].jnFlags & (JNODE_REMOVE|JNODE_REPLACE) ) break; if( pPatch[i+1].eType==JSON_NULL ){ pTarget[j+1].jnFlags |= JNODE_REMOVE; }else{ JsonNode *pNew = jsonMergePatch(pParse, iTarget+j+1, &pPatch[i+1]); if( pNew==0 ) return 0; - pTarget = &pParse->aNode[iTarget]; - if( pNew!=&pTarget[j+1] ){ - assert( pTarget[j+1].eU==0 - || pTarget[j+1].eU==1 - || pTarget[j+1].eU==2 ); - testcase( pTarget[j+1].eU==1 ); - testcase( pTarget[j+1].eU==2 ); - VVA( pTarget[j+1].eU = 5 ); - pTarget[j+1].u.pPatch = pNew; - pTarget[j+1].jnFlags |= JNODE_PATCH; + if( pNew!=&pParse->aNode[iTarget+j+1] ){ + jsonParseAddSubstNode(pParse, iTarget+j+1); + jsonParseAddNodeArray(pParse, pNew, jsonNodeSize(pNew)); } + pTarget = &pParse->aNode[iTarget]; } break; } } if( j>=pTarget->n && pPatch[i+1].eType!=JSON_NULL ){ - int iStart, iPatch; - iStart = jsonParseAddNode(pParse, JSON_OBJECT, 2, 0); + int iStart; + JsonNode *pApnd; + u32 nApnd; + iStart = jsonParseAddNode(pParse, JSON_OBJECT, 0, 0); jsonParseAddNode(pParse, JSON_STRING, nKey, zKey); - iPatch = jsonParseAddNode(pParse, JSON_TRUE, 0, 0); + pApnd = &pPatch[i+1]; + if( pApnd->eType==JSON_OBJECT ) jsonRemoveAllNulls(pApnd); + nApnd = jsonNodeSize(pApnd); + jsonParseAddNodeArray(pParse, pApnd, jsonNodeSize(pApnd)); if( pParse->oom ) return 0; - jsonRemoveAllNulls(pPatch); - pTarget = &pParse->aNode[iTarget]; - assert( pParse->aNode[iRoot].eU==0 || pParse->aNode[iRoot].eU==2 ); - testcase( pParse->aNode[iRoot].eU==2 ); + pParse->aNode[iStart].n = 1+nApnd; pParse->aNode[iRoot].jnFlags |= JNODE_APPEND; + pParse->aNode[iRoot].u.iAppend = iStart; VVA( pParse->aNode[iRoot].eU = 2 ); - pParse->aNode[iRoot].u.iAppend = iStart - iRoot; iRoot = iStart; - assert( pParse->aNode[iPatch].eU==0 ); - VVA( pParse->aNode[iPatch].eU = 5 ); - pParse->aNode[iPatch].jnFlags |= JNODE_PATCH; - pParse->aNode[iPatch].u.pPatch = &pPatch[i+1]; + pTarget = &pParse->aNode[iTarget]; } } return pTarget; @@ -2313,25 +2689,28 @@ int argc, sqlite3_value **argv ){ - JsonParse x; /* The JSON that is being patched */ - JsonParse y; /* The patch */ + JsonParse *pX; /* The JSON that is being patched */ + JsonParse *pY; /* The patch */ JsonNode *pResult; /* The result of the merge */ UNUSED_PARAMETER(argc); - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - if( jsonParse(&y, ctx, (const char*)sqlite3_value_text(argv[1])) ){ - jsonParseReset(&x); - return; - } - pResult = jsonMergePatch(&x, 0, y.aNode); - assert( pResult!=0 || x.oom ); - if( pResult ){ - jsonReturnJson(pResult, ctx, 0); + pX = jsonParseCached(ctx, argv[0], ctx, 1); + if( pX==0 ) return; + assert( pX->hasMod==0 ); + pX->hasMod = 1; + pY = jsonParseCached(ctx, argv[1], ctx, 1); + if( pY==0 ) return; + pX->useMod = 1; + pY->useMod = 1; + pResult = jsonMergePatch(pX, 0, pY->aNode); + assert( pResult!=0 || pX->oom ); + if( pResult && pX->oom==0 ){ + jsonDebugPrintParse(pX); + jsonDebugPrintNode(pResult); + jsonReturnJson(pX, pResult, ctx, 0); }else{ sqlite3_result_error_nomem(ctx); } - jsonParseReset(&x); - jsonParseReset(&y); } @@ -2387,26 +2766,120 @@ int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *pParse; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; if( argc<1 ) return; - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); + pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); + if( pParse==0 ) return; for(i=1; i<(u32)argc; i++){ zPath = (const char*)sqlite3_value_text(argv[i]); if( zPath==0 ) goto remove_done; - pNode = jsonLookup(&x, zPath, 0, ctx); - if( x.nErr ) goto remove_done; - if( pNode ) pNode->jnFlags |= JNODE_REMOVE; + pNode = jsonLookup(pParse, zPath, 0, ctx); + if( pParse->nErr ) goto remove_done; + if( pNode ){ + pNode->jnFlags |= JNODE_REMOVE; + pParse->hasMod = 1; + pParse->useMod = 1; + } } - if( (x.aNode[0].jnFlags & JNODE_REMOVE)==0 ){ - jsonReturnJson(x.aNode, ctx, 0); + if( (pParse->aNode[0].jnFlags & JNODE_REMOVE)==0 ){ + jsonReturnJson(pParse, pParse->aNode, ctx, 1); } remove_done: - jsonParseReset(&x); + jsonDebugPrintParse(p); +} + +/* +** Substitute the value at iNode with the pValue parameter. +*/ +static void jsonReplaceNode( + sqlite3_context *pCtx, + JsonParse *p, + int iNode, + sqlite3_value *pValue +){ + int idx = jsonParseAddSubstNode(p, iNode); + if( idx<=0 ){ + assert( p->oom ); + return; + } + switch( sqlite3_value_type(pValue) ){ + case SQLITE_NULL: { + jsonParseAddNode(p, JSON_NULL, 0, 0); + break; + } + case SQLITE_FLOAT: { + char *z = sqlite3_mprintf("%!0.15g", sqlite3_value_double(pValue)); + int n; + if( z==0 ){ + p->oom = 1; + break; + } + n = sqlite3Strlen30(z); + jsonParseAddNode(p, JSON_REAL, n, z); + jsonParseAddCleanup(p, sqlite3_free, z); + break; + } + case SQLITE_INTEGER: { + char *z = sqlite3_mprintf("%lld", sqlite3_value_int64(pValue)); + int n; + if( z==0 ){ + p->oom = 1; + break; + } + n = sqlite3Strlen30(z); + jsonParseAddNode(p, JSON_INT, n, z); + jsonParseAddCleanup(p, sqlite3_free, z); + + break; + } + case SQLITE_TEXT: { + const char *z = (const char*)sqlite3_value_text(pValue); + u32 n = (u32)sqlite3_value_bytes(pValue); + if( z==0 ){ + p->oom = 1; + break; + } + if( sqlite3_value_subtype(pValue)!=JSON_SUBTYPE ){ + char *zCopy = sqlite3_malloc64( n+1 ); + int k; + if( zCopy ){ + memcpy(zCopy, z, n); + zCopy[n] = 0; + jsonParseAddCleanup(p, sqlite3_free, zCopy); + }else{ + p->oom = 1; + sqlite3_result_error_nomem(pCtx); + } + k = jsonParseAddNode(p, JSON_STRING, n, zCopy); + assert( k>0 || p->oom ); + if( p->oom==0 ) p->aNode[k].jnFlags |= JNODE_RAW; + }else{ + JsonParse *pPatch = jsonParseCached(pCtx, pValue, pCtx, 1); + if( pPatch==0 ){ + p->oom = 1; + break; + } + jsonParseAddNodeArray(p, pPatch->aNode, pPatch->nNode); + /* The nodes copied out of pPatch and into p likely contain + ** u.zJContent pointers into pPatch->zJson. So preserve the + ** content of pPatch until p is destroyed. */ + assert( pPatch->nJPRef>=1 ); + pPatch->nJPRef++; + jsonParseAddCleanup(p, (void(*)(void*))jsonParseFree, pPatch); + } + break; + } + default: { + jsonParseAddNode(p, JSON_NULL, 0, 0); + sqlite3_result_error(pCtx, "JSON cannot hold BLOB values", -1); + p->nErr++; + break; + } + } } /* @@ -2420,7 +2893,7 @@ int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *pParse; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; @@ -2430,28 +2903,22 @@ jsonWrongNumArgs(ctx, "replace"); return; } - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); + pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); + if( pParse==0 ) return; + pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); - pNode = jsonLookup(&x, zPath, 0, ctx); - if( x.nErr ) goto replace_err; + pParse->useMod = 1; + pNode = jsonLookup(pParse, zPath, 0, ctx); + if( pParse->nErr ) goto replace_err; if( pNode ){ - assert( pNode->eU==0 || pNode->eU==1 || pNode->eU==4 ); - testcase( pNode->eU!=0 && pNode->eU!=1 ); - pNode->jnFlags |= (u8)JNODE_REPLACE; - VVA( pNode->eU = 4 ); - pNode->u.iReplace = i + 1; + jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); } } - if( x.aNode[0].jnFlags & JNODE_REPLACE ){ - assert( x.aNode[0].eU==4 ); - sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); - }else{ - jsonReturnJson(x.aNode, ctx, argv); - } + jsonReturnJson(pParse, pParse->aNode, ctx, 1); replace_err: - jsonParseReset(&x); + jsonDebugPrintParse(pParse); + jsonParseFree(pParse); } @@ -2472,7 +2939,7 @@ int argc, sqlite3_value **argv ){ - JsonParse x; /* The parse */ + JsonParse *pParse; /* The parse */ JsonNode *pNode; const char *zPath; u32 i; @@ -2484,33 +2951,27 @@ jsonWrongNumArgs(ctx, bIsSet ? "set" : "insert"); return; } - if( jsonParse(&x, ctx, (const char*)sqlite3_value_text(argv[0])) ) return; - assert( x.nNode ); + pParse = jsonParseCached(ctx, argv[0], ctx, argc>1); + if( pParse==0 ) return; + pParse->nJPRef++; for(i=1; i<(u32)argc; i+=2){ zPath = (const char*)sqlite3_value_text(argv[i]); bApnd = 0; - pNode = jsonLookup(&x, zPath, &bApnd, ctx); - if( x.oom ){ + pParse->useMod = 1; + pNode = jsonLookup(pParse, zPath, &bApnd, ctx); + if( pParse->oom ){ sqlite3_result_error_nomem(ctx); goto jsonSetDone; - }else if( x.nErr ){ + }else if( pParse->nErr ){ goto jsonSetDone; }else if( pNode && (bApnd || bIsSet) ){ - testcase( pNode->eU!=0 && pNode->eU!=1 ); - assert( pNode->eU!=3 && pNode->eU!=5 ); - VVA( pNode->eU = 4 ); - pNode->jnFlags |= (u8)JNODE_REPLACE; - pNode->u.iReplace = i + 1; + jsonReplaceNode(ctx, pParse, (u32)(pNode - pParse->aNode), argv[i+1]); } } - if( x.aNode[0].jnFlags & JNODE_REPLACE ){ - assert( x.aNode[0].eU==4 ); - sqlite3_result_value(ctx, argv[x.aNode[0].u.iReplace]); - }else{ - jsonReturnJson(x.aNode, ctx, argv); - } + jsonDebugPrintParse(pParse); + jsonReturnJson(pParse, pParse->aNode, ctx, 1); jsonSetDone: - jsonParseReset(&x); + jsonParseFree(pParse); } /* @@ -2529,7 +2990,7 @@ const char *zPath; JsonNode *pNode; - p = jsonParseCached(ctx, argv, ctx); + p = jsonParseCached(ctx, argv[0], ctx, 0); if( p==0 ) return; if( argc==2 ){ zPath = (const char*)sqlite3_value_text(argv[1]); @@ -2555,13 +3016,19 @@ ){ JsonParse *p; /* The parse */ UNUSED_PARAMETER(argc); - if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv, 0); + if( sqlite3_value_type(argv[0])==SQLITE_NULL ){ +#ifdef SQLITE_LEGACY_JSON_VALID + /* Incorrect legacy behavior was to return FALSE for a NULL input */ + sqlite3_result_int(ctx, 0); +#endif + return; + } + p = jsonParseCached(ctx, argv[0], 0, 0); if( p==0 || p->oom ){ sqlite3_result_error_nomem(ctx); sqlite3_free(p); }else{ - sqlite3_result_int(ctx, p->nErr==0 && p->hasNonstd==0); + sqlite3_result_int(ctx, p->nErr==0 && (p->hasNonstd==0 || p->useMod)); if( p->nErr ) jsonParseFree(p); } } @@ -2602,7 +3069,7 @@ JsonParse *p; /* The parse */ UNUSED_PARAMETER(argc); if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return; - p = jsonParseCached(ctx, argv, 0); + p = jsonParseCached(ctx, argv[0], 0, 0); if( p==0 || p->oom ){ sqlite3_result_error_nomem(ctx); sqlite3_free(p); @@ -2611,7 +3078,7 @@ }else{ int n = 1; u32 i; - const char *z = p->zJson; + const char *z = (const char*)sqlite3_value_text(argv[0]); for(i=0; iiErr && ALWAYS(z[i]); i++){ if( (z[i]&0xc0)!=0x80 ) n++; } @@ -2659,7 +3126,8 @@ assert( pStr->bStatic ); }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic ? SQLITE_TRANSIENT : + sqlite3RCStrUnref); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -2700,7 +3168,7 @@ pStr = (JsonString*)sqlite3_aggregate_context(ctx, 0); #ifdef NEVER /* pStr is always non-NULL since jsonArrayStep() or jsonObjectStep() will - ** always have been called to initalize it */ + ** always have been called to initialize it */ if( NEVER(!pStr) ) return; #endif z = pStr->zBuf; @@ -2767,7 +3235,8 @@ assert( pStr->bStatic ); }else if( isFinal ){ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, - pStr->bStatic ? SQLITE_TRANSIENT : sqlite3_free); + pStr->bStatic ? SQLITE_TRANSIENT : + sqlite3RCStrUnref); pStr->bStatic = 1; }else{ sqlite3_result_text(ctx, pStr->zBuf, (int)pStr->nUsed, SQLITE_TRANSIENT); @@ -2835,7 +3304,7 @@ UNUSED_PARAMETER(argv); UNUSED_PARAMETER(argc); UNUSED_PARAMETER(pAux); - rc = sqlite3_declare_vtab(db, + rc = sqlite3_declare_vtab(db, "CREATE TABLE x(key,value,type,atom,id,parent,fullkey,path," "json HIDDEN,root HIDDEN)"); if( rc==SQLITE_OK ){ @@ -2878,7 +3347,6 @@ /* Reset a JsonEachCursor back to its original state. Free any memory ** held. */ static void jsonEachCursorReset(JsonEachCursor *p){ - sqlite3_free(p->zJson); sqlite3_free(p->zRoot); jsonParseReset(&p->sParse); p->iRowid = 0; @@ -3016,7 +3484,7 @@ case JEACH_KEY: { if( p->i==0 ) break; if( p->eType==JSON_OBJECT ){ - jsonReturn(pThis, ctx, 0); + jsonReturn(&p->sParse, pThis, ctx); }else if( p->eType==JSON_ARRAY ){ u32 iKey; if( p->bRecursive ){ @@ -3032,7 +3500,7 @@ } case JEACH_VALUE: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; - jsonReturn(pThis, ctx, 0); + jsonReturn(&p->sParse, pThis, ctx); break; } case JEACH_TYPE: { @@ -3043,11 +3511,11 @@ case JEACH_ATOM: { if( pThis->jnFlags & JNODE_LABEL ) pThis++; if( pThis->eType>=JSON_ARRAY ) break; - jsonReturn(pThis, ctx, 0); + jsonReturn(&p->sParse, pThis, ctx); break; } case JEACH_ID: { - sqlite3_result_int64(ctx, + sqlite3_result_int64(ctx, (sqlite3_int64)p->i + ((pThis->jnFlags & JNODE_LABEL)!=0)); break; } @@ -3147,8 +3615,8 @@ idxMask |= iMask; } } - if( pIdxInfo->nOrderBy>0 - && pIdxInfo->aOrderBy[0].iColumn<0 + if( pIdxInfo->nOrderBy>0 + && pIdxInfo->aOrderBy[0].iColumn<0 && pIdxInfo->aOrderBy[0].desc==0 ){ pIdxInfo->orderByConsumed = 1; @@ -3198,11 +3666,19 @@ if( idxNum==0 ) return SQLITE_OK; z = (const char*)sqlite3_value_text(argv[0]); if( z==0 ) return SQLITE_OK; - n = sqlite3_value_bytes(argv[0]); - p->zJson = sqlite3_malloc64( n+1 ); - if( p->zJson==0 ) return SQLITE_NOMEM; - memcpy(p->zJson, z, (size_t)n+1); - if( jsonParse(&p->sParse, 0, p->zJson) ){ + memset(&p->sParse, 0, sizeof(p->sParse)); + p->sParse.nJPRef = 1; + if( sqlite3ValueIsOfClass(argv[0], sqlite3RCStrUnref) ){ + p->sParse.zJson = sqlite3RCStrRef((char*)z); + }else{ + n = sqlite3_value_bytes(argv[0]); + p->sParse.zJson = sqlite3RCStrNew( n+1 ); + if( p->sParse.zJson==0 ) return SQLITE_NOMEM; + memcpy(p->sParse.zJson, z, (size_t)n+1); + } + p->sParse.bJsonIsRCStr = 1; + p->zJson = p->sParse.zJson; + if( jsonParse(&p->sParse, 0) ){ int rc = SQLITE_NOMEM; if( p->sParse.oom==0 ){ sqlite3_free(cur->pVtab->zErrMsg); @@ -3287,7 +3763,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* The methods of the json_tree virtual table. */ @@ -3315,7 +3792,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* SQLITE_OMIT_VIRTUALTABLE */ #endif /* !defined(SQLITE_OMIT_JSON) */ @@ -3348,10 +3826,10 @@ JFUNCTION(json_parse, 1, 0, jsonParseFunc), JFUNCTION(json_test1, 1, 0, jsonTest1Func), #endif - WAGGREGATE(json_group_array, 1, 0, 0, + WAGGREGATE(json_group_array, 1, 0, 0, jsonArrayStep, jsonArrayFinal, jsonArrayValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC), - WAGGREGATE(json_group_object, 2, 0, 0, + WAGGREGATE(json_group_object, 2, 0, 0, jsonObjectStep, jsonObjectFinal, jsonObjectValue, jsonGroupInverse, SQLITE_SUBTYPE|SQLITE_UTF8|SQLITE_DETERMINISTIC) }; diff -Nru sqlite3-3.42.0/src/loadext.c sqlite3-3.44.0-0/src/loadext.c --- sqlite3-3.42.0/src/loadext.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/loadext.c 2023-11-04 14:23:58.000000000 +0000 @@ -512,7 +512,12 @@ /* Version 3.40.0 and later */ sqlite3_value_encoding, /* Version 3.41.0 and later */ - sqlite3_is_interrupted + sqlite3_is_interrupted, + /* Version 3.43.0 and later */ + sqlite3_stmt_explain, + /* Version 3.44.0 and later */ + sqlite3_get_clientdata, + sqlite3_set_clientdata }; /* True if x is the directory separator character @@ -591,6 +596,10 @@ ** See https://sqlite.org/forum/forumpost/24083b579d. */ if( nMsg>SQLITE_MAX_PATHLEN ) goto extension_not_found; + + /* Do not allow sqlite3_load_extension() to link to a copy of the + ** running application, by passing in an empty filename. */ + if( nMsg==0 ) goto extension_not_found; handle = sqlite3OsDlOpen(pVfs, zFile); #if SQLITE_OS_UNIX || SQLITE_OS_WIN @@ -724,6 +733,9 @@ ** default so as not to open security holes in older applications. */ int sqlite3_enable_load_extension(sqlite3 *db, int onoff){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); if( onoff ){ db->flags |= SQLITE_LoadExtension|SQLITE_LoadExtFunc; @@ -745,7 +757,7 @@ */ typedef struct sqlite3AutoExtList sqlite3AutoExtList; static SQLITE_WSD struct sqlite3AutoExtList { - u32 nExt; /* Number of entries in aExt[] */ + u32 nExt; /* Number of entries in aExt[] */ void (**aExt)(void); /* Pointers to the extension init functions */ } sqlite3Autoext = { 0, 0 }; @@ -773,6 +785,9 @@ void (*xInit)(void) ){ int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return SQLITE_MISUSE_BKPT; +#endif #ifndef SQLITE_OMIT_AUTOINIT rc = sqlite3_initialize(); if( rc ){ @@ -825,6 +840,9 @@ int i; int n = 0; wsdAutoextInit; +#ifdef SQLITE_ENABLE_API_ARMOR + if( xInit==0 ) return 0; +#endif sqlite3_mutex_enter(mutex); for(i=(int)wsdAutoext.nExt-1; i>=0; i--){ if( wsdAutoext.aExt[i]==xInit ){ diff -Nru sqlite3-3.42.0/src/main.c sqlite3-3.44.0-0/src/main.c --- sqlite3-3.42.0/src/main.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/main.c 2023-11-04 14:23:58.000000000 +0000 @@ -41,30 +41,20 @@ ** Forward declarations of external module initializer functions ** for modules that need them. */ -#ifdef SQLITE_ENABLE_FTS1 -int sqlite3Fts1Init(sqlite3*); -#endif -#ifdef SQLITE_ENABLE_FTS2 -int sqlite3Fts2Init(sqlite3*); -#endif #ifdef SQLITE_ENABLE_FTS5 int sqlite3Fts5Init(sqlite3*); #endif #ifdef SQLITE_ENABLE_STMTVTAB int sqlite3StmtVtabInit(sqlite3*); #endif - +#ifdef SQLITE_EXTRA_AUTOEXT +int SQLITE_EXTRA_AUTOEXT(sqlite3*); +#endif /* ** An array of pointers to extension initializer functions for ** built-in extensions. */ static int (*const sqlite3BuiltinExtensions[])(sqlite3*) = { -#ifdef SQLITE_ENABLE_FTS1 - sqlite3Fts1Init, -#endif -#ifdef SQLITE_ENABLE_FTS2 - sqlite3Fts2Init, -#endif #ifdef SQLITE_ENABLE_FTS3 sqlite3Fts3Init, #endif @@ -93,6 +83,9 @@ #ifdef SQLITE_ENABLE_BYTECODE_VTAB sqlite3VdbeBytecodeVtabInit, #endif +#ifdef SQLITE_EXTRA_AUTOEXT + SQLITE_EXTRA_AUTOEXT, +#endif }; #ifndef SQLITE_AMALGAMATION @@ -103,7 +96,7 @@ #endif /* IMPLEMENTATION-OF: R-53536-42575 The sqlite3_libversion() function returns -** a pointer to the to the sqlite3_version[] string constant. +** a pointer to the to the sqlite3_version[] string constant. */ const char *sqlite3_libversion(void){ return sqlite3_version; } @@ -167,13 +160,39 @@ char *sqlite3_data_directory = 0; /* -** Initialize SQLite. +** Determine whether or not high-precision (long double) floating point +** math works correctly on CPU currently running. +*/ +static SQLITE_NOINLINE int hasHighPrecisionDouble(int rc){ + if( sizeof(LONGDOUBLE_TYPE)<=8 ){ + /* If the size of "long double" is not more than 8, then + ** high-precision math is not possible. */ + return 0; + }else{ + /* Just because sizeof(long double)>8 does not mean that the underlying + ** hardware actually supports high-precision floating point. For example, + ** clearing the 0x100 bit in the floating-point control word on Intel + ** processors will make long double work like double, even though long + ** double takes up more space. The only way to determine if long double + ** actually works is to run an experiment. */ + LONGDOUBLE_TYPE a, b, c; + rc++; + a = 1.0+rc*0.1; + b = 1.0e+18+rc*25.0; + c = a+b; + return b!=c; + } +} + + +/* +** Initialize SQLite. ** ** This routine must be called to initialize the memory allocation, ** VFS, and mutex subsystems prior to doing any serious work with ** SQLite. But as long as you do not compile with SQLITE_OMIT_AUTOINIT ** this routine will be called automatically by key routines such as -** sqlite3_open(). +** sqlite3_open(). ** ** This routine is a no-op except on its very first call for the process, ** or for the first call after a call to sqlite3_shutdown. @@ -226,7 +245,7 @@ return SQLITE_OK; } - /* Make sure the mutex subsystem is initialized. If unable to + /* Make sure the mutex subsystem is initialized. If unable to ** initialize the mutex subsystem, return early with the error. ** If the system is so sick that we are unable to allocate a mutex, ** there is not much SQLite is going to be able to do. @@ -308,7 +327,7 @@ } #endif if( rc==SQLITE_OK ){ - sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, + sqlite3PCacheBufferSetup( sqlite3GlobalConfig.pPage, sqlite3GlobalConfig.szPage, sqlite3GlobalConfig.nPage); sqlite3MemoryBarrier(); sqlite3GlobalConfig.isInit = 1; @@ -361,6 +380,12 @@ } #endif + /* Experimentally determine if high-precision floating point is + ** available. */ +#ifndef SQLITE_OMIT_WSD + sqlite3Config.bUseLongDouble = hasHighPrecisionDouble(rc); +#endif + return rc; } @@ -539,7 +564,7 @@ ** a single parameter which is a pointer to an integer and writes into ** that integer the number of extra bytes per page required for each page ** in SQLITE_CONFIG_PAGECACHE. */ - *va_arg(ap, int*) = + *va_arg(ap, int*) = sqlite3HeaderSizeBtree() + sqlite3HeaderSizePcache() + sqlite3HeaderSizePcache1(); @@ -626,7 +651,7 @@ sqlite3GlobalConfig.nLookaside = va_arg(ap, int); break; } - + /* Record a pointer to the logger function and its first argument. ** The default is NULL. Logging is disabled if the function pointer is ** NULL. @@ -751,7 +776,7 @@ /* ** Set up the lookaside buffers for a database connection. -** Return SQLITE_OK on success. +** Return SQLITE_OK on success. ** If lookaside is already active, return SQLITE_BUSY. ** ** The sz parameter is the number of bytes in each lookaside slot. @@ -766,12 +791,12 @@ sqlite3_int64 szAlloc = sz*(sqlite3_int64)cnt; int nBig; /* Number of full-size slots */ int nSm; /* Number smaller LOOKASIDE_SMALL-byte slots */ - + if( sqlite3LookasideUsed(db,0)>0 ){ return SQLITE_BUSY; } /* Free any existing lookaside buffer for this handle before - ** allocating a new one so we don't have to have space for + ** allocating a new one so we don't have to have space for ** both at the same time. */ if( db->lookaside.bMalloced ){ @@ -931,6 +956,10 @@ int sqlite3_db_config(sqlite3 *db, int op, ...){ va_list ap; int rc; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); va_start(ap, op); switch( op ){ @@ -1051,7 +1080,7 @@ } /* -** Another built-in collating sequence: NOCASE. +** Another built-in collating sequence: NOCASE. ** ** This collating sequence is intended to be used for "case independent ** comparison". SQLite's knowledge of upper and lower case equivalents @@ -1201,7 +1230,7 @@ /* ** Return TRUE if database connection db has unfinalized prepared -** statements or unfinished sqlite3_backup objects. +** statements or unfinished sqlite3_backup objects. */ static int connectionIsBusy(sqlite3 *db){ int j; @@ -1260,6 +1289,14 @@ } #endif + while( db->pDbData ){ + DbClientData *p = db->pDbData; + db->pDbData = p->pNext; + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + sqlite3_free(p); + } + /* Convert the connection into a zombie and then close it. */ db->eOpenState = SQLITE_STATE_ZOMBIE; @@ -1417,7 +1454,7 @@ /* The temp-database schema is allocated differently from the other schema ** objects (using sqliteMalloc() directly, instead of sqlite3BtreeSchema()). ** So it needs to be freed here. Todo: Why not roll the temp schema into - ** the same sqliteMalloc() as the one that allocates the database + ** the same sqliteMalloc() as the one that allocates the database ** structure? */ sqlite3DbFree(db, db->aDb[1].pSchema); @@ -1448,7 +1485,7 @@ assert( sqlite3_mutex_held(db->mutex) ); sqlite3BeginBenignMalloc(); - /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). + /* Obtain all b-tree mutexes before making any calls to BtreeRollback(). ** This is important in case the transaction being rolled back has ** modified the database schema. If the b-tree mutexes are not taken ** here, then another shared-cache connection might sneak in between @@ -1677,9 +1714,9 @@ void *ptr, /* Database connection */ int count /* Number of times table has been busy */ ){ -#if SQLITE_OS_WIN || HAVE_USLEEP +#if SQLITE_OS_WIN || !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP /* This case is for systems that have support for sleeping for fractions of - ** a second. Examples: All windows systems, unix systems with usleep() */ + ** a second. Examples: All windows systems, unix systems with nanosleep() */ static const u8 delays[] = { 1, 2, 5, 10, 15, 20, 25, 25, 25, 50, 50, 100 }; static const u8 totals[] = @@ -1734,7 +1771,7 @@ }else{ p->nBusy++; } - return rc; + return rc; } /* @@ -1765,9 +1802,9 @@ ** be invoked every nOps opcodes. */ void sqlite3_progress_handler( - sqlite3 *db, + sqlite3 *db, int nOps, - int (*xProgress)(void*), + int (*xProgress)(void*), void *pArg ){ #ifdef SQLITE_ENABLE_API_ARMOR @@ -1844,7 +1881,7 @@ ** This function is exactly the same as sqlite3_create_function(), except ** that it is designed to be called by internal code. The difference is ** that if a malloc() fails in sqlite3_create_function(), an error code -** is returned and the mallocFailed flag cleared. +** is returned and the mallocFailed flag cleared. */ int sqlite3CreateFunc( sqlite3 *db, @@ -1885,7 +1922,7 @@ assert( SQLITE_FUNC_UNSAFE==SQLITE_INNOCUOUS ); extraFlags ^= SQLITE_FUNC_UNSAFE; /* tag-20230109-1 */ - + #ifndef SQLITE_OMIT_UTF16 /* If SQLITE_UTF16 is specified as the encoding type, transform this ** to one of SQLITE_UTF16LE or SQLITE_UTF16BE using the @@ -1925,7 +1962,7 @@ #else enc = SQLITE_UTF8; #endif - + /* Check if an existing function is being overridden or deleted. If so, ** and there are active VMs, then return SQLITE_BUSY. If a function ** is being overridden/deleted but there are no active VMs, allow the @@ -1934,7 +1971,7 @@ p = sqlite3FindFunction(db, zFunctionName, nArg, (u8)enc, 0); if( p && (p->funcFlags & SQLITE_FUNC_ENCMASK)==(u32)enc && p->nArg==nArg ){ if( db->nVdbeActive ){ - sqlite3ErrorWithMsg(db, SQLITE_BUSY, + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify user-function due to active statements"); assert( !db->mallocFailed ); return SQLITE_BUSY; @@ -2013,7 +2050,7 @@ pArg->xDestroy = xDestroy; pArg->pUserData = p; } - rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, + rc = sqlite3CreateFunc(db, zFunc, nArg, enc, p, xSFunc, xStep, xFinal, xValue, xInverse, pArg ); if( pArg && pArg->nRef==0 ){ @@ -2130,7 +2167,7 @@ ** ** If the function already exists as a regular global function, then ** this routine is a no-op. If the function does not exist, then create -** a new one that always throws a run-time error. +** a new one that always throws a run-time error. ** ** When virtual tables intend to provide an overloaded function, they ** should call this routine to make sure the global function exists. @@ -2163,7 +2200,7 @@ #ifndef SQLITE_OMIT_TRACE /* ** Register a trace function. The pArg from the previously registered trace -** is returned. +** is returned. ** ** A NULL trace function means that no tracing is executes. A non-NULL ** trace is a pointer to a function that is invoked at the start of each @@ -2214,8 +2251,8 @@ #ifndef SQLITE_OMIT_DEPRECATED /* -** Register a profile function. The pArg from the previously registered -** profile function is returned. +** Register a profile function. The pArg from the previously registered +** profile function is returned. ** ** A NULL profile function means that no profiling is executes. A non-NULL ** profile is a pointer to a function that is invoked at the conclusion of @@ -2334,6 +2371,12 @@ void *pArg /* First callback argument */ ){ void *pRet; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 ){ + return 0; + } +#endif sqlite3_mutex_enter(db->mutex); pRet = db->pPreUpdateArg; db->xPreUpdateCallback = xCallback; @@ -2349,7 +2392,7 @@ */ int sqlite3_autovacuum_pages( sqlite3 *db, /* Attach the hook to this database */ - unsigned int (*xCallback)(void*,const char*,u32,u32,u32), + unsigned int (*xCallback)(void*,const char*,u32,u32,u32), void *pArg, /* Argument to the function */ void (*xDestructor)(void*) /* Destructor for pArg */ ){ @@ -2377,7 +2420,7 @@ ** Invoke sqlite3_wal_checkpoint if the number of frames in the log file ** is greater than sqlite3.pWalArg cast to an integer (the value configured by ** wal_autocheckpoint()). -*/ +*/ int sqlite3WalDefaultHook( void *pClientData, /* Argument */ sqlite3 *db, /* Connection */ @@ -2480,7 +2523,7 @@ if( eModeSQLITE_CHECKPOINT_TRUNCATE ){ /* EVIDENCE-OF: R-03996-12088 The M parameter must be a valid checkpoint ** mode: */ - return SQLITE_MISUSE; + return SQLITE_MISUSE_BKPT; } sqlite3_mutex_enter(db->mutex); @@ -2513,7 +2556,7 @@ /* ** Checkpoint database zDb. If zDb is NULL, or if the buffer zDb points -** to contains a zero-length string, all attached databases are +** to contains a zero-length string, all attached databases are ** checkpointed. */ int sqlite3_wal_checkpoint(sqlite3 *db, const char *zDb){ @@ -2527,9 +2570,9 @@ ** Run a checkpoint on database iDb. This is a no-op if database iDb is ** not currently open in WAL mode. ** -** If a transaction is open on the database being checkpointed, this -** function returns SQLITE_LOCKED and a checkpoint is not attempted. If -** an error occurs while running the checkpoint, an SQLite error code is +** If a transaction is open on the database being checkpointed, this +** function returns SQLITE_LOCKED and a checkpoint is not attempted. If +** an error occurs while running the checkpoint, an SQLite error code is ** returned (i.e. SQLITE_IOERR). Otherwise, SQLITE_OK. ** ** The mutex on database handle db should be held by the caller. The mutex @@ -2713,7 +2756,7 @@ } int sqlite3_system_errno(sqlite3 *db){ return db ? db->iSysErrno : 0; -} +} /* ** Return a string that describes the kind of error specified in the @@ -2730,7 +2773,7 @@ */ static int createCollation( sqlite3* db, - const char *zName, + const char *zName, u8 enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), @@ -2738,7 +2781,7 @@ ){ CollSeq *pColl; int enc2; - + assert( sqlite3_mutex_held(db->mutex) ); /* If SQLITE_UTF16 is specified as the encoding type, transform this @@ -2755,14 +2798,14 @@ return SQLITE_MISUSE_BKPT; } - /* Check if this call is removing or replacing an existing collation + /* Check if this call is removing or replacing an existing collation ** sequence. If so, and there are active VMs, return busy. If there ** are no active VMs, invalidate any pre-compiled statements. */ pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, 0); if( pColl && pColl->xCmp ){ if( db->nVdbeActive ){ - sqlite3ErrorWithMsg(db, SQLITE_BUSY, + sqlite3ErrorWithMsg(db, SQLITE_BUSY, "unable to delete/modify collation sequence due to active statements"); return SQLITE_BUSY; } @@ -2773,7 +2816,7 @@ ** then any copies made by synthCollSeq() need to be invalidated. ** Also, collation destructor - CollSeq.xDel() - function may need ** to be called. - */ + */ if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){ CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName); int j; @@ -2924,7 +2967,7 @@ ** query parameter. The second argument contains the URI (or non-URI filename) ** itself. When this function is called the *pFlags variable should contain ** the default flags to open the database handle with. The value stored in -** *pFlags may be updated before returning if the URI filename contains +** *pFlags may be updated before returning if the URI filename contains ** "cache=xxx" or "mode=xxx" query parameters. ** ** If successful, SQLITE_OK is returned. In this case *ppVfs is set to point to @@ -2936,7 +2979,7 @@ ** the value returned in *pzFile to avoid a memory leak. ** ** If an error occurs, then an SQLite error code is returned and *pzErrMsg -** may be set to point to a buffer containing an English language error +** may be set to point to a buffer containing an English language error ** message. It is the responsibility of the caller to eventually release ** this buffer by calling sqlite3_free(). */ @@ -2944,7 +2987,7 @@ const char *zDefaultVfs, /* VFS to use if no "vfs=xxx" query option */ const char *zUri, /* Nul-terminated URI to parse */ unsigned int *pFlags, /* IN/OUT: SQLITE_OPEN_XXX flags */ - sqlite3_vfs **ppVfs, /* OUT: VFS to use */ + sqlite3_vfs **ppVfs, /* OUT: VFS to use */ char **pzFile, /* OUT: Filename component of URI */ char **pzErrMsg /* OUT: Error message (if rc!=SQLITE_OK) */ ){ @@ -2967,7 +3010,7 @@ int iOut = 0; /* Output character index */ u64 nByte = nUri+8; /* Bytes of space to allocate */ - /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen + /* Make sure the SQLITE_OPEN_URI flag is set to indicate to the VFS xOpen ** method that there may be extra parameters following the file-name. */ flags |= SQLITE_OPEN_URI; @@ -2985,7 +3028,7 @@ /* The following condition causes URIs with five leading / characters ** like file://///host/path to be converted into UNCs like //host/path. ** The correct URI for that UNC has only two or four leading / characters - ** file://host/path or file:////host/path. But 5 leading slashes is a + ** file://host/path or file:////host/path. But 5 leading slashes is a ** common error, we are told, so we handle it as a special case. */ if( strncmp(zUri+7, "///", 3)==0 ){ iIn++; } }else if( strncmp(zUri+5, "//localhost/", 12)==0 ){ @@ -2997,7 +3040,7 @@ iIn = 7; while( zUri[iIn] && zUri[iIn]!='/' ) iIn++; if( iIn!=7 && (iIn!=16 || memcmp("localhost", &zUri[7], 9)) ){ - *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", + *pzErrMsg = sqlite3_mprintf("invalid uri authority: %.*s", iIn-7, &zUri[7]); rc = SQLITE_ERROR; goto parse_uri_out; @@ -3005,8 +3048,8 @@ } #endif - /* Copy the filename and any query parameters into the zFile buffer. - ** Decode %HH escape codes along the way. + /* Copy the filename and any query parameters into the zFile buffer. + ** Decode %HH escape codes along the way. ** ** Within this loop, variable eState may be set to 0, 1 or 2, depending ** on the parsing context. As follows: @@ -3018,9 +3061,9 @@ eState = 0; while( (c = zUri[iIn])!=0 && c!='#' ){ iIn++; - if( c=='%' - && sqlite3Isxdigit(zUri[iIn]) - && sqlite3Isxdigit(zUri[iIn+1]) + if( c=='%' + && sqlite3Isxdigit(zUri[iIn]) + && sqlite3Isxdigit(zUri[iIn+1]) ){ int octet = (sqlite3HexToInt(zUri[iIn++]) << 4); octet += sqlite3HexToInt(zUri[iIn++]); @@ -3032,7 +3075,7 @@ ** case we ignore all text in the remainder of the path, name or ** value currently being parsed. So ignore the current character ** and skip to the next "?", "=" or "&", as appropriate. */ - while( (c = zUri[iIn])!=0 && c!='#' + while( (c = zUri[iIn])!=0 && c!='#' && (eState!=0 || c!='?') && (eState!=1 || (c!='=' && c!='&')) && (eState!=2 || c!='&') @@ -3069,7 +3112,7 @@ if( eState==1 ) zFile[iOut++] = '\0'; memset(zFile+iOut, 0, 4); /* end-of-options + empty journal filenames */ - /* Check if there were any options specified that should be interpreted + /* Check if there were any options specified that should be interpreted ** here. Options that are interpreted here include "vfs" and those that ** correspond to flags that may be passed to the sqlite3_open_v2() ** method. */ @@ -3105,7 +3148,7 @@ if( nOpt==4 && memcmp("mode", zOpt, 4)==0 ){ static struct OpenMode aOpenMode[] = { { "ro", SQLITE_OPEN_READONLY }, - { "rw", SQLITE_OPEN_READWRITE }, + { "rw", SQLITE_OPEN_READWRITE }, { "rwc", SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE }, { "memory", SQLITE_OPEN_MEMORY }, { 0, 0 } @@ -3192,7 +3235,7 @@ /* ** This routine does the work of opening a database on behalf of -** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" +** sqlite3_open() and sqlite3_open16(). The database filename "zFilename" ** is UTF-8 encoded. */ static int openDatabase( @@ -3245,11 +3288,11 @@ flags &= ~( SQLITE_OPEN_DELETEONCLOSE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_MAIN_DB | - SQLITE_OPEN_TEMP_DB | - SQLITE_OPEN_TRANSIENT_DB | - SQLITE_OPEN_MAIN_JOURNAL | - SQLITE_OPEN_TEMP_JOURNAL | - SQLITE_OPEN_SUBJOURNAL | + SQLITE_OPEN_TEMP_DB | + SQLITE_OPEN_TRANSIENT_DB | + SQLITE_OPEN_MAIN_JOURNAL | + SQLITE_OPEN_TEMP_JOURNAL | + SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_SUPER_JOURNAL | SQLITE_OPEN_NOMUTEX | SQLITE_OPEN_FULLMUTEX | @@ -3259,7 +3302,7 @@ /* Allocate the sqlite data structure */ db = sqlite3MallocZero( sizeof(sqlite3) ); if( db==0 ) goto opendb_out; - if( isThreadsafe + if( isThreadsafe #ifdef SQLITE_ENABLE_MULTITHREADED_CHECKS || sqlite3GlobalConfig.bCoreMutex #endif @@ -3291,7 +3334,7 @@ db->nextPagesize = 0; db->init.azInit = sqlite3StdType; /* Any array of string ptrs will do */ #ifdef SQLITE_ENABLE_SORTER_MMAP - /* Beginning with version 3.37.0, using the VFS xFetch() API to memory-map + /* Beginning with version 3.37.0, using the VFS xFetch() API to memory-map ** the temporary files used to do external sorts (see code in vdbesort.c) ** is disabled. It can still be used either by defining ** SQLITE_ENABLE_SORTER_MMAP at compile time or by using the @@ -3310,14 +3353,14 @@ ** ** SQLITE_DQS SQLITE_DBCONFIG_DQS_DDL SQLITE_DBCONFIG_DQS_DML ** ---------- ----------------------- ----------------------- -** undefined on on +** undefined on on ** 3 on on ** 2 on off ** 1 off on ** 0 off off ** ** Legacy behavior is 3 (double-quoted string literals are allowed anywhere) -** and so that is the default. But developers are encouranged to use +** 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) @@ -3406,7 +3449,7 @@ /* Parse the filename/URI argument ** - ** Only allow sensible combinations of bits in the flags argument. + ** Only allow sensible combinations of bits in the flags argument. ** Throw an error if any non-sense combination is used. If we ** do not block illegal combinations here, it could trigger ** assert() statements in deeper layers. Sensible combinations @@ -3460,7 +3503,7 @@ db->aDb[1].pSchema = sqlite3SchemaGet(db, 0); /* The default safety_level for the main database is FULL; for the temp - ** database it is OFF. This matches the pager layer defaults. + ** database it is OFF. This matches the pager layer defaults. */ db->aDb[0].zDbSName = "main"; db->aDb[0].safety_level = SQLITE_DEFAULT_SYNCHRONOUS+1; @@ -3499,7 +3542,7 @@ #ifdef SQLITE_ENABLE_INTERNAL_FUNCTIONS /* Testing use only!!! The -DSQLITE_ENABLE_INTERNAL_FUNCTIONS=1 compile-time - ** option gives access to internal functions by default. + ** option gives access to internal functions by default. ** Testing use only!!! */ db->mDbFlags |= DBFLAG_InternalFunc; #endif @@ -3553,8 +3596,8 @@ ** Open a new database handle. */ int sqlite3_open( - const char *zFilename, - sqlite3 **ppDb + const char *zFilename, + sqlite3 **ppDb ){ return openDatabase(zFilename, ppDb, SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE, 0); @@ -3573,7 +3616,7 @@ ** Open a new database handle. */ int sqlite3_open16( - const void *zFilename, + const void *zFilename, sqlite3 **ppDb ){ char const *zFilename8; /* zFilename encoded in UTF-8 instead of UTF-16 */ @@ -3612,9 +3655,9 @@ ** Register a new collation sequence with the database handle db. */ int sqlite3_create_collation( - sqlite3* db, - const char *zName, - int enc, + sqlite3* db, + const char *zName, + int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ @@ -3625,9 +3668,9 @@ ** Register a new collation sequence with the database handle db. */ int sqlite3_create_collation_v2( - sqlite3* db, - const char *zName, - int enc, + sqlite3* db, + const char *zName, + int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDel)(void*) @@ -3650,9 +3693,9 @@ ** Register a new collation sequence with the database handle db. */ int sqlite3_create_collation16( - sqlite3* db, + sqlite3* db, const void *zName, - int enc, + int enc, void* pCtx, int(*xCompare)(void*,int,const void*,int,const void*) ){ @@ -3680,8 +3723,8 @@ ** db. Replace any previously installed collation sequence factory. */ int sqlite3_collation_needed( - sqlite3 *db, - void *pCollNeededArg, + sqlite3 *db, + void *pCollNeededArg, void(*xCollNeeded)(void*,sqlite3*,int eTextRep,const char*) ){ #ifdef SQLITE_ENABLE_API_ARMOR @@ -3701,8 +3744,8 @@ ** db. Replace any previously installed collation sequence factory. */ int sqlite3_collation_needed16( - sqlite3 *db, - void *pCollNeededArg, + sqlite3 *db, + void *pCollNeededArg, void(*xCollNeeded16)(void*,sqlite3*,int eTextRep,const void*) ){ #ifdef SQLITE_ENABLE_API_ARMOR @@ -3717,6 +3760,69 @@ } #endif /* SQLITE_OMIT_UTF16 */ +/* +** Find existing client data. +*/ +void *sqlite3_get_clientdata(sqlite3 *db, const char *zName){ + DbClientData *p; + sqlite3_mutex_enter(db->mutex); + for(p=db->pDbData; p; p=p->pNext){ + if( strcmp(p->zName, zName)==0 ){ + void *pResult = p->pData; + sqlite3_mutex_leave(db->mutex); + return pResult; + } + } + sqlite3_mutex_leave(db->mutex); + return 0; +} + +/* +** Add new client data to a database connection. +*/ +int sqlite3_set_clientdata( + sqlite3 *db, /* Attach client data to this connection */ + const char *zName, /* Name of the client data */ + void *pData, /* The client data itself */ + void (*xDestructor)(void*) /* Destructor */ +){ + DbClientData *p, **pp; + sqlite3_mutex_enter(db->mutex); + pp = &db->pDbData; + for(p=db->pDbData; p && strcmp(p->zName,zName); p=p->pNext){ + pp = &p->pNext; + } + if( p ){ + assert( p->pData!=0 ); + if( p->xDestructor ) p->xDestructor(p->pData); + if( pData==0 ){ + *pp = p->pNext; + sqlite3_free(p); + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + } + }else if( pData==0 ){ + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; + }else{ + size_t n = strlen(zName); + p = sqlite3_malloc64( sizeof(DbClientData)+n+1 ); + if( p==0 ){ + if( xDestructor ) xDestructor(pData); + sqlite3_mutex_leave(db->mutex); + return SQLITE_NOMEM; + } + memcpy(p->zName, zName, n+1); + p->pNext = db->pDbData; + db->pDbData = p; + } + p->pData = pData; + p->xDestructor = xDestructor; + sqlite3_mutex_leave(db->mutex); + return SQLITE_OK; +} + + #ifndef SQLITE_OMIT_DEPRECATED /* ** This function is now an anachronism. It used to be used to recover from a @@ -3852,7 +3958,7 @@ /* Find the column for which info is requested */ if( zColumnName==0 ){ - /* Query for existance of table only */ + /* Query for existence of table only */ }else{ for(iCol=0; iColnCol; iCol++){ pCol = &pTab->aCol[iCol]; @@ -3874,13 +3980,13 @@ /* The following block stores the meta information that will be returned ** to the caller in local variables zDataType, zCollSeq, notnull, primarykey ** and autoinc. At this point there are two possibilities: - ** - ** 1. The specified column name was rowid", "oid" or "_rowid_" - ** and there is no explicitly declared IPK column. ** - ** 2. The table is not a view and the column name identified an + ** 1. The specified column name was rowid", "oid" or "_rowid_" + ** and there is no explicitly declared IPK column. + ** + ** 2. The table is not a view and the column name identified an ** explicitly declared column. Copy meta information from *pCol. - */ + */ if( pCol ){ zDataType = sqlite3ColumnType(pCol,0); zCollSeq = sqlite3ColumnColl(pCol); @@ -3930,7 +4036,7 @@ pVfs = sqlite3_vfs_find(0); if( pVfs==0 ) return 0; - /* This function works in milliseconds, but the underlying OsSleep() + /* This function works in milliseconds, but the underlying OsSleep() ** API uses microseconds. Hence the 1000's. */ rc = (sqlite3OsSleep(pVfs, ms<0 ? 0 : 1000*ms)/1000); @@ -4066,6 +4172,28 @@ } #endif + /* sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, sqlite3 *db, int b); + ** + ** If b is true, then activate the SQLITE_FkNoAction setting. If b is + ** false then clearn that setting. If the SQLITE_FkNoAction setting is + ** abled, all foreign key ON DELETE and ON UPDATE actions behave as if + ** they were NO ACTION, regardless of how they are defined. + ** + ** NB: One must usually run "PRAGMA writable_schema=RESET" after + ** using this test-control, before it will take full effect. failing + ** to reset the schema can result in some unexpected behavior. + */ + case SQLITE_TESTCTRL_FK_NO_ACTION: { + sqlite3 *db = va_arg(ap, sqlite3*); + int b = va_arg(ap, int); + if( b ){ + db->flags |= SQLITE_FkNoAction; + }else{ + db->flags &= ~SQLITE_FkNoAction; + } + break; + } + /* ** sqlite3_test_control(BITVEC_TEST, size, program) ** @@ -4110,7 +4238,7 @@ /* ** sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd) ** - ** Register hooks to call to indicate which malloc() failures + ** Register hooks to call to indicate which malloc() failures ** are benign. */ case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: { @@ -4172,10 +4300,12 @@ sqlite3ShowSrcList(0); sqlite3ShowWith(0); sqlite3ShowUpsert(0); +#ifndef SQLITE_OMIT_TRIGGER sqlite3ShowTriggerStep(0); sqlite3ShowTriggerStepList(0); sqlite3ShowTrigger(0); sqlite3ShowTriggerList(0); +#endif #ifndef SQLITE_OMIT_WINDOWFUNC sqlite3ShowWindow(0); sqlite3ShowWinFunc(0); @@ -4230,7 +4360,7 @@ ** 10 little-endian, determined at run-time ** 432101 big-endian, determined at compile-time ** 123410 little-endian, determined at compile-time - */ + */ case SQLITE_TESTCTRL_BYTEORDER: { rc = SQLITE_BYTEORDER*100 + SQLITE_LITTLEENDIAN*10 + SQLITE_BIGENDIAN; break; @@ -4238,7 +4368,7 @@ /* sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, sqlite3 *db, int N) ** - ** Enable or disable various optimizations for testing purposes. The + ** Enable or disable various optimizations for testing purposes. The ** argument N is a bitmask of optimizations to be disabled. For normal ** operation N should be 0. The idea is that a test program (like the ** SQL Logic Test or SLT test module) can run the same SQL multiple times @@ -4292,7 +4422,7 @@ ** formed and never corrupt. This flag is clear by default, indicating that ** database files might have arbitrary corruption. Setting the flag during ** testing causes certain assert() statements in the code to be activated - ** that demonstrat invariants on well-formed database files. + ** that demonstrate invariants on well-formed database files. */ case SQLITE_TESTCTRL_NEVER_CORRUPT: { sqlite3GlobalConfig.neverCorrupt = va_arg(ap, int); @@ -4328,7 +4458,7 @@ /* sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE, xCallback, ptr); ** - ** Set the VDBE coverage callback function to xCallback with context + ** Set the VDBE coverage callback function to xCallback with context ** pointer ptr. */ case SQLITE_TESTCTRL_VDBE_COVERAGE: { @@ -4442,11 +4572,11 @@ /* sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, op, ptr) ** - ** "ptr" is a pointer to a u32. + ** "ptr" is a pointer to a u32. ** ** op==0 Store the current sqlite3TreeTrace in *ptr ** op==1 Set sqlite3TreeTrace to the value *ptr - ** op==3 Store the current sqlite3WhereTrace in *ptr + ** op==2 Store the current sqlite3WhereTrace in *ptr ** op==3 Set sqlite3WhereTrace to the value *ptr */ case SQLITE_TESTCTRL_TRACEFLAGS: { @@ -4481,7 +4611,24 @@ *pI2 = sqlite3LogEst(*pU64); break; } - + +#if !defined(SQLITE_OMIT_WSD) + /* sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, int X); + ** + ** X<0 Make no changes to the bUseLongDouble. Just report value. + ** X==0 Disable bUseLongDouble + ** X==1 Enable bUseLongDouble + ** X>=2 Set bUseLongDouble to its default value for this platform + */ + case SQLITE_TESTCTRL_USELONGDOUBLE: { + int b = va_arg(ap, int); + if( b>=2 ) b = hasHighPrecisionDouble(b); + if( b>=0 ) sqlite3Config.bUseLongDouble = b>0; + rc = sqlite3Config.bUseLongDouble!=0; + break; + } +#endif + #if defined(SQLITE_DEBUG) && !defined(SQLITE_OMIT_WSD) /* sqlite3_test_control(SQLITE_TESTCTRL_TUNE, id, *piValue) @@ -4597,7 +4744,7 @@ /* ** This is a utility routine, useful to VFS implementations, that checks -** to see if a database file was a URI that contained a specific query +** to see if a database file was a URI that contained a specific query ** parameter, and if so obtains the value of the query parameter. ** ** The zFilename argument is the filename pointer passed into the xOpen() @@ -4745,11 +4892,11 @@ #ifdef SQLITE_ENABLE_SNAPSHOT /* -** Obtain a snapshot handle for the snapshot of database zDb currently +** Obtain a snapshot handle for the snapshot of database zDb currently ** being read by handle db. */ int sqlite3_snapshot_get( - sqlite3 *db, + sqlite3 *db, const char *zDb, sqlite3_snapshot **ppSnapshot ){ @@ -4782,11 +4929,11 @@ } /* -** Open a read-transaction on the snapshot idendified by pSnapshot. +** Open a read-transaction on the snapshot identified by pSnapshot. */ int sqlite3_snapshot_open( - sqlite3 *db, - const char *zDb, + sqlite3 *db, + const char *zDb, sqlite3_snapshot *pSnapshot ){ int rc = SQLITE_ERROR; @@ -4888,8 +5035,8 @@ int i, n; int nOpt; const char **azCompileOpt; - -#if SQLITE_ENABLE_API_ARMOR + +#ifdef SQLITE_ENABLE_API_ARMOR if( zOptName==0 ){ (void)SQLITE_MISUSE_BKPT; return 0; @@ -4901,7 +5048,7 @@ if( sqlite3StrNICmp(zOptName, "SQLITE_", 7)==0 ) zOptName += 7; n = sqlite3Strlen30(zOptName); - /* Since nOpt is normally in single digits, a linear search is + /* Since nOpt is normally in single digits, a linear search is ** adequate. No need for a binary search. */ for(i=0; imallocFailed || rc ){ return apiHandleError(db, rc); } - return rc & db->errMask; + return 0; } diff -Nru sqlite3-3.42.0/src/mem1.c sqlite3-3.44.0-0/src/mem1.c --- sqlite3-3.42.0/src/mem1.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/mem1.c 2023-11-04 14:23:58.000000000 +0000 @@ -156,7 +156,7 @@ ** or sqlite3MemRealloc(). ** ** For this low-level routine, we already know that pPrior!=0 since -** cases where pPrior==0 will have been intecepted and dealt with +** cases where pPrior==0 will have been intercepted and dealt with ** by higher-level routines. */ static void sqlite3MemFree(void *pPrior){ @@ -244,13 +244,13 @@ return SQLITE_OK; } len = sizeof(cpuCount); - /* One usually wants to use hw.acctivecpu for MT decisions, but not here */ + /* 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, + /* only 1 core, use our own zone to contention over global locks, ** e.g. we have our own dedicated locks */ _sqliteZone_ = malloc_create_zone(4096, 0); malloc_set_zone_name(_sqliteZone_, "Sqlite_Heap"); diff -Nru sqlite3-3.42.0/src/mutex.c sqlite3-3.44.0-0/src/mutex.c --- sqlite3-3.42.0/src/mutex.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/mutex.c 2023-11-04 14:23:58.000000000 +0000 @@ -133,7 +133,7 @@ assert( SQLITE_MUTEX_FAST<2 ); assert( SQLITE_MUTEX_WARNONCONTENTION<2 ); -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( ((CheckMutex*)p)->iType<2 ) #endif { diff -Nru sqlite3-3.42.0/src/mutex_unix.c sqlite3-3.44.0-0/src/mutex_unix.c --- sqlite3-3.42.0/src/mutex_unix.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/mutex_unix.c 2023-11-04 14:23:58.000000000 +0000 @@ -26,7 +26,7 @@ /* ** The sqlite3_mutex.id, sqlite3_mutex.nRef, and sqlite3_mutex.owner fields -** are necessary under two condidtions: (1) Debug builds and (2) using +** 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) @@ -64,7 +64,7 @@ ** there might be race conditions that can cause these routines to ** deliver incorrect results. In particular, if pthread_equal() is ** not an atomic operation, then these routines might delivery -** incorrect results. On most platforms, pthread_equal() is a +** incorrect results. On most platforms, pthread_equal() is a ** comparison of two integers and is therefore atomic. But we are ** told that HPUX is not such a platform. If so, then these routines ** will not always work correctly on HPUX. @@ -146,7 +146,7 @@ ** ** Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST ** or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() -** returns a different mutex on every call. But for the static +** returns a different mutex on every call. But for the static ** mutex types, the same mutex is returned on every call that has ** the same type number. */ @@ -223,7 +223,7 @@ */ static void pthreadMutexFree(sqlite3_mutex *p){ assert( p->nRef==0 ); -#if SQLITE_ENABLE_API_ARMOR +#ifdef SQLITE_ENABLE_API_ARMOR if( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE ) #endif { @@ -257,7 +257,7 @@ ** is atomic - that it cannot be deceived into thinking self ** and p->owner are equal if p->owner changes between two values ** that are not equal to self while the comparison is taking place. - ** This implementation also assumes a coherent cache - that + ** This implementation also assumes a coherent cache - that ** separate processes cannot read different values from the same ** address at the same time. If either of these two conditions ** are not met, then the mutexes will fail and problems will result. @@ -300,7 +300,7 @@ ** is atomic - that it cannot be deceived into thinking self ** and p->owner are equal if p->owner changes between two values ** that are not equal to self while the comparison is taking place. - ** This implementation also assumes a coherent cache - that + ** This implementation also assumes a coherent cache - that ** separate processes cannot read different values from the same ** address at the same time. If either of these two conditions ** are not met, then the mutexes will fail and problems will result. diff -Nru sqlite3-3.42.0/src/mutex_w32.c sqlite3-3.44.0-0/src/mutex_w32.c --- sqlite3-3.42.0/src/mutex_w32.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/mutex_w32.c 2023-11-04 14:23:58.000000000 +0000 @@ -38,7 +38,7 @@ CRITICAL_SECTION mutex; /* Mutex controlling the lock */ int id; /* Mutex type */ #ifdef SQLITE_DEBUG - volatile int nRef; /* Number of enterances */ + volatile int nRef; /* Number of entrances */ volatile DWORD owner; /* Thread holding this mutex */ volatile LONG trace; /* True to trace changes */ #endif diff -Nru sqlite3-3.42.0/src/notify.c sqlite3-3.44.0-0/src/notify.c --- sqlite3-3.42.0/src/notify.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/notify.c 2023-11-04 14:23:58.000000000 +0000 @@ -152,6 +152,9 @@ ){ int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(db->mutex); enterMutex(); diff -Nru sqlite3-3.42.0/src/os.c sqlite3-3.44.0-0/src/os.c --- sqlite3-3.42.0/src/os.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/os.c 2023-11-04 14:23:58.000000000 +0000 @@ -137,7 +137,7 @@ /* Faults are not injected into COMMIT_PHASETWO because, assuming SQLite ** is using a regular VFS, it is called after the corresponding ** transaction has been committed. Injecting a fault at this point - ** confuses the test scripts - the COMMIT comand returns SQLITE_NOMEM + ** confuses the test scripts - the COMMIT command returns SQLITE_NOMEM ** but the transaction is committed anyway. ** ** The core must call OsFileControl() though, not OsFileControlHint(), @@ -279,7 +279,7 @@ }else{ return pVfs->xRandomness(pVfs, nByte, zBufOut); } - + } int sqlite3OsSleep(sqlite3_vfs *pVfs, int nMicro){ return pVfs->xSleep(pVfs, nMicro); diff -Nru sqlite3-3.42.0/src/os_unix.c sqlite3-3.44.0-0/src/os_unix.c --- sqlite3-3.42.0/src/os_unix.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/os_unix.c 2023-11-04 14:23:58.000000000 +0000 @@ -22,7 +22,7 @@ ** This source file is organized into divisions where the logic for various ** subfunctions is contained within the appropriate division. PLEASE ** KEEP THE STRUCTURE OF THIS FILE INTACT. New code should be placed -** in the correct division and should be clearly labeled. +** in the correct division and should be clearly labelled. ** ** The layout of divisions is as follows: ** @@ -61,7 +61,7 @@ ** Styles 4, 5, and 7 are only available of SQLITE_ENABLE_LOCKING_STYLE ** is defined to 1. The SQLITE_ENABLE_LOCKING_STYLE also enables automatic ** selection of the appropriate locking style based on the filesystem -** where the database is located. +** where the database is located. */ #if !defined(SQLITE_ENABLE_LOCKING_STYLE) # if defined(__APPLE__) @@ -226,7 +226,7 @@ #endif /* -** Only set the lastErrno if the error code is a real error and not +** Only set the lastErrno if the error code is a real error and not ** a normal expected return code of SQLITE_BUSY or SQLITE_OK */ #define IS_LOCK_ERROR(x) ((x != SQLITE_OK) && (x != SQLITE_BUSY)) @@ -294,7 +294,7 @@ ** whenever any part of the database changes. An assertion fault will ** occur if a file is updated without also updating the transaction ** counter. This test is made to avoid new problems similar to the - ** one described by ticket #3584. + ** one described by ticket #3584. */ unsigned char transCntrChng; /* True if the transaction counter changed */ unsigned char dbUpdate; /* True if any part of database file changed */ @@ -303,7 +303,7 @@ #endif #ifdef SQLITE_TEST - /* In test mode, increase the size of this structure a bit so that + /* In test mode, increase the size of this structure a bit so that ** it is larger than the struct CrashFile defined in test6.c. */ char aPadding[32]; @@ -448,7 +448,7 @@ #ifdef __DJGPP__ { "fstat", 0, 0 }, #define osFstat(a,b,c) 0 -#else +#else { "fstat", (sqlite3_syscall_ptr)fstat, 0 }, #define osFstat ((int(*)(int,struct stat*))aSyscall[5].pCurrent) #endif @@ -609,7 +609,7 @@ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the -** "unix" VFSes. Return SQLITE_OK opon successfully updating the +** "unix" VFSes. Return SQLITE_OK upon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. */ @@ -692,7 +692,7 @@ /* ** Do not accept any file descriptor less than this value, in order to avoid -** opening database file using file descriptors that are commonly used for +** opening database file using file descriptors that are commonly used for ** standard input, output, and error. */ #ifndef SQLITE_MINIMUM_FILE_DESCRIPTOR @@ -734,7 +734,7 @@ (void)osUnlink(z); } osClose(fd); - sqlite3_log(SQLITE_WARNING, + sqlite3_log(SQLITE_WARNING, "attempt to open \"%s\" as file descriptor %d", z, fd); fd = -1; if( osOpen("/dev/null", O_RDONLY, m)<0 ) break; @@ -742,9 +742,9 @@ if( fd>=0 ){ if( m!=0 ){ struct stat statbuf; - if( osFstat(fd, &statbuf)==0 + if( osFstat(fd, &statbuf)==0 && statbuf.st_size==0 - && (statbuf.st_mode&0777)!=m + && (statbuf.st_mode&0777)!=m ){ osFchmod(fd, m); } @@ -759,11 +759,11 @@ /* ** Helper functions to obtain and relinquish the global mutex. The ** global mutex is used to protect the unixInodeInfo and -** vxworksFileId objects used by this file, all of which may be +** vxworksFileId objects used by this file, all of which may be ** shared by multiple threads. ** -** Function unixMutexHeld() is used to assert() that the global mutex -** is held when required. This function is only used as part of assert() +** Function unixMutexHeld() is used to assert() that the global mutex +** is held when required. This function is only used as part of assert() ** statements. e.g. ** ** unixEnterMutex() @@ -885,7 +885,7 @@ static int robust_ftruncate(int h, sqlite3_int64 sz){ int rc; #ifdef __ANDROID__ - /* On Android, ftruncate() always uses 32-bit offsets, even if + /* On Android, ftruncate() always uses 32-bit offsets, even if ** _FILE_OFFSET_BITS=64 is defined. This means it is unsafe to attempt to ** truncate a file to any size larger than 2GiB. Silently ignore any ** such attempts. */ @@ -901,32 +901,32 @@ ** This routine translates a standard POSIX errno code into something ** useful to the clients of the sqlite3 functions. Specifically, it is ** intended to translate a variety of "try again" errors into SQLITE_BUSY -** and a variety of "please close the file descriptor NOW" errors into +** and a variety of "please close the file descriptor NOW" errors into ** SQLITE_IOERR -** +** ** Errors during initialization of locks, or file system support for locks, ** should handle ENOLCK, ENOTSUP, EOPNOTSUPP separately. */ static int sqliteErrorFromPosixError(int posixError, int sqliteIOErr) { - assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || - (sqliteIOErr == SQLITE_IOERR_UNLOCK) || + assert( (sqliteIOErr == SQLITE_IOERR_LOCK) || + (sqliteIOErr == SQLITE_IOERR_UNLOCK) || (sqliteIOErr == SQLITE_IOERR_RDLOCK) || (sqliteIOErr == SQLITE_IOERR_CHECKRESERVEDLOCK) ); switch (posixError) { - case EACCES: + case EACCES: case EAGAIN: case ETIMEDOUT: case EBUSY: case EINTR: - case ENOLCK: - /* random NFS retry error, unless during file system support + case ENOLCK: + /* random NFS retry error, unless during file system support * introspection, in which it actually means what it says */ return SQLITE_BUSY; - - case EPERM: + + case EPERM: return SQLITE_PERM; - - default: + + default: return sqliteIOErr; } } @@ -941,7 +941,7 @@ ** ** A pointer to an instance of the following structure can be used as a ** unique file ID in VxWorks. Each instance of this structure contains -** a copy of the canonical filename. There is also a reference count. +** a copy of the canonical filename. There is also a reference count. ** The structure is reclaimed when the number of pointers to it drops to ** zero. ** @@ -957,7 +957,7 @@ }; #if OS_VXWORKS -/* +/* ** All unique filenames are held on a linked list headed by this ** variable: */ @@ -1029,7 +1029,7 @@ */ unixEnterMutex(); for(pCandidate=vxworksFileList; pCandidate; pCandidate=pCandidate->pNext){ - if( pCandidate->nName==n + if( pCandidate->nName==n && memcmp(pCandidate->zCanonicalName, pNew->zCanonicalName, n)==0 ){ sqlite3_free(pNew); @@ -1122,7 +1122,7 @@ ** cnt>0 means there are cnt shared locks on the file. ** ** Any attempt to lock or unlock a file first checks the locking -** structure. The fcntl() system call is only invoked to set a +** structure. The fcntl() system call is only invoked to set a ** POSIX lock if the internal lock structure transitions between ** a locked and an unlocked state. ** @@ -1131,7 +1131,7 @@ ** If you close a file descriptor that points to a file that has locks, ** all locks on that file that are owned by the current process are ** released. To work around this problem, each unixInodeInfo object -** maintains a count of the number of pending locks on tha inode. +** maintains a count of the number of pending locks on the inode. ** When an attempt is made to close an unixFile, if there are ** other unixFile open on the same inode that are holding locks, the call ** to close() the file descriptor is deferred until all of the locks clear. @@ -1145,7 +1145,7 @@ ** 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 appliation uses the newer Native Posix Thread Library (NPTL) +** 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 @@ -1155,7 +1155,7 @@ ** ** SQLite used to support LinuxThreads. But support for LinuxThreads ** was dropped beginning with version 3.7.0. SQLite will still work with -** LinuxThreads provided that (1) there is no more than one connection +** LinuxThreads provided that (1) there is no more than one connection ** per database file in the same process and (2) database connections ** do not move across threads. */ @@ -1172,7 +1172,7 @@ /* We are told that some versions of Android contain a bug that ** sizes ino_t at only 32-bits instead of 64-bits. (See ** https://android-review.googlesource.com/#/c/115351/3/dist/sqlite3.c) - ** To work around this, always allocate 64-bits for the inode number. + ** To work around this, always allocate 64-bits for the inode number. ** On small machines that only have 32-bit inodes, this wastes 4 bytes, ** but that should not be a big deal. */ /* WAS: ino_t ino; */ @@ -1260,7 +1260,7 @@ ** strerror_r(). ** ** The first argument passed to the macro should be the error code that -** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). +** will be returned to SQLite (e.g. SQLITE_IOERR_DELETE, SQLITE_CANTOPEN). ** The two subsequent arguments should be the name of the OS function that ** failed (e.g. "unlink", "open") and the associated file-system path, ** if any. @@ -1278,7 +1278,7 @@ /* If this is not a threadsafe build (SQLITE_THREADSAFE==0), then use ** the strerror() function to obtain the human-readable error message ** equivalent to errno. Otherwise, use strerror_r(). - */ + */ #if SQLITE_THREADSAFE && defined(HAVE_STRERROR_R) char aErr[80]; memset(aErr, 0, sizeof(aErr)); @@ -1286,18 +1286,18 @@ /* If STRERROR_R_CHAR_P (set by autoconf scripts) or __USE_GNU is defined, ** assume that the system provides the GNU version of strerror_r() that - ** returns a pointer to a buffer containing the error message. That pointer - ** may point to aErr[], or it may point to some static storage somewhere. - ** Otherwise, assume that the system provides the POSIX version of + ** returns a pointer to a buffer containing the error message. That pointer + ** may point to aErr[], or it may point to some static storage somewhere. + ** Otherwise, assume that the system provides the POSIX version of ** strerror_r(), which always writes an error message into aErr[]. ** ** If the code incorrectly assumes that it is the POSIX version that is ** available, the error message will often be an empty string. Not a - ** huge problem. Incorrectly concluding that the GNU version is available + ** huge problem. Incorrectly concluding that the GNU version is available ** could lead to a segfault though. */ #if defined(STRERROR_R_CHAR_P) || defined(__USE_GNU) - zErr = + zErr = # endif strerror_r(iErrno, aErr, sizeof(aErr)-1); @@ -1347,8 +1347,8 @@ } /* -** Close all file descriptors accumuated in the unixInodeInfo->pUnused list. -*/ +** Close all file descriptors accumulated in the unixInodeInfo->pUnused list. +*/ static void closePendingFds(unixFile *pFile){ unixInodeInfo *pInode = pFile->pInode; UnixUnusedFd *p; @@ -1503,7 +1503,7 @@ #else struct stat buf; return pFile->pInode!=0 && - (osStat(pFile->zPath, &buf)!=0 + (osStat(pFile->zPath, &buf)!=0 || (u64)buf.st_ino!=pFile->pInode->fileId.ino); #endif } @@ -1584,7 +1584,7 @@ } } #endif - + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (unix)\n", pFile->h, rc, reserved)); @@ -1634,7 +1634,7 @@ /* -** Attempt to set a system-lock on the file pFile. The lock is +** Attempt to set a system-lock on the file pFile. The lock is ** described by pLock. ** ** If the pFile was opened read/write from unix-excl, then the only lock @@ -1710,7 +1710,7 @@ ** 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 indentify the 'pending byte' and the 'reserved + ** 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. ** @@ -1718,7 +1718,7 @@ ** 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 Widnows95 lacks a shared-lock capability. So on Windows95, a + ** 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 @@ -1726,20 +1726,20 @@ ** ** 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 - ** 'reserved byte'. + ** 'reserved byte'. ** ** An EXCLUSIVE lock may only be requested after either a SHARED or - ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining - ** a write-lock on the entire 'shared byte range'. Since all other locks - ** require a read-lock on one of the bytes within this range, this ensures - ** that no other locks are held on the database. + ** RESERVED lock is held. An EXCLUSIVE lock is implemented by obtaining + ** a write-lock on the entire 'shared byte range'. Since all other locks + ** require a read-lock on one of the bytes within this range, this ensures + ** that no other locks are held on the database. ** ** If a process that holds a RESERVED lock requests an EXCLUSIVE, then - ** a PENDING lock is obtained first. A PENDING lock is implemented by - ** obtaining a write-lock on the 'pending byte'. This ensures that no new - ** SHARED locks can be obtained, but existing SHARED locks are allowed to + ** a PENDING lock is obtained first. A PENDING lock is implemented by + ** obtaining a write-lock on the 'pending byte'. This ensures that no new + ** SHARED locks can be obtained, but existing SHARED locks are allowed to ** persist. If the call to this function fails to obtain the EXCLUSIVE - ** lock in this case, it holds the PENDING lock intead. The client may + ** lock in this case, it holds the PENDING lock instead. The client may ** then re-attempt the EXCLUSIVE lock later on, after existing SHARED ** locks have cleared. */ @@ -1767,7 +1767,7 @@ /* 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 pendig 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 ); @@ -1782,7 +1782,7 @@ /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ - if( (pFile->eFileLock!=pInode->eFileLock && + if( (pFile->eFileLock!=pInode->eFileLock && (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) ){ rc = SQLITE_BUSY; @@ -1793,7 +1793,7 @@ ** has a SHARED or RESERVED lock, then increment reference counts and ** return SQLITE_OK. */ - if( eFileLock==SHARED_LOCK && + if( eFileLock==SHARED_LOCK && (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ assert( eFileLock==SHARED_LOCK ); assert( pFile->eFileLock==0 ); @@ -1811,7 +1811,7 @@ */ lock.l_len = 1L; lock.l_whence = SEEK_SET; - if( eFileLock==SHARED_LOCK + if( eFileLock==SHARED_LOCK || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLock==RESERVED_LOCK) ){ lock.l_type = (eFileLock==SHARED_LOCK?F_RDLCK:F_WRLCK); @@ -1853,7 +1853,7 @@ if( unixFileLock(pFile, &lock) && rc==SQLITE_OK ){ /* This could happen with a network mount */ tErrno = errno; - rc = SQLITE_IOERR_UNLOCK; + rc = SQLITE_IOERR_UNLOCK; } if( rc ){ @@ -1895,7 +1895,7 @@ } } } - + #ifdef SQLITE_DEBUG /* Set up the transaction-counter change checking flags when @@ -1920,7 +1920,7 @@ end_lock: sqlite3_mutex_leave(pInode->pLockMutex); - OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), + OSTRACE(("LOCK %d %s %s (unix)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; } @@ -1945,11 +1945,11 @@ ** ** If the locking level of the file descriptor is already at or below ** the requested locking level, this routine is a no-op. -** +** ** If handleNFSUnlock is true, then on downgrading an EXCLUSIVE_LOCK to SHARED ** the byte range is divided into 2 parts and the first part is unlocked then -** set to a read lock, then the other part is simply unlocked. This works -** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to +** set to a read lock, then the other part is simply unlocked. This works +** around a bug in BSD NFS lockd (also seen on MacOSX 10.3+) that fails to ** remove the write lock on a region when a read lock is set. */ static int posixUnlock(sqlite3_file *id, int eFileLock, int handleNFSUnlock){ @@ -1987,7 +1987,7 @@ /* downgrading to a shared lock on NFS involves clearing the write lock ** before establishing the readlock - to avoid a race condition we downgrade - ** the lock in 2 blocks, so that part of the range will be covered by a + ** the lock in 2 blocks, so that part of the range will be covered by a ** write lock until the rest is covered by a read lock: ** 1: [WWWWW] ** 2: [....W] @@ -2003,7 +2003,7 @@ if( handleNFSUnlock ){ int tErrno; /* Error code from system call errors */ off_t divSize = SHARED_SIZE - 1; - + lock.l_type = F_UNLCK; lock.l_whence = SEEK_SET; lock.l_start = SHARED_FIRST; @@ -2045,11 +2045,11 @@ lock.l_len = SHARED_SIZE; if( unixFileLock(pFile, &lock) ){ /* In theory, the call to unixFileLock() cannot fail because another - ** process is holding an incompatible lock. If it does, this + ** process is holding an incompatible lock. If it does, this ** indicates that the other process is not following the locking ** protocol. If this happens, return SQLITE_IOERR_RDLOCK. Returning - ** SQLITE_BUSY would confuse the upper layer (in practice it causes - ** an assert to fail). */ + ** SQLITE_BUSY would confuse the upper layer (in practice it causes + ** an assert to fail). */ rc = SQLITE_IOERR_RDLOCK; storeLastErrno(pFile, errno); goto end_unlock; @@ -2125,7 +2125,7 @@ #endif /* -** This function performs the parts of the "close file" operation +** This function performs the parts of the "close file" operation ** common to all locking schemes. It closes the directory and file ** handles, if they are valid, and sets all fields of the unixFile ** structure to 0. @@ -2188,7 +2188,7 @@ if( pInode->nLock ){ /* If there are outstanding locks, do not actually close the file just ** yet because that would clear those locks. Instead, add the file - ** descriptor to pInode->pUnused list. It will be automatically closed + ** descriptor to pInode->pUnused list. It will be automatically closed ** when the last lock is cleared. */ setPendingFd(pFile); @@ -2289,7 +2289,7 @@ unixFile *pFile = (unixFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); reserved = osAccess((const char*)pFile->lockingContext, 0)==0; OSTRACE(("TEST WR-LOCK %d %d %d (dotlock)\n", pFile->h, rc, reserved)); @@ -2343,7 +2343,7 @@ #endif return SQLITE_OK; } - + /* grab an exclusive lock */ rc = osMkdir(zLockFile, 0777); if( rc<0 ){ @@ -2358,8 +2358,8 @@ } } return rc; - } - + } + /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; return rc; @@ -2383,7 +2383,7 @@ OSTRACE(("UNLOCK %d %d was %d pid=%d (dotlock)\n", pFile->h, eFileLock, pFile->eFileLock, osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); - + /* no-op if possible */ if( pFile->eFileLock==eFileLock ){ return SQLITE_OK; @@ -2396,7 +2396,7 @@ pFile->eFileLock = SHARED_LOCK; return SQLITE_OK; } - + /* To fully unlock the database, delete the lock file */ assert( eFileLock==NO_LOCK ); rc = osRmdir(zLockFile); @@ -2408,7 +2408,7 @@ rc = SQLITE_IOERR_UNLOCK; storeLastErrno(pFile, tErrno); } - return rc; + return rc; } pFile->eFileLock = NO_LOCK; return SQLITE_OK; @@ -2455,7 +2455,7 @@ #else # define robust_flock(a,b) flock(a,b) #endif - + /* ** This routine checks if there is a RESERVED lock held on the specified @@ -2467,16 +2467,16 @@ int rc = SQLITE_OK; int reserved = 0; unixFile *pFile = (unixFile*)id; - + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); - + /* Check if a thread in this process holds such a lock */ if( pFile->eFileLock>SHARED_LOCK ){ reserved = 1; } - + /* Otherwise see if some other process holds it. */ if( !reserved ){ /* attempt to get the lock */ @@ -2487,7 +2487,7 @@ if ( lrc ) { int tErrno = errno; /* unlock failed with an error */ - lrc = SQLITE_IOERR_UNLOCK; + lrc = SQLITE_IOERR_UNLOCK; storeLastErrno(pFile, tErrno); rc = lrc; } @@ -2495,7 +2495,7 @@ int tErrno = errno; reserved = 1; /* someone else might have it reserved */ - lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); + lrc = sqliteErrorFromPosixError(tErrno, SQLITE_IOERR_LOCK); if( IS_LOCK_ERROR(lrc) ){ storeLastErrno(pFile, tErrno); rc = lrc; @@ -2549,15 +2549,15 @@ assert( pFile ); - /* if we already have a lock, it is exclusive. + /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ if (pFile->eFileLock > NO_LOCK) { pFile->eFileLock = eFileLock; return SQLITE_OK; } - + /* grab an exclusive lock */ - + if (robust_flock(pFile->h, LOCK_EX | LOCK_NB)) { int tErrno = errno; /* didn't get, must be busy */ @@ -2569,7 +2569,7 @@ /* got it, set the type and return ok */ pFile->eFileLock = eFileLock; } - OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), + OSTRACE(("LOCK %d %s %s (flock)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS if( (rc & 0xff) == SQLITE_IOERR ){ @@ -2589,23 +2589,23 @@ */ static int flockUnlock(sqlite3_file *id, int eFileLock) { unixFile *pFile = (unixFile*)id; - + assert( pFile ); OSTRACE(("UNLOCK %d %d was %d pid=%d (flock)\n", pFile->h, eFileLock, pFile->eFileLock, osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); - + /* no-op if possible */ if( pFile->eFileLock==eFileLock ){ return SQLITE_OK; } - + /* shared can just be set because we always have an exclusive */ if (eFileLock==SHARED_LOCK) { pFile->eFileLock = eFileLock; return SQLITE_OK; } - + /* no, really, unlock. */ if( robust_flock(pFile->h, LOCK_UN) ){ #ifdef SQLITE_IGNORE_FLOCK_LOCK_ERRORS @@ -2656,14 +2656,14 @@ unixFile *pFile = (unixFile*)id; SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); /* Check if a thread in this process holds such a lock */ if( pFile->eFileLock>SHARED_LOCK ){ reserved = 1; } - + /* Otherwise see if some other process holds it. */ if( !reserved ){ sem_t *pSem = pFile->pInode->pSem; @@ -2722,14 +2722,14 @@ sem_t *pSem = pFile->pInode->pSem; int rc = SQLITE_OK; - /* if we already have a lock, it is exclusive. + /* if we already have a lock, it is exclusive. ** Just adjust level and punt on outta here. */ if (pFile->eFileLock > NO_LOCK) { pFile->eFileLock = eFileLock; rc = SQLITE_OK; goto sem_end_lock; } - + /* lock semaphore now but bail out when already locked. */ if( sem_trywait(pSem)==-1 ){ rc = SQLITE_BUSY; @@ -2759,18 +2759,18 @@ OSTRACE(("UNLOCK %d %d was %d pid=%d (sem)\n", pFile->h, eFileLock, pFile->eFileLock, osGetpid(0))); assert( eFileLock<=SHARED_LOCK ); - + /* no-op if possible */ if( pFile->eFileLock==eFileLock ){ return SQLITE_OK; } - + /* shared can just be set because we always have an exclusive */ if (eFileLock==SHARED_LOCK) { pFile->eFileLock = eFileLock; return SQLITE_OK; } - + /* no, really unlock. */ if ( sem_post(pSem)==-1 ) { int rc, tErrno = errno; @@ -2778,7 +2778,7 @@ if( IS_LOCK_ERROR(rc) ){ storeLastErrno(pFile, tErrno); } - return rc; + return rc; } pFile->eFileLock = NO_LOCK; return SQLITE_OK; @@ -2844,7 +2844,7 @@ /* ** This is a utility for setting or clearing a bit-range lock on an ** AFP filesystem. -** +** ** Return SQLITE_OK on success, SQLITE_BUSY on failure. */ static int afpSetLock( @@ -2856,14 +2856,14 @@ ){ struct ByteRangeLockPB2 pb; int err; - + pb.unLockFlag = setLockFlag ? 0 : 1; pb.startEndFlag = 0; pb.offset = offset; - pb.length = length; + pb.length = length; pb.fd = pFile->h; - - OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", + + OSTRACE(("AFPSETLOCK [%s] for %d%s in range %llx:%llx\n", (setLockFlag?"ON":"OFF"), pFile->h, (pb.fd==-1?"[testval-1]":""), offset, length)); err = fsctl(path, afpfsByteRangeLock2FSCTL, &pb, 0); @@ -2898,9 +2898,9 @@ int reserved = 0; unixFile *pFile = (unixFile*)id; afpLockingContext *context; - + SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; ); - + assert( pFile ); context = (afpLockingContext *) pFile->lockingContext; if( context->reserved ){ @@ -2912,12 +2912,12 @@ if( pFile->pInode->eFileLock>SHARED_LOCK ){ reserved = 1; } - + /* Otherwise see if some other process holds it. */ if( !reserved ){ /* lock the RESERVED byte */ - int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); + int lrc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1,1); if( SQLITE_OK==lrc ){ /* if we succeeded in taking the reserved lock, unlock it to restore ** the original state */ @@ -2930,10 +2930,10 @@ rc=lrc; } } - + sqlite3_mutex_leave(pFile->pInode->pLockMutex); OSTRACE(("TEST WR-LOCK %d %d %d (afp)\n", pFile->h, rc, reserved)); - + *pResOut = reserved; return rc; } @@ -2967,7 +2967,7 @@ unixFile *pFile = (unixFile*)id; unixInodeInfo *pInode = pFile->pInode; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; - + assert( pFile ); OSTRACE(("LOCK %d %s was %s(%s,%d) pid=%d (afp)\n", pFile->h, azFileLock(eFileLock), azFileLock(pFile->eFileLock), @@ -2985,13 +2985,13 @@ /* 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 pendig 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 */ pInode = pFile->pInode; @@ -3000,18 +3000,18 @@ /* If some thread using this PID has a lock via a different unixFile* ** handle that precludes the requested lock, return BUSY. */ - if( (pFile->eFileLock!=pInode->eFileLock && + if( (pFile->eFileLock!=pInode->eFileLock && (pInode->eFileLock>=PENDING_LOCK || eFileLock>SHARED_LOCK)) ){ rc = SQLITE_BUSY; goto afp_end_lock; } - + /* If a SHARED lock is requested, and some thread using this PID already ** has a SHARED or RESERVED lock, then increment reference counts and ** return SQLITE_OK. */ - if( eFileLock==SHARED_LOCK && + if( eFileLock==SHARED_LOCK && (pInode->eFileLock==SHARED_LOCK || pInode->eFileLock==RESERVED_LOCK) ){ assert( eFileLock==SHARED_LOCK ); assert( pFile->eFileLock==0 ); @@ -3021,12 +3021,12 @@ pInode->nLock++; goto afp_end_lock; } - + /* A PENDING lock is needed before acquiring a SHARED lock and before ** acquiring an EXCLUSIVE lock. For the SHARED lock, the PENDING will ** be released. */ - if( eFileLock==SHARED_LOCK + if( eFileLock==SHARED_LOCK || (eFileLock==EXCLUSIVE_LOCK && pFile->eFileLocknShared==0 ); assert( pInode->eFileLock==0 ); - + mask = (sizeof(long)==8) ? LARGEST_INT64 : 0x7fffffff; /* Now get the read-lock SHARED_LOCK */ /* note that the quality of the randomness doesn't matter that much */ - lk = random(); + lk = random(); pInode->sharedByte = (lk & mask)%(SHARED_SIZE - 1); - lrc1 = afpSetLock(context->dbPath, pFile, + lrc1 = afpSetLock(context->dbPath, pFile, SHARED_FIRST+pInode->sharedByte, 1, 1); if( IS_LOCK_ERROR(lrc1) ){ lrc1Errno = pFile->lastErrno; } /* Drop the temporary PENDING lock */ lrc2 = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); - + if( IS_LOCK_ERROR(lrc1) ) { storeLastErrno(pFile, lrc1Errno); rc = lrc1; @@ -3094,34 +3094,34 @@ } if (!failed && eFileLock == EXCLUSIVE_LOCK) { /* Acquire an EXCLUSIVE lock */ - - /* Remove the shared lock before trying the range. we'll need to + + /* 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 attemmpt to get the exclusive lock range */ - failed = afpSetLock(context->dbPath, pFile, SHARED_FIRST, + /* 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, + 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 */ - rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : + rc = ((failed & 0xff) == SQLITE_IOERR) ? failed2 : SQLITE_IOERR_LOCK; goto afp_end_lock; - } + } }else{ - rc = failed; + rc = failed; } } if( failed ){ rc = failed; } } - + if( rc==SQLITE_OK ){ pFile->eFileLock = eFileLock; pInode->eFileLock = eFileLock; @@ -3129,10 +3129,10 @@ pFile->eFileLock = PENDING_LOCK; pInode->eFileLock = PENDING_LOCK; } - + afp_end_lock: sqlite3_mutex_leave(pInode->pLockMutex); - OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), + OSTRACE(("LOCK %d %s %s (afp)\n", pFile->h, azFileLock(eFileLock), rc==SQLITE_OK ? "ok" : "failed")); return rc; } @@ -3150,9 +3150,6 @@ unixInodeInfo *pInode; afpLockingContext *context = (afpLockingContext *) pFile->lockingContext; int skipShared = 0; -#ifdef SQLITE_TEST - int h = pFile->h; -#endif assert( pFile ); OSTRACE(("UNLOCK %d %d was %d(%d,%d) pid=%d (afp)\n", pFile->h, eFileLock, @@ -3168,10 +3165,7 @@ assert( pInode->nShared!=0 ); if( pFile->eFileLock>SHARED_LOCK ){ assert( pInode->eFileLock==pFile->eFileLock ); - SimulateIOErrorBenign(1); - SimulateIOError( h=(-1) ) - SimulateIOErrorBenign(0); - + #ifdef SQLITE_DEBUG /* When reducing a lock such that other processes can start ** reading the database file again, make sure that the @@ -3186,7 +3180,7 @@ || pFile->transCntrChng==1 ); pFile->inNormalWrite = 0; #endif - + if( pFile->eFileLock==EXCLUSIVE_LOCK ){ rc = afpSetLock(context->dbPath, pFile, SHARED_FIRST, SHARED_SIZE, 0); if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1) ){ @@ -3199,11 +3193,11 @@ } if( rc==SQLITE_OK && pFile->eFileLock>=PENDING_LOCK ){ rc = afpSetLock(context->dbPath, pFile, PENDING_BYTE, 1, 0); - } + } if( rc==SQLITE_OK && pFile->eFileLock>=RESERVED_LOCK && context->reserved ){ rc = afpSetLock(context->dbPath, pFile, RESERVED_BYTE, 1, 0); - if( !rc ){ - context->reserved = 0; + if( !rc ){ + context->reserved = 0; } } if( rc==SQLITE_OK && (eFileLock==SHARED_LOCK || pInode->nShared>1)){ @@ -3219,9 +3213,6 @@ unsigned long long sharedLockByte = SHARED_FIRST+pInode->sharedByte; pInode->nShared--; if( pInode->nShared==0 ){ - SimulateIOErrorBenign(1); - SimulateIOError( h=(-1) ) - SimulateIOErrorBenign(0); if( !skipShared ){ rc = afpSetLock(context->dbPath, pFile, sharedLockByte, 1, 0); } @@ -3236,7 +3227,7 @@ if( pInode->nLock==0 ) closePendingFds(pFile); } } - + sqlite3_mutex_leave(pInode->pLockMutex); if( rc==SQLITE_OK ){ pFile->eFileLock = eFileLock; @@ -3245,7 +3236,7 @@ } /* -** Close a file & cleanup AFP specific locking context +** Close a file & cleanup AFP specific locking context */ static int afpClose(sqlite3_file *id) { int rc = SQLITE_OK; @@ -3303,7 +3294,7 @@ /* ** The code above is the NFS lock implementation. The code is specific ** to MacOSX and does not work on other unix platforms. No alternative -** is available. +** is available. ** ********************* End of the NFS lock implementation ********************** ******************************************************************************/ @@ -3311,7 +3302,7 @@ /****************************************************************************** **************** Non-locking sqlite3_file methods ***************************** ** -** The next division contains implementations for all methods of the +** The next division contains implementations for all methods of the ** sqlite3_file object other than the locking methods. The locking ** methods were defined in divisions above (one locking method per ** division). Those methods that are common to all locking modes @@ -3319,7 +3310,7 @@ */ /* -** Seek to the offset passed as the second argument, then read cnt +** Seek to the offset passed as the second argument, then read cnt ** bytes into pBuf. Return the number of bytes actually read. ** ** To avoid stomping the errno value on a failed read the lastErrno value @@ -3375,8 +3366,8 @@ ** wrong. */ static int unixRead( - sqlite3_file *id, - void *pBuf, + sqlite3_file *id, + void *pBuf, int amt, sqlite3_int64 offset ){ @@ -3391,12 +3382,12 @@ #if 0 assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE + || offset+amt<=PENDING_BYTE ); #endif #if SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this read request as possible by transfering + /* Deal with as much of this read request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -3446,7 +3437,7 @@ /* ** Attempt to seek the file-descriptor passed as the first argument to ** absolute offset iOff, then attempt to write nBuf bytes of data from -** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, +** pBuf to it. If an error occurs, return -1 and set *piErrno. Otherwise, ** return the actual number of bytes written (which may be less than ** nBuf). */ @@ -3506,10 +3497,10 @@ ** or some other error code on failure. */ static int unixWrite( - sqlite3_file *id, - const void *pBuf, + sqlite3_file *id, + const void *pBuf, int amt, - sqlite3_int64 offset + sqlite3_int64 offset ){ unixFile *pFile = (unixFile*)id; int wrote = 0; @@ -3521,7 +3512,7 @@ #if 0 assert( pFile->pPreallocatedUnused==0 || offset>=PENDING_BYTE+512 - || offset+amt<=PENDING_BYTE + || offset+amt<=PENDING_BYTE ); #endif @@ -3548,7 +3539,7 @@ #endif #if defined(SQLITE_MMAP_READWRITE) && SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this write request as possible by transfering + /* Deal with as much of this write request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -3563,7 +3554,7 @@ } } #endif - + while( (wrote = seekAndWrite(pFile, offset, pBuf, amt))0 ){ amt -= wrote; offset += wrote; @@ -3629,8 +3620,8 @@ ** ** SQLite sets the dataOnly flag if the size of the file is unchanged. ** The idea behind dataOnly is that it should only write the file content -** to disk, not the inode. We only set dataOnly if the file size is -** unchanged since the file size is part of the inode. However, +** to disk, not the inode. We only set dataOnly if the file size is +** unchanged since the file size is part of the inode. However, ** Ted Ts'o tells us that fdatasync() will also write the inode if the ** file size has changed. The only real difference between fdatasync() ** and fsync(), Ted tells us, is that fdatasync() will not flush the @@ -3644,7 +3635,7 @@ int rc; /* The following "ifdef/elif/else/" block has the same structure as - ** the one below. It is replicated here solely to avoid cluttering + ** the one below. It is replicated here solely to avoid cluttering ** up the real code with the UNUSED_PARAMETER() macros. */ #ifdef SQLITE_NO_SYNC @@ -3658,7 +3649,7 @@ UNUSED_PARAMETER(dataOnly); #endif - /* Record the number of times that we do a normal fsync() and + /* Record the number of times that we do a normal fsync() and ** FULLSYNC. This is used during testing to verify that this procedure ** gets called with the correct arguments. */ @@ -3670,7 +3661,7 @@ /* 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 - ** coverate testing. + ** coverage testing. */ #ifdef SQLITE_NO_SYNC { @@ -3684,11 +3675,11 @@ rc = 1; } /* If the FULLFSYNC failed, fall back to attempting an fsync(). - ** It shouldn't be possible for fullfsync to fail on the local + ** It shouldn't be possible for fullfsync to fail on the local ** file system (on OSX), so failure indicates that FULLFSYNC - ** isn't supported for this file system. So, attempt an fsync - ** and (for now) ignore the overhead of a superfluous fcntl call. - ** It'd be better to detect fullfsync support once and avoid + ** isn't supported for this file system. So, attempt an fsync + ** and (for now) ignore the overhead of a superfluous fcntl call. + ** It'd be better to detect fullfsync support once and avoid ** the fcntl call every time sync is called. */ if( rc ) rc = fsync(fd); @@ -3698,7 +3689,7 @@ ** so currently we default to the macro that redefines fdatasync to fsync */ rc = fsync(fd); -#else +#else rc = fdatasync(fd); #if OS_VXWORKS if( rc==-1 && errno==ENOTSUP ){ @@ -3859,7 +3850,7 @@ #if SQLITE_MAX_MMAP_SIZE>0 /* If the file was just truncated to a size smaller than the currently ** mapped region, reduce the effective mapping size as well. SQLite will - ** use read() and write() to access data beyond this point from now on. + ** use read() and write() to access data beyond this point from now on. */ if( nBytemmapSize ){ pFile->mmapSize = nByte; @@ -3905,8 +3896,8 @@ static int proxyFileControl(sqlite3_file*,int,void*); #endif -/* -** This function is called to handle the SQLITE_FCNTL_SIZE_HINT +/* +** This function is called to handle the SQLITE_FCNTL_SIZE_HINT ** file-control operation. Enlarge the database to nBytes in size ** (rounded up to the next chunk-size). If the database is already ** nBytes or larger, this routine is a no-op. @@ -3915,7 +3906,7 @@ if( pFile->szChunk>0 ){ i64 nSize; /* Required file size */ struct stat buf; /* Used to hold return values of fstat() */ - + if( osFstat(pFile->h, &buf) ){ return SQLITE_IOERR_FSTAT; } @@ -3924,8 +3915,8 @@ if( nSize>(i64)buf.st_size ){ #if defined(HAVE_POSIX_FALLOCATE) && HAVE_POSIX_FALLOCATE - /* The code below is handling the return value of osFallocate() - ** correctly. posix_fallocate() is defined to "returns zero on success, + /* The code below is handling the return value of osFallocate() + ** correctly. posix_fallocate() is defined to "returns zero on success, ** or an error number on failure". See the manpage for details. */ int err; do{ @@ -3933,7 +3924,7 @@ }while( err==EINTR ); if( err && err!=EINVAL ) return SQLITE_IOERR_WRITE; #else - /* If the OS does not have posix_fallocate(), fake it. Write a + /* If the OS does not have posix_fallocate(), fake it. Write a ** single byte to the last byte in each block that falls entirely ** within the extended region. Then, if required, a single byte ** at offset (nSize-1), to set the size of the file correctly. @@ -4126,9 +4117,9 @@ /* ** If pFd->sectorSize is non-zero when this function is called, it is a -** no-op. Otherwise, the values of pFd->sectorSize and -** pFd->deviceCharacteristics are set according to the file-system -** characteristics. +** no-op. Otherwise, the values of pFd->sectorSize and +** pFd->deviceCharacteristics are set according to the file-system +** characteristics. ** ** There are two versions of this function. One for QNX and one for all ** other systems. @@ -4162,7 +4153,7 @@ static void setDeviceCharacteristics(unixFile *pFile){ if( pFile->sectorSize == 0 ){ struct statvfs fsInfo; - + /* Set defaults for non-supported filesystems */ pFile->sectorSize = SQLITE_DEFAULT_SECTOR_SIZE; pFile->deviceCharacteristics = 0; @@ -4271,7 +4262,7 @@ /* ** Return the system page size. ** -** This function should not be called directly by other code in this file. +** This function should not be called directly by other code in this file. ** Instead, it should be called via macro osGetpagesize(). */ static int unixGetpagesize(void){ @@ -4289,7 +4280,7 @@ #ifndef SQLITE_OMIT_WAL /* -** Object used to represent an shared memory buffer. +** Object used to represent an shared memory buffer. ** ** When multiple threads all reference the same wal-index, each thread ** has its own unixShm object, but they all point to a single instance @@ -4309,7 +4300,7 @@ ** nRef ** ** The following fields are read-only after the object is created: -** +** ** hShm ** zFilename ** @@ -4368,7 +4359,7 @@ /* ** Use F_GETLK to check whether or not there are any readers with open ** wal-mode transactions in other processes on database file pFile. If -** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are +** no error occurs, return SQLITE_OK and set (*piOut) to 1 if there are ** such transactions, or 0 otherwise. If an error occurs, return an ** SQLite error code. The final value of *piOut is undefined in this ** case. @@ -4478,7 +4469,7 @@ } #endif - return rc; + return rc; } /* @@ -4534,7 +4525,7 @@ ** take it now. Return SQLITE_OK if successful, or an SQLite error ** code otherwise. ** -** If the DMS cannot be locked because this is a readonly_shm=1 +** If the DMS cannot be locked because this is a readonly_shm=1 ** connection and no other process already holds a lock, return ** SQLITE_READONLY_CANTINIT and set pShmNode->isUnlocked=1. */ @@ -4545,7 +4536,7 @@ /* Use F_GETLK to determine the locks other processes are holding ** on the DMS byte. If it indicates that another process is holding ** a SHARED lock, then this process may also take a SHARED lock - ** and proceed with opening the *-shm file. + ** and proceed with opening the *-shm file. ** ** Or, if no other process is holding any lock, then this process ** is the first to open it. In this case take an EXCLUSIVE lock on the @@ -4593,20 +4584,20 @@ } /* -** Open a shared-memory area associated with open database file pDbFd. +** Open a shared-memory area associated with open database file pDbFd. ** This particular implementation uses mmapped files. ** ** The file used to implement shared-memory is in the same directory ** as the open database file and has the same name as the open database ** file with the "-shm" suffix added. For example, if the database file ** is "/home/user1/config.db" then the file that is created and mmapped -** for shared memory will be called "/home/user1/config.db-shm". +** for shared memory will be called "/home/user1/config.db-shm". ** ** Another approach to is to use files in /dev/shm or /dev/tmp or an ** some other tmpfs mount. But if a file in a different directory ** from the database file is used, then differing access permissions ** or a chroot() might cause two different processes on the same -** database to end up using different files for shared memory - +** database to end up using different files for shared memory - ** meaning that their memory would not really be shared - resulting ** in database corruption. Nevertheless, this tmpfs file usage ** can be enabled at compile-time using -DSQLITE_SHM_DIRECTORY="/dev/shm" @@ -4676,7 +4667,7 @@ memset(pShmNode, 0, sizeof(*pShmNode)+nShmFilename); zShm = pShmNode->zFilename = (char*)&pShmNode[1]; #ifdef SQLITE_SHM_DIRECTORY - sqlite3_snprintf(nShmFilename, zShm, + sqlite3_snprintf(nShmFilename, zShm, SQLITE_SHM_DIRECTORY "/sqlite-shm-%x-%x", (u32)sStat.st_ino, (u32)sStat.st_dev); #else @@ -4751,22 +4742,22 @@ } /* -** This function is called to obtain a pointer to region iRegion of the -** shared-memory associated with the database file fd. Shared-memory regions -** are numbered starting from zero. Each shared-memory region is szRegion +** This function is called to obtain a pointer to region iRegion of the +** shared-memory associated with the database file fd. Shared-memory regions +** are numbered starting from zero. Each shared-memory region is szRegion ** bytes in size. ** ** If an error occurs, an error code is returned and *pp is set to NULL. ** ** Otherwise, if the bExtend parameter is 0 and the requested shared-memory ** region has not been allocated (by any client, including one running in a -** separate process), then *pp is set to NULL and SQLITE_OK returned. If -** bExtend is non-zero and the requested shared-memory region has not yet +** separate process), then *pp is set to NULL and SQLITE_OK returned. If +** bExtend is non-zero and the requested shared-memory region has not yet ** been allocated, it is allocated by this function. ** ** If the shared-memory region has already been allocated or is allocated by -** this call as described above, then it is mapped into this processes -** address space (if it is not already), *pp is set to point to the mapped +** this call as described above, then it is mapped into this processes +** address space (if it is not already), *pp is set to point to the mapped ** memory and SQLITE_OK returned. */ static int unixShmMap( @@ -4821,7 +4812,7 @@ rc = SQLITE_IOERR_SHMSIZE; goto shmpage_out; } - + if( sStat.st_sizehShm>=0 ){ pMem = osMmap(0, nMap, - pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, + pShmNode->isReadonly ? PROT_READ : PROT_READ|PROT_WRITE, MAP_SHARED, pShmNode->hShm, szRegion*(i64)pShmNode->nRegion ); if( pMem==MAP_FAILED ){ @@ -4984,7 +4975,7 @@ ** ** In other words, if this is a blocking lock, none of the locks that ** occur later in the above list than the lock being obtained may be - ** held. + ** held. ** ** It is not permitted to block on the RECOVER lock. */ @@ -5026,7 +5017,7 @@ if( rc==SQLITE_OK ){ p->exclMask &= ~mask; p->sharedMask &= ~mask; - } + } } }else if( flags & SQLITE_SHM_SHARED ){ assert( n==1 ); @@ -5077,7 +5068,7 @@ } /* -** Implement a memory barrier or memory fence on shared memory. +** Implement a memory barrier or memory fence on shared memory. ** ** All loads and stores begun before the barrier must complete before ** any load or store begun after the barrier. @@ -5087,15 +5078,15 @@ ){ UNUSED_PARAMETER(fd); sqlite3MemoryBarrier(); /* compiler-defined memory barrier */ - assert( fd->pMethods->xLock==nolockLock - || unixFileMutexNotheld((unixFile*)fd) + assert( fd->pMethods->xLock==nolockLock + || unixFileMutexNotheld((unixFile*)fd) ); unixEnterMutex(); /* Also mutex, for redundancy */ unixLeaveMutex(); } /* -** Close a connection to shared-memory. Delete the underlying +** Close a connection to shared-memory. Delete the underlying ** storage if deleteFlag is true. ** ** If there is no shared memory associated with the connection then this @@ -5169,7 +5160,7 @@ } /* -** Attempt to set the size of the memory mapping maintained by file +** Attempt to set the size of the memory mapping maintained by file ** descriptor pFd to nNew bytes. Any existing mapping is discarded. ** ** If successful, this function sets the following variables: @@ -5261,14 +5252,14 @@ /* ** Memory map or remap the file opened by file-descriptor pFd (if the file -** is already mapped, the existing mapping is replaced by the new). Or, if -** there already exists a mapping for this file, and there are still +** is already mapped, the existing mapping is replaced by the new). Or, if +** there already exists a mapping for this file, and there are still ** outstanding xFetch() references to it, this function is a no-op. ** -** If parameter nByte is non-negative, then it is the requested size of -** the mapping to create. Otherwise, if nByte is less than zero, then the +** If parameter nByte is non-negative, then it is the requested size of +** the mapping to create. Otherwise, if nByte is less than zero, then the ** requested size is the size of the file on disk. The actual size of the -** created mapping is either the requested size or the value configured +** created mapping is either the requested size or the value configured ** using SQLITE_FCNTL_MMAP_LIMIT, whichever is smaller. ** ** SQLITE_OK is returned if no error occurs (even if the mapping is not @@ -5309,7 +5300,7 @@ ** Finally, if an error does occur, return an SQLite error code. The final ** value of *pp is undefined in this case. ** -** If this function does return a pointer, the caller must eventually +** If this function does return a pointer, the caller must eventually ** release the reference by calling unixUnfetch(). */ static int unixFetch(sqlite3_file *fd, i64 iOff, int nAmt, void **pp){ @@ -5334,13 +5325,13 @@ } /* -** If the third argument is non-NULL, then this function releases a +** If the third argument is non-NULL, then this function releases a ** reference obtained by an earlier call to unixFetch(). The second ** argument passed to this function must be the same as the corresponding -** argument that was passed to the unixFetch() invocation. +** argument that was passed to the unixFetch() invocation. ** -** Or, if the third argument is NULL, then this function is being called -** to inform the VFS layer that, according to POSIX, any existing mapping +** Or, if the third argument is NULL, then this function is being called +** to inform the VFS layer that, according to POSIX, any existing mapping ** may now be invalid and should be unmapped. */ static int unixUnfetch(sqlite3_file *fd, i64 iOff, void *p){ @@ -5348,7 +5339,7 @@ unixFile *pFd = (unixFile *)fd; /* The underlying database file */ UNUSED_PARAMETER(iOff); - /* If p==0 (unmap the entire file) then there must be no outstanding + /* If p==0 (unmap the entire file) then there must be no outstanding ** xFetch references. Or, if p!=0 (meaning it is an xFetch reference), ** then there must be at least one outstanding. */ assert( (p==0)==(pFd->nFetchOut==0) ); @@ -5556,8 +5547,8 @@ #endif #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE -/* -** This "finder" function attempts to determine the best locking strategy +/* +** This "finder" function attempts to determine the best locking strategy ** for the database file "filePath". It then returns the sqlite3_io_methods ** object that implements that strategy. ** @@ -5599,8 +5590,8 @@ } /* Default case. Handles, amongst others, "nfs". - ** Test byte-range lock using fcntl(). If the call succeeds, - ** assume that the file-system supports POSIX style locks. + ** Test byte-range lock using fcntl(). If the call succeeds, + ** assume that the file-system supports POSIX style locks. */ lockInfo.l_len = 1; lockInfo.l_start = 0; @@ -5616,7 +5607,7 @@ return &dotlockIoMethods; } } -static const sqlite3_io_methods +static const sqlite3_io_methods *(*const autolockIoFinder)(const char*,unixFile*) = autolockIoFinderImpl; #endif /* defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE */ @@ -5652,7 +5643,7 @@ return &semIoMethods; } } -static const sqlite3_io_methods +static const sqlite3_io_methods *(*const vxworksIoFinder)(const char*,unixFile*) = vxworksIoFinderImpl; #endif /* OS_VXWORKS */ @@ -5780,14 +5771,14 @@ robust_close(pNew, h, __LINE__); h = -1; } - unixLeaveMutex(); + unixLeaveMutex(); } } #endif else if( pLockingStyle == &dotlockIoMethods ){ /* Dotfile locking uses the file path so it needs to be included in - ** the dotlockLockingContext + ** the dotlockLockingContext */ char *zLockFile; int nFilename; @@ -5825,7 +5816,7 @@ unixLeaveMutex(); } #endif - + storeLastErrno(pNew, 0); #if OS_VXWORKS if( rc!=SQLITE_OK ){ @@ -5900,7 +5891,7 @@ /* It's odd to simulate an io-error here, but really this is just ** using the io-error infrastructure to test that SQLite handles this - ** function failing. + ** function failing. */ zBuf[0] = 0; SimulateIOError( return SQLITE_IOERR ); @@ -5937,7 +5928,7 @@ #endif /* -** Search for an unused file descriptor that was opened on the database +** Search for an unused file descriptor that was opened on the database ** file (not a journal or super-journal file) identified by pathname ** zPath with SQLITE_OPEN_XXX flags matching those passed as the second ** argument to this function. @@ -5946,7 +5937,7 @@ ** but the associated file descriptor could not be closed because some ** other file descriptor open on the same file is holding a file-lock. ** Refer to comments in the unixClose() function and the lengthy comment -** describing "Posix Advisory Locking" at the start of this file for +** describing "Posix Advisory Locking" at the start of this file for ** further details. Also, ticket #4018. ** ** If a suitable file descriptor is found, then it is returned. If no @@ -5957,8 +5948,8 @@ /* Do not search for an unused file descriptor on vxworks. Not because ** vxworks would not benefit from the change (it might, we're not sure), - ** but because no way to test it is currently available. It is better - ** not to risk breaking vxworks support for the sake of such an obscure + ** but because no way to test it is currently available. It is better + ** not to risk breaking vxworks support for the sake of such an obscure ** feature. */ #if !OS_VXWORKS struct stat sStat; /* Results of stat() call */ @@ -6000,7 +5991,7 @@ } /* -** Find the mode, uid and gid of file zFile. +** Find the mode, uid and gid of file zFile. */ static int getFileMode( const char *zFile, /* File name */ @@ -6024,16 +6015,16 @@ ** This function is called by unixOpen() to determine the unix permissions ** to create new files with. If no error occurs, then SQLITE_OK is returned ** and a value suitable for passing as the third argument to open(2) is -** written to *pMode. If an IO error occurs, an SQLite error code is +** written to *pMode. If an IO error occurs, an SQLite error code is ** returned and the value of *pMode is not modified. ** ** In most cases, this routine sets *pMode to 0, which will become ** an indication to robust_open() to create the file using ** SQLITE_DEFAULT_FILE_PERMISSIONS adjusted by the umask. -** But if the file being opened is a WAL or regular journal file, then -** this function queries the file-system for the permissions on the -** corresponding database file and sets *pMode to this value. Whenever -** possible, WAL and journal files are created using the same permissions +** But if the file being opened is a WAL or regular journal file, then +** this function queries the file-system for the permissions on the +** corresponding database file and sets *pMode to this value. Whenever +** possible, WAL and journal files are created using the same permissions ** as the associated database file. ** ** If the SQLITE_ENABLE_8_3_NAMES option is enabled, then the @@ -6065,7 +6056,7 @@ ** "-journalNN" ** "-walNN" ** - ** where NN is a decimal number. The NN naming schemes are + ** where NN is a decimal number. The NN naming schemes are ** used by the test_multiplex.c module. ** ** In normal operation, the journal file name will always contain @@ -6101,7 +6092,7 @@ /* ** Open the file zPath. -** +** ** Previously, the SQLite OS layer used three functions in place of this ** one: ** @@ -6112,13 +6103,13 @@ ** These calls correspond to the following combinations of flags: ** ** ReadWrite() -> (READWRITE | CREATE) -** ReadOnly() -> (READONLY) +** ReadOnly() -> (READONLY) ** OpenExclusive() -> (READWRITE | CREATE | EXCLUSIVE) ** ** The old OpenExclusive() accepted a boolean argument - "delFlag". If ** true, the file was configured to be automatically deleted when the -** file handle closed. To achieve the same effect using this new -** interface, add the DELETEONCLOSE flag to those specified above for +** file handle closed. To achieve the same effect using this new +** interface, add the DELETEONCLOSE flag to those specified above for ** OpenExclusive(). */ static int unixOpen( @@ -6153,8 +6144,8 @@ ** is called the directory file descriptor will be fsync()ed and close()d. */ int isNewJrnl = (isCreate && ( - eType==SQLITE_OPEN_SUPER_JOURNAL - || eType==SQLITE_OPEN_MAIN_JOURNAL + eType==SQLITE_OPEN_SUPER_JOURNAL + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_WAL )); @@ -6164,9 +6155,9 @@ char zTmpname[MAX_PATHNAME+2]; const char *zName = zPath; - /* Check the following statements are true: + /* Check the following statements are true: ** - ** (a) Exactly one of the READWRITE and READONLY flags must be set, and + ** (a) Exactly one of the READWRITE and READONLY flags must be set, and ** (b) if CREATE is set, then READWRITE must also be set, and ** (c) if EXCLUSIVE is set, then CREATE must also be set. ** (d) if DELETEONCLOSE is set, then CREATE must also be set. @@ -6176,7 +6167,7 @@ assert(isExclusive==0 || isCreate); assert(isDelete==0 || isCreate); - /* The main DB, main journal, WAL file and super-journal are never + /* The main DB, main journal, WAL file and super-journal are never ** automatically deleted. Nor are they ever temporary files. */ assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_DB ); assert( (!isDelete && zName) || eType!=SQLITE_OPEN_MAIN_JOURNAL ); @@ -6184,9 +6175,9 @@ assert( (!isDelete && zName) || eType!=SQLITE_OPEN_WAL ); /* Assert that the upper layer has set one of the "file-type" flags. */ - assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB - || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL - || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL + assert( eType==SQLITE_OPEN_MAIN_DB || eType==SQLITE_OPEN_TEMP_DB + || eType==SQLITE_OPEN_MAIN_JOURNAL || eType==SQLITE_OPEN_TEMP_JOURNAL + || eType==SQLITE_OPEN_SUBJOURNAL || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_TRANSIENT_DB || eType==SQLITE_OPEN_WAL ); @@ -6240,7 +6231,7 @@ /* Determine the value of the flags parameter passed to POSIX function ** open(). These must be calculated even if open() is not called, as - ** they may be stored as part of the file handle and used by the + ** they may be stored as part of the file handle and used by the ** 'conch file' locking functions later on. */ if( isReadonly ) openFlags |= O_RDONLY; if( isReadWrite ) openFlags |= O_RDWR; @@ -6305,7 +6296,7 @@ if( p->pPreallocatedUnused ){ p->pPreallocatedUnused->fd = fd; - p->pPreallocatedUnused->flags = + p->pPreallocatedUnused->flags = flags & (SQLITE_OPEN_READONLY|SQLITE_OPEN_READWRITE); } @@ -6327,7 +6318,7 @@ p->openFlags = openFlags; } #endif - + #if defined(__APPLE__) || SQLITE_ENABLE_LOCKING_STYLE if( fstatfs(fd, &fsInfo) == -1 ){ storeLastErrno(p, errno); @@ -6358,7 +6349,7 @@ char *envforce = getenv("SQLITE_FORCE_PROXY_LOCKING"); int useProxy = 0; - /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means + /* SQLITE_FORCE_PROXY_LOCKING==1 means force always use proxy, 0 means ** never use proxy, NULL means use proxy for non-local files only. */ if( envforce!=NULL ){ useProxy = atoi(envforce)>0; @@ -6370,9 +6361,9 @@ if( rc==SQLITE_OK ){ rc = proxyTransformUnixFile((unixFile*)pFile, ":auto:"); if( rc!=SQLITE_OK ){ - /* Use unixClose to clean up the resources added in fillInUnixFile - ** and clear all the structure's references. Specifically, - ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op + /* Use unixClose to clean up the resources added in fillInUnixFile + ** and clear all the structure's references. Specifically, + ** pFile->pMethods will be NULL so sqlite3OsClose will be a no-op */ unixClose(pFile); return rc; @@ -6382,9 +6373,9 @@ } } #endif - - assert( zPath==0 || zPath[0]=='/' - || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL + + assert( zPath==0 || zPath[0]=='/' + || eType==SQLITE_OPEN_SUPER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL ); rc = fillInUnixFile(pVfs, fd, pFile, zPath, ctrlFlags); @@ -6569,9 +6560,9 @@ /* ** Turn a relative pathname into a full pathname. The relative path ** is stored as a nul-terminated string in the buffer pointed to by -** zPath. +** zPath. ** -** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes +** zOut points to a buffer of at least sqlite3_vfs.mxPathname bytes ** (in this case, MAX_PATHNAME bytes). The full-path is written to ** this buffer before returning. */ @@ -6631,7 +6622,7 @@ unixLeaveMutex(); } static void (*unixDlSym(sqlite3_vfs *NotUsed, void *p, const char*zSym))(void){ - /* + /* ** GCC with -pedantic-errors says that C90 does not allow a void* to be ** cast into a pointer to a function. And yet the library dlsym() routine ** returns a void* which is really a pointer to a function. So how do we @@ -6641,7 +6632,7 @@ ** parameters void* and const char* and returning a pointer to a function. ** We initialize x by assigning it a pointer to the dlsym() function. ** (That assignment requires a cast.) Then we call the function that - ** x points to. + ** x points to. ** ** This work-around is unlikely to work correctly on any system where ** you really cannot cast a function pointer into void*. But then, on the @@ -6684,7 +6675,7 @@ ** tests repeatable. */ memset(zBuf, 0, nBuf); - randomnessPid = osGetpid(0); + randomnessPid = osGetpid(0); #if !defined(SQLITE_TEST) && !defined(SQLITE_OMIT_RANDOMNESS) { int fd, got; @@ -6715,12 +6706,17 @@ ** than the argument. */ static int unixSleep(sqlite3_vfs *NotUsed, int microseconds){ -#if OS_VXWORKS || _POSIX_C_SOURCE >= 199309L +#if !defined(HAVE_NANOSLEEP) || HAVE_NANOSLEEP+0 struct timespec sp; - sp.tv_sec = microseconds / 1000000; sp.tv_nsec = (microseconds % 1000000) * 1000; + + /* Almost all modern unix systems support nanosleep(). But if you are + ** compiling for one of the rare exceptions, you can use + ** -DHAVE_NANOSLEEP=0 (perhaps in conjuction with -DHAVE_USLEEP if + ** usleep() is available) in order to bypass the use of nanosleep() */ nanosleep(&sp, NULL); + UNUSED_PARAMETER(NotUsed); return microseconds; #elif defined(HAVE_USLEEP) && HAVE_USLEEP @@ -6752,7 +6748,7 @@ ** epoch of noon in Greenwich on November 24, 4714 B.C according to the ** proleptic Gregorian calendar. ** -** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date +** On success, return SQLITE_OK. Return SQLITE_ERROR if the time and date ** cannot be found. */ static int unixCurrentTimeInt64(sqlite3_vfs *NotUsed, sqlite3_int64 *piNow){ @@ -6859,7 +6855,7 @@ ** To address the performance and cache coherency issues, proxy file locking ** changes the way database access is controlled by limiting access to a ** single host at a time and moving file locks off of the database file -** and onto a proxy file on the local file system. +** and onto a proxy file on the local file system. ** ** ** Using proxy locks @@ -6885,19 +6881,19 @@ ** actual proxy file name is generated from the name and path of the ** database file. For example: ** -** For database path "/Users/me/foo.db" +** For database path "/Users/me/foo.db" ** The lock path will be "/sqliteplocks/_Users_me_foo.db:auto:") ** ** Once a lock proxy is configured for a database connection, it can not ** be removed, however it may be switched to a different proxy path via ** the above APIs (assuming the conch file is not being held by another -** connection or process). +** connection or process). ** ** ** How proxy locking works ** ----------------------- ** -** Proxy file locking relies primarily on two new supporting files: +** Proxy file locking relies primarily on two new supporting files: ** ** * conch file to limit access to the database file to a single host ** at a time @@ -6924,11 +6920,11 @@ ** host (the conch ensures that they all use the same local lock file). ** ** Requesting the lock proxy does not immediately take the conch, it is -** only taken when the first request to lock database file is made. +** only taken when the first request to lock database file is made. ** This matches the semantics of the traditional locking behavior, where ** opening a connection to a database file does not take a lock on it. -** The shared lock and an open file descriptor are maintained until -** the connection to the database is closed. +** The shared lock and an open file descriptor are maintained until +** the connection to the database is closed. ** ** The proxy file and the lock file are never deleted so they only need ** to be created the first time they are used. @@ -6942,7 +6938,7 @@ ** automatically configured for proxy locking, lock files are ** named automatically using the same logic as ** PRAGMA lock_proxy_file=":auto:" -** +** ** SQLITE_PROXY_DEBUG ** ** Enables the logging of error messages during host id file @@ -6957,8 +6953,8 @@ ** ** Permissions to use when creating a directory for storing the ** lock proxy files, only used when LOCKPROXYDIR is not set. -** -** +** +** ** As mentioned above, when compiled with SQLITE_PREFER_PROXY_LOCKING, ** setting the environment variable SQLITE_FORCE_PROXY_LOCKING to 1 will ** force proxy locking to be used for every database file opened, and 0 @@ -6968,12 +6964,12 @@ */ /* -** Proxy locking is only available on MacOSX +** Proxy locking is only available on MacOSX */ #if defined(__APPLE__) && SQLITE_ENABLE_LOCKING_STYLE /* -** The proxyLockingContext has the path and file structures for the remote +** The proxyLockingContext has the path and file structures for the remote ** and local proxy files in it */ typedef struct proxyLockingContext proxyLockingContext; @@ -6989,10 +6985,10 @@ sqlite3_io_methods const *pOldMethod; /* Original I/O methods for close */ }; -/* -** The proxy lock file path for the database at dbPath is written into lPath, +/* +** The proxy lock file path for the database at dbPath is written into lPath, ** which must point to valid, writable memory large enough for a maxLen length -** file path. +** file path. */ static int proxyGetLockPath(const char *dbPath, char *lPath, size_t maxLen){ int len; @@ -7009,7 +7005,7 @@ lPath, errno, osGetpid(0))); return SQLITE_IOERR_LOCK; } - len = strlcat(lPath, "sqliteplocks", maxLen); + len = strlcat(lPath, "sqliteplocks", maxLen); } # else len = strlcpy(lPath, "/tmp/", maxLen); @@ -7019,7 +7015,7 @@ if( lPath[len-1]!='/' ){ len = strlcat(lPath, "/", maxLen); } - + /* transform the db path to a unique cache name */ dbLen = (int)strlen(dbPath); for( i=0; i 0) ){ /* only mkdir if leaf dir != "." or "/" or ".." */ - if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') + if( i-start>2 || (i-start==1 && buf[start] != '.' && buf[start] != '/') || (i-start==2 && buf[start] != '.' && buf[start+1] != '.') ){ buf[i]='\0'; if( osMkdir(buf, SQLITE_DEFAULT_PROXYDIR_PERMISSIONS) ){ @@ -7124,13 +7120,13 @@ switch (terrno) { case EACCES: return SQLITE_PERM; - case EIO: + case EIO: return SQLITE_IOERR_LOCK; /* even though it is the conch */ default: return SQLITE_CANTOPEN_BKPT; } } - + pNew = (unixFile *)sqlite3_malloc64(sizeof(*pNew)); if( pNew==NULL ){ rc = SQLITE_NOMEM_BKPT; @@ -7144,13 +7140,13 @@ pUnused->fd = fd; pUnused->flags = openFlags; pNew->pPreallocatedUnused = pUnused; - + rc = fillInUnixFile(&dummyVfs, fd, (sqlite3_file*)pNew, path, 0); if( rc==SQLITE_OK ){ *ppFile = pNew; return SQLITE_OK; } -end_create_proxy: +end_create_proxy: robust_close(pNew, fd, __LINE__); sqlite3_free(pNew); sqlite3_free(pUnused); @@ -7169,7 +7165,7 @@ extern int gethostuuid(uuid_t id, const struct timespec *wait); #endif -/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN +/* get the host ID via gethostuuid(), pHostID must point to PROXY_HOSTIDLEN ** bytes of writable memory. */ static int proxyGetHostID(unsigned char *pHostID, int *pError){ @@ -7195,7 +7191,7 @@ pHostID[0] = (char)(pHostID[0] + (char)(sqlite3_hostid_num & 0xFF)); } #endif - + return SQLITE_OK; } @@ -7206,14 +7202,14 @@ #define PROXY_PATHINDEX (PROXY_HEADERLEN+PROXY_HOSTIDLEN) #define PROXY_MAXCONCHLEN (PROXY_HEADERLEN+PROXY_HOSTIDLEN+MAXPATHLEN) -/* -** Takes an open conch file, copies the contents to a new path and then moves +/* +** Takes an open conch file, copies the contents to a new path and then moves ** it back. The newly created file's file descriptor is assigned to the -** conch file structure and finally the original conch file descriptor is +** conch file structure and finally the original conch file descriptor is ** closed. Returns zero if successful. */ static int proxyBreakConchLock(unixFile *pFile, uuid_t myHostID){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *conchFile = pCtx->conchFile; char tPath[MAXPATHLEN]; char buf[PROXY_MAXCONCHLEN]; @@ -7227,7 +7223,7 @@ /* create a new path by replace the trailing '-conch' with '-break' */ pathLen = strlcpy(tPath, cPath, MAXPATHLEN); - if( pathLen>MAXPATHLEN || pathLen<6 || + if( pathLen>MAXPATHLEN || pathLen<6 || (strlcpy(&tPath[pathLen-5], "break", 6) != 5) ){ sqlite3_snprintf(sizeof(errmsg),errmsg,"path error (len %d)",(int)pathLen); goto end_breaklock; @@ -7269,24 +7265,24 @@ return rc; } -/* Take the requested lock on the conch file and break a stale lock if the +/* Take the requested lock on the conch file and break a stale lock if the ** host id matches. */ static int proxyConchLock(unixFile *pFile, uuid_t myHostID, int lockType){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; unixFile *conchFile = pCtx->conchFile; int rc = SQLITE_OK; int nTries = 0; struct timespec conchModTime; - + memset(&conchModTime, 0, sizeof(conchModTime)); do { rc = conchFile->pMethod->xLock((sqlite3_file*)conchFile, lockType); nTries ++; if( rc==SQLITE_BUSY ){ /* If the lock failed (busy): - * 1st try: get the mod time of the conch, wait 0.5s and try again. - * 2nd try: fail if the mod time changed or host id is different, wait + * 1st try: get the mod time of the conch, wait 0.5s and try again. + * 2nd try: fail if the mod time changed or host id is different, wait * 10 sec and try again * 3rd try: break the lock unless the mod time has changed. */ @@ -7295,20 +7291,20 @@ storeLastErrno(pFile, errno); return SQLITE_IOERR_LOCK; } - + if( nTries==1 ){ conchModTime = buf.st_mtimespec; unixSleep(0,500000); /* wait 0.5 sec and try the lock again*/ - continue; + continue; } assert( nTries>1 ); - if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || + if( conchModTime.tv_sec != buf.st_mtimespec.tv_sec || conchModTime.tv_nsec != buf.st_mtimespec.tv_nsec ){ return SQLITE_BUSY; } - - if( nTries==2 ){ + + if( nTries==2 ){ char tBuf[PROXY_MAXCONCHLEN]; int len = osPread(conchFile->h, tBuf, PROXY_MAXCONCHLEN, 0); if( len<0 ){ @@ -7325,9 +7321,9 @@ return SQLITE_BUSY; } unixSleep(0,10000000); /* wait 10 sec and try the lock again */ - continue; + continue; } - + assert( nTries==3 ); if( 0==proxyBreakConchLock(pFile, myHostID) ){ rc = SQLITE_OK; @@ -7340,19 +7336,19 @@ } } } while( rc==SQLITE_BUSY && nTries<3 ); - + return rc; } -/* Takes the conch by taking a shared lock and read the contents conch, if -** lockPath is non-NULL, the host ID and lock file path must match. A NULL -** lockPath means that the lockPath in the conch file will be used if the -** host IDs match, or a new lock path will be generated automatically +/* Takes the conch by taking a shared lock and read the contents conch, if +** lockPath is non-NULL, the host ID and lock file path must match. A NULL +** lockPath means that the lockPath in the conch file will be used if the +** host IDs match, or a new lock path will be generated automatically ** and written to the conch file. */ static int proxyTakeConch(unixFile *pFile){ - proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; - + proxyLockingContext *pCtx = (proxyLockingContext *)pFile->lockingContext; + if( pCtx->conchHeld!=0 ){ return SQLITE_OK; }else{ @@ -7368,7 +7364,7 @@ int readLen = 0; int tryOldLockPath = 0; int forceNewLockPath = 0; - + OSTRACE(("TAKECONCH %d for %s pid=%d\n", conchFile->h, (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), osGetpid(0))); @@ -7389,21 +7385,21 @@ storeLastErrno(pFile, conchFile->lastErrno); rc = SQLITE_IOERR_READ; goto end_takeconch; - }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || + }else if( readLen<=(PROXY_HEADERLEN+PROXY_HOSTIDLEN) || readBuf[0]!=(char)PROXY_CONCHVERSION ){ - /* a short read or version format mismatch means we need to create a new - ** conch file. + /* a short read or version format mismatch means we need to create a new + ** conch file. */ createConch = 1; } /* if the host id matches and the lock path already exists in the conch - ** we'll try to use the path there, if we can't open that path, we'll - ** retry with a new auto-generated path + ** we'll try to use the path there, if we can't open that path, we'll + ** retry with a new auto-generated path */ do { /* in case we need to try again for an :auto: named lock file */ if( !createConch && !forceNewLockPath ){ - hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, + hostIdMatch = !memcmp(&readBuf[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); /* if the conch has data compare the contents */ if( !pCtx->lockProxyPath ){ @@ -7412,7 +7408,7 @@ */ if( hostIdMatch ){ size_t pathLen = (readLen - PROXY_PATHINDEX); - + if( pathLen>=MAXPATHLEN ){ pathLen=MAXPATHLEN-1; } @@ -7428,23 +7424,23 @@ readLen-PROXY_PATHINDEX) ){ /* conch host and lock path match */ - goto end_takeconch; + goto end_takeconch; } } - + /* if the conch isn't writable and doesn't match, we can't take it */ if( (conchFile->openFlags&O_RDWR) == 0 ){ rc = SQLITE_BUSY; goto end_takeconch; } - + /* either the conch didn't match or we need to create a new one */ if( !pCtx->lockProxyPath ){ proxyGetLockPath(pCtx->dbPath, lockPath, MAXPATHLEN); tempLockPath = lockPath; /* create a copy of the lock path _only_ if the conch is taken */ } - + /* update conch with host and path (this will fail if other process ** has a shared lock already), if the host id matches, use the big ** stick. @@ -7455,7 +7451,7 @@ /* We are trying for an exclusive lock but another thread in this ** same process is still holding a shared lock. */ rc = SQLITE_BUSY; - } else { + } else { rc = proxyConchLock(pFile, myHostID, EXCLUSIVE_LOCK); } }else{ @@ -7464,7 +7460,7 @@ if( rc==SQLITE_OK ){ char writeBuffer[PROXY_MAXCONCHLEN]; int writeSize = 0; - + writeBuffer[0] = (char)PROXY_CONCHVERSION; memcpy(&writeBuffer[PROXY_HEADERLEN], myHostID, PROXY_HOSTIDLEN); if( pCtx->lockProxyPath!=NULL ){ @@ -7477,8 +7473,8 @@ robust_ftruncate(conchFile->h, writeSize); rc = unixWrite((sqlite3_file *)conchFile, writeBuffer, writeSize, 0); full_fsync(conchFile->h,0,0); - /* If we created a new conch file (not just updated the contents of a - ** valid conch file), try to match the permissions of the database + /* If we created a new conch file (not just updated the contents of a + ** valid conch file), try to match the permissions of the database */ if( rc==SQLITE_OK && createConch ){ struct stat buf; @@ -7502,14 +7498,14 @@ } }else{ int code = errno; - fprintf(stderr, "STAT FAILED[%d] with %d %s\n", + fprintf(stderr, "STAT FAILED[%d] with %d %s\n", err, code, strerror(code)); #endif } } } conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, SHARED_LOCK); - + end_takeconch: OSTRACE(("TRANSPROXY: CLOSE %d\n", pFile->h)); if( rc==SQLITE_OK && pFile->openFlags ){ @@ -7532,7 +7528,7 @@ rc = proxyCreateUnixFile(path, &pCtx->lockProxy, 1); if( rc!=SQLITE_OK && rc!=SQLITE_NOMEM && tryOldLockPath ){ /* we couldn't create the proxy lock file with the old lock file path - ** so try again via auto-naming + ** so try again via auto-naming */ forceNewLockPath = 1; tryOldLockPath = 0; @@ -7552,7 +7548,7 @@ } if( rc==SQLITE_OK ){ pCtx->conchHeld = 1; - + if( pCtx->lockProxy->pMethod == &afpIoMethods ){ afpLockingContext *afpCtx; afpCtx = (afpLockingContext *)pCtx->lockProxy->lockingContext; @@ -7564,7 +7560,7 @@ OSTRACE(("TAKECONCH %d %s\n", conchFile->h, rc==SQLITE_OK?"ok":"failed")); return rc; - } while (1); /* in case we need to retry the :auto: lock file - + } while (1); /* in case we need to retry the :auto: lock file - ** we should never get here except via the 'continue' call. */ } } @@ -7580,7 +7576,7 @@ pCtx = (proxyLockingContext *)pFile->lockingContext; conchFile = pCtx->conchFile; OSTRACE(("RELEASECONCH %d for %s pid=%d\n", conchFile->h, - (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), + (pCtx->lockProxyPath ? pCtx->lockProxyPath : ":auto:"), osGetpid(0))); if( pCtx->conchHeld>0 ){ rc = conchFile->pMethod->xUnlock((sqlite3_file*)conchFile, NO_LOCK); @@ -7608,13 +7604,13 @@ char *conchPath; /* buffer in which to construct conch name */ /* Allocate space for the conch filename and initialize the name to - ** the name of the original database file. */ + ** the name of the original database file. */ *pConchPath = conchPath = (char *)sqlite3_malloc64(len + 8); if( conchPath==0 ){ return SQLITE_NOMEM_BKPT; } memcpy(conchPath, dbPath, len+1); - + /* now insert a "." before the last / character */ for( i=(len-1); i>=0; i-- ){ if( conchPath[i]=='/' ){ @@ -7637,7 +7633,7 @@ /* Takes a fully configured proxy locking-style unix file and switches -** the local lock file path +** the local lock file path */ static int switchLockProxyPath(unixFile *pFile, const char *path) { proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; @@ -7646,7 +7642,7 @@ if( pFile->eFileLock!=NO_LOCK ){ return SQLITE_BUSY; - } + } /* nothing to do if the path is NULL, :auto: or matches the existing path */ if( !path || path[0]=='\0' || !strcmp(path, ":auto:") || @@ -7664,7 +7660,7 @@ sqlite3_free(oldPath); pCtx->lockProxyPath = sqlite3DbStrDup(0, path); } - + return rc; } @@ -7678,7 +7674,7 @@ static int proxyGetDbPathForUnixFile(unixFile *pFile, char *dbPath){ #if defined(__APPLE__) if( pFile->pMethod == &afpIoMethods ){ - /* afp style keeps a reference to the db path in the filePath field + /* afp style keeps a reference to the db path in the filePath field ** of the struct */ assert( (int)strlen((char*)pFile->lockingContext)<=MAXPATHLEN ); strlcpy(dbPath, ((afpLockingContext *)pFile->lockingContext)->dbPath, @@ -7699,9 +7695,9 @@ } /* -** Takes an already filled in unix file and alters it so all file locking +** Takes an already filled in unix file and alters it so all file locking ** will be performed on the local proxy lock file. The following fields -** are preserved in the locking context so that they can be restored and +** are preserved in the locking context so that they can be restored and ** the unix structure properly cleaned up at close time: ** ->lockingContext ** ->pMethod @@ -7711,7 +7707,7 @@ char dbPath[MAXPATHLEN+1]; /* Name of the database file */ char *lockPath=NULL; int rc = SQLITE_OK; - + if( pFile->eFileLock!=NO_LOCK ){ return SQLITE_BUSY; } @@ -7721,7 +7717,7 @@ }else{ lockPath=(char *)path; } - + OSTRACE(("TRANSPROXY %d for %s pid=%d\n", pFile->h, (lockPath ? lockPath : ":auto:"), osGetpid(0))); @@ -7755,7 +7751,7 @@ rc = SQLITE_OK; } } - } + } if( rc==SQLITE_OK && lockPath ){ pCtx->lockProxyPath = sqlite3DbStrDup(0, lockPath); } @@ -7767,7 +7763,7 @@ } } if( rc==SQLITE_OK ){ - /* all memory is allocated, proxys are created and assigned, + /* all memory is allocated, proxys are created and assigned, ** switch the locking context and pMethod then return. */ pCtx->oldLockingContext = pFile->lockingContext; @@ -7775,12 +7771,12 @@ pCtx->pOldMethod = pFile->pMethod; pFile->pMethod = &proxyIoMethods; }else{ - if( pCtx->conchFile ){ + if( pCtx->conchFile ){ pCtx->conchFile->pMethod->xClose((sqlite3_file *)pCtx->conchFile); sqlite3_free(pCtx->conchFile); } sqlite3DbFree(0, pCtx->lockProxyPath); - sqlite3_free(pCtx->conchFilePath); + sqlite3_free(pCtx->conchFilePath); sqlite3_free(pCtx); } OSTRACE(("TRANSPROXY %d %s\n", pFile->h, @@ -7818,7 +7814,7 @@ if( isProxyStyle ){ /* turn off proxy locking - not supported. If support is added for ** switching proxy locking mode off then it will need to fail if - ** the journal mode is WAL mode. + ** the journal mode is WAL mode. */ rc = SQLITE_ERROR /*SQLITE_PROTOCOL? SQLITE_MISUSE?*/; }else{ @@ -7828,9 +7824,9 @@ }else{ const char *proxyPath = (const char *)pArg; if( isProxyStyle ){ - proxyLockingContext *pCtx = + proxyLockingContext *pCtx = (proxyLockingContext*)pFile->lockingContext; - if( !strcmp(pArg, ":auto:") + if( !strcmp(pArg, ":auto:") || (pCtx->lockProxyPath && !strncmp(pCtx->lockProxyPath, proxyPath, MAXPATHLEN)) ){ @@ -7955,7 +7951,7 @@ unixFile *lockProxy = pCtx->lockProxy; unixFile *conchFile = pCtx->conchFile; int rc = SQLITE_OK; - + if( lockProxy ){ rc = lockProxy->pMethod->xUnlock((sqlite3_file*)lockProxy, NO_LOCK); if( rc ) return rc; @@ -7992,7 +7988,7 @@ ** The proxy locking style is intended for use with AFP filesystems. ** And since AFP is only supported on MacOSX, the proxy locking is also ** restricted to MacOSX. -** +** ** ******************* End of the proxy lock implementation ********************** ******************************************************************************/ @@ -8010,8 +8006,8 @@ ** necessarily been initialized when this routine is called, and so they ** should not be used. */ -int sqlite3_os_init(void){ - /* +int sqlite3_os_init(void){ + /* ** The following macro defines an initializer for an sqlite3_vfs object. ** The name of the VFS is NAME. The pAppData is a pointer to a pointer ** to the "finder" function. (pAppData is a pointer to a pointer because @@ -8027,7 +8023,7 @@ ** ** Most finders simply return a pointer to a fixed sqlite3_io_methods ** object. But the "autolockIoFinder" available on MacOSX does a little - ** more than that; it looks at the filesystem type that hosts the + ** more than that; it looks at the filesystem type that hosts the ** database file and tries to choose an locking method appropriate for ** that filesystem time. */ @@ -8130,7 +8126,7 @@ /* Initialize temp file dir array. */ unixTempFileInit(); - return SQLITE_OK; + return SQLITE_OK; } /* @@ -8140,9 +8136,9 @@ ** to release dynamically allocated objects. But not on unix. ** This routine is a no-op for unix. */ -int sqlite3_os_end(void){ +int sqlite3_os_end(void){ unixBigLock = 0; - return SQLITE_OK; + return SQLITE_OK; } - + #endif /* SQLITE_OS_UNIX */ diff -Nru sqlite3-3.42.0/src/os_win.c sqlite3-3.44.0-0/src/os_win.c --- sqlite3-3.42.0/src/os_win.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/os_win.c 2023-11-04 14:23:58.000000000 +0000 @@ -1159,7 +1159,7 @@ /* ** This is the xSetSystemCall() method of sqlite3_vfs for all of the -** "win32" VFSes. Return SQLITE_OK opon successfully updating the +** "win32" VFSes. Return SQLITE_OK upon successfully updating the ** system call pointer, or SQLITE_NOTFOUND if there is no configurable ** system call named zName. */ @@ -2739,7 +2739,7 @@ pFile->h, pBuf, amt, offset, pFile->locktype)); #if SQLITE_MAX_MMAP_SIZE>0 - /* Deal with as much of this read request as possible by transfering + /* Deal with as much of this read request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -2817,7 +2817,7 @@ 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 transfering + /* Deal with as much of this write request as possible by transferring ** data from the memory mapping using memcpy(). */ if( offsetmmapSize ){ if( offset+amt <= pFile->mmapSize ){ @@ -2927,7 +2927,7 @@ ** 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 trancations a no-op if there are pending reads. We + ** now to simply make transactions a no-op if there are pending reads. We ** can maybe revisit this decision in the future. */ return SQLITE_OK; @@ -2986,7 +2986,7 @@ #ifdef SQLITE_TEST /* ** Count the number of fullsyncs and normal syncs. This is used to test -** that syncs and fullsyncs are occuring at the right times. +** that syncs and fullsyncs are occurring at the right times. */ int sqlite3_sync_count = 0; int sqlite3_fullsync_count = 0; @@ -3343,7 +3343,7 @@ */ if( locktype==EXCLUSIVE_LOCK && res ){ assert( pFile->locktype>=SHARED_LOCK ); - res = winUnlockReadLock(pFile); + (void)winUnlockReadLock(pFile); res = winLockFile(&pFile->h, SQLITE_LOCKFILE_FLAGS, SHARED_FIRST, 0, SHARED_SIZE, 0); if( res ){ @@ -4747,6 +4747,7 @@ "ABCDEFGHIJKLMNOPQRSTUVWXYZ" "0123456789"; size_t i, j; + DWORD pid; int nPre = sqlite3Strlen30(SQLITE_TEMP_FILE_PREFIX); int nMax, nBuf, nDir, nLen; char *zBuf; @@ -4959,7 +4960,10 @@ j = sqlite3Strlen30(zBuf); sqlite3_randomness(15, &zBuf[j]); + pid = osGetCurrentProcessId(); for(i=0; i<15; i++, j++){ + zBuf[j] += pid & 0xff; + pid >>= 8; zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ]; } zBuf[j] = 0; diff -Nru sqlite3-3.42.0/src/pager.c sqlite3-3.44.0-0/src/pager.c --- sqlite3-3.42.0/src/pager.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/pager.c 2023-11-04 14:23:58.000000000 +0000 @@ -10,7 +10,7 @@ ** ************************************************************************* ** This is the implementation of the page cache subsystem or "pager". -** +** ** The pager is used to access a database disk file. It implements ** atomic commit and rollback through the use of a journal file that ** is separate from the database file. The pager also implements file @@ -36,60 +36,60 @@ ** ** Definition: A page of the database file is said to be "overwriteable" 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 overwriteable. -** +** ** (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 ** and the content in the database at the beginning of the current ** transaction. -** +** ** (3) Writes to the database file are an integer multiple of the page size ** in length and are aligned on a page boundary. -** +** ** (4) Reads from the database file are either aligned on a page boundary and ** an integer multiple of the page size in length or are taken from the ** first 100 bytes of the database file. -** +** ** (5) All writes to the database file are synced prior to the rollback journal ** being deleted, truncated, or zeroed. -** +** ** (6) If a super-journal file is used, then all writes to the database file ** are synced prior to the super-journal being deleted. -** +** ** Definition: Two databases (or the same database at two points it time) ** are said to be "logically equivalent" if they give the same answer to ** all queries. Note in particular the content of freelist leaf ** pages can be changed arbitrarily without affecting the logical equivalence ** of the database. -** +** ** (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 +** of the unsynced changes to a rollback journal are removed and the ** journal is rolled back, the resulting database file will be logically ** equivalent to the database file at the beginning of the transaction. -** +** ** (8) When a transaction is rolled back, the xTruncate method of the VFS ** is called to restore the database file to the same size it was at ** the beginning of the transaction. (In some VFSes, the xTruncate ** method is a no-op, but that does not change the fact the SQLite will ** invoke it.) -** +** ** (9) Whenever the database file is modified, at least one bit in the range ** of bytes from 24 through 39 inclusive will be changed prior to releasing ** the EXCLUSIVE lock, thus signaling other connections on the same @@ -122,7 +122,7 @@ /* ** The following two macros are used within the PAGERTRACE() macros above -** to print out file-descriptors. +** to print out file-descriptors. ** ** PAGERID() takes a pointer to a Pager struct as its argument. The ** associated file-descriptor is returned. FILEHANDLEID() takes an sqlite3_file @@ -143,7 +143,7 @@ ** | | | ** | V | ** |<-------WRITER_LOCKED------> ERROR -** | | ^ +** | | ^ ** | V | ** |<------WRITER_CACHEMOD-------->| ** | | | @@ -155,7 +155,7 @@ ** ** ** List of state transitions and the C [function] that performs each: -** +** ** OPEN -> READER [sqlite3PagerSharedLock] ** READER -> OPEN [pager_unlock] ** @@ -167,7 +167,7 @@ ** ** WRITER_*** -> ERROR [pager_error] ** ERROR -> OPEN [pager_unlock] -** +** ** ** OPEN: ** @@ -181,9 +181,9 @@ ** ** READER: ** -** In this state all the requirements for reading the database in +** In this state all the requirements for reading the database in ** rollback (non-WAL) mode are met. Unless the pager is (or recently -** was) in exclusive-locking mode, a user-level read transaction is +** was) in exclusive-locking mode, a user-level read transaction is ** open. The database size is known in this state. ** ** A connection running with locking_mode=normal enters this state when @@ -193,28 +193,28 @@ ** this state even after the read-transaction is closed. The only way ** a locking_mode=exclusive connection can transition from READER to OPEN ** is via the ERROR state (see below). -** +** ** * A read transaction may be active (but a write-transaction cannot). ** * A SHARED or greater lock is held on the database file. -** * The dbSize variable may be trusted (even if a user-level read +** * The dbSize variable may be trusted (even if a user-level read ** transaction is not active). The dbOrigSize and dbFileSize variables ** may not be trusted at this point. ** * If the database is a WAL database, then the WAL connection is open. -** * Even if a read-transaction is not open, it is guaranteed that +** * Even if a read-transaction is not open, it is guaranteed that ** there is no hot-journal in the file-system. ** ** WRITER_LOCKED: ** ** The pager moves to this state from READER when a write-transaction -** is first opened on the database. In WRITER_LOCKED state, all locks -** required to start a write-transaction are held, but no actual +** is first opened on the database. In WRITER_LOCKED state, all locks +** required to start a write-transaction are held, but no actual ** modifications to the cache or database have taken place. ** -** In rollback mode, a RESERVED or (if the transaction was opened with +** In rollback mode, a RESERVED or (if the transaction was opened with ** BEGIN EXCLUSIVE) EXCLUSIVE lock is obtained on the database file when -** moving to this state, but the journal file is not written to or opened -** to in this state. If the transaction is committed or rolled back while -** in WRITER_LOCKED state, all that is required is to unlock the database +** moving to this state, but the journal file is not written to or opened +** to in this state. If the transaction is committed or rolled back while +** in WRITER_LOCKED state, all that is required is to unlock the database ** file. ** ** IN WAL mode, WalBeginWriteTransaction() is called to lock the log file. @@ -222,7 +222,7 @@ ** is made to obtain an EXCLUSIVE lock on the database file. ** ** * A write transaction is active. -** * If the connection is open in rollback-mode, a RESERVED or greater +** * If the connection is open in rollback-mode, a RESERVED or greater ** lock is held on the database file. ** * If the connection is open in WAL-mode, a WAL write transaction ** is open (i.e. sqlite3WalBeginWriteTransaction() has been successfully @@ -241,7 +241,7 @@ ** ** * A write transaction is active. ** * A RESERVED or greater lock is held on the database file. -** * The journal file is open and the first header has been written +** * The journal file is open and the first header has been written ** to it, but the header has not been synced to disk. ** * The contents of the page cache have been modified. ** @@ -254,7 +254,7 @@ ** ** * A write transaction is active. ** * An EXCLUSIVE or greater lock is held on the database file. -** * The journal file is open and the first header has been written +** * The journal file is open and the first header has been written ** and synced to disk. ** * The contents of the page cache have been modified (and possibly ** written to disk). @@ -266,8 +266,8 @@ ** A rollback-mode pager changes to WRITER_FINISHED state from WRITER_DBMOD ** state after the entire transaction has been successfully written into the ** database file. In this state the transaction may be committed simply -** by finalizing the journal file. Once in WRITER_FINISHED state, it is -** not possible to modify the database further. At this point, the upper +** by finalizing the journal file. Once in WRITER_FINISHED state, it is +** not possible to modify the database further. At this point, the upper ** layer must either commit or rollback the transaction. ** ** * A write transaction is active. @@ -275,19 +275,19 @@ ** * All writing and syncing of journal and database data has finished. ** If no error occurred, all that remains is to finalize the journal to ** commit the transaction. If an error did occur, the caller will need -** to rollback the transaction. +** to rollback the transaction. ** ** ERROR: ** ** The ERROR state is entered when an IO or disk-full error (including -** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it -** difficult to be sure that the in-memory pager state (cache contents, +** SQLITE_IOERR_NOMEM) occurs at a point in the code that makes it +** difficult to be sure that the in-memory pager state (cache contents, ** db size etc.) are consistent with the contents of the file-system. ** ** Temporary pager files may enter the ERROR state, but in-memory pagers ** cannot. ** -** For example, if an IO error occurs while performing a rollback, +** For example, if an IO error occurs while performing a rollback, ** the contents of the page-cache may be left in an inconsistent state. ** At this point it would be dangerous to change back to READER state ** (as usually happens after a rollback). Any subsequent readers might @@ -297,13 +297,13 @@ ** 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 +** 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 +** 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 peformed) +** 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 +** the pager into READER state). At that point the system has recovered ** from the error. ** ** Specifically, the pager jumps into the ERROR state if: @@ -319,21 +319,21 @@ ** memory. ** ** In other cases, the error is returned to the b-tree layer. The b-tree -** layer then attempts a rollback operation. If the error condition +** layer then attempts a rollback operation. If the error condition ** persists, the pager enters the ERROR state via condition (1) above. ** ** Condition (3) is necessary because it can be triggered by a read-only ** statement executed within a transaction. In this case, if the error ** code were simply returned to the user, the b-tree layer would not ** automatically attempt a rollback, as it assumes that an error in a -** read-only statement cannot leave the pager in an internally inconsistent +** read-only statement cannot leave the pager in an internally inconsistent ** state. ** ** * The Pager.errCode variable is set to something other than SQLITE_OK. ** * There are one or more outstanding references to pages (after the ** last reference is dropped the pager should move back to OPEN state). ** * The pager is not an in-memory pager. -** +** ** ** Notes: ** @@ -343,7 +343,7 @@ ** ** * Normally, a connection open in exclusive mode is never in PAGER_OPEN ** state. There are two exceptions: immediately after exclusive-mode has -** been turned on (and before any read or write transactions are +** been turned on (and before any read or write transactions are ** executed), and when the pager is leaving the "error state". ** ** * See also: assert_pager_state(). @@ -357,7 +357,7 @@ #define PAGER_ERROR 6 /* -** The Pager.eLock variable is almost always set to one of the +** The Pager.eLock variable is almost always set to one of the ** following locking-states, according to the lock currently held on ** the database file: NO_LOCK, SHARED_LOCK, RESERVED_LOCK or EXCLUSIVE_LOCK. ** This variable is kept up to date as locks are taken and released by @@ -372,20 +372,20 @@ ** to a less exclusive (lower) value than the lock that is actually held ** at the system level, but it is never set to a more exclusive value. ** -** This is usually safe. If an xUnlock fails or appears to fail, there may +** This is usually safe. If an xUnlock fails or appears to fail, there may ** be a few redundant xLock() calls or a lock may be held for longer than ** required, but nothing really goes wrong. ** ** The exception is when the database file is unlocked as the pager moves -** from ERROR to OPEN state. At this point there may be a hot-journal file +** from ERROR to OPEN state. At this point there may be a hot-journal file ** in the file-system that needs to be rolled back (as part of an OPEN->SHARED ** transition, by the same pager or any other). If the call to xUnlock() ** fails at this point and the pager is left holding an EXCLUSIVE lock, this ** can confuse the call to xCheckReservedLock() call made later as part ** of hot-journal detection. ** -** xCheckReservedLock() is defined as returning true "if there is a RESERVED -** lock held by this process or any others". So xCheckReservedLock may +** xCheckReservedLock() is defined as returning true "if there is a RESERVED +** lock held by this process or any others". So xCheckReservedLock may ** return true because the caller itself is holding an EXCLUSIVE lock (but ** doesn't know it because of a previous error in xUnlock). If this happens ** a hot-journal may be mistaken for a journal being created by an active @@ -396,18 +396,18 @@ ** database in the ERROR state, Pager.eLock is set to UNKNOWN_LOCK. It ** is only changed back to a real locking state after a successful call ** to xLock(EXCLUSIVE). Also, the code to do the OPEN->SHARED state transition -** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK +** omits the check for a hot-journal if Pager.eLock is set to UNKNOWN_LOCK ** lock. Instead, it assumes a hot-journal exists and obtains an EXCLUSIVE ** lock on the database file before attempting to roll it back. See function ** PagerSharedLock() for more detail. ** -** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in +** Pager.eLock may only be set to UNKNOWN_LOCK when the pager is in ** PAGER_OPEN state. */ #define UNKNOWN_LOCK (EXCLUSIVE_LOCK+1) /* -** The maximum allowed sector size. 64KiB. If the xSectorsize() method +** The maximum allowed sector size. 64KiB. If the xSectorsize() method ** returns a value larger than this, then MAX_SECTOR_SIZE is used instead. ** This could conceivably cause corruption following a power failure on ** such a system. This is currently an undocumented limit. @@ -423,7 +423,7 @@ ** ** When a savepoint is created, the PagerSavepoint.iHdrOffset field is ** set to 0. If a journal-header is written into the main journal while -** the savepoint is active, then iHdrOffset is set to the byte offset +** the savepoint is active, then iHdrOffset is set to the byte offset ** immediately following the last journal record written into the main ** journal before the journal-header. This is required during savepoint ** rollback (see pagerPlaybackSavepoint()). @@ -474,34 +474,34 @@ ** ** changeCountDone ** -** This boolean variable is used to make sure that the change-counter -** (the 4-byte header field at byte offset 24 of the database file) is -** not updated more often than necessary. +** This boolean variable is used to make sure that the change-counter +** (the 4-byte header field at byte offset 24 of the database file) is +** not updated more often than necessary. ** -** It is set to true when the change-counter field is updated, which +** It is set to true when the change-counter field is updated, which ** can only happen if an exclusive lock is held on the database file. -** It is cleared (set to false) whenever an exclusive lock is +** It is cleared (set to false) whenever an exclusive lock is ** relinquished on the database file. Each time a transaction is committed, ** The changeCountDone flag is inspected. If it is true, the work of ** updating the change-counter is omitted for the current transaction. ** -** This mechanism means that when running in exclusive mode, a connection +** This mechanism means that when running in exclusive mode, a connection ** need only update the change-counter once, for the first transaction ** committed. ** ** setSuper ** ** When PagerCommitPhaseOne() is called to commit a transaction, it may -** (or may not) specify a super-journal name to be written into the +** (or may not) specify a super-journal name to be written into the ** journal file before it is synced to disk. ** -** Whether or not a journal file contains a super-journal pointer affects -** the way in which the journal file is finalized after the transaction is +** Whether or not a journal file contains a super-journal pointer affects +** the way in which the journal file is finalized after the transaction is ** committed or rolled back when running in "journal_mode=PERSIST" mode. ** If a journal file does not contain a super-journal pointer, it is ** finalized by overwriting the first journal header with zeroes. If -** it does contain a super-journal pointer the journal file is finalized -** by truncating it to zero bytes, just as if the connection were +** it does contain a super-journal pointer the journal file is finalized +** by truncating it to zero bytes, just as if the connection were ** running in "journal_mode=truncate" mode. ** ** Journal files that contain super-journal pointers cannot be finalized @@ -527,12 +527,12 @@ ** to allocate a new page to prevent the journal file from being written ** while it is being traversed by code in pager_playback(). The SPILLFLAG_OFF ** case is a user preference. -** +** ** If the SPILLFLAG_NOSYNC bit is set, writing to the database from ** pagerStress() is permitted, but syncing the journal file is not. ** This flag is set by sqlite3PagerWrite() when the file-system sector-size ** is larger than the database page-size in order to prevent a journal sync -** from happening in between the journalling of two pages on the same sector. +** from happening in between the journalling of two pages on the same sector. ** ** subjInMemory ** @@ -540,16 +540,16 @@ ** is opened as an in-memory journal file. If false, then in-memory ** sub-journals are only used for in-memory pager files. ** -** This variable is updated by the upper layer each time a new +** This variable is updated by the upper layer each time a new ** write-transaction is opened. ** ** dbSize, dbOrigSize, dbFileSize ** ** Variable dbSize is set to the number of pages in the database file. ** It is valid in PAGER_READER and higher states (all states except for -** OPEN and ERROR). +** OPEN and ERROR). ** -** dbSize is set based on the size of the database file, which may be +** dbSize is set based on the size of the database file, which may be ** larger than the size of the database (the value stored at offset ** 28 of the database header by the btree). If the size of the file ** is not an integer multiple of the page-size, the value stored in @@ -560,10 +560,10 @@ ** ** During a write-transaction, if pages with page-numbers greater than ** dbSize are modified in the cache, dbSize is updated accordingly. -** Similarly, if the database is truncated using PagerTruncateImage(), +** Similarly, if the database is truncated using PagerTruncateImage(), ** dbSize is updated. ** -** Variables dbOrigSize and dbFileSize are valid in states +** Variables dbOrigSize and dbFileSize are valid in states ** PAGER_WRITER_LOCKED and higher. dbOrigSize is a copy of the dbSize ** variable at the start of the transaction. It is used during rollback, ** and to determine whether or not pages need to be journalled before @@ -572,12 +572,12 @@ ** Throughout a write-transaction, dbFileSize contains the size of ** the file on disk in pages. It is set to a copy of dbSize when the ** write-transaction is first opened, and updated when VFS calls are made -** to write or truncate the database file on disk. +** to write or truncate the database file on disk. ** -** The only reason the dbFileSize variable is required is to suppress -** unnecessary calls to xTruncate() after committing a transaction. If, -** when a transaction is committed, the dbFileSize variable indicates -** that the database file is larger than the database image (Pager.dbSize), +** The only reason the dbFileSize variable is required is to suppress +** unnecessary calls to xTruncate() after committing a transaction. If, +** when a transaction is committed, the dbFileSize variable indicates +** that the database file is larger than the database image (Pager.dbSize), ** pager_truncate() is called. The pager_truncate() call uses xFilesize() ** to measure the database file on disk, and then truncates it if required. ** dbFileSize is not used when rolling back a transaction. In this case @@ -588,20 +588,20 @@ ** dbHintSize ** ** The dbHintSize variable is used to limit the number of calls made to -** the VFS xFileControl(FCNTL_SIZE_HINT) method. +** the VFS xFileControl(FCNTL_SIZE_HINT) method. ** ** dbHintSize is set to a copy of the dbSize variable when a ** write-transaction is opened (at the same time as dbFileSize and ** dbOrigSize). If the xFileControl(FCNTL_SIZE_HINT) method is called, ** dbHintSize is increased to the number of pages that correspond to the -** size-hint passed to the method call. See pager_write_pagelist() for +** size-hint passed to the method call. See pager_write_pagelist() for ** details. ** ** errCode ** ** The Pager.errCode variable is only ever used in PAGER_ERROR state. It -** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode -** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX +** is set to zero in all other states. In PAGER_ERROR state, Pager.errCode +** is always set to SQLITE_FULL, SQLITE_IOERR or one of the SQLITE_IOERR_XXX ** sub-codes. ** ** syncFlags, walSyncFlags @@ -704,7 +704,7 @@ /* ** Indexes for use with Pager.aStat[]. The Pager.aStat[] array contains -** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS +** the values accessed by passing SQLITE_DBSTATUS_CACHE_HIT, CACHE_MISS ** or CACHE_WRITE to sqlite3_db_status(). */ #define PAGER_STAT_HIT 0 @@ -762,7 +762,7 @@ #define JOURNAL_PG_SZ(pPager) ((pPager->pageSize) + 8) /* -** The journal header size for this pager. This is usually the same +** The journal header size for this pager. This is usually the same ** size as a single disk sector. See also setSectorSize(). */ #define JOURNAL_HDR_SZ(pPager) (pPager->sectorSize) @@ -837,7 +837,7 @@ # define pagerBeginReadTransaction(z) SQLITE_OK #endif -#ifndef NDEBUG +#ifndef NDEBUG /* ** Usage: ** @@ -866,25 +866,25 @@ assert( p->tempFile==0 || p->eLock==EXCLUSIVE_LOCK ); assert( p->tempFile==0 || pPager->changeCountDone ); - /* If the useJournal flag is clear, the journal-mode must be "OFF". + /* If the useJournal flag is clear, the journal-mode must be "OFF". ** And if the journal-mode is "OFF", the journal file must not be open. */ assert( p->journalMode==PAGER_JOURNALMODE_OFF || p->useJournal ); assert( p->journalMode!=PAGER_JOURNALMODE_OFF || !isOpen(p->jfd) ); - /* Check that MEMDB implies noSync. And an in-memory journal. Since - ** this means an in-memory pager performs no IO at all, it cannot encounter - ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing - ** a journal file. (although the in-memory journal implementation may - ** return SQLITE_IOERR_NOMEM while the journal file is being written). It - ** is therefore not possible for an in-memory pager to enter the ERROR + /* Check that MEMDB implies noSync. And an in-memory journal. Since + ** this means an in-memory pager performs no IO at all, it cannot encounter + ** either SQLITE_IOERR or SQLITE_FULL during rollback or while finalizing + ** a journal file. (although the in-memory journal implementation may + ** return SQLITE_IOERR_NOMEM while the journal file is being written). It + ** is therefore not possible for an in-memory pager to enter the ERROR ** state. */ if( MEMDB ){ assert( !isOpen(p->fd) ); assert( p->noSync ); - assert( p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_MEMORY + assert( p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_MEMORY ); assert( p->eState!=PAGER_ERROR && p->eState!=PAGER_OPEN ); assert( pagerUseWal(p)==0 ); @@ -931,9 +931,9 @@ ** to journal_mode=wal. */ assert( p->eLock>=RESERVED_LOCK ); - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL ); } assert( pPager->dbOrigSize==pPager->dbFileSize ); @@ -945,9 +945,9 @@ assert( pPager->errCode==SQLITE_OK ); assert( !pagerUseWal(pPager) ); assert( p->eLock>=EXCLUSIVE_LOCK ); - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) ); assert( pPager->dbOrigSize<=pPager->dbHintSize ); @@ -957,9 +957,9 @@ assert( p->eLock==EXCLUSIVE_LOCK ); assert( pPager->errCode==SQLITE_OK ); assert( !pagerUseWal(pPager) ); - assert( isOpen(p->jfd) - || p->journalMode==PAGER_JOURNALMODE_OFF - || p->journalMode==PAGER_JOURNALMODE_WAL + assert( isOpen(p->jfd) + || p->journalMode==PAGER_JOURNALMODE_OFF + || p->journalMode==PAGER_JOURNALMODE_WAL || (sqlite3OsDeviceCharacteristics(p->fd)&SQLITE_IOCAP_BATCH_ATOMIC) ); break; @@ -978,7 +978,7 @@ } #endif /* ifndef NDEBUG */ -#ifdef SQLITE_DEBUG +#ifdef SQLITE_DEBUG /* ** Return a pointer to a human readable string in a static buffer ** containing the state of the Pager object passed as an argument. This @@ -1129,7 +1129,7 @@ ** succeeds, set the Pager.eLock variable to match the (attempted) new lock. ** ** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is -** called, do not modify it. See the comment above the #define of +** called, do not modify it. See the comment above the #define of ** UNKNOWN_LOCK for an explanation of this. */ static int pagerUnlockDb(Pager *pPager, int eLock){ @@ -1153,11 +1153,11 @@ /* ** Lock the database file to level eLock, which must be either SHARED_LOCK, ** RESERVED_LOCK or EXCLUSIVE_LOCK. If the caller is successful, set the -** Pager.eLock variable to the new locking state. +** Pager.eLock variable to the new locking state. ** -** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is -** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. -** See the comment above the #define of UNKNOWN_LOCK for an explanation +** Except, if Pager.eLock is set to UNKNOWN_LOCK when this function is +** called, do not modify it unless the new locking state is EXCLUSIVE_LOCK. +** See the comment above the #define of UNKNOWN_LOCK for an explanation ** of this. */ static int pagerLockDb(Pager *pPager, int eLock){ @@ -1184,7 +1184,7 @@ ** (b) the value returned by OsSectorSize() is less than or equal ** to the page size. ** -** If it can be used, then the value returned is the size of the journal +** If it can be used, then the value returned is the size of the journal ** file when it contains rollback data for exactly one page. ** ** The atomic-batch-write optimization can be used if OsDeviceCharacteristics() @@ -1275,8 +1275,8 @@ /* ** When this is called the journal file for pager pPager must be open. -** This function attempts to read a super-journal file name from the -** end of the file and, if successful, copies it into memory supplied +** This function attempts to read a super-journal file name from the +** end of the file and, if successful, copies it into memory supplied ** by the caller. See comments above writeSuperJournal() for the format ** used to store a super-journal file name at the end of a journal file. ** @@ -1292,7 +1292,7 @@ ** nul-terminator byte is appended to the buffer following the ** super-journal file name. ** -** If it is determined that no super-journal file name is present +** If it is determined that no super-journal file name is present ** zSuper[0] is set to 0 and SQLITE_OK returned. ** ** If an error occurs while reading from the journal file, an SQLite @@ -1310,9 +1310,9 @@ if( SQLITE_OK!=(rc = sqlite3OsFileSize(pJrnl, &szJ)) || szJ<16 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-16, &len)) - || len>=nSuper + || len>=nSuper || len>szJ-16 - || len==0 + || len==0 || SQLITE_OK!=(rc = read32bits(pJrnl, szJ-12, &cksum)) || SQLITE_OK!=(rc = sqlite3OsRead(pJrnl, aMagic, 8, szJ-8)) || memcmp(aMagic, aJournalMagic, 8) @@ -1335,13 +1335,13 @@ } zSuper[len] = '\0'; zSuper[len+1] = '\0'; - + return SQLITE_OK; } /* -** Return the offset of the sector boundary at or immediately -** following the value in pPager->journalOff, assuming a sector +** Return the offset of the sector boundary at or immediately +** following the value in pPager->journalOff, assuming a sector ** size of pPager->sectorSize bytes. ** ** i.e for a sector size of 512: @@ -1352,7 +1352,7 @@ ** 512 512 ** 100 512 ** 2000 2048 -** +** */ static i64 journalHdrOffset(Pager *pPager){ i64 offset = 0; @@ -1374,12 +1374,12 @@ ** ** If doTruncate is non-zero or the Pager.journalSizeLimit variable is ** set to 0, then truncate the journal file to zero bytes in size. Otherwise, -** zero the 28-byte header at the start of the journal file. In either case, -** if the pager is not in no-sync mode, sync the journal file immediately +** zero the 28-byte header at the start of the journal file. In either case, +** if the pager is not in no-sync mode, sync the journal file immediately ** after writing or truncating it. ** ** If Pager.journalSizeLimit is set to a positive, non-zero value, and -** following the truncation or zeroing described above the size of the +** following the truncation or zeroing described above the size of the ** journal file in bytes is larger than this value, then truncate the ** journal file to Pager.journalSizeLimit bytes. The journal file does ** not need to be synced following this operation. @@ -1405,8 +1405,8 @@ rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->syncFlags); } - /* At this point the transaction is committed but the write lock - ** is still held on the file. If there is a size limit configured for + /* At this point the transaction is committed but the write lock + ** is still held on the file. If there is a size limit configured for ** the persistent journal and the journal file currently consumes more ** space than that limit allows for, truncate it now. There is no need ** to sync the file following this operation. @@ -1434,7 +1434,7 @@ ** - 4 bytes: Initial database page count. ** - 4 bytes: Sector size used by the process that wrote this journal. ** - 4 bytes: Database page size. -** +** ** Followed by (JOURNAL_HDR_SZ - 28) bytes of unused space. */ static int writeJournalHdr(Pager *pPager){ @@ -1450,8 +1450,8 @@ nHeader = JOURNAL_HDR_SZ(pPager); } - /* If there are active savepoints and any of them were created - ** since the most recent journal header was written, update the + /* If there are active savepoints and any of them were created + ** since the most recent journal header was written, update the ** PagerSavepoint.iHdrOffset fields now. */ for(ii=0; iinSavepoint; ii++){ @@ -1462,10 +1462,10 @@ pPager->journalHdr = pPager->journalOff = journalHdrOffset(pPager); - /* + /* ** Write the nRec Field - the number of page records that follow this ** journal header. Normally, zero is written to this value at this time. - ** After the records are added to the journal (and the journal synced, + ** After the records are added to the journal (and the journal synced, ** if in full-sync mode), the zero is overwritten with the true number ** of records (see syncJournal()). ** @@ -1484,7 +1484,7 @@ */ assert( isOpen(pPager->fd) || pPager->noSync ); if( pPager->noSync || (pPager->journalMode==PAGER_JOURNALMODE_MEMORY) - || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) + || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_SAFE_APPEND) ){ memcpy(zHeader, aJournalMagic, sizeof(aJournalMagic)); put32bits(&zHeader[sizeof(aJournalMagic)], 0xffffffff); @@ -1492,9 +1492,32 @@ memset(zHeader, 0, sizeof(aJournalMagic)+4); } - /* The random check-hash initializer */ - sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + + + /* The random check-hash initializer */ + if( pPager->journalMode!=PAGER_JOURNALMODE_MEMORY ){ + sqlite3_randomness(sizeof(pPager->cksumInit), &pPager->cksumInit); + } +#ifdef SQLITE_DEBUG + else{ + /* The Pager.cksumInit variable is usually randomized above to protect + ** against there being existing records in the journal file. This is + ** dangerous, as following a crash they may be mistaken for records + ** written by the current transaction and rolled back into the database + ** file, causing corruption. The following assert statements verify + ** that this is not required in "journal_mode=memory" mode, as in that + ** case the journal file is always 0 bytes in size at this point. + ** It is advantageous to avoid the sqlite3_randomness() call if possible + ** as it takes the global PRNG mutex. */ + i64 sz = 0; + sqlite3OsFileSize(pPager->jfd, &sz); + assert( sz==0 ); + assert( pPager->journalOff==journalHdrOffset(pPager) ); + assert( sqlite3JournalIsInMemory(pPager->jfd) ); + } +#endif put32bits(&zHeader[sizeof(aJournalMagic)+4], pPager->cksumInit); + /* The initial database size */ put32bits(&zHeader[sizeof(aJournalMagic)+8], pPager->dbOrigSize); /* The assumed sector size for this process */ @@ -1511,23 +1534,23 @@ memset(&zHeader[sizeof(aJournalMagic)+20], 0, nHeader-(sizeof(aJournalMagic)+20)); - /* In theory, it is only necessary to write the 28 bytes that the - ** journal header consumes to the journal file here. Then increment the - ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next + /* In theory, it is only necessary to write the 28 bytes that the + ** journal header consumes to the journal file here. Then increment the + ** Pager.journalOff variable by JOURNAL_HDR_SZ so that the next ** record is written to the following sector (leaving a gap in the file ** that will be implicitly filled in by the OS). ** - ** However it has been discovered that on some systems this pattern can + ** However it has been discovered that on some systems this pattern can ** be significantly slower than contiguously writing data to the file, - ** even if that means explicitly writing data to the block of + ** even if that means explicitly writing data to the block of ** (JOURNAL_HDR_SZ - 28) bytes that will not be used. So that is what - ** is done. + ** is done. ** - ** The loop is required here in case the sector-size is larger than the + ** The loop is required here in case the sector-size is larger than the ** database page size. Since the zHeader buffer is only Pager.pageSize ** bytes in size, more than one call to sqlite3OsWrite() may be required ** to populate the entire journal header sector. - */ + */ for(nWrite=0; rc==SQLITE_OK&&nWritejournalHdr, nHeader)) rc = sqlite3OsWrite(pPager->jfd, zHeader, nHeader, pPager->journalOff); @@ -1625,29 +1648,29 @@ /* Check that the values read from the page-size and sector-size fields ** are within range. To be 'in range', both values need to be a power - ** of two greater than or equal to 512 or 32, and not greater than their + ** of two greater than or equal to 512 or 32, and not greater than their ** respective compile time maximum limits. */ if( iPageSize<512 || iSectorSize<32 || iPageSize>SQLITE_MAX_PAGE_SIZE || iSectorSize>MAX_SECTOR_SIZE - || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 + || ((iPageSize-1)&iPageSize)!=0 || ((iSectorSize-1)&iSectorSize)!=0 ){ - /* If the either the page-size or sector-size in the journal-header is - ** invalid, then the process that wrote the journal-header must have - ** crashed before the header was synced. In this case stop reading + /* If the either the page-size or sector-size in the journal-header is + ** invalid, then the process that wrote the journal-header must have + ** crashed before the header was synced. In this case stop reading ** the journal file here. */ return SQLITE_DONE; } - /* Update the page-size to match the value read from the journal. - ** Use a testcase() macro to make sure that malloc failure within + /* Update the page-size to match the value read from the journal. + ** Use a testcase() macro to make sure that malloc failure within ** PagerSetPagesize() is tested. */ rc = sqlite3PagerSetPagesize(pPager, &iPageSize, -1); testcase( rc!=SQLITE_OK ); - /* Update the assumed sector-size to match the value used by + /* Update the assumed sector-size to match the value used by ** the process that created this journal. If this journal was ** created by a process other than this one, then this routine ** is being called from within pager_playback(). The local value @@ -1674,10 +1697,10 @@ ** + 4 bytes: super-journal name checksum. ** + 8 bytes: aJournalMagic[]. ** -** The super-journal page checksum is the sum of the bytes in thesuper-journal +** The super-journal page checksum is the sum of the bytes in the super-journal ** name, where each byte is interpreted as a signed 8-bit integer. ** -** If zSuper is a NULL pointer (occurs for a single database transaction), +** If zSuper is a NULL pointer (occurs for a single database transaction), ** this call is a no-op. */ static int writeSuperJournal(Pager *pPager, const char *zSuper){ @@ -1690,8 +1713,8 @@ assert( pPager->setSuper==0 ); assert( !pagerUseWal(pPager) ); - if( !zSuper - || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + if( !zSuper + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY || !isOpen(pPager->jfd) ){ return SQLITE_OK; @@ -1727,16 +1750,16 @@ } pPager->journalOff += (nSuper+20); - /* If the pager is in peristent-journal mode, then the physical + /* 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 + ** 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. + ** 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 + ** Easiest thing to do in this scenario is to truncate the journal ** file to the required size. - */ + */ if( SQLITE_OK==(rc = sqlite3OsFileSize(pPager->jfd, &jrnlSize)) && jrnlSize>pPager->journalOff ){ @@ -1781,7 +1804,7 @@ } /* -** Set the bit number pgno in the PagerSavepoint.pInSavepoint +** Set the bit number pgno in the PagerSavepoint.pInSavepoint ** bitvecs of all open savepoints. Return SQLITE_OK if successful ** or SQLITE_NOMEM if a malloc failure occurs. */ @@ -1810,8 +1833,8 @@ ** not exhibit the UNDELETABLE_WHEN_OPEN property, the journal file is ** closed (if it is open). ** -** If the pager is in ERROR state when this function is called, the -** contents of the pager cache are discarded before switching back to +** If the pager is in ERROR state when this function is called, the +** contents of the pager cache are discarded before switching back to ** the OPEN state. Regardless of whether the pager is in exclusive-mode ** or not, any journal file left in the file-system will be treated ** as a hot-journal and rolled back the next time a read-transaction @@ -1819,9 +1842,9 @@ */ static void pager_unlock(Pager *pPager){ - assert( pPager->eState==PAGER_READER - || pPager->eState==PAGER_OPEN - || pPager->eState==PAGER_ERROR + assert( pPager->eState==PAGER_READER + || pPager->eState==PAGER_OPEN + || pPager->eState==PAGER_ERROR ); sqlite3BitvecDestroy(pPager->pInJournal); @@ -1897,18 +1920,18 @@ /* ** This function is called whenever an IOERR or FULL error that requires -** the pager to transition into the ERROR state may ahve occurred. -** The first argument is a pointer to the pager structure, the second -** the error-code about to be returned by a pager API function. The -** value returned is a copy of the second argument to this function. +** 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, ** all major API calls on the Pager will immediately return Pager.errCode. ** -** The ERROR state indicates that the contents of the pager-cache -** cannot be trusted. This state can be cleared by completely discarding +** The ERROR state indicates that the contents of the pager-cache +** cannot be trusted. This state can be cleared by completely discarding ** the contents of the pager-cache. If a transaction was active when ** the persistent error occurred, then the rollback journal may need ** to be replayed to restore the contents of the database file (as if @@ -1956,27 +1979,27 @@ } /* -** This routine ends a transaction. A transaction is usually ended by -** either a COMMIT or a ROLLBACK operation. This routine may be called +** This routine ends a transaction. A transaction is usually ended by +** either a COMMIT or a ROLLBACK operation. This routine may be called ** after rollback of a hot-journal, or if an error occurs while opening ** the journal file or writing the very first journal-header of a ** database transaction. -** +** ** This routine is never called in PAGER_ERROR state. If it is called ** in PAGER_NONE or PAGER_SHARED state and the lock held is less ** exclusive than a RESERVED lock, it is a no-op. ** ** Otherwise, any active savepoints are released. ** -** If the journal file is open, then it is "finalized". Once a journal -** file has been finalized it is not possible to use it to roll back a +** If the journal file is open, then it is "finalized". Once a journal +** file has been finalized it is not possible to use it to roll back a ** transaction. Nor will it be considered to be a hot-journal by this ** or any other database connection. Exactly how a journal is finalized ** depends on whether or not the pager is running in exclusive mode and ** the current journal-mode (Pager.journalMode value), as follows: ** ** journalMode==MEMORY -** Journal file descriptor is simply closed. This destroys an +** Journal file descriptor is simply closed. This destroys an ** in-memory journal. ** ** journalMode==TRUNCATE @@ -1996,12 +2019,12 @@ ** journalMode==PERSIST is used instead. ** ** After the journal is finalized, the pager moves to PAGER_READER state. -** If running in non-exclusive rollback mode, the lock on the file is +** If running in non-exclusive rollback mode, the lock on the file is ** downgraded to a SHARED_LOCK. ** ** SQLITE_OK is returned if no error occurs. If an error occurs during ** any of the IO operations to finalize the journal file or unlock the -** database then the IO error code is returned to the user. If the +** database then the IO error code is returned to the user. If the ** operation to finalize the journal file fails, then the code still ** tries to unlock the database file if not in exclusive mode. If the ** unlock operation fails as well, then the first error code related @@ -2020,9 +2043,9 @@ ** 1. After a successful hot-journal rollback, it is called with ** eState==PAGER_NONE and eLock==EXCLUSIVE_LOCK. ** - ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE + ** 2. If a connection with locking_mode=exclusive holding an EXCLUSIVE ** lock switches back to locking_mode=normal and then executes a - ** read-transaction, this function is called with eState==PAGER_READER + ** read-transaction, this function is called with eState==PAGER_READER ** and eLock==EXCLUSIVE_LOCK when the read-transaction is closed. */ assert( assert_pager_state(pPager) ); @@ -2032,7 +2055,7 @@ } releaseAllSavepoints(pPager); - assert( isOpen(pPager->jfd) || pPager->pInJournal==0 + assert( isOpen(pPager->jfd) || pPager->pInJournal==0 || (sqlite3OsDeviceCharacteristics(pPager->fd)&SQLITE_IOCAP_BATCH_ATOMIC) ); if( isOpen(pPager->jfd) ){ @@ -2070,9 +2093,9 @@ */ int bDelete = !pPager->tempFile; assert( sqlite3JournalIsInMemory(pPager->jfd)==0 ); - assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE - || pPager->journalMode==PAGER_JOURNALMODE_MEMORY - || pPager->journalMode==PAGER_JOURNALMODE_WAL + assert( pPager->journalMode==PAGER_JOURNALMODE_DELETE + || pPager->journalMode==PAGER_JOURNALMODE_MEMORY + || pPager->journalMode==PAGER_JOURNALMODE_WAL ); sqlite3OsClose(pPager->jfd); if( bDelete ){ @@ -2105,8 +2128,8 @@ } if( pagerUseWal(pPager) ){ - /* Drop the WAL write-lock, if any. Also, if the connection was in - ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE + /* Drop the WAL write-lock, if any. Also, if the connection was in + ** locking_mode=exclusive mode but is no longer, drop the EXCLUSIVE ** lock held on the database file. */ rc2 = sqlite3WalEndWriteTransaction(pPager->pWal); @@ -2114,7 +2137,7 @@ }else if( rc==SQLITE_OK && bCommit && pPager->dbFileSize>pPager->dbSize ){ /* This branch is taken when committing a transaction in rollback-journal ** mode if the database file on disk is larger than the database image. - ** At this point the journal has been finalized and the transaction + ** At this point the journal has been finalized and the transaction ** successfully committed, but the EXCLUSIVE lock is still held on the ** file. So it is safe to truncate the database file to its minimum ** required size. */ @@ -2127,7 +2150,7 @@ if( rc==SQLITE_NOTFOUND ) rc = SQLITE_OK; } - if( !pPager->exclusiveMode + if( !pPager->exclusiveMode && (!pagerUseWal(pPager) || sqlite3WalExclusiveMode(pPager->pWal, 0)) ){ rc2 = pagerUnlockDb(pPager, SHARED_LOCK); @@ -2138,20 +2161,23 @@ return (rc==SQLITE_OK?rc2:rc); } +/* Forward reference */ +static int pager_playback(Pager *pPager, int isHot); + /* -** Execute a rollback if a transaction is active and unlock the -** database file. +** Execute a rollback if a transaction is active and unlock the +** database file. ** -** If the pager has already entered the ERROR state, do not attempt +** If the pager has already entered the ERROR state, do not attempt ** the rollback at this time. Instead, pager_unlock() is called. The ** call to pager_unlock() will discard all in-memory pages, unlock -** the database file and move the pager back to OPEN state. If this -** means that there is a hot-journal left in the file-system, the next -** connection to obtain a shared lock on the pager (which may be this one) +** the database file and move the pager back to OPEN state. If this +** means that there is a hot-journal left in the file-system, the next +** connection to obtain a shared lock on the pager (which may be this one) ** will roll it back. ** ** If the pager has not already entered the ERROR state, but an IO or -** malloc error occurs during a rollback, then this will itself cause +** malloc error occurs during a rollback, then this will itself cause ** the pager to enter the ERROR state. Which will be cleared by the ** call to pager_unlock(), as described above. */ @@ -2166,16 +2192,31 @@ assert( pPager->eState==PAGER_READER ); pager_end_transaction(pPager, 0, 0); } + }else if( pPager->eState==PAGER_ERROR + && pPager->journalMode==PAGER_JOURNALMODE_MEMORY + && isOpen(pPager->jfd) + ){ + /* Special case for a ROLLBACK due to I/O error with an in-memory + ** journal: We have to rollback immediately, before the journal is + ** closed, because once it is closed, all content is forgotten. */ + int errCode = pPager->errCode; + u8 eLock = pPager->eLock; + pPager->eState = PAGER_OPEN; + pPager->errCode = SQLITE_OK; + pPager->eLock = EXCLUSIVE_LOCK; + pager_playback(pPager, 1); + pPager->errCode = errCode; + pPager->eLock = eLock; } pager_unlock(pPager); } /* ** Parameter aData must point to a buffer of pPager->pageSize bytes -** of data. Compute and return a checksum based ont the contents of the +** of data. Compute and return a checksum based on the contents of the ** page of data and the current value of pPager->cksumInit. ** -** This is not a real checksum. It is really just the sum of the +** This is not a real checksum. It is really just the sum of the ** random initial value (pPager->cksumInit) and every 200th byte ** of the page data, starting with byte offset (pPager->pageSize%200). ** Each byte is interpreted as an 8-bit unsigned integer. @@ -2183,8 +2224,8 @@ ** Changing the formula used to compute this checksum results in an ** incompatible journal file format. ** -** If journal corruption occurs due to a power failure, the most likely -** scenario is that one end or the other of the record will be changed. +** If journal corruption occurs due to a power failure, the most likely +** scenario is that one end or the other of the record will be changed. ** It is much less likely that the two ends of the journal record will be ** correct and the middle be corrupt. Thus, this "checksum" scheme, ** though fast and simple, catches the mostly likely kind of corruption. @@ -2205,7 +2246,7 @@ ** The page begins at offset *pOffset into the file. The *pOffset ** value is increased to the start of the next page in the journal. ** -** The main rollback journal uses checksums - the statement journal does +** The main rollback journal uses checksums - the statement journal does ** not. ** ** If the page number of the page record read from the (sub-)journal file @@ -2225,7 +2266,7 @@ ** is successfully read from the (sub-)journal file but appears to be ** corrupted, SQLITE_DONE is returned. Data is considered corrupted in ** two circumstances: -** +** ** * If the record page-number is illegal (0 or PAGER_SJ_PGNO), or ** * If the record is being rolled back from the main journal file ** and the checksum field does not match the record content. @@ -2260,7 +2301,7 @@ assert( aData ); /* Temp storage must have already been allocated */ assert( pagerUseWal(pPager)==0 || (!isMainJrnl && isSavepnt) ); - /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction + /* Either the state is greater than PAGER_WRITER_CACHEMOD (a transaction ** or savepoint rollback done at the request of the caller) or this is ** a hot-journal rollback. If it is a hot-journal rollback, the pager ** is in state OPEN and holds an EXCLUSIVE lock. Hot-journal rollback @@ -2326,7 +2367,7 @@ ** assert()able. ** ** If in WRITER_DBMOD, WRITER_FINISHED or OPEN state, then we update the - ** pager cache if it exists and the main file. The page is then marked + ** pager cache if it exists and the main file. The page is then marked ** not dirty. Since this code is only executed in PAGER_OPEN state for ** a hot-journal rollback, it is guaranteed that the page-cache is empty ** if the pager is in OPEN state. @@ -2390,18 +2431,18 @@ }else if( !isMainJrnl && pPg==0 ){ /* If this is a rollback of a savepoint and data was not written to ** the database and the page is not in-memory, there is a potential - ** problem. When the page is next fetched by the b-tree layer, it - ** will be read from the database file, which may or may not be - ** current. + ** problem. When the page is next fetched by the b-tree layer, it + ** will be read from the database file, which may or may not be + ** current. ** ** There are a couple of different ways this can happen. All are quite - ** obscure. When running in synchronous mode, this can only happen + ** obscure. When running in synchronous mode, this can only happen ** if the page is on the free-list at the start of the transaction, then ** populated, then moved using sqlite3PagerMovepage(). ** ** The solution is to add an in-memory page to the cache containing - ** the data just read from the sub-journal. Mark the page as dirty - ** and if the pager requires a journal-sync, then mark the page as + ** the data just read from the sub-journal. Mark the page as dirty + ** and if the pager requires a journal-sync, then mark the page as ** requiring a journal-sync before it is written. */ assert( isSavepnt ); @@ -2446,26 +2487,26 @@ ** This routine checks if it is possible to delete the super-journal file, ** and does so if it is. ** -** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not +** Argument zSuper may point to Pager.pTmpSpace. So that buffer is not ** available for use within this function. ** -** When a super-journal file is created, it is populated with the names -** of all of its child journals, one after another, formatted as utf-8 -** encoded text. The end of each child journal file is marked with a +** When a super-journal file is created, it is populated with the names +** of all of its child journals, one after another, formatted as utf-8 +** encoded text. The end of each child journal file is marked with a ** nul-terminator byte (0x00). i.e. the entire contents of a super-journal ** file for a transaction involving two databases might be: ** ** "/home/bill/a.db-journal\x00/home/bill/b.db-journal\x00" ** -** A super-journal file may only be deleted once all of its child +** A super-journal file may only be deleted once all of its child ** journals have been rolled back. ** -** This function reads the contents of the super-journal file into +** This function reads the contents of the super-journal file into ** memory and loops through each of the child journal names. For ** each child journal, it checks if: ** ** * if the child journal exists, and if so -** * if the child journal contains a reference to super-journal +** * if the child journal contains a reference to super-journal ** file zSuper ** ** If a child journal can be found that matches both of the criteria @@ -2475,12 +2516,12 @@ ** ** If an IO error within this function, an error code is returned. This ** function allocates memory by calling sqlite3Malloc(). If an allocation -** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors +** fails, SQLITE_NOMEM is returned. Otherwise, if no IO or malloc errors ** occur, SQLITE_OK is returned. ** ** TODO: This function allocates a single block of memory to load ** the entire contents of the super-journal file. This could be -** a couple of kilobytes or so - potentially larger than the page +** a couple of kilobytes or so - potentially larger than the page ** size. */ static int pager_delsuper(Pager *pPager, const char *zSuper){ @@ -2541,7 +2582,7 @@ /* One of the journals pointed to by the super-journal exists. ** Open it and check if it points at the super-journal. If ** so, return without deleting the super-journal file. - ** NB: zJournal is really a MAIN_JOURNAL. But call it a + ** NB: zJournal is really a MAIN_JOURNAL. But call it a ** SUPER_JOURNAL here so that the VFS will not send the zJournal ** name into sqlite3_database_file_object(). */ @@ -2566,7 +2607,7 @@ } zJournal += (sqlite3Strlen30(zJournal)+1); } - + sqlite3OsClose(pSuper); rc = sqlite3OsDelete(pVfs, zSuper, 0); @@ -2582,20 +2623,20 @@ /* -** This function is used to change the actual size of the database +** This function is used to change the actual size of the database ** file in the file-system. This only happens when committing a transaction, ** or rolling back a transaction (including rolling back a hot-journal). ** ** If the main database file is not open, or the pager is not in either -** DBMOD or OPEN state, this function is a no-op. Otherwise, the size -** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). +** DBMOD or OPEN state, this function is a no-op. Otherwise, the size +** of the file is changed to nPage pages (nPage*pPager->pageSize bytes). ** If the file on disk is currently larger than nPage pages, then use the VFS ** xTruncate() method to truncate it. ** -** Or, it might be the case that the file on disk is smaller than -** nPage pages. Some operating system implementations can get confused if -** you try to truncate a file to some size that is larger than it -** currently is, so detect this case and write a single zero byte to +** Or, it might be the case that the file on disk is smaller than +** nPage pages. Some operating system implementations can get confused if +** you try to truncate a file to some size that is larger than it +** currently is, so detect this case and write a single zero byte to ** the end of the new file instead. ** ** If successful, return SQLITE_OK. If an IO error occurs while modifying @@ -2607,9 +2648,9 @@ assert( pPager->eState!=PAGER_READER ); PAGERTRACE(("Truncate %d npage %u\n", PAGERID(pPager), nPage)); - - if( isOpen(pPager->fd) - && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) + + if( isOpen(pPager->fd) + && (pPager->eState>=PAGER_WRITER_DBMOD || pPager->eState==PAGER_OPEN) ){ i64 currentSize, newSize; int szPage = pPager->pageSize; @@ -2654,8 +2695,8 @@ /* ** Set the value of the Pager.sectorSize variable for the given ** pager based on the value returned by the xSectorSize method -** of the open database file. The sector size will be used -** to determine the size and alignment of journal header and +** of the open database file. The sector size will be used +** to determine the size and alignment of journal header and ** super-journal pointers within created journal files. ** ** For temporary files the effective sector size is always 512 bytes. @@ -2678,7 +2719,7 @@ assert( isOpen(pPager->fd) || pPager->tempFile ); if( pPager->tempFile - || (sqlite3OsDeviceCharacteristics(pPager->fd) & + || (sqlite3OsDeviceCharacteristics(pPager->fd) & SQLITE_IOCAP_POWERSAFE_OVERWRITE)!=0 ){ /* Sector size doesn't matter for temporary files. Also, the file @@ -2692,15 +2733,15 @@ /* ** Playback the journal and thus restore the database file to -** the state it was in before we started making changes. +** the state it was in before we started making changes. ** -** The journal file format is as follows: +** The journal file format is as follows: ** ** (1) 8 byte prefix. A copy of aJournalMagic[]. ** (2) 4 byte big-endian integer which is the number of valid page records ** in the journal. If this value is 0xffffffff, then compute the ** number of page records from the journal size. -** (3) 4 byte big-endian integer which is the initial value for the +** (3) 4 byte big-endian integer which is the initial value for the ** sanity checksum. ** (4) 4 byte integer which is the number of pages to truncate the ** database to during a rollback. @@ -2729,7 +2770,7 @@ ** from the file size. This value is used when the user selects the ** no-sync option for the journal. A power failure could lead to corruption ** in this case. But for things like temporary table (which will be -** deleted when the power is restored) we don't care. +** deleted when the power is restored) we don't care. ** ** If the file opened as the journal file is not a well-formed ** journal file then all pages up to the first corrupted page are rolled @@ -2741,7 +2782,7 @@ ** and an error code is returned. ** ** The isHot parameter indicates that we are trying to rollback a journal -** that might be a hot journal. Or, it could be that the journal is +** that might be a hot journal. Or, it could be that the journal is ** preserved because of JOURNALMODE_PERSIST or JOURNALMODE_TRUNCATE. ** If the journal really is hot, reset the pager cache prior rolling ** back any content. If the journal is merely persistent, no reset is @@ -2792,9 +2833,9 @@ pPager->journalOff = 0; needPagerReset = isHot; - /* This loop terminates either when a readJournalHdr() or - ** pager_playback_one_page() call returns SQLITE_DONE or an IO error - ** occurs. + /* This loop terminates either when a readJournalHdr() or + ** pager_playback_one_page() call returns SQLITE_DONE or an IO error + ** occurs. */ while( 1 ){ /* Read the next journal header from the journal file. If there are @@ -2803,7 +2844,7 @@ ** This indicates nothing more needs to be rolled back. */ rc = readJournalHdr(pPager, isHot, szJ, &nRec, &mxPg); - if( rc!=SQLITE_OK ){ + if( rc!=SQLITE_OK ){ if( rc==SQLITE_DONE ){ rc = SQLITE_OK; } @@ -2831,7 +2872,7 @@ ** chunk of the journal contains zero pages to be rolled back. But ** when doing a ROLLBACK and the nRec==0 chunk is the last chunk in ** the journal, it means that the journal might contain additional - ** pages that need to be rolled back and that the number of pages + ** pages that need to be rolled back and that the number of pages ** should be computed based on the journal file size. */ if( nRec==0 && !isHot && @@ -2853,7 +2894,7 @@ } } - /* Copy original pages out of the journal and back into the + /* Copy original pages out of the journal and back into the ** database file and/or page cache. */ for(u=0; ufd,SQLITE_FCNTL_DB_UNCHANGED,0); #endif - /* If this playback is happening automatically as a result of an IO or - ** malloc error that occurred after the change-counter was updated but - ** before the transaction was committed, then the change-counter - ** modification may just have been reverted. If this happens in exclusive + /* If this playback is happening automatically as a result of an IO or + ** malloc error that occurred after the change-counter was updated but + ** before the transaction was committed, then the change-counter + ** modification may just have been reverted. If this happens in exclusive ** mode, then subsequent transactions performed by the connection will not ** update the change-counter at all. This may lead to cache inconsistency ** problems for other processes at some point in the future. So, just @@ -2957,7 +2998,7 @@ /* ** Read the content for page pPg out of the database file (or out of -** the WAL if that is where the most recent copy if found) into +** the WAL if that is where the most recent copy if found) into ** pPg->pData. A shared lock or greater must be held on the database ** file before this function is called. ** @@ -3047,15 +3088,15 @@ #ifndef SQLITE_OMIT_WAL /* -** This function is invoked once for each page that has already been +** This function is invoked once for each page that has already been ** written into the log file when a WAL transaction is rolled back. -** Parameter iPg is the page number of said page. The pCtx argument +** Parameter iPg is the page number of said page. The pCtx argument ** is actually a pointer to the Pager structure. ** ** If page iPg is present in the cache, and has no outstanding references, ** it is discarded. Otherwise, if there are one or more outstanding ** references, the page content is reloaded from the database. If the -** attempt to reload content from the database is required and fails, +** attempt to reload content from the database is required and fails, ** return an SQLite error code. Otherwise, SQLITE_OK. */ static int pagerUndoCallback(void *pCtx, Pgno iPg){ @@ -3081,7 +3122,7 @@ ** updated as data is copied out of the rollback journal and into the ** database. This is not generally possible with a WAL database, as ** rollback involves simply truncating the log file. Therefore, if one - ** or more frames have already been written to the log (and therefore + ** or more frames have already been written to the log (and therefore ** also copied into the backup databases) as part of this transaction, ** the backups must be restarted. */ @@ -3098,7 +3139,7 @@ PgHdr *pList; /* List of dirty pages to revert */ /* For all pages in the cache that are currently dirty or have already - ** been written (but not committed) to the log file, do one of the + ** been written (but not committed) to the log file, do one of the ** following: ** ** + Discard the cached page (if refcount==0), or @@ -3120,11 +3161,11 @@ ** This function is a wrapper around sqlite3WalFrames(). As well as logging ** the contents of the list of pages headed by pList (connected by pDirty), ** this function notifies any active backup processes that the pages have -** changed. +** changed. ** ** The list of pages passed into this routine is always sorted by page number. ** Hence, if page 1 appears anywhere on the list, it will be the first page. -*/ +*/ static int pagerWalFrames( Pager *pPager, /* Pager object */ PgHdr *pList, /* List of frames to log */ @@ -3138,7 +3179,7 @@ assert( pPager->pWal ); assert( pList ); #ifdef SQLITE_DEBUG - /* Verify that the page list is in accending order */ + /* Verify that the page list is in ascending order */ for(p=pList; p && p->pDirty; p=p->pDirty){ assert( p->pgno < p->pDirty->pgno ); } @@ -3165,7 +3206,7 @@ pPager->aStat[PAGER_STAT_WRITE] += nList; if( pList->pgno==1 ) pager_write_changecounter(pList); - rc = sqlite3WalFrames(pPager->pWal, + rc = sqlite3WalFrames(pPager->pWal, pPager->pageSize, pList, nTruncate, isCommit, pPager->walSyncFlags ); if( rc==SQLITE_OK && pPager->pBackup ){ @@ -3269,7 +3310,7 @@ #ifndef SQLITE_OMIT_WAL /* ** Check if the *-wal file that corresponds to the database opened by pPager -** exists if the database is not empy, or verify that the *-wal file does +** exists if the database is not empty, or verify that the *-wal file does ** not exist (by deleting it) if the database file is empty. ** ** If the database is not empty and the *-wal file exists, open the pager @@ -3280,9 +3321,9 @@ ** Return SQLITE_OK or an error code. ** ** The caller must hold a SHARED lock on the database file to call this -** function. Because an EXCLUSIVE lock on the db file is required to delete -** a WAL on a none-empty database, this ensures there is no race condition -** between the xAccess() below and an xDelete() being executed by some +** function. Because an EXCLUSIVE lock on the db file is required to delete +** a WAL on a none-empty database, this ensures there is no race condition +** between the xAccess() below and an xDelete() being executed by some ** other connection. */ static int pagerOpenWalIfPresent(Pager *pPager){ @@ -3318,21 +3359,21 @@ /* ** Playback savepoint pSavepoint. Or, if pSavepoint==NULL, then playback -** the entire super-journal file. The case pSavepoint==NULL occurs when -** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction +** the entire super-journal file. The case pSavepoint==NULL occurs when +** a ROLLBACK TO command is invoked on a SAVEPOINT that is a transaction ** savepoint. ** -** When pSavepoint is not NULL (meaning a non-transaction savepoint is +** When pSavepoint is not NULL (meaning a non-transaction savepoint is ** being rolled back), then the rollback consists of up to three stages, ** performed in the order specified: ** ** * Pages are played back from the main journal starting at byte -** offset PagerSavepoint.iOffset and continuing to +** offset PagerSavepoint.iOffset and continuing to ** PagerSavepoint.iHdrOffset, or to the end of the main journal ** file if PagerSavepoint.iHdrOffset is zero. ** ** * If PagerSavepoint.iHdrOffset is not zero, then pages are played -** back starting from the journal header immediately following +** back starting from the journal header immediately following ** PagerSavepoint.iHdrOffset to the end of the main journal file. ** ** * Pages are then played back from the sub-journal file, starting @@ -3348,7 +3389,7 @@ ** journal file. There is no need for a bitvec in this case. ** ** In either case, before playback commences the Pager.dbSize variable -** is reset to the value that it held at the start of the savepoint +** is reset to the value that it held at the start of the savepoint ** (or transaction). No page with a page-number greater than this value ** is played back. If one is encountered it is simply skipped. */ @@ -3369,7 +3410,7 @@ } } - /* Set the database size back to the value it was before the savepoint + /* Set the database size back to the value it was before the savepoint ** being reverted was opened. */ pPager->dbSize = pSavepoint ? pSavepoint->nOrig : pPager->dbOrigSize; @@ -3422,7 +3463,7 @@ ** test is related to ticket #2565. See the discussion in the ** pager_playback() function for additional information. */ - if( nJRec==0 + if( nJRec==0 && pPager->journalHdr+JOURNAL_HDR_SZ(pPager)==pPager->journalOff ){ nJRec = (u32)((szJ - pPager->journalOff)/JOURNAL_PG_SZ(pPager)); @@ -3596,7 +3637,7 @@ /* ** The following global variable is incremented whenever the library ** attempts to open a temporary file. This information is used for -** testing and analysis only. +** testing and analysis only. */ #ifdef SQLITE_TEST int sqlite3_opentemp_count = 0; @@ -3605,8 +3646,8 @@ /* ** Open a temporary file. ** -** Write the file descriptor into *pFile. Return SQLITE_OK on success -** or some other error code if we fail. The OS will automatically +** Write the file descriptor into *pFile. Return SQLITE_OK on success +** or some other error code if we fail. The OS will automatically ** delete the temporary file when it is closed. ** ** The flags passed to the VFS layer xOpen() call are those specified @@ -3638,9 +3679,9 @@ /* ** Set the busy handler function. ** -** The pager invokes the busy-handler if sqlite3OsLock() returns +** The pager invokes the busy-handler if sqlite3OsLock() returns ** SQLITE_BUSY when trying to upgrade from no-lock to a SHARED lock, -** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE +** or when trying to upgrade from a RESERVED lock to an EXCLUSIVE ** lock. It does *not* invoke the busy handler when upgrading from ** SHARED to RESERVED, or when upgrading from SHARED to EXCLUSIVE ** (which occurs during hot-journal rollback). Summary: @@ -3652,7 +3693,7 @@ ** SHARED_LOCK -> EXCLUSIVE_LOCK | No ** RESERVED_LOCK -> EXCLUSIVE_LOCK | Yes ** -** If the busy-handler callback returns non-zero, the lock is +** If the busy-handler callback returns non-zero, the lock is ** retried. If it returns zero, then the SQLITE_BUSY error is ** returned to the caller of the pager API function. */ @@ -3671,16 +3712,16 @@ } /* -** Change the page size used by the Pager object. The new page size +** Change the page size used by the Pager object. The new page size ** is passed in *pPageSize. ** ** If the pager is in the error state when this function is called, it -** is a no-op. The value returned is the error state error code (i.e. +** is a no-op. The value returned is the error state error code (i.e. ** one of SQLITE_IOERR, an SQLITE_IOERR_xxx sub-code or SQLITE_FULL). ** ** Otherwise, if all of the following are true: ** -** * the new page size (value of *pPageSize) is valid (a power +** * the new page size (value of *pPageSize) is valid (a power ** of two between 512 and SQLITE_MAX_PAGE_SIZE, inclusive), and ** ** * there are no outstanding page references, and @@ -3690,14 +3731,14 @@ ** ** then the pager object page size is set to *pPageSize. ** -** If the page size is changed, then this function uses sqlite3PagerMalloc() -** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt -** fails, SQLITE_NOMEM is returned and the page size remains unchanged. +** If the page size is changed, then this function uses sqlite3PagerMalloc() +** to obtain a new Pager.pTmpSpace buffer. If this allocation attempt +** fails, SQLITE_NOMEM is returned and the page size remains unchanged. ** In all other cases, SQLITE_OK is returned. ** ** If the page size is not changed, either because one of the enumerated ** conditions above is not true, the pager was in error state when this -** function was called, or because the memory allocation attempt failed, +** function was called, or because the memory allocation attempt failed, ** then *pPageSize is set to the old, retained page size before returning. */ int sqlite3PagerSetPagesize(Pager *pPager, u32 *pPageSize, int nReserve){ @@ -3707,7 +3748,7 @@ ** function may be called from within PagerOpen(), before the state ** of the Pager object is internally consistent. ** - ** At one point this function returned an error if the pager was in + ** At one point this function returned an error if the pager was in ** PAGER_ERROR state. But since PAGER_ERROR state guarantees that ** there is at least one outstanding page reference, this function ** is a no-op for that case anyhow. @@ -3716,8 +3757,8 @@ u32 pageSize = *pPageSize; assert( pageSize==0 || (pageSize>=512 && pageSize<=SQLITE_MAX_PAGE_SIZE) ); if( (pPager->memDb==0 || pPager->dbSize==0) - && sqlite3PcacheRefCount(pPager->pPCache)==0 - && pageSize && pageSize!=(u32)pPager->pageSize + && sqlite3PcacheRefCount(pPager->pPCache)==0 + && pageSize && pageSize!=(u32)pPager->pageSize ){ char *pNew = NULL; /* New temp space */ i64 nByte = 0; @@ -3774,7 +3815,7 @@ } /* -** Attempt to set the maximum database page count if mxPage is positive. +** Attempt to set the maximum database page count if mxPage is positive. ** Make no changes if mxPage is zero or negative. And never reduce the ** maximum page count below the current size of the database. ** @@ -3818,11 +3859,11 @@ /* ** Read the first N bytes from the beginning of the file into memory -** that pDest points to. +** that pDest points to. ** ** If the pager was opened on a transient file (zFilename==""), or ** opened on a file less than N bytes in size, the output buffer is -** zeroed and SQLITE_OK returned. The rationale for this is that this +** zeroed and SQLITE_OK returned. The rationale for this is that this ** function is used to read database headers, and a new transient or ** zero sized database has a header than consists entirely of zeroes. ** @@ -3855,7 +3896,7 @@ ** This function may only be called when a read-transaction is open on ** the pager. It returns the total number of pages in the database. ** -** However, if the file is between 1 and bytes in size, then +** However, if the file is between 1 and bytes in size, then ** this is considered a 1 page file. */ void sqlite3PagerPagecount(Pager *pPager, int *pnPage){ @@ -3870,19 +3911,19 @@ ** a similar or greater lock is already held, this function is a no-op ** (returning SQLITE_OK immediately). ** -** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke -** the busy callback if the lock is currently not available. Repeat -** until the busy callback returns false or until the attempt to +** Otherwise, attempt to obtain the lock using sqlite3OsLock(). Invoke +** the busy callback if the lock is currently not available. Repeat +** until the busy callback returns false or until the attempt to ** obtain the lock succeeds. ** ** Return SQLITE_OK on success and an error code if we cannot obtain -** the lock. If the lock is obtained successfully, set the Pager.state +** the lock. If the lock is obtained successfully, set the Pager.state ** variable to locktype before returning. */ static int pager_wait_on_lock(Pager *pPager, int locktype){ int rc; /* Return code */ - /* Check that this is either a no-op (because the requested lock is + /* Check that this is either a no-op (because the requested lock is ** already held), or one of the transitions that the busy-handler ** may be invoked during, according to the comment above ** sqlite3PagerSetBusyhandler(). @@ -3899,10 +3940,10 @@ } /* -** Function assertTruncateConstraint(pPager) checks that one of the +** Function assertTruncateConstraint(pPager) checks that one of the ** following is true for all dirty pages currently in the page-cache: ** -** a) The page number is less than or equal to the size of the +** a) The page number is less than or equal to the size of the ** current database image, in pages, OR ** ** b) if the page content were written at this time, it would not @@ -3914,9 +3955,9 @@ ** the database file. If a savepoint transaction were rolled back after ** this happened, the correct behavior would be to restore the current ** content of the page. However, since this content is not present in either -** the database file or the portion of the rollback journal and +** the database file or the portion of the rollback journal and ** sub-journal rolled back the content could not be restored and the -** database image would become corrupt. It is therefore fortunate that +** database image would become corrupt. It is therefore fortunate that ** this circumstance cannot arise. */ #if defined(SQLITE_DEBUG) @@ -3940,9 +3981,9 @@ #endif /* -** Truncate the in-memory database file image to nPage pages. This -** function does not actually modify the database file on disk. It -** just sets the internal state of the pager object so that the +** Truncate the in-memory database file image to nPage pages. This +** function does not actually modify the database file on disk. It +** just sets the internal state of the pager object so that the ** truncation will be done when the current transaction is committed. ** ** This function is only called right before committing a transaction. @@ -3957,11 +3998,11 @@ /* At one point the code here called assertTruncateConstraint() to ** ensure that all pages being truncated away by this operation are, - ** if one or more savepoints are open, present in the savepoint + ** if one or more savepoints are open, present in the savepoint ** journal so that they can be restored if the savepoint is rolled ** back. This is no longer necessary as this function is now only - ** called right before committing a transaction. So although the - ** Pager object may still have open savepoints (Pager.nSavepoint!=0), + ** called right before committing a transaction. So although the + ** Pager object may still have open savepoints (Pager.nSavepoint!=0), ** they cannot be rolled back. So the assertTruncateConstraint() call ** is no longer correct. */ } @@ -3973,12 +4014,12 @@ ** size of the journal file so that the pager_playback() routine knows ** that the entire journal file has been synced. ** -** Syncing a hot-journal to disk before attempting to roll it back ensures +** Syncing a hot-journal to disk before attempting to roll it back ensures ** that if a power-failure occurs during the rollback, the process that ** attempts rollback following system recovery sees the same journal ** content as this process. ** -** If everything goes as planned, SQLITE_OK is returned. Otherwise, +** If everything goes as planned, SQLITE_OK is returned. Otherwise, ** an SQLite error code. */ static int pagerSyncHotJournal(Pager *pPager){ @@ -3994,7 +4035,7 @@ #if SQLITE_MAX_MMAP_SIZE>0 /* -** Obtain a reference to a memory mapped page object for page number pgno. +** Obtain a reference to a memory mapped page object for page number pgno. ** The new object will use the pointer pData, obtained from xFetch(). ** If successful, set *ppPage to point to the new page reference ** and return SQLITE_OK. Otherwise, return an SQLite error code and set @@ -4010,7 +4051,7 @@ PgHdr **ppPage /* OUT: Acquired page object */ ){ PgHdr *p; /* Memory mapped page to return */ - + if( pPager->pMmapFreelist ){ *ppPage = p = pPager->pMmapFreelist; pPager->pMmapFreelist = p->pDirty; @@ -4044,7 +4085,7 @@ #endif /* -** Release a reference to page pPg. pPg must have been returned by an +** Release a reference to page pPg. pPg must have been returned by an ** earlier call to pagerAcquireMapPage(). */ static void pagerReleaseMapPage(PgHdr *pPg){ @@ -4104,7 +4145,7 @@ ** result in a coredump. ** ** This function always succeeds. If a transaction is active an attempt -** is made to roll it back. If an error occurs during the rollback +** is made to roll it back. If an error occurs during the rollback ** a hot journal may be left in the filesystem but no error is returned ** to the caller. */ @@ -4121,7 +4162,7 @@ { u8 *a = 0; assert( db || pPager->pWal==0 ); - if( db && 0==(db->flags & SQLITE_NoCkptOnClose) + if( db && 0==(db->flags & SQLITE_NoCkptOnClose) && SQLITE_OK==databaseIsUnmoved(pPager) ){ a = pTmp; @@ -4135,8 +4176,8 @@ pager_unlock(pPager); }else{ /* If it is open, sync the journal file before calling UnlockAndRollback. - ** If this is not done, then an unsynced portion of the open journal - ** file may be played back into the database. If a power failure occurs + ** If this is not done, then an unsynced portion of the open journal + ** file may be played back into the database. If a power failure occurs ** while this is happening, the database could become corrupt. ** ** If an error occurs while trying to sync the journal, shift the pager @@ -4187,7 +4228,7 @@ ** disk and can be restored in the event of a hot-journal rollback. ** ** If the Pager.noSync flag is set, then this function is a no-op. -** Otherwise, the actions required depend on the journal-mode and the +** Otherwise, the actions required depend on the journal-mode and the ** device characteristics of the file-system, as follows: ** ** * If the journal file is an in-memory journal file, no action need @@ -4199,7 +4240,7 @@ ** been written following it. If the pager is operating in full-sync ** mode, then the journal file is synced before this field is updated. ** -** * If the device does not support the SEQUENTIAL property, then +** * If the device does not support the SEQUENTIAL property, then ** journal file is synced. ** ** Or, in pseudo-code: @@ -4208,11 +4249,11 @@ ** if( NOT SAFE_APPEND ){ ** if( ) xSync(); ** -** } +** } ** if( NOT SEQUENTIAL ) xSync(); ** } ** -** If successful, this routine clears the PGHDR_NEED_SYNC flag of every +** If successful, this routine clears the PGHDR_NEED_SYNC flag of every ** page currently held in memory before returning SQLITE_OK. If an IO ** error is encountered, then the IO error code is returned to the caller. */ @@ -4240,10 +4281,10 @@ ** mode, then the journal file may at this point actually be larger ** than Pager.journalOff bytes. If the next thing in the journal ** file happens to be a journal-header (written as part of the - ** previous connection's transaction), and a crash or power-failure - ** occurs after nRec is updated but before this connection writes - ** anything else to the journal file (or commits/rolls back its - ** transaction), then SQLite may become confused when doing the + ** previous connection's transaction), and a crash or power-failure + ** occurs after nRec is updated but before this connection writes + ** anything else to the journal file (or commits/rolls back its + ** transaction), then SQLite may become confused when doing the ** hot-journal rollback following recovery. It may roll back all ** of this connections data, then proceed to rolling back the old, ** out-of-date data that follows it. Database corruption. @@ -4253,7 +4294,7 @@ ** byte to the start of it to prevent it from being recognized. ** ** Variable iNextHdrOffset is set to the offset at which this - ** problematic header will occur, if it exists. aMagic is used + ** problematic header will occur, if it exists. aMagic is used ** as a temporary buffer to inspect the first couple of bytes of ** the potential journal header. */ @@ -4280,7 +4321,7 @@ ** it as a candidate for rollback. ** ** This is not required if the persistent media supports the - ** SAFE_APPEND property. Because in this case it is not possible + ** SAFE_APPEND property. Because in this case it is not possible ** for garbage data to be appended to the file, the nRec field ** is populated with 0xFFFFFFFF when the journal header is written ** and never needs to be updated. @@ -4300,7 +4341,7 @@ if( 0==(iDc&SQLITE_IOCAP_SEQUENTIAL) ){ PAGERTRACE(("SYNC journal of %d\n", PAGERID(pPager))); IOTRACE(("JSYNC %p\n", pPager)) - rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| + rc = sqlite3OsSync(pPager->jfd, pPager->syncFlags| (pPager->syncFlags==SQLITE_SYNC_FULL?SQLITE_SYNC_DATAONLY:0) ); if( rc!=SQLITE_OK ) return rc; @@ -4317,8 +4358,8 @@ } } - /* Unless the pager is in noSync mode, the journal file was just - ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on + /* Unless the pager is in noSync mode, the journal file was just + ** successfully synced. Either way, clear the PGHDR_NEED_SYNC flag on ** all pages. */ sqlite3PcacheClearSyncFlags(pPager->pPCache); @@ -4338,9 +4379,9 @@ ** is called. Before writing anything to the database file, this lock ** is upgraded to an EXCLUSIVE lock. If the lock cannot be obtained, ** SQLITE_BUSY is returned and no data is written to the database file. -** +** ** If the pager is a temp-file pager and the actual file-system file -** is not yet open, it is created and opened before any data is +** is not yet open, it is created and opened before any data is ** written out. ** ** Once the lock has been upgraded and, if necessary, the file opened, @@ -4355,7 +4396,7 @@ ** in Pager.dbFileVers[] is updated to match the new value stored in ** the database file. ** -** If everything is successful, SQLITE_OK is returned. If an IO error +** If everything is successful, SQLITE_OK is returned. If an IO error ** occurs, an IO error code is returned. Or, if the EXCLUSIVE lock cannot ** be obtained, SQLITE_BUSY is returned. */ @@ -4381,7 +4422,7 @@ ** file size will be. */ assert( rc!=SQLITE_OK || isOpen(pPager->fd) ); - if( rc==SQLITE_OK + if( rc==SQLITE_OK && pPager->dbHintSizedbSize && (pList->pDirty || pList->pgno>pPager->dbHintSize) ){ @@ -4403,7 +4444,7 @@ */ if( pgno<=pPager->dbSize && 0==(pList->flags&PGHDR_DONT_WRITE) ){ i64 offset = (pgno-1)*(i64)pPager->pageSize; /* Offset to write */ - char *pData; /* Data to write */ + char *pData; /* Data to write */ assert( (pList->flags&PGHDR_NEED_SYNC)==0 ); if( pList->pgno==1 ) pager_write_changecounter(pList); @@ -4414,8 +4455,8 @@ rc = sqlite3OsWrite(pPager->fd, pData, pPager->pageSize, offset); /* If page 1 was just written, update Pager.dbFileVers to match - ** the value now stored in the database file. If writing this - ** page caused the database file to grow, update dbFileSize. + ** the value now stored in the database file. If writing this + ** page caused the database file to grow, update dbFileSize. */ if( pgno==1 ){ memcpy(&pPager->dbFileVers, &pData[24], sizeof(pPager->dbFileVers)); @@ -4443,18 +4484,18 @@ } /* -** Ensure that the sub-journal file is open. If it is already open, this +** Ensure that the sub-journal file is open. If it is already open, this ** function is a no-op. ** -** SQLITE_OK is returned if everything goes according to plan. An -** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() +** SQLITE_OK is returned if everything goes according to plan. An +** SQLITE_IOERR_XXX error code is returned if a call to sqlite3OsOpen() ** fails. */ static int openSubJournal(Pager *pPager){ int rc = SQLITE_OK; if( !isOpen(pPager->sjfd) ){ - const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE - | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE + const int flags = SQLITE_OPEN_SUBJOURNAL | SQLITE_OPEN_READWRITE + | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE; int nStmtSpill = sqlite3Config.nStmtSpill; if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY || pPager->subjInMemory ){ @@ -4466,13 +4507,13 @@ } /* -** Append a record of the current state of page pPg to the sub-journal. +** Append a record of the current state of page pPg to the sub-journal. ** ** If successful, set the bit corresponding to pPg->pgno in the bitvecs ** for all open savepoints before returning. ** ** This function returns SQLITE_OK if everything is successful, an IO -** error code if the attempt to write to the sub-journal fails, or +** error code if the attempt to write to the sub-journal fails, or ** SQLITE_NOMEM if a malloc fails while setting a bit in a savepoint ** bitvec. */ @@ -4485,9 +4526,9 @@ assert( pPager->useJournal ); assert( isOpen(pPager->jfd) || pagerUseWal(pPager) ); assert( isOpen(pPager->sjfd) || pPager->nSubRec==0 ); - assert( pagerUseWal(pPager) - || pageInJournal(pPager, pPg) - || pPg->pgno>pPager->dbOrigSize + assert( pagerUseWal(pPager) + || pageInJournal(pPager, pPg) + || pPg->pgno>pPager->dbOrigSize ); rc = openSubJournal(pPager); @@ -4524,14 +4565,14 @@ ** This function is called by the pcache layer when it has reached some ** soft memory limit. The first argument is a pointer to a Pager object ** (cast as a void*). The pager is always 'purgeable' (not an in-memory -** database). The second argument is a reference to a page that is +** database). The second argument is a reference to a page that is ** currently dirty but has no outstanding references. The page -** is always associated with the Pager object passed as the first +** is always associated with the Pager object passed as the first ** argument. ** ** The job of this function is to make pPg clean by writing its contents ** out to the database file, if possible. This may involve syncing the -** journal file. +** journal file. ** ** If successful, sqlite3PcacheMakeClean() is called on the page and ** SQLITE_OK returned. If an IO error occurs while trying to make the @@ -4556,7 +4597,7 @@ ** a rollback or by user request, respectively. ** ** Spilling is also prohibited when in an error state since that could - ** lead to database corruption. In the current implementation it + ** lead to database corruption. In the current implementation it ** is impossible for sqlite3PcacheFetch() to be called with createFlag==3 ** while in the error state, hence it is impossible for this routine to ** be called in the error state. Nevertheless, we include a NEVER() @@ -4577,26 +4618,26 @@ pPg->pDirty = 0; if( pagerUseWal(pPager) ){ /* Write a single frame for this page to the log. */ - rc = subjournalPageIfRequired(pPg); + rc = subjournalPageIfRequired(pPg); if( rc==SQLITE_OK ){ rc = pagerWalFrames(pPager, pPg, 0, 0); } }else{ - + #ifdef SQLITE_ENABLE_BATCH_ATOMIC_WRITE if( pPager->tempFile==0 ){ rc = sqlite3JournalCreate(pPager->jfd); if( rc!=SQLITE_OK ) return pager_error(pPager, rc); } #endif - + /* Sync the journal file if required. */ - if( pPg->flags&PGHDR_NEED_SYNC + if( pPg->flags&PGHDR_NEED_SYNC || pPager->eState==PAGER_WRITER_CACHEMOD ){ rc = syncJournal(pPager, 1); } - + /* Write the contents of the page out to the database file. */ if( rc==SQLITE_OK ){ assert( (pPg->flags&PGHDR_NEED_SYNC)==0 ); @@ -4610,7 +4651,7 @@ sqlite3PcacheMakeClean(pPg); } - return pager_error(pPager, rc); + return pager_error(pPager, rc); } /* @@ -4641,8 +4682,8 @@ ** The zFilename argument is the path to the database file to open. ** If zFilename is NULL then a randomly-named temporary file is created ** and used as the file to be cached. Temporary files are be deleted -** automatically when they are closed. If zFilename is ":memory:" then -** all information is held in cache. It is never written to disk. +** automatically when they are closed. If zFilename is ":memory:" then +** all information is held in cache. It is never written to disk. ** This can be used to implement an in-memory database. ** ** The nExtra parameter specifies the number of bytes of space allocated @@ -4656,13 +4697,13 @@ ** of the PAGER_* flags. ** ** The vfsFlags parameter is a bitmask to pass to the flags parameter -** of the xOpen() method of the supplied VFS when opening files. +** of the xOpen() method of the supplied VFS when opening files. ** -** If the pager object is allocated and the specified file opened +** If the pager object is allocated and the specified file opened ** successfully, SQLITE_OK is returned and *ppPager set to point to ** the new pager object. If an error occurs, *ppPager is set to NULL ** and error code returned. This function may return SQLITE_NOMEM -** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or +** (sqlite3Malloc() is used to allocate memory), SQLITE_CANTOPEN or ** various SQLITE_IO_XXX errors. */ int sqlite3PagerOpen( @@ -4679,11 +4720,7 @@ int rc = SQLITE_OK; /* Return code */ int tempFile = 0; /* True for temp files (incl. in-memory files) */ int memDb = 0; /* True if this is an in-memory file */ -#ifndef SQLITE_OMIT_DESERIALIZE int memJM = 0; /* Memory journal mode */ -#else -# define memJM 0 -#endif int readOnly = 0; /* True if this is a read-only file */ int journalFileSize; /* Bytes to allocate for each journal fd */ char *zPathname = 0; /* Full path to database file */ @@ -4759,7 +4796,7 @@ } /* Allocate memory for the Pager structure, PCache object, the - ** three file descriptors, the database file name and the journal + ** three file descriptors, the database file name and the journal ** file name. The layout in memory is as follows: ** ** Pager object (sizeof(Pager) bytes) @@ -4802,12 +4839,13 @@ ** specific formatting and order of the various filenames, so if the format ** changes here, be sure to change it there as well. */ + assert( SQLITE_PTRSIZE==sizeof(Pager*) ); pPtr = (u8 *)sqlite3MallocZero( ROUND8(sizeof(*pPager)) + /* Pager structure */ ROUND8(pcacheSize) + /* PCache object */ ROUND8(pVfs->szOsFile) + /* The main db file */ journalFileSize * 2 + /* The two journal files */ - sizeof(pPager) + /* Space to hold a pointer */ + SQLITE_PTRSIZE + /* Space to hold a pointer */ 4 + /* Database prefix */ nPathname + 1 + /* database filename */ nUriByte + /* query parameters */ @@ -4828,7 +4866,7 @@ pPager->sjfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; pPager->jfd = (sqlite3_file*)pPtr; pPtr += journalFileSize; assert( EIGHT_BYTE_ALIGNMENT(pPager->jfd) ); - memcpy(pPtr, &pPager, sizeof(pPager)); pPtr += sizeof(pPager); + memcpy(pPtr, &pPager, SQLITE_PTRSIZE); pPtr += SQLITE_PTRSIZE; /* Fill in the Pager.zFilename and pPager.zQueryParam fields */ pPtr += 4; /* Skip zero prefix */ @@ -4882,9 +4920,7 @@ int fout = 0; /* VFS flags returned by xOpen() */ rc = sqlite3OsOpen(pVfs, pPager->zFilename, pPager->fd, vfsFlags, &fout); assert( !memDb ); -#ifndef SQLITE_OMIT_DESERIALIZE pPager->memVfs = memJM = (fout&SQLITE_OPEN_MEMORY)!=0; -#endif readOnly = (fout&SQLITE_OPEN_READONLY)!=0; /* If the file was successfully opened for read/write access, @@ -4938,7 +4974,7 @@ ** disk and uses an in-memory rollback journal. ** ** This branch also runs for files marked as immutable. - */ + */ act_like_temp_file: tempFile = 1; pPager->eState = PAGER_READER; /* Pretend we already have a lock */ @@ -4947,7 +4983,7 @@ readOnly = (vfsFlags&SQLITE_OPEN_READONLY); } - /* The following call to PagerSetPagesize() serves to set the value of + /* The following call to PagerSetPagesize() serves to set the value of ** Pager.pageSize and to allocate the Pager.pTmpSpace buffer. */ if( rc==SQLITE_OK ){ @@ -4987,10 +5023,10 @@ /* pPager->state = PAGER_UNLOCK; */ /* pPager->errMask = 0; */ pPager->tempFile = (u8)tempFile; - assert( tempFile==PAGER_LOCKINGMODE_NORMAL + assert( tempFile==PAGER_LOCKINGMODE_NORMAL || tempFile==PAGER_LOCKINGMODE_EXCLUSIVE ); assert( PAGER_LOCKINGMODE_EXCLUSIVE==1 ); - pPager->exclusiveMode = (u8)tempFile; + pPager->exclusiveMode = (u8)tempFile; pPager->changeCountDone = pPager->tempFile; pPager->memDb = (u8)memDb; pPager->readOnly = (u8)readOnly; @@ -5021,7 +5057,7 @@ /* ** Return the sqlite3_file for the main database given the name -** of the corresonding WAL or Journal name as passed into +** of the corresponding WAL or Journal name as passed into ** xOpen. */ sqlite3_file *sqlite3_database_file_object(const char *zName){ @@ -5037,7 +5073,7 @@ /* ** This function is called after transitioning from PAGER_UNLOCK to ** PAGER_SHARED state. It tests if there is a hot journal present in -** the file-system for the given pager. A hot journal is one that +** the file-system for the given pager. A hot journal is one that ** needs to be played back. According to this function, a hot-journal ** file exists if the following criteria are met: ** @@ -5056,10 +5092,10 @@ ** at the end of the file. If there is, and that super-journal file ** does not exist, then the journal file is not really hot. In this ** case this routine will return a false-positive. The pager_playback() -** routine will discover that the journal file is not really hot and -** will not roll it back. +** routine will discover that the journal file is not really hot and +** will not roll it back. ** -** If a hot-journal file is found to exist, *pExists is set to 1 and +** If a hot-journal file is found to exist, *pExists is set to 1 and ** SQLITE_OK returned. If no hot-journal file is present, *pExists is ** set to 0 and SQLITE_OK returned. If an IO error occurs while trying ** to determine whether or not a hot-journal file exists, the IO error @@ -5087,7 +5123,7 @@ int locked = 0; /* True if some process holds a RESERVED lock */ /* Race condition here: Another process might have been holding the - ** the RESERVED lock and have a journal open at the sqlite3OsAccess() + ** the RESERVED lock and have a journal open at the sqlite3OsAccess() ** call above, but then delete the journal and drop the lock before ** we get to the following sqlite3OsCheckReservedLock() call. If that ** is the case, this routine might think there is a hot journal when @@ -5120,7 +5156,7 @@ /* The journal file exists and no other connection has a reserved ** or greater lock on the database file. Now check that there is ** at least one non-zero bytes at the start of the journal file. - ** If there is, then we consider this journal to be hot. If not, + ** If there is, then we consider this journal to be hot. If not, ** it can be ignored. */ if( !jrnlOpen ){ @@ -5170,7 +5206,7 @@ ** on the database file), then an attempt is made to obtain a ** SHARED lock on the database file. Immediately after obtaining ** the SHARED lock, the file-system is checked for a hot-journal, -** which is played back if present. Following any hot-journal +** which is played back if present. Following any hot-journal ** rollback, the contents of the cache are validated by checking ** the 'change-counter' field of the database file header and ** discarded if they are found to be invalid. @@ -5181,8 +5217,8 @@ ** the contents of the page cache and rolling back any open journal ** file. ** -** If everything is successful, SQLITE_OK is returned. If an IO error -** occurs while locking the database, checking for a hot-journal file or +** If everything is successful, SQLITE_OK is returned. If an IO error +** occurs while locking the database, checking for a hot-journal file or ** rolling back a journal file, the IO error code is returned. */ int sqlite3PagerSharedLock(Pager *pPager){ @@ -5190,7 +5226,7 @@ /* This routine is only called from b-tree and only when there are no ** outstanding pages. This implies that the pager state should either - ** be OPEN or READER. READER is only possible if the pager is or was in + ** be OPEN or READER. READER is only possible if the pager is or was in ** exclusive access mode. */ assert( sqlite3PcacheRefCount(pPager->pPCache)==0 ); assert( assert_pager_state(pPager) ); @@ -5228,12 +5264,12 @@ ** important that a RESERVED lock is not obtained on the way to the ** EXCLUSIVE lock. If it were, another process might open the ** database file, detect the RESERVED lock, and conclude that the - ** database is safe to read while this process is still rolling the + ** database is safe to read while this process is still rolling the ** hot-journal back. - ** + ** ** Because the intermediate RESERVED lock is not requested, any - ** other process attempting to access the database file will get to - ** this point in the code and fail to obtain its own EXCLUSIVE lock + ** other process attempting to access the database file will get to + ** this point in the code and fail to obtain its own EXCLUSIVE lock ** on the database file. ** ** Unless the pager is in locking_mode=exclusive mode, the lock is @@ -5243,17 +5279,17 @@ if( rc!=SQLITE_OK ){ goto failed; } - - /* If it is not already open and the file exists on disk, open the - ** journal for read/write access. Write access is required because - ** in exclusive-access mode the file descriptor will be kept open - ** and possibly used for a transaction later on. Also, write-access - ** is usually required to finalize the journal in journal_mode=persist + + /* If it is not already open and the file exists on disk, open the + ** journal for read/write access. Write access is required because + ** in exclusive-access mode the file descriptor will be kept open + ** and possibly used for a transaction later on. Also, write-access + ** is usually required to finalize the journal in journal_mode=persist ** mode (and also for journal_mode=truncate on some systems). ** - ** If the journal does not exist, it usually means that some - ** other connection managed to get in and roll it back before - ** this connection obtained the exclusive lock above. Or, it + ** If the journal does not exist, it usually means that some + ** other connection managed to get in and roll it back before + ** this connection obtained the exclusive lock above. Or, it ** may mean that the pager was in the error-state when this ** function was called and the journal file does not exist. */ @@ -5274,7 +5310,7 @@ } } } - + /* Playback and delete the journal. Drop the database write ** lock and reacquire the read lock. Purge the cache before ** playing back the hot-journal so that we don't end up with @@ -5299,8 +5335,8 @@ ** or roll back a hot-journal while holding an EXCLUSIVE lock. The ** pager_unlock() routine will be called before returning to unlock ** the file. If the unlock attempt fails, then Pager.eLock must be - ** set to UNKNOWN_LOCK (see the comment above the #define for - ** UNKNOWN_LOCK above for an explanation). + ** set to UNKNOWN_LOCK (see the comment above the #define for + ** UNKNOWN_LOCK above for an explanation). ** ** In order to get pager_unlock() to do this, set Pager.eState to ** PAGER_ERROR now. This is not actually counted as a transition @@ -5308,7 +5344,7 @@ ** since we know that the same call to pager_unlock() will very ** shortly transition the pager object to the OPEN state. Calling ** assert_pager_state() would fail now, as it should not be possible - ** to be in ERROR state when there are zero outstanding page + ** to be in ERROR state when there are zero outstanding page ** references. */ pager_error(pPager, rc); @@ -5333,8 +5369,8 @@ ** a 32-bit counter that is incremented with each change. The ** other bytes change randomly with each file change when ** a codec is in use. - ** - ** There is a vanishingly small chance that a change will not be + ** + ** There is a vanishingly small chance that a change will not be ** detected. The chance of an undetected change is so small that ** it can be neglected. */ @@ -5401,7 +5437,7 @@ ** Except, in locking_mode=EXCLUSIVE when there is nothing to in ** the rollback journal, the unlock is not performed and there is ** nothing to rollback, so this routine is a no-op. -*/ +*/ static void pagerUnlockIfUnused(Pager *pPager){ if( sqlite3PcacheRefCount(pPager->pPCache)==0 ){ assert( pPager->nMmapOut==0 ); /* because page1 is never memory mapped */ @@ -5411,7 +5447,7 @@ /* ** The page getter methods each try to acquire a reference to a -** page with page number pgno. If the requested reference is +** page with page number pgno. If the requested reference is ** successfully obtained, it is copied to *ppPage and SQLITE_OK returned. ** ** There are different implementations of the getter method depending @@ -5421,22 +5457,22 @@ ** getPageError() -- Used if the pager is in an error state ** getPageMmap() -- Used if memory-mapped I/O is enabled ** -** If the requested page is already in the cache, it is returned. +** If the requested page is already in the cache, it is returned. ** Otherwise, a new page object is allocated and populated with data ** read from the database file. In some cases, the pcache module may ** choose not to allocate a new page object and may reuse an existing ** object with no outstanding references. ** -** The extra data appended to a page is always initialized to zeros the -** first time a page is loaded into memory. If the page requested is +** The extra data appended to a page is always initialized to zeros the +** first time a page is loaded into memory. If the page requested is ** already in the cache when this function is called, then the extra ** data is left as it was when the page object was last used. ** -** If the database image is smaller than the requested page or if -** the flags parameter contains the PAGER_GET_NOCONTENT bit and the -** requested page is not already stored in the cache, then no -** actual disk read occurs. In this case the memory image of the -** page is initialized to all zeros. +** If the database image is smaller than the requested page or if +** the flags parameter contains the PAGER_GET_NOCONTENT bit and the +** requested page is not already stored in the cache, then no +** actual disk read occurs. In this case the memory image of the +** page is initialized to all zeros. ** ** If PAGER_GET_NOCONTENT is true, it means that we do not care about ** the contents of the page. This occurs in two scenarios: @@ -5507,7 +5543,7 @@ return SQLITE_OK; }else{ - /* The pager cache has created a new page. Its content needs to + /* The pager cache has created a new page. Its content needs to ** be initialized. But first some error checks: ** ** (*) obsolete. Was: maximum page number is 2^31 @@ -5532,9 +5568,9 @@ } if( noContent ){ /* Failure to set the bits in the InJournal bit-vectors is benign. - ** It merely means that we might do some extra work to journal a - ** page that does not need to be journaled. Nevertheless, be sure - ** to test the case where a malloc error occurs while trying to set + ** It merely means that we might do some extra work to journal a + ** page that does not need to be journaled. Nevertheless, be sure + ** to test the case where a malloc error occurs while trying to set ** a bit in a bit vector. */ sqlite3BeginBenignMalloc(); @@ -5584,7 +5620,7 @@ /* It is acceptable to use a read-only (mmap) page for any page except ** page 1 if there is no write-transaction open or the ACQUIRE_READONLY - ** flag was specified by the caller. And so long as the db is not a + ** flag was specified by the caller. And so long as the db is not a ** temporary or in-memory database. */ const int bMmapOk = (pgno>1 && (pPager->eState==PAGER_READER || (flags & PAGER_GET_READONLY)) @@ -5613,7 +5649,7 @@ } if( bMmapOk && iFrame==0 ){ void *pData = 0; - rc = sqlite3OsFetch(pPager->fd, + rc = sqlite3OsFetch(pPager->fd, (i64)(pgno-1) * pPager->pageSize, pPager->pageSize, &pData ); if( rc==SQLITE_OK && pData ){ @@ -5663,19 +5699,31 @@ DbPage **ppPage, /* Write a pointer to the page here */ int flags /* PAGER_GET_XXX flags */ ){ - /* printf("PAGE %u\n", pgno); fflush(stdout); */ +#if 0 /* Trace page fetch by setting to 1 */ + int rc; + printf("PAGE %u\n", pgno); + fflush(stdout); + rc = pPager->xGet(pPager, pgno, ppPage, flags); + if( rc ){ + printf("PAGE %u failed with 0x%02x\n", pgno, rc); + fflush(stdout); + } + return rc; +#else + /* Normal, high-speed version of sqlite3PagerGet() */ return pPager->xGet(pPager, pgno, ppPage, flags); +#endif } /* ** Acquire a page if it is already in the in-memory cache. Do ** not read the page from disk. Return a pointer to the page, -** or 0 if the page is not in cache. +** or 0 if the page is not in cache. ** ** See also sqlite3PagerGet(). The difference between this routine ** and sqlite3PagerGet() is that _get() will go to the disk and read ** in the page if the page is not already in cache. This routine -** returns NULL if the page is not in cache or if a disk I/O error +** returns NULL if the page is not in cache or if a disk I/O error ** has ever happened. */ DbPage *sqlite3PagerLookup(Pager *pPager, Pgno pgno){ @@ -5730,24 +5778,24 @@ /* ** This function is called at the start of every write transaction. -** There must already be a RESERVED or EXCLUSIVE lock on the database +** There must already be a RESERVED or EXCLUSIVE lock on the database ** file when this routine is called. ** ** Open the journal file for pager pPager and write a journal header ** to the start of it. If there are active savepoints, open the sub-journal -** as well. This function is only used when the journal file is being -** opened to write a rollback log for a transaction. It is not used +** as well. This function is only used when the journal file is being +** opened to write a rollback log for a transaction. It is not used ** when opening a hot journal file to roll it back. ** ** If the journal file is already open (as it may be in exclusive mode), ** then this function just writes a journal header to the start of the -** already open file. +** already open file. ** ** Whether or not the journal file is opened by this function, the ** Pager.pInJournal bitvec structure is allocated. ** -** Return SQLITE_OK if everything is successful. Otherwise, return -** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or +** Return SQLITE_OK if everything is successful. Otherwise, return +** SQLITE_NOMEM if the attempt to allocate Pager.pInJournal fails, or ** an IO error code if opening or writing the journal file fails. */ static int pager_open_journal(Pager *pPager){ @@ -5757,7 +5805,7 @@ assert( pPager->eState==PAGER_WRITER_LOCKED ); assert( assert_pager_state(pPager) ); assert( pPager->pInJournal==0 ); - + /* If already in the error state, this function is a no-op. But on ** the other hand, this routine is never called if we are already in ** an error state. */ @@ -5768,7 +5816,7 @@ if( pPager->pInJournal==0 ){ return SQLITE_NOMEM_BKPT; } - + /* Open the journal file if it is not already open. */ if( !isOpen(pPager->jfd) ){ if( pPager->journalMode==PAGER_JOURNALMODE_MEMORY ){ @@ -5785,7 +5833,7 @@ flags |= SQLITE_OPEN_MAIN_JOURNAL; nSpill = jrnlBufferSize(pPager); } - + /* Verify that the database still has the same name as it did when ** it was originally opened. */ rc = databaseIsUnmoved(pPager); @@ -5797,9 +5845,9 @@ } assert( rc!=SQLITE_OK || isOpen(pPager->jfd) ); } - - - /* Write the first journal header to the journal file and open + + + /* Write the first journal header to the journal file and open ** the sub-journal if necessary. */ if( rc==SQLITE_OK ){ @@ -5825,12 +5873,12 @@ } /* -** Begin a write-transaction on the specified pager object. If a +** Begin a write-transaction on the specified pager object. If a ** write-transaction has already been opened, this function is a no-op. ** ** If the exFlag argument is false, then acquire at least a RESERVED ** lock on the database file. If exFlag is true, then acquire at least -** an EXCLUSIVE lock. If such a lock is already held, no locking +** an EXCLUSIVE lock. If such a lock is already held, no locking ** functions need be called. ** ** If the subjInMemory argument is non-zero, then any sub-journal opened @@ -5838,7 +5886,7 @@ ** has no effect if the sub-journal is already opened (as it may be when ** running in exclusive mode) or if the transaction does not require a ** sub-journal. If the subjInMemory argument is zero, then any required -** sub-journal is implemented in-memory if pPager is an in-memory database, +** sub-journal is implemented in-memory if pPager is an in-memory database, ** or using a temporary file otherwise. */ int sqlite3PagerBegin(Pager *pPager, int exFlag, int subjInMemory){ @@ -5886,9 +5934,9 @@ ** ** WAL mode sets Pager.eState to PAGER_WRITER_LOCKED or CACHEMOD ** when it has an open transaction, but never to DBMOD or FINISHED. - ** This is because in those states the code to roll back savepoint - ** transactions may copy data from the sub-journal into the database - ** file as well as into the page cache. Which would be incorrect in + ** This is because in those states the code to roll back savepoint + ** transactions may copy data from the sub-journal into the database + ** file as well as into the page cache. Which would be incorrect in ** WAL mode. */ pPager->eState = PAGER_WRITER_LOCKED; @@ -5942,11 +5990,11 @@ rc = write32bits(pPager->jfd, iOff+pPager->pageSize+4, cksum); if( rc!=SQLITE_OK ) return rc; - IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, + IOTRACE(("JOUT %p %d %lld %d\n", pPager, pPg->pgno, pPager->journalOff, pPager->pageSize)); PAGER_INCR(sqlite3_pager_writej_count); PAGERTRACE(("JOURNAL %d page %d needSync=%d hash(%08x)\n", - PAGERID(pPager), pPg->pgno, + PAGERID(pPager), pPg->pgno, ((pPg->flags&PGHDR_NEED_SYNC)?1:0), pager_pagehash(pPg))); pPager->journalOff += 8 + pPager->pageSize; @@ -5961,9 +6009,9 @@ } /* -** Mark a single data page as writeable. The page is written into the +** Mark a single data page as writeable. The page is written into the ** main journal or sub-journal as required. If the page is written into -** one of the journals, the corresponding bit is set in the +** one of the journals, the corresponding bit is set in the ** Pager.pInJournal bitvec and the PagerSavepoint.pInSavepoint bitvecs ** of any open savepoints as appropriate. */ @@ -5971,7 +6019,7 @@ Pager *pPager = pPg->pPager; int rc = SQLITE_OK; - /* This routine is not called unless a write-transaction has already + /* This routine is not called unless a write-transaction has already ** been started. The journal file may or may not be open at this point. ** It is never called in the ERROR state. */ @@ -5988,7 +6036,7 @@ ** obtained the necessary locks to begin the write-transaction, but the ** rollback journal might not yet be open. Open it now if this is the case. ** - ** This is done before calling sqlite3PcacheMakeDirty() on the page. + ** This is done before calling sqlite3PcacheMakeDirty() on the page. ** Otherwise, if it were done after calling sqlite3PcacheMakeDirty(), then ** an error might occur and the pager would end up in WRITER_LOCKED state ** with pages marked as dirty in the cache. @@ -6033,7 +6081,7 @@ ** PGHDR_WRITEABLE bit that indicates that the page can be safely modified. */ pPg->flags |= PGHDR_WRITEABLE; - + /* If the statement journal is open and the page is not in it, ** then write the page into the statement journal. */ @@ -6117,7 +6165,7 @@ } } - /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages + /* If the PGHDR_NEED_SYNC flag is set for any of the nPage pages ** starting at pg1, then it needs to be set for all of them. Because ** writing to any of these nPage pages may damage the others, the ** journal file must contain sync()ed copies of all of them @@ -6140,9 +6188,9 @@ } /* -** Mark a data page as writeable. This routine must be called before -** making changes to a page. The caller must check the return value -** of this function and be careful not to change any page data unless +** Mark a data page as writeable. This routine must be called before +** making changes to a page. The caller must check the return value +** of this function and be careful not to change any page data unless ** this routine returns SQLITE_OK. ** ** The difference between this function and pager_write() is that this @@ -6193,13 +6241,13 @@ ** on the given page is unused. The pager marks the page as clean so ** that it does not get written to disk. ** -** Tests show that this optimization can quadruple the speed of large +** Tests show that this optimization can quadruple the speed of large ** DELETE operations. ** ** This optimization cannot be used with a temp-file, as the page may ** have been dirty at the start of the transaction. In that case, if -** memory pressure forces page pPg out of the cache, the data does need -** to be written out to disk so that it may be read back in if the +** memory pressure forces page pPg out of the cache, the data does need +** to be written out to disk so that it may be read back in if the ** current transaction is rolled back. */ void sqlite3PagerDontWrite(PgHdr *pPg){ @@ -6215,17 +6263,17 @@ } /* -** This routine is called to increment the value of the database file -** change-counter, stored as a 4-byte big-endian integer starting at +** This routine is called to increment the value of the database file +** change-counter, stored as a 4-byte big-endian integer starting at ** byte offset 24 of the pager file. The secondary change counter at ** 92 is also updated, as is the SQLite version number at offset 96. ** ** But this only happens if the pPager->changeCountDone flag is false. ** To avoid excess churning of page 1, the update only happens once. -** See also the pager_write_changecounter() routine that does an +** See also the pager_write_changecounter() routine that does an ** unconditional update of the change counters. ** -** If the isDirectMode flag is zero, then this is done by calling +** If the isDirectMode flag is zero, then this is done by calling ** sqlite3PagerWrite() on page 1, then modifying the contents of the ** page data. In this case the file will be updated when the current ** transaction is committed. @@ -6233,7 +6281,7 @@ ** The isDirectMode flag may only be non-zero if the library was compiled ** with the SQLITE_ENABLE_ATOMIC_WRITE macro defined. In this case, ** if isDirect is non-zero, then the database file is updated directly -** by writing an updated version of page 1 using a call to the +** by writing an updated version of page 1 using a call to the ** sqlite3OsWrite() function. */ static int pager_incr_changecounter(Pager *pPager, int isDirectMode){ @@ -6272,7 +6320,7 @@ assert( pPgHdr==0 || rc==SQLITE_OK ); /* If page one was fetched successfully, and this function is not - ** operating in direct-mode, make page 1 writable. When not in + ** operating in direct-mode, make page 1 writable. When not in ** direct mode, page 1 is always held in cache and hence the PagerGet() ** above is always successful - hence the ALWAYS on rc==SQLITE_OK. */ @@ -6333,22 +6381,22 @@ /* ** This function may only be called while a write-transaction is active in -** rollback. If the connection is in WAL mode, this call is a no-op. -** Otherwise, if the connection does not already have an EXCLUSIVE lock on +** rollback. If the connection is in WAL mode, this call is a no-op. +** Otherwise, if the connection does not already have an EXCLUSIVE lock on ** the database file, an attempt is made to obtain one. ** ** If the EXCLUSIVE lock is already held or the attempt to obtain it is ** successful, or the connection is in WAL mode, SQLITE_OK is returned. -** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is +** Otherwise, either SQLITE_BUSY or an SQLITE_IOERR_XXX error code is ** returned. */ int sqlite3PagerExclusiveLock(Pager *pPager){ int rc = pPager->errCode; assert( assert_pager_state(pPager) ); if( rc==SQLITE_OK ){ - assert( pPager->eState==PAGER_WRITER_CACHEMOD - || pPager->eState==PAGER_WRITER_DBMOD - || pPager->eState==PAGER_WRITER_LOCKED + assert( pPager->eState==PAGER_WRITER_CACHEMOD + || pPager->eState==PAGER_WRITER_DBMOD + || pPager->eState==PAGER_WRITER_LOCKED ); assert( assert_pager_state(pPager) ); if( 0==pagerUseWal(pPager) ){ @@ -6361,19 +6409,19 @@ /* ** Sync the database file for the pager pPager. zSuper points to the name ** of a super-journal file that should be written into the individual -** journal file. zSuper may be NULL, which is interpreted as no +** journal file. zSuper may be NULL, which is interpreted as no ** super-journal (a single database transaction). ** ** This routine ensures that: ** ** * The database file change-counter is updated, ** * the journal is synced (unless the atomic-write optimization is used), -** * all dirty pages are written to the database file, +** * all dirty pages are written to the database file, ** * the database file is truncated (if required), and -** * the database file synced. +** * the database file synced. ** -** The only thing that remains to commit the transaction is to finalize -** (delete, truncate or zero the first part of) the journal file (or +** The only thing that remains to commit the transaction is to finalize +** (delete, truncate or zero the first part of) the journal file (or ** delete the super-journal file if specified). ** ** Note that if zSuper==NULL, this does not overwrite a previous value @@ -6404,7 +6452,7 @@ /* Provide the ability to easily simulate an I/O error during testing */ if( sqlite3FaultSim(400) ) return SQLITE_IOERR; - PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", + PAGERTRACE(("DATABASE SYNC: File=%s zSuper=%s nSize=%d\n", pPager->zFilename, zSuper, pPager->dbSize)); /* If no database changes have been made, return early. */ @@ -6455,11 +6503,11 @@ #ifdef SQLITE_ENABLE_ATOMIC_WRITE /* The following block updates the change-counter. Exactly how it ** does this depends on whether or not the atomic-update optimization - ** was enabled at compile time, and if this transaction meets the - ** runtime criteria to use the operation: + ** was enabled at compile time, and if this transaction meets the + ** runtime criteria to use the operation: ** ** * The file-system supports the atomic-write property for - ** blocks of size page-size, and + ** blocks of size page-size, and ** * This commit is not part of a multi-file transaction, and ** * Exactly one page has been modified and store in the journal file. ** @@ -6469,7 +6517,7 @@ ** is not applicable to this transaction, call sqlite3JournalCreate() ** to make sure the journal file has actually been created, then call ** pager_incr_changecounter() to update the change-counter in indirect - ** mode. + ** mode. ** ** Otherwise, if the optimization is both enabled and applicable, ** then call pager_incr_changecounter() to update the change-counter @@ -6478,19 +6526,19 @@ */ if( bBatch==0 ){ PgHdr *pPg; - assert( isOpen(pPager->jfd) - || pPager->journalMode==PAGER_JOURNALMODE_OFF - || pPager->journalMode==PAGER_JOURNALMODE_WAL + assert( isOpen(pPager->jfd) + || pPager->journalMode==PAGER_JOURNALMODE_OFF + || pPager->journalMode==PAGER_JOURNALMODE_WAL ); - if( !zSuper && isOpen(pPager->jfd) - && pPager->journalOff==jrnlBufferSize(pPager) + if( !zSuper && isOpen(pPager->jfd) + && pPager->journalOff==jrnlBufferSize(pPager) && pPager->dbSize>=pPager->dbOrigSize && (!(pPg = sqlite3PcacheDirtyList(pPager->pPCache)) || 0==pPg->pDirty) ){ - /* Update the db file change counter via the direct-write method. The - ** following call will modify the in-memory representation of page 1 - ** to include the updated change counter and then write page 1 - ** directly to the database file. Because of the atomic-write + /* Update the db file change counter via the direct-write method. The + ** following call will modify the in-memory representation of page 1 + ** to include the updated change counter and then write page 1 + ** directly to the database file. Because of the atomic-write ** property of the host file-system, this is safe. */ rc = pager_incr_changecounter(pPager, 1); @@ -6512,24 +6560,24 @@ rc = pager_incr_changecounter(pPager, 0); #endif /* !SQLITE_ENABLE_ATOMIC_WRITE */ if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - + /* Write the super-journal name into the journal file. If a - ** super-journal file name has already been written to the journal file, + ** super-journal file name has already been written to the journal file, ** or if zSuper is NULL (no super-journal), then this call is a no-op. */ rc = writeSuperJournal(pPager, zSuper); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; - + /* Sync the journal file and write all dirty pages to the database. - ** If the atomic-update optimization is being used, this sync will not + ** If the atomic-update optimization is being used, this sync will not ** create the journal file or perform any real IO. ** ** Because the change-counter page was just modified, unless the ** atomic-update optimization is used it is almost certain that the ** journal requires a sync here. However, in locking_mode=exclusive - ** on a system under memory pressure it is just possible that this is + ** on a system under memory pressure it is just possible that this is ** not the case. In this case it is likely enough that the redundant - ** xSync() call will be changed to a no-op by the OS anyhow. + ** xSync() call will be changed to a no-op by the OS anyhow. */ rc = syncJournal(pPager, 0); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; @@ -6540,6 +6588,13 @@ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_BEGIN_ATOMIC_WRITE, 0); if( rc==SQLITE_OK ){ rc = pager_write_pagelist(pPager, pList); + if( rc==SQLITE_OK && pPager->dbSize>pPager->dbFileSize ){ + char *pTmp = pPager->pTmpSpace; + int szPage = (int)pPager->pageSize; + memset(pTmp, 0, szPage); + rc = sqlite3OsWrite(pPager->fd, pTmp, szPage, + ((i64)pPager->dbSize*pPager->pageSize)-szPage); + } if( rc==SQLITE_OK ){ rc = sqlite3OsFileControl(fd, SQLITE_FCNTL_COMMIT_ATOMIC_WRITE, 0); } @@ -6570,7 +6625,7 @@ } sqlite3PcacheCleanAll(pPager->pPCache); - /* If the file on disk is smaller than the database image, use + /* If the file on disk is smaller than the database image, use ** pager_truncate to grow the file here. This can happen if the database ** image was extended as part of the current transaction and then the ** last page in the db image moved to the free-list. In this case the @@ -6582,7 +6637,7 @@ rc = pager_truncate(pPager, nNew); if( rc!=SQLITE_OK ) goto commit_phase_one_exit; } - + /* Finally, sync the database file. */ if( !noSync ){ rc = sqlite3PagerSync(pPager, zSuper); @@ -6602,12 +6657,12 @@ /* ** When this function is called, the database file has been completely ** updated to reflect the changes made by the current transaction and -** synced to disk. The journal file still exists in the file-system +** synced to disk. The journal file still exists in the file-system ** though, and if a failure occurs at this point it will eventually ** be used as a hot-journal and the current transaction rolled back. ** -** This function finalizes the journal file, either by deleting, -** truncating or partially zeroing it, so that it cannot be used +** This function finalizes the journal file, either by deleting, +** truncating or partially zeroing it, so that it cannot be used ** for hot-journal rollback. Once this is done the transaction is ** irrevocably committed. ** @@ -6633,15 +6688,15 @@ ** this transaction, the pager is running in exclusive-mode and is ** using persistent journals, then this function is a no-op. ** - ** The start of the journal file currently contains a single journal + ** The start of the journal file currently contains a single journal ** header with the nRec field set to 0. If such a journal is used as ** a hot-journal during hot-journal rollback, 0 changes will be made - ** to the database file. So there is no need to zero the journal + ** to the database file. So there is no need to zero the journal ** header. Since the pager is in exclusive mode, there is no need ** to drop any locks either. */ - if( pPager->eState==PAGER_WRITER_LOCKED - && pPager->exclusiveMode + if( pPager->eState==PAGER_WRITER_LOCKED + && pPager->exclusiveMode && pPager->journalMode==PAGER_JOURNALMODE_PERSIST ){ assert( pPager->journalOff==JOURNAL_HDR_SZ(pPager) || !pPager->journalOff ); @@ -6655,7 +6710,7 @@ } /* -** If a write transaction is open, then all changes made within the +** If a write transaction is open, then all changes made within the ** transaction are reverted and the current write-transaction is closed. ** The pager falls back to PAGER_READER state if successful, or PAGER_ERROR ** state if an error occurs. @@ -6665,14 +6720,14 @@ ** ** Otherwise, in rollback mode, this function performs two functions: ** -** 1) It rolls back the journal file, restoring all database file and +** 1) It rolls back the journal file, restoring all database file and ** in-memory cache pages to the state they were in when the transaction ** was opened, and ** ** 2) It finalizes the journal file, so that it is not used for hot ** rollback at any point in the future. ** -** Finalization of the journal file (task 2) is only performed if the +** Finalization of the journal file (task 2) is only performed if the ** rollback is successful. ** ** In WAL mode, all cache-entries containing data modified within the @@ -6685,7 +6740,7 @@ PAGERTRACE(("ROLLBACK %d\n", PAGERID(pPager))); /* PagerRollback() is a no-op if called in READER or OPEN state. If - ** the pager is already in the ERROR state, the rollback is not + ** the pager is already in the ERROR state, the rollback is not ** attempted here. Instead, the error code is returned to the caller. */ assert( assert_pager_state(pPager) ); @@ -6701,7 +6756,7 @@ int eState = pPager->eState; rc = pager_end_transaction(pPager, 0, 0); if( !MEMDB && eState>PAGER_WRITER_LOCKED ){ - /* This can happen using journal_mode=off. Move the pager to the error + /* This can happen using journal_mode=off. Move the pager to the error ** state to indicate that the contents of the cache may not be trusted. ** Any active readers will get SQLITE_ABORT. */ @@ -6716,7 +6771,7 @@ assert( pPager->eState==PAGER_READER || rc!=SQLITE_OK ); assert( rc==SQLITE_OK || rc==SQLITE_FULL || rc==SQLITE_CORRUPT - || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR + || rc==SQLITE_NOMEM || (rc&0xFF)==SQLITE_IOERR || rc==SQLITE_CANTOPEN ); @@ -6790,8 +6845,8 @@ ** it was added later. ** ** Before returning, *pnVal is incremented by the -** current cache hit or miss count, according to the value of eStat. If the -** reset parameter is non-zero, the cache hit or miss count is zeroed before +** current cache hit or miss count, according to the value of eStat. If the +** reset parameter is non-zero, the cache hit or miss count is zeroed before ** returning. */ void sqlite3PagerCacheStat(Pager *pPager, int eStat, int reset, int *pnVal){ @@ -6827,7 +6882,7 @@ ** to make up the difference. If the number of savepoints is already ** equal to nSavepoint, then this function is a no-op. ** -** If a memory allocation fails, SQLITE_NOMEM is returned. If an error +** If a memory allocation fails, SQLITE_NOMEM is returned. If an error ** occurs while opening the sub-journal file, then an IO error code is ** returned. Otherwise, SQLITE_OK. */ @@ -6842,7 +6897,7 @@ assert( nSavepoint>nCurrent && pPager->useJournal ); /* Grow the Pager.aSavepoint array using realloc(). Return SQLITE_NOMEM - ** if the allocation fails. Otherwise, zero the new portion in case a + ** if the allocation fails. Otherwise, zero the new portion in case a ** malloc failure occurs while populating it in the for(...) loop below. */ aNew = (PagerSavepoint *)sqlite3Realloc( @@ -6891,7 +6946,7 @@ /* ** This function is called to rollback or release (commit) a savepoint. -** The savepoint to release or rollback need not be the most recently +** The savepoint to release or rollback need not be the most recently ** created savepoint. ** ** Parameter op is always either SAVEPOINT_ROLLBACK or SAVEPOINT_RELEASE. @@ -6899,29 +6954,29 @@ ** index iSavepoint. If it is SAVEPOINT_ROLLBACK, then rollback all changes ** that have occurred since the specified savepoint was created. ** -** The savepoint to rollback or release is identified by parameter +** The savepoint to rollback or release is identified by parameter ** iSavepoint. A value of 0 means to operate on the outermost savepoint ** (the first created). A value of (Pager.nSavepoint-1) means operate ** on the most recently created savepoint. If iSavepoint is greater than ** (Pager.nSavepoint-1), then this function is a no-op. ** ** If a negative value is passed to this function, then the current -** transaction is rolled back. This is different to calling +** transaction is rolled back. This is different to calling ** sqlite3PagerRollback() because this function does not terminate -** the transaction or unlock the database, it just restores the -** contents of the database to its original state. +** the transaction or unlock the database, it just restores the +** contents of the database to its original state. ** -** In any case, all savepoints with an index greater than iSavepoint +** In any case, all savepoints with an index greater than iSavepoint ** are destroyed. If this is a release operation (op==SAVEPOINT_RELEASE), ** then savepoint iSavepoint is also destroyed. ** ** This function may return SQLITE_NOMEM if a memory allocation fails, -** or an IO error code if an IO error occurs while rolling back a +** or an IO error code if an IO error occurs while rolling back a ** savepoint. If no errors occur, SQLITE_OK is returned. -*/ +*/ int sqlite3PagerSavepoint(Pager *pPager, int op, int iSavepoint){ int rc = pPager->errCode; - + #ifdef SQLITE_ENABLE_ZIPVFS if( op==SAVEPOINT_RELEASE ) rc = SQLITE_OK; #endif @@ -6934,7 +6989,7 @@ int nNew; /* Number of remaining savepoints after this op. */ /* Figure out how many savepoints will still be active after this - ** operation. Store this value in nNew. Then free resources associated + ** operation. Store this value in nNew. Then free resources associated ** with any savepoints that are destroyed by this operation. */ nNew = iSavepoint + (( op==SAVEPOINT_RELEASE ) ? 0 : 1); @@ -6967,14 +7022,14 @@ rc = pagerPlaybackSavepoint(pPager, pSavepoint); assert(rc!=SQLITE_DONE); } - + #ifdef SQLITE_ENABLE_ZIPVFS - /* If the cache has been modified but the savepoint cannot be rolled + /* If the cache has been modified but the savepoint cannot be rolled ** back journal_mode=off, put the pager in the error state. This way, ** if the VFS used by this pager includes ZipVFS, the entire transaction ** can be rolled back at the ZipVFS level. */ - else if( - pPager->journalMode==PAGER_JOURNALMODE_OFF + else if( + pPager->journalMode==PAGER_JOURNALMODE_OFF && pPager->eState>=PAGER_WRITER_CACHEMOD ){ pPager->errCode = SQLITE_ABORT; @@ -7063,8 +7118,8 @@ ** transaction is active). ** ** If the fourth argument, isCommit, is non-zero, then this page is being -** moved as part of a database reorganization just before the transaction -** is being committed. In this case, it is guaranteed that the database page +** moved as part of a database reorganization just before the transaction +** is being committed. In this case, it is guaranteed that the database page ** pPg refers to will not be written to again within this transaction. ** ** This function may return SQLITE_NOMEM or an IO error code if an error @@ -7092,7 +7147,7 @@ } /* If the page being moved is dirty and has not been saved by the latest - ** savepoint, then save the current contents of the page into the + ** savepoint, then save the current contents of the page into the ** sub-journal now. This is required to handle the following scenario: ** ** BEGIN; @@ -7115,7 +7170,7 @@ return rc; } - PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", + PAGERTRACE(("MOVE %d page %d (needSync=%d) moves to %d\n", PAGERID(pPager), pPg->pgno, (pPg->flags&PGHDR_NEED_SYNC)?1:0, pgno)); IOTRACE(("MOVE %p %d %d\n", pPager, pPg->pgno, pgno)) @@ -7123,7 +7178,7 @@ ** be written to, store pPg->pgno in local variable needSyncPgno. ** ** If the isCommit flag is set, there is no need to remember that - ** the journal needs to be sync()ed before database page pPg->pgno + ** the journal needs to be sync()ed before database page pPg->pgno ** can be written to. The caller has already promised not to write to it. */ if( (pPg->flags&PGHDR_NEED_SYNC) && !isCommit ){ @@ -7134,8 +7189,8 @@ } /* If the cache contains a page with page-number pgno, remove it - ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for - ** page pgno before the 'move' operation, it needs to be retained + ** from its hash chain. Also, if the PGHDR_NEED_SYNC flag was set for + ** page pgno before the 'move' operation, it needs to be retained ** for the page moved there. */ pPg->flags &= ~PGHDR_NEED_SYNC; @@ -7170,9 +7225,9 @@ } if( needSyncPgno ){ - /* If needSyncPgno is non-zero, then the journal file needs to be + /* If needSyncPgno is non-zero, then the journal file needs to be ** sync()ed before any data is written to database file page needSyncPgno. - ** Currently, no such page exists in the page-cache and the + ** Currently, no such page exists in the page-cache and the ** "is journaled" bitvec flag has been set. This needs to be remedied by ** loading the page into the pager-cache and setting the PGHDR_NEED_SYNC ** flag. @@ -7203,9 +7258,9 @@ #endif /* -** The page handle passed as the first argument refers to a dirty page -** with a page number other than iNew. This function changes the page's -** page number to iNew and sets the value of the PgHdr.flags field to +** The page handle passed as the first argument refers to a dirty page +** with a page number other than iNew. This function changes the page's +** page number to iNew and sets the value of the PgHdr.flags field to ** the value passed as the third parameter. */ void sqlite3PagerRekey(DbPage *pPg, Pgno iNew, u16 flags){ @@ -7223,7 +7278,7 @@ } /* -** Return a pointer to the Pager.nExtra bytes of "extra" space +** Return a pointer to the Pager.nExtra bytes of "extra" space ** allocated along with the specified page. */ void *sqlite3PagerGetExtra(DbPage *pPg){ @@ -7232,7 +7287,7 @@ /* ** Get/set the locking-mode for this pager. Parameter eMode must be one -** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or +** of PAGER_LOCKINGMODE_QUERY, PAGER_LOCKINGMODE_NORMAL or ** PAGER_LOCKINGMODE_EXCLUSIVE. If the parameter is not _QUERY, then ** the locking-mode is set to the value specified. ** @@ -7306,7 +7361,7 @@ assert( pPager->eState!=PAGER_ERROR ); pPager->journalMode = (u8)eMode; - /* When transistioning from TRUNCATE or PERSIST to any other journal + /* 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. */ @@ -7351,7 +7406,7 @@ } assert( state==pPager->eState ); } - }else if( eMode==PAGER_JOURNALMODE_OFF ){ + }else if( eMode==PAGER_JOURNALMODE_OFF || eMode==PAGER_JOURNALMODE_MEMORY ){ sqlite3OsClose(pPager->jfd); } } @@ -7479,7 +7534,7 @@ eOrigLock = pPager->eLock; rc = pagerLockDb(pPager, EXCLUSIVE_LOCK); if( rc!=SQLITE_OK ){ - /* If the attempt to grab the exclusive lock failed, release the + /* If the attempt to grab the exclusive lock failed, release the ** pending lock that may have been obtained instead. */ pagerUnlockDb(pPager, eOrigLock); } @@ -7488,7 +7543,7 @@ } /* -** Call sqlite3WalOpen() to open the WAL handle. If the pager is in +** Call sqlite3WalOpen() to open the WAL handle. If the pager is in ** exclusive-locking mode when this function is called, take an EXCLUSIVE ** lock on the database file and use heap-memory to store the wal-index ** in. Otherwise, use the normal shared-memory. @@ -7499,8 +7554,8 @@ assert( pPager->pWal==0 && pPager->tempFile==0 ); assert( pPager->eLock==SHARED_LOCK || pPager->eLock==EXCLUSIVE_LOCK ); - /* If the pager is already in exclusive-mode, the WAL module will use - ** heap-memory for the wal-index instead of the VFS shared-memory + /* If the pager is already in exclusive-mode, the WAL module will use + ** heap-memory for the wal-index instead of the VFS shared-memory ** implementation. Take the exclusive lock now, before opening the WAL ** file, to make sure this is safe. */ @@ -7508,7 +7563,7 @@ rc = pagerExclusiveLock(pPager); } - /* Open the connection to the log file. If this operation fails, + /* Open the connection to the log file. If this operation fails, ** (e.g. due to malloc() failure), return an error code. */ if( rc==SQLITE_OK ){ @@ -7530,7 +7585,7 @@ ** If the pager passed as the first argument is open on a real database ** file (not a temp file or an in-memory database), and the WAL file ** is not already open, make an attempt to open it now. If successful, -** return SQLITE_OK. If an error occurs or the VFS used by the pager does +** return SQLITE_OK. If an error occurs or the VFS used by the pager does ** not support the xShmXXX() methods, return an error code. *pbOpen is ** not modified in either case. ** @@ -7572,7 +7627,7 @@ ** This function is called to close the connection to the log file prior ** to switching from WAL to rollback mode. ** -** Before closing the log file, this function attempts to take an +** Before closing the log file, this function attempts to take an ** EXCLUSIVE lock on the database file. If this cannot be obtained, an ** error (SQLITE_BUSY) is returned and the log connection is not closed. ** If successful, the EXCLUSIVE lock is not released before returning. @@ -7598,7 +7653,7 @@ rc = pagerOpenWal(pPager); } } - + /* Checkpoint and close the log. Because an EXCLUSIVE lock is held on ** the database file, the log and log-summary files will be deleted. */ @@ -7618,7 +7673,7 @@ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT /* ** If pager pPager is a wal-mode database not in exclusive locking mode, -** invoke the sqlite3WalWriteLock() function on the associated Wal object +** invoke the sqlite3WalWriteLock() function on the associated Wal object ** with the same db and bLock parameters as were passed to this function. ** Return an SQLite error code if an error occurs, or SQLITE_OK otherwise. */ @@ -7631,7 +7686,7 @@ } /* -** Set the database handle used by the wal layer to determine if +** Set the database handle used by the wal layer to determine if ** blocking locks are required. */ void sqlite3PagerWalDb(Pager *pPager, sqlite3 *db){ @@ -7656,11 +7711,11 @@ /* ** If this is a WAL database, store a pointer to pSnapshot. Next time a -** read transaction is opened, attempt to read from the snapshot it +** read transaction is opened, attempt to read from the snapshot it ** identifies. If this is not a WAL database, return an error. */ int sqlite3PagerSnapshotOpen( - Pager *pPager, + Pager *pPager, sqlite3_snapshot *pSnapshot ){ int rc = SQLITE_OK; @@ -7673,7 +7728,7 @@ } /* -** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this +** If this is a WAL database, call sqlite3WalSnapshotRecover(). If this ** is not a WAL database, return an error. */ int sqlite3PagerSnapshotRecover(Pager *pPager){ @@ -7690,7 +7745,7 @@ ** The caller currently has a read transaction open on the database. ** If this is not a WAL database, SQLITE_ERROR is returned. Otherwise, ** this function takes a SHARED lock on the CHECKPOINTER slot and then -** checks if the snapshot passed as the second argument is still +** checks if the snapshot passed as the second argument is still ** available. If so, SQLITE_OK is returned. ** ** If the snapshot is not available, SQLITE_ERROR is returned. Or, if @@ -7734,4 +7789,10 @@ } #endif +#ifdef SQLITE_USE_SEH +int sqlite3PagerWalSystemErrno(Pager *pPager){ + return sqlite3WalSystemErrno(pPager->pWal); +} +#endif + #endif /* SQLITE_OMIT_DISKIO */ diff -Nru sqlite3-3.42.0/src/pager.h sqlite3-3.44.0-0/src/pager.h --- sqlite3-3.42.0/src/pager.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/pager.h 2023-11-04 14:23:58.000000000 +0000 @@ -240,4 +240,8 @@ # define enable_simulated_io_errors() #endif +#if defined(SQLITE_USE_SEH) && !defined(SQLITE_OMIT_WAL) +int sqlite3PagerWalSystemErrno(Pager*); +#endif + #endif /* SQLITE_PAGER_H */ diff -Nru sqlite3-3.42.0/src/parse.y sqlite3-3.44.0-0/src/parse.y --- sqlite3-3.42.0/src/parse.y 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/parse.y 2023-11-04 14:23:58.000000000 +0000 @@ -15,7 +15,7 @@ ** The canonical source code to this file ("parse.y") is a Lemon grammar ** file that specifies the input grammar and actions to take while parsing. ** That input file is processed by Lemon to generate a C-language -** implementation of a parser for the given grammer. You might be reading +** implementation of a parser for the given grammar. You might be reading ** this comment as part of the translated C-code. Edits should be made ** to the original parse.y sources. */ @@ -148,8 +148,8 @@ ecmd ::= cmdx SEMI. %ifndef SQLITE_OMIT_EXPLAIN ecmd ::= explain cmdx SEMI. {NEVER-REDUCE} -explain ::= EXPLAIN. { pParse->explain = 1; } -explain ::= EXPLAIN QUERY PLAN. { pParse->explain = 2; } +explain ::= EXPLAIN. { if( pParse->pReprepare==0 ) pParse->explain = 1; } +explain ::= EXPLAIN QUERY PLAN. { if( pParse->pReprepare==0 ) pParse->explain = 2; } %endif SQLITE_OMIT_EXPLAIN cmdx ::= cmd. { sqlite3FinishCoding(pParse); } @@ -267,7 +267,7 @@ %wildcard ANY. // Define operator precedence early so that this is the first occurrence -// of the operator tokens in the grammer. Keeping the operators together +// 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. // @@ -554,12 +554,11 @@ select(A) ::= WITH RECURSIVE wqlist(W) selectnowith(X). {A = attachWithToSelect(pParse,X,W);} %endif /* SQLITE_OMIT_CTE */ -select(A) ::= selectnowith(X). { - Select *p = X; +select(A) ::= selectnowith(A). { + Select *p = A; if( p ){ parserDoubleLinkSelect(pParse, p); } - A = p; /*A-overwrites-X*/ } selectnowith(A) ::= oneselect(A). @@ -655,14 +654,17 @@ if( Y.n>0 ) sqlite3ExprListSetName(pParse, A, &Y, 1); sqlite3ExprListSetSpan(pParse,A,B,Z); } -selcollist(A) ::= sclp(A) scanpt STAR. { +selcollist(A) ::= sclp(A) scanpt STAR(X). { Expr *p = sqlite3Expr(pParse->db, TK_ASTERISK, 0); + sqlite3ExprSetErrorOffset(p, (int)(X.z - pParse->zTail)); A = sqlite3ExprListAppend(pParse, A, p); } -selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR. { - Expr *pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); - Expr *pLeft = tokenExpr(pParse, TK_ID, X); - Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); +selcollist(A) ::= sclp(A) scanpt nm(X) DOT STAR(Y). { + Expr *pRight, *pLeft, *pDot; + pRight = sqlite3PExpr(pParse, TK_ASTERISK, 0, 0); + sqlite3ExprSetErrorOffset(pRight, (int)(Y.z - pParse->zTail)); + pLeft = tokenExpr(pParse, TK_ID, X); + pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight); A = sqlite3ExprListAppend(pParse,A, pDot); } @@ -1142,6 +1144,10 @@ expr(A) ::= idj(X) LP distinct(D) exprlist(Y) RP. { A = sqlite3ExprFunction(pParse, Y, &X, D); } +expr(A) ::= idj(X) LP distinct(D) exprlist(Y) ORDER BY sortlist(O) RP. { + A = sqlite3ExprFunction(pParse, Y, &X, D); + sqlite3ExprAddFunctionOrderBy(pParse, A, O); +} expr(A) ::= idj(X) LP STAR RP. { A = sqlite3ExprFunction(pParse, 0, &X, 0); } @@ -1151,6 +1157,11 @@ A = sqlite3ExprFunction(pParse, Y, &X, D); sqlite3WindowAttach(pParse, A, Z); } +expr(A) ::= idj(X) LP distinct(D) exprlist(Y) ORDER BY sortlist(O) RP filter_over(Z). { + A = sqlite3ExprFunction(pParse, Y, &X, D); + sqlite3WindowAttach(pParse, A, Z); + sqlite3ExprAddFunctionOrderBy(pParse, A, O); +} expr(A) ::= idj(X) LP STAR RP filter_over(Z). { A = sqlite3ExprFunction(pParse, 0, &X, 0); sqlite3WindowAttach(pParse, A, Z); @@ -1758,7 +1769,7 @@ %ifndef SQLITE_OMIT_WINDOWFUNC %type windowdefn_list {Window*} %destructor windowdefn_list {sqlite3WindowListDelete(pParse->db, $$);} -windowdefn_list(A) ::= windowdefn(Z). { A = Z; } +windowdefn_list(A) ::= windowdefn(A). windowdefn_list(A) ::= windowdefn_list(Y) COMMA windowdefn(Z). { assert( Z!=0 ); sqlite3WindowChain(pParse, Z, Y); @@ -1814,9 +1825,7 @@ window(A) ::= nm(W) ORDER BY sortlist(Y) frame_opt(Z). { A = sqlite3WindowAssemble(pParse, Z, 0, Y, &W); } -window(A) ::= frame_opt(Z). { - A = Z; -} +window(A) ::= frame_opt(A). window(A) ::= nm(W) frame_opt(Z). { A = sqlite3WindowAssemble(pParse, Z, 0, 0, &W); } diff -Nru sqlite3-3.42.0/src/pcache1.c sqlite3-3.44.0-0/src/pcache1.c --- sqlite3-3.42.0/src/pcache1.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/pcache1.c 2023-11-04 14:23:58.000000000 +0000 @@ -64,14 +64,14 @@ ** ** The third case is a chunk of heap memory (defaulting to 100 pages worth) ** that is allocated when the page cache is created. The size of the local -** bulk allocation can be adjusted using +** bulk allocation can be adjusted using ** ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, (void*)0, 0, N). ** ** If N is positive, then N pages worth of memory are allocated using a single ** sqlite3Malloc() call and that memory is used for the first N pages allocated. ** Or if N is negative, then -1024*N bytes of memory are allocated and used -** for as many pages as can be accomodated. +** for as many pages as can be accommodated. ** ** Only one of (2) or (3) can be used. Once the memory available to (2) or ** (3) is exhausted, subsequent allocations fail over to the general-purpose @@ -89,7 +89,7 @@ typedef struct PGroup PGroup; /* -** Each cache entry is represented by an instance of the following +** Each cache entry is represented by an instance of the following ** structure. A buffer of PgHdr1.pCache->szPage bytes is allocated ** directly before this structure and is used to cache the page content. ** @@ -100,12 +100,12 @@ ** overrun area, so that overreads are harmless. ** ** Variables isBulkLocal and isAnchor were once type "u8". That works, -** but causes a 2-byte gap in the structure for most architectures (since +** 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 +** 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 unitialized gap is accessed. Using u16 +** 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. ** @@ -133,7 +133,7 @@ #define PAGE_IS_PINNED(p) ((p)->pLruNext==0) #define PAGE_IS_UNPINNED(p) ((p)->pLruNext!=0) -/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set +/* Each page cache (or PCache) belongs to a PGroup. A PGroup is a set ** of one or more PCaches that are able to recycle each other's unpinned ** pages when they are under memory pressure. A PGroup is an instance of ** the following object. @@ -169,13 +169,13 @@ ** temporary or transient database) has a single page cache which ** is an instance of this object. ** -** Pointers to structures of this type are cast and returned as +** Pointers to structures of this type are cast and returned as ** opaque sqlite3_pcache* handles. */ struct PCache1 { /* Cache configuration parameters. Page size (szPage) and the purgeable ** flag (bPurgeable) and the pnPurgeable pointer are all set when the - ** cache is created and are never changed thereafter. nMax may be + ** cache is created and are never changed thereafter. nMax may be ** modified at any time by a call to the pcache1Cachesize() method. ** The PGroup mutex must be held when accessing nMax. */ @@ -223,7 +223,7 @@ */ int isInit; /* True if initialized */ int separateCache; /* Use a new PGroup for each PCache */ - int nInitPage; /* Initial bulk allocation size */ + int nInitPage; /* Initial bulk allocation size */ int szSlot; /* Size of each free slot */ int nSlot; /* The number of pcache slots */ int nReserve; /* Try to keep nFreeSlot above this */ @@ -264,7 +264,7 @@ /* -** This function is called during initialization if a static buffer is +** This function is called during initialization if a static buffer is ** supplied to use for the page-cache by passing the SQLITE_CONFIG_PAGECACHE ** verb to sqlite3_config(). Parameter pBuf points to an allocation large ** enough to contain 'n' buffers of 'sz' bytes each. @@ -334,8 +334,8 @@ /* ** Malloc function used within this file to allocate space from the buffer -** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no -** such buffer exists or there is no space left in it, this function falls +** configured using sqlite3_config(SQLITE_CONFIG_PAGECACHE) option. If no +** such buffer exists or there is no space left in it, this function falls ** back to sqlite3Malloc(). ** ** Multiple threads can run this routine at the same time. Global variables @@ -442,7 +442,7 @@ }else{ #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT /* The group mutex must be released before pcache1Alloc() is called. This - ** is because it might call sqlite3_release_memory(), which assumes that + ** is because it might call sqlite3_release_memory(), which assumes that ** this mutex is not held. */ assert( pcache1.separateCache==0 ); assert( pCache->pGroup==&pcache1.grp ); @@ -569,7 +569,7 @@ } /* -** This function is used internally to remove the page pPage from the +** This function is used internally to remove the page pPage from the ** PGroup LRU list, if is part of it. If pPage is not part of the PGroup ** LRU list, then this function is a no-op. ** @@ -594,7 +594,7 @@ /* -** Remove the page supplied as an argument from the hash table +** Remove the page supplied as an argument from the hash table ** (PCache1.apHash structure) that it is currently stored in. ** Also free the page if freePage is true. ** @@ -637,8 +637,8 @@ } /* -** Discard all pages from cache pCache with a page number (key value) -** greater than or equal to iLimit. Any pinned pages that meet this +** Discard all pages from cache pCache with a page number (key value) +** greater than or equal to iLimit. Any pinned pages that meet this ** criteria are unpinned before they are discarded. ** ** The PCache mutex must be held when this function is called. @@ -670,7 +670,7 @@ PgHdr1 **pp; PgHdr1 *pPage; assert( hnHash ); - pp = &pCache->apHash[h]; + pp = &pCache->apHash[h]; while( (pPage = *pp)!=0 ){ if( pPage->iKey>=iLimit ){ pCache->nPage--; @@ -709,7 +709,7 @@ ** ** * Use a unified cache in single-threaded applications that have ** configured a start-time buffer for use as page-cache memory using - ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL + ** sqlite3_config(SQLITE_CONFIG_PAGECACHE, pBuf, sz, N) with non-NULL ** pBuf argument. ** ** * Otherwise use separate caches (mode-1) @@ -744,7 +744,7 @@ /* ** Implementation of the sqlite3_pcache.xShutdown method. -** Note that the static mutex allocated in xInit does +** Note that the static mutex allocated in xInit does ** not need to be freed. */ static void pcache1Shutdown(void *NotUsed){ @@ -807,7 +807,7 @@ } /* -** Implementation of the sqlite3_pcache.xCachesize method. +** Implementation of the sqlite3_pcache.xCachesize method. ** ** Configure the cache_size limit for a cache. */ @@ -832,7 +832,7 @@ } /* -** Implementation of the sqlite3_pcache.xShrink method. +** Implementation of the sqlite3_pcache.xShrink method. ** ** Free up as much memory as possible. */ @@ -851,7 +851,7 @@ } /* -** Implementation of the sqlite3_pcache.xPagecount method. +** Implementation of the sqlite3_pcache.xPagecount method. */ static int pcache1Pagecount(sqlite3_pcache *p){ int n; @@ -872,8 +872,8 @@ ** for these steps, the main pcache1Fetch() procedure can run faster. */ static SQLITE_NOINLINE PgHdr1 *pcache1FetchStage2( - PCache1 *pCache, - unsigned int iKey, + PCache1 *pCache, + unsigned int iKey, int createFlag ){ unsigned int nPinned; @@ -915,8 +915,8 @@ } } - /* Step 5. If a usable page buffer has still not been found, - ** attempt to allocate a new one. + /* Step 5. If a usable page buffer has still not been found, + ** attempt to allocate a new one. */ if( !pPage ){ pPage = pcache1AllocPage(pCache, createFlag==1); @@ -941,13 +941,13 @@ } /* -** Implementation of the sqlite3_pcache.xFetch method. +** Implementation of the sqlite3_pcache.xFetch method. ** ** Fetch a page by key value. ** ** Whether or not a new page may be allocated by this function depends on ** the value of the createFlag argument. 0 means do not allocate a new -** page. 1 means allocate a new page if space is easily available. 2 +** page. 1 means allocate a new page if space is easily available. 2 ** means to try really hard to allocate a new page. ** ** For a non-purgeable cache (a cache used as the storage for an in-memory @@ -958,7 +958,7 @@ ** There are three different approaches to obtaining space for a page, ** depending on the value of parameter createFlag (which may be 0, 1 or 2). ** -** 1. Regardless of the value of createFlag, the cache is searched for a +** 1. Regardless of the value of createFlag, the cache is searched for a ** copy of the requested page. If one is found, it is returned. ** ** 2. If createFlag==0 and the page is not already in the cache, NULL is @@ -972,13 +972,13 @@ ** PCache1.nMax, or ** ** (b) the number of pages pinned by the cache is greater than -** the sum of nMax for all purgeable caches, less the sum of +** the sum of nMax for all purgeable caches, less the sum of ** nMin for all other purgeable caches, or ** ** 4. If none of the first three conditions apply and the cache is marked ** as purgeable, and if one of the following is true: ** -** (a) The number of pages allocated for the cache is already +** (a) The number of pages allocated for the cache is already ** PCache1.nMax, or ** ** (b) The number of pages allocated for all purgeable caches is @@ -990,7 +990,7 @@ ** ** then attempt to recycle a page from the LRU list. If it is the right ** size, return the recycled buffer. Otherwise, free the buffer and -** proceed to step 5. +** proceed to step 5. ** ** 5. Otherwise, allocate and return a new page buffer. ** @@ -1000,8 +1000,8 @@ ** invokes the appropriate routine. */ static PgHdr1 *pcache1FetchNoMutex( - sqlite3_pcache *p, - unsigned int iKey, + sqlite3_pcache *p, + unsigned int iKey, int createFlag ){ PCache1 *pCache = (PCache1 *)p; @@ -1030,8 +1030,8 @@ } #if PCACHE1_MIGHT_USE_GROUP_MUTEX static PgHdr1 *pcache1FetchWithMutex( - sqlite3_pcache *p, - unsigned int iKey, + sqlite3_pcache *p, + unsigned int iKey, int createFlag ){ PCache1 *pCache = (PCache1 *)p; @@ -1045,8 +1045,8 @@ } #endif static sqlite3_pcache_page *pcache1Fetch( - sqlite3_pcache *p, - unsigned int iKey, + sqlite3_pcache *p, + unsigned int iKey, int createFlag ){ #if PCACHE1_MIGHT_USE_GROUP_MUTEX || defined(SQLITE_DEBUG) @@ -1076,18 +1076,18 @@ ** Mark a page as unpinned (eligible for asynchronous recycling). */ static void pcache1Unpin( - sqlite3_pcache *p, - sqlite3_pcache_page *pPg, + sqlite3_pcache *p, + sqlite3_pcache_page *pPg, int reuseUnlikely ){ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = (PgHdr1 *)pPg; PGroup *pGroup = pCache->pGroup; - + assert( pPage->pCache==pCache ); pcache1EnterMutex(pGroup); - /* It is an error to call this function if the page is already + /* It is an error to call this function if the page is already ** part of the PGroup LRU list. */ assert( pPage->pLruNext==0 ); @@ -1108,7 +1108,7 @@ } /* -** Implementation of the sqlite3_pcache.xRekey method. +** Implementation of the sqlite3_pcache.xRekey method. */ static void pcache1Rekey( sqlite3_pcache *p, @@ -1119,7 +1119,7 @@ PCache1 *pCache = (PCache1 *)p; PgHdr1 *pPage = (PgHdr1 *)pPg; PgHdr1 **pp; - unsigned int hOld, hNew; + unsigned int hOld, hNew; assert( pPage->iKey==iOld ); assert( pPage->pCache==pCache ); assert( iOld!=iNew ); /* The page number really is changing */ @@ -1147,7 +1147,7 @@ } /* -** Implementation of the sqlite3_pcache.xTruncate method. +** Implementation of the sqlite3_pcache.xTruncate method. ** ** Discard all unpinned pages in the cache with a page number equal to ** or greater than parameter iLimit. Any pinned pages with a page number @@ -1164,7 +1164,7 @@ } /* -** Implementation of the sqlite3_pcache.xDestroy method. +** Implementation of the sqlite3_pcache.xDestroy method. ** ** Destroy a cache allocated using pcache1Create(). */ @@ -1230,7 +1230,7 @@ ** by the current thread may be sqlite3_free()ed. ** ** nReq is the number of bytes of memory required. Once this much has -** been released, the function returns. The return value is the total number +** been released, the function returns. The return value is the total number ** of bytes of memory released. */ int sqlite3PcacheReleaseMemory(int nReq){ diff -Nru sqlite3-3.42.0/src/pcache.c sqlite3-3.44.0-0/src/pcache.c --- sqlite3-3.42.0/src/pcache.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/pcache.c 2023-11-04 14:23:58.000000000 +0000 @@ -107,7 +107,7 @@ ** Return 1 if pPg is on the dirty list for pCache. Return 0 if not. ** This routine runs inside of assert() statements only. */ -#ifdef SQLITE_DEBUG +#if defined(SQLITE_ENABLE_EXPENSIVE_ASSERT) static int pageOnDirtyList(PCache *pCache, PgHdr *pPg){ PgHdr *p; for(p=pCache->pDirty; p; p=p->pDirtyNext){ @@ -115,6 +115,16 @@ } return 0; } +static int pageNotOnDirtyList(PCache *pCache, PgHdr *pPg){ + PgHdr *p; + for(p=pCache->pDirty; p; p=p->pDirtyNext){ + if( p==pPg ) return 0; + } + return 1; +} +#else +# define pageOnDirtyList(A,B) 1 +# define pageNotOnDirtyList(A,B) 1 #endif /* @@ -135,7 +145,7 @@ assert( pCache!=0 ); /* Every page has an associated PCache */ if( pPg->flags & PGHDR_CLEAN ){ assert( (pPg->flags & PGHDR_DIRTY)==0 );/* Cannot be both CLEAN and DIRTY */ - assert( !pageOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirty list */ + assert( pageNotOnDirtyList(pCache, pPg) );/* CLEAN pages not on dirtylist */ }else{ assert( (pPg->flags & PGHDR_DIRTY)!=0 );/* If not CLEAN must be DIRTY */ assert( pPg->pDirtyNext==0 || pPg->pDirtyNext->pDirtyPrev==pPg ); @@ -271,7 +281,7 @@ return p->szCache; }else{ i64 n; - /* IMPLEMANTATION-OF: R-59858-46238 If the argument N is negative, then the + /* 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. */ @@ -759,7 +769,7 @@ } /* -** Sort the list of pages in accending order by pgno. Pages are +** Sort the list of pages in ascending order by pgno. Pages are ** connected by pDirty pointers. The pDirtyPrev pointers are ** corrupted by this sort. ** diff -Nru sqlite3-3.42.0/src/pragma.c sqlite3-3.44.0-0/src/pragma.c --- sqlite3-3.42.0/src/pragma.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/pragma.c 2023-11-04 14:23:58.000000000 +0000 @@ -26,13 +26,13 @@ ** that includes the PragType_XXXX macro definitions and the aPragmaName[] ** object. This ensures that the aPragmaName[] table is arranged in ** lexicographical order to facility a binary search of the pragma name. -** Do not edit pragma.h directly. Edit and rerun the script in at +** Do not edit pragma.h directly. Edit and rerun the script in at ** ../tool/mkpragmatab.tcl. */ #include "pragma.h" /* ** Interpret the given string as a safety level. Return 0 for OFF, -** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or +** 1 for ON or NORMAL, 2 for FULL, and 3 for EXTRA. Return 1 for an empty or ** unrecognized string argument. The FULL and EXTRA option is disallowed ** if the omitFull parameter it 1. ** @@ -91,7 +91,7 @@ /* ** Interpret the given string as an auto-vacuum mode value. ** -** The following strings, "none", "full" and "incremental" are +** The following strings, "none", "full" and "incremental" are ** acceptable, as are their numeric equivalents: 0, 1 and 2 respectively. */ static int getAutoVacuum(const char *z){ @@ -245,7 +245,7 @@ case OE_SetDflt: zName = "SET DEFAULT"; break; case OE_Cascade: zName = "CASCADE"; break; case OE_Restrict: zName = "RESTRICT"; break; - default: zName = "NO ACTION"; + default: zName = "NO ACTION"; assert( action==OE_None ); break; } return zName; @@ -307,7 +307,7 @@ int isBuiltin, /* True if this is a built-in function */ int showInternFuncs /* True if showing internal functions */ ){ - u32 mask = + u32 mask = SQLITE_DETERMINISTIC | SQLITE_DIRECTONLY | SQLITE_SUBTYPE | @@ -329,7 +329,7 @@ && showInternFuncs==0 ){ continue; - } + } if( p->xValue!=0 ){ zType = "w"; }else if( p->xFinalize!=0 ){ @@ -364,7 +364,7 @@ } /* -** Process a pragma statement. +** Process a pragma statement. ** ** Pragmas are of this form: ** @@ -379,7 +379,7 @@ ** id and pId2 is any empty string. */ void sqlite3Pragma( - Parse *pParse, + Parse *pParse, Token *pId1, /* First part of [schema.]id field */ Token *pId2, /* Second part of [schema.]id field, or NULL */ Token *pValue, /* Token for , or NULL */ @@ -407,8 +407,8 @@ if( iDb<0 ) return; pDb = &db->aDb[iDb]; - /* If the temp database has been explicitly named as part of the - ** pragma, make sure it is open. + /* If the temp database has been explicitly named as part of the + ** pragma, make sure it is open. */ if( iDb==1 && sqlite3OpenTempDatabase(pParse) ){ return; @@ -480,7 +480,7 @@ } /* Register the result column names for pragmas that return results */ - if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 + if( (pPragma->mPragFlg & PragFlg_NoColumns)==0 && ((pPragma->mPragFlg & PragFlg_NoColumns1)==0 || zRight==0) ){ setPragmaResultColumnNames(v, pPragma); @@ -488,7 +488,7 @@ /* Jump to the appropriate pragma handler */ switch( pPragma->ePragTyp ){ - + #if !defined(SQLITE_OMIT_PAGER_PRAGMAS) && !defined(SQLITE_OMIT_DEPRECATED) /* ** PRAGMA [schema.]default_cache_size @@ -604,7 +604,7 @@ ** PRAGMA [schema.]max_page_count=N ** ** The first form reports the current setting for the - ** maximum number of pages in the database file. The + ** maximum number of pages in the database file. The ** second form attempts to change this setting. Both ** forms return the current setting. ** @@ -771,7 +771,7 @@ */ rc = sqlite3BtreeSetAutoVacuum(pBt, eAuto); if( rc==SQLITE_OK && (eAuto==1 || eAuto==2) ){ - /* When setting the auto_vacuum mode to either "full" or + /* When setting the auto_vacuum mode to either "full" or ** "incremental", write the value of meta[6] in the database ** file. Before writing to meta[6], check that meta[3] indicates ** that this really is an auto-vacuum capable database. @@ -854,7 +854,7 @@ ** ** The first form reports the current local setting for the ** page cache spill size. The second form turns cache spill on - ** or off. When turnning cache spill on, the size is set to the + ** 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 @@ -873,7 +873,7 @@ assert( sqlite3SchemaMutexHeld(db, iDb, 0) ); if( !zRight ){ returnSingleInt(v, - (db->flags & SQLITE_CacheSpill)==0 ? 0 : + (db->flags & SQLITE_CacheSpill)==0 ? 0 : sqlite3BtreeSetSpillSize(pDb->pBt,0)); }else{ int size = 1; @@ -1053,7 +1053,7 @@ Pager *pPager = sqlite3BtreePager(pDb->pBt); char *proxy_file_path = NULL; sqlite3_file *pFile = sqlite3PagerFile(pPager); - sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, + sqlite3OsFileControlHint(pFile, SQLITE_GET_LOCKPROXYFILE, &proxy_file_path); returnSingleText(v, proxy_file_path); }else{ @@ -1061,10 +1061,10 @@ sqlite3_file *pFile = sqlite3PagerFile(pPager); int res; if( zRight[0] ){ - res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, zRight); } else { - res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, + res=sqlite3OsFileControl(pFile, SQLITE_SET_LOCKPROXYFILE, NULL); } if( res!=SQLITE_OK ){ @@ -1074,8 +1074,8 @@ } break; } -#endif /* SQLITE_ENABLE_LOCKING_STYLE */ - +#endif /* SQLITE_ENABLE_LOCKING_STYLE */ + /* ** PRAGMA [schema.]synchronous ** PRAGMA [schema.]synchronous=OFF|ON|NORMAL|FULL|EXTRA @@ -1090,7 +1090,7 @@ returnSingleInt(v, pDb->safety_level-1); }else{ if( !db->autoCommit ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "Safety level may not be changed inside a transaction"); }else if( iDb!=1 ){ int iLevel = (getSafetyLevel(zRight,0,1)+1) & PAGER_SYNCHRONOUS_MASK; @@ -1124,7 +1124,11 @@ #endif if( sqlite3GetBoolean(zRight, 0) ){ - db->flags |= mask; + if( (mask & SQLITE_WriteSchema)==0 + || (db->flags & SQLITE_Defensive)==0 + ){ + db->flags |= mask; + } }else{ db->flags &= ~mask; if( mask==SQLITE_DeferFKs ) db->nDeferredImmCons = 0; @@ -1138,7 +1142,7 @@ } } - /* Many of the flag-pragmas modify the code generated by the SQL + /* Many of the flag-pragmas modify the code generated by the SQL ** compiler (eg. count_changes). So add an opcode to expire all ** compiled SQL statements after modifying a pragma value. */ @@ -1465,7 +1469,7 @@ pFK = pTab->u.tab.pFKey; if( pFK ){ int iTabDb = sqlite3SchemaToIndex(db, pTab->pSchema); - int i = 0; + int i = 0; pParse->nMem = 8; sqlite3CodeVerifySchema(pParse, iTabDb); while(pFK){ @@ -1562,8 +1566,8 @@ addrOk = sqlite3VdbeMakeLabel(pParse); /* Generate code to read the child key values into registers - ** regRow..regRow+n. If any of the child key values are NULL, this - ** row cannot cause an FK violation. Jump directly to addrOk in + ** regRow..regRow+n. If any of the child key values are NULL, this + ** row cannot cause an FK violation. Jump directly to addrOk in ** this case. */ sqlite3TouchRegister(pParse, regRow + pFK->nCol); for(j=0; jnCol; j++){ @@ -1629,12 +1633,12 @@ ** ** Verify the integrity of the database. ** - ** The "quick_check" is reduced version of + ** The "quick_check" is reduced version of ** integrity_check designed to detect most database corruption ** without the overhead of cross-checking indexes. Quick_check - ** is linear time wherease integrity_check is O(NlogN). + ** is linear time whereas integrity_check is O(NlogN). ** - ** The maximum nubmer of errors is 100 by default. A different default + ** 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 @@ -1757,8 +1761,31 @@ int r2; /* Previous key for WITHOUT ROWID tables */ int mxCol; /* Maximum non-virtual column number */ - if( !IsOrdinaryTable(pTab) ) continue; if( pObjTab && pObjTab!=pTab ) continue; + if( !IsOrdinaryTable(pTab) ){ +#ifndef SQLITE_OMIT_VIRTUALTABLE + sqlite3_vtab *pVTab; + int a1; + if( !IsVirtual(pTab) ) continue; + if( pTab->nCol<=0 ){ + const char *zMod = pTab->u.vtab.azArg[0]; + if( sqlite3HashFind(&db->aModule, zMod)==0 ) continue; + } + sqlite3ViewGetColumnNames(pParse, pTab); + if( pTab->u.vtab.p==0 ) continue; + pVTab = pTab->u.vtab.p->pVtab; + if( NEVER(pVTab==0) ) continue; + if( NEVER(pVTab->pModule==0) ) continue; + if( pVTab->pModule->iVersion<4 ) continue; + if( pVTab->pModule->xIntegrity==0 ) continue; + sqlite3VdbeAddOp3(v, OP_VCheck, i, 3, isQuick); + sqlite3VdbeAppendP4(v, pTab, P4_TABLE); + a1 = sqlite3VdbeAddOp1(v, OP_IsNull, 3); VdbeCoverage(v); + integrityCheckResultRow(v); + sqlite3VdbeJumpHere(v, a1); +#endif + continue; + } if( isQuick || HasRowid(pTab) ){ pPk = 0; r2 = 0; @@ -1770,7 +1797,7 @@ sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenRead, 0, 1, 0, &iDataCur, &iIdxCur); /* reg[7] counts the number of entries in the table. - ** reg[8+i] counts the number of entries in the i-th index + ** reg[8+i] counts the number of entries in the i-th index */ sqlite3VdbeAddOp2(v, OP_Integer, 0, 7); for(j=0, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, j++){ @@ -1795,7 +1822,7 @@ if( mxCol==pTab->iPKey ) mxCol--; }else{ /* COLFLAG_VIRTUAL columns are not included in the WITHOUT ROWID - ** PK index column-count, so there is no need to account for them + ** PK index column-count, so there is no need to account for them ** in this case. */ mxCol = sqlite3PrimaryKeyIndex(pTab)->nColumn-1; } @@ -1895,7 +1922,7 @@ sqlite3VdbeAddOp3(v, OP_Column, p1, p3, 3); jmp3 = sqlite3VdbeAddOp2(v, OP_NotNull, 3, labelOk); VdbeCoverage(v); - } + } zErr = sqlite3MPrintf(db, "NULL value in %s.%s", pTab->zName, pCol->zCnName); sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0, zErr, P4_DYNAMIC); @@ -1967,7 +1994,7 @@ for(k=pCheck->nExpr-1; k>0; k--){ sqlite3ExprIfFalse(pParse, pCheck->a[k].pExpr, addrCkFault, 0); } - sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, + sqlite3ExprIfTrue(pParse, pCheck->a[0].pExpr, addrCkOk, SQLITE_JUMPIFNULL); sqlite3VdbeResolveLabel(v, addrCkFault); pParse->iSelfTab = 0; @@ -2037,7 +2064,7 @@ sqlite3VdbeGoto(v, jmp5-1); sqlite3VdbeJumpHere(v, jmp6); } - + /* For UNIQUE indexes, verify that only one entry exists with the ** current key. The entry is unique if (1) any column is NULL ** or (2) the next entry has a different key */ @@ -2082,7 +2109,7 @@ sqlite3ReleaseTempRange(pParse, r2, pPk->nKeyCol); } } - } + } } { static const int iLn = VDBE_OFFSET_LINENO(2); @@ -2124,7 +2151,7 @@ ** encoding that will be used for the main database file if a new file ** is created. If an existing main database file is opened, then the ** default text encoding for the existing database is used. - ** + ** ** In all cases new databases created using the ATTACH command are ** created to use the same default text encoding as the main database. If ** the main database has not been initialized and/or created when ATTACH @@ -2312,8 +2339,8 @@ if( zRight ){ sqlite3_wal_autocheckpoint(db, sqlite3Atoi(zRight)); } - returnSingleInt(v, - db->xWalCallback==sqlite3WalDefaultHook ? + returnSingleInt(v, + db->xWalCallback==sqlite3WalDefaultHook ? SQLITE_PTR_TO_INT(db->pWalArg) : 0); } break; @@ -2353,7 +2380,7 @@ ** 0x0002 Run ANALYZE on tables that might benefit. On by default. ** See below for additional information. ** - ** 0x0004 (Not yet implemented) Record usage and performance + ** 0x0004 (Not yet implemented) Record usage and performance ** information from the current session in the ** database file so that it will be available to "optimize" ** pragmas run by future database connections. @@ -2364,7 +2391,7 @@ ** The default MASK is and always shall be 0xfffe. 0xfffe means perform all ** of the optimizations listed above except Debug Mode, including new ** optimizations that have not yet been invented. If new optimizations are - ** ever added that should be off by default, those off-by-default + ** ever added that should be off by default, those off-by-default ** optimizations will have bitmasks of 0x10000 or larger. ** ** DETERMINATION OF WHEN TO RUN ANALYZE @@ -2392,7 +2419,7 @@ Schema *pSchema; /* The current schema */ Table *pTab; /* A table in the schema */ Index *pIdx; /* An index of the table */ - LogEst szThreshold; /* Size threshold above which reanalysis is needd */ + LogEst szThreshold; /* Size threshold above which reanalysis needed */ char *zSubSql; /* SQL statement for the OP_SqlExec opcode */ u32 opMask; /* Mask of operations to perform */ @@ -2425,7 +2452,7 @@ } if( szThreshold ){ sqlite3OpenTable(pParse, iTabCur, iDb, pTab, OP_OpenRead); - sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, + sqlite3VdbeAddOp3(v, OP_IfSmaller, iTabCur, sqlite3VdbeCurrentAddr(v)+2+(opMask&1), szThreshold); VdbeCoverage(v); } @@ -2559,7 +2586,7 @@ pBt = db->aDb[i].pBt; if( pBt==0 || sqlite3BtreePager(pBt)==0 ){ zState = "closed"; - }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, + }else if( sqlite3_file_control(db, i ? db->aDb[i].zDbSName : 0, SQLITE_FCNTL_LOCKSTATE, &j)==SQLITE_OK ){ zState = azLockName[j]; } @@ -2583,7 +2610,7 @@ /* The following block is a no-op unless SQLITE_DEBUG is defined. Its only ** purpose is to execute assert() statements to verify that if the ** PragFlg_NoColumns1 flag is set and the caller specified an argument - ** to the PRAGMA, the implementation has not added any OP_ResultRow + ** to the PRAGMA, the implementation has not added any OP_ResultRow ** instructions to the VM. */ if( (pPragma->mPragFlg & PragFlg_NoColumns1) && zRight ){ sqlite3VdbeVerifyNoResultRow(v); @@ -2614,7 +2641,7 @@ char *azArg[2]; /* Value of the argument and schema */ }; -/* +/* ** Pragma virtual table module xConnect method. */ static int pragmaVtabConnect( @@ -2676,7 +2703,7 @@ return rc; } -/* +/* ** Pragma virtual table module xDisconnect method. */ static int pragmaVtabDisconnect(sqlite3_vtab *pVtab){ @@ -2774,11 +2801,11 @@ return rc; } -/* +/* ** Pragma virtual table module xFilter method. */ static int pragmaVtabFilter( - sqlite3_vtab_cursor *pVtabCursor, + sqlite3_vtab_cursor *pVtabCursor, int idxNum, const char *idxStr, int argc, sqlite3_value **argv ){ @@ -2833,11 +2860,11 @@ } /* The xColumn method simply returns the corresponding column from -** the PRAGMA. +** the PRAGMA. */ static int pragmaVtabColumn( - sqlite3_vtab_cursor *pVtabCursor, - sqlite3_context *ctx, + sqlite3_vtab_cursor *pVtabCursor, + sqlite3_context *ctx, int i ){ PragmaVtabCursor *pCsr = (PragmaVtabCursor*)pVtabCursor; @@ -2850,7 +2877,7 @@ return SQLITE_OK; } -/* +/* ** Pragma virtual table module xRowid method. */ static int pragmaVtabRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *p){ @@ -2884,7 +2911,8 @@ 0, /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ - 0 /* xShadowName */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff -Nru sqlite3-3.42.0/src/prepare.c sqlite3-3.44.0-0/src/prepare.c --- sqlite3-3.42.0/src/prepare.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/prepare.c 2023-11-04 14:23:58.000000000 +0000 @@ -598,8 +598,6 @@ db->lookaside.sz = db->lookaside.bDisable ? 0 : db->lookaside.szTrue; assert( pParse->db->pParse==pParse ); db->pParse = pParse->pOuterParse; - pParse->db = 0; - pParse->disableLookaside = 0; } /* @@ -608,7 +606,7 @@ ** immediately. ** ** Use this mechanism for uncommon cleanups. There is a higher setup -** cost for this mechansim (an extra malloc), so it should not be used +** cost for this mechanism (an extra malloc), so it should not be used ** for common cleanups that happen on most calls. But for less ** common cleanups, we save a single NULL-pointer comparison in ** sqlite3ParseObjectReset(), which reduces the total CPU cycle count. @@ -700,7 +698,12 @@ sParse.pOuterParse = db->pParse; db->pParse = &sParse; sParse.db = db; - sParse.pReprepare = pReprepare; + if( pReprepare ){ + sParse.pReprepare = pReprepare; + sParse.explain = sqlite3_stmt_isexplain((sqlite3_stmt*)pReprepare); + }else{ + assert( sParse.pReprepare==0 ); + } assert( ppStmt && *ppStmt==0 ); if( db->mallocFailed ){ sqlite3ErrorMsg(&sParse, "out of memory"); diff -Nru sqlite3-3.42.0/src/printf.c sqlite3-3.44.0-0/src/printf.c --- sqlite3-3.42.0/src/printf.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/printf.c 2023-11-04 14:23:58.000000000 +0000 @@ -105,57 +105,6 @@ ** %!S Like %S but prefer the zName over the zAlias */ -/* Floating point constants used for rounding */ -static const double arRound[] = { - 5.0e-01, 5.0e-02, 5.0e-03, 5.0e-04, 5.0e-05, - 5.0e-06, 5.0e-07, 5.0e-08, 5.0e-09, 5.0e-10, -}; - -/* -** If SQLITE_OMIT_FLOATING_POINT is defined, then none of the floating point -** conversions will work. -*/ -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** "*val" is a double such that 0.1 <= *val < 10.0 -** Return the ascii code for the leading digit of *val, then -** multiply "*val" by 10.0 to renormalize. -** -** Example: -** input: *val = 3.14159 -** output: *val = 1.4159 function return = '3' -** -** The counter *cnt is incremented each time. After counter exceeds -** 16 (the number of significant digits in a 64-bit float) '0' is -** always returned. -*/ -static char et_getdigit(LONGDOUBLE_TYPE *val, int *cnt){ - int digit; - LONGDOUBLE_TYPE d; - if( (*cnt)<=0 ) return '0'; - (*cnt)--; - digit = (int)*val; - d = digit; - digit += '0'; - *val = (*val - d)*10.0; - return (char)digit; -} -#endif /* SQLITE_OMIT_FLOATING_POINT */ - -#ifndef SQLITE_OMIT_FLOATING_POINT -/* -** "*val" is a u64. *msd is a divisor used to extract the -** most significant digit of *val. Extract that most significant -** digit and return it. -*/ -static char et_getdigit_int(u64 *val, u64 *msd){ - u64 x = (*val)/(*msd); - *val -= x*(*msd); - if( *msd>=10 ) *msd /= 10; - return '0' + (char)(x & 15); -} -#endif /* SQLITE_OMIT_FLOATING_POINT */ - /* ** Set the StrAccum object to an error mode. */ @@ -247,20 +196,15 @@ u8 bArgList; /* True for SQLITE_PRINTF_SQLFUNC */ char prefix; /* Prefix character. "+" or "-" or " " or '\0'. */ sqlite_uint64 longvalue; /* Value for integer types */ - LONGDOUBLE_TYPE realvalue; /* Value for real types */ - sqlite_uint64 msd; /* Divisor to get most-significant-digit - ** of longvalue */ + double realvalue; /* Value for real types */ const et_info *infop; /* Pointer to the appropriate info structure */ char *zOut; /* Rendering buffer */ int nOut; /* Size of the rendering buffer */ char *zExtra = 0; /* Malloced memory used by some conversion */ -#ifndef SQLITE_OMIT_FLOATING_POINT - int exp, e2; /* exponent of real numbers */ - int nsd; /* Number of significant digits returned */ - double rounder; /* Used for rounding floating point values */ + int exp, e2; /* exponent of real numbers */ etByte flag_dp; /* True if decimal point should be shown */ etByte flag_rtz; /* True if trailing zeros should be removed */ -#endif + PrintfArguments *pArgList = 0; /* Arguments for SQLITE_PRINTF_SQLFUNC */ char buf[etBUFSIZE]; /* Conversion buffer */ @@ -535,94 +479,61 @@ break; case etFLOAT: case etEXP: - case etGENERIC: + case etGENERIC: { + FpDecode s; + int iRound; + int j; + if( bArgList ){ realvalue = getDoubleArg(pArgList); }else{ realvalue = va_arg(ap,double); } -#ifdef SQLITE_OMIT_FLOATING_POINT - length = 0; -#else if( precision<0 ) precision = 6; /* Set default precision */ #ifdef SQLITE_FP_PRECISION_LIMIT if( precision>SQLITE_FP_PRECISION_LIMIT ){ precision = SQLITE_FP_PRECISION_LIMIT; } #endif - if( realvalue<0.0 ){ - realvalue = -realvalue; - prefix = '-'; + if( xtype==etFLOAT ){ + iRound = -precision; + }else if( xtype==etGENERIC ){ + iRound = precision; }else{ - prefix = flag_prefix; + iRound = precision+1; } - exp = 0; - if( xtype==etGENERIC && precision>0 ) precision--; - testcase( precision>0xfff ); - if( realvalue<1.0e+16 - && realvalue==(LONGDOUBLE_TYPE)(longvalue = (u64)realvalue) - ){ - /* Number is a pure integer that can be represented as u64 */ - for(msd=1; msd*10<=longvalue; msd *= 10, exp++){} - if( exp>precision && xtype!=etFLOAT ){ - u64 rnd = msd/2; - int kk = precision; - while( kk-- > 0 ){ rnd /= 10; } - longvalue += rnd; - } - }else{ - msd = 0; - longvalue = 0; /* To prevent a compiler warning */ - idx = precision & 0xfff; - rounder = arRound[idx%10]; - while( idx>=10 ){ rounder *= 1.0e-10; idx -= 10; } - if( xtype==etFLOAT ){ - double rx = (double)realvalue; - sqlite3_uint64 u; - int ex; - memcpy(&u, &rx, sizeof(u)); - ex = -1023 + (int)((u>>52)&0x7ff); - if( precision+(ex/3) < 15 ) rounder += realvalue*3e-16; - realvalue += rounder; - } - if( sqlite3IsNaN((double)realvalue) ){ - if( flag_zeropad ){ - bufpt = "null"; - length = 4; + sqlite3FpDecode(&s, realvalue, iRound, flag_altform2 ? 26 : 16); + if( s.isSpecial ){ + if( s.isSpecial==2 ){ + bufpt = flag_zeropad ? "null" : "NaN"; + length = sqlite3Strlen30(bufpt); + break; + }else if( flag_zeropad ){ + s.z[0] = '9'; + s.iDP = 1000; + s.n = 1; + }else{ + memcpy(buf, "-Inf", 5); + bufpt = buf; + if( s.sign=='-' ){ + /* no-op */ + }else if( flag_prefix ){ + buf[0] = flag_prefix; }else{ - bufpt = "NaN"; - length = 3; + bufpt++; } + length = sqlite3Strlen30(bufpt); break; } - - /* Normalize realvalue to within 10.0 > realvalue >= 1.0 */ - if( ALWAYS(realvalue>0.0) ){ - LONGDOUBLE_TYPE scale = 1.0; - while( realvalue>=1e100*scale && exp<=350){ scale*=1e100;exp+=100;} - while( realvalue>=1e10*scale && exp<=350 ){ scale*=1e10; exp+=10; } - while( realvalue>=10.0*scale && exp<=350 ){ scale *= 10.0; exp++; } - realvalue /= scale; - while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; } - while( realvalue<1.0 ){ realvalue *= 10.0; exp--; } - if( exp>350 ){ - if( flag_zeropad ){ - realvalue = 9.0; - exp = 999; - }else{ - bufpt = buf; - buf[0] = prefix; - memcpy(buf+(prefix!=0),"Inf",4); - length = 3+(prefix!=0); - break; - } - } - if( xtype!=etFLOAT ){ - realvalue += rounder; - if( realvalue>=10.0 ){ realvalue *= 0.1; exp++; } - } - } } + if( s.sign=='-' ){ + prefix = '-'; + }else{ + prefix = flag_prefix; + } + + exp = s.iDP-1; + if( xtype==etGENERIC && precision>0 ) precision--; /* ** If the field type is etGENERIC, then convert to either etEXP @@ -642,9 +553,8 @@ if( xtype==etEXP ){ e2 = 0; }else{ - e2 = exp; + e2 = s.iDP - 1; } - nsd = 16 + flag_altform2*10; bufpt = buf; { i64 szBufNeeded; /* Size of a temporary buffer needed */ @@ -662,16 +572,12 @@ *(bufpt++) = prefix; } /* Digits prior to the decimal point */ + j = 0; if( e2<0 ){ *(bufpt++) = '0'; - }else if( msd>0 ){ - for(; e2>=0; e2--){ - *(bufpt++) = et_getdigit_int(&longvalue,&msd); - if( cThousand && (e2%3)==0 && e2>1 ) *(bufpt++) = ','; - } }else{ for(; e2>=0; e2--){ - *(bufpt++) = et_getdigit(&realvalue,&nsd); + *(bufpt++) = j1 ) *(bufpt++) = ','; } } @@ -681,19 +587,12 @@ } /* "0" digits after the decimal point but before the first ** significant digit of the number */ - for(e2++; e2<0; precision--, e2++){ - assert( precision>0 ); + for(e2++; e2<0 && precision>0; precision--, e2++){ *(bufpt++) = '0'; } /* Significant digits after the decimal point */ - if( msd>0 ){ - while( (precision--)>0 ){ - *(bufpt++) = et_getdigit_int(&longvalue,&msd); - } - }else{ - while( (precision--)>0 ){ - *(bufpt++) = et_getdigit(&realvalue,&nsd); - } + while( (precision--)>0 ){ + *(bufpt++) = jcharset]; if( exp<0 ){ *(bufpt++) = '-'; exp = -exp; @@ -742,8 +642,8 @@ while( nPad-- ) bufpt[i++] = '0'; length = width; } -#endif /* !defined(SQLITE_OMIT_FLOATING_POINT) */ break; + } case etSIZE: if( !bArgList ){ *(va_arg(ap,int*)) = pAccum->nChar; @@ -1466,3 +1366,72 @@ sqlite3_str_vappendf(p, zFormat, ap); va_end(ap); } + + +/***************************************************************************** +** Reference counted string storage +*****************************************************************************/ + +/* +** Increase the reference count of the string by one. +** +** The input parameter is returned. +*/ +char *sqlite3RCStrRef(char *z){ + RCStr *p = (RCStr*)z; + assert( p!=0 ); + p--; + p->nRCRef++; + return z; +} + +/* +** Decrease the reference count by one. Free the string when the +** reference count reaches zero. +*/ +void sqlite3RCStrUnref(void *z){ + RCStr *p = (RCStr*)z; + assert( p!=0 ); + p--; + assert( p->nRCRef>0 ); + if( p->nRCRef>=2 ){ + p->nRCRef--; + }else{ + sqlite3_free(p); + } +} + +/* +** Create a new string that is capable of holding N bytes of text, not counting +** the zero byte at the end. The string is uninitialized. +** +** The reference count is initially 1. Call sqlite3RCStrUnref() to free the +** newly allocated string. +** +** This routine returns 0 on an OOM. +*/ +char *sqlite3RCStrNew(u64 N){ + RCStr *p = sqlite3_malloc64( N + sizeof(*p) + 1 ); + if( p==0 ) return 0; + p->nRCRef = 1; + return (char*)&p[1]; +} + +/* +** Change the size of the string so that it is able to hold N bytes. +** The string might be reallocated, so return the new allocation. +*/ +char *sqlite3RCStrResize(char *z, u64 N){ + RCStr *p = (RCStr*)z; + RCStr *pNew; + assert( p!=0 ); + p--; + assert( p->nRCRef==1 ); + pNew = sqlite3_realloc64(p, N+sizeof(RCStr)+1); + if( pNew==0 ){ + sqlite3_free(p); + return 0; + }else{ + return (char*)&pNew[1]; + } +} diff -Nru sqlite3-3.42.0/src/resolve.c sqlite3-3.44.0-0/src/resolve.c --- sqlite3-3.42.0/src/resolve.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/resolve.c 2023-11-04 14:23:58.000000000 +0000 @@ -104,21 +104,36 @@ } /* -** Subqueries stores the original database, table and column names for their -** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN". -** Check to see if the zSpan given to this routine matches the zDb, zTab, -** and zCol. If any of zDb, zTab, and zCol are NULL then those fields will -** match anything. +** Subqueries store the original database, table and column names for their +** result sets in ExprList.a[].zSpan, in the form "DATABASE.TABLE.COLUMN", +** and mark the expression-list item by setting ExprList.a[].fg.eEName +** to ENAME_TAB. +** +** Check to see if the zSpan/eEName of the expression-list item passed to this +** routine matches the zDb, zTab, and zCol. If any of zDb, zTab, and zCol are +** NULL then those fields will match anything. Return true if there is a match, +** or false otherwise. +** +** SF_NestedFrom subqueries also store an entry for the implicit rowid (or +** _rowid_, or oid) column by setting ExprList.a[].fg.eEName to ENAME_ROWID, +** and setting zSpan to "DATABASE.TABLE.". This type of pItem +** argument matches if zCol is a rowid alias. If it is not NULL, (*pbRowid) +** is set to 1 if there is this kind of match. */ int sqlite3MatchEName( const struct ExprList_item *pItem, const char *zCol, const char *zTab, - const char *zDb + const char *zDb, + int *pbRowid ){ int n; const char *zSpan; - if( pItem->fg.eEName!=ENAME_TAB ) return 0; + int eEName = pItem->fg.eEName; + if( eEName!=ENAME_TAB && (eEName!=ENAME_ROWID || NEVER(pbRowid==0)) ){ + return 0; + } + assert( pbRowid==0 || *pbRowid==0 ); zSpan = pItem->zEName; for(n=0; ALWAYS(zSpan[n]) && zSpan[n]!='.'; n++){} if( zDb && (sqlite3StrNICmp(zSpan, zDb, n)!=0 || zDb[n]!=0) ){ @@ -130,9 +145,11 @@ return 0; } zSpan += n+1; - if( zCol && sqlite3StrICmp(zSpan, zCol)!=0 ){ - return 0; + if( zCol ){ + if( eEName==ENAME_TAB && sqlite3StrICmp(zSpan, zCol)!=0 ) return 0; + if( eEName==ENAME_ROWID && sqlite3IsRowid(zCol)==0 ) return 0; } + if( eEName==ENAME_ROWID ) *pbRowid = 1; return 1; } @@ -166,7 +183,7 @@ pExTab = pExpr->y.pTab; assert( pExTab!=0 ); if( (pExTab->tabFlags & TF_HasGenerated)!=0 - && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 + && (pExTab->aCol[n].colFlags & COLFLAG_GENERATED)!=0 ){ testcase( pExTab->nCol==BMS-1 ); testcase( pExTab->nCol==BMS ); @@ -230,7 +247,7 @@ /* ** Given the name of a column of the form X.Y.Z or Y.Z or just Z, look up -** that name in the set of source tables in pSrcList and make the pExpr +** that name in the set of source tables in pSrcList and make the pExpr ** expression node refer back to that source column. The following changes ** are made to pExpr: ** @@ -265,7 +282,7 @@ ){ int i, j; /* Loop counters */ int cnt = 0; /* Number of matching column names */ - int cntTab = 0; /* Number of matching table names */ + int cntTab = 0; /* Number of potential "rowid" matches */ int nSubquery = 0; /* How many levels of subquery */ sqlite3 *db = pParse->db; /* The database connection */ SrcItem *pItem; /* Use for looping over pSrcList items */ @@ -342,39 +359,49 @@ assert( pEList!=0 ); assert( pEList->nExpr==pTab->nCol ); for(j=0; jnExpr; j++){ - if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb) ){ + int bRowid = 0; /* True if possible rowid match */ + if( !sqlite3MatchEName(&pEList->a[j], zCol, zTab, zDb, &bRowid) ){ continue; } - if( cnt>0 ){ - if( pItem->fg.isUsing==0 - || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 - ){ - /* Two or more tables have the same column name which is - ** not joined by USING. This is an error. Signal as much - ** by clearing pFJMatch and letting cnt go above 1. */ - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else - if( (pItem->fg.jointype & JT_RIGHT)==0 ){ - /* An INNER or LEFT JOIN. Use the left-most table */ - continue; - }else - if( (pItem->fg.jointype & JT_LEFT)==0 ){ - /* A RIGHT JOIN. Use the right-most table */ - cnt = 0; - sqlite3ExprListDelete(db, pFJMatch); - pFJMatch = 0; - }else{ - /* For a FULL JOIN, we must construct a coalesce() func */ - extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + if( bRowid==0 ){ + if( cnt>0 ){ + if( pItem->fg.isUsing==0 + || sqlite3IdListIndex(pItem->u3.pUsing, zCol)<0 + ){ + /* Two or more tables have the same column name which is + ** not joined by USING. This is an error. Signal as much + ** by clearing pFJMatch and letting cnt go above 1. */ + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else + if( (pItem->fg.jointype & JT_RIGHT)==0 ){ + /* An INNER or LEFT JOIN. Use the left-most table */ + continue; + }else + if( (pItem->fg.jointype & JT_LEFT)==0 ){ + /* A RIGHT JOIN. Use the right-most table */ + cnt = 0; + sqlite3ExprListDelete(db, pFJMatch); + pFJMatch = 0; + }else{ + /* For a FULL JOIN, we must construct a coalesce() func */ + extendFJMatch(pParse, &pFJMatch, pMatch, pExpr->iColumn); + } } + cnt++; + hit = 1; + }else if( cnt>0 ){ + /* This is a potential rowid match, but there has already been + ** a real match found. So this can be ignored. */ + continue; } - cnt++; - cntTab = 2; + cntTab++; pMatch = pItem; pExpr->iColumn = j; pEList->a[j].fg.bUsed = 1; - hit = 1; + + /* rowid cannot be part of a USING clause - assert() this. */ + assert( bRowid==0 || pEList->a[j].fg.bUsingTerm==0 ); if( pEList->a[j].fg.bUsingTerm ) break; } if( hit || zTab==0 ) continue; @@ -454,7 +481,7 @@ } /* if( pSrcList ) */ #if !defined(SQLITE_OMIT_TRIGGER) || !defined(SQLITE_OMIT_UPSERT) - /* If we have not already resolved the name, then maybe + /* If we have not already resolved the name, then maybe ** it is a new.* or old.* trigger argument reference. Or ** maybe it is an excluded.* from an upsert. Or maybe it is ** a reference in the RETURNING clause to a table being modified. @@ -492,7 +519,7 @@ } #endif /* SQLITE_OMIT_UPSERT */ - if( pTab ){ + if( pTab ){ int iCol; u8 hCol = sqlite3StrIHash(zCol); pSchema = pTab->pSchema; @@ -569,10 +596,10 @@ && pMatch && (pNC->ncFlags & (NC_IdxExpr|NC_GenCol))==0 && sqlite3IsRowid(zCol) - && ALWAYS(VisibleRowid(pMatch->pTab)) + && ALWAYS(VisibleRowid(pMatch->pTab) || pMatch->fg.isNestedFrom) ){ cnt = 1; - pExpr->iColumn = -1; + if( pMatch->fg.isNestedFrom==0 ) pExpr->iColumn = -1; pExpr->affExpr = SQLITE_AFF_INTEGER; } @@ -633,7 +660,7 @@ } goto lookupname_end; } - } + } } /* Advance to the next name context. The loop will exit when either @@ -824,7 +851,7 @@ ** ** static void notValid( ** Parse *pParse, // Leave error message here -** NameContext *pNC, // The name context +** NameContext *pNC, // The name context ** const char *zMsg, // Type of error ** int validMask, // Set of contexts for which prohibited ** Expr *pExpr // Invalidate this expression on error @@ -905,7 +932,7 @@ /* The special operator TK_ROW means use the rowid for the first ** column in the FROM clause. This is used by the LIMIT and ORDER BY - ** clause processing on UPDATE and DELETE statements, and by + ** clause processing on UPDATE and DELETE statements, and by ** UPDATE ... FROM statement processing. */ case TK_ROW: { @@ -941,7 +968,7 @@ int anRef[8]; NameContext *p; int i; - for(i=0, p=pNC; p && ipNext, i++){ + for(i=0, p=pNC; p && ipNext, i++){ anRef[i] = p->nRef; } sqlite3WalkExpr(pWalker, pExpr->pLeft); @@ -966,7 +993,7 @@ ** Or a database, table and column: ID.ID.ID ** ** The TK_ID and TK_OUT cases are combined so that there will only - ** be one call to lookupName(). Then the compiler will in-line + ** be one call to lookupName(). Then the compiler will in-line ** lookupName() for a size reduction and performance increase. */ case TK_ID: @@ -1025,6 +1052,7 @@ Window *pWin = (IsWindowFunc(pExpr) ? pExpr->y.pWin : 0); #endif assert( !ExprHasProperty(pExpr, EP_xIsSelect|EP_IntValue) ); + assert( pExpr->pLeft==0 || pExpr->pLeft->op==TK_ORDER ); zId = pExpr->u.zToken; pDef = sqlite3FindFunction(pParse->db, zId, n, enc, 0); if( pDef==0 ){ @@ -1057,7 +1085,7 @@ ** to likelihood(X,0.9375). */ /* TUNING: unlikely() probability is 0.0625. likely() is 0.9375 */ pExpr->iTable = pDef->zName[0]=='u' ? 8388608 : 125829120; - } + } } #ifndef SQLITE_OMIT_AUTHORIZATION { @@ -1119,11 +1147,11 @@ || (pDef->xValue && pDef->xInverse && pDef->xSFunc && pDef->xFinalize) ); if( pDef && pDef->xValue==0 && pWin ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "%#T() may not be used as a window function", pExpr ); pNC->nNcErr++; - }else if( + }else if( (is_agg && (pNC->ncFlags & NC_AllowAgg)==0) || (is_agg && (pDef->funcFlags&SQLITE_FUNC_WINDOW) && !pWin) || (is_agg && pWin && (pNC->ncFlags & NC_AllowWin)==0) @@ -1159,13 +1187,17 @@ } #ifndef SQLITE_OMIT_WINDOWFUNC else if( is_agg==0 && ExprHasProperty(pExpr, EP_WinFunc) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "FILTER may not be used with non-aggregate %#T()", pExpr ); pNC->nNcErr++; } #endif + else if( is_agg==0 && pExpr->pLeft ){ + sqlite3ExprOrderByAggregateError(pParse, pExpr); + pNC->nNcErr++; + } if( is_agg ){ /* Window functions may not be arguments of aggregate functions. ** Or arguments of other window functions. But aggregate functions @@ -1184,6 +1216,11 @@ #endif sqlite3WalkExprList(pWalker, pList); if( is_agg ){ + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3WalkExprList(pWalker, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ Select *pSel = pNC->pWinSelect; @@ -1209,7 +1246,7 @@ } #endif pNC2 = pNC; - while( pNC2 + while( pNC2 && sqlite3ReferencesSrcList(pParse, pExpr, pNC2->pSrcList)==0 ){ pExpr->op2++; @@ -1221,7 +1258,7 @@ assert( SQLITE_FUNC_ANYORDER==NC_OrderAgg ); testcase( (pDef->funcFlags & SQLITE_FUNC_MINMAX)!=0 ); testcase( (pDef->funcFlags & SQLITE_FUNC_ANYORDER)!=0 ); - pNC2->ncFlags |= NC_HasAgg + pNC2->ncFlags |= NC_HasAgg | ((pDef->funcFlags^SQLITE_FUNC_ANYORDER) & (SQLITE_FUNC_MINMAX|SQLITE_FUNC_ANYORDER)); } @@ -1229,7 +1266,7 @@ pNC->ncFlags |= savedAllowFlags; } /* FIX ME: Compute pExpr->affinity based on the expected return - ** type of the function + ** type of the function */ return WRC_Prune; } @@ -1318,7 +1355,7 @@ sqlite3ErrorMsg(pParse, "row value misused"); sqlite3RecordErrorOffsetOfExpr(pParse->db, pExpr); } - break; + break; } } assert( pParse->db->mallocFailed==0 || pParse->nErr!=0 ); @@ -1433,7 +1470,7 @@ int mx, /* Largest permissible value of i */ Expr *pError /* Associate the error with the expression */ ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "%r %s BY term out of range - should be " "between 1 and %d", i, zType, mx); sqlite3RecordErrorOffsetOfExpr(pParse->db, pError); @@ -1499,7 +1536,7 @@ iCol = resolveAsName(pParse, pEList, pE); if( iCol==0 ){ /* Now test if expression pE matches one of the values returned - ** by pSelect. In the usual case this is done by duplicating the + ** by pSelect. In the usual case this is done by duplicating the ** expression, resolving any symbols in it, and then comparing ** it against each expression returned by the SELECT statement. ** Once the comparisons are finished, the duplicate expression @@ -1694,7 +1731,7 @@ } for(j=0; jpEList->nExpr; j++){ if( sqlite3ExprCompare(0, pE, pSelect->pEList->a[j].pExpr, -1)==0 ){ - /* Since this expresion is being changed into a reference + /* 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); @@ -1718,7 +1755,7 @@ ExprList *pGroupBy; /* The GROUP BY clause */ Select *pLeftmost; /* Left-most of SELECT of a compound */ sqlite3 *db; /* Database connection */ - + assert( p!=0 ); if( p->selFlags & SF_Resolved ){ @@ -1747,10 +1784,8 @@ while( p ){ assert( (p->selFlags & SF_Expanded)!=0 ); assert( (p->selFlags & SF_Resolved)==0 ); - assert( db->suppressErr==0 ); /* SF_Resolved not set if errors suppressed */ p->selFlags |= SF_Resolved; - /* Resolve the expressions in the LIMIT and OFFSET clauses. These ** are not allowed to refer to any names, so pass an empty NameContext. */ @@ -1774,7 +1809,7 @@ pSub->pOrderBy = p->pOrderBy; p->pOrderBy = 0; } - + /* Recursively resolve names in all subqueries in the FROM clause */ for(i=0; ipSrc->nSrc; i++){ @@ -1801,19 +1836,19 @@ } } } - + /* Set up the local name-context to pass to sqlite3ResolveExprNames() to ** resolve the result-set expression list. */ sNC.ncFlags = NC_AllowAgg|NC_AllowWin; sNC.pSrcList = p->pSrc; sNC.pNext = pOuterNC; - + /* Resolve names in the result set. */ if( sqlite3ResolveExprListNames(&sNC, p->pEList) ) return WRC_Abort; sNC.ncFlags &= ~NC_AllowWin; - - /* If there are no aggregate functions in the result-set, and no GROUP BY + + /* If there are no aggregate functions in the result-set, and no GROUP BY ** expression, do not allow aggregates in any of the other expressions. */ assert( (p->selFlags & SF_Aggregate)==0 ); @@ -1825,7 +1860,7 @@ }else{ sNC.ncFlags &= ~NC_AllowAgg; } - + /* Add the output column list to the name-context before parsing the ** other expressions in the SELECT statement. This is so that ** expressions in the WHERE clause (etc.) can refer to expressions by @@ -1850,7 +1885,7 @@ for(i=0; ipSrc->nSrc; i++){ SrcItem *pItem = &p->pSrc->a[i]; if( pItem->fg.isTabFunc - && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) + && sqlite3ResolveExprListNames(&sNC, pItem->u1.pFuncArg) ){ return WRC_Abort; } @@ -1870,12 +1905,12 @@ #endif /* The ORDER BY and GROUP BY clauses may not refer to terms in - ** outer queries + ** outer queries */ sNC.pNext = 0; sNC.ncFlags |= NC_AllowAgg|NC_AllowWin; - /* If this is a converted compound query, move the ORDER BY clause from + /* If this is a converted compound query, move the ORDER BY clause from ** the sub-query back to the parent query. At this point each term ** within the ORDER BY clause has been transformed to an integer value. ** These integers will be replaced by copies of the corresponding result @@ -1906,13 +1941,13 @@ return WRC_Abort; } sNC.ncFlags &= ~NC_AllowWin; - - /* Resolve the GROUP BY clause. At the same time, make sure + + /* Resolve the GROUP BY clause. At the same time, make sure ** the GROUP BY clause does not contain aggregate functions. */ if( pGroupBy ){ struct ExprList_item *pItem; - + if( resolveOrderGroupBy(&sNC, p, pGroupBy, "GROUP") || db->mallocFailed ){ return WRC_Abort; } @@ -1954,7 +1989,7 @@ ** checking on function usage and set a flag if any aggregate functions ** are seen. ** -** To resolve table columns references we look for nodes (or subtrees) of the +** To resolve table columns references we look for nodes (or subtrees) of the ** form X.Y.Z or Y.Z or just Z where ** ** X: The name of a database. Ex: "main" or "temp" or @@ -1986,7 +2021,7 @@ ** ** SELECT a+b AS x, c+d AS y FROM t1 ORDER BY a+b; ** -** Function calls are checked to make sure that the function is +** Function calls are checked to make sure that the function is ** defined and that the correct number of arguments are specified. ** If the function is an aggregate function, then the NC_HasAgg flag is ** set and the opcode is changed from TK_FUNCTION to TK_AGG_FUNCTION. @@ -1996,7 +2031,7 @@ ** An error message is left in pParse if anything is amiss. The number ** if errors is returned. */ -int sqlite3ResolveExprNames( +int sqlite3ResolveExprNames( NameContext *pNC, /* Namespace to resolve expressions in. */ Expr *pExpr /* The expression to be analyzed. */ ){ @@ -2017,7 +2052,8 @@ return SQLITE_ERROR; } #endif - sqlite3WalkExpr(&w, pExpr); + assert( pExpr!=0 ); + sqlite3WalkExprNN(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight -= pExpr->nHeight; #endif @@ -2035,7 +2071,7 @@ ** just like sqlite3ResolveExprNames() except that it works for an expression ** list rather than a single expression. */ -int sqlite3ResolveExprListNames( +int sqlite3ResolveExprListNames( NameContext *pNC, /* Namespace to resolve expressions in. */ ExprList *pList /* The expression list to be analyzed. */ ){ @@ -2059,7 +2095,7 @@ return WRC_Abort; } #endif - sqlite3WalkExpr(&w, pExpr); + sqlite3WalkExprNN(&w, pExpr); #if SQLITE_MAX_EXPR_DEPTH>0 w.pParse->nHeight -= pExpr->nHeight; #endif @@ -2081,7 +2117,7 @@ /* ** Resolve all names in all expressions of a SELECT and in all -** decendents of the SELECT, including compounds off of p->pPrior, +** descendants of the SELECT, including compounds off of p->pPrior, ** subqueries in expressions, and subqueries used as FROM clause ** terms. ** diff -Nru sqlite3-3.42.0/src/rowset.c sqlite3-3.44.0-0/src/rowset.c --- sqlite3-3.42.0/src/rowset.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/rowset.c 2023-11-04 14:23:58.000000000 +0000 @@ -35,14 +35,14 @@ ** extracts the least value from the RowSet. ** ** The INSERT primitive might allocate additional memory. Memory is -** allocated in chunks so most INSERTs do no allocation. There is an +** 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 nubmer, then the +** 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. @@ -83,7 +83,7 @@ ** in the list, pLeft points to the tree, and v is unused. The ** RowSet.pForest value points to the head of this forest list. */ -struct RowSetEntry { +struct RowSetEntry { i64 v; /* ROWID value for this entry */ struct RowSetEntry *pRight; /* Right subtree (larger entries) or list */ struct RowSetEntry *pLeft; /* Left subtree (smaller entries) */ @@ -235,7 +235,7 @@ /* ** Merge two lists of RowSetEntry objects. Remove duplicates. ** -** The input lists are connected via pRight pointers and are +** The input lists are connected via pRight pointers and are ** assumed to each already be in sorted order. */ static struct RowSetEntry *rowSetEntryMerge( @@ -272,7 +272,7 @@ /* ** Sort all elements on the list of RowSetEntry objects into order of ** increasing v. -*/ +*/ static struct RowSetEntry *rowSetEntrySort(struct RowSetEntry *pIn){ unsigned int i; struct RowSetEntry *pNext, *aBucket[40]; @@ -345,7 +345,7 @@ struct RowSetEntry *pLeft; /* Left subtree */ if( *ppList==0 ){ /*OPTIMIZATION-IF-TRUE*/ /* Prevent unnecessary deep recursion when we run out of entries */ - return 0; + return 0; } if( iDepth>1 ){ /*OPTIMIZATION-IF-TRUE*/ /* This branch causes a *balanced* tree to be generated. A valid tree diff -Nru sqlite3-3.42.0/src/select.c sqlite3-3.44.0-0/src/select.c --- sqlite3-3.42.0/src/select.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/select.c 2023-11-04 14:23:58.000000000 +0000 @@ -231,8 +231,8 @@ ** NATURAL FULL - JT_NATURAL|JT_LEFT|JT_RIGHT ** NATURAL FULL OUTER JT_NATRUAL|JT_LEFT|JT_RIGHT ** -** To preserve historical compatibly, SQLite also accepts a variety -** of other non-standard and in many cases non-sensical join types. +** To preserve historical compatibly, SQLite also accepts a variety +** of other non-standard and in many cases nonsensical join types. ** This routine makes as much sense at it can from the nonsense join ** type and returns a result. Examples of accepted nonsense join types ** include but are not limited to: @@ -282,7 +282,7 @@ for(i=0; i<3 && apAll[i]; i++){ p = apAll[i]; for(j=0; jn==aKeyword[j].nChar + if( p->n==aKeyword[j].nChar && sqlite3StrNICmp((char*)p->z, &zKeyText[aKeyword[j].i], p->n)==0 ){ jointype |= aKeyword[j].code; break; @@ -368,7 +368,7 @@ for(i=iStart; i<=iEnd; i++){ iCol = sqlite3ColumnIndex(pSrc->a[i].pTab, zCol); - if( iCol>=0 + if( iCol>=0 && (bIgnoreHidden==0 || IsHiddenColumn(&pSrc->a[i].pTab->aCol[iCol])==0) ){ if( piTab ){ @@ -426,7 +426,7 @@ } sqlite3SetJoinExpr(p->pLeft, iTable, joinFlag); p = p->pRight; - } + } } /* Undo the work of sqlite3SetJoinExpr(). This is used when a LEFT JOIN @@ -454,6 +454,7 @@ } if( p->op==TK_FUNCTION ){ assert( ExprUseXList(p) ); + assert( p->pLeft==0 ); if( p->x.pList ){ int i; for(i=0; ix.pList->nExpr; i++){ @@ -463,7 +464,7 @@ } unsetJoinExpr(p->pLeft, iTable, nullable); p = p->pRight; - } + } } /* @@ -503,7 +504,7 @@ if( NEVER(pLeft->pTab==0 || pRightTab==0) ) continue; joinType = (pRight->fg.jointype & JT_OUTER)!=0 ? EP_OuterON : EP_InnerON; - /* If this is a NATURAL join, synthesize an approprate USING clause + /* If this is a NATURAL join, synthesize an appropriate USING clause ** to specify which columns should be joined. */ if( pRight->fg.jointype & JT_NATURAL ){ @@ -536,7 +537,7 @@ } /* Create extra terms on the WHERE clause for each column named - ** in the USING clause. Example: If the two tables to be joined are + ** in the USING clause. Example: If the two tables to be joined are ** A and B and the USING clause names X, Y, and Z, then add this ** to the WHERE clause: A.X=B.X AND A.Y=B.Y AND A.Z=B.Z ** Report an error if any column mentioned in the USING clause is @@ -718,8 +719,8 @@ ** case regData==regOrigData. ** (3) Some output columns are omitted from the sort record due to ** the SQLITE_ENABLE_SORTER_REFERENCES optimization, or due to the - ** SQLITE_ECEL_OMITREF optimization, or due to the - ** SortCtx.pDeferredRowLoad optimiation. In any of these cases + ** 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. */ @@ -760,7 +761,7 @@ pParse->nMem += pSort->nOBSat; nKey = nExpr - pSort->nOBSat + bSeq; if( bSeq ){ - addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); + addrFirst = sqlite3VdbeAddOp1(v, OP_IfNot, regBase+nExpr); }else{ addrFirst = sqlite3VdbeAddOp1(v, OP_SequenceTest, pSort->iECursor); } @@ -775,7 +776,7 @@ testcase( pKI->nAllField > pKI->nKeyField+2 ); pOp->p4.pKeyInfo = sqlite3KeyInfoFromExprList(pParse,pSort->pOrderBy,nOBSat, pKI->nAllField-pKI->nKeyField-1); - pOp = 0; /* Ensure pOp not used after sqltie3VdbeAddOp3() */ + pOp = 0; /* Ensure pOp not used after sqlite3VdbeAddOp3() */ addrJmp = sqlite3VdbeCurrentAddr(v); sqlite3VdbeAddOp3(v, OP_Jump, addrJmp+1, 0, addrJmp+1); VdbeCoverage(v); pSort->labelBkOut = sqlite3VdbeMakeLabel(pParse); @@ -794,10 +795,10 @@ /* At this point the values for the new sorter entry are stored ** in an array of registers. They need to be composed into a record ** and inserted into the sorter if either (a) there are currently - ** less than LIMIT+OFFSET items or (b) the new record is smaller than + ** less than LIMIT+OFFSET items or (b) the new record is smaller than ** the largest record currently in the sorter. If (b) is true and there ** are already LIMIT+OFFSET items in the sorter, delete the largest - ** entry before inserting the new one. This way there are never more + ** entry before inserting the new one. This way there are never more ** than LIMIT+OFFSET items in the sorter. ** ** If the new record does not need to be inserted into the sorter, @@ -869,7 +870,7 @@ ** The returned value in this case is a copy of parameter iTab. ** ** WHERE_DISTINCT_ORDERED: -** In this case rows are being delivered sorted order. The ephermal +** In this case rows are being delivered sorted order. The ephemeral ** table is not required. Instead, the current set of values ** is compared against previous row. If they match, the new row ** is not distinct and control jumps to VM address addrRepeat. Otherwise, @@ -885,10 +886,10 @@ ** In this case it has already been determined that the rows are distinct. ** No special action is required. The return value is zero. ** -** Parameter pEList is the list of expressions used to generated the -** contents of each row. It is used by this routine to determine (a) -** how many elements there are in the array of registers and (b) the -** collation sequences that should be used for the comparisons if +** Parameter pEList is the list of expressions used to generated the +** contents of each row. It is used by this routine to determine (a) +** how many elements there are in the array of registers and (b) the +** collation sequences that should be used for the comparisons if ** eTnctType is WHERE_DISTINCT_ORDERED. */ static int codeDistinct( @@ -990,7 +991,7 @@ sqlite3VdbeChangeToNoop(v, iOpenEphAddr+1); } if( eTnctType==WHERE_DISTINCT_ORDERED ){ - /* Change the OP_OpenEphemeral to an OP_Null that sets the MEM_Cleared + /* Change the OP_OpenEphemeral to an OP_Null that sets the MEM_Cleared ** bit on the first register of the previous value. This will cause the ** OP_Ne added in codeDistinct() to always fail on the first iteration of ** the loop even if the first row is all NULLs. */ @@ -1005,8 +1006,8 @@ #ifdef SQLITE_ENABLE_SORTER_REFERENCES /* ** This function is called as part of inner-loop generation for a SELECT -** statement with an ORDER BY that is not optimized by an index. It -** determines the expressions, if any, that the sorter-reference +** statement with an ORDER BY that is not optimized by an index. It +** determines the expressions, if any, that the sorter-reference ** optimization should be used for. The sorter-reference optimization ** is used for SELECT queries like: ** @@ -1016,11 +1017,11 @@ ** storing values read from that column in the sorter records, the PK of ** the row from table t1 is stored instead. Then, as records are extracted from ** the sorter to return to the user, the required value of bigblob is -** retrieved directly from table t1. If the values are very large, this +** retrieved directly from table t1. If the values are very large, this ** can be more efficient than storing them directly in the sorter records. ** -** The ExprList_item.fg.bSorterRef flag is set for each expression in pEList -** for which the sorter-reference optimization should be enabled. +** The ExprList_item.fg.bSorterRef flag is set for each expression in pEList +** for which the sorter-reference optimization should be enabled. ** Additionally, the pSort->aDefer[] array is populated with entries ** for all cursors required to evaluate all selected expressions. Finally. ** output variable (*ppExtra) is set to an expression list containing @@ -1094,7 +1095,7 @@ ** ** If srcTab is negative, then the p->pEList expressions ** are evaluated in order to get the data for this row. If srcTab is -** zero or more, then data is pulled from srcTab and p->pEList is used only +** zero or more, then data is pulled from srcTab and p->pEList is used only ** to get the number of columns and the collation sequence for each column. */ static void selectInnerLoop( @@ -1176,8 +1177,8 @@ } if( pSort && hasDistinct==0 && eDest!=SRT_EphemTab && eDest!=SRT_Table ){ /* For each expression in p->pEList that is a copy of an expression in - ** the ORDER BY clause (pSort->pOrderBy), set the associated - ** iOrderByCol value to one more than the index of the ORDER BY + ** the ORDER BY clause (pSort->pOrderBy), set the associated + ** iOrderByCol value to one more than the index of the ORDER BY ** expression within the sort-key that pushOntoSorter() will generate. ** This allows the p->pEList field to be omitted from the sorted record, ** saving space and CPU cycles. */ @@ -1193,7 +1194,7 @@ selectExprDefer(pParse, pSort, p->pEList, &pExtra); if( pExtra && pParse->db->mallocFailed==0 ){ /* If there are any extra PK columns to add to the sorter records, - ** allocate extra memory cells and adjust the OpenEphemeral + ** allocate extra memory cells and adjust the OpenEphemeral ** instruction to account for the larger records. This is only ** required if there are one or more WITHOUT ROWID tables with ** composite primary keys in the SortCtx.aDefer[] array. */ @@ -1223,7 +1224,7 @@ testcase( eDest==SRT_Mem ); testcase( eDest==SRT_Coroutine ); testcase( eDest==SRT_Output ); - assert( eDest==SRT_Set || eDest==SRT_Mem + assert( eDest==SRT_Set || eDest==SRT_Mem || eDest==SRT_Coroutine || eDest==SRT_Output || eDest==SRT_Upfrom ); } @@ -1235,7 +1236,7 @@ if( pExtra ) nResultCol += pExtra->nExpr; #endif if( p->iLimit - && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 + && (ecelFlags & SQLITE_ECEL_OMITREF)!=0 && nPrefixReg>0 ){ assert( pSort!=0 ); @@ -1298,6 +1299,16 @@ testcase( eDest==SRT_Fifo ); testcase( eDest==SRT_DistFifo ); sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nResultCol, r1+nPrefixReg); +#if !defined(SQLITE_ENABLE_NULL_TRIM) && defined(SQLITE_DEBUG) + /* A destination of SRT_Table and a non-zero iSDParm2 parameter means + ** that this is an "UPDATE ... FROM" on a virtual table or view. In this + ** case set the p5 parameter of the OP_MakeRecord to OPFLAG_NOCHNG_MAGIC. + ** This does not affect operation in any way - it just allows MakeRecord + ** to process OPFLAG_NOCHANGE values without an assert() failing. */ + if( eDest==SRT_Table && pDest->iSDParm2 ){ + sqlite3VdbeChangeP5(v, OPFLAG_NOCHNG_MAGIC); + } +#endif #ifndef SQLITE_OMIT_CTE if( eDest==SRT_DistFifo ){ /* If the destination is DistFifo, then cursor (iParm+1) is open @@ -1366,7 +1377,7 @@ }else{ int r1 = sqlite3GetTempReg(pParse); assert( sqlite3Strlen30(pDest->zAffSdst)==nResultCol ); - sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, + sqlite3VdbeAddOp4(v, OP_MakeRecord, regResult, nResultCol, r1, pDest->zAffSdst, nResultCol); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, iParm, r1, regResult, nResultCol); sqlite3ReleaseTempReg(pParse, r1); @@ -1384,7 +1395,7 @@ } /* If this is a scalar select that is part of an expression, then - ** store the results in the appropriate memory cell or array of + ** store the results in the appropriate memory cell or array of ** memory cells and break out of the scan loop. */ case SRT_Mem: { @@ -1439,7 +1450,7 @@ /* If the destination is DistQueue, then cursor (iParm+1) is open ** on a second ephemeral index that holds all values every previously ** added to the queue. */ - addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, + addrTest = sqlite3VdbeAddOp4Int(v, OP_Found, iParm+1, 0, regResult, nResultCol); VdbeCoverage(v); } @@ -1659,7 +1670,7 @@ int addrExplain; /* Address of OP_Explain instruction */ #endif - ExplainQueryPlan2(addrExplain, (pParse, 0, + ExplainQueryPlan2(addrExplain, (pParse, 0, "USE TEMP B-TREE FOR %sORDER BY", pSort->nOBSat>0?"RIGHT PART OF ":"") ); sqlite3VdbeScanStatusRange(v, addrExplain,pSort->addrPush,pSort->addrPushEnd); @@ -1706,7 +1717,7 @@ if( pSort->labelBkOut ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } - sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, + sqlite3VdbeAddOp3(v, OP_OpenPseudo, iSortTab, regSortOut, nKey+1+nColumn+nRefKey); if( addrOnce ) sqlite3VdbeJumpHere(v, addrOnce); addr = 1 + sqlite3VdbeAddOp2(v, OP_SorterSort, iTab, addrBreak); @@ -1742,7 +1753,7 @@ sqlite3VdbeAddOp1(v, OP_NullRow, iCsr); if( HasRowid(pTab) ){ sqlite3VdbeAddOp3(v, OP_Column, iSortTab, iKey++, regKey); - sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, + sqlite3VdbeAddOp3(v, OP_SeekRowid, iCsr, sqlite3VdbeCurrentAddr(v)+1, regKey); }else{ int k; @@ -1812,7 +1823,7 @@ break; } default: { - assert( eDest==SRT_Output || eDest==SRT_Coroutine ); + assert( eDest==SRT_Output || eDest==SRT_Coroutine ); testcase( eDest==SRT_Output ); testcase( eDest==SRT_Coroutine ); if( eDest==SRT_Output ){ @@ -1852,14 +1863,14 @@ ** original CREATE TABLE statement if the expression is a column. The ** declaration type for a ROWID field is INTEGER. Exactly when an expression ** is considered a column can be complex in the presence of subqueries. The -** result-set expression in all of the following SELECT statements is +** result-set expression in all of the following SELECT statements is ** considered a column by this function. ** ** SELECT col FROM tbl; ** SELECT (SELECT col FROM tbl; ** SELECT (SELECT col FROM tbl); ** SELECT abc FROM (SELECT col AS abc FROM tbl); -** +** ** The declaration type for any expression other than a column is NULL. ** ** This routine has either 3 or 6 parameters depending on whether or not @@ -1871,7 +1882,7 @@ # define columnType(A,B,C,D,E) columnTypeImpl(A,B) #endif static const char *columnTypeImpl( - NameContext *pNC, + NameContext *pNC, #ifndef SQLITE_ENABLE_COLUMN_METADATA Expr *pExpr #else @@ -1914,19 +1925,19 @@ if( pTab==0 ){ /* At one time, code such as "SELECT new.x" within a trigger would ** cause this condition to run. Since then, we have restructured how - ** trigger code is generated and so this condition is no longer + ** trigger code is generated and so this condition is no longer ** possible. However, it can still be true for statements like ** the following: ** ** CREATE TABLE t1(col INTEGER); ** SELECT (SELECT t1.col) FROM FROM t1; ** - ** when columnType() is called on the expression "t1.col" in the + ** when columnType() is called on the expression "t1.col" in the ** sub-select. In this case, set the column type to NULL, even ** though it should really be "INTEGER". ** ** This is not a problem, as the column type of "t1.col" is never - ** used. When columnType() is called on the expression + ** used. When columnType() is called on the expression ** "(SELECT t1.col)", the correct type is returned (see the TK_SELECT ** branch below. */ break; @@ -1944,9 +1955,9 @@ #else && ALWAYS(iCol>=0) #endif - ){ + ){ /* If iCol is less than zero, then the expression requests the - ** rowid of the sub-select or view. This expression is legal (see + ** rowid of the sub-select or view. This expression is legal (see ** test case misc2.2.2) - it always evaluates to NULL. */ NameContext sNC; @@ -1954,7 +1965,7 @@ sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol); + zType = columnType(&sNC, p,&zOrigDb,&zOrigTab,&zOrigCol); } }else{ /* A real table or a CTE table */ @@ -2000,13 +2011,13 @@ sNC.pSrcList = pS->pSrc; sNC.pNext = pNC; sNC.pParse = pNC->pParse; - zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); + zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); break; } #endif } -#ifdef SQLITE_ENABLE_COLUMN_METADATA +#ifdef SQLITE_ENABLE_COLUMN_METADATA if( pzOrigDb ){ assert( pzOrigTab && pzOrigCol ); *pzOrigDb = zOrigDb; @@ -2042,7 +2053,7 @@ const char *zOrigCol = 0; zType = columnType(&sNC, p, &zOrigDb, &zOrigTab, &zOrigCol); - /* The vdbe must make its own copy of the column-type and other + /* The vdbe must make its own copy of the column-type and other ** column specific strings, in case the schema is reset before this ** virtual machine is deleted. */ @@ -2101,13 +2112,6 @@ int fullName; /* TABLE.COLUMN if no AS clause and is a direct table ref */ int srcName; /* COLUMN or TABLE.COLUMN if no AS clause and is direct */ -#ifndef SQLITE_OMIT_EXPLAIN - /* If this is an EXPLAIN, skip this step */ - if( pParse->explain ){ - return; - } -#endif - if( pParse->colNamesSet ) return; /* Column names are determined by the left-most term of a compound select */ while( pSelect->pPrior ) pSelect = pSelect->pPrior; @@ -2294,7 +2298,7 @@ ** kind (maybe a parenthesized subquery in the FROM clause of a larger ** query, or a VIEW, or a CTE). This routine computes type information ** for that Table object based on the Select object that implements the -** subquery. For the purposes of this routine, "type infomation" means: +** subquery. For the purposes of this routine, "type information" means: ** ** * The datatype name, as it might appear in a CREATE TABLE statement ** * Which collating sequence to use for the column @@ -2438,9 +2442,9 @@ ** Compute the iLimit and iOffset fields of the SELECT based on the ** pLimit expressions. pLimit->pLeft and pLimit->pRight hold the expressions ** that appear in the original SQL statement after the LIMIT and OFFSET -** keywords. Or NULL if those keywords are omitted. iLimit and iOffset -** are the integer memory register numbers for counters used to compute -** the limit and offset. If there is no limit and/or offset, then +** keywords. Or NULL if those keywords are omitted. iLimit and iOffset +** are the integer memory register numbers for counters used to compute +** the limit and offset. If there is no limit and/or offset, then ** iLimit and iOffset are negative. ** ** This routine changes the values of iLimit and iOffset only if @@ -2466,7 +2470,7 @@ if( p->iLimit ) return; - /* + /* ** "LIMIT -1" always shows all rows. There is some ** controversy about what the correct behavior should be. ** The current implementation interprets "LIMIT 0" to mean @@ -2594,7 +2598,7 @@ ** inserted into the Queue table. The iDistinct table keeps a copy of all rows ** that have ever been inserted into Queue and causes duplicates to be ** discarded. If the operator is UNION ALL, then duplicates are allowed. -** +** ** If the query has an ORDER BY, then entries in the Queue table are kept in ** ORDER BY order and the first entry is extracted for each cycle. Without ** an ORDER BY, the Queue table is just a FIFO. @@ -2623,7 +2627,7 @@ 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 targetting the Queue table */ + SelectDest destQueue; /* SelectDest targeting the Queue table */ int i; /* Loop counter */ int rc; /* Result code */ ExprList *pOrderBy; /* The ORDER BY clause */ @@ -2831,7 +2835,7 @@ ** ** "p" points to the right-most of the two queries. the query on the ** left is p->pPrior. The left query could also be a compound query -** in which case this routine will be called recursively. +** in which case this routine will be called recursively. ** ** The results of the total query are to be written into a destination ** of type eDest with parameter iParm. @@ -2959,7 +2963,7 @@ p->nSelectRow = sqlite3LogEstAdd(p->nSelectRow, pPrior->nSelectRow); if( p->pLimit && sqlite3ExprIsInteger(p->pLimit->pLeft, &nLimit) - && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) + && nLimit>0 && p->nSelectRow > sqlite3LogEst((u64)nLimit) ){ p->nSelectRow = sqlite3LogEst((u64)nLimit); } @@ -2976,7 +2980,7 @@ Expr *pLimit; /* Saved values of p->nLimit */ int addr; SelectDest uniondest; - + testcase( p->op==TK_EXCEPT ); testcase( p->op==TK_UNION ); priorOp = SRT_Union; @@ -2998,8 +3002,8 @@ findRightmost(p)->selFlags |= SF_UsesEphemeral; assert( p->pEList ); } - - + + /* Code the SELECT statements to our left */ assert( !pPrior->pOrderBy ); @@ -3009,7 +3013,7 @@ if( rc ){ goto multi_select_end; } - + /* Code the current SELECT statement */ if( p->op==TK_EXCEPT ){ @@ -3038,7 +3042,7 @@ p->pLimit = pLimit; p->iLimit = 0; p->iOffset = 0; - + /* Convert the data in the temporary table into whatever form ** it is that we currently need. */ @@ -3067,7 +3071,7 @@ int addr; SelectDest intersectdest; int r1; - + /* INTERSECT is different from the others since it requires ** two temporary tables. Hence it has its own case. Begin ** by allocating the tables we will need. @@ -3075,13 +3079,13 @@ tab1 = pParse->nTab++; tab2 = pParse->nTab++; assert( p->pOrderBy==0 ); - + addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0); assert( p->addrOpenEphm[0] == -1 ); p->addrOpenEphm[0] = addr; findRightmost(p)->selFlags |= SF_UsesEphemeral; assert( p->pEList ); - + /* Code the SELECTs to our left into temporary table "tab1". */ sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1); @@ -3090,7 +3094,7 @@ if( rc ){ goto multi_select_end; } - + /* Code the current SELECT into temporary table "tab2" */ addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab2, 0); @@ -3112,7 +3116,7 @@ } sqlite3ExprDelete(db, p->pLimit); p->pLimit = pLimit; - + /* Generate code to take the intersection of the two temporary ** tables. */ @@ -3137,7 +3141,7 @@ break; } } - + #ifndef SQLITE_OMIT_EXPLAIN if( p->pNext==0 ){ ExplainQueryPlanPop(pParse); @@ -3145,8 +3149,8 @@ #endif } if( pParse->nErr ) goto multi_select_end; - - /* Compute collating sequences used by + + /* Compute collating sequences used by ** temporary tables needed to implement the compound select. ** Attach the KeyInfo structure to all temporary tables. ** @@ -3223,7 +3227,7 @@ /* ** Code an output subroutine for a coroutine implementation of a -** SELECT statment. +** 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 @@ -3258,7 +3262,7 @@ addr = sqlite3VdbeCurrentAddr(v); iContinue = sqlite3VdbeMakeLabel(pParse); - /* Suppress duplicates for UNION, EXCEPT, and INTERSECT + /* Suppress duplicates for UNION, EXCEPT, and INTERSECT */ if( regPrev ){ int addr1, addr2; @@ -3300,7 +3304,7 @@ int r1; testcase( pIn->nSdst>1 ); r1 = sqlite3GetTempReg(pParse); - sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, + sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iSdst, pIn->nSdst, r1, pDest->zAffSdst, pIn->nSdst); sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pDest->iSDParm, r1, pIn->iSdst, pIn->nSdst); @@ -3338,7 +3342,7 @@ ** SRT_Output. This routine is never called with any other ** destination other than the ones handled above or SRT_Output. ** - ** For SRT_Output, results are stored in a sequence of registers. + ** For SRT_Output, results are stored in a sequence of registers. ** Then the OP_ResultRow opcode is used to cause sqlite3_step() to ** return the next row of result. */ @@ -3395,7 +3399,7 @@ ** ** EofB: Called when data is exhausted from selectB. ** -** The implementation of the latter five subroutines depend on which +** The implementation of the latter five subroutines depend on which ** is used: ** ** @@ -3445,7 +3449,7 @@ ** ** We call AltB, AeqB, AgtB, EofA, and EofB "subroutines" but they are not ** actually called using Gosub and they do not Return. EofA and EofB loop -** until all data is exhausted then jump to the "end" labe. AltB, AeqB, +** until all data is exhausted then jump to the "end" label. AltB, AeqB, ** and AgtB jump to either L2 or to one of EofA or EofB. */ #ifndef SQLITE_OMIT_COMPOUND_SELECT @@ -3482,7 +3486,7 @@ int savedOffset; /* Saved value of p->iOffset */ int labelCmpr; /* Label for the start of the merge algorithm */ int labelEnd; /* Label for the end of the overall SELECT stmt */ - int addr1; /* Jump instructions that get retargetted */ + int addr1; /* Jump instructions that get retargeted */ int op; /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */ KeyInfo *pKeyDup = 0; /* Comparison information for duplicate removal */ KeyInfo *pKeyMerge; /* Comparison information for merging rows */ @@ -3502,7 +3506,7 @@ /* Patch up the ORDER BY clause */ - op = p->op; + op = p->op; assert( p->pPrior->pOrderBy==0 ); pOrderBy = p->pOrderBy; assert( pOrderBy ); @@ -3574,7 +3578,7 @@ } } } - + /* Separate the left and the right query from one another */ nSelect = 1; @@ -3637,7 +3641,7 @@ sqlite3VdbeEndCoroutine(v, regAddrA); sqlite3VdbeJumpHere(v, addr1); - /* Generate a coroutine to evaluate the SELECT statement on + /* Generate a coroutine to evaluate the SELECT statement on ** the right - the "B" select */ addrSelectB = sqlite3VdbeCurrentAddr(v) + 1; @@ -3646,7 +3650,7 @@ savedLimit = p->iLimit; savedOffset = p->iOffset; p->iLimit = regLimitB; - p->iOffset = 0; + p->iOffset = 0; ExplainQueryPlan((pParse, 1, "RIGHT")); sqlite3Select(pParse, p, &destB); p->iLimit = savedLimit; @@ -3660,7 +3664,7 @@ addrOutA = generateOutputSubroutine(pParse, p, &destA, pDest, regOutA, regPrev, pKeyDup, labelEnd); - + /* Generate a subroutine that outputs the current row of the B ** select as the next output row of the compound select. */ @@ -3677,7 +3681,7 @@ */ if( op==TK_EXCEPT || op==TK_INTERSECT ){ addrEofA_noB = addrEofA = labelEnd; - }else{ + }else{ VdbeNoopComment((v, "eof-A subroutine")); addrEofA = sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB); addrEofA_noB = sqlite3VdbeAddOp2(v, OP_Yield, regAddrB, labelEnd); @@ -3692,7 +3696,7 @@ if( op==TK_INTERSECT ){ addrEofB = addrEofA; if( p->nSelectRow > pPrior->nSelectRow ) p->nSelectRow = pPrior->nSelectRow; - }else{ + }else{ VdbeNoopComment((v, "eof-B subroutine")); addrEofB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA); sqlite3VdbeAddOp2(v, OP_Yield, regAddrA, labelEnd); VdbeCoverage(v); @@ -3752,7 +3756,7 @@ /* Make arrangements to free the 2nd and subsequent arms of the compound ** after the parse has finished */ if( pSplit->pPrior ){ - sqlite3ParserAddCleanup(pParse, + sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3SelectDelete, pSplit->pPrior); } pSplit->pPrior = pPrior; @@ -3819,13 +3823,13 @@ /* ** Scan through the expression pExpr. Replace every reference to ** a column in table number iTable with a copy of the iColumn-th -** entry in pEList. (But leave references to the ROWID column +** entry in pEList. (But leave references to the ROWID column ** unchanged.) ** ** This routine is part of the flattening procedure. A subquery ** whose result set is defined by pEList appears as entry in the ** FROM clause of a SELECT such that the VDBE cursor assigned to that -** FORM clause entry is iTable. This routine makes the necessary +** FORM clause entry is iTable. This routine makes the necessary ** changes to pExpr so that it refers directly to the source table ** of the subquery rather the result set of the subquery. */ @@ -3851,11 +3855,14 @@ #endif { Expr *pNew; - int iColumn = pExpr->iColumn; - Expr *pCopy = pSubst->pEList->a[iColumn].pExpr; + int iColumn; + Expr *pCopy; Expr ifNullRow; + iColumn = pExpr->iColumn; + assert( iColumn>=0 ); assert( pSubst->pEList!=0 && iColumnpEList->nExpr ); assert( pExpr->pRight==0 ); + pCopy = pSubst->pEList->a[iColumn].pExpr; if( sqlite3ExprIsVector(pCopy) ){ sqlite3VectorErrorMsg(pSubst->pParse, pCopy); }else{ @@ -4002,7 +4009,7 @@ #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW) /* ** Assign new cursor numbers to each of the items in pSrc. For each -** new cursor number assigned, set an entry in the aCsrMap[] array +** new cursor number assigned, set an entry in the aCsrMap[] array ** to map the old cursor number to the new: ** ** aCsrMap[iOld+1] = iNew; @@ -4064,10 +4071,10 @@ /* ** Assign a new cursor number to each cursor in the FROM clause (Select.pSrc) -** of the SELECT statement passed as the second argument, and to each +** of the SELECT statement passed as the second argument, and to each ** cursor in the FROM clause of any FROM clause sub-selects, recursively. ** Except, do not assign a new cursor number to the iExcept'th element in -** the FROM clause of (*p). Update all expressions and other references +** the FROM clause of (*p). Update all expressions and other references ** to refer to the new cursor numbers. ** ** Argument aCsrMap is an array that may be used for temporary working @@ -4076,8 +4083,8 @@ ** * the array is larger than the largest cursor number used within the ** select statement passed as an argument, and ** -** * the array entries for all cursor numbers that do *not* appear in -** FROM clauses of the select statement as described above are +** * the array entries for all cursor numbers that do *not* appear in +** FROM clauses of the select statement as described above are ** initialized to zero. */ static void renumberCursors( @@ -4159,7 +4166,7 @@ ** SELECT x+y AS a FROM t1 WHERE z<100 AND a>5 ** ** The code generated for this simplification gives the same result -** but only has to scan the data once. And because indices might +** but only has to scan the data once. And because indices might ** exist on the table t1, a complete scan of the data might be ** avoided. ** @@ -4188,7 +4195,7 @@ ** (4) The subquery can not be DISTINCT. ** ** (**) At one point restrictions (4) and (5) defined a subset of DISTINCT -** sub-queries that were excluded from this optimization. Restriction +** sub-queries that were excluded from this optimization. Restriction ** (4) has since been expanded to exclude all DISTINCT subqueries. ** ** (**) We no longer attempt to flatten aggregate subqueries. Was: @@ -4204,8 +4211,8 @@ ** (9) If the subquery uses LIMIT then the outer query may not be aggregate. ** ** (**) Restriction (10) was removed from the code on 2005-02-05 but we -** accidently carried the comment forward until 2014-09-15. Original -** constraint: "If the subquery is aggregate then the outer query +** accidentally carried the comment forward until 2014-09-15. Original +** constraint: "If the subquery is aggregate then the outer query ** may not use LIMIT." ** ** (11) The subquery and the outer query may not both have ORDER BY clauses. @@ -4223,7 +4230,7 @@ ** ** (16) If the outer query is aggregate, then the subquery may not ** use ORDER BY. (Ticket #2942) This used to not matter -** until we introduced the group_concat() function. +** until we introduced the group_concat() function. ** ** (17) If the subquery is a compound select, then ** (17a) all compound operators must be a UNION ALL, and @@ -4278,7 +4285,7 @@ ** recursive queries in multiSelect(). ** ** (**) We no longer attempt to flatten aggregate subqueries. Was: -** The subquery may not be an aggregate that uses the built-in min() or +** The subquery may not be an aggregate that uses the built-in min() or ** or max() functions. (Without this restriction, a query like: ** "SELECT x FROM (SELECT max(y), x FROM t1)" would not necessarily ** return the value X for which Y was maximal.) @@ -4296,7 +4303,8 @@ ** (27b) the subquery is a compound query and the RIGHT JOIN occurs ** in any arm of the compound query. (See also (17g).) ** -** (28) The subquery is not a MATERIALIZED CTE. +** (28) The subquery is not a MATERIALIZED CTE. (This is handled +** in the caller before ever reaching this routine.) ** ** ** In this routine, the "p" parameter is a pointer to the outer query. @@ -4323,7 +4331,7 @@ SrcList *pSubSrc; /* The FROM clause of the subquery */ int iParent; /* VDBE cursor number of the pSub result set temp table */ int iNewParent = -1;/* Replacement table for iParent */ - int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ + int isOuterJoin = 0; /* True if pSub is the right side of a LEFT JOIN */ int i; /* Loop counter */ Expr *pWhere; /* The WHERE clause */ SrcItem *pSubitem; /* The subquery */ @@ -4406,9 +4414,9 @@ if( iFrom>0 && (pSubSrc->a[0].fg.jointype & JT_LTORJ)!=0 ){ return 0; /* Restriction (27a) */ } - if( pSubitem->fg.isCte && pSubitem->u2.pCteUse->eM10d==M10d_Yes ){ - return 0; /* (28) */ - } + + /* Condition (28) is blocked by the caller */ + assert( !pSubitem->fg.isCte || pSubitem->u2.pCteUse->eM10d!=M10d_Yes ); /* Restriction (17): If the sub-query is a compound SELECT, then it must ** use only the UNION ALL operator. And none of the simple select queries @@ -4478,7 +4486,7 @@ testcase( i==SQLITE_DENY ); pParse->zAuthContext = zSavedAuthContext; - /* Delete the transient structures associated with thesubquery */ + /* Delete the transient structures associated with the subquery */ pSub1 = pSubitem->pSelect; sqlite3DbFree(db, pSubitem->zDatabase); sqlite3DbFree(db, pSubitem->zName); @@ -4490,13 +4498,13 @@ assert( pSubitem->fg.isUsing!=0 || pSubitem->u3.pOn==0 ); /* If the sub-query is a compound SELECT statement, then (by restrictions - ** 17 and 18 above) it must be a UNION ALL and the parent query must + ** 17 and 18 above) it must be a UNION ALL and the parent query must ** be of the form: ** - ** SELECT FROM () + ** SELECT FROM () ** ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block - ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or + ** creates N-1 copies of the parent query without any ORDER BY, LIMIT or ** OFFSET clauses and joins them to the left-hand-side of the original ** using UNION ALL operators. In this case N is the number of simple ** select statements in the compound sub-query. @@ -4570,7 +4578,7 @@ Table *pTabToDel = pSubitem->pTab; if( pTabToDel->nTabRef==1 ){ Parse *pToplevel = sqlite3ParseToplevel(pParse); - sqlite3ParserAddCleanup(pToplevel, + sqlite3ParserAddCleanup(pToplevel, (void(*)(sqlite3*,void*))sqlite3DeleteTable, pTabToDel); testcase( pToplevel->earlyCleanup ); @@ -4606,7 +4614,7 @@ if( pParent==p ){ jointype = pSubitem->fg.jointype; /* First time through the loop */ } - + /* The subquery uses a single slot of the FROM clause of the outer ** query. If the subquery has more than one element in its FROM clause, ** then expand the outer query to make space for it to hold all elements @@ -4642,10 +4650,10 @@ } pSrc->a[iFrom].fg.jointype &= JT_LTORJ; pSrc->a[iFrom].fg.jointype |= jointype | ltorj; - - /* Now begin substituting subquery result set expressions for + + /* Now begin substituting subquery result set expressions for ** references to the iParent in the outer query. - ** + ** ** Example: ** ** SELECT a+5, b*10 FROM (SELECT x*3 AS a, y+10 AS b FROM t1) WHERE a>b; @@ -4660,7 +4668,7 @@ ** ORDER BY column expression is identical to the iOrderByCol'th ** expression returned by SELECT statement pSub. Since these values ** do not necessarily correspond to columns in SELECT statement pParent, - ** zero them before transfering the ORDER BY clause. + ** 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 @@ -4696,12 +4704,12 @@ x.pCList = findLeftmostExprlist(pSub); substSelect(&x, pParent, 0); } - + /* The flattened query is a compound if either the inner or the ** outer query is a compound. */ pParent->selFlags |= pSub->selFlags & SF_Compound; assert( (pSub->selFlags & SF_Distinct)==0 ); /* restriction (17b) */ - + /* ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y; ** @@ -4720,8 +4728,7 @@ } } - /* Finially, delete what is left of the subquery and return - ** success. + /* Finally, delete what is left of the subquery and return success. */ sqlite3AggInfoPersistWalkerInit(&w, pParse); sqlite3WalkSelect(&w,pSub1); @@ -4756,7 +4763,7 @@ /* ** Add a new entry to the pConst object. Except, do not add duplicate -** pColumn entires. Also, do not add if doing so would not be appropriate. +** pColumn entries. Also, do not add if doing so would not be appropriate. ** ** The caller guarantees the pColumn is a column and pValue is a constant. ** This routine has to do some additional checks before completing the @@ -4839,15 +4846,15 @@ /* ** This is a helper function for Walker callback propagateConstantExprRewrite(). ** -** Argument pExpr is a candidate expression to be replaced by a value. If -** pExpr is equivalent to one of the columns named in pWalker->u.pConst, +** Argument pExpr is a candidate expression to be replaced by a value. If +** pExpr is equivalent to one of the columns named in pWalker->u.pConst, ** then overwrite it with the corresponding value. Except, do not do so ** if argument bIgnoreAffBlob is non-zero and the affinity of pExpr ** is SQLITE_AFF_BLOB. */ static int propagateConstantExprRewriteOne( WhereConst *pConst, - Expr *pExpr, + Expr *pExpr, int bIgnoreAffBlob ){ int i; @@ -4892,7 +4899,7 @@ ** ** + pExpr is a binary comparison operator (=, <=, >=, <, >) that ** uses an affinity other than TEXT and one of its immediate -** children is a column that matches one of the columns in +** children is a column that matches one of the columns in ** pWalker->u.pConst. */ static int propagateConstantExprRewrite(Walker *pWalker, Expr *pExpr){ @@ -4942,7 +4949,7 @@ ** SELECT * FROM t1 WHERE a=123 AND b=123; ** ** The two SELECT statements above should return different answers. b=a -** is alway true because the comparison uses numeric affinity, but b=123 +** is always true because the comparison uses numeric affinity, but b=123 ** is false because it uses text affinity and '0123' is not the same as '123'. ** To work around this, the expression tree is not actually changed from ** "b=a" to "b=123" but rather the "a" in "b=a" is tagged with EP_FixedCol @@ -5004,7 +5011,7 @@ sqlite3DbFree(x.pParse->db, x.apExpr); nChng += x.nChng; } - }while( x.nChng ); + }while( x.nChng ); return nChng; } @@ -5014,19 +5021,19 @@ ** This function is called to determine whether or not it is safe to ** push WHERE clause expression pExpr down to FROM clause sub-query ** pSubq, which contains at least one window function. Return 1 -** if it is safe and the expression should be pushed down, or 0 +** if it is safe and the expression should be pushed down, or 0 ** otherwise. ** -** It is only safe to push the expression down if it consists only +** It is only safe to push the expression down if it consists only ** of constants and copies of expressions that appear in the PARTITION ** BY clause of all window function used by the sub-query. It is safe ** to filter out entire partitions, but not rows within partitions, as ** this may change the results of the window functions. ** -** At the time this function is called it is guaranteed that +** At the time this function is called it is guaranteed that ** -** * the sub-query uses only one distinct window frame, and -** * that the window frame has a PARTITION BY clase. +** * the sub-query uses only one distinct window frame, and +** * that the window frame has a PARTITION BY clause. */ static int pushDownWindowCheck(Parse *pParse, Select *pSubq, Expr *pExpr){ assert( pSubq->pWin->pPartition ); @@ -5084,19 +5091,19 @@ ** But if the (b2=2) term were to be pushed down into the bb subquery, ** then the (1,1,NULL) row would be suppressed. ** -** (6) Window functions make things tricky as changes to the WHERE clause -** of the inner query could change the window over which window +** (6) Window functions make things tricky as changes to the WHERE clause +** of the inner query could change the window over which window ** functions are calculated. Therefore, do not attempt the optimization ** if: ** ** (6a) The inner query uses multiple incompatible window partitions. ** -** (6b) The inner query is a compound and uses window-functions. +** (6b) The inner query is a compound and uses window-functions. ** ** (6c) The WHERE clause does not consist entirely of constants and ** copies of expressions found in the PARTITION BY clause of ** all window-functions used by the sub-query. It is safe to -** filter out entire partitions, as this does not change the +** filter out entire partitions, as this does not change the ** window over which any window-function is calculated. ** ** (7) The inner query is a Common Table Expression (CTE) that should @@ -5153,7 +5160,7 @@ int notUnionAll = 0; for(pSel=pSubq; pSel; pSel=pSel->pPrior){ u8 op = pSel->op; - assert( op==TK_ALL || op==TK_SELECT + assert( op==TK_ALL || op==TK_SELECT || op==TK_UNION || op==TK_INTERSECT || op==TK_EXCEPT ); if( op!=TK_ALL && op!=TK_SELECT ){ notUnionAll = 1; @@ -5190,7 +5197,7 @@ ** in the future. */ { - Select *pX; + Select *pX; for(pX=pSubq; pX; pX=pX->pPrior){ assert( (pX->selFlags & (SF_Recursive))==0 ); } @@ -5230,7 +5237,7 @@ return 0; /* restriction (4) */ } if( ExprHasProperty(pWhere,EP_OuterON) - && pWhere->w.iJoin!=iCursor + && pWhere->w.iJoin!=iCursor ){ return 0; /* restriction (5) */ } @@ -5295,12 +5302,12 @@ assert( pItem->pSelect!=0 ); pSub = pItem->pSelect; assert( pSub->pEList->nExpr==pTab->nCol ); - if( (pSub->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ - testcase( pSub->selFlags & SF_Distinct ); - testcase( pSub->selFlags & SF_Aggregate ); - return 0; - } for(pX=pSub; pX; pX=pX->pPrior){ + if( (pX->selFlags & (SF_Distinct|SF_Aggregate))!=0 ){ + testcase( pX->selFlags & SF_Distinct ); + testcase( pX->selFlags & SF_Aggregate ); + return 0; + } if( pX->pPrior && pX->op!=TK_ALL ){ /* This optimization does not work for compound subqueries that ** use UNION, INTERSECT, or EXCEPT. Only UNION ALL is allowed. */ @@ -5344,7 +5351,7 @@ /* ** The pFunc is the only aggregate function in the query. Check to see -** if the query is a candidate for the min/max optimization. +** if the query is a candidate for the min/max optimization. ** ** If the query is a candidate for the min/max optimization, then set ** *ppMinMax to be an ORDER BY clause to be used for the optimization @@ -5370,7 +5377,7 @@ assert( !IsWindowFunc(pFunc) ); assert( ExprUseXList(pFunc) ); pEList = pFunc->x.pList; - if( pEList==0 + if( pEList==0 || pEList->nExpr!=1 || ExprHasProperty(pFunc, EP_WinFunc) || OptimizationDisabled(db, SQLITE_MinMaxOpt) @@ -5398,7 +5405,7 @@ /* ** The select statement passed as the first argument is an aggregate query. -** The second argument is the associated aggregate-info object. This +** The second argument is the associated aggregate-info object. This ** function tests if the SELECT is of the form: ** ** SELECT count(*) FROM @@ -5419,8 +5426,8 @@ assert( !p->pGroupBy ); - if( p->pWhere - || p->pEList->nExpr!=1 + if( p->pWhere + || p->pEList->nExpr!=1 || p->pSrc->nSrc!=1 || p->pSrc->a[0].pSelect || pAggInfo->nFunc!=1 @@ -5448,8 +5455,8 @@ /* ** If the source-list item passed as an argument was augmented with an ** INDEXED BY clause, then try to locate the specified index. If there -** was such a clause and the named index cannot be found, return -** SQLITE_ERROR and leave an error in pParse. Otherwise, populate +** was such a clause and the named index cannot be found, return +** SQLITE_ERROR and leave an error in pParse. Otherwise, populate ** pFrom->pIndex and return SQLITE_OK. */ int sqlite3IndexedByLookup(Parse *pParse, SrcItem *pFrom){ @@ -5459,8 +5466,8 @@ assert( pTab!=0 ); assert( pFrom->fg.isIndexedBy!=0 ); - for(pIdx=pTab->pIndex; - pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); + for(pIdx=pTab->pIndex; + pIdx && sqlite3StrICmp(pIdx->zName, zIndexedBy); pIdx=pIdx->pNext ); if( !pIdx ){ @@ -5474,7 +5481,7 @@ } /* -** Detect compound SELECT statements that use an ORDER BY clause with +** Detect compound SELECT statements that use an ORDER BY clause with ** an alternative collating sequence. ** ** SELECT ... FROM t1 EXCEPT SELECT ... FROM t2 ORDER BY .. COLLATE ... @@ -5569,9 +5576,9 @@ #ifndef SQLITE_OMIT_CTE /* -** Argument pWith (which may be NULL) points to a linked list of nested -** WITH contexts, from inner to outermost. If the table identified by -** FROM clause element pItem is really a common-table-expression (CTE) +** Argument pWith (which may be NULL) points to a linked list of nested +** WITH contexts, from inner to outermost. If the table identified by +** FROM clause element pItem is really a common-table-expression (CTE) ** then return a pointer to the CTE definition for that table. Otherwise ** return NULL. ** @@ -5607,7 +5614,7 @@ ** onto the top of the stack. If argument bFree is true, then this ** WITH clause will never be popped from the stack but should instead ** be freed along with the Parse object. In other cases, when -** bFree==0, the With object will be freed along with the SELECT +** bFree==0, the With object will be freed along with the SELECT ** statement with which it is associated. ** ** This routine returns a copy of pWith. Or, if bFree is true and @@ -5620,7 +5627,7 @@ With *sqlite3WithPush(Parse *pParse, With *pWith, u8 bFree){ if( pWith ){ if( bFree ){ - pWith = (With*)sqlite3ParserAddCleanup(pParse, + pWith = (With*)sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3WithDelete, pWith); if( pWith==0 ) return 0; @@ -5635,7 +5642,7 @@ } /* -** This function checks if argument pFrom refers to a CTE declared by +** This function checks if argument pFrom refers to a CTE declared by ** a WITH clause on the stack currently maintained by the parser (on the ** pParse->pWith linked list). And if currently processing a CTE ** CTE expression, through routine checks to see if the reference is @@ -5644,7 +5651,7 @@ ** If pFrom matches a CTE according to either of these two above, pFrom->pTab ** and other fields are populated accordingly. ** -** Return 0 if no match is found. +** Return 0 if no match is found. ** Return 1 if a match is found. ** Return 2 if an error condition is detected. */ @@ -5743,8 +5750,8 @@ assert( pRecTerm->pPrior!=0 ); for(i=0; inSrc; i++){ SrcItem *pItem = &pSrc->a[i]; - if( pItem->zDatabase==0 - && pItem->zName!=0 + if( pItem->zDatabase==0 + && pItem->zName!=0 && 0==sqlite3StrICmp(pItem->zName, pCte->zName) ){ pItem->pTab = pTab; @@ -5822,12 +5829,12 @@ #ifndef SQLITE_OMIT_CTE /* -** If the SELECT passed as the second argument has an associated WITH +** If the SELECT passed as the second argument has an associated WITH ** clause, pop it from the stack stored as part of the Parse object. ** ** This function is used as the xSelectCallback2() callback by ** sqlite3SelectExpand() when walking a SELECT tree to resolve table -** names and other FROM clause elements. +** names and other FROM clause elements. */ void sqlite3SelectPopWith(Walker *pWalker, Select *p){ Parse *pParse = pWalker->pParse; @@ -5907,7 +5914,7 @@ ** (1) Make sure VDBE cursor numbers have been assigned to every ** element of the FROM clause. ** -** (2) Fill in the pTabList->a[].pTab fields in the SrcList that +** (2) Fill in the pTabList->a[].pTab fields in the SrcList that ** defines FROM clause. When views appear in the FROM clause, ** fill pTabList->a[].pSelect with a copy of the SELECT statement ** that implements the view. A copy is made of the view's SELECT @@ -6106,12 +6113,20 @@ ** expanded. */ int tableSeen = 0; /* Set to 1 when TABLE matches */ char *zTName = 0; /* text of name of TABLE */ + int iErrOfst; if( pE->op==TK_DOT ){ + assert( (selFlags & SF_NestedFrom)==0 ); assert( pE->pLeft!=0 ); assert( !ExprHasProperty(pE->pLeft, EP_IntValue) ); zTName = pE->pLeft->u.zToken; + assert( ExprUseWOfst(pE->pLeft) ); + iErrOfst = pE->pRight->w.iOfst; + }else{ + assert( ExprUseWOfst(pE) ); + iErrOfst = pE->w.iOfst; } for(i=0, pFrom=pTabList->a; inSrc; i++, pFrom++){ + int nAdd; /* Number of cols including rowid */ Table *pTab = pFrom->pTab; /* Table for this data source */ ExprList *pNestedFrom; /* Result-set of a nested FROM clause */ char *zTabName; /* AS name for this data source */ @@ -6129,6 +6144,7 @@ pNestedFrom = pFrom->pSelect->pEList; assert( pNestedFrom!=0 ); assert( pNestedFrom->nExpr==pTab->nCol ); + assert( VisibleRowid(pTab)==0 ); }else{ if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){ continue; @@ -6146,6 +6162,7 @@ for(ii=0; iinId; ii++){ const char *zUName = pUsing->a[ii].zName; pRight = sqlite3Expr(db, TK_ID, zUName); + sqlite3ExprSetErrorOffset(pRight, iErrOfst); pNew = sqlite3ExprListAppend(pParse, pNew, pRight); if( pNew ){ struct ExprList_item *pX = &pNew->a[pNew->nExpr-1]; @@ -6158,33 +6175,48 @@ }else{ pUsing = 0; } - for(j=0; jnCol; j++){ - char *zName = pTab->aCol[j].zCnName; + + nAdd = pTab->nCol + (VisibleRowid(pTab) && (selFlags&SF_NestedFrom)); + for(j=0; ja[j], 0, zTName, 0)==0 - ){ - continue; - } + if( j==pTab->nCol ){ + zName = sqlite3RowidAlias(pTab); + if( zName==0 ) continue; + }else{ + zName = pTab->aCol[j].zCnName; - /* If a column is marked as 'hidden', omit it from the expanded - ** result-set list unless the SELECT has the SF_IncludeHidden - ** bit set. - */ - if( (p->selFlags & SF_IncludeHidden)==0 - && IsHiddenColumn(&pTab->aCol[j]) - ){ - continue; - } - if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 - && zTName==0 - && (selFlags & (SF_NestedFrom))==0 - ){ - continue; + /* If pTab is actually an SF_NestedFrom sub-select, do not + ** expand any ENAME_ROWID columns. */ + if( pNestedFrom && pNestedFrom->a[j].fg.eEName==ENAME_ROWID ){ + continue; + } + + if( zTName + && pNestedFrom + && sqlite3MatchEName(&pNestedFrom->a[j], 0, zTName, 0, 0)==0 + ){ + continue; + } + + /* If a column is marked as 'hidden', omit it from the expanded + ** result-set list unless the SELECT has the SF_IncludeHidden + ** bit set. + */ + if( (p->selFlags & SF_IncludeHidden)==0 + && IsHiddenColumn(&pTab->aCol[j]) + ){ + continue; + } + if( (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + && zTName==0 + && (selFlags & (SF_NestedFrom))==0 + ){ + continue; + } } + assert( zName ); tableSeen = 1; if( i>0 && zTName==0 && (selFlags & SF_NestedFrom)==0 ){ @@ -6218,6 +6250,7 @@ }else{ pExpr = pRight; } + sqlite3ExprSetErrorOffset(pExpr, iErrOfst); pNew = sqlite3ExprListAppend(pParse, pNew, pExpr); if( pNew==0 ){ break; /* OOM */ @@ -6233,11 +6266,11 @@ zSchemaName, zTabName, zName); testcase( pX->zEName==0 ); } - pX->fg.eEName = ENAME_TAB; + pX->fg.eEName = (j==pTab->nCol ? ENAME_ROWID : ENAME_TAB); if( (pFrom->fg.isUsing && sqlite3IdListIndex(pFrom->u3.pUsing, zName)>=0) || (pUsing && sqlite3IdListIndex(pUsing, zName)>=0) - || (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)!=0 + || (jnCol && (pTab->aCol[j].colFlags & COLFLAG_NOEXPAND)) ){ pX->fg.bNoExpand = 1; } @@ -6417,9 +6450,9 @@ sqlite3DebugPrintf( "agg-column[%d] pTab=%s iTable=%d iColumn=%d iMem=%d" " iSorterColumn=%d %s\n", - ii, pCol->pTab ? pCol->pTab->zName : "NULL", + ii, pCol->pTab ? pCol->pTab->zName : "NULL", pCol->iTable, pCol->iColumn, pAggInfo->iFirstReg+ii, - pCol->iSorterColumn, + pCol->iSorterColumn, ii>=pAggInfo->nAccumulator ? "" : " Accumulator"); sqlite3TreeViewExpr(0, pAggInfo->aCol[ii].pCExpr, 0); } @@ -6458,8 +6491,14 @@ pNC->ncFlags |= NC_InAggFunc; for(i=0; inFunc; i++){ Expr *pExpr = pAggInfo->aFunc[i].pFExpr; + assert( pExpr->op==TK_FUNCTION || pExpr->op==TK_AGG_FUNCTION ); assert( ExprUseXList(pExpr) ); sqlite3ExprAnalyzeAggList(pNC, pExpr->x.pList); + if( pExpr->pLeft ){ + assert( pExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pExpr->pLeft) ); + sqlite3ExprAnalyzeAggList(pNC, pExpr->pLeft->x.pList); + } #ifndef SQLITE_OMIT_WINDOWFUNC assert( !IsWindowFunc(pExpr) ); if( ExprHasProperty(pExpr, EP_WinFunc) ){ @@ -6534,7 +6573,7 @@ pExpr->op = TK_AGG_COLUMN; pExpr->iTable = pCol->iTable; pExpr->iColumn = pCol->iColumn; - ExprClearProperty(pExpr, EP_Skip|EP_Collate); + ExprClearProperty(pExpr, EP_Skip|EP_Collate|EP_Unlikely); return WRC_Prune; } @@ -6565,7 +6604,7 @@ ** * The aCol[] and aFunc[] arrays may be modified ** * The AggInfoColumnReg() and AggInfoFuncReg() macros may not be used ** -** After clling this routine: +** After calling this routine: ** ** * The aCol[] and aFunc[] arrays are fixed ** * The AggInfoColumnReg() and AggInfoFuncReg() macros may be used @@ -6608,12 +6647,38 @@ pFunc->iDistinct = -1; }else{ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pE->x.pList,0,0); - pFunc->iDistAddr = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iDistAddr = sqlite3VdbeAddOp4(v, OP_OpenEphemeral, pFunc->iDistinct, 0, 0, (char*)pKeyInfo, P4_KEYINFO); ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(DISTINCT)", pFunc->pFunc->zName)); } } + if( pFunc->iOBTab>=0 ){ + ExprList *pOBList; + KeyInfo *pKeyInfo; + int nExtra = 0; + assert( pFunc->pFExpr->pLeft!=0 ); + assert( pFunc->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pFunc->pFExpr->pLeft) ); + pOBList = pFunc->pFExpr->pLeft->x.pList; + if( !pFunc->bOBUnique ){ + nExtra++; /* One extra column for the OP_Sequence */ + } + if( pFunc->bOBPayload ){ + /* extra columns for the function arguments */ + assert( ExprUseXList(pFunc->pFExpr) ); + nExtra += pFunc->pFExpr->x.pList->nExpr; + } + pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOBList, 0, nExtra); + if( !pFunc->bOBUnique && pParse->nErr==0 ){ + pKeyInfo->nKeyField++; + } + sqlite3VdbeAddOp4(v, OP_OpenEphemeral, + pFunc->iOBTab, pOBList->nExpr+nExtra, 0, + (char*)pKeyInfo, P4_KEYINFO); + ExplainQueryPlan((pParse, 0, "USE TEMP B-TREE FOR %s(ORDER BY)", + pFunc->pFunc->zName)); + } } } @@ -6629,13 +6694,46 @@ ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); pList = pF->pFExpr->x.pList; + if( pF->iOBTab>=0 ){ + /* For an ORDER BY aggregate, calls to OP_AggStep where deferred and + ** all content was stored in emphermal table pF->iOBTab. Extract that + ** content now (in ORDER BY order) and make all calls to OP_AggStep + ** before doing the OP_AggFinal call. */ + int iTop; /* Start of loop for extracting columns */ + int nArg; /* Number of columns to extract */ + int nKey; /* Key columns to be skipped */ + int regAgg; /* Extract into this array */ + int j; /* Loop counter */ + + nArg = pList->nExpr; + regAgg = sqlite3GetTempRange(pParse, nArg); + + if( pF->bOBPayload==0 ){ + nKey = 0; + }else{ + assert( pF->pFExpr->pLeft!=0 ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + assert( pF->pFExpr->pLeft->x.pList!=0 ); + nKey = pF->pFExpr->pLeft->x.pList->nExpr; + if( ALWAYS(!pF->bOBUnique) ) nKey++; + } + iTop = sqlite3VdbeAddOp1(v, OP_Rewind, pF->iOBTab); VdbeCoverage(v); + for(j=nArg-1; j>=0; j--){ + sqlite3VdbeAddOp3(v, OP_Column, pF->iOBTab, nKey+j, regAgg+j); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3VdbeAddOp2(v, OP_Next, pF->iOBTab, iTop+1); VdbeCoverage(v); + sqlite3VdbeJumpHere(v, iTop); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); + } sqlite3VdbeAddOp2(v, OP_AggFinal, AggInfoFuncReg(pAggInfo,i), pList ? pList->nExpr : 0); sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); } } - /* ** Generate code that will update the accumulator memory cells for an ** aggregate based on the current cursor position. @@ -6644,10 +6742,17 @@ ** in pAggInfo, then only populate the pAggInfo->nAccumulator accumulator ** registers if register regAcc contains 0. The caller will take care ** of setting and clearing regAcc. +** +** For an ORDER BY aggregate, the actual accumulator memory cell update +** is deferred until after all input rows have been received, so that they +** can be run in the requested order. In that case, instead of invoking +** OP_AggStep to update the accumulator, just add the arguments that would +** have been passed into OP_AggStep into the sorting ephemeral table +** (along with the appropriate sort key). */ static void updateAccumulator( - Parse *pParse, - int regAcc, + Parse *pParse, + int regAcc, AggInfo *pAggInfo, int eDistinctType ){ @@ -6665,14 +6770,16 @@ int nArg; int addrNext = 0; int regAgg; + int regAggSz = 0; + int regDistinct = 0; ExprList *pList; assert( ExprUseXList(pF->pFExpr) ); assert( !IsWindowFunc(pF->pFExpr) ); pList = pF->pFExpr->x.pList; if( ExprHasProperty(pF->pFExpr, EP_WinFunc) ){ Expr *pFilter = pF->pFExpr->y.pWin->pFilter; - if( pAggInfo->nAccumulator - && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) + if( pAggInfo->nAccumulator + && (pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL) && regAcc ){ /* If regAcc==0, there there exists some min() or max() function @@ -6681,7 +6788,7 @@ if( regHit==0 ) regHit = ++pParse->nMem; /* If this is the first row of the group (regAcc contains 0), clear the ** "magnet" register regHit so that the accumulator registers - ** are populated if the FILTER clause jumps over the the + ** are populated if the FILTER clause jumps over the the ** invocation of min() or max() altogether. Or, if this is not ** the first row (regAcc contains 1), set the magnet register so that ** the accumulators are not populated unless the min()/max() is invoked @@ -6691,39 +6798,85 @@ addrNext = sqlite3VdbeMakeLabel(pParse); sqlite3ExprIfFalse(pParse, pFilter, addrNext, SQLITE_JUMPIFNULL); } - if( pList ){ + if( pF->iOBTab>=0 ){ + /* Instead of invoking AggStep, we must push the arguments that would + ** have been passed to AggStep onto the sorting table. */ + int jj; /* Registered used so far in building the record */ + ExprList *pOBList; /* The ORDER BY clause */ + assert( pList!=0 ); + nArg = pList->nExpr; + assert( nArg>0 ); + assert( pF->pFExpr->pLeft!=0 ); + assert( pF->pFExpr->pLeft->op==TK_ORDER ); + assert( ExprUseXList(pF->pFExpr->pLeft) ); + pOBList = pF->pFExpr->pLeft->x.pList; + assert( pOBList!=0 ); + assert( pOBList->nExpr>0 ); + regAggSz = pOBList->nExpr; + if( !pF->bOBUnique ){ + regAggSz++; /* One register for OP_Sequence */ + } + if( pF->bOBPayload ){ + regAggSz += nArg; + } + regAggSz++; /* One extra register to hold result of MakeRecord */ + regAgg = sqlite3GetTempRange(pParse, regAggSz); + regDistinct = regAgg; + sqlite3ExprCodeExprList(pParse, pOBList, regAgg, 0, SQLITE_ECEL_DUP); + jj = pOBList->nExpr; + if( !pF->bOBUnique ){ + sqlite3VdbeAddOp2(v, OP_Sequence, pF->iOBTab, regAgg+jj); + jj++; + } + if( pF->bOBPayload ){ + regDistinct = regAgg+jj; + sqlite3ExprCodeExprList(pParse, pList, regDistinct, 0, SQLITE_ECEL_DUP); + } + }else if( pList ){ nArg = pList->nExpr; regAgg = sqlite3GetTempRange(pParse, nArg); + regDistinct = regAgg; sqlite3ExprCodeExprList(pParse, pList, regAgg, 0, SQLITE_ECEL_DUP); }else{ nArg = 0; regAgg = 0; } if( pF->iDistinct>=0 && pList ){ - if( addrNext==0 ){ + if( addrNext==0 ){ addrNext = sqlite3VdbeMakeLabel(pParse); } - pF->iDistinct = codeDistinct(pParse, eDistinctType, - pF->iDistinct, addrNext, pList, regAgg); + pF->iDistinct = codeDistinct(pParse, eDistinctType, + pF->iDistinct, addrNext, pList, regDistinct); } - if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ - CollSeq *pColl = 0; - struct ExprList_item *pItem; - int j; - assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ - for(j=0, pItem=pList->a; !pColl && jpExpr); - } - if( !pColl ){ - pColl = pParse->db->pDfltColl; - } - if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; - sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, (char *)pColl, P4_COLLSEQ); + if( pF->iOBTab>=0 ){ + /* Insert a new record into the ORDER BY table */ + sqlite3VdbeAddOp3(v, OP_MakeRecord, regAgg, regAggSz-1, + regAgg+regAggSz-1); + sqlite3VdbeAddOp4Int(v, OP_IdxInsert, pF->iOBTab, regAgg+regAggSz-1, + regAgg, regAggSz-1); + sqlite3ReleaseTempRange(pParse, regAgg, regAggSz); + }else{ + /* Invoke the AggStep function */ + if( pF->pFunc->funcFlags & SQLITE_FUNC_NEEDCOLL ){ + CollSeq *pColl = 0; + struct ExprList_item *pItem; + int j; + assert( pList!=0 ); /* pList!=0 if pF->pFunc has NEEDCOLL */ + for(j=0, pItem=pList->a; !pColl && jpExpr); + } + if( !pColl ){ + pColl = pParse->db->pDfltColl; + } + if( regHit==0 && pAggInfo->nAccumulator ) regHit = ++pParse->nMem; + sqlite3VdbeAddOp4(v, OP_CollSeq, regHit, 0, 0, + (char *)pColl, P4_COLLSEQ); + } + sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); + sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); + sqlite3VdbeChangeP5(v, (u8)nArg); + sqlite3ReleaseTempRange(pParse, regAgg, nArg); } - sqlite3VdbeAddOp3(v, OP_AggStep, 0, regAgg, AggInfoFuncReg(pAggInfo,i)); - sqlite3VdbeAppendP4(v, pF->pFunc, P4_FUNCDEF); - sqlite3VdbeChangeP5(v, (u8)nArg); - sqlite3ReleaseTempRange(pParse, regAgg, nArg); if( addrNext ){ sqlite3VdbeResolveLabel(v, addrNext); } @@ -6770,10 +6923,10 @@ /* ** sqlite3WalkExpr() callback used by havingToWhere(). ** -** If the node passed to the callback is a TK_AND node, return +** If the node passed to the callback is a TK_AND node, return ** WRC_Continue to tell sqlite3WalkExpr() to iterate through child nodes. ** -** Otherwise, return WRC_Prune. In this case, also check if the +** Otherwise, return WRC_Prune. In this case, also check if the ** sub-expression matches the criteria for being moved to the WHERE ** clause. If so, add it to the WHERE clause and replace the sub-expression ** within the HAVING expression with a constant "1". @@ -6788,7 +6941,7 @@ ** belongs to an outer query. Do not move the expression to the WHERE ** clause in this obscure case, as doing so may corrupt the outer Select ** statements AggInfo structure. */ - if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) + if( sqlite3ExprIsConstantOrGroupBy(pWalker->pParse, pExpr, pS->pGroupBy) && ExprAlwaysFalse(pExpr)==0 && pExpr->pAggInfo==0 ){ @@ -7066,7 +7219,7 @@ } /* -** Generate code for the SELECT statement given in the p argument. +** Generate code for the SELECT statement given in the p argument. ** ** The results are returned according to the SelectDest structure. ** See comments in sqliteInt.h for further information. @@ -7125,7 +7278,7 @@ assert( p->pOrderBy==0 || pDest->eDest!=SRT_DistQueue ); assert( p->pOrderBy==0 || pDest->eDest!=SRT_Queue ); if( IgnorableDistinct(pDest) ){ - assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || + assert(pDest->eDest==SRT_Exists || pDest->eDest==SRT_Union || pDest->eDest==SRT_Except || pDest->eDest==SRT_Discard || pDest->eDest==SRT_DistQueue || pDest->eDest==SRT_DistFifo ); /* All of these destinations are also able to ignore the ORDER BY clause */ @@ -7135,7 +7288,7 @@ if( sqlite3TreeTrace & 0x800 ){ sqlite3TreeViewExprList(0, p->pOrderBy, 0, "ORDERBY"); } -#endif +#endif sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3ExprListDelete, p->pOrderBy); @@ -7160,18 +7313,18 @@ /* If the SF_UFSrcCheck flag is set, then this function is being called ** as part of populating the temp table for an UPDATE...FROM statement. - ** In this case, it is an error if the target object (pSrc->a[0]) name - ** or alias is duplicated within FROM clause (pSrc->a[1..n]). + ** In this case, it is an error if the target object (pSrc->a[0]) name + ** or alias is duplicated within FROM clause (pSrc->a[1..n]). ** - ** Postgres disallows this case too. The reason is that some other - ** systems handle this case differently, and not all the same way, + ** Postgres disallows this case too. The reason is that some other + ** systems handle this case differently, and not all the same way, ** which is just confusing. To avoid this, we follow PG's lead and ** disallow it altogether. */ if( p->selFlags & SF_UFSrcCheck ){ SrcItem *p0 = &p->pSrc->a[0]; if( sameSrcAlias(p0, p->pSrc) ){ - sqlite3ErrorMsg(pParse, - "target object/alias may not appear in FROM clause: %s", + sqlite3ErrorMsg(pParse, + "target object/alias may not appear in FROM clause: %s", p0->zAlias ? p0->zAlias : p0->pTab->zName ); goto select_end; @@ -7219,22 +7372,59 @@ ** to a real table */ assert( pTab!=0 ); - /* Convert LEFT JOIN into JOIN if there are terms of the right table - ** of the LEFT JOIN used in the WHERE clause. - */ - if( (pItem->fg.jointype & (JT_LEFT|JT_RIGHT))==JT_LEFT - && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor) + /* Try to simplify joins: + ** + ** LEFT JOIN -> JOIN + ** RIGHT JOIN -> JOIN + ** FULL JOIN -> RIGHT JOIN + ** + ** If terms of the i-th table are used in the WHERE clause in such a + ** way that the i-th table cannot be the NULL row of a join, then + ** perform the appropriate simplification. This is called + ** "OUTER JOIN strength reduction" in the SQLite documentation. + */ + if( (pItem->fg.jointype & (JT_LEFT|JT_LTORJ))!=0 + && sqlite3ExprImpliesNonNullRow(p->pWhere, pItem->iCursor, + pItem->fg.jointype & JT_LTORJ) && OptimizationEnabled(db, SQLITE_SimplifyJoin) ){ - TREETRACE(0x1000,pParse,p, - ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); - pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); + if( pItem->fg.jointype & JT_LEFT ){ + if( pItem->fg.jointype & JT_RIGHT ){ + TREETRACE(0x1000,pParse,p, + ("FULL-JOIN simplifies to RIGHT-JOIN on term %d\n",i)); + pItem->fg.jointype &= ~JT_LEFT; + }else{ + TREETRACE(0x1000,pParse,p, + ("LEFT-JOIN simplifies to JOIN on term %d\n",i)); + pItem->fg.jointype &= ~(JT_LEFT|JT_OUTER); + } + } + if( pItem->fg.jointype & JT_LTORJ ){ + for(j=i+1; jnSrc; j++){ + SrcItem *pI2 = &pTabList->a[j]; + if( pI2->fg.jointype & JT_RIGHT ){ + if( pI2->fg.jointype & JT_LEFT ){ + TREETRACE(0x1000,pParse,p, + ("FULL-JOIN simplifies to LEFT-JOIN on term %d\n",j)); + pI2->fg.jointype &= ~JT_RIGHT; + }else{ + TREETRACE(0x1000,pParse,p, + ("RIGHT-JOIN simplifies to JOIN on term %d\n",j)); + pI2->fg.jointype &= ~(JT_RIGHT|JT_OUTER); + } + } + } + for(j=pTabList->nSrc-1; j>=i; j--){ + pTabList->a[j].fg.jointype &= ~JT_LTORJ; + if( pTabList->a[j].fg.jointype & JT_RIGHT ) break; + } + } assert( pItem->iCursor>=0 ); unsetJoinExpr(p->pWhere, pItem->iCursor, pTabList->a[0].fg.jointype & JT_LTORJ); } - /* No futher action if this term of the FROM clause is not a subquery */ + /* No further action if this term of the FROM clause is not a subquery */ if( pSub==0 ) continue; /* Catch mismatch in the declared columns of a view and the number of @@ -7245,6 +7435,14 @@ goto select_end; } + /* Do not attempt the usual optimizations (flattening and ORDER BY + ** elimination) on a MATERIALIZED common table expression because + ** a MATERIALIZED common table expression is an optimization fence. + */ + if( pItem->fg.isCte && pItem->u2.pCteUse->eM10d==M10d_Yes ){ + continue; + } + /* Do not try to flatten an aggregate subquery. ** ** Flattening an aggregate subquery is only possible if the outer query @@ -7274,6 +7472,8 @@ ** (a) The outer query has a different ORDER BY clause ** (b) The subquery is part of a join ** See forum post 062d576715d277c8 + ** + ** Also retain the ORDER BY if the OmitOrderBy optimization is disabled. */ if( pSub->pOrderBy!=0 && (p->pOrderBy!=0 || pTabList->nSrc>1) /* Condition (5) */ @@ -7284,7 +7484,7 @@ ){ TREETRACE(0x800,pParse,p, ("omit superfluous ORDER BY on %r FROM-clause subquery\n",i+1)); - sqlite3ParserAddCleanup(pParse, + sqlite3ParserAddCleanup(pParse, (void(*)(sqlite3*,void*))sqlite3ExprListDelete, pSub->pOrderBy); pSub->pOrderBy = 0; @@ -7429,7 +7629,7 @@ ** inside the subquery. This can help the subquery to run more efficiently. */ if( OptimizationEnabled(db, SQLITE_PushDown) - && (pItem->fg.isCte==0 + && (pItem->fg.isCte==0 || (pItem->u2.pCteUse->eM10d!=M10d_Yes && pItem->u2.pCteUse->nUse<2)) && pushDownWhereTerms(pParse, pSub, p->pWhere, pTabList, i) ){ @@ -7471,7 +7671,7 @@ ** set on each invocation. */ int addrTop = sqlite3VdbeCurrentAddr(v)+1; - + pItem->regReturn = ++pParse->nMem; sqlite3VdbeAddOp3(v, OP_InitCoroutine, pItem->regReturn, 0, addrTop); VdbeComment((v, "%!S", pItem)); @@ -7488,7 +7688,7 @@ }else if( pItem->fg.isCte && pItem->u2.pCteUse->addrM9e>0 ){ /* This is a CTE for which materialization code has already been ** generated. Invoke the subroutine to compute the materialization, - ** the make the pItem->iCursor be a copy of the ephemerial table that + ** the make the pItem->iCursor be a copy of the ephemeral table that ** holds the result of the materialization. */ CteUse *pCteUse = pItem->u2.pCteUse; sqlite3VdbeAddOp2(v, OP_Gosub, pCteUse->regRtn, pCteUse->addrM9e); @@ -7568,7 +7768,7 @@ } #endif - /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and + /* If the query is DISTINCT with an ORDER BY but is not an aggregate, and ** if the select-list is the same as the ORDER BY list, then this query ** can be rewritten as a GROUP BY. In other words, this: ** @@ -7578,12 +7778,12 @@ ** ** SELECT xyz FROM ... GROUP BY xyz ORDER BY xyz ** - ** The second form is preferred as a single index (or temp-table) may be - ** used for both the ORDER BY and DISTINCT processing. As originally - ** written the query must use a temp-table for at least one of the ORDER + ** The second form is preferred as a single index (or temp-table) may be + ** used for both the ORDER BY and DISTINCT processing. As originally + ** written the query must use a temp-table for at least one of the ORDER ** BY and DISTINCT, and an index or separate temp-table for the other. */ - if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct + if( (p->selFlags & (SF_Distinct|SF_Aggregate))==SF_Distinct && sqlite3ExprListCompare(sSort.pOrderBy, pEList, -1)==0 #ifndef SQLITE_OMIT_WINDOWFUNC && p->pWin==0 @@ -7705,7 +7905,7 @@ } TREETRACE(0x2,pParse,p,("WhereBegin returns\n")); - /* If sorting index that was created by a prior OP_OpenEphemeral + /* If sorting index that was created by a prior OP_OpenEphemeral ** instruction ended up not being needed, then change the OP_OpenEphemeral ** into an OP_Noop. */ @@ -7778,8 +7978,8 @@ if( p->nSelectRow>66 ) p->nSelectRow = 66; /* If there is both a GROUP BY and an ORDER BY clause and they are - ** identical, then it may be possible to disable the ORDER BY clause - ** on the grounds that the GROUP BY will cause elements to come out + ** identical, then it may be possible to disable the ORDER BY clause + ** on the grounds that the GROUP BY will cause elements to come out ** in the correct order. It also may not - the GROUP BY might use a ** database index that causes rows to be grouped together as required ** but not actually sorted. Either way, record the fact that the @@ -7789,8 +7989,8 @@ int ii; /* The GROUP BY processing doesn't care whether rows are delivered in ** ASC or DESC order - only that each group is returned contiguously. - ** So set the ASC/DESC flags in the GROUP BY to match those in the - ** ORDER BY to maximize the chances of rows being delivered in an + ** So set the ASC/DESC flags in the GROUP BY to match those in the + ** ORDER BY to maximize the chances of rows being delivered in an ** order that makes the ORDER BY redundant. */ for(ii=0; iinExpr; ii++){ u8 sortFlags; @@ -7871,7 +8071,7 @@ */ if( pGroupBy ){ KeyInfo *pKeyInfo; /* Keying information for the group by clause */ - int addr1; /* A-vs-B comparision jump */ + 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 */ @@ -7883,7 +8083,7 @@ u16 distFlag = 0; int eDist = WHERE_DISTINCT_NOOP; - if( pAggInfo->nFunc==1 + if( pAggInfo->nFunc==1 && pAggInfo->aFunc[0].iDistinct>=0 && ALWAYS(pAggInfo->aFunc[0].pFExpr!=0) && ALWAYS(ExprUseXList(pAggInfo->aFunc[0].pFExpr)) @@ -7899,13 +8099,13 @@ /* If there is a GROUP BY clause we might need a sorting index to ** implement it. Allocate that sorting index now. If it turns out ** that we do not need it after all, the OP_SorterOpen instruction - ** will be converted into a Noop. + ** will be converted into a Noop. */ pAggInfo->sortingIdx = pParse->nTab++; pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pGroupBy, 0, pAggInfo->nColumn); - addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, - pAggInfo->sortingIdx, pAggInfo->nSortingColumn, + addrSortingIdx = sqlite3VdbeAddOp4(v, OP_SorterOpen, + pAggInfo->sortingIdx, pAggInfo->nSortingColumn, 0, (char*)pKeyInfo, P4_KEYINFO); /* Initialize memory locations used by GROUP BY aggregate processing @@ -7932,7 +8132,7 @@ sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset); TREETRACE(0x2,pParse,p,("WhereBegin\n")); pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, pGroupBy, pDistinct, - p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) + p, (sDistinct.isTnct==2 ? WHERE_DISTINCTBY : WHERE_GROUPBY) | (orderByGrp ? WHERE_SORTBYGROUP : 0) | distFlag, 0 ); if( pWInfo==0 ){ @@ -7962,9 +8162,13 @@ int nCol; int nGroupBy; - explainTempTable(pParse, +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + int addrExp; /* Address of OP_Explain instruction */ +#endif + ExplainQueryPlan2(addrExp, (pParse, 0, "USE TEMP B-TREE FOR %s", (sDistinct.isTnct && (p->selFlags&SF_Distinct)==0) ? - "DISTINCT" : "GROUP BY"); + "DISTINCT" : "GROUP BY" + )); groupBySort = 1; nGroupBy = pGroupBy->nExpr; @@ -7989,18 +8193,23 @@ } pAggInfo->directMode = 0; regRecord = sqlite3GetTempReg(pParse); + sqlite3VdbeScanStatusCounters(v, addrExp, 0, sqlite3VdbeCurrentAddr(v)); sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nCol, regRecord); sqlite3VdbeAddOp2(v, OP_SorterInsert, pAggInfo->sortingIdx, regRecord); + sqlite3VdbeScanStatusRange(v, addrExp, sqlite3VdbeCurrentAddr(v)-2, -1); sqlite3ReleaseTempReg(pParse, regRecord); sqlite3ReleaseTempRange(pParse, regBase, nCol); TREETRACE(0x2,pParse,p,("WhereEnd\n")); sqlite3WhereEnd(pWInfo); pAggInfo->sortingIdxPTab = sortPTab = pParse->nTab++; sortOut = sqlite3GetTempReg(pParse); + sqlite3VdbeScanStatusCounters(v, addrExp, sqlite3VdbeCurrentAddr(v), 0); sqlite3VdbeAddOp3(v, OP_OpenPseudo, sortPTab, sortOut, nCol); sqlite3VdbeAddOp2(v, OP_SorterSort, pAggInfo->sortingIdx, addrEnd); VdbeComment((v, "GROUP BY sort")); VdbeCoverage(v); pAggInfo->useSortingIdx = 1; + sqlite3VdbeScanStatusRange(v, addrExp, -1, sortPTab); + sqlite3VdbeScanStatusRange(v, addrExp, -1, pAggInfo->sortingIdx); } /* If there are entries in pAgggInfo->aFunc[] that contain subexpressions @@ -8025,9 +8234,9 @@ ** clause, cancel the ephemeral table open coded earlier. ** ** This is an optimization - the correct answer should result regardless. - ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to + ** Use the SQLITE_GroupByOrder flag with SQLITE_TESTCTRL_OPTIMIZER to ** disable this optimization for testing purposes. */ - if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) + if( orderByGrp && OptimizationEnabled(db, SQLITE_GroupByOrder) && (groupBySort || sqlite3WhereIsSorted(pWInfo)) ){ sSort.pOrderBy = 0; @@ -8173,7 +8382,7 @@ ** ** (2013-10-03) Do not count the entries in a partial index. ** - ** In practice the KeyInfo structure will not be used. It is only + ** In practice the KeyInfo structure will not be used. It is only ** passed to keep OP_OpenRead happy. */ if( !HasRowid(pTab) ) pBest = sqlite3PrimaryKeyIndex(pTab); @@ -8215,7 +8424,7 @@ ** that the accumulator registers are (a) updated only once if ** there are no min() or max functions or (b) always updated for the ** first row visited by the aggregate, so that they are updated at - ** least once even if the FILTER clause means the min() or max() + ** least once even if the FILTER clause means the min() or max() ** function visits zero rows. */ if( pAggInfo->nAccumulator ){ for(i=0; inFunc; i++){ @@ -8279,11 +8488,11 @@ sSort.pOrderBy = 0; sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL); - selectInnerLoop(pParse, p, -1, 0, 0, + selectInnerLoop(pParse, p, -1, 0, 0, pDest, addrEnd, addrEnd); } sqlite3VdbeResolveLabel(v, addrEnd); - + } /* endif aggregate query */ if( sDistinct.eTnctType==WHERE_DISTINCT_UNORDERED ){ diff -Nru sqlite3-3.42.0/src/shell.c.in sqlite3-3.44.0-0/src/shell.c.in --- sqlite3-3.42.0/src/shell.c.in 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/shell.c.in 2023-11-04 14:23:58.000000000 +0000 @@ -228,6 +228,7 @@ #if SQLITE_OS_WINRT #include #endif +#undef WIN32_LEAN_AND_MEAN #define WIN32_LEAN_AND_MEAN #include @@ -448,20 +449,25 @@ */ static int stdin_is_interactive = 1; +/* +** If build is for non-RT Windows, without 3rd-party line editing, +** console input and output may be done in a UTF-8 compatible way, +** if the OS is capable of it and the --no-utf8 option is not seen. +*/ #if (defined(_WIN32) || defined(WIN32)) && SHELL_USE_LOCAL_GETLINE \ - && !defined(SHELL_OMIT_WIN_UTF8) + && !defined(SHELL_OMIT_WIN_UTF8) && !SQLITE_OS_WINRT # define SHELL_WIN_UTF8_OPT 1 +/* Record whether to do UTF-8 console I/O translation per stream. */ + static int console_utf8_in = 0; + static int console_utf8_out = 0; +/* Record whether can do UTF-8 or --no-utf8 seen in invocation. */ + static int mbcs_opted = 1; /* Assume cannot do until shown otherwise. */ #else +# define console_utf8_in 0 +# define console_utf8_out 0 # define SHELL_WIN_UTF8_OPT 0 #endif -#if SHELL_WIN_UTF8_OPT -/* -** Setup console for UTF-8 input/output when following variable true. -*/ -static int console_utf8 = 0; -#endif - /* ** On Windows systems we have to know if standard output is a console ** in order to translate UTF-8 into MBCS. The following variable is @@ -595,13 +601,13 @@ #endif /* !defined(SQLITE_OMIT_DYNAPROMPT) */ #if SHELL_WIN_UTF8_OPT -/* Following struct is used for -utf8 operation. */ +/* Following struct is used for UTF-8 console I/O. */ static struct ConsoleState { int stdinEof; /* EOF has been seen on console input */ int infsMode; /* Input file stream mode upon shell start */ UINT inCodePage; /* Input code page upon shell start */ UINT outCodePage; /* Output code page upon shell start */ - HANDLE hConsoleIn; /* Console input handle */ + HANDLE hConsole; /* Console input or output handle */ DWORD consoleMode; /* Console mode upon shell start */ } conState = { 0, 0, 0, 0, INVALID_HANDLE_VALUE, 0 }; @@ -610,50 +616,122 @@ #endif /* -** Prepare console, (if known to be a WIN32 console), for UTF-8 -** input (from either typing or suitable paste operations) and for -** UTF-8 rendering. This may "fail" with a message to stderr, where -** the preparation is not done and common "code page" issues occur. -*/ -static void console_prepare(void){ - HANDLE hCI = GetStdHandle(STD_INPUT_HANDLE); - DWORD consoleMode = 0; - if( isatty(0) && GetFileType(hCI)==FILE_TYPE_CHAR - && GetConsoleMode( hCI, &consoleMode) ){ - if( !IsValidCodePage(CP_UTF8) ){ - fprintf(stderr, "Cannot use UTF-8 code page.\n"); - console_utf8 = 0; - return; - } - conState.hConsoleIn = hCI; - conState.consoleMode = consoleMode; - conState.inCodePage = GetConsoleCP(); - conState.outCodePage = GetConsoleOutputCP(); - SetConsoleCP(CP_UTF8); +** If given stream number is a console, return 1 and get some attributes, +** else return 0 and set the output attributes to invalid values. +*/ +static short console_attrs(unsigned stnum, HANDLE *pH, DWORD *pConsMode){ + static int stid[3] = { STD_INPUT_HANDLE,STD_OUTPUT_HANDLE,STD_ERROR_HANDLE }; + HANDLE h; + *pH = INVALID_HANDLE_VALUE; + *pConsMode = 0; + if( stnum > 2 ) return 0; + h = GetStdHandle(stid[stnum]); + if( h!=*pH && GetFileType(h)==FILE_TYPE_CHAR && GetConsoleMode(h,pConsMode) ){ + *pH = h; + return 1; + } + return 0; +} + +/* +** Perform a runtime test of Windows console to determine if it can +** do char-stream I/O correctly when the code page is set to CP_UTF8. +** Returns are: 1 => yes it can, 0 => no it cannot +** +** The console's output code page is momentarily set, then restored. +** So this should only be run when the process is given use of the +** console for either input or output. +*/ +static short ConsoleDoesUTF8(void){ + UINT ocp = GetConsoleOutputCP(); + const char TrialUtf8[] = { '\xC8', '\xAB' }; /* "ȫ" or 2 MBCS characters */ + WCHAR aReadBack[1] = { 0 }; /* Read back as 0x022B when decoded as UTF-8. */ + CONSOLE_SCREEN_BUFFER_INFO csbInfo = {0}; + /* Create an inactive screen buffer with which to do the experiment. */ + HANDLE hCSB = CreateConsoleScreenBuffer(GENERIC_READ|GENERIC_WRITE, 0, 0, + CONSOLE_TEXTMODE_BUFFER, NULL); + if( hCSB!=INVALID_HANDLE_VALUE ){ + COORD cpos = {0,0}; + DWORD rbc; + SetConsoleCursorPosition(hCSB, cpos); SetConsoleOutputCP(CP_UTF8); - consoleMode |= ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT; - SetConsoleMode(conState.hConsoleIn, consoleMode); + /* Write 2 chars which are a single character in UTF-8 but more in MBCS. */ + WriteConsoleA(hCSB, TrialUtf8, sizeof(TrialUtf8), NULL, NULL); + ReadConsoleOutputCharacterW(hCSB, &aReadBack[0], 1, cpos, &rbc); + GetConsoleScreenBufferInfo(hCSB, &csbInfo); + SetConsoleOutputCP(ocp); + CloseHandle(hCSB); + } + /* Return 1 if cursor advanced by 1 position, else 0. */ + return (short)(csbInfo.dwCursorPosition.X == 1 && aReadBack[0] == 0x022B); +} + +static short in_console = 0; +static short out_console = 0; + +/* +** Determine whether either normal I/O stream is the console, +** and whether it can do UTF-8 translation, setting globals +** in_console, out_console and mbcs_opted accordingly. +*/ +static void probe_console(void){ + HANDLE h; + DWORD cMode; + in_console = console_attrs(0, &h, &cMode); + out_console = console_attrs(1, &h, &cMode); + if( in_console || out_console ) mbcs_opted = !ConsoleDoesUTF8(); +} + +/* +** If console is used for normal I/O, absent a --no-utf8 option, +** prepare console for UTF-8 input (from either typing or suitable +** paste operations) and/or for UTF-8 output rendering. +** +** The console state upon entry is preserved, in conState, so that +** console_restore() can later restore the same console state. +** +** The globals console_utf8_in and console_utf8_out are set, for +** later use in selecting UTF-8 or MBCS console I/O translations. +** This routine depends upon globals set by probe_console(). +*/ +static void console_prepare_utf8(void){ + struct ConsoleState csWork = { 0, 0, 0, 0, INVALID_HANDLE_VALUE, 0 }; + + console_utf8_in = console_utf8_out = 0; + if( (!in_console && !out_console) || mbcs_opted ) return; + console_attrs((in_console)? 0 : 1, &conState.hConsole, &conState.consoleMode); + conState.inCodePage = GetConsoleCP(); + conState.outCodePage = GetConsoleOutputCP(); + if( in_console ){ + SetConsoleCP(CP_UTF8); + SetConsoleMode(conState.hConsole, conState.consoleMode + | ENABLE_LINE_INPUT | ENABLE_PROCESSED_INPUT); conState.infsMode = _setmode(_fileno(stdin), _O_U16TEXT); - console_utf8 = 1; - }else{ - console_utf8 = 0; + console_utf8_in = 1; + } + if( out_console ){ + SetConsoleOutputCP(CP_UTF8); + console_utf8_out = 1; } } /* -** Undo the effects of console_prepare(), if any. +** Undo the effects of console_prepare_utf8(), if any. */ static void SQLITE_CDECL console_restore(void){ - if( console_utf8 && conState.inCodePage!=0 - && conState.hConsoleIn!=INVALID_HANDLE_VALUE ){ - _setmode(_fileno(stdin), conState.infsMode); - SetConsoleCP(conState.inCodePage); - SetConsoleOutputCP(conState.outCodePage); - SetConsoleMode(conState.hConsoleIn, conState.consoleMode); + if( (console_utf8_in||console_utf8_out) + && conState.hConsole!=INVALID_HANDLE_VALUE ){ + if( console_utf8_in ){ + SetConsoleCP(conState.inCodePage); + _setmode(_fileno(stdin), conState.infsMode); + } + if( console_utf8_out ) SetConsoleOutputCP(conState.outCodePage); + SetConsoleMode(conState.hConsole, conState.consoleMode); /* Avoid multiple calls. */ - conState.hConsoleIn = INVALID_HANDLE_VALUE; + conState.hConsole = INVALID_HANDLE_VALUE; conState.consoleMode = 0; - console_utf8 = 0; + console_utf8_in = 0; + console_utf8_out = 0; } } @@ -661,11 +739,11 @@ ** Collect input like fgets(...) with special provisions for input ** from the Windows console to get around its strange coding issues. ** Defers to plain fgets() when input is not interactive or when the -** startup option, -utf8, has not been provided or taken effect. +** UTF-8 input is unavailable or opted out. */ static char* utf8_fgets(char *buf, int ncmax, FILE *fin){ if( fin==0 ) fin = stdin; - if( fin==stdin && stdin_is_interactive && console_utf8 ){ + if( fin==stdin && stdin_is_interactive && console_utf8_in ){ # define SQLITE_IALIM 150 wchar_t wbuf[SQLITE_IALIM]; int lend = 0; @@ -678,7 +756,7 @@ ? SQLITE_IALIM : (ncmax-1 - noc)/4; # undef SQLITE_IALIM DWORD nbr = 0; - BOOL bRC = ReadConsoleW(conState.hConsoleIn, wbuf, na, &nbr, 0); + BOOL bRC = ReadConsoleW(conState.hConsole, wbuf, na, &nbr, 0); if( !bRC || (noc==0 && nbr==0) ) return 0; if( nbr > 0 ){ int nmb = WideCharToMultiByte(CP_UTF8,WC_COMPOSITECHECK|WC_DEFAULTCHAR, @@ -724,20 +802,16 @@ /* ** Render output like fprintf(). Except, if the output is going to the -** console and if this is running on a Windows machine, and if the -utf8 -** option is unavailable or (available and inactive), translate the +** console and if this is running on a Windows machine, and if UTF-8 +** output unavailable (or available but opted out), translate the ** output from UTF-8 into MBCS for output through 8-bit stdout stream. -** (With -utf8 active, no translation is needed and must not be done.) +** (Without -no-utf8, no translation is needed and must not be done.) */ #if defined(_WIN32) || defined(WIN32) void utf8_printf(FILE *out, const char *zFormat, ...){ va_list ap; va_start(ap, zFormat); - if( stdout_is_console && (out==stdout || out==stderr) -# if SHELL_WIN_UTF8_OPT - && !console_utf8 -# endif - ){ + if( stdout_is_console && (out==stdout || out==stderr) && !console_utf8_out ){ char *z1 = sqlite3_vmprintf(zFormat, ap); char *z2 = sqlite3_win32_utf8_to_mbcs_v2(z1, 0); sqlite3_free(z1); @@ -948,14 +1022,10 @@ } } #if defined(_WIN32) || defined(WIN32) - /* For interactive input on Windows systems, without -utf8, + /* For interactive input on Windows systems, with -no-utf8, ** translate the multi-byte characterset characters into UTF-8. - ** This is the translation that predates the -utf8 option. */ - if( stdin_is_interactive && in==stdin -# if SHELL_WIN_UTF8_OPT - && !console_utf8 -# endif /* SHELL_WIN_UTF8_OPT */ - ){ + ** This is the translation that predates console UTF-8 input. */ + if( stdin_is_interactive && in==stdin && !console_utf8_in ){ char *zTrans = sqlite3_win32_mbcs_to_utf8_v2(zLine, 0); if( zTrans ){ i64 nTrans = strlen(zTrans)+1; @@ -1207,6 +1277,46 @@ } /* +** SQL function: strtod(X) +** +** Use the C-library strtod() function to convert string X into a double. +** Used for comparing the accuracy of SQLite's internal text-to-float conversion +** routines against the C-library. +*/ +static void shellStrtod( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + char *z = (char*)sqlite3_value_text(apVal[0]); + UNUSED_PARAMETER(nVal); + if( z==0 ) return; + sqlite3_result_double(pCtx, strtod(z,0)); +} + +/* +** SQL function: dtostr(X) +** +** Use the C-library printf() function to convert real value X into a string. +** Used for comparing the accuracy of SQLite's internal float-to-text conversion +** routines against the C-library. +*/ +static void shellDtostr( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + double r = sqlite3_value_double(apVal[0]); + int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26; + char z[400]; + if( n<1 ) n = 1; + if( n>350 ) n = 350; + snprintf(z, sizeof(z)-1, "%#+.*e", n, r); + sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); +} + + +/* ** SQL function: shell_module_schema(X) ** ** Return a fake schema for the table-valued function or eponymous virtual @@ -1317,6 +1427,7 @@ #define dirent DIRENT #endif INCLUDE ../ext/misc/memtrace.c +INCLUDE ../ext/misc/pcachetrace.c INCLUDE ../ext/misc/shathree.c INCLUDE ../ext/misc/uint.c INCLUDE ../ext/misc/decimal.c @@ -1411,7 +1522,7 @@ struct ShellState { sqlite3 *db; /* The database */ u8 autoExplain; /* Automatically turn on .explain mode */ - u8 autoEQP; /* Run EXPLAIN QUERY PLAN prior to seach SQL stmt */ + u8 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 scanstatsOn; /* True to display scan stats before each finalize */ @@ -1423,7 +1534,7 @@ u8 bSafeModePersist; /* The long-term value of bSafeMode */ ColModeOpts cmOpts; /* Option values affecting columnar mode output */ unsigned statsOn; /* True to display memory stats before each finalize */ - unsigned mEqpLines; /* Mask of veritical lines in the EQP output graph */ + unsigned mEqpLines; /* Mask of vertical lines in the EQP output graph */ int inputNesting; /* Track nesting level of .read and other redirects */ int outCount; /* Revert to stdout when reaching zero */ int cnt; /* Number of records displayed so far */ @@ -1474,7 +1585,7 @@ int *aiIndent; /* Array of indents used in MODE_Explain */ int nIndent; /* Size of array aiIndent[] */ int iIndent; /* Index of current op in aiIndent[] */ - char *zNonce; /* Nonce for temporary safe-mode excapes */ + char *zNonce; /* Nonce for temporary safe-mode escapes */ EQPGraph sGraph; /* Information for the graphical EXPLAIN QUERY PLAN */ ExpertInfo expert; /* Valid if previous command was ".expert OPT..." */ #ifdef SQLITE_SHELL_FIDDLE @@ -1516,7 +1627,7 @@ /* Bits in the ShellState.flgProgress variable */ #define SHELL_PROGRESS_QUIET 0x01 /* Omit announcing every progress callback */ -#define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progres +#define SHELL_PROGRESS_RESET 0x02 /* Reset the count when the progress ** callback limit is reached, and for each ** top-level SQL statement */ #define SHELL_PROGRESS_ONCE 0x04 /* Cancel the --limit after firing once */ @@ -1565,6 +1676,7 @@ #define MODE_Box 16 /* Unicode box-drawing characters */ #define MODE_Count 17 /* Output only a count of the rows of output */ #define MODE_Off 18 /* No query output shown */ +#define MODE_ScanExp 19 /* Like MODE_Explain, but for ".scanstats vm" */ static const char *modeDescr[] = { "line", @@ -2478,38 +2590,58 @@ } break; } + case MODE_ScanExp: case MODE_Explain: { - static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13}; - if( nArg>ArraySize(aExplainWidth) ){ - nArg = ArraySize(aExplainWidth); + static const int aExplainWidth[] = {4, 13, 4, 4, 4, 13, 2, 13}; + static const int aExplainMap[] = {0, 1, 2, 3, 4, 5, 6, 7 }; + static const int aScanExpWidth[] = {4, 6, 6, 13, 4, 4, 4, 13, 2, 13}; + static const int aScanExpMap[] = {0, 9, 8, 1, 2, 3, 4, 5, 6, 7 }; + + const int *aWidth = aExplainWidth; + const int *aMap = aExplainMap; + int nWidth = ArraySize(aExplainWidth); + int iIndent = 1; + + if( p->cMode==MODE_ScanExp ){ + aWidth = aScanExpWidth; + aMap = aScanExpMap; + nWidth = ArraySize(aScanExpWidth); + iIndent = 3; } + if( nArg>nWidth ) nArg = nWidth; + + /* If this is the first row seen, print out the headers */ if( p->cnt++==0 ){ for(i=0; iout, w, azCol[i]); + utf8_width_print(p->out, aWidth[i], azCol[ aMap[i] ]); fputs(i==nArg-1 ? "\n" : " ", p->out); } for(i=0; iout, w); + print_dashes(p->out, aWidth[i]); fputs(i==nArg-1 ? "\n" : " ", p->out); } } + + /* If there is no data, exit early. */ if( azArg==0 ) break; + for(i=0; iw ){ - w = strlenChar(azArg[i]); + if( zVal && strlenChar(zVal)>w ){ + w = strlenChar(zVal); + zSep = " "; } - if( i==1 && p->aiIndent && p->pStmt ){ + if( i==iIndent && p->aiIndent && p->pStmt ){ if( p->iIndentnIndent ){ utf8_printf(p->out, "%*.s", p->aiIndent[p->iIndent], ""); } p->iIndent++; } - utf8_width_print(p->out, w, azArg[i] ? azArg[i] : p->nullValue); - fputs(i==nArg-1 ? "\n" : " ", p->out); + utf8_width_print(p->out, w, zVal ? zVal : p->nullValue); + fputs(i==nArg-1 ? "\n" : zSep, p->out); } break; } @@ -3030,7 +3162,7 @@ */ static char *save_err_msg( sqlite3 *db, /* Database to query */ - const char *zPhase, /* When the error occcurs */ + const char *zPhase, /* When the error occurs */ int rc, /* Error code returned from API */ const char *zSql /* SQL string, or NULL */ ){ @@ -3290,17 +3422,11 @@ } #endif -/* -** Display scan stats. -*/ -static void display_scanstats( +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS +static void display_explain_scanstats( sqlite3 *db, /* Database to query */ ShellState *pArg /* Pointer to ShellState */ ){ -#ifndef SQLITE_ENABLE_STMT_SCANSTATUS - UNUSED_PARAMETER(db); - UNUSED_PARAMETER(pArg); -#else static const int f = SQLITE_SCANSTAT_COMPLEX; sqlite3_stmt *p = pArg->pStmt; int ii = 0; @@ -3314,7 +3440,7 @@ if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){ break; } - n = strlen(z) + scanStatsHeight(p, ii)*3; + n = (int)strlen(z) + scanStatsHeight(p, ii)*3; if( n>nWidth ) nWidth = n; } nWidth += 4; @@ -3326,12 +3452,12 @@ i64 nCycle = 0; int iId = 0; int iPid = 0; - const char *z = 0; + const char *zo = 0; const char *zName = 0; char *zText = 0; double rEst = 0.0; - if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&z) ){ + if( sqlite3_stmt_scanstatus_v2(p,ii,SQLITE_SCANSTAT_EXPLAIN,f,(void*)&zo) ){ break; } sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_EST,f,(void*)&rEst); @@ -3342,7 +3468,7 @@ sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_PARENTID,f,(void*)&iPid); sqlite3_stmt_scanstatus_v2(p, ii, SQLITE_SCANSTAT_NAME,f,(void*)&zName); - zText = sqlite3_mprintf("%s", z); + zText = sqlite3_mprintf("%s", zo); if( nCycle>=0 || nLoop>=0 || nRow>=0 ){ char *z = 0; if( nCycle>=0 && nTotal>0 ){ @@ -3372,8 +3498,9 @@ } eqp_render(pArg, nTotal); -#endif } +#endif + /* ** Parameter azArray points to a zero-terminated array of strings. zStr @@ -3411,8 +3538,6 @@ ** and "Goto" by 2 spaces. */ static void explain_data_prepare(ShellState *p, sqlite3_stmt *pSql){ - const char *zSql; /* The text of the SQL statement */ - const char *z; /* Used to check if this is an EXPLAIN */ int *abYield = 0; /* True if op is an OP_Yield */ int nAlloc = 0; /* Allocated size of p->aiIndent[], abYield */ int iOp; /* Index of operation in p->aiIndent[] */ @@ -3423,65 +3548,45 @@ "Rewind", 0 }; const char *azGoto[] = { "Goto", 0 }; - /* Try to figure out if this is really an EXPLAIN statement. If this - ** cannot be verified, return early. */ - if( sqlite3_column_count(pSql)!=8 ){ - p->cMode = p->mode; - return; - } - zSql = sqlite3_sql(pSql); - if( zSql==0 ) return; - for(z=zSql; *z==' ' || *z=='\t' || *z=='\n' || *z=='\f' || *z=='\r'; z++); - if( sqlite3_strnicmp(z, "explain", 7) ){ - p->cMode = p->mode; - return; - } + /* The caller guarantees that the leftmost 4 columns of the statement + ** passed to this function are equivalent to the leftmost 4 columns + ** of EXPLAIN statement output. In practice the statement may be + ** an EXPLAIN, or it may be a query on the bytecode() virtual table. */ + assert( sqlite3_column_count(pSql)>=4 ); + assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 0), "addr" ) ); + assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 1), "opcode" ) ); + assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 2), "p1" ) ); + assert( 0==sqlite3_stricmp( sqlite3_column_name(pSql, 3), "p2" ) ); for(iOp=0; SQLITE_ROW==sqlite3_step(pSql); iOp++){ int i; int iAddr = sqlite3_column_int(pSql, 0); const char *zOp = (const char*)sqlite3_column_text(pSql, 1); - - /* Set p2 to the P2 field of the current opcode. Then, assuming that - ** p2 is an instruction address, set variable p2op to the index of that - ** instruction in the aiIndent[] array. p2 and p2op may be different if - ** the current instruction is part of a sub-program generated by an - ** SQL trigger or foreign key. */ + int p1 = sqlite3_column_int(pSql, 2); int p2 = sqlite3_column_int(pSql, 3); + + /* Assuming that p2 is an instruction address, set variable p2op to the + ** index of that instruction in the aiIndent[] array. p2 and p2op may be + ** different if the current instruction is part of a sub-program generated + ** by an SQL trigger or foreign key. */ int p2op = (p2 + (iOp-iAddr)); /* Grow the p->aiIndent array as required */ if( iOp>=nAlloc ){ - if( iOp==0 ){ - /* Do further verfication that this is explain output. Abort if - ** it is not */ - static const char *explainCols[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment" }; - int jj; - for(jj=0; jjcMode = p->mode; - sqlite3_reset(pSql); - return; - } - } - } nAlloc += 100; p->aiIndent = (int*)sqlite3_realloc64(p->aiIndent, nAlloc*sizeof(int)); shell_check_oom(p->aiIndent); abYield = (int*)sqlite3_realloc64(abYield, nAlloc*sizeof(int)); shell_check_oom(abYield); } + abYield[iOp] = str_in_array(zOp, azYield); p->aiIndent[iOp] = 0; p->nIndent = iOp+1; - if( str_in_array(zOp, azNext) && p2op>0 ){ for(i=p2op; iaiIndent[i] += 2; } - if( str_in_array(zOp, azGoto) && p2opnIndent - && (abYield[p2op] || sqlite3_column_int(pSql, 2)) - ){ + if( str_in_array(zOp, azGoto) && p2opaiIndent[i] += 2; } } @@ -3501,6 +3606,48 @@ p->iIndent = 0; } +static void exec_prepared_stmt(ShellState*, sqlite3_stmt*); + +/* +** Display scan stats. +*/ +static void display_scanstats( + sqlite3 *db, /* Database to query */ + ShellState *pArg /* Pointer to ShellState */ +){ +#ifndef SQLITE_ENABLE_STMT_SCANSTATUS + UNUSED_PARAMETER(db); + UNUSED_PARAMETER(pArg); +#else + if( pArg->scanstatsOn==3 ){ + const char *zSql = + " SELECT addr, opcode, p1, p2, p3, p4, p5, comment, nexec," + " round(ncycle*100.0 / (sum(ncycle) OVER ()), 2)||'%' AS cycles" + " FROM bytecode(?)"; + + int rc = SQLITE_OK; + sqlite3_stmt *pStmt = 0; + rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); + if( rc==SQLITE_OK ){ + sqlite3_stmt *pSave = pArg->pStmt; + pArg->pStmt = pStmt; + sqlite3_bind_pointer(pStmt, 1, pSave, "stmt-pointer", 0); + + pArg->cnt = 0; + pArg->cMode = MODE_ScanExp; + explain_data_prepare(pArg, pStmt); + exec_prepared_stmt(pArg, pStmt); + explain_data_delete(pArg); + + sqlite3_finalize(pStmt); + pArg->pStmt = pSave; + } + }else{ + display_explain_scanstats(db, pArg); + } +#endif +} + /* ** Disable and restore .wheretrace and .treetrace/.selecttrace settings. */ @@ -3796,7 +3943,7 @@ */ static void exec_prepared_stmt_columnar( ShellState *p, /* Pointer to ShellState */ - sqlite3_stmt *pStmt /* Statment to run */ + sqlite3_stmt *pStmt /* Statement to run */ ){ sqlite3_int64 nRow = 0; int nColumn = 0; @@ -4022,7 +4169,7 @@ */ static void exec_prepared_stmt( ShellState *pArg, /* Pointer to ShellState */ - sqlite3_stmt *pStmt /* Statment to run */ + sqlite3_stmt *pStmt /* Statement to run */ ){ int rc; sqlite3_uint64 nRow = 0; @@ -4281,7 +4428,7 @@ if( zStmtSql==0 ) zStmtSql = ""; while( IsSpace(zStmtSql[0]) ) zStmtSql++; - /* save off the prepared statment handle and reset row count */ + /* save off the prepared statement handle and reset row count */ if( pArg ){ pArg->pStmt = pStmt; pArg->cnt = 0; @@ -4290,16 +4437,15 @@ /* Show the EXPLAIN QUERY PLAN if .eqp is on */ if( pArg && pArg->autoEQP && sqlite3_stmt_isexplain(pStmt)==0 ){ sqlite3_stmt *pExplain; - char *zEQP; int triggerEQP = 0; disable_debug_trace_modes(); sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, -1, &triggerEQP); if( pArg->autoEQP>=AUTOEQP_trigger ){ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 1, 0); } - zEQP = sqlite3_mprintf("EXPLAIN QUERY PLAN %s", zStmtSql); - shell_check_oom(zEQP); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + pExplain = pStmt; + sqlite3_reset(pExplain); + rc = sqlite3_stmt_explain(pExplain, 2); if( rc==SQLITE_OK ){ while( sqlite3_step(pExplain)==SQLITE_ROW ){ const char *zEQPLine = (const char*)sqlite3_column_text(pExplain,3); @@ -4311,36 +4457,31 @@ } eqp_render(pArg, 0); } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); if( pArg->autoEQP>=AUTOEQP_full ){ /* Also do an EXPLAIN for ".eqp full" mode */ - zEQP = sqlite3_mprintf("EXPLAIN %s", zStmtSql); - shell_check_oom(zEQP); - rc = sqlite3_prepare_v2(db, zEQP, -1, &pExplain, 0); + sqlite3_reset(pExplain); + rc = sqlite3_stmt_explain(pExplain, 1); if( rc==SQLITE_OK ){ pArg->cMode = MODE_Explain; + assert( sqlite3_stmt_isexplain(pExplain)==1 ); explain_data_prepare(pArg, pExplain); exec_prepared_stmt(pArg, pExplain); explain_data_delete(pArg); } - sqlite3_finalize(pExplain); - sqlite3_free(zEQP); } if( pArg->autoEQP>=AUTOEQP_trigger && triggerEQP==0 ){ sqlite3_db_config(db, SQLITE_DBCONFIG_TRIGGER_EQP, 0, 0); - /* Reprepare pStmt before reactiving trace modes */ - sqlite3_finalize(pStmt); - sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0); - if( pArg ) pArg->pStmt = pStmt; } + sqlite3_reset(pStmt); + sqlite3_stmt_explain(pStmt, 0); restore_debug_trace_modes(); } if( pArg ){ + int bIsExplain = (sqlite3_stmt_isexplain(pStmt)==1); pArg->cMode = pArg->mode; if( pArg->autoExplain ){ - if( sqlite3_stmt_isexplain(pStmt)==1 ){ + if( bIsExplain ){ pArg->cMode = MODE_Explain; } if( sqlite3_stmt_isexplain(pStmt)==2 ){ @@ -4350,7 +4491,7 @@ /* If the shell is currently in ".explain" mode, gather the extra ** data required to add indents to the output.*/ - if( pArg->cMode==MODE_Explain ){ + if( pArg->cMode==MODE_Explain && bIsExplain ){ explain_data_prepare(pArg, pStmt); } } @@ -4466,7 +4607,7 @@ */ if( preserveRowid && isIPK ){ /* If a single PRIMARY KEY column with type INTEGER was seen, then it - ** might be an alise for the ROWID. But it might also be a WITHOUT ROWID + ** 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 @@ -4727,7 +4868,6 @@ " --async Write to FILE without journal and fsync()", #endif ".bail on|off Stop after hitting an error. Default OFF", - ".binary on|off Turn binary output on or off. Default OFF", #ifndef SQLITE_SHELL_FIDDLE ".cd DIRECTORY Change the working directory to DIRECTORY", #endif @@ -4737,6 +4877,9 @@ ".clone NEWDB Clone data into NEWDB from the existing database", #endif ".connection [close] [#] Open or close an auxiliary database connection", +#if defined(_WIN32) || defined(WIN32) + ".crnl on|off Translate \\n to \\r\\n. Default ON", +#endif ".databases List names and files of attached databases", ".dbconfig ?op? ?val? List or change sqlite3_db_config() options", #if SQLITE_SHELL_HAVE_RECOVER @@ -5443,7 +5586,7 @@ /* Let custom-included extensions get their ..._init() called. * The WHATEVER_INIT( db, pzErrorMsg, pApi ) macro should cause * the extension's sqlite3_*_init( db, pzErrorMsg, pApi ) - * inititialization routine to be called. + * initialization routine to be called. */ { int irc = SHELL_SUBMACRO(SQLITE_SHELL_EXTFUNCS, INIT)(p->db); @@ -5461,6 +5604,12 @@ } #endif + sqlite3_create_function(p->db, "strtod", 1, SQLITE_UTF8, 0, + shellStrtod, 0, 0); + sqlite3_create_function(p->db, "dtostr", 1, SQLITE_UTF8, 0, + shellDtostr, 0, 0); + sqlite3_create_function(p->db, "dtostr", 2, SQLITE_UTF8, 0, + shellDtostr, 0, 0); sqlite3_create_function(p->db, "shell_add_schema", 3, SQLITE_UTF8, 0, shellAddSchemaName, 0, 0); sqlite3_create_function(p->db, "shell_module_schema", 1, SQLITE_UTF8, 0, @@ -5520,7 +5669,7 @@ } /* -** Attempt to close the databaes connection. Report errors. +** Attempt to close the database connection. Report errors. */ void close_db(sqlite3 *db){ int rc = sqlite3_close(db); @@ -6014,7 +6163,7 @@ if( rc ){ utf8_printf(stderr, "Error %d: %s on [%s]\n", sqlite3_extended_errcode(newDb), sqlite3_errmsg(newDb), - zQuery); + zInsert); goto end_data_xfer; } for(k=0; k<2; k++){ @@ -7967,7 +8116,6 @@ azArg[nArg++] = &zLine[h]; while( zLine[h] && !IsSpace(zLine[h]) ){ h++; } if( zLine[h] ) zLine[h++] = 0; - resolve_backslashes(azArg[nArg-1]); } } azArg[nArg] = 0; @@ -8086,6 +8234,7 @@ } }else + /* Undocumented. Legacy only. See "crnl" below */ if( c=='b' && n>=3 && cli_strncmp(azArg[0], "binary", n)==0 ){ if( nArg==2 ){ if( booleanValue(azArg[1]) ){ @@ -8094,6 +8243,8 @@ setTextMode(p->out, 1); } }else{ + raw_printf(stderr, "The \".binary\" command is deprecated." + " Use \".crnl\" instead.\n"); raw_printf(stderr, "Usage: .binary on|off\n"); rc = 1; } @@ -8221,6 +8372,22 @@ } }else + if( c=='c' && n==4 && cli_strncmp(azArg[0], "crnl", n)==0 ){ + if( nArg==2 ){ + if( booleanValue(azArg[1]) ){ + setTextMode(p->out, 1); + }else{ + setBinaryMode(p->out, 1); + } + }else{ +#if !defined(_WIN32) && !defined(WIN32) + raw_printf(stderr, "The \".crnl\" is a no-op on non-Windows machines.\n"); +#endif + raw_printf(stderr, "Usage: .crnl on|off\n"); + rc = 1; + } + }else + if( c=='d' && n>1 && cli_strncmp(azArg[0], "databases", n)==0 ){ char **azName = 0; int nName = 0; @@ -8687,8 +8854,10 @@ "SELECT rowid FROM sqlite_schema" " WHERE name GLOB 'sqlite_stat[134]'", -1, &pStmt, 0); - doStats = sqlite3_step(pStmt)==SQLITE_ROW; - sqlite3_finalize(pStmt); + if( rc==SQLITE_OK ){ + doStats = sqlite3_step(pStmt)==SQLITE_ROW; + sqlite3_finalize(pStmt); + } } if( doStats==0 ){ raw_printf(p->out, "/* No STAT tables available */\n"); @@ -8977,6 +9146,14 @@ ** the remaining columns. */ if( p->mode==MODE_Ascii && (z==0 || z[0]==0) && i==0 ) break; + /* + ** For CSV mode, per RFC 4180, accept EOF in lieu of final + ** record terminator but only for last field of multi-field row. + ** (If there are too few fields, it's not valid CSV anyway.) + */ + if( z==0 && (xRead==csv_read_one_field) && i==nCol-1 && i>0 ){ + z = ""; + } sqlite3_bind_text(pStmt, i+1, z, -1, SQLITE_TRANSIENT); if( iscanstatsOn = 3; + }else if( cli_strcmp(azArg[1], "est")==0 ){ p->scanstatsOn = 2; }else{ @@ -10530,7 +10710,8 @@ "with tabcols as materialized(\n" "select tname, cname\n" "from (" - " select ss.tname as tname, ti.name as cname\n" + " select printf('\"%%w\"',ss.tname) as tname," + " printf('\"%%w\"',ti.name) as cname\n" " from (%z) ss\n inner join pragma_table_info(tname) ti))\n" "select 'SELECT total(bad_text_count) AS bad_text_count\n" "FROM ('||group_concat(query, ' UNION ALL ')||')' as btc_query\n" @@ -10802,7 +10983,7 @@ static const struct { const char *zCtrlName; /* Name of a test-control option */ int ctrlCode; /* Integer code for that option */ - int unSafe; /* Not valid for --safe mode */ + int unSafe; /* Not valid unless --unsafe-testing */ const char *zUsage; /* Usage notes */ } aCtrl[] = { {"always", SQLITE_TESTCTRL_ALWAYS, 1, "BOOLEAN" }, @@ -10812,6 +10993,7 @@ {"byteorder", SQLITE_TESTCTRL_BYTEORDER, 0, "" }, {"extra_schema_checks",SQLITE_TESTCTRL_EXTRA_SCHEMA_CHECKS,0,"BOOLEAN" }, /*{"fault_install", SQLITE_TESTCTRL_FAULT_INSTALL, 1,"" },*/ + {"fk_no_action", SQLITE_TESTCTRL_FK_NO_ACTION, 0, "BOOLEAN" }, {"imposter", SQLITE_TESTCTRL_IMPOSTER,1,"SCHEMA ON/OFF ROOTPAGE"}, {"internal_functions", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS,0,"" }, {"localtime_fault", SQLITE_TESTCTRL_LOCALTIME_FAULT,0,"BOOLEAN" }, @@ -10827,6 +11009,7 @@ {"seek_count", SQLITE_TESTCTRL_SEEK_COUNT, 0, "" }, {"sorter_mmap", SQLITE_TESTCTRL_SORTER_MMAP, 0, "NMAX" }, {"tune", SQLITE_TESTCTRL_TUNE, 1, "ID VALUE" }, + {"uselongdouble", SQLITE_TESTCTRL_USELONGDOUBLE,0,"?BOOLEAN|\"default\"?"}, }; int testctrl = -1; int iCtrl = -1; @@ -10835,12 +11018,6 @@ int i, n2; const char *zCmd = 0; - if( !ShellHasFlag(p,SHFLG_TestingMode) ){ - utf8_printf(stderr, ".%s unavailable without --unsafe-testing\n", - "testctrl"); - rc = 1; - goto meta_command_exit; - } open_db(p, 0); zCmd = nArg>=2 ? azArg[1] : "help"; @@ -10854,6 +11031,7 @@ if( cli_strcmp(zCmd,"help")==0 ){ utf8_printf(p->out, "Available test-controls:\n"); for(i=0; iout, " .testctrl %s %s\n", aCtrl[i].zCtrlName, aCtrl[i].zUsage); } @@ -10865,6 +11043,7 @@ ** of the option name, or a numerical value. */ n2 = strlen30(zCmd); for(i=0; ibSafeMode ){ - utf8_printf(stderr, - "line %d: \".testctrl %s\" may not be used in safe mode\n", - p->lineno, aCtrl[iCtrl].zCtrlName); - exit(1); }else{ switch(testctrl){ /* sqlite3_test_control(int, db, int) */ case SQLITE_TESTCTRL_OPTIMIZATIONS: + case SQLITE_TESTCTRL_FK_NO_ACTION: if( nArg==3 ){ unsigned int opt = (unsigned int)strtol(azArg[2], 0, 0); rc2 = sqlite3_test_control(testctrl, p->db, opt); @@ -10957,6 +11132,21 @@ } break; + /* sqlite3_test_control(int, int) */ + case SQLITE_TESTCTRL_USELONGDOUBLE: { + int opt = -1; + if( nArg==3 ){ + if( cli_strcmp(azArg[2],"default")==0 ){ + opt = 2; + }else{ + opt = booleanValue(azArg[2]); + } + } + rc2 = sqlite3_test_control(testctrl, opt); + isOk = 1; + break; + } + /* sqlite3_test_control(sqlite3*) */ case SQLITE_TESTCTRL_INTERNAL_FUNCTIONS: rc2 = sqlite3_test_control(testctrl, p->db); @@ -11194,6 +11384,7 @@ #endif /* SQLITE_USER_AUTHENTICATION */ if( c=='v' && cli_strncmp(azArg[0], "version", n)==0 ){ + char *zPtrSz = sizeof(void*)==8 ? "64-bit" : "32-bit"; utf8_printf(p->out, "SQLite %s %s\n" /*extra-version-info*/, sqlite3_libversion(), sqlite3_sourceid()); #if SQLITE_HAVE_ZLIB @@ -11204,11 +11395,11 @@ #if defined(__clang__) && defined(__clang_major__) utf8_printf(p->out, "clang-" CTIMEOPT_VAL(__clang_major__) "." CTIMEOPT_VAL(__clang_minor__) "." - CTIMEOPT_VAL(__clang_patchlevel__) "\n"); + CTIMEOPT_VAL(__clang_patchlevel__) " (%s)\n", zPtrSz); #elif defined(_MSC_VER) - utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) "\n"); + utf8_printf(p->out, "msvc-" CTIMEOPT_VAL(_MSC_VER) " (%s)\n", zPtrSz); #elif defined(__GNUC__) && defined(__VERSION__) - utf8_printf(p->out, "gcc-" __VERSION__ "\n"); + utf8_printf(p->out, "gcc-" __VERSION__ " (%s)\n", zPtrSz); #endif }else @@ -11826,10 +12017,14 @@ " -multiplex enable the multiplexor VFS\n" #endif " -newline SEP set output row separator. Default: '\\n'\n" +#if SHELL_WIN_UTF8_OPT + " -no-utf8 do not try to set up UTF-8 output (for legacy)\n" +#endif " -nofollow refuse to open symbolic links to database files\n" " -nonce STRING set the safe-mode escape nonce\n" " -nullvalue TEXT set text string for NULL values. Default ''\n" " -pagecache SIZE N use N slots of SZ bytes each for page cache memory\n" + " -pcachetrace trace all page cache operations\n" " -quote set output mode to 'quote'\n" " -readonly open the database read-only\n" " -safe enable safe-mode\n" @@ -11841,7 +12036,7 @@ " -table set output mode to 'table'\n" " -tabs set output mode to 'tabs'\n" " -unsafe-testing allow unsafe commands and modes for testing\n" -#if SHELL_WIN_UTF8_OPT +#if SHELL_WIN_UTF8_OPT && 0 /* Option is accepted, but is now the default. */ " -utf8 setup interactive console code page for UTF-8\n" #endif " -version show SQLite version\n" @@ -11992,7 +12187,8 @@ stdout_is_console = isatty(1); #endif #if SHELL_WIN_UTF8_OPT - atexit(console_restore); /* Needs revision for CLI as library call */ + probe_console(); /* Check for console I/O and UTF-8 capability. */ + if( !mbcs_opted ) atexit(console_restore); #endif atexit(sayAbnormalExit); #ifdef SQLITE_DEBUG @@ -12079,8 +12275,8 @@ /* Do an initial pass through the command-line argument to locate ** the name of the database file, the name of the initialization file, - ** the size of the alternative malloc heap, - ** and the first command to execute. + ** the size of the alternative malloc heap, options affecting commands + ** or SQL run from the command line, and the first command to execute. */ #ifndef SQLITE_SHELL_FIDDLE verify_uninitialized(); @@ -12092,7 +12288,7 @@ if( data.aAuxDb->zDbFilename==0 ){ data.aAuxDb->zDbFilename = z; }else{ - /* Excesss arguments are interpreted as SQL (or dot-commands) and + /* Excess arguments are interpreted as SQL (or dot-commands) and ** mean that nothing is read from stdin */ readStdin = 0; nCmd++; @@ -12114,12 +12310,26 @@ (void)cmdline_option_value(argc, argv, ++i); }else if( cli_strcmp(z,"-init")==0 ){ zInitFile = cmdline_option_value(argc, argv, ++i); + }else if( cli_strcmp(z,"-interactive")==0 ){ + /* Need to check for interactive override here to so that it can + ** affect console setup (for Windows only) and testing thereof. + */ + stdin_is_interactive = 1; }else if( cli_strcmp(z,"-batch")==0 ){ /* Need to check for batch mode here to so we can avoid printing ** informational messages (like from process_sqliterc) before ** we do the actual processing of arguments later in a second pass. */ stdin_is_interactive = 0; + }else if( cli_strcmp(z,"-utf8")==0 ){ +#if SHELL_WIN_UTF8_OPT + /* Option accepted, but is ignored except for this diagnostic. */ + if( mbcs_opted ) fprintf(stderr, "Cannot do UTF-8 at this console.\n"); +#endif /* SHELL_WIN_UTF8_OPT */ + }else if( cli_strcmp(z,"-no-utf8")==0 ){ +#if SHELL_WIN_UTF8_OPT + mbcs_opted = 1; +#endif /* SHELL_WIN_UTF8_OPT */ }else if( cli_strcmp(z,"-heap")==0 ){ #if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5) const char *zSize; @@ -12177,7 +12387,7 @@ #endif #ifdef SQLITE_ENABLE_MULTIPLEX }else if( cli_strcmp(z,"-multiplex")==0 ){ - extern int sqlite3_multiple_initialize(const char*,int); + extern int sqlite3_multiplex_initialize(const char*,int); sqlite3_multiplex_initialize(0, 1); #endif }else if( cli_strcmp(z,"-mmap")==0 ){ @@ -12216,11 +12426,13 @@ #endif }else if( cli_strcmp(z, "-memtrace")==0 ){ sqlite3MemTraceActivate(stderr); + }else if( cli_strcmp(z, "-pcachetrace")==0 ){ + sqlite3PcacheTraceActivate(stderr); }else if( cli_strcmp(z,"-bail")==0 ){ bail_on_error = 1; }else if( cli_strcmp(z,"-nonce")==0 ){ free(data.zNonce); - data.zNonce = strdup(argv[++i]); + data.zNonce = strdup(cmdline_option_value(argc, argv, ++i)); }else if( cli_strcmp(z,"-unsafe-testing")==0 ){ ShellSetFlag(&data,SHFLG_TestingMode); }else if( cli_strcmp(z,"-safe")==0 ){ @@ -12256,6 +12468,15 @@ exit(1); } } +#if SHELL_WIN_UTF8_OPT + /* Get indicated Windows console setup done before running invocation commands. */ + if( in_console || out_console ){ + console_prepare_utf8(); + } + if( !in_console ){ + setBinaryMode(stdin, 0); + } +#endif if( data.pAuxDb->zDbFilename==0 ){ #ifndef SQLITE_OMIT_MEMORYDB @@ -12379,16 +12600,17 @@ }else if( cli_strcmp(z,"-bail")==0 ){ /* No-op. The bail_on_error flag should already be set. */ }else if( cli_strcmp(z,"-version")==0 ){ - printf("%s %s\n", sqlite3_libversion(), sqlite3_sourceid()); + printf("%s %s (%d-bit)\n", sqlite3_libversion(), sqlite3_sourceid(), + 8*(int)sizeof(char*)); return 0; }else if( cli_strcmp(z,"-interactive")==0 ){ - stdin_is_interactive = 1; + /* already handled */ }else if( cli_strcmp(z,"-batch")==0 ){ - stdin_is_interactive = 0; + /* already handled */ }else if( cli_strcmp(z,"-utf8")==0 ){ -#if SHELL_WIN_UTF8_OPT - console_utf8 = 1; -#endif /* SHELL_WIN_UTF8_OPT */ + /* already handled */ + }else if( cli_strcmp(z,"-no-utf8")==0 ){ + /* already handled */ }else if( cli_strcmp(z,"-heap")==0 ){ i++; }else if( cli_strcmp(z,"-pagecache")==0 ){ @@ -12403,6 +12625,8 @@ i++; }else if( cli_strcmp(z,"-memtrace")==0 ){ i++; + }else if( cli_strcmp(z,"-pcachetrace")==0 ){ + i++; #ifdef SQLITE_ENABLE_SORTER_REFERENCES }else if( cli_strcmp(z,"-sorterref")==0 ){ i++; @@ -12468,14 +12692,6 @@ } data.cMode = data.mode; } -#if SHELL_WIN_UTF8_OPT - if( console_utf8 && stdin_is_interactive ){ - console_prepare(); - }else{ - setBinaryMode(stdin, 0); - console_utf8 = 0; - } -#endif if( !readStdin ){ /* Run all arguments that do not begin with '-' as if they were separate @@ -12511,11 +12727,20 @@ if( stdin_is_interactive ){ char *zHome; char *zHistory; + const char *zCharset = ""; int nHistory; +#if SHELL_WIN_UTF8_OPT + switch( console_utf8_in+2*console_utf8_out ){ + default: case 0: break; + case 1: zCharset = " (utf8 in)"; break; + case 2: zCharset = " (utf8 out)"; break; + case 3: zCharset = " (utf8 I/O)"; break; + } +#endif printf( - "SQLite version %s %.19s\n" /*extra-version-info*/ + "SQLite version %s %.19s%s\n" /*extra-version-info*/ "Enter \".help\" for usage hints.\n", - sqlite3_libversion(), sqlite3_sourceid() + sqlite3_libversion(), sqlite3_sourceid(), zCharset ); if( warnInmemoryDb ){ printf("Connected to a "); diff -Nru sqlite3-3.42.0/src/sqlite3ext.h sqlite3-3.44.0-0/src/sqlite3ext.h --- sqlite3-3.42.0/src/sqlite3ext.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/sqlite3ext.h 2023-11-04 14:23:58.000000000 +0000 @@ -361,6 +361,11 @@ int (*value_encoding)(sqlite3_value*); /* Version 3.41.0 and later */ int (*is_interrupted)(sqlite3*); + /* Version 3.43.0 and later */ + int (*stmt_explain)(sqlite3_stmt*,int); + /* Version 3.44.0 and later */ + void *(*get_clientdata)(sqlite3*,const char*); + int (*set_clientdata)(sqlite3*, const char*, void*, void(*)(void*)); }; /* @@ -689,6 +694,11 @@ #define sqlite3_value_encoding sqlite3_api->value_encoding /* Version 3.41.0 and later */ #define sqlite3_is_interrupted sqlite3_api->is_interrupted +/* Version 3.43.0 and later */ +#define sqlite3_stmt_explain sqlite3_api->stmt_explain +/* Version 3.44.0 and later */ +#define sqlite3_get_clientdata sqlite3_api->get_clientdata +#define sqlite3_set_clientdata sqlite3_api->set_clientdata #endif /* !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) */ #if !defined(SQLITE_CORE) && !defined(SQLITE_OMIT_LOAD_EXTENSION) diff -Nru sqlite3-3.42.0/src/sqlite.h.in sqlite3-3.44.0-0/src/sqlite.h.in --- sqlite3-3.42.0/src/sqlite.h.in 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/sqlite.h.in 2023-11-04 14:23:58.000000000 +0000 @@ -131,7 +131,7 @@ ** be held constant and Z will be incremented or else Y will be incremented ** and Z will be reset to zero. ** -** Since [version 3.6.18] ([dateof:3.6.18]), +** Since [version 3.6.18] ([dateof:3.6.18]), ** SQLite source code has been stored in the ** Fossil configuration management ** system. ^The SQLITE_SOURCE_ID macro evaluates to @@ -528,6 +528,7 @@ #define SQLITE_IOERR_ROLLBACK_ATOMIC (SQLITE_IOERR | (31<<8)) #define SQLITE_IOERR_DATA (SQLITE_IOERR | (32<<8)) #define SQLITE_IOERR_CORRUPTFS (SQLITE_IOERR | (33<<8)) +#define SQLITE_IOERR_IN_PAGE (SQLITE_IOERR | (34<<8)) #define SQLITE_LOCKED_SHAREDCACHE (SQLITE_LOCKED | (1<<8)) #define SQLITE_LOCKED_VTAB (SQLITE_LOCKED | (2<<8)) #define SQLITE_BUSY_RECOVERY (SQLITE_BUSY | (1<<8)) @@ -716,7 +717,7 @@ /* ** CAPI3REF: OS Interface Open File Handle ** -** An [sqlite3_file] object represents an open file in the +** An [sqlite3_file] object represents an open file in the ** [sqlite3_vfs | OS interface layer]. Individual OS interface ** implementations will ** want to subclass this object by appending additional fields @@ -738,7 +739,7 @@ ** This object defines the methods used to perform various operations ** against the open file represented by the [sqlite3_file] object. ** -** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element +** If the [sqlite3_vfs.xOpen] method sets the sqlite3_file.pMethods element ** to a non-NULL pointer, then the sqlite3_io_methods.xClose method ** may be invoked even if the [sqlite3_vfs.xOpen] reported that it failed. The ** only way to prevent a call to xClose following a failed [sqlite3_vfs.xOpen] @@ -982,13 +983,13 @@ **
  • [[SQLITE_FCNTL_OVERWRITE]] ** ^The [SQLITE_FCNTL_OVERWRITE] opcode is invoked by SQLite after opening ** a write transaction to indicate that, unless it is rolled back for some -** reason, the entire database file will be overwritten by the current +** reason, the entire database file will be overwritten by the current ** transaction. This is used by VACUUM operations. ** **
  • [[SQLITE_FCNTL_VFSNAME]] ** ^The [SQLITE_FCNTL_VFSNAME] opcode can be used to obtain the names of ** all [VFSes] in the VFS stack. The names are of all VFS shims and the -** final bottom-level VFS are written into memory obtained from +** final bottom-level VFS are written into memory obtained from ** [sqlite3_malloc()] and the result is stored in the char* variable ** that the fourth parameter of [sqlite3_file_control()] points to. ** The caller is responsible for freeing the memory when done. As with @@ -1179,22 +1180,22 @@ ** **
  • [[SQLITE_FCNTL_EXTERNAL_READER]] ** The EXPERIMENTAL [SQLITE_FCNTL_EXTERNAL_READER] opcode is used to detect -** whether or not there is a database client in another process with a wal-mode +** whether or not there is a database client in another process with a wal-mode ** transaction open on the database or not. It is only available on unix.The ** (void*) argument passed with this file-control should be a pointer to a ** value of type (int). The integer value is set to 1 if the database is a wal ** mode database and there exists at least one client in another process that -** currently has an SQL transaction open on the database. It is set to 0 if +** currently has an SQL transaction open on the database. It is set to 0 if ** the database is not a wal-mode db, or if there is no such connection in any ** other process. This opcode cannot be used to detect transactions opened ** by clients within the current process, only within other processes. ** **
  • [[SQLITE_FCNTL_CKSM_FILE]] -** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use interally by the +** The [SQLITE_FCNTL_CKSM_FILE] opcode is for use internally by the ** [checksum VFS shim] only. ** **
  • [[SQLITE_FCNTL_RESET_CACHE]] -** If there is currently no transaction open on the database, and the +** If there is currently no transaction open on the database, and the ** database is not a temp db, then the [SQLITE_FCNTL_RESET_CACHE] file-control ** purges the contents of the in-memory page cache. If there is an open ** transaction, or if the db is a temp-db, this opcode is a no-op, not an error. @@ -1496,7 +1497,7 @@ /* ** The methods above are in versions 1 through 3 of the sqlite_vfs object. ** New fields may be appended in future versions. The iVersion - ** value will increment whenever this happens. + ** value will increment whenever this happens. */ }; @@ -1688,7 +1689,7 @@ ** [database connection] (specified in the first argument). ** ** The second argument to sqlite3_db_config(D,V,...) is the -** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code +** [SQLITE_DBCONFIG_LOOKASIDE | configuration verb] - an integer code ** that indicates what aspect of the [database connection] is being configured. ** Subsequent arguments vary depending on the configuration verb. ** @@ -1736,7 +1737,7 @@ ** allocators round up memory allocations at least to the next multiple ** of 8. Some allocators round up to a larger multiple or to a power of 2. ** Every memory allocation request coming in through [sqlite3_malloc()] -** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, +** or [sqlite3_realloc()] first calls xRoundup. If xRoundup returns 0, ** that causes the corresponding memory allocation to fail. ** ** The xInit method initializes the memory allocator. For example, @@ -1811,7 +1812,7 @@ ** by a single thread. ^If SQLite is compiled with ** the [SQLITE_THREADSAFE | SQLITE_THREADSAFE=0] compile-time option then ** it is not possible to change the [threading mode] from its default -** value of Single-thread and so [sqlite3_config()] will return +** value of Single-thread and so [sqlite3_config()] will return ** [SQLITE_ERROR] if called with the SQLITE_CONFIG_SINGLETHREAD ** configuration option. ** @@ -2126,7 +2127,7 @@ ** is stored in each sorted record and the required column values loaded ** from the database as records are returned in sorted order. The default ** value for this option is to never use this optimization. Specifying a -** negative value for this option restores the default behaviour. +** negative value for this option restores the default behavior. ** This option is only available if SQLite is compiled with the ** [SQLITE_ENABLE_SORTER_REFERENCES] compile-time option. ** @@ -2295,13 +2296,13 @@ ** until after the database connection closes. ** ** -** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] +** [[SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE]] **
    SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    -**
    Usually, when a database in wal mode is closed or detached from a -** database handle, SQLite checks if this will mean that there are now no -** connections at all to the database. If so, it performs a checkpoint +**
    Usually, when a database in wal mode is closed or detached from a +** database handle, SQLite checks if this will mean that there are now no +** connections at all to the database. If so, it performs a checkpoint ** operation before closing the connection. This option may be used to -** override this behaviour. The first parameter passed to this operation +** override this behavior. The first parameter passed to this operation ** is an integer - positive to disable checkpoints-on-close, or zero (the ** default) to enable them, and negative to leave the setting unchanged. ** The second parameter is a pointer to an integer @@ -2318,7 +2319,7 @@ ** slower. But the QPSG has the advantage of more predictable behavior. With ** the QPSG active, SQLite will always use the same query plan in the field as ** was used during testing in the lab. -** The first argument to this setting is an integer which is 0 to disable +** The first argument to this setting is an integer which is 0 to disable ** the QPSG, positive to enable QPSG, or negative to leave the setting ** unchanged. The second parameter is a pointer to an integer into which ** is written 0 or 1 to indicate whether the QPSG is disabled or enabled @@ -2326,15 +2327,15 @@ **
    ** ** [[SQLITE_DBCONFIG_TRIGGER_EQP]]
    SQLITE_DBCONFIG_TRIGGER_EQP
    -**
    By default, the output of EXPLAIN QUERY PLAN commands does not +**
    By default, the output of EXPLAIN QUERY PLAN commands does not ** include output for any operations performed by trigger programs. This ** option is used to set or clear (the default) a flag that governs this ** behavior. The first parameter passed to this operation is an integer - ** positive to enable output for trigger programs, or zero to disable it, ** or negative to leave the setting unchanged. -** The second parameter is a pointer to an integer into which is written -** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if -** it is not disabled, 1 if it is. +** The second parameter is a pointer to an integer into which is written +** 0 or 1 to indicate whether output-for-triggers has been disabled - 0 if +** it is not disabled, 1 if it is. **
    ** ** [[SQLITE_DBCONFIG_RESET_DATABASE]]
    SQLITE_DBCONFIG_RESET_DATABASE
    @@ -2348,7 +2349,7 @@ ** database, or calling sqlite3_table_column_metadata(), ignoring any ** errors. This step is only necessary if the application desires to keep ** the database in WAL mode after the reset if it was in WAL mode before -** the reset. +** the reset. **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 1, 0); **
  • [sqlite3_exec](db, "[VACUUM]", 0, 0, 0); **
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); @@ -2364,7 +2365,7 @@ ** [[SQLITE_DBCONFIG_DEFENSIVE]]
    SQLITE_DBCONFIG_DEFENSIVE
    **
    The SQLITE_DBCONFIG_DEFENSIVE option activates or deactivates the ** "defensive" flag for a database connection. When the defensive -** flag is enabled, language features that allow ordinary SQL to +** flag is enabled, language features that allow ordinary SQL to ** deliberately corrupt the database file are disabled. The disabled ** features include but are not limited to the following: **
      @@ -2380,7 +2381,7 @@ **
      The SQLITE_DBCONFIG_WRITABLE_SCHEMA option activates or deactivates the ** "writable_schema" flag. This has the same effect and is logically equivalent ** to setting [PRAGMA writable_schema=ON] or [PRAGMA writable_schema=OFF]. -** The first argument to this setting is an integer which is 0 to disable +** The first argument to this setting is an integer which is 0 to disable ** the writable_schema, positive to enable writable_schema, or negative to ** leave the setting unchanged. The second parameter is a pointer to an ** integer into which is written 0 or 1 to indicate whether the writable_schema @@ -2424,7 +2425,7 @@ ** including: **
        **
      • Prohibit the use of SQL functions inside triggers, views, -** CHECK constraints, DEFAULT clauses, expression indexes, +** CHECK constraints, DEFAULT clauses, expression indexes, ** partial indexes, or generated columns ** unless those functions are tagged with [SQLITE_INNOCUOUS]. **
      • Prohibit the use of virtual tables inside of triggers or views @@ -2445,7 +2446,7 @@ ** any SQLite version back to 3.0.0 ([dateof:3.0.0]). Without this setting, ** newly created databases are generally not understandable by SQLite versions ** prior to 3.3.0 ([dateof:3.3.0]). As these words are written, there -** is now scarcely any need to generate database files that are compatible +** is now scarcely any need to generate database files that are compatible ** all the way back to version 3.0.0, and so this setting is of little ** practical use, but is provided so that SQLite can continue to claim the ** ability to generate new database files that are compatible with version @@ -2454,7 +2455,7 @@ ** the [VACUUM] command will fail with an obscure error when attempting to ** process a table with generated columns and a descending index. This is ** not considered a bug since SQLite versions 3.3.0 and earlier do not support -** either generated columns or decending indexes. +** either generated columns or descending indexes. **
      ** ** [[SQLITE_DBCONFIG_STMT_SCANSTATUS]] @@ -2463,7 +2464,7 @@ ** SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears ** a flag that enables collection of the sqlite3_stmt_scanstatus_v2() ** statistics. For statistics to be collected, the flag must be set on -** the database handle both when the SQL statement is prepared and when it +** the database handle both when the SQL statement is prepared and when it ** is stepped. The flag is set (collection of statistics is enabled) ** by default. This option takes two arguments: an integer and a pointer to ** an integer.. The first argument is 1, 0, or -1 to enable, disable, or @@ -2537,8 +2538,8 @@ ** ^The sqlite3_last_insert_rowid(D) interface usually returns the [rowid] of ** the most recent successful [INSERT] into a rowid table or [virtual table] ** on database connection D. ^Inserts into [WITHOUT ROWID] tables are not -** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred -** on the database connection D, then sqlite3_last_insert_rowid(D) returns +** recorded. ^If no successful [INSERT]s into rowid tables have ever occurred +** on the database connection D, then sqlite3_last_insert_rowid(D) returns ** zero. ** ** As well as being set automatically as rows are inserted into database @@ -2548,15 +2549,15 @@ ** Some virtual table implementations may INSERT rows into rowid tables as ** part of committing a transaction (e.g. to flush data accumulated in memory ** to disk). In this case subsequent calls to this function return the rowid -** associated with these internal INSERT operations, which leads to +** associated with these internal INSERT operations, which leads to ** unintuitive results. Virtual table implementations that do write to rowid -** tables in this way can avoid this problem by restoring the original -** rowid value using [sqlite3_set_last_insert_rowid()] before returning +** tables in this way can avoid this problem by restoring the original +** rowid value using [sqlite3_set_last_insert_rowid()] before returning ** control to the user. ** -** ^(If an [INSERT] occurs within a trigger then this routine will -** return the [rowid] of the inserted row as long as the trigger is -** running. Once the trigger program ends, the value returned +** ^(If an [INSERT] occurs within a trigger then this routine will +** return the [rowid] of the inserted row as long as the trigger is +** running. Once the trigger program ends, the value returned ** by this routine reverts to what it was before the trigger was fired.)^ ** ** ^An [INSERT] that fails due to a constraint violation is not a @@ -2589,7 +2590,7 @@ ** METHOD: sqlite3 ** ** The sqlite3_set_last_insert_rowid(D, R) method allows the application to -** set the value returned by calling sqlite3_last_insert_rowid(D) to R +** set the value returned by calling sqlite3_last_insert_rowid(D) to R ** without inserting a row into the database. */ void sqlite3_set_last_insert_rowid(sqlite3*,sqlite3_int64); @@ -2602,43 +2603,43 @@ ** deleted by the most recently completed INSERT, UPDATE or DELETE ** statement on the database connection specified by the only parameter. ** The two functions are identical except for the type of the return value -** and that if the number of rows modified by the most recent INSERT, UPDATE +** and that if the number of rows modified by the most recent INSERT, UPDATE ** or DELETE is greater than the maximum value supported by type "int", then ** the return value of sqlite3_changes() is undefined. ^Executing any other ** type of SQL statement does not modify the value returned by these functions. ** ** ^Only changes made directly by the INSERT, UPDATE or DELETE statement are -** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], +** considered - auxiliary changes caused by [CREATE TRIGGER | triggers], ** [foreign key actions] or [REPLACE] constraint resolution are not counted. -** -** Changes to a view that are intercepted by -** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value -** returned by sqlite3_changes() immediately after an INSERT, UPDATE or -** DELETE statement run on a view is always zero. Only changes made to real +** +** Changes to a view that are intercepted by +** [INSTEAD OF trigger | INSTEAD OF triggers] are not counted. ^The value +** returned by sqlite3_changes() immediately after an INSERT, UPDATE or +** DELETE statement run on a view is always zero. Only changes made to real ** tables are counted. ** ** Things are more complicated if the sqlite3_changes() function is ** executed while a trigger program is running. This may happen if the ** program uses the [changes() SQL function], or if some other callback ** function invokes sqlite3_changes() directly. Essentially: -** +** **
        **
      • ^(Before entering a trigger program the value returned by -** sqlite3_changes() function is saved. After the trigger program +** sqlite3_changes() function is saved. After the trigger program ** has finished, the original value is restored.)^ -** -**
      • ^(Within a trigger program each INSERT, UPDATE and DELETE -** statement sets the value returned by sqlite3_changes() -** upon completion as normal. Of course, this value will not include -** any changes performed by sub-triggers, as the sqlite3_changes() +** +**
      • ^(Within a trigger program each INSERT, UPDATE and DELETE +** statement sets the value returned by sqlite3_changes() +** upon completion as normal. Of course, this value will not include +** any changes performed by sub-triggers, as the sqlite3_changes() ** value will be saved and restored after each sub-trigger has run.)^ **
      -** +** ** ^This means that if the changes() SQL function (or similar) is used -** by the first INSERT, UPDATE or DELETE statement within a trigger, it +** by the first INSERT, UPDATE or DELETE statement within a trigger, it ** returns the value as set when the calling statement began executing. -** ^If it is used by the second or subsequent such statement within a trigger -** program, the value returned reflects the number of rows modified by the +** ^If it is used by the second or subsequent such statement within a trigger +** program, the value returned reflects the number of rows modified by the ** previous INSERT, UPDATE or DELETE statement within the same trigger. ** ** If a separate thread makes changes on the same database connection @@ -2663,16 +2664,16 @@ ** ^These functions return the total number of rows inserted, modified or ** deleted by all [INSERT], [UPDATE] or [DELETE] statements completed ** since the database connection was opened, including those executed as -** part of trigger programs. The two functions are identical except for the -** type of the return value and that if the number of rows modified by the +** part of trigger programs. The two functions are identical except for the +** type of the return value and that if the number of rows modified by the ** connection exceeds the maximum value supported by type "int", then -** the return value of sqlite3_total_changes() is undefined. ^Executing -** any other type of SQL statement does not affect the value returned by +** the return value of sqlite3_total_changes() is undefined. ^Executing +** any other type of SQL statement does not affect the value returned by ** sqlite3_total_changes(). -** +** ** ^Changes made as part of [foreign key actions] are included in the ** count, but those made as part of REPLACE constraint resolution are -** not. ^Changes to a view that are intercepted by INSTEAD OF triggers +** not. ^Changes to a view that are intercepted by INSTEAD OF triggers ** are not counted. ** ** The [sqlite3_total_changes(D)] interface only reports the number @@ -2681,7 +2682,7 @@ ** To detect changes against a database file from other database ** connections use the [PRAGMA data_version] command or the ** [SQLITE_FCNTL_DATA_VERSION] [file control]. -** +** ** If a separate thread makes changes on the same database connection ** while [sqlite3_total_changes()] is running then the value ** returned is unpredictable and not meaningful. @@ -2724,7 +2725,7 @@ ** ** ^The sqlite3_interrupt(D) call is in effect until all currently running ** SQL statements on [database connection] D complete. ^Any new SQL statements -** that are started after the sqlite3_interrupt() call and before the +** that are started after the sqlite3_interrupt() call and before the ** running statement count reaches zero are interrupted as if they had been ** running prior to the sqlite3_interrupt() call. ^New SQL statements ** that are started after the running statement count reaches zero are @@ -2735,6 +2736,7 @@ ** ** ^The [sqlite3_is_interrupted(D)] interface can be used to determine whether ** or not an interrupt is currently in effect for [database connection] D. +** It returns 1 if an interrupt is currently in effect, or 0 otherwise. */ void sqlite3_interrupt(sqlite3*); int sqlite3_is_interrupted(sqlite3*); @@ -2760,7 +2762,7 @@ ** ^These routines do not parse the SQL statements thus ** will not detect syntactically incorrect SQL. ** -** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior +** ^(If SQLite has not been initialized using [sqlite3_initialize()] prior ** to invoking sqlite3_complete16() then sqlite3_initialize() is invoked ** automatically by sqlite3_complete16(). If that initialization fails, ** then the return value from sqlite3_complete16() will be non-zero @@ -2805,7 +2807,7 @@ ** The presence of a busy handler does not guarantee that it will be invoked ** when there is lock contention. ^If SQLite determines that invoking the busy ** handler could result in a deadlock, it will go ahead and return [SQLITE_BUSY] -** to the application instead of invoking the +** to the application instead of invoking the ** busy handler. ** Consider a scenario where one process is holding a read lock that ** it is trying to promote to a reserved lock and @@ -2830,7 +2832,7 @@ ** database connection that invoked the busy handler. In other words, ** the busy handler is not reentrant. Any such actions ** result in undefined behavior. -** +** ** A busy handler must not close the database connection ** or [prepared statement] that invoked the busy handler. */ @@ -2948,7 +2950,7 @@ ** These routines are work-alikes of the "printf()" family of functions ** from the standard C library. ** These routines understand most of the common formatting options from -** the standard library printf() +** the standard library printf() ** plus some additional non-standard formats ([%q], [%Q], [%w], and [%z]). ** See the [built-in printf()] documentation for details. ** @@ -3144,7 +3146,7 @@ ** requested is ok. ^When the callback returns [SQLITE_DENY], the ** [sqlite3_prepare_v2()] or equivalent call that triggered the ** authorizer will fail with an error message explaining that -** access is denied. +** access is denied. ** ** ^The first parameter to the authorizer callback is a copy of the third ** parameter to the sqlite3_set_authorizer() interface. ^The second parameter @@ -3197,7 +3199,7 @@ ** database connections for the meaning of "modify" in this paragraph. ** ** ^When [sqlite3_prepare_v2()] is used to prepare a statement, the -** statement might be re-prepared during [sqlite3_step()] due to a +** statement might be re-prepared during [sqlite3_step()] due to a ** schema change. Hence, the application should ensure that the ** correct authorizer callback remains in place during the [sqlite3_step()]. ** @@ -3388,10 +3390,12 @@ ** M argument should be the bitwise OR-ed combination of ** zero or more [SQLITE_TRACE] constants. ** -** ^Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides -** (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). +** ^Each call to either sqlite3_trace(D,X,P) or sqlite3_trace_v2(D,M,X,P) +** overrides (cancels) all prior calls to sqlite3_trace(D,X,P) or +** sqlite3_trace_v2(D,M,X,P) for the [database connection] D. Each +** database connection may have at most one trace callback. ** -** ^The X callback is invoked whenever any of the events identified by +** ^The X callback is invoked whenever any of the events identified by ** mask M occur. ^The integer return value from the callback is currently ** ignored, though this may change in future releases. Callback ** implementations should return zero to ensure future compatibility. @@ -3423,8 +3427,8 @@ ** database connection D. An example use for this ** interface is to keep a GUI updated during a large query. ** -** ^The parameter P is passed through as the only parameter to the -** callback function X. ^The parameter N is the approximate number of +** ^The parameter P is passed through as the only parameter to the +** callback function X. ^The parameter N is the approximate number of ** [virtual machine instructions] that are evaluated between successive ** invocations of the callback X. ^If N is less than one then the progress ** handler is disabled. @@ -3601,17 +3605,17 @@ ** information. ** ** URI filenames are parsed according to RFC 3986. ^If the URI contains an -** authority, then it must be either an empty string or the string -** "localhost". ^If the authority is not an empty string or "localhost", an -** error is returned to the caller. ^The fragment component of a URI, if +** authority, then it must be either an empty string or the string +** "localhost". ^If the authority is not an empty string or "localhost", an +** error is returned to the caller. ^The fragment component of a URI, if ** present, is ignored. ** ** ^SQLite uses the path component of the URI as the name of the disk file -** which contains the database. ^If the path begins with a '/' character, -** then it is interpreted as an absolute path. ^If the path does not begin +** which contains the database. ^If the path begins with a '/' character, +** then it is interpreted as an absolute path. ^If the path does not begin ** with a '/' (meaning that the authority section is omitted from the URI) -** then the path is interpreted as a relative path. -** ^(On windows, the first component of an absolute path +** then the path is interpreted as a relative path. +** ^(On windows, the first component of an absolute path ** is a drive specification (e.g. "C:").)^ ** ** [[core URI query parameters]] @@ -3631,13 +3635,13 @@ ** **
    • mode: ^(The mode parameter may be set to either "ro", "rw", ** "rwc", or "memory". Attempting to set it to any other value is -** an error)^. -** ^If "ro" is specified, then the database is opened for read-only -** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the -** third argument to sqlite3_open_v2(). ^If the mode option is set to -** "rw", then the database is opened for read-write (but not create) -** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had -** been set. ^Value "rwc" is equivalent to setting both +** an error)^. +** ^If "ro" is specified, then the database is opened for read-only +** access, just as if the [SQLITE_OPEN_READONLY] flag had been set in the +** third argument to sqlite3_open_v2(). ^If the mode option is set to +** "rw", then the database is opened for read-write (but not create) +** access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had +** been set. ^Value "rwc" is equivalent to setting both ** SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. ^If the mode option is ** set to "memory" then a pure [in-memory database] that never reads ** or writes from disk is used. ^It is an error to specify a value for @@ -3647,7 +3651,7 @@ **
    • cache: ^The cache parameter may be set to either "shared" or ** "private". ^Setting it to "shared" is equivalent to setting the ** SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to -** sqlite3_open_v2(). ^Setting the cache parameter to "private" is +** sqlite3_open_v2(). ^Setting the cache parameter to "private" is ** equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. ** ^If sqlite3_open_v2() is used and the "cache" parameter is present in ** a URI filename, its value overrides any behavior requested by setting @@ -3673,7 +3677,7 @@ ** property on a database file that does in fact change can result ** in incorrect query results and/or [SQLITE_CORRUPT] errors. ** See also: [SQLITE_IOCAP_IMMUTABLE]. -** +** **
    ** ** ^Specifying an unknown parameter in the query component of a URI is not an @@ -3685,37 +3689,37 @@ ** **
  • **
    URI filenames Results -**
    file:data.db +**
    file:data.db ** Open the file "data.db" in the current directory. **
    file:/home/fred/data.db
    -** file:///home/fred/data.db
    -** file://localhost/home/fred/data.db
    +** file:///home/fred/data.db
    +** file://localhost/home/fred/data.db
    ** Open the database file "/home/fred/data.db". -**
    file://darkstar/home/fred/data.db +**
    file://darkstar/home/fred/data.db ** An error. "darkstar" is not a recognized authority. -**
    +**
    ** file:///C:/Documents%20and%20Settings/fred/Desktop/data.db ** Windows only: Open the file "data.db" on fred's desktop on drive -** C:. Note that the %20 escaping in this example is not strictly +** C:. Note that the %20 escaping in this example is not strictly ** necessary - space characters can be used literally ** in URI filenames. -**
    file:data.db?mode=ro&cache=private +**
    file:data.db?mode=ro&cache=private ** Open file "data.db" in the current directory for read-only access. ** Regardless of whether or not shared-cache mode is enabled by ** default, use a private cache. **
    file:/home/fred/data.db?vfs=unix-dotfile ** Open file "/home/fred/data.db". Use the special VFS "unix-dotfile" ** that uses dot-files in place of posix advisory locking. -**
    file:data.db?mode=readonly +**
    file:data.db?mode=readonly ** An error. "readonly" is not a valid option for the "mode" parameter. ** Use "ro" instead: "file:data.db?mode=ro". **
    ** ** ^URI hexadecimal escape sequences (%HH) are supported within the path and ** query components of a URI. A hexadecimal escape sequence consists of a -** percent sign - "%" - followed by exactly two hexadecimal digits +** percent sign - "%" - followed by exactly two hexadecimal digits ** specifying an octet value. ^Before the path or query components of a -** URI filename are interpreted, they are encoded using UTF-8 and all +** URI filename are interpreted, they are encoded using UTF-8 and all ** hexadecimal escape sequences replaced by a single byte containing the ** corresponding octet. If this process generates an invalid UTF-8 encoding, ** the results are undefined. @@ -3751,14 +3755,14 @@ ** CAPI3REF: Obtain Values For URI Parameters ** ** These are utility routines, useful to [VFS|custom VFS implementations], -** that check if a database file was a URI that contained a specific query +** 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: **
      **
    • A database filename pointer created by the SQLite core and -** passed into the xOpen() method of a VFS implemention, or +** passed into the xOpen() method of a VFS implementation, or **
    • A filename obtained from [sqlite3_db_filename()], or **
    • A new filename constructed using [sqlite3_create_filename()]. **
    @@ -3769,7 +3773,7 @@ ** If F is a suitable filename (as described in the previous paragraph) ** and if P is the name of the query parameter, then ** sqlite3_uri_parameter(F,P) returns the value of the P -** parameter if it exists or a NULL pointer if P does not appear as a +** parameter if it exists or a NULL pointer if P does not appear as a ** query parameter on F. If P is a query parameter of F and it ** has no explicit value, then sqlite3_uri_parameter(F,P) returns ** a pointer to an empty string. @@ -3778,7 +3782,7 @@ ** parameter and returns true (1) or false (0) according to the value ** of P. The sqlite3_uri_boolean(F,P,B) routine returns true (1) if the ** value of query parameter P is one of "yes", "true", or "on" in any -** case or if the value begins with a non-zero number. The +** case or if the value begins with a non-zero number. The ** sqlite3_uri_boolean(F,P,B) routines returns false (0) if the value of ** query parameter P is one of "no", "false", or "off" in any case or ** if the value begins with a numeric zero. If P is not a query @@ -3796,7 +3800,7 @@ ** parameters minus 1. The N value is zero-based so N should be 0 to obtain ** the name of the first query parameter, 1 for the second parameter, and ** so forth. -** +** ** If F is a NULL pointer, then sqlite3_uri_parameter(F,P) returns NULL and ** sqlite3_uri_boolean(F,P,B) returns B. If F is not a NULL pointer and ** is not a database file pathname pointer that the SQLite core passed @@ -3853,14 +3857,14 @@ ** CAPI3REF: Database File Corresponding To A Journal ** ** ^If X is the name of a rollback or WAL-mode journal file that is -** passed into the xOpen method of [sqlite3_vfs], then +** passed into the xOpen method of [sqlite3_vfs], then ** sqlite3_database_file_object(X) returns a pointer to the [sqlite3_file] ** object that represents the main database file. ** ** This routine is intended for use in custom [VFS] implementations ** only. It is not a general-purpose interface. ** The argument sqlite3_file_object(X) must be a filename pointer that -** has been passed into [sqlite3_vfs].xOpen method where the +** has been passed into [sqlite3_vfs].xOpen method where the ** flags parameter to xOpen contains one of the bits ** [SQLITE_OPEN_MAIN_JOURNAL] or [SQLITE_OPEN_WAL]. Any other use ** of this routine results in undefined and probably undesirable @@ -3871,7 +3875,7 @@ /* ** CAPI3REF: Create and Destroy VFS Filenames ** -** These interfces are provided for use by [VFS shim] implementations and +** 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 @@ -3883,7 +3887,7 @@ **
  • [sqlite3_uri_parameter()], **
  • [sqlite3_uri_boolean()], **
  • [sqlite3_uri_int64()], -**
  • [sqlite3_uri_key()], +**
  • [sqlite3_uri_key()], **
  • [sqlite3_filename_database()], **
  • [sqlite3_filename_journal()], or **
  • [sqlite3_filename_wal()]. @@ -3907,7 +3911,7 @@ ** If the Y parameter to sqlite3_free_filename(Y) is anything other ** than a NULL pointer or a pointer previously acquired from ** sqlite3_create_filename(), then bad things such as heap -** corruption or segfaults may occur. The value Y should not be +** corruption or segfaults may occur. The value Y should not be ** used again after sqlite3_free_filename(Y) has been called. This means ** that if the [sqlite3_vfs.xOpen()] method of a VFS has been called using Y, ** then the corresponding [sqlite3_module.xClose() method should also be @@ -3926,12 +3930,12 @@ ** CAPI3REF: Error Codes And Messages ** METHOD: sqlite3 ** -** ^If the most recent sqlite3_* API call associated with +** ^If the most recent sqlite3_* API call associated with ** [database connection] D failed, then the sqlite3_errcode(D) interface ** returns the numeric [result code] or [extended result code] for that ** API call. ** ^The sqlite3_extended_errcode() -** interface is the same except that it always returns the +** interface is the same except that it always returns the ** [extended result code] even when extended result codes are ** disabled. ** @@ -3951,6 +3955,7 @@ ** ** ^The sqlite3_errmsg() and sqlite3_errmsg16() return English-language ** text that describes the error, as either UTF-8 or UTF-16 respectively. +** (See how SQLite handles [invalid UTF] for exceptions to this rule.) ** ^(Memory to hold the error message string is managed internally. ** The application does not need to worry about freeing the result. ** However, the error string might be overwritten or deallocated by @@ -3997,7 +4002,7 @@ ** has been compiled into binary form and is ready to be evaluated. ** ** Think of each SQL statement as a separate computer program. The -** original SQL text is source code. A prepared statement object +** original SQL text is source code. A prepared statement object ** is the compiled object code. All SQL must be converted into a ** prepared statement before it can be run. ** @@ -4027,7 +4032,7 @@ ** new limit for that construct.)^ ** ** ^If the new limit is a negative number, the limit is unchanged. -** ^(For each limit category SQLITE_LIMIT_NAME there is a +** ^(For each limit category SQLITE_LIMIT_NAME there is a ** [limits | hard upper bound] ** set at compile-time by a C preprocessor macro called ** [limits | SQLITE_MAX_NAME]. @@ -4035,7 +4040,7 @@ ** ^Attempts to increase a limit above its hard upper bound are ** silently truncated to the hard upper bound. ** -** ^Regardless of whether or not the limit was changed, the +** ^Regardless of whether or not the limit was changed, the ** [sqlite3_limit()] interface returns the prior value of the limit. ** ^Hence, to find the current value of a limit without changing it, ** simply invoke this interface with the third parameter set to -1. @@ -4140,7 +4145,7 @@ **
    The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner ** that the prepared statement will be retained for a long time and ** probably reused many times.)^ ^Without this flag, [sqlite3_prepare_v3()] -** and [sqlite3_prepare16_v3()] assume that the prepared statement will +** and [sqlite3_prepare16_v3()] assume that the prepared statement will ** be used just once or at most a few times and then destroyed using ** [sqlite3_finalize()] relatively soon. The current implementation acts ** on this hint by avoiding the use of [lookaside memory] so as not to @@ -4247,12 +4252,12 @@ **
  • ** **
  • -** ^If the specific value bound to a [parameter | host parameter] in the +** ^If the specific value bound to a [parameter | host parameter] in the ** WHERE clause might influence the choice of query plan for a statement, -** then the statement will be automatically recompiled, as if there had been +** then the statement will be automatically recompiled, as if there had been ** a schema change, on the first [sqlite3_step()] call following any change -** to the [sqlite3_bind_text | bindings] of that [parameter]. -** ^The specific value of a WHERE-clause [parameter] might influence the +** to the [sqlite3_bind_text | bindings] of that [parameter]. +** ^The specific value of a WHERE-clause [parameter] might influence the ** choice of query plan if the parameter is the left-hand side of a [LIKE] ** or [GLOB] operator or if the parameter is compared to an indexed column ** and the [SQLITE_ENABLE_STAT4] compile-time option is enabled. @@ -4366,8 +4371,8 @@ ** the content of the database file. ** ** Note that [application-defined SQL functions] or -** [virtual tables] might change the database indirectly as a side effect. -** ^(For example, if an application defines a function "eval()" that +** [virtual tables] might change the database indirectly as a side effect. +** ^(For example, if an application defines a function "eval()" that ** calls [sqlite3_exec()], then the following SQL statement would ** change the database file through side-effects: ** @@ -4381,10 +4386,10 @@ ** ^Transaction control statements such as [BEGIN], [COMMIT], [ROLLBACK], ** [SAVEPOINT], and [RELEASE] cause sqlite3_stmt_readonly() to return true, ** since the statements themselves do not actually modify the database but -** rather they control the timing of when other statements modify the +** rather they control the timing of when other statements modify the ** database. ^The [ATTACH] and [DETACH] statements also cause ** sqlite3_stmt_readonly() to return true since, while those statements -** change the configuration of a database connection, they do not make +** change the configuration of a database connection, they do not make ** changes to the content of the database files on disk. ** ^The sqlite3_stmt_readonly() interface returns true for [BEGIN] since ** [BEGIN] merely sets internal flags, but the [BEGIN|BEGIN IMMEDIATE] and @@ -4397,7 +4402,7 @@ ** ^For example, an UPDATE statement might have a WHERE clause that ** makes it a no-op, but the sqlite3_stmt_readonly() result would still ** be false. ^Similarly, a CREATE TABLE IF NOT EXISTS statement is a -** read-only no-op if the table already exists, but +** read-only no-op if the table already exists, but ** sqlite3_stmt_readonly() still returns false for such a statement. ** ** ^If prepared statement X is an [EXPLAIN] or [EXPLAIN QUERY PLAN] @@ -4419,22 +4424,57 @@ int sqlite3_stmt_isexplain(sqlite3_stmt *pStmt); /* +** CAPI3REF: Change The EXPLAIN Setting For A Prepared Statement +** METHOD: sqlite3_stmt +** +** The sqlite3_stmt_explain(S,E) interface changes the EXPLAIN +** setting for [prepared statement] S. If E is zero, then S becomes +** a normal prepared statement. If E is 1, then S behaves as if +** its SQL text began with "[EXPLAIN]". If E is 2, then S behaves as if +** its SQL text began with "[EXPLAIN QUERY PLAN]". +** +** Calling sqlite3_stmt_explain(S,E) might cause S to be reprepared. +** SQLite tries to avoid a reprepare, but a reprepare might be necessary +** on the first transition into EXPLAIN or EXPLAIN QUERY PLAN mode. +** +** Because of the potential need to reprepare, a call to +** sqlite3_stmt_explain(S,E) will fail with SQLITE_ERROR if S cannot be +** reprepared because it was created using [sqlite3_prepare()] instead of +** the newer [sqlite3_prepare_v2()] or [sqlite3_prepare_v3()] interfaces and +** hence has no saved SQL text with which to reprepare. +** +** Changing the explain setting for a prepared statement does not change +** the original SQL text for the statement. Hence, if the SQL text originally +** began with EXPLAIN or EXPLAIN QUERY PLAN, but sqlite3_stmt_explain(S,0) +** is called to convert the statement into an ordinary statement, the EXPLAIN +** or EXPLAIN QUERY PLAN keywords will still appear in the sqlite3_sql(S) +** output, even though the statement now acts like a normal SQL statement. +** +** This routine returns SQLITE_OK if the explain mode is successfully +** changed, or an error code if the explain mode could not be changed. +** The explain mode cannot be changed while a statement is active. +** Hence, it is good practice to call [sqlite3_reset(S)] +** immediately prior to calling sqlite3_stmt_explain(S,E). +*/ +int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode); + +/* ** CAPI3REF: Determine If A Prepared Statement Has Been Reset ** METHOD: sqlite3_stmt ** ** ^The sqlite3_stmt_busy(S) interface returns true (non-zero) if the -** [prepared statement] S has been stepped at least once using +** [prepared statement] S has been stepped at least once using ** [sqlite3_step(S)] but has neither run to completion (returned ** [SQLITE_DONE] from [sqlite3_step(S)]) nor ** been reset using [sqlite3_reset(S)]. ^The sqlite3_stmt_busy(S) -** interface returns false if S is a NULL pointer. If S is not a +** interface returns false if S is a NULL pointer. If S is not a ** NULL pointer and is not a pointer to a valid [prepared statement] ** object, then the behavior is undefined and probably undesirable. ** ** This interface can be used in combination [sqlite3_next_stmt()] -** to locate all prepared statements associated with a database +** to locate all prepared statements associated with a database ** connection that are in need of being reset. This can be used, -** for example, in diagnostic routines to search for prepared +** for example, in diagnostic routines to search for prepared ** statements that are holding a transaction open. */ int sqlite3_stmt_busy(sqlite3_stmt*); @@ -4453,7 +4493,7 @@ ** will accept either a protected or an unprotected sqlite3_value. ** Every interface that accepts sqlite3_value arguments specifies ** whether or not it requires a protected sqlite3_value. The -** [sqlite3_value_dup()] interface can be used to construct a new +** [sqlite3_value_dup()] interface can be used to construct a new ** protected sqlite3_value from an unprotected sqlite3_value. ** ** The terms "protected" and "unprotected" refer to whether or not @@ -4461,7 +4501,7 @@ ** sqlite3_value object but no mutex is held for an unprotected ** sqlite3_value object. If SQLite is compiled to be single-threaded ** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0) -** or if SQLite is run in one of reduced mutex modes +** or if SQLite is run in one of reduced mutex modes ** [SQLITE_CONFIG_SINGLETHREAD] or [SQLITE_CONFIG_MULTITHREAD] ** then there is no distinction between protected and unprotected ** sqlite3_value objects and they can be used interchangeably. However, @@ -4552,7 +4592,7 @@ ** found in first character, which is removed, or in the absence of a BOM ** the byte order is the native byte order of the host ** machine for sqlite3_bind_text16() or the byte order specified in -** the 6th parameter for sqlite3_bind_text64().)^ +** the 6th parameter for sqlite3_bind_text64().)^ ** ^If UTF16 input text contains invalid unicode ** characters, then SQLite might change those invalid characters ** into the unicode replacement character: U+FFFD. @@ -4569,7 +4609,7 @@ ** or sqlite3_bind_text16() or sqlite3_bind_text64() then ** that parameter must be the byte offset ** where the NUL terminator would occur assuming the string were NUL -** terminated. If any NUL characters occurs at byte offsets less than +** terminated. If any NUL characters occurs at byte offsets less than ** the value of the fourth parameter then the resulting string value will ** contain embedded NULs. The result of expressions involving strings ** with embedded NULs is undefined. @@ -4581,7 +4621,7 @@ ** with it may be passed. ^It is called to dispose of the BLOB or string even ** if the call to the bind API fails, except the destructor is not called if ** the third parameter is a NULL pointer or the fourth parameter is negative. -** ^ (2) The special constant, [SQLITE_STATIC], may be passsed to indicate that +** ^ (2) The special constant, [SQLITE_STATIC], may be passed to indicate that ** the application remains responsible for disposing of the object. ^In this ** case, the object and the provided pointer to it must remain valid until ** either the prepared statement is finalized or the same SQL parameter is @@ -4735,7 +4775,7 @@ ** METHOD: sqlite3_stmt ** ** ^Return the number of columns in the result set returned by the -** [prepared statement]. ^If this routine returns 0, that means the +** [prepared statement]. ^If this routine returns 0, that means the ** [prepared statement] returns no data (for example an [UPDATE]). ** ^However, just because this routine returns a positive number does not ** mean that one or more rows of data will be returned. ^A SELECT statement @@ -4917,7 +4957,7 @@ ** For all versions of SQLite up to and including 3.6.23.1, a call to ** [sqlite3_reset()] was required after sqlite3_step() returned anything ** other than [SQLITE_ROW] before any subsequent invocation of -** sqlite3_step(). Failure to reset the prepared statement using +** sqlite3_step(). Failure to reset the prepared statement using ** [sqlite3_reset()] would result in an [SQLITE_MISUSE] return from ** sqlite3_step(). But after [version 3.6.23.1] ([dateof:3.6.23.1], ** sqlite3_step() began @@ -5008,7 +5048,7 @@ ** sqlite3_column_int64→64-bit INTEGER result ** sqlite3_column_text→UTF-8 TEXT result ** sqlite3_column_text16→UTF-16 TEXT result -** sqlite3_column_value→The result as an +** sqlite3_column_value→The result as an ** [sqlite3_value|unprotected sqlite3_value] object. **     ** sqlite3_column_bytes→Size of a BLOB @@ -5056,7 +5096,7 @@ ** The return value of sqlite3_column_type() can be used to decide which ** of the first six interface should be used to extract the column value. ** The value returned by sqlite3_column_type() is only meaningful if no -** automatic type conversions have occurred for the value in question. +** automatic type conversions have occurred for the value in question. ** After a type conversion, the result of calling sqlite3_column_type() ** is undefined, though harmless. Future ** versions of SQLite may change the behavior of sqlite3_column_type() @@ -5084,7 +5124,7 @@ ** the number of bytes in that string. ** ^If the result is NULL, then sqlite3_column_bytes16() returns zero. ** -** ^The values returned by [sqlite3_column_bytes()] and +** ^The values returned by [sqlite3_column_bytes()] and ** [sqlite3_column_bytes16()] do not include the zero terminators at the end ** of the string. ^For clarity: the values returned by ** [sqlite3_column_bytes()] and [sqlite3_column_bytes16()] are the number of @@ -5107,7 +5147,7 @@ ** to routines like [sqlite3_value_int()], [sqlite3_value_text()], ** or [sqlite3_value_bytes()], the behavior is not threadsafe. ** Hence, the sqlite3_column_value() interface -** is normally only useful within the implementation of +** is normally only useful within the implementation of ** [application-defined SQL functions] or [virtual tables], not within ** top-level application code. ** @@ -5260,20 +5300,33 @@ ** ^The [sqlite3_reset(S)] interface resets the [prepared statement] S ** back to the beginning of its program. ** -** ^If the most recent call to [sqlite3_step(S)] for the -** [prepared statement] S returned [SQLITE_ROW] or [SQLITE_DONE], -** or if [sqlite3_step(S)] has never before been called on S, -** then [sqlite3_reset(S)] returns [SQLITE_OK]. +** ^The return code from [sqlite3_reset(S)] indicates whether or not +** the previous evaluation of prepared statement S completed successfully. +** ^If [sqlite3_step(S)] has never before been called on S or if +** [sqlite3_step(S)] has not been called since the previous call +** to [sqlite3_reset(S)], then [sqlite3_reset(S)] will return +** [SQLITE_OK]. ** ** ^If the most recent call to [sqlite3_step(S)] for the ** [prepared statement] S indicated an error, then ** [sqlite3_reset(S)] returns an appropriate [error code]. +** ^The [sqlite3_reset(S)] interface might also return an [error code] +** if there were no prior errors but the process of resetting +** the prepared statement caused a new error. ^For example, if an +** [INSERT] statement with a [RETURNING] clause is only stepped one time, +** that one call to [sqlite3_step(S)] might return SQLITE_ROW but +** the overall statement might still fail and the [sqlite3_reset(S)] call +** might return SQLITE_BUSY if locking constraints prevent the +** database change from committing. Therefore, it is important that +** applications check the return code from [sqlite3_reset(S)] even if +** no prior call to [sqlite3_step(S)] indicated a problem. ** ** ^The [sqlite3_reset(S)] interface does not change the values ** of any [sqlite3_bind_blob|bindings] on the [prepared statement] S. */ int sqlite3_reset(sqlite3_stmt *pStmt); + /* ** CAPI3REF: Create Or Redefine SQL Functions ** KEYWORDS: {function creation routines} @@ -5282,8 +5335,8 @@ ** ^These functions (collectively known as "function creation routines") ** are used to add SQL functions or aggregates or to redefine the behavior ** of existing SQL functions or aggregates. The only differences between -** the three "sqlite3_create_function*" routines are the text encoding -** expected for the second parameter (the name of the function being +** the three "sqlite3_create_function*" routines are the text encoding +** expected for the second parameter (the name of the function being ** created) and the presence or absence of a destructor callback for ** the application data pointer. Function sqlite3_create_window_function() ** is similar, but allows the user to supply the extra callback functions @@ -5297,7 +5350,7 @@ ** ^The second parameter is the name of the SQL function to be created or ** redefined. ^The length of the name is limited to 255 bytes in a UTF-8 ** representation, exclusive of the zero-terminator. ^Note that the name -** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +** length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. ** ^Any attempt to create a function with a longer name ** will result in [SQLITE_MISUSE] being returned. ** @@ -5312,7 +5365,7 @@ ** ^The fourth parameter, eTextRep, specifies what ** [SQLITE_UTF8 | text encoding] this SQL function prefers for ** its parameters. The application should set this parameter to -** [SQLITE_UTF16LE] if the function implementation invokes +** [SQLITE_UTF16LE] if the function implementation invokes ** [sqlite3_value_text16le()] on an input, or [SQLITE_UTF16BE] if the ** implementation invokes [sqlite3_value_text16be()] on an input, or ** [SQLITE_UTF16] if [sqlite3_value_text16()] is used, or [SQLITE_UTF8] @@ -5338,7 +5391,7 @@ ** For best security, the [SQLITE_DIRECTONLY] flag is recommended for ** all application-defined SQL functions that do not need to be ** used inside of triggers, view, CHECK constraints, or other elements of -** the database schema. This flags is especially recommended for SQL +** the database schema. This flags is especially recommended for SQL ** functions that have side effects or reveal internal application state. ** Without this flag, an attacker might be able to modify the schema of ** a database file to include invocations of the function with parameters @@ -5358,21 +5411,21 @@ ** SQL function or aggregate, pass NULL pointers for all three function ** callbacks. ** -** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue +** ^The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue ** and xInverse) passed to sqlite3_create_window_function are pointers to ** C-language callbacks that implement the new function. xStep and xFinal ** must both be non-NULL. xValue and xInverse may either both be NULL, in -** which case a regular aggregate function is created, or must both be +** which case a regular aggregate function is created, or must both be ** non-NULL, in which case the new function may be used as either an aggregate ** or aggregate window function. More details regarding the implementation -** of aggregate window functions are +** of aggregate window functions are ** [user-defined window functions|available here]. ** ** ^(If the final parameter to sqlite3_create_function_v2() or ** sqlite3_create_window_function() is not NULL, then it is destructor for -** the application data pointer. The destructor is invoked when the function -** is deleted, either by being overloaded or when the database connection -** closes.)^ ^The destructor is also invoked if the call to +** the application data pointer. The destructor is invoked when the function +** is deleted, either by being overloaded or when the database connection +** closes.)^ ^The destructor is also invoked if the call to ** sqlite3_create_function_v2() fails. ^When the destructor callback is ** invoked, it is passed a single argument which is a copy of the application ** data pointer which was the fifth parameter to sqlite3_create_function_v2(). @@ -5385,7 +5438,7 @@ ** nArg parameter is a better match than a function implementation with ** a negative nArg. ^A function where the preferred text encoding ** matches the database encoding is a better -** match than a function where the encoding is different. +** match than a function where the encoding is different. ** ^A function where the encoding difference is between UTF16le and UTF16be ** is a closer match than a function where the encoding difference is ** between UTF8 and UTF16. @@ -5457,7 +5510,7 @@ /* ** CAPI3REF: Function Flags ** -** These constants may be ORed together with the +** These constants may be ORed together with the ** [SQLITE_UTF8 | preferred text encoding] as the fourth argument ** to [sqlite3_create_function()], [sqlite3_create_function16()], or ** [sqlite3_create_function_v2()]. @@ -5473,18 +5526,18 @@ ** SQLite might also optimize deterministic functions by factoring them ** out of inner loops. ** -** +** ** [[SQLITE_DIRECTONLY]]
    SQLITE_DIRECTONLY
    ** The SQLITE_DIRECTONLY flag means that the function may only be invoked -** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in +** from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in ** schema structures such as [CHECK constraints], [DEFAULT clauses], ** [expression indexes], [partial indexes], or [generated columns]. **

    -** The SQLITE_DIRECTONLY flag is recommended for any +** The SQLITE_DIRECTONLY flag is recommended for any ** [application-defined SQL function] ** that has side-effects or that could potentially leak sensitive information. ** This will prevent attacks in which an application is tricked -** into using a database file that has had its schema surreptiously +** into using a database file that has had its schema surreptitiously ** modified to invoke the application-defined function in ways that are ** harmful. **

    @@ -5540,7 +5593,7 @@ ** DEPRECATED ** ** These functions are [deprecated]. In order to maintain -** backwards compatibility with older code, these functions continue +** backwards compatibility with older code, these functions continue ** to be supported. However, new applications should avoid ** the use of these functions. To encourage programmers to avoid ** these functions, we will not explain what they do. @@ -5608,11 +5661,11 @@ ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces ** extract UTF-16 strings as big-endian and little-endian respectively. ** -** ^If [sqlite3_value] object V was initialized +** ^If [sqlite3_value] object V was initialized ** using [sqlite3_bind_pointer(S,I,P,X,D)] or [sqlite3_result_pointer(C,P,X,D)] ** and if X and Y are strings that compare equal according to strcmp(X,Y), ** then sqlite3_value_pointer(V,Y) will return the pointer P. ^Otherwise, -** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() +** sqlite3_value_pointer(V,Y) returns a NULL. The sqlite3_bind_pointer() ** routine is part of the [pointer passing interface] added for SQLite 3.20.0. ** ** ^(The sqlite3_value_type(V) interface returns the @@ -5758,7 +5811,7 @@ ** Implementations of aggregate SQL functions use this ** routine to allocate memory for storing their state. ** -** ^The first time the sqlite3_aggregate_context(C,N) routine is called +** ^The first time the sqlite3_aggregate_context(C,N) routine is called ** for a particular aggregate function, SQLite allocates ** N bytes of memory, zeroes out that memory, and returns a pointer ** to the new memory. ^On second and subsequent calls to @@ -5771,7 +5824,7 @@ ** In those cases, sqlite3_aggregate_context() might be called for the ** first time from within xFinal().)^ ** -** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer +** ^The sqlite3_aggregate_context(C,N) routine returns a NULL pointer ** when first called if N is less than or equal to zero or if a memory ** allocation error occurs. ** @@ -5780,10 +5833,10 @@ ** value of N in any subsequent call to sqlite3_aggregate_context() within ** the same aggregate function instance will not resize the memory ** allocation.)^ Within the xFinal callback, it is customary to set -** N=0 in calls to sqlite3_aggregate_context(C,N) so that no +** N=0 in calls to sqlite3_aggregate_context(C,N) so that no ** pointless memory allocations occur. ** -** ^SQLite automatically frees the memory allocated by +** ^SQLite automatically frees the memory allocated by ** sqlite3_aggregate_context() when the aggregate query concludes. ** ** The first parameter must be a copy of the @@ -5828,48 +5881,48 @@ ** METHOD: sqlite3_context ** ** These functions may be used by (non-aggregate) SQL functions to -** associate metadata with argument values. If the same value is passed to -** multiple invocations of the same SQL function during query execution, under -** some circumstances the associated metadata may be preserved. An example -** of where this might be useful is in a regular-expression matching -** function. The compiled version of the regular expression can be stored as -** metadata associated with the pattern string. +** associate auxiliary data with argument values. If the same argument +** value is passed to multiple invocations of the same SQL function during +** query execution, under some circumstances the associated auxiliary data +** might be preserved. An example of where this might be useful is in a +** regular-expression matching function. The compiled version of the regular +** expression can be stored as auxiliary data associated with the pattern string. ** Then as long as the pattern string remains the same, ** the compiled regular expression can be reused on multiple ** invocations of the same function. ** -** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata +** ^The sqlite3_get_auxdata(C,N) interface returns a pointer to the auxiliary data ** associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument ** value to the application-defined function. ^N is zero for the left-most -** function argument. ^If there is no metadata +** function argument. ^If there is no auxiliary data ** associated with the function argument, the sqlite3_get_auxdata(C,N) interface ** returns a NULL pointer. ** -** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th -** argument of the application-defined function. ^Subsequent +** ^The sqlite3_set_auxdata(C,N,P,X) interface saves P as auxiliary data for the +** N-th argument of the application-defined function. ^Subsequent ** calls to sqlite3_get_auxdata(C,N) return P from the most recent -** sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or -** NULL if the metadata has been discarded. +** sqlite3_set_auxdata(C,N,P,X) call if the auxiliary data is still valid or +** NULL if the auxiliary data has been discarded. ** ^After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, ** SQLite will invoke the destructor function X with parameter P exactly -** once, when the metadata is discarded. -** SQLite is free to discard the metadata at any time, including:

      +** once, when the auxiliary data is discarded. +** SQLite is free to discard the auxiliary data at any time, including:
        **
      • ^(when the corresponding function parameter changes)^, or **
      • ^(when [sqlite3_reset()] or [sqlite3_finalize()] is called for the ** SQL statement)^, or **
      • ^(when sqlite3_set_auxdata() is invoked again on the same ** parameter)^, or -**
      • ^(during the original sqlite3_set_auxdata() call when a memory +**
      • ^(during the original sqlite3_set_auxdata() call when a memory ** allocation error occurs.)^
      ** -** Note the last bullet in particular. The destructor X in +** Note the last bullet in particular. The destructor X in ** sqlite3_set_auxdata(C,N,P,X) might be called immediately, before the ** sqlite3_set_auxdata() interface even returns. Hence sqlite3_set_auxdata() ** should be called near the end of the function implementation and the ** function implementation should not make any use of P after ** sqlite3_set_auxdata() has been called. ** -** ^(In practice, metadata is preserved between function calls for +** ^(In practice, auxiliary data is preserved between function calls for ** function parameters that are compile-time constants, including literal ** values and [parameters] and expressions composed from the same.)^ ** @@ -5879,10 +5932,67 @@ ** ** These routines must be called from the same thread in which ** the SQL function is running. +** +** See also: [sqlite3_get_clientdata()] and [sqlite3_set_clientdata()]. */ void *sqlite3_get_auxdata(sqlite3_context*, int N); void sqlite3_set_auxdata(sqlite3_context*, int N, void*, void (*)(void*)); +/* +** CAPI3REF: Database Connection Client Data +** METHOD: sqlite3 +** +** These functions are used to associate one or more named pointers +** with a [database connection]. +** A call to sqlite3_set_clientdata(D,N,P,X) causes the pointer P +** to be attached to [database connection] D using name N. Subsequent +** calls to sqlite3_get_clientdata(D,N) will return a copy of pointer P +** or a NULL pointer if there were no prior calls to +** sqlite3_set_clientdata() with the same values of D and N. +** Names are compared using strcmp() and are thus case sensitive. +** +** If P and X are both non-NULL, then the destructor X is invoked with +** argument P on the first of the following occurrences: +**
        +**
      • An out-of-memory error occurs during the call to +** sqlite3_set_clientdata() which attempts to register pointer P. +**
      • A subsequent call to sqlite3_set_clientdata(D,N,P,X) is made +** with the same D and N parameters. +**
      • The database connection closes. SQLite does not make any guarantees +** about the order in which destructors are called, only that all +** destructors will be called exactly once at some point during the +** database connection closing process. +**
      +** +** SQLite does not do anything with client data other than invoke +** destructors on the client data at the appropriate time. The intended +** use for client data is to provide a mechanism for wrapper libraries +** to store additional information about an SQLite database connection. +** +** There is no limit (other than available memory) on the number of different +** client data pointers (with different names) that can be attached to a +** single database connection. However, the implementation is optimized +** for the case of having only one or two different client data names. +** Applications and wrapper libraries are discouraged from using more than +** one client data name each. +** +** There is no way to enumerate the client data pointers +** associated with a database connection. The N parameter can be thought +** of as a secret key such that only code that knows the secret key is able +** to access the associated data. +** +** Security Warning: These interfaces should not be exposed in scripting +** languages or in other circumstances where it might be possible for an +** an attacker to invoke them. Any agent that can invoke these interfaces +** can probably also take control of the process. +** +** Database connection client data is only available for SQLite +** version 3.44.0 ([dateof:3.44.0]) and later. +** +** See also: [sqlite3_set_auxdata()] and [sqlite3_get_auxdata()]. +*/ +void *sqlite3_get_clientdata(sqlite3*,const char*); +int sqlite3_set_clientdata(sqlite3*, const char*, void*, void(*)(void*)); /* ** CAPI3REF: Constants Defining Special Destructor Behavior @@ -6036,7 +6146,7 @@ ** ** ^The sqlite3_result_pointer(C,P,T,D) interface sets the result to an ** SQL NULL value, just like [sqlite3_result_null(C)], except that it -** also associates the host-language pointer P or type T with that +** also associates the host-language pointer P or type T with that ** NULL value such that the pointer can be retrieved within an ** [application-defined SQL function] using [sqlite3_value_pointer()]. ** ^If the D parameter is not NULL, then it is a pointer to a destructor @@ -6078,8 +6188,8 @@ ** METHOD: sqlite3_context ** ** The sqlite3_result_subtype(C,T) function causes the subtype of -** the result from the [application-defined SQL function] with -** [sqlite3_context] C to be the value T. Only the lower 8 bits +** the result from the [application-defined SQL function] with +** [sqlite3_context] C to be the value T. Only the lower 8 bits ** of the subtype T are preserved in current versions of SQLite; ** higher order bits are discarded. ** The number of subtype bytes preserved by SQLite might increase @@ -6126,7 +6236,7 @@ ** deleted. ^When all collating functions having the same name are deleted, ** that collation is no longer usable. ** -** ^The collating function callback is invoked with a copy of the pArg +** ^The collating function callback is invoked with a copy of the pArg ** application data pointer and with two strings in the encoding specified ** by the eTextRep argument. The two integer parameters to the collating ** function callback are the length of the two strings, in bytes. The collating @@ -6157,36 +6267,36 @@ ** calls to the collation creation functions or when the ** [database connection] is closed using [sqlite3_close()]. ** -** ^The xDestroy callback is not called if the +** ^The xDestroy callback is not called if the ** sqlite3_create_collation_v2() function fails. Applications that invoke -** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should +** sqlite3_create_collation_v2() with a non-NULL xDestroy argument should ** check the return code and dispose of the application data pointer ** themselves rather than expecting SQLite to deal with it for them. -** This is different from every other SQLite interface. The inconsistency -** is unfortunate but cannot be changed without breaking backwards +** This is different from every other SQLite interface. The inconsistency +** is unfortunate but cannot be changed without breaking backwards ** compatibility. ** ** See also: [sqlite3_collation_needed()] and [sqlite3_collation_needed16()]. */ int sqlite3_create_collation( - sqlite3*, - const char *zName, - int eTextRep, + sqlite3*, + const char *zName, + int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); int sqlite3_create_collation_v2( - sqlite3*, - const char *zName, - int eTextRep, + sqlite3*, + const char *zName, + int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*), void(*xDestroy)(void*) ); int sqlite3_create_collation16( - sqlite3*, + sqlite3*, const void *zName, - int eTextRep, + int eTextRep, void *pArg, int(*xCompare)(void*,int,const void*,int,const void*) ); @@ -6219,19 +6329,19 @@ ** [sqlite3_create_collation_v2()]. */ int sqlite3_collation_needed( - sqlite3*, - void*, + sqlite3*, + void*, void(*)(void*,sqlite3*,int eTextRep,const char*) ); int sqlite3_collation_needed16( - sqlite3*, + sqlite3*, void*, void(*)(void*,sqlite3*,int eTextRep,const void*) ); #ifdef SQLITE_ENABLE_CEROD /* -** Specify the activation key for a CEROD database. Unless +** Specify the activation key for a CEROD database. Unless ** activated, none of the CEROD routines will work. */ void sqlite3_activate_cerod( @@ -6294,7 +6404,7 @@ ** ^The [temp_store_directory pragma] may modify this variable and cause ** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, ** the [temp_store_directory pragma] always assumes that any string -** that this variable points to is held in memory obtained from +** that this variable points to is held in memory obtained from ** [sqlite3_malloc] and the pragma may attempt to free that memory ** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be @@ -6351,7 +6461,7 @@ ** ^The [data_store_directory pragma] may modify this variable and cause ** it to point to memory obtained from [sqlite3_malloc]. ^Furthermore, ** the [data_store_directory pragma] always assumes that any string -** that this variable points to is held in memory obtained from +** that this variable points to is held in memory obtained from ** [sqlite3_malloc] and the pragma may attempt to free that memory ** using [sqlite3_free]. ** Hence, if this variable is modified directly, either it should be @@ -6515,7 +6625,7 @@ int sqlite3_txn_state(sqlite3*,const char *zSchema); /* -** CAPI3REF: Allowed return values from [sqlite3_txn_state()] +** CAPI3REF: Allowed return values from sqlite3_txn_state() ** KEYWORDS: {transaction state} ** ** These constants define the current transaction state of a database file. @@ -6617,7 +6727,7 @@ ** CAPI3REF: Autovacuum Compaction Amount Callback ** METHOD: sqlite3 ** -** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback +** ^The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback ** function C that is invoked prior to each autovacuum of the database ** file. ^The callback is passed a copy of the generic data pointer (P), ** the schema-name of the attached database that is being autovacuumed, @@ -6647,7 +6757,7 @@ ** ^Each call to the sqlite3_autovacuum_pages() interface overrides all ** previous invocations for that database connection. ^If the callback ** argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, -** then the autovacuum steps callback is cancelled. The return value +** then the autovacuum steps callback is canceled. The return value ** from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might ** be some other error code if something goes wrong. The current ** implementation will only return SQLITE_OK or SQLITE_MISUSE, but other @@ -6729,7 +6839,7 @@ ** and [sqlite3_preupdate_hook()] interfaces. */ void *sqlite3_update_hook( - sqlite3*, + sqlite3*, void(*)(void *,int ,char const *,char const *,sqlite3_int64), void* ); @@ -6748,7 +6858,7 @@ ** [use of shared cache mode is discouraged]. ** ** ^Cache sharing is enabled and disabled for an entire process. -** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). +** This is a change as of SQLite [version 3.5.0] ([dateof:3.5.0]). ** In prior versions of SQLite, ** sharing was enabled or disabled for each thread separately. ** @@ -6769,8 +6879,8 @@ ** with the [SQLITE_OPEN_SHAREDCACHE] flag. ** ** Note: This method is disabled on MacOS X 10.7 and iOS version 5.0 -** and will always return SQLITE_MISUSE. On those systems, -** shared cache mode should be enabled per-database connection via +** and will always return SQLITE_MISUSE. On those systems, +** shared cache mode should be enabled per-database connection via ** [sqlite3_open_v2()] with [SQLITE_OPEN_SHAREDCACHE]. ** ** This interface is threadsafe on processors where writing a @@ -6823,7 +6933,7 @@ ** as heap memory usages approaches the limit. ** ^The soft heap limit is "soft" because even though SQLite strives to stay ** below the limit, it will exceed the limit rather than generate -** an [SQLITE_NOMEM] error. In other words, the soft heap limit +** an [SQLITE_NOMEM] error. In other words, the soft heap limit ** is advisory only. ** ** ^The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of @@ -6939,7 +7049,7 @@ ** ** ^If the specified table is actually a view, an [error code] is returned. ** -** ^If the specified column is "rowid", "oid" or "_rowid_" and the table +** ^If the specified column is "rowid", "oid" or "_rowid_" and the table ** is not a [WITHOUT ROWID] table and an ** [INTEGER PRIMARY KEY] column has been explicitly declared, then the output ** parameters are set for the explicitly declared column. ^(If there is no @@ -7005,7 +7115,7 @@ ** prior to calling this API, ** otherwise an error will be returned. ** -** Security warning: It is recommended that the +** Security warning: It is recommended that the ** [SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION] method be used to enable only this ** interface. The use of the [sqlite3_enable_load_extension()] interface ** should be avoided. This will keep the SQL function [load_extension()] @@ -7092,7 +7202,7 @@ ** ^The [sqlite3_cancel_auto_extension(X)] interface unregisters the ** initialization routine X that was registered using a prior call to ** [sqlite3_auto_extension(X)]. ^The [sqlite3_cancel_auto_extension(X)] -** routine returns 1 if initialization routine X was successfully +** routine returns 1 if initialization routine X was successfully ** unregistered and it returns 0 if X was not on the list of initialization ** routines. */ @@ -7118,8 +7228,8 @@ ** CAPI3REF: Virtual Table Object ** KEYWORDS: sqlite3_module {virtual table module} ** -** This structure, sometimes called a "virtual table module", -** defines the implementation of a [virtual table]. +** This structure, sometimes called a "virtual table module", +** defines the implementation of a [virtual table]. ** This structure consists mostly of methods for the module. ** ** ^A virtual table module is created by filling in a persistent @@ -7158,7 +7268,7 @@ void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); - /* The methods above are in version 1 of the sqlite_module object. Those + /* The methods above are in version 1 of the sqlite_module object. Those ** below are for version 2 and greater. */ int (*xSavepoint)(sqlite3_vtab *pVTab, int); int (*xRelease)(sqlite3_vtab *pVTab, int); @@ -7166,6 +7276,10 @@ /* The methods above are in versions 1 and 2 of the sqlite_module object. ** Those below are for version 3 and greater. */ int (*xShadowName)(const char*); + /* The methods above are in versions 1 through 3 of the sqlite_module object. + ** Those below are for version 4 and greater. */ + int (*xIntegrity)(sqlite3_vtab *pVTab, const char *zSchema, + const char *zTabName, int mFlags, char **pzErr); }; /* @@ -7208,7 +7322,7 @@ ** required by SQLite. If the table has at least 64 columns and any column ** to the right of the first 63 is required, then bit 63 of colUsed is also ** set. In other words, column iCol may be required if the expression -** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to +** (colUsed & ((sqlite3_uint64)1 << (iCol>=63 ? 63 : iCol))) evaluates to ** non-zero. ** ** The [xBestIndex] method must fill aConstraintUsage[] with information @@ -7235,17 +7349,17 @@ ** ** ^The estimatedCost value is an estimate of the cost of a particular ** strategy. A cost of N indicates that the cost of the strategy is similar -** to a linear scan of an SQLite table with N rows. A cost of log(N) +** to a linear scan of an SQLite table with N rows. A cost of log(N) ** indicates that the expense of the operation is similar to that of a ** binary search on a unique indexed field of an SQLite table with N rows. ** ** ^The estimatedRows value is an estimate of the number of rows that ** will be returned by the strategy. ** -** The xBestIndex method may optionally populate the idxFlags field with a +** The xBestIndex method may optionally populate the idxFlags field with a ** mask of SQLITE_INDEX_SCAN_* flags. Currently there is only one such flag - ** SQLITE_INDEX_SCAN_UNIQUE. If the xBestIndex method sets this flag, SQLite -** assumes that the strategy may visit at most one row. +** assumes that the strategy may visit at most one row. ** ** Additionally, if xBestIndex sets the SQLITE_INDEX_SCAN_UNIQUE flag, then ** SQLite also assumes that if a call to the xUpdate() method is made as @@ -7258,14 +7372,14 @@ ** the xUpdate method are automatically rolled back by SQLite. ** ** IMPORTANT: The estimatedRows field was added to the sqlite3_index_info -** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). +** structure for SQLite [version 3.8.2] ([dateof:3.8.2]). ** If a virtual table extension is -** used with an SQLite version earlier than 3.8.2, the results of attempting -** to read or write the estimatedRows field are undefined (but are likely +** used with an SQLite version earlier than 3.8.2, the results of attempting +** to read or write the estimatedRows field are undefined (but are likely ** to include crashing the application). The estimatedRows field should ** therefore only be used if [sqlite3_libversion_number()] returns a ** value greater than or equal to 3008002. Similarly, the idxFlags field -** was added for [version 3.9.0] ([dateof:3.9.0]). +** was added for [version 3.9.0] ([dateof:3.9.0]). ** It may therefore only be used if ** sqlite3_libversion_number() returns a value greater than or equal to ** 3009000. @@ -7305,7 +7419,7 @@ /* ** CAPI3REF: Virtual Table Scan Flags ** -** Virtual table implementations are allowed to set the +** Virtual table implementations are allowed to set the ** [sqlite3_index_info].idxFlags field to some combination of ** these bits. */ @@ -7377,7 +7491,7 @@ ** preexisting [virtual table] for the module. ** ** ^The module name is registered on the [database connection] specified -** by the first parameter. ^The name of the module is given by the +** by the first parameter. ^The name of the module is given by the ** second parameter. ^The third parameter is a pointer to ** the implementation of the [virtual table module]. ^The fourth ** parameter is an arbitrary client data pointer that is passed through @@ -7492,7 +7606,7 @@ ** METHOD: sqlite3 ** ** ^(Virtual tables can provide alternative implementations of functions -** using the [xFindFunction] method of the [virtual table module]. +** using the [xFindFunction] method of the [virtual table module]. ** But global versions of those functions ** must exist in order to be overloaded.)^ ** @@ -7533,7 +7647,7 @@ ** SELECT zColumn FROM zDb.zTable WHERE [rowid] = iRow; ** )^ ** -** ^(Parameter zDb is not the filename that contains the database, but +** ^(Parameter zDb is not the filename that contains the database, but ** rather the symbolic name of the database. For attached databases, this is ** the name that appears after the AS keyword in the [ATTACH] statement. ** For the main database file, the database name is "main". For TEMP @@ -7546,28 +7660,28 @@ ** ^(On success, [SQLITE_OK] is returned and the new [BLOB handle] is stored ** in *ppBlob. Otherwise an [error code] is returned and, unless the error ** code is SQLITE_MISUSE, *ppBlob is set to NULL.)^ ^This means that, provided -** the API is not misused, it is always safe to call [sqlite3_blob_close()] +** the API is not misused, it is always safe to call [sqlite3_blob_close()] ** on *ppBlob after this function it returns. ** ** This function fails with SQLITE_ERROR if any of the following are true: **
        -**
      • ^(Database zDb does not exist)^, -**
      • ^(Table zTable does not exist within database zDb)^, -**
      • ^(Table zTable is a WITHOUT ROWID table)^, +**
      • ^(Database zDb does not exist)^, +**
      • ^(Table zTable does not exist within database zDb)^, +**
      • ^(Table zTable is a WITHOUT ROWID table)^, **
      • ^(Column zColumn does not exist)^, **
      • ^(Row iRow is not present in the table)^, **
      • ^(The specified column of row iRow contains a value that is not ** a TEXT or BLOB value)^, -**
      • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE +**
      • ^(Column zColumn is part of an index, PRIMARY KEY or UNIQUE ** constraint and the blob is being opened for read/write access)^, -**
      • ^([foreign key constraints | Foreign key constraints] are enabled, +**
      • ^([foreign key constraints | Foreign key constraints] are enabled, ** column zColumn is part of a [child key] definition and the blob is ** being opened for read/write access)^. **
      ** -** ^Unless it returns SQLITE_MISUSE, this function sets the -** [database connection] error code and message accessible via -** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** ^Unless it returns SQLITE_MISUSE, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** ** A BLOB referenced by sqlite3_blob_open() may be read using the ** [sqlite3_blob_read()] interface and modified by using @@ -7593,7 +7707,7 @@ ** blob. ** ** ^The [sqlite3_bind_zeroblob()] and [sqlite3_result_zeroblob()] interfaces -** and the built-in [zeroblob] SQL function may be used to create a +** and the built-in [zeroblob] SQL function may be used to create a ** zero-filled blob to read or write using the incremental-blob interface. ** ** To avoid a resource leak, every open [BLOB handle] should eventually @@ -7643,7 +7757,7 @@ ** DESTRUCTOR: sqlite3_blob ** ** ^This function closes an open [BLOB handle]. ^(The BLOB handle is closed -** unconditionally. Even if this routine returns an error code, the +** unconditionally. Even if this routine returns an error code, the ** handle is still closed.)^ ** ** ^If the blob handle being closed was opened for read-write access, and if @@ -7653,10 +7767,10 @@ ** code is returned and the transaction rolled back. ** ** Calling this function with an argument that is not a NULL pointer or an -** open blob handle results in undefined behaviour. ^Calling this routine -** with a null pointer (such as would be returned by a failed call to +** open blob handle results in undefined behavior. ^Calling this routine +** with a null pointer (such as would be returned by a failed call to ** [sqlite3_blob_open()]) is a harmless no-op. ^Otherwise, if this function -** is passed a valid open blob handle, the values returned by the +** is passed a valid open blob handle, the values returned by the ** sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. */ int sqlite3_blob_close(sqlite3_blob *); @@ -7665,7 +7779,7 @@ ** CAPI3REF: Return The Size Of An Open BLOB ** METHOD: sqlite3_blob ** -** ^Returns the size in bytes of the BLOB accessible via the +** ^Returns the size in bytes of the BLOB accessible via the ** successfully opened [BLOB handle] in its only argument. ^The ** incremental blob I/O routines can only read or overwriting existing ** blob content; they cannot change the size of a blob. @@ -7716,9 +7830,9 @@ ** ** ^(On success, sqlite3_blob_write() returns SQLITE_OK. ** Otherwise, an [error code] or an [extended error code] is returned.)^ -** ^Unless SQLITE_MISUSE is returned, this function sets the -** [database connection] error code and message accessible via -** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. +** ^Unless SQLITE_MISUSE is returned, this function sets the +** [database connection] error code and message accessible via +** [sqlite3_errcode()] and [sqlite3_errmsg()] and related functions. ** ** ^If the [BLOB handle] passed as the first argument was not opened for ** writing (the flags parameter to [sqlite3_blob_open()] was zero), @@ -7727,9 +7841,9 @@ ** This function may only modify the contents of the BLOB; it is ** not possible to increase the size of a BLOB using this API. ** ^If offset iOffset is less than N bytes from the end of the BLOB, -** [SQLITE_ERROR] is returned and no data is written. The size of the -** BLOB (and hence the maximum value of N+iOffset) can be determined -** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less +** [SQLITE_ERROR] is returned and no data is written. The size of the +** BLOB (and hence the maximum value of N+iOffset) can be determined +** using the [sqlite3_blob_bytes()] interface. ^If N or iOffset are less ** than zero [SQLITE_ERROR] is returned and no data is written. ** ** ^An attempt to write to an expired [BLOB handle] fails with an @@ -8048,7 +8162,7 @@ ** CAPI3REF: Retrieve the mutex for a database connection ** METHOD: sqlite3 ** -** ^This interface returns a pointer the [sqlite3_mutex] object that +** ^This interface returns a pointer the [sqlite3_mutex] object that ** serializes access to the [database connection] given in the argument ** when the [threading mode] is Serialized. ** ^If the [threading mode] is Single-thread or Multi-thread then this @@ -8075,7 +8189,7 @@ ** method becomes the return value of this routine. ** ** A few opcodes for [sqlite3_file_control()] are handled directly -** by the SQLite core and never invoke the +** by the SQLite core and never invoke the ** sqlite3_io_methods.xFileControl method. ** ^The [SQLITE_FCNTL_FILE_POINTER] value for the op parameter causes ** a pointer to the underlying [sqlite3_file] object to be written into @@ -8133,6 +8247,7 @@ #define SQLITE_TESTCTRL_PRNG_SAVE 5 #define SQLITE_TESTCTRL_PRNG_RESTORE 6 #define SQLITE_TESTCTRL_PRNG_RESET 7 /* NOT USED */ +#define SQLITE_TESTCTRL_FK_NO_ACTION 7 #define SQLITE_TESTCTRL_BITVEC_TEST 8 #define SQLITE_TESTCTRL_FAULT_INSTALL 9 #define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS 10 @@ -8161,12 +8276,13 @@ #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 #define SQLITE_TESTCTRL_LOGEST 33 -#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_USELONGDOUBLE 34 +#define SQLITE_TESTCTRL_LAST 34 /* Largest TESTCTRL */ /* ** CAPI3REF: SQL Keyword Checking ** -** These routines provide access to the set of SQL language keywords +** These routines provide access to the set of SQL language keywords ** recognized by SQLite. Applications can uses these routines to determine ** whether or not a specific identifier needs to be escaped (for example, ** by enclosing in double-quotes) so as not to confuse the parser. @@ -8238,14 +8354,14 @@ ** ** ^The [sqlite3_str_new(D)] interface allocates and initializes ** a new [sqlite3_str] object. To avoid memory leaks, the object returned by -** [sqlite3_str_new()] must be freed by a subsequent call to +** [sqlite3_str_new()] must be freed by a subsequent call to ** [sqlite3_str_finish(X)]. ** ** ^The [sqlite3_str_new(D)] interface always returns a pointer to a ** valid [sqlite3_str] object, though in the event of an out-of-memory ** error the returned object might be a special singleton that will -** silently reject new text, always return SQLITE_NOMEM from -** [sqlite3_str_errcode()], always return 0 for +** silently reject new text, always return SQLITE_NOMEM from +** [sqlite3_str_errcode()], always return 0 for ** [sqlite3_str_length()], and always return NULL from ** [sqlite3_str_finish(X)]. It is always safe to use the value ** returned by [sqlite3_str_new(D)] as the sqlite3_str parameter @@ -8281,9 +8397,9 @@ ** These interfaces add content to an sqlite3_str object previously obtained ** from [sqlite3_str_new()]. ** -** ^The [sqlite3_str_appendf(X,F,...)] and +** ^The [sqlite3_str_appendf(X,F,...)] and ** [sqlite3_str_vappendf(X,F,V)] interfaces uses the [built-in printf] -** functionality of SQLite to append formatted text onto the end of +** functionality of SQLite to append formatted text onto the end of ** [sqlite3_str] object X. ** ** ^The [sqlite3_str_append(X,S,N)] method appends exactly N bytes from string S @@ -8300,7 +8416,7 @@ ** ^This method can be used, for example, to add whitespace indentation. ** ** ^The [sqlite3_str_reset(X)] method resets the string under construction -** inside [sqlite3_str] object X back to zero bytes in length. +** inside [sqlite3_str] object X back to zero bytes in length. ** ** These methods do not return a result code. ^If an error occurs, that fact ** is recorded in the [sqlite3_str] object and can be recovered by a @@ -8402,7 +8518,7 @@ **
      This parameter records the largest memory allocation request ** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their ** internal equivalents). Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
      )^ ** ** [[SQLITE_STATUS_MALLOC_COUNT]] ^(
      SQLITE_STATUS_MALLOC_COUNT
      @@ -8411,11 +8527,11 @@ ** ** [[SQLITE_STATUS_PAGECACHE_USED]] ^(
      SQLITE_STATUS_PAGECACHE_USED
      **
      This parameter returns the number of pages used out of the -** [pagecache memory allocator] that was configured using +** [pagecache memory allocator] that was configured using ** [SQLITE_CONFIG_PAGECACHE]. The ** value returned is in pages, not in bytes.
      )^ ** -** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] +** [[SQLITE_STATUS_PAGECACHE_OVERFLOW]] ** ^(
      SQLITE_STATUS_PAGECACHE_OVERFLOW
      **
      This parameter returns the number of bytes of page cache ** allocation which could not be satisfied by the [SQLITE_CONFIG_PAGECACHE] @@ -8428,7 +8544,7 @@ ** [[SQLITE_STATUS_PAGECACHE_SIZE]] ^(
      SQLITE_STATUS_PAGECACHE_SIZE
      **
      This parameter records the largest memory allocation request ** handed to the [pagecache memory allocator]. Only the value returned in the -** *pHighwater parameter to [sqlite3_status()] is of interest. +** *pHighwater parameter to [sqlite3_status()] is of interest. ** The value written into the *pCurrent parameter is undefined.
      )^ ** ** [[SQLITE_STATUS_SCRATCH_USED]]
      SQLITE_STATUS_SCRATCH_USED
      @@ -8441,7 +8557,7 @@ **
      No longer used.
      ** ** [[SQLITE_STATUS_PARSER_STACK]] ^(
      SQLITE_STATUS_PARSER_STACK
      -**
      The *pHighwater parameter records the deepest parser stack. +**
      The *pHighwater parameter records the deepest parser stack. ** The *pCurrent value is undefined. The *pHighwater value is only ** meaningful if SQLite is compiled with [YYTRACKMAXSTACKDEPTH].
      )^ ** @@ -8463,12 +8579,12 @@ ** CAPI3REF: Database Connection Status ** METHOD: sqlite3 ** -** ^This interface is used to retrieve runtime status information +** ^This interface is used to retrieve runtime status information ** about a single [database connection]. ^The first argument is the ** database connection object to be interrogated. ^The second argument ** is an integer constant, taken from the set of ** [SQLITE_DBSTATUS options], that -** determines the parameter to interrogate. The set of +** determines the parameter to interrogate. The set of ** [SQLITE_DBSTATUS options] is likely ** to grow in future releases of SQLite. ** @@ -8503,7 +8619,7 @@ ** checked out.
    )^ ** ** [[SQLITE_DBSTATUS_LOOKASIDE_HIT]] ^(
    SQLITE_DBSTATUS_LOOKASIDE_HIT
    -**
    This parameter returns the number of malloc attempts that were +**
    This parameter returns the number of malloc attempts that were ** satisfied using lookaside memory. Only the high-water value is meaningful; ** the current value is always zero.)^ ** @@ -8528,7 +8644,7 @@ ** memory used by all pager caches associated with the database connection.)^ ** ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. ** -** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] +** [[SQLITE_DBSTATUS_CACHE_USED_SHARED]] ** ^(
    SQLITE_DBSTATUS_CACHE_USED_SHARED
    **
    This parameter is similar to DBSTATUS_CACHE_USED, except that if a ** pager cache is shared between two or more connections the bytes of heap @@ -8543,7 +8659,7 @@ ** [[SQLITE_DBSTATUS_SCHEMA_USED]] ^(
    SQLITE_DBSTATUS_SCHEMA_USED
    **
    This parameter returns the approximate number of bytes of heap ** memory used to store the schema for all databases associated -** with the connection - main, temp, and any [ATTACH]-ed databases.)^ +** with the connection - main, temp, and any [ATTACH]-ed databases.)^ ** ^The full amount of memory used by the schemas is reported, even if the ** schema memory is shared with other database connections due to ** [shared cache mode] being enabled. @@ -8558,13 +8674,13 @@ ** ** [[SQLITE_DBSTATUS_CACHE_HIT]] ^(
    SQLITE_DBSTATUS_CACHE_HIT
    **
    This parameter returns the number of pager cache hits that have -** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT ** is always 0. **
    ** ** [[SQLITE_DBSTATUS_CACHE_MISS]] ^(
    SQLITE_DBSTATUS_CACHE_MISS
    **
    This parameter returns the number of pager cache misses that have -** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS +** occurred.)^ ^The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS ** is always 0. **
    ** @@ -8622,7 +8738,7 @@ ** statements. For example, if the number of table steps greatly exceeds ** the number of table searches or result rows, that would tend to indicate ** that the prepared statement is using a full table scan rather than -** an index. +** an index. ** ** ^(This interface is used to retrieve and reset counter values from ** a [prepared statement]. The first argument is the prepared statement @@ -8649,7 +8765,7 @@ ** [[SQLITE_STMTSTATUS_FULLSCAN_STEP]]
    SQLITE_STMTSTATUS_FULLSCAN_STEP
    **
    ^This is the number of times that SQLite has stepped forward in ** a table as part of a full table scan. Large numbers for this counter -** may indicate opportunities for performance improvement through +** may indicate opportunities for performance improvement through ** careful use of indices.
    ** ** [[SQLITE_STMTSTATUS_SORT]]
    SQLITE_STMTSTATUS_SORT
    @@ -8667,14 +8783,14 @@ ** [[SQLITE_STMTSTATUS_VM_STEP]]
    SQLITE_STMTSTATUS_VM_STEP
    **
    ^This is the number of virtual machine operations executed ** by the prepared statement if that number is less than or equal -** to 2147483647. The number of virtual machine operations can be +** to 2147483647. The number of virtual machine operations can be ** used as a proxy for the total work done by the prepared statement. ** If the number of virtual machine operations exceeds 2147483647 ** then the value returned by this statement status code is undefined. ** ** [[SQLITE_STMTSTATUS_REPREPARE]]
    SQLITE_STMTSTATUS_REPREPARE
    **
    ^This is the number of times that the prepare statement has been -** automatically regenerated due to schema changes or changes to +** automatically regenerated due to schema changes or changes to ** [bound parameters] that might affect the query plan. ** ** [[SQLITE_STMTSTATUS_RUN]]
    SQLITE_STMTSTATUS_RUN
    @@ -8685,7 +8801,7 @@ ** cycle. ** ** [[SQLITE_STMTSTATUS_FILTER_MISS]] -** [[SQLITE_STMTSTATUS_FILTER HIT]] +** [[SQLITE_STMTSTATUS_FILTER HIT]] **
    SQLITE_STMTSTATUS_FILTER_HIT
    ** SQLITE_STMTSTATUS_FILTER_MISS
    **
    ^SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join @@ -8746,15 +8862,15 @@ ** KEYWORDS: {page cache} ** ** ^(The [sqlite3_config]([SQLITE_CONFIG_PCACHE2], ...) interface can -** register an alternative page cache implementation by passing in an +** register an alternative page cache implementation by passing in an ** instance of the sqlite3_pcache_methods2 structure.)^ -** In many applications, most of the heap memory allocated by +** In many applications, most of the heap memory allocated by ** SQLite is used for the page cache. -** By implementing a +** By implementing a ** custom page cache using this API, an application can better control -** the amount of memory consumed by SQLite, the way in which -** that memory is allocated and released, and the policies used to -** determine exactly which parts of a database file are cached and for +** the amount of memory consumed by SQLite, the way in which +** that memory is allocated and released, and the policies used to +** determine exactly which parts of a database file are cached and for ** how long. ** ** The alternative page cache mechanism is an @@ -8767,19 +8883,19 @@ ** [sqlite3_config()] returns.)^ ** ** [[the xInit() page cache method]] -** ^(The xInit() method is called once for each effective +** ^(The xInit() method is called once for each effective ** call to [sqlite3_initialize()])^ ** (usually only once during the lifetime of the process). ^(The xInit() ** method is passed a copy of the sqlite3_pcache_methods2.pArg value.)^ -** The intent of the xInit() method is to set up global data structures -** required by the custom page cache implementation. -** ^(If the xInit() method is NULL, then the +** The intent of the xInit() method is to set up global data structures +** required by the custom page cache implementation. +** ^(If the xInit() method is NULL, then the ** built-in default page cache is used instead of the application defined ** page cache.)^ ** ** [[the xShutdown() page cache method]] ** ^The xShutdown() method is called by [sqlite3_shutdown()]. -** It can be used to clean up +** It can be used to clean up ** any outstanding resources before process shutdown, if required. ** ^The xShutdown() method may be NULL. ** @@ -8798,7 +8914,7 @@ ** though this is not guaranteed. ^The ** first parameter, szPage, is the size in bytes of the pages that must ** be allocated by the cache. ^szPage will always a power of two. ^The -** second parameter szExtra is a number of bytes of extra storage +** second parameter szExtra is a number of bytes of extra storage ** associated with each page cache entry. ^The szExtra parameter will ** a number less than 250. SQLite will use the ** extra szExtra bytes on each page to store metadata about the underlying @@ -8811,7 +8927,7 @@ ** it is purely advisory. ^On a cache where bPurgeable is false, SQLite will ** never invoke xUnpin() except to deliberately delete a page. ** ^In other words, calls to xUnpin() on a cache with bPurgeable set to -** false will always have the "discard" flag set to true. +** false will always have the "discard" flag set to true. ** ^Hence, a cache created with bPurgeable false will ** never contain any unpinned pages. ** @@ -8826,12 +8942,12 @@ ** [[the xPagecount() page cache methods]] ** The xPagecount() method must return the number of pages currently ** stored in the cache, both pinned and unpinned. -** +** ** [[the xFetch() page cache methods]] -** The xFetch() method locates a page in the cache and returns a pointer to +** The xFetch() method locates a page in the cache and returns a pointer to ** an sqlite3_pcache_page object associated with that page, or a NULL pointer. ** The pBuf element of the returned sqlite3_pcache_page object will be a -** pointer to a buffer of szPage bytes used to store the content of a +** pointer to a buffer of szPage bytes used to store the content of a ** single database page. The pExtra element of sqlite3_pcache_page will be ** a pointer to the szExtra bytes of extra storage that SQLite has requested ** for each entry in the page cache. @@ -8870,8 +8986,8 @@ ** page cache implementation. ^The page cache implementation ** may choose to evict unpinned pages at any time. ** -** The cache must not perform any reference counting. A single -** call to xUnpin() unpins the page regardless of the number of prior calls +** The cache must not perform any reference counting. A single +** call to xUnpin() unpins the page regardless of the number of prior calls ** to xFetch(). ** ** [[the xRekey() page cache methods]] @@ -8911,7 +9027,7 @@ int (*xPagecount)(sqlite3_pcache*); sqlite3_pcache_page *(*xFetch)(sqlite3_pcache*, unsigned key, int createFlag); void (*xUnpin)(sqlite3_pcache*, sqlite3_pcache_page*, int discard); - void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, + void (*xRekey)(sqlite3_pcache*, sqlite3_pcache_page*, unsigned oldKey, unsigned newKey); void (*xTruncate)(sqlite3_pcache*, unsigned iLimit); void (*xDestroy)(sqlite3_pcache*); @@ -8956,7 +9072,7 @@ ** ** The backup API copies the content of one database into another. ** It is useful either for creating backups of databases or -** for copying in-memory databases to or from persistent files. +** for copying in-memory databases to or from persistent files. ** ** See Also: [Using the SQLite Online Backup API] ** @@ -8967,36 +9083,36 @@ ** ^Thus, the backup may be performed on a live source database without ** preventing other database connections from ** reading or writing to the source database while the backup is underway. -** -** ^(To perform a backup operation: +** +** ^(To perform a backup operation: **
      **
    1. sqlite3_backup_init() is called once to initialize the -** backup, -**
    2. sqlite3_backup_step() is called one or more times to transfer +** backup, +**
    3. sqlite3_backup_step() is called one or more times to transfer ** the data between the two databases, and finally -**
    4. sqlite3_backup_finish() is called to release all resources -** associated with the backup operation. +**
    5. sqlite3_backup_finish() is called to release all resources +** associated with the backup operation. **
    )^ ** There should be exactly one call to sqlite3_backup_finish() for each ** successful call to sqlite3_backup_init(). ** ** [[sqlite3_backup_init()]] sqlite3_backup_init() ** -** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the -** [database connection] associated with the destination database +** ^The D and N arguments to sqlite3_backup_init(D,N,S,M) are the +** [database connection] associated with the destination database ** and the database name, respectively. ** ^The database name is "main" for the main database, "temp" for the ** temporary database, or the name specified after the AS keyword in ** an [ATTACH] statement for an attached database. -** ^The S and M arguments passed to +** ^The S and M arguments passed to ** sqlite3_backup_init(D,N,S,M) identify the [database connection] ** and database name of the source database, respectively. ** ^The source and destination [database connections] (parameters S and D) ** must be different or else sqlite3_backup_init(D,N,S,M) will fail with ** an error. ** -** ^A call to sqlite3_backup_init() will fail, returning NULL, if -** there is already a read or read-write transaction open on the +** ^A call to sqlite3_backup_init() will fail, returning NULL, if +** there is already a read or read-write transaction open on the ** destination database. ** ** ^If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is @@ -9008,14 +9124,14 @@ ** ^A successful call to sqlite3_backup_init() returns a pointer to an ** [sqlite3_backup] object. ** ^The [sqlite3_backup] object may be used with the sqlite3_backup_step() and -** sqlite3_backup_finish() functions to perform the specified backup +** sqlite3_backup_finish() functions to perform the specified backup ** operation. ** ** [[sqlite3_backup_step()]] sqlite3_backup_step() ** -** ^Function sqlite3_backup_step(B,N) will copy up to N pages between +** ^Function sqlite3_backup_step(B,N) will copy up to N pages between ** the source and destination databases specified by [sqlite3_backup] object B. -** ^If N is negative, all remaining source pages are copied. +** ^If N is negative, all remaining source pages are copied. ** ^If sqlite3_backup_step(B,N) successfully copies N pages and there ** are still more pages to be copied, then the function returns [SQLITE_OK]. ** ^If sqlite3_backup_step(B,N) successfully finishes copying all pages @@ -9037,8 +9153,8 @@ ** ** ^If sqlite3_backup_step() cannot obtain a required file-system lock, then ** the [sqlite3_busy_handler | busy-handler function] -** is invoked (if one is specified). ^If the -** busy-handler returns non-zero before the lock is available, then +** is invoked (if one is specified). ^If the +** busy-handler returns non-zero before the lock is available, then ** [SQLITE_BUSY] is returned to the caller. ^In this case the call to ** sqlite3_backup_step() can be retried later. ^If the source ** [database connection] @@ -9046,15 +9162,15 @@ ** is called, then [SQLITE_LOCKED] is returned immediately. ^Again, in this ** case the call to sqlite3_backup_step() can be retried later on. ^(If ** [SQLITE_IOERR_ACCESS | SQLITE_IOERR_XXX], [SQLITE_NOMEM], or -** [SQLITE_READONLY] is returned, then -** there is no point in retrying the call to sqlite3_backup_step(). These -** errors are considered fatal.)^ The application must accept -** that the backup operation has failed and pass the backup operation handle +** [SQLITE_READONLY] is returned, then +** there is no point in retrying the call to sqlite3_backup_step(). These +** errors are considered fatal.)^ The application must accept +** that the backup operation has failed and pass the backup operation handle ** to the sqlite3_backup_finish() to release associated resources. ** ** ^The first call to sqlite3_backup_step() obtains an exclusive lock -** on the destination file. ^The exclusive lock is not released until either -** sqlite3_backup_finish() is called or the backup operation is complete +** on the destination file. ^The exclusive lock is not released until either +** sqlite3_backup_finish() is called or the backup operation is complete ** and sqlite3_backup_step() returns [SQLITE_DONE]. ^Every call to ** sqlite3_backup_step() obtains a [shared lock] on the source database that ** lasts for the duration of the sqlite3_backup_step() call. @@ -9063,18 +9179,18 @@ ** through the backup process. ^If the source database is modified by an ** external process or via a database connection other than the one being ** used by the backup operation, then the backup will be automatically -** restarted by the next call to sqlite3_backup_step(). ^If the source +** restarted by the next call to sqlite3_backup_step(). ^If the source ** database is modified by the using the same database connection as is used ** by the backup operation, then the backup database is automatically ** updated at the same time. ** ** [[sqlite3_backup_finish()]] sqlite3_backup_finish() ** -** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the +** When sqlite3_backup_step() has returned [SQLITE_DONE], or when the ** application wishes to abandon the backup operation, the application ** should destroy the [sqlite3_backup] by passing it to sqlite3_backup_finish(). ** ^The sqlite3_backup_finish() interfaces releases all -** resources associated with the [sqlite3_backup] object. +** resources associated with the [sqlite3_backup] object. ** ^If sqlite3_backup_step() has not yet returned [SQLITE_DONE], then any ** active write-transaction on the destination database is rolled back. ** The [sqlite3_backup] object is invalid @@ -9114,8 +9230,8 @@ ** connections, then the source database connection may be used concurrently ** from within other threads. ** -** However, the application must guarantee that the destination -** [database connection] is not passed to any other API (by any thread) after +** However, the application must guarantee that the destination +** [database connection] is not passed to any other API (by any thread) after ** sqlite3_backup_init() is called and before the corresponding call to ** sqlite3_backup_finish(). SQLite does not currently check to see ** if the application incorrectly accesses the destination [database connection] @@ -9126,11 +9242,11 @@ ** If running in [shared cache mode], the application must ** guarantee that the shared cache used by the destination database ** is not accessed while the backup is running. In practice this means -** that the application must guarantee that the disk file being +** that the application must guarantee that the disk file being ** backed up to is not accessed by any connection within the process, ** not just the specific connection that was passed to sqlite3_backup_init(). ** -** The [sqlite3_backup] object itself is partially threadsafe. Multiple +** The [sqlite3_backup] object itself is partially threadsafe. Multiple ** threads may safely make multiple concurrent calls to sqlite3_backup_step(). ** However, the sqlite3_backup_remaining() and sqlite3_backup_pagecount() ** APIs are not strictly speaking threadsafe. If they are invoked at the @@ -9155,8 +9271,8 @@ ** ^When running in shared-cache mode, a database operation may fail with ** an [SQLITE_LOCKED] error if the required locks on the shared-cache or ** individual tables within the shared-cache cannot be obtained. See -** [SQLite Shared-Cache Mode] for a description of shared-cache locking. -** ^This API may be used to register a callback that SQLite will invoke +** [SQLite Shared-Cache Mode] for a description of shared-cache locking. +** ^This API may be used to register a callback that SQLite will invoke ** when the connection currently holding the required lock relinquishes it. ** ^This API is only available if the library was compiled with the ** [SQLITE_ENABLE_UNLOCK_NOTIFY] C-preprocessor symbol defined. @@ -9164,14 +9280,14 @@ ** See Also: [Using the SQLite Unlock Notification Feature]. ** ** ^Shared-cache locks are released when a database connection concludes -** its current transaction, either by committing it or rolling it back. +** its current transaction, either by committing it or rolling it back. ** ** ^When a connection (known as the blocked connection) fails to obtain a ** shared-cache lock and SQLITE_LOCKED is returned to the caller, the ** identity of the database connection (the blocking connection) that -** has locked the required resource is stored internally. ^After an +** has locked the required resource is stored internally. ^After an ** application receives an SQLITE_LOCKED error, it may call the -** sqlite3_unlock_notify() method with the blocked connection handle as +** sqlite3_unlock_notify() method with the blocked connection handle as ** the first argument to register for a callback that will be invoked ** when the blocking connections current transaction is concluded. ^The ** callback is invoked from within the [sqlite3_step] or [sqlite3_close] @@ -9185,15 +9301,15 @@ ** ** ^If the blocked connection is attempting to obtain a write-lock on a ** shared-cache table, and more than one other connection currently holds -** a read-lock on the same table, then SQLite arbitrarily selects one of +** a read-lock on the same table, then SQLite arbitrarily selects one of ** the other connections to use as the blocking connection. ** -** ^(There may be at most one unlock-notify callback registered by a +** ^(There may be at most one unlock-notify callback registered by a ** blocked connection. If sqlite3_unlock_notify() is called when the ** blocked connection already has a registered unlock-notify callback, ** then the new callback replaces the old.)^ ^If sqlite3_unlock_notify() is ** called with a NULL pointer as its second argument, then any existing -** unlock-notify callback is canceled. ^The blocked connections +** unlock-notify callback is canceled. ^The blocked connections ** unlock-notify callback may also be canceled by closing the blocked ** connection using [sqlite3_close()]. ** @@ -9206,7 +9322,7 @@ ** ** Callback Invocation Details ** -** When an unlock-notify callback is registered, the application provides a +** When an unlock-notify callback is registered, the application provides a ** single void* pointer that is passed to the callback when it is invoked. ** However, the signature of the callback function allows SQLite to pass ** it an array of void* context pointers. The first argument passed to @@ -9219,12 +9335,12 @@ ** same callback function, then instead of invoking the callback function ** multiple times, it is invoked once with the set of void* context pointers ** specified by the blocked connections bundled together into an array. -** This gives the application an opportunity to prioritize any actions +** This gives the application an opportunity to prioritize any actions ** related to the set of unblocked database connections. ** ** Deadlock Detection ** -** Assuming that after registering for an unlock-notify callback a +** Assuming that after registering for an unlock-notify callback a ** database waits for the callback to be issued before taking any further ** action (a reasonable assumption), then using this API may cause the ** application to deadlock. For example, if connection X is waiting for @@ -9247,7 +9363,7 @@ ** ** The "DROP TABLE" Exception ** -** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost +** When a call to [sqlite3_step()] returns SQLITE_LOCKED, it is almost ** always appropriate to call sqlite3_unlock_notify(). There is however, ** one exception. When executing a "DROP TABLE" or "DROP INDEX" statement, ** SQLite checks if there are any currently executing SELECT statements @@ -9260,7 +9376,7 @@ ** One way around this problem is to check the extended error code returned ** by an sqlite3_step() call. ^(If there is a blocking connection, then the ** extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in -** the special "DROP TABLE/INDEX" case, the extended error code is just +** the special "DROP TABLE/INDEX" case, the extended error code is just ** SQLITE_LOCKED.)^ */ int sqlite3_unlock_notify( @@ -9351,8 +9467,8 @@ ** ^The [sqlite3_wal_hook()] function is used to register a callback that ** is invoked each time data is committed to a database in wal mode. ** -** ^(The callback is invoked by SQLite after the commit has taken place and -** the associated write-lock on the database released)^, so the implementation +** ^(The callback is invoked by SQLite after the commit has taken place and +** the associated write-lock on the database released)^, so the implementation ** may read, write or [checkpoint] the database as required. ** ** ^The first parameter passed to the callback function when it is invoked @@ -9371,7 +9487,7 @@ ** that does not correspond to any valid SQLite error code, the results ** are undefined. ** -** A single database handle may have at most a single write-ahead log callback +** A single database handle may have at most a single write-ahead log callback ** registered at one time. ^Calling [sqlite3_wal_hook()] replaces any ** previously registered write-ahead log callback. ^The return value is ** a copy of the third parameter from the previous call, if any, or 0. @@ -9380,7 +9496,7 @@ ** overwrite any prior [sqlite3_wal_hook()] settings. */ void *sqlite3_wal_hook( - sqlite3*, + sqlite3*, int(*)(void *,sqlite3*,const char*,int), void* ); @@ -9393,7 +9509,7 @@ ** [sqlite3_wal_hook()] that causes any database on [database connection] D ** to automatically [checkpoint] ** after committing a transaction if there are N or -** more frames in the [write-ahead log] file. ^Passing zero or +** more frames in the [write-ahead log] file. ^Passing zero or ** a negative value as the nFrame parameter disables automatic ** checkpoints entirely. ** @@ -9423,7 +9539,7 @@ ** ^(The sqlite3_wal_checkpoint(D,X) is equivalent to ** [sqlite3_wal_checkpoint_v2](D,X,[SQLITE_CHECKPOINT_PASSIVE],0,0).)^ ** -** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the +** In brief, sqlite3_wal_checkpoint(D,X) causes the content in the ** [write-ahead log] for database X on [database connection] D to be ** transferred into the database file and for the write-ahead log to ** be reset. See the [checkpointing] documentation for addition @@ -9449,10 +9565,10 @@ ** **
    **
    SQLITE_CHECKPOINT_PASSIVE
    -** ^Checkpoint as many frames as possible without waiting for any database -** readers or writers to finish, then sync the database file if all frames +** ^Checkpoint as many frames as possible without waiting for any database +** readers or writers to finish, then sync the database file if all frames ** in the log were checkpointed. ^The [busy-handler callback] -** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. +** is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. ** ^On the other hand, passive mode might leave the checkpoint unfinished ** if there are concurrent readers or writers. ** @@ -9466,9 +9582,9 @@ ** **
    SQLITE_CHECKPOINT_RESTART
    ** ^This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition -** that after checkpointing the log file it blocks (calls the +** that after checkpointing the log file it blocks (calls the ** [busy-handler callback]) -** until all readers are reading from the database file only. ^This ensures +** until all readers are reading from the database file only. ^This ensures ** that the next writer will restart the log file from the beginning. ** ^Like SQLITE_CHECKPOINT_FULL, this mode blocks new ** database writer attempts while it is pending, but does not impede readers. @@ -9490,31 +9606,31 @@ ** truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. ** ** ^All calls obtain an exclusive "checkpoint" lock on the database file. ^If -** any other process is running a checkpoint operation at the same time, the -** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a +** any other process is running a checkpoint operation at the same time, the +** lock cannot be obtained and SQLITE_BUSY is returned. ^Even if there is a ** busy-handler configured, it will not be invoked in this case. ** -** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the +** ^The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the ** exclusive "writer" lock on the database file. ^If the writer lock cannot be ** obtained immediately, and a busy-handler is configured, it is invoked and ** the writer lock retried until either the busy-handler returns 0 or the lock ** is successfully obtained. ^The busy-handler is also invoked while waiting for ** database readers as described above. ^If the busy-handler returns 0 before ** the writer lock is obtained or while waiting for database readers, the -** checkpoint operation proceeds from that point in the same way as -** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible +** checkpoint operation proceeds from that point in the same way as +** SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible ** without blocking any further. ^SQLITE_BUSY is returned in this case. ** ** ^If parameter zDb is NULL or points to a zero length string, then the -** specified operation is attempted on all WAL databases [attached] to +** specified operation is attempted on all WAL databases [attached] to ** [database connection] db. In this case the -** values written to output parameters *pnLog and *pnCkpt are undefined. ^If -** an SQLITE_BUSY error is encountered when processing one or more of the -** attached WAL databases, the operation is still attempted on any remaining -** attached databases and SQLITE_BUSY is returned at the end. ^If any other -** error occurs while processing an attached database, processing is abandoned -** and the error code is returned to the caller immediately. ^If no error -** (SQLITE_BUSY or otherwise) is encountered while processing the attached +** values written to output parameters *pnLog and *pnCkpt are undefined. ^If +** an SQLITE_BUSY error is encountered when processing one or more of the +** attached WAL databases, the operation is still attempted on any remaining +** attached databases and SQLITE_BUSY is returned at the end. ^If any other +** error occurs while processing an attached database, processing is abandoned +** and the error code is returned to the caller immediately. ^If no error +** (SQLITE_BUSY or otherwise) is encountered while processing the attached ** databases, SQLITE_OK is returned. ** ** ^If database zDb is the name of an attached database that is not in WAL @@ -9574,7 +9690,7 @@ /* ** CAPI3REF: Virtual Table Configuration Options -** KEYWORDS: {virtual table configuration options} +** KEYWORDS: {virtual table configuration options} ** KEYWORDS: {virtual table configuration option} ** ** These macros define the various options to the @@ -9597,27 +9713,27 @@ ** If X is non-zero, then the virtual table implementation guarantees ** that if [xUpdate] returns [SQLITE_CONSTRAINT], it will do so before ** any modifications to internal or persistent data structures have been made. -** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite +** If the [ON CONFLICT] mode is ABORT, FAIL, IGNORE or ROLLBACK, SQLite ** is able to roll back a statement or database transaction, and abandon -** or continue processing the current SQL statement as appropriate. +** or continue processing the current SQL statement as appropriate. ** If the ON CONFLICT mode is REPLACE and the [xUpdate] method returns ** [SQLITE_CONSTRAINT], SQLite handles this as if the ON CONFLICT mode ** had been ABORT. ** ** Virtual table implementations that are required to handle OR REPLACE -** must do so within the [xUpdate] method. If a call to the -** [sqlite3_vtab_on_conflict()] function indicates that the current ON -** CONFLICT policy is REPLACE, the virtual table implementation should +** must do so within the [xUpdate] method. If a call to the +** [sqlite3_vtab_on_conflict()] function indicates that the current ON +** CONFLICT policy is REPLACE, the virtual table implementation should ** silently replace the appropriate rows within the xUpdate callback and ** return SQLITE_OK. Or, if this is not possible, it may return -** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT +** SQLITE_CONSTRAINT, in which case SQLite falls back to OR ABORT ** constraint handling. **
    ** ** [[SQLITE_VTAB_DIRECTONLY]]
    SQLITE_VTAB_DIRECTONLY
    **
    Calls of the form ** [sqlite3_vtab_config](db,SQLITE_VTAB_DIRECTONLY) from within the -** the [xConnect] or [xCreate] methods of a [virtual table] implmentation +** the [xConnect] or [xCreate] methods of a [virtual table] implementation ** prohibits that virtual table from being used from within triggers and ** views. **
    @@ -9797,7 +9913,7 @@ /* ** CAPI3REF: Identify and handle IN constraints in xBestIndex ** -** This interface may only be used from within an +** This interface may only be used from within an ** [xBestIndex|xBestIndex() method] of a [virtual table] implementation. ** The result of invoking this interface from any other context is ** undefined and probably harmful. @@ -9807,7 +9923,7 @@ ** communicated to the xBestIndex method as a ** [SQLITE_INDEX_CONSTRAINT_EQ] constraint.)^ If xBestIndex wants to use ** this constraint, it must set the corresponding -** aConstraintUsage[].argvIndex to a postive integer. ^(Then, under +** aConstraintUsage[].argvIndex to a positive integer. ^(Then, under ** the usual mode of handling IN operators, SQLite generates [bytecode] ** that invokes the [xFilter|xFilter() method] once for each value ** on the right-hand side of the IN operator.)^ Thus the virtual table @@ -9856,7 +9972,7 @@ **
  • The last call to sqlite3_vtab_in(P,N,F) for which F was ** non-negative had F>=1. ** )^ -** +** ** ^If either or both of the conditions above are false, then SQLite uses ** the traditional one-at-a-time processing strategy for the IN constraint. ** ^If both conditions are true, then the argvIndex-th parameter to the @@ -9931,7 +10047,7 @@ ** that constraint if the right-hand operand is known. ^If the ** right-hand operand is not known, then *V is set to a NULL pointer. ** ^The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if -** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) +** and only if *V is set to a value. ^The sqlite3_vtab_rhs_value(P,J,V) ** inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th ** constraint is not available. ^The sqlite3_vtab_rhs_value() interface ** can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if @@ -10021,14 +10137,14 @@ ** [[SQLITE_SCANSTAT_SELECTID]]

    SQLITE_SCANSTAT_SELECTID
    **
    ^The "int" variable pointed to by the V parameter will be set to the ** id for the X-th query plan element. The id value is unique within the -** statement. The select-id is the same value as is output in the first +** statement. The select-id is the same value as is output in the first ** column of an [EXPLAIN QUERY PLAN] query. ** ** [[SQLITE_SCANSTAT_PARENTID]]
    SQLITE_SCANSTAT_PARENTID
    **
    The "int" variable pointed to by the V parameter will be set to the ** the id of the parent of the current query element, if applicable, or ** to zero if the query element has no parent. This is the same value as -** returned in the second column of an [EXPLAIN QUERY PLAN] query. +** returned in the second column of an [EXPLAIN QUERY PLAN] query. ** ** [[SQLITE_SCANSTAT_NCYCLE]]
    SQLITE_SCANSTAT_NCYCLE
    **
    The sqlite3_int64 output value is set to the number of cycles, @@ -10062,23 +10178,23 @@ ** ** The "iScanStatusOp" parameter determines which status information to return. ** The "iScanStatusOp" must be one of the [scanstatus options] or the behavior -** of this interface is undefined. ^The requested measurement is written into +** of this interface is undefined. ^The requested measurement is written into ** a variable pointed to by the "pOut" parameter. ** ** The "flags" parameter must be passed a mask of flags. At present only ** one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX -** is specified, then status information is available for all elements +** is specified, then status information is available for all elements ** of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If ** SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements ** that correspond to query loops (the "SCAN..." and "SEARCH..." elements of ** the EXPLAIN QUERY PLAN output) are available. Invoking API -** sqlite3_stmt_scanstatus() is equivalent to calling +** sqlite3_stmt_scanstatus() is equivalent to calling ** sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter. -** +** ** Parameter "idx" identifies the specific query element to retrieve statistics ** for. Query elements are numbered starting from zero. A value of -1 may be ** to query for statistics regarding the entire query. ^If idx is out of range -** - less than -1 or greater than or equal to the total number of query +** - less than -1 or greater than or equal to the total number of query ** elements used to implement the statement - a non-zero value is returned and ** the variable that pOut points to is unchanged. ** @@ -10089,14 +10205,14 @@ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ void *pOut /* Result written here */ -); +); int sqlite3_stmt_scanstatus_v2( sqlite3_stmt *pStmt, /* Prepared statement for which info desired */ int idx, /* Index of loop to report on */ int iScanStatusOp, /* Information desired. SQLITE_SCANSTAT_* */ int flags, /* Mask of flags defined below */ void *pOut /* Result written here */ -); +); /* ** CAPI3REF: Prepared Statement Scan Status @@ -10121,15 +10237,15 @@ ** ** ^If a write-transaction is open on [database connection] D when the ** [sqlite3_db_cacheflush(D)] interface invoked, any dirty -** pages in the pager-cache that are not currently in use are written out +** pages in the pager-cache that are not currently in use are written out ** to disk. A dirty page may be in use if a database cursor created by an ** active SQL statement is reading from it, or if it is page 1 of a database ** file (page 1 is always "in use"). ^The [sqlite3_db_cacheflush(D)] ** interface flushes caches for all schemas - "main", "temp", and ** any [attached] databases. ** -** ^If this function needs to obtain extra database locks before dirty pages -** can be flushed to disk, it does so. ^If those locks cannot be obtained +** ^If this function needs to obtain extra database locks before dirty pages +** can be flushed to disk, it does so. ^If those locks cannot be obtained ** immediately and there is a busy-handler callback configured, it is invoked ** in the usual manner. ^If the required lock still cannot be obtained, then ** the database is skipped and an attempt made to flush any dirty pages @@ -10177,16 +10293,16 @@ ** kind of update operation that is about to occur. ** ^(The fourth parameter to the preupdate callback is the name of the ** database within the database connection that is being modified. This -** will be "main" for the main database or "temp" for TEMP tables or +** will be "main" for the main database or "temp" for TEMP tables or ** the name given after the AS keyword in the [ATTACH] statement for attached ** databases.)^ ** ^The fifth parameter to the preupdate callback is the name of the ** table that is being modified. ** ** For an UPDATE or DELETE operation on a [rowid table], the sixth -** parameter passed to the preupdate callback is the initial [rowid] of the +** parameter passed to the preupdate callback is the initial [rowid] of the ** row being modified or deleted. For an INSERT operation on a rowid table, -** or any operation on a WITHOUT ROWID table, the value of the sixth +** or any operation on a WITHOUT ROWID table, the value of the sixth ** parameter is undefined. For an INSERT or UPDATE on a rowid table the ** seventh parameter is the final rowid value of the row being inserted ** or updated. The value of the seventh parameter passed to the callback @@ -10229,14 +10345,14 @@ ** ** ^The [sqlite3_preupdate_depth(D)] interface returns 0 if the preupdate ** callback was invoked as a result of a direct insert, update, or delete -** operation; or 1 for inserts, updates, or deletes invoked by top-level +** operation; or 1 for inserts, updates, or deletes invoked by top-level ** triggers; or 2 for changes resulting from triggers called by top-level ** triggers; and so forth. ** ** When the [sqlite3_blob_write()] API is used to update a blob column, ** the pre-update hook is invoked with SQLITE_DELETE. This is because the ** in this case the new values are not available. In this case, when a -** callback made with op==SQLITE_DELETE is actuall a write using the +** callback made with op==SQLITE_DELETE is actually a write using the ** sqlite3_blob_write() API, the [sqlite3_preupdate_blobwrite()] returns ** the index of the column being written. In other cases, where the ** pre-update hook is being invoked for some other reason, including a @@ -10274,7 +10390,7 @@ ** The return value is OS-dependent. For example, on unix systems, after ** [sqlite3_open_v2()] returns [SQLITE_CANTOPEN], this interface could be ** called to get back the underlying "errno" that caused the problem, such -** as ENOSPC, EAUTH, EISDIR, and so forth. +** as ENOSPC, EAUTH, EISDIR, and so forth. */ int sqlite3_system_errno(sqlite3*); @@ -10312,12 +10428,12 @@ ** [sqlite3_snapshot_get(D,S,P)] interface writes a pointer to the newly ** created [sqlite3_snapshot] object into *P and returns SQLITE_OK. ** If there is not already a read-transaction open on schema S when -** this function is called, one is opened automatically. +** this function is called, one is opened automatically. ** ** The following must be true for this function to succeed. If any of ** the following statements are false when sqlite3_snapshot_get() is ** called, SQLITE_ERROR is returned. The final value of *P is undefined -** in this case. +** in this case. ** **
      **
    • The database handle must not be in [autocommit mode]. @@ -10329,13 +10445,13 @@ ** **
    • One or more transactions must have been written to the current wal ** file since it was created on disk (by any connection). This means -** that a snapshot cannot be taken on a wal mode database with no wal +** that a snapshot cannot be taken on a wal mode database with no wal ** file immediately after it is first opened. At least one transaction ** must be written to it first. **
    ** ** This function may also return SQLITE_NOMEM. If it is called with the -** database handle in autocommit mode but fails for some other reason, +** database handle in autocommit mode but fails for some other reason, ** whether or not a read transaction is opened on schema S is undefined. ** ** The [sqlite3_snapshot] object returned from a successful call to @@ -10355,38 +10471,38 @@ ** CAPI3REF: Start a read transaction on an historical snapshot ** METHOD: sqlite3_snapshot ** -** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read -** transaction or upgrades an existing one for schema S of -** [database connection] D such that the read transaction refers to -** historical [snapshot] P, rather than the most recent change to the -** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK +** ^The [sqlite3_snapshot_open(D,S,P)] interface either starts a new read +** transaction or upgrades an existing one for schema S of +** [database connection] D such that the read transaction refers to +** historical [snapshot] P, rather than the most recent change to the +** database. ^The [sqlite3_snapshot_open()] interface returns SQLITE_OK ** on success or an appropriate [error code] if it fails. ** -** ^In order to succeed, the database connection must not be in +** ^In order to succeed, the database connection must not be in ** [autocommit mode] when [sqlite3_snapshot_open(D,S,P)] is called. If there ** is already a read transaction open on schema S, then the database handle ** must have no active statements (SELECT statements that have been passed -** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). +** to sqlite3_step() but not sqlite3_reset() or sqlite3_finalize()). ** SQLITE_ERROR is returned if either of these conditions is violated, or ** if schema S does not exist, or if the snapshot object is invalid. ** ** ^A call to sqlite3_snapshot_open() will fail to open if the specified -** snapshot has been overwritten by a [checkpoint]. In this case +** snapshot has been overwritten by a [checkpoint]. In this case ** SQLITE_ERROR_SNAPSHOT is returned. ** -** If there is already a read transaction open when this function is +** If there is already a read transaction open when this function is ** invoked, then the same read transaction remains open (on the same ** database snapshot) if SQLITE_ERROR, SQLITE_BUSY or SQLITE_ERROR_SNAPSHOT ** is returned. If another error code - for example SQLITE_PROTOCOL or an ** SQLITE_IOERR error code - is returned, then the final state of the -** read transaction is undefined. If SQLITE_OK is returned, then the +** read transaction is undefined. If SQLITE_OK is returned, then the ** read transaction is now open on database snapshot P. ** ** ^(A call to [sqlite3_snapshot_open(D,S,P)] will fail if the ** database connection D does not know that the database file for ** schema S is in [WAL mode]. A database connection might not know ** that the database file is in [WAL mode] if there has been no prior -** I/O on that database connection, or if the database entered [WAL mode] +** I/O on that database connection, or if the database entered [WAL mode] ** after the most recent I/O on the database connection.)^ ** (Hint: Run "[PRAGMA application_id]" against a newly opened ** database connection in order to make it ready to use snapshots.) @@ -10418,17 +10534,17 @@ ** METHOD: sqlite3_snapshot ** ** The sqlite3_snapshot_cmp(P1, P2) interface is used to compare the ages -** of two valid snapshot handles. +** of two valid snapshot handles. ** -** If the two snapshot handles are not associated with the same database -** file, the result of the comparison is undefined. +** If the two snapshot handles are not associated with the same database +** file, the result of the comparison is undefined. ** ** Additionally, the result of the comparison is only valid if both of the ** snapshot handles were obtained by calling sqlite3_snapshot_get() since the ** last time the wal file was deleted. The wal file is deleted when the ** database is changed back to rollback mode or when the number of database -** clients drops to zero. If either snapshot handle was obtained before the -** wal file was last deleted, the value returned by this function +** clients drops to zero. If either snapshot handle was obtained before the +** wal file was last deleted, the value returned by this function ** is undefined. ** ** Otherwise, this API returns a negative value if P1 refers to an older @@ -10493,10 +10609,17 @@ ** representation of the database will usually only exist if there has ** been a prior call to [sqlite3_deserialize(D,S,...)] with the same ** values of D and S. -** The size of the database is written into *P even if the +** The size of the database is written into *P even if the ** SQLITE_SERIALIZE_NOCOPY bit is set but no contiguous copy ** of the database exists. ** +** After the call, if the SQLITE_SERIALIZE_NOCOPY bit had been set, +** the returned buffer content will remain accessible and unchanged +** until either the next write operation on the connection or when +** the connection is closed, and applications must not modify the +** buffer. If the bit had been clear, the returned buffer will not +** be accessed by SQLite after the call. +** ** A call to sqlite3_serialize(D,S,P,F) might return NULL even if the ** SQLITE_SERIALIZE_NOCOPY bit is omitted from argument F if a memory ** allocation error occurs. @@ -10530,7 +10653,7 @@ /* ** CAPI3REF: Deserialize a database ** -** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the +** The sqlite3_deserialize(D,S,P,N,M,F) interface causes the ** [database connection] D to disconnect from database S and then ** reopen S as an in-memory database based on the serialization contained ** in P. The serialized database P is N bytes in size. M is the size of @@ -10545,6 +10668,9 @@ ** SQLite will try to increase the buffer size using sqlite3_realloc64() ** if writes on the database cause it to grow larger than M bytes. ** +** Applications must not modify the buffer P or invalidate it before +** the database connection D is closed. +** ** The sqlite3_deserialize() interface will fail with SQLITE_BUSY if the ** database is currently in a read transaction or is involved in a backup ** operation. @@ -10553,7 +10679,14 @@ ** S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the ** function returns SQLITE_ERROR. ** -** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the +** The deserialized database should not be in [WAL mode]. If the database +** is in WAL mode, then any attempt to use the database file will result +** in an [SQLITE_CANTOPEN] error. The application can set the +** [file format version numbers] (bytes 18 and 19) of the input database P +** to 0x01 prior to invoking sqlite3_deserialize(D,S,P,N,M,F) to force the +** database file into rollback mode and work around this limitation. +** +** If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the ** SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then ** [sqlite3_free()] is invoked on argument P prior to returning. ** diff -Nru sqlite3-3.42.0/src/sqliteInt.h sqlite3-3.44.0-0/src/sqliteInt.h --- sqlite3-3.42.0/src/sqliteInt.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/sqliteInt.h 2023-11-04 14:23:58.000000000 +0000 @@ -25,20 +25,20 @@ ** used on lines of code that actually ** implement parts of coverage testing. ** -** OPTIMIZATION-IF-TRUE - This branch is allowed to alway be false +** OPTIMIZATION-IF-TRUE - This branch is allowed to always be false ** and the correct answer is still obtained, ** though perhaps more slowly. ** -** OPTIMIZATION-IF-FALSE - This branch is allowed to alway be true +** OPTIMIZATION-IF-FALSE - This branch is allowed to always be true ** and the correct answer is still obtained, ** though perhaps more slowly. ** ** PREVENTS-HARMLESS-OVERREAD - This branch prevents a buffer overread ** that would be harmless and undetectable -** if it did occur. +** if it did occur. ** ** In all cases, the special comment must be enclosed in the usual -** slash-asterisk...asterisk-slash comment marks, with no spaces between the +** slash-asterisk...asterisk-slash comment marks, with no spaces between the ** asterisks and the comment text. */ @@ -182,7 +182,7 @@ #endif /* Optionally #include a user-defined header, whereby compilation options -** may be set prior to where they take effect, but after platform setup. +** may be set prior to where they take effect, but after platform setup. ** If SQLITE_CUSTOM_INCLUDE=? is defined, its value names the #include ** file. */ @@ -230,7 +230,7 @@ #ifndef __has_extension # define __has_extension(x) 0 /* compatibility with non-clang compilers */ #endif -#if GCC_VERSION>=4007000 || __has_extension(c_atomic) +#if GCC_VERSION>=4007000 || __has_extension(c_atomic) # define SQLITE_ATOMIC_INTRINSICS 1 # define AtomicLoad(PTR) __atomic_load_n((PTR),__ATOMIC_RELAXED) # define AtomicStore(PTR,VAL) __atomic_store_n((PTR),(VAL),__ATOMIC_RELAXED) @@ -319,6 +319,16 @@ #endif /* +** Enable SQLITE_USE_SEH by default on MSVC builds. Only omit +** SEH support if the -DSQLITE_OMIT_SEH option is given. +*/ +#if defined(_MSC_VER) && !defined(SQLITE_OMIT_SEH) +# define SQLITE_USE_SEH 1 +#else +# undef SQLITE_USE_SEH +#endif + +/* ** The SQLITE_THREADSAFE macro must be defined as 0, 1, or 2. ** 0 means mutexes are permanently disable and the library is never ** threadsafe. 1 means the library is serialized which is the highest @@ -722,7 +732,7 @@ #endif /* -** The compile-time options SQLITE_MMAP_READWRITE and +** The compile-time options SQLITE_MMAP_READWRITE and ** SQLITE_ENABLE_BATCH_ATOMIC_WRITE are not compatible with one another. ** You must choose one or the other (or neither) but not both. */ @@ -889,8 +899,31 @@ ** the end of buffer S. This macro returns true if P points to something ** contained within the buffer S. */ -#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) +#define SQLITE_WITHIN(P,S,E) (((uptr)(P)>=(uptr)(S))&&((uptr)(P)<(uptr)(E))) +/* +** P is one byte past the end of a large buffer. Return true if a span of bytes +** between S..E crosses the end of that buffer. In other words, return true +** if the sub-buffer S..E-1 overflows the buffer whose last byte is P-1. +** +** S is the start of the span. E is one byte past the end of end of span. +** +** P +** |-----------------| FALSE +** |-------| +** S E +** +** P +** |-----------------| +** |-------| TRUE +** S E +** +** P +** |-----------------| +** |-------| FALSE +** S E +*/ +#define SQLITE_OVERFLOW(P,S,E) (((uptr)(S)<(uptr)(P))&&((uptr)(E)>(uptr)(P))) /* ** Macros to determine whether the machine is big or little endian, @@ -900,16 +933,33 @@ ** using C-preprocessor macros. If that is unsuccessful, or if ** -DSQLITE_BYTEORDER=0 is set, then byte-order is determined ** at run-time. -*/ -#ifndef SQLITE_BYTEORDER -# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ +** +** If you are building SQLite on some obscure platform for which the +** following ifdef magic does not work, you can always include either: +** +** -DSQLITE_BYTEORDER=1234 +** +** or +** +** -DSQLITE_BYTEORDER=4321 +** +** to cause the build to work for little-endian or big-endian processors, +** respectively. +*/ +#ifndef SQLITE_BYTEORDER /* Replicate changes at tag-20230904a */ +# if defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_BIG_ENDIAN__ +# define SQLITE_BYTEORDER 4321 +# elif defined(__BYTE_ORDER__) && __BYTE_ORDER__==__ORDER_LITTLE_ENDIAN__ +# define SQLITE_BYTEORDER 1234 +# elif defined(__BIG_ENDIAN__) && __BIG_ENDIAN__==1 +# define SQLITE_BYTEORDER 4321 +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ defined(__ARMEL__) || defined(__AARCH64EL__) || defined(_M_ARM64) -# define SQLITE_BYTEORDER 1234 -# elif defined(sparc) || defined(__ppc__) || \ - defined(__ARMEB__) || defined(__AARCH64EB__) -# define SQLITE_BYTEORDER 4321 +# define SQLITE_BYTEORDER 1234 +# elif defined(sparc) || defined(__ARMEB__) || defined(__AARCH64EB__) +# define SQLITE_BYTEORDER 4321 # else # define SQLITE_BYTEORDER 0 # endif @@ -1124,7 +1174,7 @@ /* ** Name of table that holds the database schema. ** -** The PREFERRED names are used whereever possible. But LEGACY is also +** The PREFERRED names are used wherever possible. But LEGACY is also ** used for backwards compatibility. ** ** 1. Queries can use either the PREFERRED or the LEGACY names @@ -1233,11 +1283,13 @@ typedef struct Cte Cte; typedef struct CteUse CteUse; typedef struct Db Db; +typedef struct DbClientData DbClientData; typedef struct DbFixer DbFixer; typedef struct Schema Schema; typedef struct Expr Expr; typedef struct ExprList ExprList; typedef struct FKey FKey; +typedef struct FpDecode FpDecode; typedef struct FuncDestructor FuncDestructor; typedef struct FuncDef FuncDef; typedef struct FuncDefHash FuncDefHash; @@ -1256,6 +1308,7 @@ typedef struct ParseCleanup ParseCleanup; typedef struct PreUpdate PreUpdate; typedef struct PrintfArguments PrintfArguments; +typedef struct RCStr RCStr; typedef struct RenameToken RenameToken; typedef struct Returning Returning; typedef struct RowSet RowSet; @@ -1342,7 +1395,7 @@ /* ** Default synchronous levels. ** -** Note that (for historcal reasons) the PAGER_SYNCHRONOUS_* macros differ +** Note that (for historical reasons) the PAGER_SYNCHRONOUS_* macros differ ** from the SQLITE_DEFAULT_SYNCHRONOUS value by 1. ** ** PAGER_SYNCHRONOUS DEFAULT_SYNCHRONOUS @@ -1381,7 +1434,7 @@ ** 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 databaes (sqlite3.aDb[1]) which is free-standing. +** 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. ** @@ -1492,7 +1545,7 @@ LookasideSlot *pInit; /* List of buffers not previously used */ LookasideSlot *pFree; /* List of available buffers */ #ifndef SQLITE_OMIT_TWOSIZE_LOOKASIDE - LookasideSlot *pSmallInit; /* List of small buffers not prediously used */ + LookasideSlot *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 */ @@ -1509,7 +1562,7 @@ #define EnableLookaside db->lookaside.bDisable--;\ db->lookaside.sz=db->lookaside.bDisable?0:db->lookaside.szTrue -/* Size of the smaller allocations in two-size lookside */ +/* Size of the smaller allocations in two-size lookaside */ #ifdef SQLITE_OMIT_TWOSIZE_LOOKASIDE # define LOOKASIDE_SMALL 0 #else @@ -1709,6 +1762,7 @@ i64 nDeferredCons; /* Net deferred constraints this transaction. */ i64 nDeferredImmCons; /* Net deferred immediate constraints */ int *pnBytesFreed; /* If not NULL, increment this in DbFree() */ + DbClientData *pDbData; /* sqlite3_set_clientdata() content */ #ifdef SQLITE_ENABLE_UNLOCK_NOTIFY /* The following variables are all protected by the STATIC_MAIN ** mutex, not by sqlite3.mutex. They are used by code in notify.c. @@ -1791,6 +1845,7 @@ /* the count using a callback. */ #define SQLITE_CorruptRdOnly HI(0x00002) /* Prohibit writes due to error */ #define SQLITE_ReadUncommit HI(0x00004) /* READ UNCOMMITTED in shared-cache */ +#define SQLITE_FkNoAction HI(0x00008) /* Treat all FK as NO ACTION */ /* Flags used only if debugging */ #ifdef SQLITE_DEBUG @@ -1848,6 +1903,7 @@ #define SQLITE_IndexedExpr 0x01000000 /* Pull exprs from index when able */ #define SQLITE_Coroutines 0x02000000 /* Co-routines for subqueries */ #define SQLITE_NullUnusedCols 0x04000000 /* NULL unused columns in subqueries */ +#define SQLITE_OnePass 0x08000000 /* Single-pass DELETE and UPDATE */ #define SQLITE_AllOpts 0xffffffff /* All optimizations */ /* @@ -1930,6 +1986,7 @@ ** SQLITE_FUNC_ANYORDER == NC_OrderAgg == SF_OrderByReqd ** SQLITE_FUNC_LENGTH == OPFLAG_LENGTHARG ** SQLITE_FUNC_TYPEOF == OPFLAG_TYPEOFARG +** SQLITE_FUNC_BYTELEN == OPFLAG_BYTELENARG ** SQLITE_FUNC_CONSTANT == SQLITE_DETERMINISTIC from the API ** SQLITE_FUNC_DIRECT == SQLITE_DIRECTONLY from the API ** SQLITE_FUNC_UNSAFE == SQLITE_INNOCUOUS -- opposite meanings!!! @@ -1937,7 +1994,7 @@ ** ** Note that even though SQLITE_FUNC_UNSAFE and SQLITE_INNOCUOUS have the ** same bit value, their meanings are inverted. SQLITE_FUNC_UNSAFE is -** used internally and if set means tha the function has side effects. +** used internally and if set means that the function has side effects. ** SQLITE_INNOCUOUS is used by application code and means "not unsafe". ** See multiple instances of tag-20230109-1. */ @@ -1948,6 +2005,7 @@ #define SQLITE_FUNC_NEEDCOLL 0x0020 /* sqlite3GetFuncCollSeq() might be called*/ #define SQLITE_FUNC_LENGTH 0x0040 /* Built-in length() function */ #define SQLITE_FUNC_TYPEOF 0x0080 /* Built-in typeof() function */ +#define SQLITE_FUNC_BYTELEN 0x00c0 /* Built-in octet_length() function */ #define SQLITE_FUNC_COUNT 0x0100 /* Built-in count(*) aggregate */ /* 0x0200 -- available for reuse */ #define SQLITE_FUNC_UNLIKELY 0x0400 /* Built-in unlikely() function */ @@ -1970,7 +2028,7 @@ #define INLINEFUNC_coalesce 0 #define INLINEFUNC_implies_nonnull_row 1 #define INLINEFUNC_expr_implies_expr 2 -#define INLINEFUNC_expr_compare 3 +#define INLINEFUNC_expr_compare 3 #define INLINEFUNC_affinity 4 #define INLINEFUNC_iif 5 #define INLINEFUNC_sqlite_offset 6 @@ -2019,7 +2077,7 @@ ** PURE_DATE(zName, nArg, iArg, bNC, xFunc) ** Used for "pure" date/time functions, this macro is like DFUNCTION ** except that it does set the SQLITE_FUNC_CONSTANT flags. iArg is -** ignored and the user-data for these functions is set to an +** ignored and the user-data for these functions is set to an ** arbitrary non-NULL pointer. The bNC parameter is not used. ** ** AGGREGATE(zName, nArg, iArg, bNC, xStep, xFinal) @@ -2527,7 +2585,7 @@ ** foreign key. ** ** The OE_Default value is a place holder that means to use whatever -** conflict resolution algorthm is required from context. +** conflict resolution algorithm is required from context. ** ** The following symbolic values are used to record which type ** of conflict resolution action to take. @@ -2803,6 +2861,9 @@ FuncDef *pFunc; /* The aggregate function implementation */ int iDistinct; /* Ephemeral table used to enforce DISTINCT */ int iDistAddr; /* Address of OP_OpenEphemeral */ + int iOBTab; /* Ephemeral table to implement ORDER BY */ + u8 bOBPayload; /* iOBTab has payload columns separate from key */ + u8 bOBUnique; /* Enforce uniqueness on iOBTab keys */ } *aFunc; int nFunc; /* Number of entries in aFunc[] */ u32 selId; /* Select to which this AggInfo belongs */ @@ -2814,7 +2875,7 @@ /* ** Macros to compute aCol[] and aFunc[] register numbers. ** -** These macros should not be used prior to the call to +** These macros should not be used prior to the call to ** assignAggregateRegisters() that computes the value of pAggInfo->iFirstReg. ** The assert()s that are part of this macro verify that constraint. */ @@ -2941,7 +3002,7 @@ ** TK_REGISTER: register number ** TK_TRIGGER: 1 -> new, 0 -> old ** EP_Unlikely: 134217728 times likelihood - ** TK_IN: ephemerial table holding RHS + ** 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. @@ -2987,7 +3048,7 @@ #define EP_Reduced 0x004000 /* Expr struct EXPR_REDUCEDSIZE bytes only */ #define EP_Win 0x008000 /* Contains window functions */ #define EP_TokenOnly 0x010000 /* Expr struct EXPR_TOKENONLYSIZE bytes only */ - /* 0x020000 // Available for reuse */ +#define EP_FullSize 0x020000 /* Expr structure must remain full sized */ #define EP_IfNullRow 0x040000 /* The TK_IF_NULL_ROW opcode */ #define EP_Unlikely 0x080000 /* unlikely() or likelihood() function */ #define EP_ConstFunc 0x100000 /* A SQLITE_FUNC_CONSTANT or _SLOCHNG function */ @@ -3017,12 +3078,15 @@ #define ExprClearProperty(E,P) (E)->flags&=~(P) #define ExprAlwaysTrue(E) (((E)->flags&(EP_OuterON|EP_IsTrue))==EP_IsTrue) #define ExprAlwaysFalse(E) (((E)->flags&(EP_OuterON|EP_IsFalse))==EP_IsFalse) +#define ExprIsFullSize(E) (((E)->flags&(EP_Reduced|EP_TokenOnly))==0) /* Macros used to ensure that the correct members of unions are accessed ** in Expr. */ #define ExprUseUToken(E) (((E)->flags&EP_IntValue)==0) #define ExprUseUValue(E) (((E)->flags&EP_IntValue)!=0) +#define ExprUseWOfst(E) (((E)->flags&(EP_InnerON|EP_OuterON))==0) +#define ExprUseWJoin(E) (((E)->flags&(EP_InnerON|EP_OuterON))!=0) #define ExprUseXList(E) (((E)->flags&EP_xIsSelect)==0) #define ExprUseXSelect(E) (((E)->flags&EP_xIsSelect)!=0) #define ExprUseYTab(E) (((E)->flags&(EP_WinFunc|EP_Subrtn))==0) @@ -3132,6 +3196,7 @@ #define ENAME_NAME 0 /* The AS clause of a result set */ #define ENAME_SPAN 1 /* Complete text of the result set expression */ #define ENAME_TAB 2 /* "DB.TABLE.NAME" for the result set */ +#define ENAME_ROWID 3 /* "DB.TABLE._rowid_" for * expansion of rowid */ /* ** An instance of this structure can hold a simple list of identifiers, @@ -3211,7 +3276,7 @@ unsigned notCte :1; /* This item may not match a CTE */ unsigned isUsing :1; /* u3.pUsing is valid */ unsigned isOn :1; /* u3.pOn was once valid and non-NULL */ - unsigned isSynthUsing :1; /* u3.pUsing is synthensized from NATURAL */ + unsigned isSynthUsing :1; /* u3.pUsing is synthesized from NATURAL */ unsigned isNestedFrom :1; /* pSelect is a SF_NestedFrom subquery */ } fg; int iCursor; /* The VDBE cursor number used to access this table */ @@ -3376,7 +3441,7 @@ ** conflict-target clause.) The pUpsertTargetWhere is the optional ** WHERE clause used to identify partial unique indexes. ** -** pUpsertSet is the list of column=expr terms of the UPDATE statement. +** pUpsertSet is the list of column=expr terms of the UPDATE statement. ** The pUpsertSet field is NULL for a ON CONFLICT DO NOTHING. The ** pUpsertWhere is the WHERE clause for the UPDATE and is NULL if the ** WHERE clause is omitted. @@ -3740,6 +3805,7 @@ int *aLabel; /* Space to hold the labels */ ExprList *pConstExpr;/* Constant expressions */ IndexedExpr *pIdxEpr;/* List of expressions used by active indexes */ + IndexedExpr *pIdxPartExpr; /* Exprs constrained by index WHERE clauses */ Token constraintName;/* Name of the constraint currently being parsed */ yDbMask writeMask; /* Start a write transaction on these databases */ yDbMask cookieMask; /* Bitmask of schema verified databases */ @@ -3747,6 +3813,9 @@ int regRoot; /* Register holding root page number for new objects */ int nMaxArg; /* Max args passed to user function by sub-program */ int nSelect; /* Number of SELECT stmts. Counter for Select.selId */ +#ifndef SQLITE_OMIT_PROGRESS_CALLBACK + u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ +#endif #ifndef SQLITE_OMIT_SHARED_CACHE int nTableLock; /* Number of locks in aTableLock */ TableLock *aTableLock; /* Required table locks for shared-cache mode */ @@ -3760,12 +3829,9 @@ int addrCrTab; /* Address of OP_CreateBtree on CREATE TABLE */ Returning *pReturning; /* The RETURNING clause */ } u1; - u32 nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u32 oldmask; /* Mask of old.* columns referenced */ u32 newmask; /* Mask of new.* columns referenced */ -#ifndef SQLITE_OMIT_PROGRESS_CALLBACK - u32 nProgressSteps; /* xProgress steps taken during sqlite3_prepare() */ -#endif + LogEst nQueryLoop; /* Est number of iterations of a query (10*log2(N)) */ u8 eTriggerOp; /* TK_UPDATE, TK_INSERT or TK_DELETE */ u8 bReturning; /* Coding a RETURNING trigger */ u8 eOrconf; /* Default ON CONFLICT policy for trigger steps */ @@ -3889,6 +3955,7 @@ #define OPFLAG_ISNOOP 0x40 /* OP_Delete does pre-update-hook only */ #define OPFLAG_LENGTHARG 0x40 /* OP_Column only used for length() */ #define OPFLAG_TYPEOFARG 0x80 /* OP_Column only used for typeof() */ +#define OPFLAG_BYTELENARG 0xc0 /* OP_Column only for octet_length() */ #define OPFLAG_BULKCSR 0x01 /* OP_Open** used to open bulk cursor */ #define OPFLAG_SEEKEQ 0x02 /* OP_Open** cursor uses EQ seek only */ #define OPFLAG_FORDELETE 0x08 /* OP_Open should use BTREE_FORDELETE */ @@ -3897,7 +3964,7 @@ #define OPFLAG_SAVEPOSITION 0x02 /* OP_Delete/Insert: save cursor pos */ #define OPFLAG_AUXDELETE 0x04 /* OP_Delete: index in a DELETE op */ #define OPFLAG_NOCHNG_MAGIC 0x6d /* OP_MakeRecord: serialtype 10 is ok */ -#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ +#define OPFLAG_PREFORMAT 0x80 /* OP_Insert uses preformatted cell */ /* ** Each trigger present in the database schema is stored as an instance of @@ -4010,6 +4077,7 @@ int iRetCur; /* Transient table holding RETURNING results */ int nRetCol; /* Number of in pReturnEL after expansion */ int iRetReg; /* Register array for holding a row of RETURNING */ + char zName[40]; /* Name of trigger: "sqlite_returning_%p" */ }; /* @@ -4031,6 +4099,25 @@ #define isMalloced(X) (((X)->printfFlags & SQLITE_PRINTF_MALLOCED)!=0) +/* +** The following object is the header for an "RCStr" or "reference-counted +** string". An RCStr is passed around and used like any other char* +** that has been dynamically allocated. The important interface +** differences: +** +** 1. RCStr strings are reference counted. They are deallocated +** when the reference count reaches zero. +** +** 2. Use sqlite3RCStrUnref() to free an RCStr string rather than +** sqlite3_free() +** +** 3. Make a (read-only) copy of a read-only RCStr string using +** sqlite3RCStrRef(). +*/ +struct RCStr { + u64 nRCRef; /* Number of references */ + /* Total structure size should be a multiple of 8 bytes for alignment */ +}; /* ** A pointer to this structure is used to communicate information @@ -4057,7 +4144,7 @@ /* Tuning parameters are set using SQLITE_TESTCTRL_TUNE and are controlled ** on debug-builds of the CLI using ".testctrl tune ID VALUE". Tuning ** parameters are for temporary use during development, to help find -** optimial values for parameters in the query planner. The should not +** optimal values for parameters in the query planner. The should not ** be used on trunk check-ins. They are a temporary mechanism available ** for transient development builds only. ** @@ -4083,6 +4170,7 @@ u8 bUseCis; /* Use covering indices for full-scans */ u8 bSmallMalloc; /* Avoid large memory allocations if true */ u8 bExtraSchemaChecks; /* Verify type,name,tbl_name in schema */ + u8 bUseLongDouble; /* Make use of long double */ int mxStrlen; /* Maximum string length */ int neverCorrupt; /* Database is always well-formed */ int szLookaside; /* Default lookaside buffer size */ @@ -4169,6 +4257,7 @@ void (*xSelectCallback2)(Walker*,Select*);/* Second callback for SELECTs */ int walkerDepth; /* Number of subqueries */ u16 eCode; /* A small processing code */ + u16 mWFlags; /* Use-dependent flags */ union { /* Extra data for callback */ NameContext *pNC; /* Naming context */ int n; /* A counter */ @@ -4208,6 +4297,7 @@ /* Forward declarations */ int sqlite3WalkExpr(Walker*, Expr*); +int sqlite3WalkExprNN(Walker*, Expr*); int sqlite3WalkExprList(Walker*, ExprList*); int sqlite3WalkSelect(Walker*, Select*); int sqlite3WalkSelectExpr(Walker*, Select*); @@ -4288,6 +4378,16 @@ }; +/* Client data associated with sqlite3_set_clientdata() and +** sqlite3_get_clientdata(). +*/ +struct DbClientData { + DbClientData *pNext; /* Next in a linked list */ + void *pData; /* The data */ + void (*xDestructor)(void*); /* Destructor. Might be NULL */ + char zName[1]; /* Name of this client data. MUST BE LAST */ +}; + #ifdef SQLITE_DEBUG /* ** An instance of the TreeView object is used for printing the content of @@ -4589,6 +4689,20 @@ sqlite3_value **apArg; /* The argument values */ }; +/* +** An instance of this object receives the decoding of a floating point +** value into an approximate decimal representation. +*/ +struct FpDecode { + char sign; /* '+' or '-' */ + char isSpecial; /* 1: Infinity 2: NaN */ + int n; /* Significant digits in the decode */ + int iDP; /* Location of the decimal point */ + char *z; /* Start of significant digits */ + char zBuf[24]; /* Storage for significant digits */ +}; + +void sqlite3FpDecode(FpDecode*,double,int,int); char *sqlite3MPrintf(sqlite3*,const char*, ...); char *sqlite3VMPrintf(sqlite3*,const char*, va_list); #if defined(SQLITE_DEBUG) || defined(SQLITE_HAVE_OS_TRACE) @@ -4678,6 +4792,8 @@ Expr *sqlite3ExprAnd(Parse*,Expr*, Expr*); Expr *sqlite3ExprSimplifiedAndOr(Expr*); Expr *sqlite3ExprFunction(Parse*,ExprList*, const Token*, int); +void sqlite3ExprAddFunctionOrderBy(Parse*,Expr*,ExprList*); +void sqlite3ExprOrderByAggregateError(Parse*,Expr*); void sqlite3ExprFunctionUsable(Parse*,const Expr*,const FuncDef*); void sqlite3ExprAssignVarNumber(Parse*, Expr*, u32); void sqlite3ExprDelete(sqlite3*, Expr*); @@ -4879,7 +4995,7 @@ int sqlite3ExprCompareSkip(Expr*,Expr*,int); int sqlite3ExprListCompare(const ExprList*,const ExprList*, int); int sqlite3ExprImpliesExpr(const Parse*,const Expr*,const Expr*, int); -int sqlite3ExprImpliesNonNullRow(Expr*,int); +int sqlite3ExprImpliesNonNullRow(Expr*,int,int); void sqlite3AggInfoPersistWalkerInit(Walker*,Parse*); void sqlite3ExprAnalyzeAggregates(NameContext*, Expr*); void sqlite3ExprAnalyzeAggList(NameContext*,ExprList*); @@ -4914,6 +5030,7 @@ int sqlite3ExprCanBeNull(const Expr*); int sqlite3ExprNeedsNoAffinityChange(const Expr*, char); int sqlite3IsRowid(const char*); +const char *sqlite3RowidAlias(Table *pTab); void sqlite3GenerateRowDelete( Parse*,Table*,Trigger*,int,int,int,i16,u8,u8,u8,int); void sqlite3GenerateRowIndexDelete(Parse*, Table*, int, int, int*, int); @@ -5028,6 +5145,7 @@ int sqlite3FixSelect(DbFixer*, Select*); int sqlite3FixExpr(DbFixer*, Expr*); int sqlite3FixTriggerStep(DbFixer*, TriggerStep*); + int sqlite3RealSameAsInt(double,sqlite3_int64); i64 sqlite3RealToI64(double); int sqlite3Int64ToText(i64,char*); @@ -5132,6 +5250,7 @@ u8 sqlite3GetBoolean(const char *z,u8); const void *sqlite3ValueText(sqlite3_value*, u8); +int sqlite3ValueIsOfClass(const sqlite3_value*, void(*)(void*)); int sqlite3ValueBytes(sqlite3_value*, u8); void sqlite3ValueSetStr(sqlite3_value*, int, const void *,u8, void(*)(void*)); @@ -5183,7 +5302,8 @@ const struct ExprList_item*, const char*, const char*, - const char* + const char*, + int* ); Bitmask sqlite3ExprColUsed(Expr*); u8 sqlite3StrIHash(const char*); @@ -5227,10 +5347,10 @@ #endif int sqlite3CreateFunc(sqlite3 *, const char *, int, int, void *, void (*)(sqlite3_context*,int,sqlite3_value **), - void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*), void (*)(sqlite3_context*), - void (*)(sqlite3_context*,int,sqlite3_value **), + void (*)(sqlite3_context*,int,sqlite3_value **), FuncDestructor *pDestructor ); void sqlite3NoopDestructor(void*); @@ -5239,6 +5359,11 @@ int sqlite3ApiExit(sqlite3 *db, int); int sqlite3OpenTempDatabase(Parse *); +char *sqlite3RCStrRef(char*); +void sqlite3RCStrUnref(void*); +char *sqlite3RCStrNew(u64); +char *sqlite3RCStrResize(char*,u64); + void sqlite3StrAccumInit(StrAccum*, sqlite3*, char*, int, int); int sqlite3StrAccumEnlarge(StrAccum*, i64); char *sqlite3StrAccumFinish(StrAccum*); @@ -5490,6 +5615,7 @@ #define sqlite3SelectExprHeight(x) 0 #define sqlite3ExprCheckHeight(x,y) #endif +void sqlite3ExprSetErrorOffset(Expr*,int); u32 sqlite3Get4byte(const u8*); void sqlite3Put4byte(u8*, u32); diff -Nru sqlite3-3.42.0/src/sqliteLimit.h sqlite3-3.44.0-0/src/sqliteLimit.h --- sqlite3-3.42.0/src/sqliteLimit.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/sqliteLimit.h 2023-11-04 14:23:58.000000000 +0000 @@ -9,7 +9,7 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** +** ** This file defines various limits of what SQLite can process. */ @@ -57,9 +57,9 @@ #endif /* -** The maximum depth of an expression tree. This is limited to -** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might -** want to place more severe limits on the complexity of an +** The maximum depth of an expression tree. This is limited to +** some extent by SQLITE_MAX_SQL_LENGTH. But sometime you might +** want to place more severe limits on the complexity of an ** expression. A value of 0 means that there is no limit. */ #ifndef SQLITE_MAX_EXPR_DEPTH @@ -72,7 +72,7 @@ ** 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 compount SELECT. +** any limit on the number of terms in a compound SELECT. */ #ifndef SQLITE_MAX_COMPOUND_SELECT # define SQLITE_MAX_COMPOUND_SELECT 500 @@ -140,10 +140,10 @@ ** ** Earlier versions of SQLite allowed the user to change this value at ** compile time. This is no longer permitted, on the grounds that it creates -** a library that is technically incompatible with an SQLite library -** compiled with a different limit. If a process operating on a database -** with a page-size of 65536 bytes crashes, then an instance of SQLite -** compiled with the default page-size limit will not be able to rollback +** a library that is technically incompatible with an SQLite library +** compiled with a different limit. If a process operating on a database +** with a page-size of 65536 bytes crashes, then an instance of SQLite +** compiled with the default page-size limit will not be able to rollback ** the aborted transaction. This could lead to database corruption. */ #ifdef SQLITE_MAX_PAGE_SIZE @@ -202,7 +202,7 @@ ** Maximum depth of recursion for triggers. ** ** A value of 1 means that a trigger program will not be able to itself -** fire any triggers. A value of 0 means that no trigger programs at all +** fire any triggers. A value of 0 means that no trigger programs at all ** may be executed. */ #ifndef SQLITE_MAX_TRIGGER_DEPTH diff -Nru sqlite3-3.42.0/src/tclsqlite.c sqlite3-3.44.0-0/src/tclsqlite.c --- sqlite3-3.42.0/src/tclsqlite.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/tclsqlite.c 2023-11-04 14:23:58.000000000 +0000 @@ -55,6 +55,25 @@ # include # include typedef unsigned char u8; +# ifndef SQLITE_PTRSIZE +# if defined(__SIZEOF_POINTER__) +# define SQLITE_PTRSIZE __SIZEOF_POINTER__ +# elif defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(_M_ARM) || defined(__arm__) || defined(__x86) || \ + (defined(__APPLE__) && defined(__POWERPC__)) || \ + (defined(__TOS_AIX__) && !defined(__64BIT__)) +# define SQLITE_PTRSIZE 4 +# else +# define SQLITE_PTRSIZE 8 +# endif +# endif /* SQLITE_PTRSIZE */ +# if defined(HAVE_STDINT_H) + typedef uintptr_t uptr; +# elif SQLITE_PTRSIZE==4 + typedef unsigned int uptr; +# else + typedef sqlite3_uint64 uptr; +# endif #endif #include @@ -675,7 +694,7 @@ pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); Tcl_IncrRefCount(pCmd); Tcl_ListObjAppendElement(pDb->interp, pCmd, - Tcl_NewWideIntObj((Tcl_WideInt)pStmt)); + Tcl_NewWideIntObj((Tcl_WideInt)(uptr)pStmt)); Tcl_ListObjAppendElement(pDb->interp, pCmd, Tcl_NewStringObj(zSql, -1)); Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); @@ -690,7 +709,7 @@ pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); Tcl_IncrRefCount(pCmd); Tcl_ListObjAppendElement(pDb->interp, pCmd, - Tcl_NewWideIntObj((Tcl_WideInt)pStmt)); + Tcl_NewWideIntObj((Tcl_WideInt)(uptr)pStmt)); Tcl_ListObjAppendElement(pDb->interp, pCmd, Tcl_NewWideIntObj((Tcl_WideInt)ns)); Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); @@ -704,7 +723,7 @@ pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); Tcl_IncrRefCount(pCmd); Tcl_ListObjAppendElement(pDb->interp, pCmd, - Tcl_NewWideIntObj((Tcl_WideInt)pStmt)); + Tcl_NewWideIntObj((Tcl_WideInt)(uptr)pStmt)); Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); Tcl_DecrRefCount(pCmd); Tcl_ResetResult(pDb->interp); @@ -716,7 +735,7 @@ pCmd = Tcl_NewStringObj(pDb->zTraceV2, -1); Tcl_IncrRefCount(pCmd); Tcl_ListObjAppendElement(pDb->interp, pCmd, - Tcl_NewWideIntObj((Tcl_WideInt)db)); + Tcl_NewWideIntObj((Tcl_WideInt)(uptr)db)); Tcl_EvalObjEx(pDb->interp, pCmd, TCL_EVAL_DIRECT); Tcl_DecrRefCount(pCmd); Tcl_ResetResult(pDb->interp); @@ -1780,7 +1799,7 @@ /* ** If using Tcl version 8.6 or greater, use the NR functions to avoid -** recursive evalution of scripts by the [db eval] and [db trans] +** 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. @@ -2441,7 +2460,7 @@ ** ** This command usage is equivalent to the sqlite2.x COPY statement, ** which imports file data into a table using the PostgreSQL COPY file format: - ** $db copy $conflit_algo $table_name $filename \t \\N + ** $db copy $conflict_algorithm $table_name $filename \t \\N */ case DB_COPY: { char *zTable; /* Insert data into this table */ @@ -3427,7 +3446,7 @@ ** 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 transation was started, do nothing. + ** 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 diff -Nru sqlite3-3.42.0/src/test1.c sqlite3-3.44.0-0/src/test1.c --- sqlite3-3.42.0/src/test1.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test1.c 2023-11-04 14:23:58.000000000 +0000 @@ -992,6 +992,46 @@ } /* +** SQL function: strtod(X) +** +** Use the C-library strtod() function to convert string X into a double. +** Used for comparing the accuracy of SQLite's internal text-to-float conversion +** routines against the C-library. +*/ +static void shellStrtod( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + char *z = (char*)sqlite3_value_text(apVal[0]); + UNUSED_PARAMETER(nVal); + if( z==0 ) return; + sqlite3_result_double(pCtx, strtod(z,0)); +} + +/* +** SQL function: dtostr(X) +** +** Use the C-library printf() function to convert real value X into a string. +** Used for comparing the accuracy of SQLite's internal float-to-text conversion +** routines against the C-library. +*/ +static void shellDtostr( + sqlite3_context *pCtx, + int nVal, + sqlite3_value **apVal +){ + double r = sqlite3_value_double(apVal[0]); + int n = nVal>=2 ? sqlite3_value_int(apVal[1]) : 26; + char z[400]; + if( n<1 ) n = 1; + if( n>350 ) n = 350; + sprintf(z, "%#+.*e", n, r); + sqlite3_result_text(pCtx, z, -1, SQLITE_TRANSIENT); +} + + +/* ** Usage: sqlite3_create_function DB ** ** Call the sqlite3_create_function API on the given database in order @@ -1063,6 +1103,27 @@ 0, intrealFunction, 0, 0); } + /* Functions strtod() and dtostr() work as in the shell. These routines + ** use the standard C library to convert between floating point and + ** text. This is used to compare SQLite's internal conversion routines + ** against the standard library conversion routines. + ** + ** Both routines copy/pasted from the shell.c.in implementation + ** on 2023-07-03. + */ + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "strtod", 1, SQLITE_UTF8, 0, + shellStrtod, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "dtostr", 1, SQLITE_UTF8, 0, + shellDtostr, 0, 0); + } + if( rc==SQLITE_OK ){ + rc = sqlite3_create_function(db, "dtostr", 2, SQLITE_UTF8, 0, + shellDtostr, 0, 0); + } + #ifndef SQLITE_OMIT_UTF16 /* Use the sqlite3_create_function16() API here. Mainly for fun, but also ** because it is not tested anywhere else. */ @@ -2216,6 +2277,7 @@ int flags = 0; int iSelectId = 0; int iParentId = 0; + int bDebug = 0; if( objc==5 ){ struct Flag { @@ -2223,6 +2285,7 @@ int flag; } aTbl[] = { {"complex", SQLITE_SCANSTAT_COMPLEX}, + {"debug", -1}, {0, 0} }; @@ -2239,7 +2302,11 @@ interp, aFlag[ii], aTbl, sizeof(aTbl[0]), "flag", 0, &iVal ); if( res ) return TCL_ERROR; - flags |= aTbl[iVal].flag; + if( aTbl[iVal].flag==-1 ){ + bDebug = 1; + }else{ + flags |= aTbl[iVal].flag; + } } } @@ -2253,6 +2320,13 @@ return TCL_ERROR; } + if( bDebug && 0==(flags & SQLITE_SCANSTAT_COMPLEX) ){ + Tcl_SetObjResult(interp, + Tcl_NewStringObj("may not specify debug without complex", -1) + ); + return TCL_ERROR; + } + if( idx<0 ){ Tcl_Obj *pRet = Tcl_NewObj(); res = sqlite3_stmt_scanstatus_v2( @@ -2299,6 +2373,36 @@ pStmt, idx, SQLITE_SCANSTAT_NCYCLE, flags, (void*)&nCycle); Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("nCycle", -1)); Tcl_ListObjAppendElement(0, pRet, Tcl_NewWideIntObj(nCycle)); + + if( bDebug ){ + int ii; + ScanStatus *pScan = &((Vdbe*)pStmt)->aScan[idx]; + Tcl_Obj *pRange = Tcl_NewObj(); + Tcl_Obj *pCsr = Tcl_NewObj(); + + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("debug_loop", -1)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(pScan->addrLoop)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("debug_visit", -1)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(pScan->addrVisit)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("debug_explain",-1)); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewIntObj(pScan->addrExplain)); + for(ii=0; iiaAddrRange)/2; ii++){ + int iStart = pScan->aAddrRange[ii*2]; + int iEnd = pScan->aAddrRange[ii*2+1]; + if( iStart>0 ){ + Tcl_ListObjAppendElement(0, pRange, Tcl_NewIntObj(iStart)); + Tcl_ListObjAppendElement(0, pRange, Tcl_NewIntObj(iEnd)); + }else if( iStart<0 ){ + Tcl_ListObjAppendElement(0, pCsr, Tcl_NewIntObj(iEnd)); + } + } + + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("debug_range", -1)); + Tcl_ListObjAppendElement(0, pRet, pRange); + Tcl_ListObjAppendElement(0, pRet, Tcl_NewStringObj("debug_csr", -1)); + Tcl_ListObjAppendElement(0, pRet, pCsr); + } + Tcl_SetObjResult(interp, pRet); }else{ Tcl_ResetResult(interp); @@ -2736,7 +2840,7 @@ /* ** Usage: sqlite3_next_stmt DB STMT ** -** Return the next statment in sequence after STMT. +** Return the next statement in sequence after STMT. */ static int SQLITE_TCLAPI test_next_stmt( void * clientData, @@ -2819,6 +2923,34 @@ } /* +** Usage: sqlite3_stmt_explain STMT INT +** +** Set the explain to normal (0), EXPLAIN (1) or EXPLAIN QUERY PLAN (2). +*/ +static int SQLITE_TCLAPI test_stmt_explain( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + sqlite3_stmt *pStmt; + int eMode = 0; + int rc; + + if( objc!=3 ){ + Tcl_AppendResult(interp, "wrong # args: should be \"", + Tcl_GetStringFromObj(objv[0], 0), " STMT INT", 0); + return TCL_ERROR; + } + + if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; + if( Tcl_GetIntFromObj(interp, objv[2], &eMode) ) return TCL_ERROR; + rc = sqlite3_stmt_explain(pStmt, eMode); + Tcl_SetObjResult(interp, Tcl_NewIntObj(rc)); + return TCL_OK; +} + +/* ** Usage: sqlite3_stmt_busy STMT ** ** Return true if STMT is a non-NULL pointer to a statement @@ -3459,10 +3591,10 @@ /* ** Usage: sqlite3_test_errstr ** -** Test that the english language string equivalents for sqlite error codes +** Test that the English language string equivalents for sqlite error codes ** are sane. The parameter is an integer representing an sqlite error code. ** The result is a list of two elements, the string representation of the -** error code and the english language explanation. +** error code and the English language explanation. */ static int SQLITE_TCLAPI test_errstr( void * clientData, @@ -3648,7 +3780,7 @@ } } } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((uptr)p)); return TCL_OK; } /* @@ -3684,7 +3816,7 @@ p[i] = v; } } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((uptr)p)); return TCL_OK; } /* @@ -3718,7 +3850,7 @@ } } } - Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((uptr)p)); return TCL_OK; } /* @@ -3751,7 +3883,7 @@ } } n = objc-1; - Tcl_SetObjResult(interp, Tcl_NewWideIntObj((sqlite3_int64)p)); + Tcl_SetObjResult(interp, Tcl_NewWideIntObj((uptr)p)); return TCL_OK; } @@ -4090,9 +4222,11 @@ sqlite3_stmt *pStmt; int idx; int bidx; +#ifdef SQLITE_ENABLE_PREUPDATE_HOOK const char *z3 = 0; sqlite3 *db = 0; sqlite3_value *pVal = 0; +#endif if( objc!=5 ){ Tcl_WrongNumArgs(interp, 1, objv, "STMT N NEW|OLD IDX"); @@ -4101,11 +4235,11 @@ if( getStmtPointer(interp, Tcl_GetString(objv[1]), &pStmt) ) return TCL_ERROR; if( Tcl_GetIntFromObj(interp, objv[2], &idx) ) return TCL_ERROR; - z3 = Tcl_GetString(objv[3]); if( Tcl_GetIntFromObj(interp, objv[4], &bidx) ) return TCL_ERROR; - db = sqlite3_db_handle(pStmt); #ifdef SQLITE_ENABLE_PREUPDATE_HOOK + z3 = Tcl_GetString(objv[3]); + db = sqlite3_db_handle(pStmt); if( z3[0]=='n' ){ sqlite3_preupdate_new(db, bidx, &pVal); }else if( z3[0]=='o' ){ @@ -6115,7 +6249,7 @@ 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 existig VFS that is + ** default VFS, even if the 1st parameter is an existing VFS that is ** previously registered as the non-default. */ sqlite3_vfs_register(&one, 1); @@ -6995,6 +7129,37 @@ } /* +** tclcmd: use_long_double BOOLEAN|"default" +** +** If no argument, report the current value of the use-long-double flag. +** +** If argument is "default", set the use-long-double flag to the default +** value for this build, based on the size of LONGDOUBLE_TYPE. +** +** If argument is a boolean, set the use-long-double flag accordingly. +** +** Return the new setting. +*/ +static int SQLITE_TCLAPI use_long_double( + ClientData clientData, /* Pointer to sqlite3_enable_XXX function */ + Tcl_Interp *interp, /* The TCL interpreter that invoked this command */ + int objc, /* Number of arguments */ + Tcl_Obj *CONST objv[] /* Command arguments */ +){ + int i = -1; + if( objc==2 ){ + if( strcmp(Tcl_GetString(objv[1]),"default")==0 ){ + i = 2; + }else{ + if( Tcl_GetBooleanFromObj(interp,objv[1],&i) ) return TCL_ERROR; + } + } + i = sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, i); + Tcl_SetObjResult(interp, Tcl_NewIntObj(i)); + return TCL_OK; +} + +/* ** tclcmd: database_may_be_corrupt ** ** Indicate that database files might be corrupt. In other words, set the normal @@ -7417,6 +7582,61 @@ } /* +** TCLCMD: strftime FORMAT UNIXTIMESTAMP +** +** Access to the C-library strftime() routine, so that its results +** can be compared against SQLite's internal strftime() SQL function +** implementation. +*/ +static int SQLITE_TCLAPI strftime_cmd( + void * clientData, + Tcl_Interp *interp, + int objc, + Tcl_Obj *CONST objv[] +){ + Tcl_WideInt ts; + time_t t; + struct tm *pTm; + const char *zFmt; + size_t n; + char zBuf[1000]; + if( objc!=3 ){ + Tcl_WrongNumArgs(interp, 1, objv, "FORMAT UNIXTIMESTAMP"); + return TCL_ERROR; + } + if( Tcl_GetWideIntFromObj(interp, objv[2], &ts) ) return TCL_ERROR; + zFmt = Tcl_GetString(objv[1]); + t = (time_t)ts; + pTm = gmtime(&t); + n = strftime(zBuf, sizeof(zBuf)-1, zFmt, pTm); + if( n>=0 && n=2 ){ + if( Tcl_GetIntFromObj(interp, objv[1], (int*)&v)==TCL_OK ){ + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 1, &v); + } + } + sqlite3_test_control(SQLITE_TESTCTRL_TRACEFLAGS, 0, &v); + Tcl_SetObjResult(interp, Tcl_NewIntObj((int)v)); + return TCL_OK; +} + +/* ** sqlite3_test_control VERB ARGS... */ static int SQLITE_TCLAPI test_test_control( @@ -7433,6 +7653,7 @@ { "SQLITE_TESTCTRL_SORTER_MMAP", SQLITE_TESTCTRL_SORTER_MMAP }, { "SQLITE_TESTCTRL_IMPOSTER", SQLITE_TESTCTRL_IMPOSTER }, { "SQLITE_TESTCTRL_INTERNAL_FUNCTIONS", SQLITE_TESTCTRL_INTERNAL_FUNCTIONS}, + { "SQLITE_TESTCTRL_FK_NO_ACTION", SQLITE_TESTCTRL_FK_NO_ACTION}, { 0, 0 } }; int iVerb; @@ -7472,6 +7693,20 @@ break; } + case SQLITE_TESTCTRL_FK_NO_ACTION: { + int val = 0; + sqlite3 *db = 0; + if( objc!=4 ){ + Tcl_WrongNumArgs(interp, 2, objv, "DB BOOLEAN"); + return TCL_ERROR; + } + if( getDbPointer(interp, Tcl_GetString(objv[2]), &db) ) return TCL_ERROR; + if( Tcl_GetBooleanFromObj(interp, objv[3], &val) ) return TCL_ERROR; + + sqlite3_test_control(SQLITE_TESTCTRL_FK_NO_ACTION, db, val); + break; + } + case SQLITE_TESTCTRL_SORTER_MMAP: { int val; sqlite3 *db; @@ -7826,6 +8061,7 @@ { "push-down", SQLITE_PushDown }, { "balanced-merge", SQLITE_BalancedMerge }, { "propagate-const", SQLITE_PropagateConst }, + { "one-pass", SQLITE_OnePass }, }; if( objc!=4 ){ @@ -8836,6 +9072,7 @@ { "sqlite3_next_stmt", test_next_stmt ,0 }, { "sqlite3_stmt_readonly", test_stmt_readonly ,0 }, { "sqlite3_stmt_isexplain", test_stmt_isexplain,0 }, + { "sqlite3_stmt_explain", test_stmt_explain ,0 }, { "sqlite3_stmt_busy", test_stmt_busy ,0 }, { "uses_stmt_journal", uses_stmt_journal ,0 }, @@ -8862,6 +9099,7 @@ { "reset_prng_state", reset_prng_state, 0 }, { "prng_seed", prng_seed, 0 }, { "extra_schema_checks", extra_schema_checks, 0}, + { "use_long_double", use_long_double, 0}, { "database_never_corrupt", database_never_corrupt, 0}, { "database_may_be_corrupt", database_may_be_corrupt, 0}, { "optimization_control", optimization_control,0}, @@ -8966,7 +9204,9 @@ #ifndef SQLITE_OMIT_EXPLAIN { "print_explain_query_plan", test_print_eqp, 0 }, #endif + { "strftime", strftime_cmd }, { "sqlite3_test_control", test_test_control }, + { ".treetrace", test_treetrace }, #if SQLITE_OS_UNIX { "getrusage", test_getrusage }, #endif diff -Nru sqlite3-3.42.0/src/test2.c sqlite3-3.44.0-0/src/test2.c --- sqlite3-3.42.0/src/test2.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test2.c 2023-11-04 14:23:58.000000000 +0000 @@ -608,7 +608,7 @@ zInt[i] = (x%10) + '0'; } if( isNeg ) zInt[i--] = '-'; - memcpy(faultSimScript+faultSimScriptSize, zInt+i+1, sizeof(zInt)-i); + memcpy(faultSimScript+faultSimScriptSize, zInt+i+1, sizeof(zInt)-i-1); } rc = Tcl_Eval(faultSimInterp, faultSimScript); if( rc ){ diff -Nru sqlite3-3.42.0/src/test3.c sqlite3-3.44.0-0/src/test3.c --- sqlite3-3.42.0/src/test3.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test3.c 2023-11-04 14:23:58.000000000 +0000 @@ -422,7 +422,7 @@ ** routines, both for accuracy and for speed. ** ** An integer is written using putVarint() and read back with -** getVarint() and varified to be unchanged. This repeats COUNT +** getVarint() and verified to be unchanged. This repeats COUNT ** times. The first integer is START*MULTIPLIER. Each iteration ** increases the integer by INCREMENT. ** diff -Nru sqlite3-3.42.0/src/test6.c sqlite3-3.44.0-0/src/test6.c --- sqlite3-3.42.0/src/test6.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test6.c 2023-11-04 14:23:58.000000000 +0000 @@ -33,25 +33,25 @@ /* ** Method: ** -** This layer is implemented as a wrapper around the "real" -** sqlite3_file object for the host system. Each time data is +** This layer is implemented as a wrapper around the "real" +** sqlite3_file object for the host system. Each time data is ** written to the file object, instead of being written to the -** underlying file, the write operation is stored in an in-memory +** underlying file, the write operation is stored in an in-memory ** structure (type WriteBuffer). This structure is placed at the ** end of a global ordered list (the write-list). ** ** When data is read from a file object, the requested region is -** first retrieved from the real file. The write-list is then -** traversed and data copied from any overlapping WriteBuffer +** first retrieved from the real file. The write-list is then +** traversed and data copied from any overlapping WriteBuffer ** structures to the output buffer. i.e. a read() operation following ** one or more write() operations works as expected, even if no ** data has actually been written out to the real file. ** -** When a fsync() operation is performed, an operating system crash -** may be simulated, in which case exit(-1) is called (the call to +** When a fsync() operation is performed, an operating system crash +** may be simulated, in which case exit(-1) is called (the call to ** xSync() never returns). Whether or not a crash is simulated, -** the data associated with a subset of the WriteBuffer structures -** stored in the write-list is written to the real underlying files +** the data associated with a subset of the WriteBuffer structures +** stored in the write-list is written to the real underlying files ** and the entries removed from the write-list. If a crash is simulated, ** a subset of the buffers may be corrupted before the data is written. ** @@ -63,13 +63,13 @@ ** Normal mode is used when the simulated device has none of the ** SQLITE_IOCAP_XXX flags set. ** -** In normal mode, if the fsync() is not a simulated crash, the +** In normal mode, if the fsync() is not a simulated crash, the ** write-list is traversed from beginning to end. Each WriteBuffer ** structure associated with the file handle used to call xSync() ** is written to the real file and removed from the write-list. ** -** If a crash is simulated, one of the following takes place for -** each WriteBuffer in the write-list, regardless of which +** If a crash is simulated, one of the following takes place for +** each WriteBuffer in the write-list, regardless of which ** file-handle it is associated with: ** ** 1. The buffer is correctly written to the file, just as if @@ -77,14 +77,14 @@ ** ** 2. Nothing is done. ** -** 3. Garbage data is written to all sectors of the file that +** 3. Garbage data is written to all sectors of the file that ** overlap the region specified by the WriteBuffer. Or garbage -** data is written to some contiguous section within the +** data is written to some contiguous section within the ** overlapped sectors. ** ** Device Characteristic flag handling: ** -** If the IOCAP_ATOMIC flag is set, then option (3) above is +** If the IOCAP_ATOMIC flag is set, then option (3) above is ** never selected. ** ** If the IOCAP_ATOMIC512 flag is set, and the WriteBuffer represents @@ -96,11 +96,11 @@ ** ** If either the IOCAP_SAFEAPPEND or IOCAP_SEQUENTIAL flags are set ** and a crash is being simulated, then an entry of the write-list is -** selected at random. Everything in the list after the selected entry +** selected at random. Everything in the list after the selected entry ** is discarded before processing begins. ** -** If IOCAP_SEQUENTIAL is set and a crash is being simulated, option -** (1) is selected for all write-list entries except the last. If a +** If IOCAP_SEQUENTIAL is set and a crash is being simulated, option +** (1) is selected for all write-list entries except the last. If a ** crash is not being simulated, then all entries in the write-list ** that occur before at least one write() on the file-handle specified ** as part of the xSync() are written to their associated real files. @@ -114,7 +114,7 @@ ** Each write operation in the write-list is represented by an instance ** of the following structure. ** -** If zBuf is 0, then this structure represents a call to xTruncate(), +** If zBuf is 0, then this structure represents a call to xTruncate(), ** not xWrite(). In that case, iOffset is the size that the file is ** truncated to. */ @@ -133,7 +133,7 @@ char *zName; int flags; /* Flags the file was opened with */ - /* Cache of the entire file. This is used to speed up OsRead() and + /* Cache of the entire file. This is used to speed up OsRead() and ** OsFileSize() calls. Although both could be done by traversing the ** write-list, in practice this is impractically slow. */ @@ -150,7 +150,7 @@ int iDeviceCharacteristics; /* Value of simulated device characteristics */ int iCrash; /* Crash on the iCrash'th call to xSync() */ - char zCrashFile[500]; /* Crash during an xSync() on this file */ + char zCrashFile[500]; /* Crash during an xSync() on this file */ }; static CrashGlobal g = {0, 0, SQLITE_DEFAULT_SECTOR_SIZE, 0, 0}; @@ -172,7 +172,7 @@ /* ** Wrapper around the sqlite3OsWrite() function that avoids writing to the -** 512 byte block begining at offset PENDING_BYTE. +** 512 byte block beginning at offset PENDING_BYTE. */ static int writeDbFile(CrashFile *p, u8 *z, i64 iAmt, i64 iOff){ int rc = SQLITE_OK; @@ -194,7 +194,7 @@ WriteBuffer *pWrite; WriteBuffer **ppPtr; - /* If this is not a crash simulation, set pFinal to point to the + /* If this is not a crash simulation, set pFinal to point to the ** last element of the write-list that is associated with file handle ** pFile. ** @@ -242,7 +242,7 @@ char random; sqlite3_randomness(1, &random); - /* Do not select option 3 (sector trashing) if the IOCAP_ATOMIC flag + /* Do not select option 3 (sector trashing) if the IOCAP_ATOMIC flag ** is set or this is an OsTruncate(), not an Oswrite(). */ if( (iDc&SQLITE_IOCAP_ATOMIC) || (pWrite->zBuf==0) ){ @@ -288,7 +288,7 @@ *ppPtr = pWrite->pNext; #ifdef TRACE_CRASHTEST if( isCrash ){ - printf("Writing %d bytes @ %d (%s)\n", + printf("Writing %d bytes @ %d (%s)\n", pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName ); } @@ -300,7 +300,7 @@ ppPtr = &pWrite->pNext; #ifdef TRACE_CRASHTEST if( isCrash ){ - printf("Omiting %d bytes @ %d (%s)\n", + printf("Omiting %d bytes @ %d (%s)\n", pWrite->nBuf, (int)pWrite->iOffset, pWrite->pFile->zName ); } @@ -315,7 +315,7 @@ assert(pWrite->zBuf); #ifdef TRACE_CRASHTEST - printf("Trashing %d sectors (%d bytes) @ %lld (sector %d) (%s)\n", + printf("Trashing %d sectors (%d bytes) @ %lld (sector %d) (%s)\n", 1+iLast-iFirst, (1+iLast-iFirst)*g.iSectorSize, pWrite->iOffset, iFirst, pWrite->pFile->zName ); @@ -325,7 +325,7 @@ if( zGarbage ){ sqlite3_int64 i; for(i=iFirst; rc==SQLITE_OK && i<=iLast; i++){ - sqlite3_randomness(g.iSectorSize, zGarbage); + sqlite3_randomness(g.iSectorSize, zGarbage); rc = writeDbFile( pWrite->pFile, zGarbage, g.iSectorSize, i*g.iSectorSize ); @@ -389,7 +389,7 @@ g.pWriteList = pNew; } g.pWriteListEnd = pNew; - + return SQLITE_OK; } @@ -407,9 +407,9 @@ ** Read data from a crash-file. */ static int cfRead( - sqlite3_file *pFile, - void *zBuf, - int iAmt, + sqlite3_file *pFile, + void *zBuf, + int iAmt, sqlite_int64 iOfst ){ CrashFile *pCrash = (CrashFile *)pFile; @@ -431,9 +431,9 @@ ** Write data to a crash-file. */ static int cfWrite( - sqlite3_file *pFile, - const void *zBuf, - int iAmt, + sqlite3_file *pFile, + const void *zBuf, + int iAmt, sqlite_int64 iOfst ){ CrashFile *pCrash = (CrashFile *)pFile; @@ -604,7 +604,7 @@ ** ** The caller will have allocated pVfs->szOsFile bytes of space ** at pFile. This file uses this space for the CrashFile structure -** and allocates space for the "real" file structure using +** and allocates space for the "real" file structure using ** sqlite3_malloc(). The assumption here is (pVfs->szOsFile) is ** equal or greater than sizeof(CrashFile). */ @@ -667,17 +667,17 @@ return pVfs->xDelete(pVfs, zPath, dirSync); } static int cfAccess( - sqlite3_vfs *pCfVfs, - const char *zPath, - int flags, + sqlite3_vfs *pCfVfs, + const char *zPath, + int flags, int *pResOut ){ sqlite3_vfs *pVfs = (sqlite3_vfs *)pCfVfs->pAppData; return pVfs->xAccess(pVfs, zPath, flags, pResOut); } static int cfFullPathname( - sqlite3_vfs *pCfVfs, - const char *zPath, + sqlite3_vfs *pCfVfs, + const char *zPath, int nPathOut, char *zPathOut ){ @@ -754,11 +754,11 @@ int nOpt; char *zOpt = Tcl_GetStringFromObj(objv[i], &nOpt); - if( (nOpt>11 || nOpt<2 || strncmp("-sectorsize", zOpt, nOpt)) + if( (nOpt>11 || nOpt<2 || strncmp("-sectorsize", zOpt, nOpt)) && (nOpt>16 || nOpt<2 || strncmp("-characteristics", zOpt, nOpt)) ){ - Tcl_AppendResult(interp, - "Bad option: \"", zOpt, + Tcl_AppendResult(interp, + "Bad option: \"", zOpt, "\" - must be \"-characteristics\" or \"-sectorsize\"", 0 ); return TCL_ERROR; @@ -786,7 +786,7 @@ Tcl_Obj *pFlag = Tcl_DuplicateObj(apObj[j]); Tcl_IncrRefCount(pFlag); Tcl_UtfToLower(Tcl_GetString(pFlag)); - + rc = Tcl_GetIndexFromObjStruct( interp, pFlag, aFlag, sizeof(aFlag[0]), "no such flag", 0, &iChoice ); @@ -814,7 +814,7 @@ /* ** tclcmd: sqlite3_crash_now ** -** Simulate a crash immediately. This function does not return +** Simulate a crash immediately. This function does not return ** (writeListSync() calls exit(-1)). */ static int SQLITE_TCLAPI crashNowCmd( @@ -853,7 +853,7 @@ 0, /* pNext */ "crash", /* zName */ 0, /* pAppData */ - + cfOpen, /* xOpen */ cfDelete, /* xDelete */ cfAccess, /* xAccess */ @@ -909,7 +909,7 @@ ** an argument. For -sectorsize, this is the simulated sector size in ** bytes. For -characteristics, the argument must be a list of io-capability ** flags to simulate. Valid flags are "atomic", "atomic512", "atomic1K", -** "atomic2K", "atomic4K", "atomic8K", "atomic16K", "atomic32K", +** "atomic2K", "atomic4K", "atomic8K", "atomic16K", "atomic32K", ** "atomic64K", "sequential" and "safe_append". ** ** Example: @@ -1046,7 +1046,7 @@ zParent = Tcl_GetString(objv[1]); if( objc==3 ){ if( strcmp(zParent, "-default") ){ - Tcl_AppendResult(interp, + Tcl_AppendResult(interp, "bad option \"", zParent, "\": must be -default", 0 ); return TCL_ERROR; diff -Nru sqlite3-3.42.0/src/test8.c sqlite3-3.44.0-0/src/test8.c --- sqlite3-3.42.0/src/test8.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test8.c 2023-11-04 14:23:58.000000000 +0000 @@ -29,7 +29,7 @@ /* ** The test module defined in this file uses four global Tcl variables to -** commicate with test-scripts: +** communicate with test-scripts: ** ** $::echo_module ** $::echo_module_sync_fail @@ -1317,7 +1317,12 @@ echoCommit, /* xCommit - commit transaction */ echoRollback, /* xRollback - rollback transaction */ echoFindFunction, /* xFindFunction - function overloading */ - echoRename /* xRename - rename the table */ + echoRename, /* xRename - rename the table */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; static sqlite3_module echoModuleV2 = { @@ -1343,7 +1348,9 @@ echoRename, /* xRename - rename the table */ echoSavepoint, echoRelease, - echoRollbackTo + echoRollbackTo, + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff -Nru sqlite3-3.42.0/src/test_bestindex.c sqlite3-3.44.0-0/src/test_bestindex.c --- sqlite3-3.42.0/src/test_bestindex.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_bestindex.c 2023-11-04 14:23:58.000000000 +0000 @@ -814,6 +814,11 @@ 0, /* xRollback */ tclFindFunction, /* xFindFunction */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff -Nru sqlite3-3.42.0/src/test_config.c sqlite3-3.44.0-0/src/test_config.c --- sqlite3-3.42.0/src/test_config.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_config.c 2023-11-04 14:23:58.000000000 +0000 @@ -408,18 +408,6 @@ Tcl_SetVar2(interp, "sqlite_options", "foreignkey", "1", TCL_GLOBAL_ONLY); #endif -#ifdef SQLITE_ENABLE_FTS1 - Tcl_SetVar2(interp, "sqlite_options", "fts1", "1", TCL_GLOBAL_ONLY); -#else - Tcl_SetVar2(interp, "sqlite_options", "fts1", "0", TCL_GLOBAL_ONLY); -#endif - -#ifdef SQLITE_ENABLE_FTS2 - Tcl_SetVar2(interp, "sqlite_options", "fts2", "1", TCL_GLOBAL_ONLY); -#else - Tcl_SetVar2(interp, "sqlite_options", "fts2", "0", TCL_GLOBAL_ONLY); -#endif - #ifdef SQLITE_ENABLE_FTS3 Tcl_SetVar2(interp, "sqlite_options", "fts3", "1", TCL_GLOBAL_ONLY); #else diff -Nru sqlite3-3.42.0/src/test_devsym.c sqlite3-3.44.0-0/src/test_devsym.c --- sqlite3-3.42.0/src/test_devsym.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_devsym.c 2023-11-04 14:23:58.000000000 +0000 @@ -187,7 +187,7 @@ } /* -** Shared-memory methods are all pass-thrus. +** Shared-memory methods are all pass-throughs. */ static int devsymShmLock(sqlite3_file *pFile, int ofst, int n, int flags){ devsym_file *p = (devsym_file *)pFile; diff -Nru sqlite3-3.42.0/src/test_fs.c sqlite3-3.44.0-0/src/test_fs.c --- sqlite3-3.42.0/src/test_fs.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_fs.c 2023-11-04 14:23:58.000000000 +0000 @@ -816,6 +816,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; static sqlite3_module fsdirModule = { @@ -839,6 +844,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; static sqlite3_module fstreeModule = { @@ -862,6 +872,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff -Nru sqlite3-3.42.0/src/test_init.c sqlite3-3.44.0-0/src/test_init.c --- sqlite3-3.42.0/src/test_init.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_init.c 2023-11-04 14:23:58.000000000 +0000 @@ -38,12 +38,12 @@ sqlite3_mem_methods mem; sqlite3_mutex_methods mutex; - int mem_init; /* True if mem subsystem is initalized */ - int mem_fail; /* True to fail mem subsystem inialization */ - int mutex_init; /* True if mutex subsystem is initalized */ - int mutex_fail; /* True to fail mutex subsystem inialization */ - int pcache_init; /* True if pcache subsystem is initalized */ - int pcache_fail; /* True to fail pcache subsystem inialization */ + int mem_init; /* True if mem subsystem is initialized */ + int mem_fail; /* True to fail mem subsystem initialization */ + int mutex_init; /* True if mutex subsystem is initialized */ + int mutex_fail; /* True to fail mutex subsystem initialization */ + int pcache_init; /* True if pcache subsystem is initialized */ + int pcache_fail; /* True to fail pcache subsystem initialization */ } wrapped; static int wrMemInit(void *pAppData){ diff -Nru sqlite3-3.42.0/src/test_intarray.c sqlite3-3.44.0-0/src/test_intarray.c --- sqlite3-3.42.0/src/test_intarray.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_intarray.c 2023-11-04 14:23:58.000000000 +0000 @@ -205,6 +205,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ diff -Nru sqlite3-3.42.0/src/test_intarray.h sqlite3-3.44.0-0/src/test_intarray.h --- sqlite3-3.42.0/src/test_intarray.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_intarray.h 2023-11-04 14:23:58.000000000 +0000 @@ -23,7 +23,7 @@ ** ** SELECT * FROM table WHERE x IN (?,?,?,...,?); ** -** And then binding indivdual integers to each of ? slots, a C-language +** 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: ** diff -Nru sqlite3-3.42.0/src/test_md5.c sqlite3-3.44.0-0/src/test_md5.c --- sqlite3-3.42.0/src/test_md5.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_md5.c 2023-11-04 14:23:58.000000000 +0000 @@ -295,7 +295,7 @@ /* -** Convert a 128-bit MD5 digest into sequency of eight 5-digit integers +** Convert a 128-bit MD5 digest into sequences of eight 5-digit integers ** each representing 16 bits of the digest and separated from each ** other by a "-" character. */ diff -Nru sqlite3-3.42.0/src/test_multiplex.c sqlite3-3.44.0-0/src/test_multiplex.c --- sqlite3-3.42.0/src/test_multiplex.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_multiplex.c 2023-11-04 14:23:58.000000000 +0000 @@ -28,9 +28,9 @@ ** ** The procedure call above will create and register a new VFS shim named ** "multiplex". The multiplex VFS will use the VFS named by zOrigVfsName to -** do the actual disk I/O. (The zOrigVfsName parameter may be NULL, in +** do the actual disk I/O. (The zOrigVfsName parameter may be NULL, in ** which case the default VFS at the moment sqlite3_multiplex_initialize() -** is called will be used as the underlying real VFS.) +** is called will be used as the underlying real VFS.) ** ** If the makeDefault parameter is TRUE then multiplex becomes the new ** default VFS. Otherwise, you can use the multiplex VFS by specifying @@ -39,7 +39,7 @@ ** URI. ** ** The multiplex VFS allows databases up to 32 GiB in size. But it splits -** the files up into smaller pieces, so that they will work even on +** the files up into smaller pieces, so that they will work even on ** filesystems that do not support large files. The default chunk size ** is 2147418112 bytes (which is 64KiB less than 2GiB) but this can be ** changed at compile-time by defining the SQLITE_MULTIPLEX_CHUNK_SIZE @@ -58,10 +58,10 @@ #endif #include "sqlite3ext.h" -/* -** These should be defined to be the same as the values in +/* +** These should be defined to be the same as the values in ** sqliteInt.h. They are defined separately here so that -** the multiplex VFS shim can be built as a loadable +** the multiplex VFS shim can be built as a loadable ** module. */ #define UNUSED_PARAMETER(x) (void)(x) @@ -83,7 +83,7 @@ #endif /* This is the limit on the chunk size. It may be changed by calling -** the xFileControl() interface. It will be rounded up to a +** the xFileControl() interface. It will be rounded up to a ** multiple of MAX_PAGE_SIZE. We default it here to 2GiB less 64KiB. */ #ifndef SQLITE_MULTIPLEX_CHUNK_SIZE @@ -130,7 +130,7 @@ /* ** An instance of the following object represents each open connection -** to a file that is multiplex'ed. This object is a +** to a file that is multiplex'ed. This object is a ** subclass of sqlite3_file. The sqlite3_file object for the underlying ** VFS is appended to this structure. */ @@ -157,11 +157,11 @@ */ sqlite3_vfs sThisVfs; - /* The sIoMethods defines the methods used by sqlite3_file objects + /* The sIoMethods defines the methods used by sqlite3_file objects ** associated with this shim. It is initialized at start-time and does ** not require a mutex. ** - ** When the underlying VFS is called to open a file, it might return + ** When the underlying VFS is called to open a file, it might return ** either a version 1 or a version 2 sqlite3_file object. This shim ** has to create a wrapper sqlite3_file of the same version. Hence ** there are two I/O method structures, one for version 1 and the other @@ -199,16 +199,16 @@ ** nul-terminator. ** ** If iChunk is 0 (or 400 - the number for the first journal file chunk), -** the output is a copy of the input string. Otherwise, if +** the output is a copy of the input string. Otherwise, if ** SQLITE_ENABLE_8_3_NAMES is not defined or the input buffer does not contain -** a "." character, then the output is a copy of the input string with the -** three-digit zero-padded decimal representation if iChunk appended to it. +** a "." character, then the output is a copy of the input string with the +** three-digit zero-padded decimal representation if iChunk appended to it. ** For example: ** ** zBase="test.db", iChunk=4 -> zOut="test.db004" ** ** Or, if SQLITE_ENABLE_8_3_NAMES is defined and the input buffer contains -** a "." character, then everything after the "." is replaced by the +** a "." character, then everything after the "." is replaced by the ** three-digit representation of iChunk. ** ** zBase="test.db", iChunk=4 -> zOut="test.004" @@ -232,12 +232,12 @@ if( i>=n-4 ) n = i+1; if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ /* The extensions on overflow files for main databases are 001, 002, - ** 003 and so forth. To avoid name collisions, add 400 to the + ** 003 and so forth. To avoid name collisions, add 400 to the ** extensions of journal files so that they are 401, 402, 403, .... */ iChunk += SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET; }else if( flags & SQLITE_OPEN_WAL ){ - /* To avoid name collisions, add 700 to the + /* To avoid name collisions, add 700 to the ** extensions of WAL files so that they are 701, 702, 703, .... */ iChunk += SQLITE_MULTIPLEX_WAL_8_3_OFFSET; @@ -297,8 +297,8 @@ sqlite3_vfs *pOrigVfs = gMultiplex.pOrigVfs; /* Real VFS */ #ifdef SQLITE_ENABLE_8_3_NAMES - /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are - ** part of a database journal are named db.401, db.402, and so on. A + /* If JOURNAL_8_3_OFFSET is set to (say) 400, then any overflow files are + ** part of a database journal are named db.401, db.402, and so on. A ** database may therefore not grow to larger than 400 chunks. Attempting ** to open chunk 401 indicates the database is full. */ if( iChunk>=SQLITE_MULTIPLEX_JOURNAL_8_3_OFFSET ){ @@ -351,8 +351,8 @@ /* ** Return the size, in bytes, of chunk number iChunk. If that chunk -** does not exist, then return 0. This function does not distingish between -** non-existant files and zero-length files. +** does not exist, then return 0. This function does not distinguish between +** non-existent files and zero-length files. */ static sqlite3_int64 multiplexSubSize( multiplexGroup *pGroup, /* The multiplexor group */ @@ -367,7 +367,7 @@ if( pSub==0 ) return 0; *rc = pSub->pMethods->xFileSize(pSub, &sz); return sz; -} +} /* ** This is the implementation of the multiplex_control() SQL function. @@ -382,22 +382,22 @@ int op = 0; int iVal; - if( !db || argc!=2 ){ - rc = SQLITE_ERROR; + if( !db || argc!=2 ){ + rc = SQLITE_ERROR; }else{ /* extract params */ op = sqlite3_value_int(argv[0]); iVal = sqlite3_value_int(argv[1]); /* map function op to file_control op */ switch( op ){ - case 1: - op = MULTIPLEX_CTRL_ENABLE; + case 1: + op = MULTIPLEX_CTRL_ENABLE; break; - case 2: - op = MULTIPLEX_CTRL_SET_CHUNK_SIZE; + case 2: + op = MULTIPLEX_CTRL_SET_CHUNK_SIZE; break; - case 3: - op = MULTIPLEX_CTRL_SET_MAX_CHUNKS; + case 3: + op = MULTIPLEX_CTRL_SET_MAX_CHUNKS; break; default: rc = SQLITE_NOTFOUND; @@ -411,16 +411,16 @@ } /* -** This is the entry point to register the auto-extension for the +** This is the entry point to register the auto-extension for the ** multiplex_control() function. */ static int multiplexFuncInit( - sqlite3 *db, - char **pzErrMsg, + sqlite3 *db, + char **pzErrMsg, const sqlite3_api_routines *pApi ){ int rc; - rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, + rc = sqlite3_create_function(db, "multiplex_control", 2, SQLITE_ANY, 0, multiplexControlFunc, 0, 0); return rc; } @@ -508,7 +508,7 @@ memset(pGroup, 0, sz); pMultiplexOpen->pGroup = pGroup; pGroup->bEnabled = (unsigned char)-1; - pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate", + pGroup->bTruncate = (unsigned char)sqlite3_uri_boolean(zUri, "truncate", (flags & SQLITE_OPEN_MAIN_DB)==0); pGroup->szChunk = (int)sqlite3_uri_int64(zUri, "chunksize", SQLITE_MULTIPLEX_CHUNK_SIZE); @@ -551,11 +551,11 @@ if( sz64==0 ){ if( flags & SQLITE_OPEN_MAIN_JOURNAL ){ /* If opening a main journal file and the first chunk is zero - ** bytes in size, delete any subsequent chunks from the + ** bytes in size, delete any subsequent chunks from the ** file-system. */ int iChunk = 1; do { - rc = pOrigVfs->xAccess(pOrigVfs, + rc = pOrigVfs->xAccess(pOrigVfs, pGroup->aReal[iChunk].z, SQLITE_ACCESS_EXISTS, &bExists ); if( rc==SQLITE_OK && bExists ){ @@ -573,8 +573,8 @@ ** ** 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 togethre. + ** 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); @@ -618,7 +618,7 @@ rc = pOrigVfs->xDelete(pOrigVfs, zName, syncDir); if( rc==SQLITE_OK ){ /* If the main chunk was deleted successfully, also delete any subsequent - ** chunks - starting with the last (highest numbered). + ** chunks - starting with the last (highest numbered). */ int nName = (int)strlen(zName); char *z; @@ -695,7 +695,7 @@ /* xClose requests get passed through to the original VFS. ** We loop over all open chunk handles and close them. -** The group structure for this file is unlinked from +** The group structure for this file is unlinked from ** our list of groups and freed. */ static int multiplexClose(sqlite3_file *pConn){ @@ -1008,7 +1008,7 @@ /* ** PRAGMA multiplex_chunksize; ** - ** Return the chunksize for the multiplexor, or no-op if the + ** Return the chunksize for the multiplexor, or no-op if the ** multiplexor is not active. */ if( sqlite3_stricmp(aFcntl[1],"multiplex_chunksize")==0 @@ -1138,8 +1138,8 @@ /* ** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize() ** -** Use the VFS named zOrigVfsName as the VFS that does the actual work. -** Use the default if zOrigVfsName==NULL. +** Use the VFS named zOrigVfsName as the VFS that does the actual work. +** Use the default if zOrigVfsName==NULL. ** ** The multiplex VFS shim is named "multiplex". It will become the default ** VFS if makeDefault is non-zero. diff -Nru sqlite3-3.42.0/src/test_multiplex.h sqlite3-3.44.0-0/src/test_multiplex.h --- sqlite3-3.42.0/src/test_multiplex.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_multiplex.h 2023-11-04 14:23:58.000000000 +0000 @@ -13,8 +13,8 @@ ** This file contains a VFS "shim" - a layer that sits in between the ** pager and the real VFS. ** -** This particular shim enforces a multiplex system on DB files. -** This shim shards/partitions a single DB file into smaller +** This particular shim enforces a multiplex system on DB files. +** This shim shards/partitions a single DB file into smaller ** "chunks" such that the total DB file size may exceed the maximum ** file size of the underlying file system. ** @@ -33,14 +33,14 @@ ** shim. ** ** MULTIPLEX_CTRL_SET_CHUNK_SIZE: -** This file control is used to set the maximum allowed chunk -** size for a multiplex file set. The chunk size should be +** This file control is used to set the maximum allowed chunk +** size for a multiplex file set. The chunk size should be ** a multiple of SQLITE_MAX_PAGE_SIZE, and will be rounded up ** if not. ** ** MULTIPLEX_CTRL_SET_MAX_CHUNKS: ** This file control is used to set the maximum number of chunks -** allowed to be used for a mutliplex file set. +** allowed to be used for a multiplex file set. */ #define MULTIPLEX_CTRL_ENABLE 214014 #define MULTIPLEX_CTRL_SET_CHUNK_SIZE 214015 @@ -53,26 +53,26 @@ /* ** CAPI: Initialize the multiplex VFS shim - sqlite3_multiplex_initialize() ** -** Use the VFS named zOrigVfsName as the VFS that does the actual work. -** Use the default if zOrigVfsName==NULL. +** Use the VFS named zOrigVfsName as the VFS that does the actual work. +** Use the default if zOrigVfsName==NULL. ** ** The multiplex VFS shim is named "multiplex". It will become the default ** VFS if makeDefault is non-zero. ** -** An auto-extension is registered which will make the function +** An auto-extension is registered which will make the function ** multiplex_control() available to database connections. This -** function gives access to the xFileControl interface of the +** function gives access to the xFileControl interface of the ** multiplex VFS shim. ** ** SELECT multiplex_control(,); -** +** ** =1 MULTIPLEX_CTRL_ENABLE ** =0 disable ** =1 enable -** +** ** =2 MULTIPLEX_CTRL_SET_CHUNK_SIZE ** int, chunk size -** +** ** =3 MULTIPLEX_CTRL_SET_MAX_CHUNKS ** int, max chunks ** diff -Nru sqlite3-3.42.0/src/test_mutex.c sqlite3-3.44.0-0/src/test_mutex.c --- sqlite3-3.42.0/src/test_mutex.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_mutex.c 2023-11-04 14:23:58.000000000 +0000 @@ -45,7 +45,7 @@ /* State variables */ static struct test_mutex_globals { int isInstalled; /* True if installed */ - int disableInit; /* True to cause sqlite3_initalize() to fail */ + 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 */ diff -Nru sqlite3-3.42.0/src/test_osinst.c sqlite3-3.44.0-0/src/test_osinst.c --- sqlite3-3.42.0/src/test_osinst.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_osinst.c 2023-11-04 14:23:58.000000000 +0000 @@ -1090,7 +1090,12 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ - }; + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ + }; sqlite3_create_module(db, "vfslog", &vfslog_module, 0); return SQLITE_OK; diff -Nru sqlite3-3.42.0/src/test_pcache.c sqlite3-3.44.0-0/src/test_pcache.c --- sqlite3-3.42.0/src/test_pcache.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_pcache.c 2023-11-04 14:23:58.000000000 +0000 @@ -9,17 +9,17 @@ ** May you share freely, never taking more than you give. ** ************************************************************************* -** +** ** This file contains code used for testing the SQLite system. ** None of the code in this file goes into a deliverable build. -** +** ** This file contains an application-defined pager cache ** implementation that can be plugged in in place of the ** default pcache. This alternative pager cache will throw ** some errors that the default cache does not. ** ** This pagecache implementation is designed for simplicity -** not speed. +** not speed. */ #include "sqlite3.h" #include @@ -36,7 +36,7 @@ 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 agressively */ + unsigned highStress; /* Call xStress aggressively */ }; static testpcacheGlobalType testpcacheGlobal; @@ -131,8 +131,8 @@ ** Allocate a new page cache instance. */ static sqlite3_pcache *testpcacheCreate( - int szPage, - int szExtra, + int szPage, + int szExtra, int bPurgeable ){ int nMem; @@ -225,7 +225,7 @@ return 0; } - /* Do not allocate if highStress is enabled and createFlag is not 2. + /* Do not allocate if highStress is enabled and createFlag is not 2. ** ** The highStress setting causes pagerStress() to be called much more ** often, which exercises the pager logic more intensely. @@ -428,7 +428,7 @@ 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 agressively */ + unsigned highStress /* Call xStress aggressively */ ){ static const sqlite3_pcache_methods2 testPcache = { 1, diff -Nru sqlite3-3.42.0/src/test_quota.c sqlite3-3.44.0-0/src/test_quota.c --- sqlite3-3.42.0/src/test_quota.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_quota.c 2023-11-04 14:23:58.000000000 +0000 @@ -999,7 +999,7 @@ 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 objecct */ + quota_FILE *p /* Write to this quota_FILE object */ ){ sqlite3_int64 iOfst; sqlite3_int64 iEnd; @@ -1876,7 +1876,7 @@ Tcl_Obj *CONST objv[] ){ const char *zPattern; /* The glob pattern */ - const char *zText; /* Text to compare agains the pattern */ + const char *zText; /* Text to compare against the pattern */ int rc; if( objc!=3 ){ Tcl_WrongNumArgs(interp, 1, objv, "PATTERN TEXT"); diff -Nru sqlite3-3.42.0/src/test_schema.c sqlite3-3.44.0-0/src/test_schema.c --- sqlite3-3.42.0/src/test_schema.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_schema.c 2023-11-04 14:23:58.000000000 +0000 @@ -292,6 +292,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; #endif /* !defined(SQLITE_OMIT_VIRTUALTABLE) */ diff -Nru sqlite3-3.42.0/src/test_tclvar.c sqlite3-3.44.0-0/src/test_tclvar.c --- sqlite3-3.42.0/src/test_tclvar.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_tclvar.c 2023-11-04 14:23:58.000000000 +0000 @@ -487,6 +487,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* diff -Nru sqlite3-3.42.0/src/test_vfstrace.c sqlite3-3.44.0-0/src/test_vfstrace.c --- sqlite3-3.42.0/src/test_vfstrace.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_vfstrace.c 2023-11-04 14:23:58.000000000 +0000 @@ -787,7 +787,7 @@ } /* -** Return th3 emost recent error code and message +** Return th3 most recent error code and message */ static int vfstraceGetLastError(sqlite3_vfs *pVfs, int iErr, char *zErr){ vfstrace_info *pInfo = (vfstrace_info*)pVfs->pAppData; diff -Nru sqlite3-3.42.0/src/test_windirent.h sqlite3-3.44.0-0/src/test_windirent.h --- sqlite3-3.42.0/src/test_windirent.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/test_windirent.h 2023-11-04 14:23:58.000000000 +0000 @@ -140,7 +140,7 @@ #endif /* -** Provide the function prototype for the POSIX compatiable getenv() +** Provide the function prototype for the POSIX compatible getenv() ** function. This function is not thread-safe. */ diff -Nru sqlite3-3.42.0/src/tokenize.c sqlite3-3.44.0-0/src/tokenize.c --- sqlite3-3.42.0/src/tokenize.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/tokenize.c 2023-11-04 14:23:58.000000000 +0000 @@ -433,7 +433,7 @@ testcase( z[0]=='0' ); testcase( z[0]=='1' ); testcase( z[0]=='2' ); testcase( z[0]=='3' ); testcase( z[0]=='4' ); testcase( z[0]=='5' ); testcase( z[0]=='6' ); testcase( z[0]=='7' ); testcase( z[0]=='8' ); - testcase( z[0]=='9' ); + testcase( z[0]=='9' ); testcase( z[0]=='.' ); *tokenType = TK_INTEGER; #ifndef SQLITE_OMIT_HEX_INTEGER if( z[0]=='0' && (z[1]=='x' || z[1]=='X') && sqlite3Isxdigit(z[2]) ){ @@ -505,7 +505,8 @@ return i; } case CC_KYWD0: { - for(i=1; aiClass[z[i]]<=CC_KYWD; i++){} + if( aiClass[z[1]]>CC_KYWD ){ i = 1; break; } + for(i=2; aiClass[z[i]]<=CC_KYWD; i++){} if( IdChar(z[i]) ){ /* This token started out using characters that can appear in keywords, ** but z[i] is a character not allowed within keywords, so this must diff -Nru sqlite3-3.42.0/src/treeview.c sqlite3-3.44.0-0/src/treeview.c --- sqlite3-3.42.0/src/treeview.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/treeview.c 2023-11-04 14:23:58.000000000 +0000 @@ -412,6 +412,7 @@ sqlite3TreeViewItem(pView, "FILTER", 1); sqlite3TreeViewExpr(pView, pWin->pFilter, 0); sqlite3TreeViewPop(&pView); + if( pWin->eFrmType==TK_FILTER ) return; } sqlite3TreeViewPush(&pView, more); if( pWin->zName ){ @@ -421,7 +422,7 @@ } if( pWin->zBase ) nElement++; if( pWin->pOrderBy ) nElement++; - if( pWin->eFrmType ) nElement++; + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ) nElement++; if( pWin->eExclude ) nElement++; if( pWin->zBase ){ sqlite3TreeViewPush(&pView, (--nElement)>0); @@ -434,7 +435,7 @@ if( pWin->pOrderBy ){ sqlite3TreeViewExprList(pView, pWin->pOrderBy, (--nElement)>0, "ORDER-BY"); } - if( pWin->eFrmType ){ + if( pWin->eFrmType!=0 && pWin->eFrmType!=TK_FILTER ){ char zBuf[30]; const char *zFrmType = "ROWS"; if( pWin->eFrmType==TK_RANGE ) zFrmType = "RANGE"; @@ -643,7 +644,8 @@ }; assert( pExpr->op2==TK_IS || pExpr->op2==TK_ISNOT ); assert( pExpr->pRight ); - assert( sqlite3ExprSkipCollate(pExpr->pRight)->op==TK_TRUEFALSE ); + assert( sqlite3ExprSkipCollateAndLikely(pExpr->pRight)->op + == TK_TRUEFALSE ); x = (pExpr->op2==TK_ISNOT)*2 + sqlite3ExprTruthValue(pExpr->pRight); zUniOp = azOp[x]; break; @@ -681,7 +683,7 @@ assert( ExprUseXList(pExpr) ); pFarg = pExpr->x.pList; #ifndef SQLITE_OMIT_WINDOWFUNC - pWin = ExprHasProperty(pExpr, EP_WinFunc) ? pExpr->y.pWin : 0; + pWin = IsWindowFunc(pExpr) ? pExpr->y.pWin : 0; #else pWin = 0; #endif @@ -707,7 +709,13 @@ sqlite3TreeViewLine(pView, "FUNCTION %Q%s", pExpr->u.zToken, zFlgs); } if( pFarg ){ - sqlite3TreeViewExprList(pView, pFarg, pWin!=0, 0); + sqlite3TreeViewExprList(pView, pFarg, pWin!=0 || pExpr->pLeft, 0); + if( pExpr->pLeft ){ + Expr *pOB = pExpr->pLeft; + assert( pOB->op==TK_ORDER ); + assert( ExprUseXList(pOB) ); + sqlite3TreeViewExprList(pView, pOB->x.pList, pWin!=0, "ORDERBY"); + } } #ifndef SQLITE_OMIT_WINDOWFUNC if( pWin ){ @@ -716,6 +724,10 @@ #endif break; } + case TK_ORDER: { + sqlite3TreeViewExprList(pView, pExpr->x.pList, 0, "ORDERBY"); + break; + } #ifndef SQLITE_OMIT_SUBQUERY case TK_EXISTS: { assert( ExprUseXSelect(pExpr) ); diff -Nru sqlite3-3.42.0/src/trigger.c sqlite3-3.44.0-0/src/trigger.c --- sqlite3-3.42.0/src/trigger.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/trigger.c 2023-11-04 14:23:58.000000000 +0000 @@ -183,6 +183,10 @@ sqlite3ErrorMsg(pParse, "cannot create triggers on virtual tables"); goto trigger_orphan_error; } + if( (pTab->tabFlags & TF_Shadow)!=0 && sqlite3ReadOnlyShadowTables(db) ){ + sqlite3ErrorMsg(pParse, "cannot create triggers on shadow tables"); + goto trigger_orphan_error; + } /* Check that the trigger name is not reserved and that no trigger of the ** specified name exists */ @@ -966,10 +970,17 @@ SrcList sFrom; assert( v!=0 ); - assert( pParse->bReturning ); + if( !pParse->bReturning ){ + /* This RETURNING trigger must be for a different statement as + ** this statement lacks a RETURNING clause. */ + return; + } assert( db->pParse==pParse ); pReturning = pParse->u1.pReturning; - assert( pTrigger == &(pReturning->retTrig) ); + if( pTrigger != &(pReturning->retTrig) ){ + /* This RETURNING trigger is for a different statement */ + return; + } memset(&sSelect, 0, sizeof(sSelect)); memset(&sFrom, 0, sizeof(sFrom)); sSelect.pEList = sqlite3ExprListDup(db, pReturning->pReturnEL, 0); diff -Nru sqlite3-3.42.0/src/update.c sqlite3-3.44.0-0/src/update.c --- sqlite3-3.42.0/src/update.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/update.c 2023-11-04 14:23:58.000000000 +0000 @@ -30,10 +30,10 @@ /* ** The most recently coded instruction was an OP_Column to retrieve the -** i-th column of table pTab. This routine sets the P4 parameter of the +** i-th column of table pTab. This routine sets the P4 parameter of the ** OP_Column to the default value, if any. ** -** The default value of a column is specified by a DEFAULT clause in the +** The default value of a column is specified by a DEFAULT clause in the ** column definition. This was either supplied by the user when the table ** was created, or added later to the table definition by an ALTER TABLE ** command. If the latter, then the row-records in the table btree on disk @@ -42,9 +42,9 @@ ** If the former, then all row-records are guaranteed to include a value ** for the column and the P4 value is not required. ** -** Column definitions created by an ALTER TABLE command may only have +** Column definitions created by an ALTER TABLE command may only have ** literal default values specified: a number, null or a string. (If a more -** complicated default expression value was provided, it is evaluated +** complicated default expression value was provided, it is evaluated ** when the ALTER TABLE is executed and one of the literal values written ** into the sqlite_schema table.) ** @@ -69,8 +69,8 @@ assert( !IsView(pTab) ); VdbeComment((v, "%s.%s", pTab->zName, pCol->zCnName)); assert( inCol ); - sqlite3ValueFromExpr(sqlite3VdbeDb(v), - sqlite3ColumnExpr(pTab,pCol), enc, + sqlite3ValueFromExpr(sqlite3VdbeDb(v), + sqlite3ColumnExpr(pTab,pCol), enc, pCol->affinity, &pValue); if( pValue ){ sqlite3VdbeAppendP4(v, pValue, P4_MEM); @@ -150,17 +150,17 @@ ** Assuming both the pLimit and pOrderBy parameters are NULL, this function ** generates VM code to run the query: ** -** SELECT , pChanges FROM pTabList WHERE pWhere +** SELECT , pChanges FROM pTabList WHERE pWhere ** -** and write the results to the ephemeral table already opened as cursor -** iEph. None of pChanges, pTabList or pWhere are modified or consumed by +** and write the results to the ephemeral table already opened as cursor +** iEph. None of pChanges, pTabList or pWhere are modified or consumed by ** this function, they must be deleted by the caller. ** ** Or, if pLimit and pOrderBy are not NULL, and pTab is not a view: ** -** SELECT , pChanges FROM pTabList +** SELECT , pChanges FROM pTabList ** WHERE pWhere -** GROUP BY +** GROUP BY ** ORDER BY pOrderBy LIMIT pLimit ** ** If pTab is a view, the GROUP BY clause is omitted. @@ -178,11 +178,11 @@ ** the view. The results are written to the ephemeral table iEph as records ** with automatically assigned integer keys. ** -** If the table is a virtual or ordinary intkey table, then +** If the table is a virtual or ordinary intkey table, then ** is its rowid. For a virtual table, the results are written to iEph as ** records with automatically assigned integer keys For intkey tables, the -** rowid value in is used as the integer key, and the -** remaining fields make up the table record. +** rowid value in is used as the integer key, and the +** remaining fields make up the table record. */ static void updateFromSelect( Parse *pParse, /* Parse context */ @@ -224,7 +224,7 @@ assert( pTabList->nSrc>1 ); if( pSrc ){ - pSrc->a[0].fg.notCte = 1; + assert( pSrc->a[0].fg.notCte ); pSrc->a[0].iCursor = -1; pSrc->a[0].pTab->nTabRef--; pSrc->a[0].pTab = 0; @@ -257,13 +257,13 @@ assert( pChanges!=0 || pParse->db->mallocFailed ); if( pChanges ){ for(i=0; inExpr; i++){ - pList = sqlite3ExprListAppend(pParse, pList, + pList = sqlite3ExprListAppend(pParse, pList, sqlite3ExprDup(db, pChanges->a[i].pExpr, 0) ); } } - pSelect = sqlite3SelectNew(pParse, pList, - pSrc, pWhere2, pGrp, 0, pOrderBy2, + pSelect = sqlite3SelectNew(pParse, pList, + pSrc, pWhere2, pGrp, 0, pOrderBy2, SF_UFSrcCheck|SF_IncludeHidden|SF_UpdateFrom, pLimit2 ); if( pSelect ) pSelect->selFlags |= SF_OrderByReqd; @@ -357,7 +357,7 @@ } assert( db->mallocFailed==0 ); - /* Locate the table which we want to update. + /* Locate the table which we want to update. */ pTab = sqlite3SrcListLookup(pParse, pTabList); if( pTab==0 ) goto update_cleanup; @@ -435,7 +435,7 @@ } pTabList->a[0].iCursor = iDataCur; - /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. + /* Allocate space for aXRef[], aRegIdx[], and aToOpen[]. ** Initialize aXRef[] and aToOpen[] to their default values. */ aXRef = sqlite3DbMallocRawNN(db, sizeof(int) * (pTab->nCol+nIdx+1) + nIdx+2 ); @@ -486,7 +486,7 @@ else if( pTab->aCol[j].colFlags & COLFLAG_GENERATED ){ testcase( pTab->aCol[j].colFlags & COLFLAG_VIRTUAL ); testcase( pTab->aCol[j].colFlags & COLFLAG_STORED ); - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot UPDATE generated column \"%s\"", pTab->aCol[j].zCnName); goto update_cleanup; @@ -529,11 +529,11 @@ #ifndef SQLITE_OMIT_GENERATED_COLUMNS /* Mark generated columns as changing if their generator expressions - ** reference any changing column. The actual aXRef[] value for + ** reference any changing column. The actual aXRef[] value for ** generated expressions is not used, other than to check to see that it ** is non-negative, so the value of aXRef[] for generated columns can be ** set to any non-negative number. We use 99999 so that the value is - ** obvious when looking at aXRef[] in a symbolic debugger. + ** obvious when looking at aXRef[] in a symbolic debugger. */ if( pTab->tabFlags & TF_HasGenerated ){ int bProgress; @@ -556,7 +556,7 @@ } #endif - /* The SET expressions are not actually used inside the WHERE loop. + /* The SET expressions are not actually used inside the WHERE loop. ** So reset the colUsed mask. Unless this is a virtual table. In that ** case, set all bits of the colUsed mask (to ensure that the virtual ** table implementation makes all columns available). @@ -595,7 +595,7 @@ } aRegIdx[nAllIdx] = ++pParse->nMem; /* Register storing the table record */ if( bReplace ){ - /* If REPLACE conflict resolution might be invoked, open cursors on all + /* If REPLACE conflict resolution might be invoked, open cursors on all ** indexes in case they are needed to delete records. */ memset(aToOpen, 1, nIdx+1); } @@ -634,7 +634,7 @@ */ #if !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) if( nChangeFrom==0 && isView ){ - sqlite3MaterializeView(pParse, pTab, + sqlite3MaterializeView(pParse, pTab, pWhere, pOrderBy, pLimit, iDataCur ); pOrderBy = 0; @@ -706,7 +706,7 @@ } } } - + if( nChangeFrom ){ sqlite3MultiWrite(pParse); eOnePass = ONEPASS_OFF; @@ -724,7 +724,7 @@ sqlite3ExprIfFalse(pParse, pWhere, labelBreak, SQLITE_JUMPIFNULL); bFinishSeek = 0; }else{ - /* Begin the database scan. + /* Begin the database scan. ** ** Do not consider a single-pass strategy for a multi-row update if ** there is anything that might disrupt the cursor being used to do @@ -741,7 +741,7 @@ && !hasFK && !chngKey && !bReplace - && (sNC.ncFlags & NC_Subquery)==0 + && (pWhere==0 || !ExprHasProperty(pWhere, EP_Subquery)) ){ flags |= WHERE_ONEPASS_MULTIROW; } @@ -787,7 +787,7 @@ /* Read the PK of the current row into an array of registers. In ** ONEPASS_OFF mode, serialize the array into a record and store it in ** the ephemeral table. Or, in ONEPASS_SINGLE or MULTI mode, change - ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table + ** the OP_OpenEphemeral instruction to a Noop (the ephemeral table ** is not required) and leave the PK fields in the array of registers. */ for(i=0; iaiColumn[i]>=0 ); @@ -810,26 +810,28 @@ if( nChangeFrom==0 && eOnePass!=ONEPASS_MULTI ){ sqlite3WhereEnd(pWInfo); } - + if( !isView ){ int addrOnce = 0; - + int iNotUsed1 = 0; + int iNotUsed2 = 0; + /* Open every index that needs updating. */ if( eOnePass!=ONEPASS_OFF ){ if( aiCurOnePass[0]>=0 ) aToOpen[aiCurOnePass[0]-iBaseCur] = 0; if( aiCurOnePass[1]>=0 ) aToOpen[aiCurOnePass[1]-iBaseCur] = 0; } - + if( eOnePass==ONEPASS_MULTI && (nIdx-(aiCurOnePass[1]>=0))>0 ){ addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); } sqlite3OpenTableAndIndices(pParse, pTab, OP_OpenWrite, 0, iBaseCur, - aToOpen, 0, 0); + aToOpen, &iNotUsed1, &iNotUsed2); if( addrOnce ){ sqlite3VdbeJumpHereOrPopInst(v, addrOnce); } } - + /* Top of the update loop */ if( eOnePass!=ONEPASS_OFF ){ if( aiCurOnePass[0]!=iDataCur @@ -902,7 +904,7 @@ ** information is needed */ if( chngPk || hasFK || pTrigger ){ u32 oldmask = (hasFK ? sqlite3FkOldmask(pParse, pTab) : 0); - oldmask |= sqlite3TriggerColmask(pParse, + oldmask |= sqlite3TriggerColmask(pParse, pTrigger, pChanges, 0, TRIGGER_BEFORE|TRIGGER_AFTER, pTab, onError ); for(i=0; inCol; i++){ @@ -931,8 +933,8 @@ ** If there are one or more BEFORE triggers, then do not populate the ** registers associated with columns that are (a) not modified by ** this UPDATE statement and (b) not accessed by new.* references. The - ** values for registers not modified by the UPDATE must be reloaded from - ** the database after the BEFORE triggers are fired anyway (as the trigger + ** values for registers not modified by the UPDATE must be reloaded from + ** the database after the BEFORE triggers are fired anyway (as the trigger ** may have modified them). So not loading those that are not going to ** be used eliminates some redundant opcodes. */ @@ -955,7 +957,7 @@ sqlite3ExprCode(pParse, pChanges->a[j].pExpr, k); } }else if( 0==(tmask&TRIGGER_BEFORE) || i>31 || (newmask & MASKBIT32(i)) ){ - /* This branch loads the value of a column that will not be changed + /* This branch loads the value of a column that will not be changed ** into a register. This is done if there are no BEFORE triggers, or ** if there are one or more BEFORE triggers that use this value via ** a new.* reference in a trigger program. @@ -982,12 +984,12 @@ */ if( tmask&TRIGGER_BEFORE ){ sqlite3TableAffinity(v, pTab, regNew); - sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, TRIGGER_BEFORE, pTab, regOldRowid, onError, labelContinue); if( !isView ){ /* The row-trigger may have deleted the row being updated. In this - ** case, jump to the next row. No updates or AFTER triggers are + ** case, jump to the next row. No updates or AFTER triggers are ** required. This behavior - what happens when the row being updated ** is deleted or renamed by a BEFORE trigger - is left undefined in the ** documentation. @@ -1001,8 +1003,8 @@ } /* After-BEFORE-trigger-reload-loop: - ** If it did not delete it, the BEFORE trigger may still have modified - ** some of the columns of the row being updated. Load the values for + ** If it did not delete it, the BEFORE trigger may still have modified + ** some of the columns of the row being updated. Load the values for ** all columns not modified by the update statement into their registers ** in case this has happened. Only unmodified columns are reloaded. ** The values computed for modified columns use the values before the @@ -1022,7 +1024,7 @@ testcase( pTab->tabFlags & TF_HasStored ); sqlite3ComputeGeneratedColumns(pParse, regNew, pTab); } -#endif +#endif } } @@ -1066,7 +1068,7 @@ ** to process, delete the old record. Otherwise, add a noop OP_Delete ** to invoke the pre-update hook. ** - ** That (regNew==regnewRowid+1) is true is also important for the + ** That (regNew==regnewRowid+1) is true is also important for the ** pre-update hook. If the caller invokes preupdate_new(), the returned ** value is copied from memory cell (regNewRowid+1+iCol), where iCol ** is the column index supplied by the user. @@ -1093,30 +1095,32 @@ if( hasFK ){ sqlite3FkCheck(pParse, pTab, 0, regNewRowid, aXRef, chngKey); } - + /* Insert the new index entries and the new record. */ sqlite3CompleteInsertion( - pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx, - OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0), + pParse, pTab, iDataCur, iIdxCur, regNewRowid, aRegIdx, + OPFLAG_ISUPDATE | (eOnePass==ONEPASS_MULTI ? OPFLAG_SAVEPOSITION : 0), 0, 0 ); /* Do any ON CASCADE, SET NULL or SET DEFAULT operations required to ** handle rows (possibly in other tables) that refer via a foreign key - ** to the row just updated. */ + ** to the row just updated. */ if( hasFK ){ sqlite3FkActions(pParse, pTab, pChanges, regOldRowid, aXRef, chngKey); } } - /* Increment the row counter + /* Increment the row counter */ if( regRowCount ){ sqlite3VdbeAddOp2(v, OP_AddImm, regRowCount, 1); } - sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, - TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); + if( pTrigger ){ + sqlite3CodeRowTrigger(pParse, pTrigger, TK_UPDATE, pChanges, + TRIGGER_AFTER, pTab, regOldRowid, onError, labelContinue); + } /* Repeat the above with the next record to be updated, until ** all record selected by the WHERE clause have been updated. @@ -1154,7 +1158,7 @@ sqlite3SrcListDelete(db, pTabList); sqlite3ExprListDelete(db, pChanges); sqlite3ExprDelete(db, pWhere); -#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) +#if defined(SQLITE_ENABLE_UPDATE_DELETE_LIMIT) sqlite3ExprListDelete(db, pOrderBy); sqlite3ExprDelete(db, pLimit); #endif @@ -1174,8 +1178,8 @@ /* ** Generate code for an UPDATE of a virtual table. ** -** There are two possible strategies - the default and the special -** "onepass" strategy. Onepass is only used if the virtual table +** There are two possible strategies - the default and the special +** "onepass" strategy. Onepass is only used if the virtual table ** implementation indicates that pWhere may match at most one row. ** ** The default strategy is to create an ephemeral table that contains @@ -1211,7 +1215,7 @@ int nArg = 2 + pTab->nCol; /* Number of arguments to VUpdate */ int regArg; /* First register in VUpdate arg array */ int regRec; /* Register in which to assemble record */ - int regRowid; /* Register for ephem table rowid */ + int regRowid; /* Register for ephemeral table rowid */ int iCsr = pSrc->a[0].iCursor; /* Cursor used for virtual table scan */ int aDummy[2]; /* Unused arg for sqlite3WhereOkOnePass() */ int eOnePass; /* True to use onepass strategy */ @@ -1255,7 +1259,9 @@ sqlite3ExprDup(db, pChanges->a[aXRef[i]].pExpr, 0) ); }else{ - pList = sqlite3ExprListAppend(pParse, pList, exprRowColumn(pParse, i)); + Expr *pRowExpr = exprRowColumn(pParse, i); + if( pRowExpr ) pRowExpr->op2 = OPFLAG_NOCHNG; + pList = sqlite3ExprListAppend(pParse, pList, pRowExpr); } } @@ -1332,10 +1338,10 @@ sqlite3WhereEnd(pWInfo); } - /* Begin scannning through the ephemeral table. */ + /* 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 + /* Extract arguments from the current row of the ephemeral table and ** invoke the VUpdate method. */ for(i=0; ia[jj].pExpr,pExpr,iCursor)<2 ){ + if( sqlite3ExprCompare(0,pTarget->a[jj].pExpr,pExpr,iCursor)<2 ){ break; /* Column ii of the index matches column jj of target */ } } diff -Nru sqlite3-3.42.0/src/util.c sqlite3-3.44.0-0/src/util.c --- sqlite3-3.42.0/src/util.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/util.c 2023-11-04 14:23:58.000000000 +0000 @@ -23,8 +23,8 @@ /* ** 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 futher downstream. +** 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. @@ -82,7 +82,7 @@ } /* -** Return the declared type of a column. Or return zDflt if the column +** Return the declared type of a column. Or return zDflt if the column ** has no declared type. ** ** The column type is an extra string stored after the zero-terminator on @@ -141,6 +141,23 @@ */ void sqlite3SystemError(sqlite3 *db, int rc){ if( rc==SQLITE_IOERR_NOMEM ) return; +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_IOERR_IN_PAGE ){ + int ii; + int iErr; + sqlite3BtreeEnterAll(db); + for(ii=0; iinDb; ii++){ + if( db->aDb[ii].pBt ){ + iErr = sqlite3PagerWalSystemErrno(sqlite3BtreePager(db->aDb[ii].pBt)); + if( iErr ){ + db->iSysErrno = iErr; + } + } + } + sqlite3BtreeLeaveAll(db); + return; + } +#endif rc &= 0xff; if( rc==SQLITE_CANTOPEN || rc==SQLITE_IOERR ){ db->iSysErrno = sqlite3OsGetLastError(db->pVfs); @@ -185,12 +202,16 @@ p->rc = SQLITE_INTERRUPT; } #ifndef SQLITE_OMIT_PROGRESS_CALLBACK - if( db->xProgress && (++p->nProgressSteps)>=db->nProgressOps ){ - if( db->xProgress(db->pProgressArg) ){ - p->nErr++; - p->rc = SQLITE_INTERRUPT; + if( db->xProgress ){ + if( p->rc==SQLITE_INTERRUPT ){ + p->nProgressSteps = 0; + }else if( (++p->nProgressSteps)>=db->nProgressOps ){ + if( db->xProgress(db->pProgressArg) ){ + p->nErr++; + p->rc = SQLITE_INTERRUPT; + } + p->nProgressSteps = 0; } - p->nProgressSteps = 0; } #endif } @@ -386,43 +407,40 @@ return h; } -/* -** Compute 10 to the E-th power. Examples: E==1 results in 10. -** E==2 results in 100. E==50 results in 1.0e50. +/* Double-Double multiplication. (x[0],x[1]) *= (y,yy) ** -** This routine only works for values of E between 1 and 341. -*/ -static LONGDOUBLE_TYPE sqlite3Pow10(int E){ -#if defined(_MSC_VER) - static const LONGDOUBLE_TYPE x[] = { - 1.0e+001L, - 1.0e+002L, - 1.0e+004L, - 1.0e+008L, - 1.0e+016L, - 1.0e+032L, - 1.0e+064L, - 1.0e+128L, - 1.0e+256L - }; - LONGDOUBLE_TYPE r = 1.0; - int i; - assert( E>=0 && E<=307 ); - for(i=0; E!=0; i++, E >>=1){ - if( E & 1 ) r *= x[i]; - } - return r; -#else - LONGDOUBLE_TYPE x = 10.0; - LONGDOUBLE_TYPE r = 1.0; - while(1){ - if( E & 1 ) r *= x; - E >>= 1; - if( E==0 ) break; - x *= x; - } - return r; -#endif +** Reference: +** T. J. Dekker, "A Floating-Point Technique for Extending the +** Available Precision". 1971-07-26. +*/ +static void dekkerMul2(volatile double *x, double y, double yy){ + /* + ** The "volatile" keywords on parameter x[] and on local variables + ** below are needed force intermediate results to be truncated to + ** binary64 rather than be carried around in an extended-precision + ** format. The truncation is necessary for the Dekker algorithm to + ** work. Intel x86 floating point might omit the truncation without + ** the use of volatile. + */ + volatile double tx, ty, p, q, c, cc; + double hx, hy; + u64 m; + memcpy(&m, (void*)&x[0], 8); + m &= 0xfffffffffc000000LL; + memcpy(&hx, &m, 8); + tx = x[0] - hx; + memcpy(&m, &y, 8); + m &= 0xfffffffffc000000LL; + memcpy(&hy, &m, 8); + ty = y - hy; + p = hx*hy; + q = hx*ty + tx*hy; + c = p+q; + cc = p - c + q + tx*ty; + cc = x[0]*yy + x[1]*y + cc; + x[0] = c + cc; + x[1] = c - x[0]; + x[1] += cc; } /* @@ -438,7 +456,7 @@ ** 1 => The input string is a pure integer ** 2 or more => The input has a decimal point or eNNN clause ** 0 or less => The input string is not a valid number -** -1 => Not a valid number, but has a valid prefix which +** -1 => Not a valid number, but has a valid prefix which ** includes a decimal point and/or an eNNN clause ** ** Valid numbers are in one of these formats: @@ -463,12 +481,11 @@ const char *zEnd; /* sign * significand * (10 ^ (esign * exponent)) */ int sign = 1; /* sign of significand */ - i64 s = 0; /* significand */ + u64 s = 0; /* significand */ int d = 0; /* adjust exponent for shifting decimal point */ int esign = 1; /* sign of exponent */ int e = 0; /* exponent */ int eValid = 1; /* True exponent is either not used or is well-formed */ - double result; int nDigit = 0; /* Number of digits processed */ int eType = 1; /* 1: pure integer, 2+: fractional -1 or less: bad UTF16 */ @@ -508,7 +525,7 @@ while( z=((LARGEST_INT64-9)/10) ){ + if( s>=((LARGEST_UINT64-9)/10) ){ /* skip non-significant significand digits ** (increase exponent by d to shift decimal left) */ while( z=zEnd ) goto do_atof_calc; /*PREVENTS-HARMLESS-OVERREAD*/ @@ -563,79 +580,89 @@ while( z0 ){ /*OPTIMIZATION-IF-TRUE*/ - if( esign>0 ){ - if( s>=(LARGEST_INT64/10) ) break; /*OPTIMIZATION-IF-FALSE*/ - s *= 10; - }else{ - if( s%10!=0 ) break; /*OPTIMIZATION-IF-FALSE*/ - s /= 10; - } - e--; - } - - /* adjust the sign of significand */ - s = sign<0 ? -s : s; + /* adjust exponent by d, and update sign */ + e = (e*esign) + d; - if( e==0 ){ /*OPTIMIZATION-IF-TRUE*/ - result = (double)s; + /* Try to adjust the exponent to make it smaller */ + while( e>0 && s<(LARGEST_UINT64/10) ){ + s *= 10; + e--; + } + while( e<0 && (s%10)==0 ){ + s /= 10; + e++; + } + + if( e==0 ){ + *pResult = s; + }else if( sqlite3Config.bUseLongDouble ){ + LONGDOUBLE_TYPE r = (LONGDOUBLE_TYPE)s; + if( e>0 ){ + while( e>=100 ){ e-=100; r *= 1.0e+100L; } + while( e>=10 ){ e-=10; r *= 1.0e+10L; } + while( e>=1 ){ e-=1; r *= 1.0e+01L; } }else{ - /* attempt to handle extremely small/large numbers better */ - if( e>307 ){ /*OPTIMIZATION-IF-TRUE*/ - if( e<342 ){ /*OPTIMIZATION-IF-TRUE*/ - LONGDOUBLE_TYPE scale = sqlite3Pow10(e-308); - if( esign<0 ){ - result = s / scale; - result /= 1.0e+308; - }else{ - result = s * scale; - result *= 1.0e+308; - } - }else{ assert( e>=342 ); - if( esign<0 ){ - result = 0.0*s; - }else{ + while( e<=-100 ){ e+=100; r *= 1.0e-100L; } + while( e<=-10 ){ e+=10; r *= 1.0e-10L; } + while( e<=-1 ){ e+=1; r *= 1.0e-01L; } + } + assert( r>=0.0 ); + if( r>+1.7976931348623157081452742373e+308L ){ #ifdef INFINITY - result = INFINITY*s; + *pResult = +INFINITY; #else - result = 1e308*1e308*s; /* Infinity */ + *pResult = 1.0e308*10.0; #endif - } - } - }else{ - LONGDOUBLE_TYPE scale = sqlite3Pow10(e); - if( esign<0 ){ - result = s / scale; - }else{ - result = s * scale; - } + }else{ + *pResult = (double)r; + } + }else{ + double rr[2]; + u64 s2; + rr[0] = (double)s; + s2 = (u64)rr[0]; + rr[1] = s>=s2 ? (double)(s - s2) : -(double)(s2 - s); + if( e>0 ){ + while( e>=100 ){ + e -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( e>=10 ){ + e -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( e>=1 ){ + e -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); + } + }else{ + while( e<=-100 ){ + e += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( e<=-10 ){ + e += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( e<=-1 ){ + e += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); } } + *pResult = rr[0]+rr[1]; + if( sqlite3IsNaN(*pResult) ) *pResult = 1e300*1e300; } + if( sign<0 ) *pResult = -*pResult; + assert( !sqlite3IsNaN(*pResult) ); - /* store the result */ - *pResult = result; - - /* return true if number and no extra non-whitespace chracters after */ +atof_return: + /* 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 ){ @@ -771,7 +798,7 @@ /* This test and assignment is needed only to suppress UB warnings ** from clang and -fsanitize=undefined. This test and assignment make ** the code a little larger and slower, and no harm comes from omitting - ** them, but we must appaise the undefined-behavior pharisees. */ + ** them, but we must appease the undefined-behavior pharisees. */ *pNum = neg ? SMALLEST_INT64 : LARGEST_INT64; }else if( neg ){ *pNum = -(i64)u; @@ -849,7 +876,9 @@ }else #endif /* SQLITE_OMIT_HEX_INTEGER */ { - return sqlite3Atoi64(z, pOut, sqlite3Strlen30(z), SQLITE_UTF8); + int n = (int)(0x3fffffff&strspn(z,"+- \n\t0123456789")); + if( z[n] ) n++; + return sqlite3Atoi64(z, pOut, n, SQLITE_UTF8); } } @@ -929,6 +958,153 @@ } /* +** Decode a floating-point value into an approximate decimal +** representation. +** +** Round the decimal representation to n significant digits if +** n is positive. Or round to -n signficant digits after the +** decimal point if n is negative. No rounding is performed if +** n is zero. +** +** The significant digits of the decimal representation are +** stored in p->z[] which is a often (but not always) a pointer +** into the middle of p->zBuf[]. There are p->n significant digits. +** The p->z[] array is *not* zero-terminated. +*/ +void sqlite3FpDecode(FpDecode *p, double r, int iRound, int mxRound){ + int i; + u64 v; + int e, exp = 0; + p->isSpecial = 0; + p->z = p->zBuf; + + /* Convert negative numbers to positive. Deal with Infinity, 0.0, and + ** NaN. */ + if( r<0.0 ){ + p->sign = '-'; + r = -r; + }else if( r==0.0 ){ + p->sign = '+'; + p->n = 1; + p->iDP = 1; + p->z = "0"; + return; + }else{ + p->sign = '+'; + } + memcpy(&v,&r,8); + e = v>>52; + if( (e&0x7ff)==0x7ff ){ + p->isSpecial = 1 + (v!=0x7ff0000000000000LL); + p->n = 0; + p->iDP = 0; + return; + } + + /* Multiply r by powers of ten until it lands somewhere in between + ** 1.0e+19 and 1.0e+17. + */ + if( sqlite3Config.bUseLongDouble ){ + LONGDOUBLE_TYPE rr = r; + if( rr>=1.0e+19 ){ + while( rr>=1.0e+119L ){ exp+=100; rr *= 1.0e-100L; } + while( rr>=1.0e+29L ){ exp+=10; rr *= 1.0e-10L; } + while( rr>=1.0e+19L ){ exp++; rr *= 1.0e-1L; } + }else{ + while( rr<1.0e-97L ){ exp-=100; rr *= 1.0e+100L; } + while( rr<1.0e+07L ){ exp-=10; rr *= 1.0e+10L; } + while( rr<1.0e+17L ){ exp--; rr *= 1.0e+1L; } + } + v = (u64)rr; + }else{ + /* If high-precision floating point is not available using "long double", + ** then use Dekker-style double-double computation to increase the + ** precision. + ** + ** The error terms on constants like 1.0e+100 computed using the + ** decimal extension, for example as follows: + ** + ** SELECT decimal_exp(decimal_sub('1.0e+100',decimal(1.0e+100))); + */ + double rr[2]; + rr[0] = r; + rr[1] = 0.0; + if( rr[0]>9.223372036854774784e+18 ){ + while( rr[0]>9.223372036854774784e+118 ){ + exp += 100; + dekkerMul2(rr, 1.0e-100, -1.99918998026028836196e-117); + } + while( rr[0]>9.223372036854774784e+28 ){ + exp += 10; + dekkerMul2(rr, 1.0e-10, -3.6432197315497741579e-27); + } + while( rr[0]>9.223372036854774784e+18 ){ + exp += 1; + dekkerMul2(rr, 1.0e-01, -5.5511151231257827021e-18); + } + }else{ + while( rr[0]<9.223372036854774784e-83 ){ + exp -= 100; + dekkerMul2(rr, 1.0e+100, -1.5902891109759918046e+83); + } + while( rr[0]<9.223372036854774784e+07 ){ + exp -= 10; + dekkerMul2(rr, 1.0e+10, 0.0); + } + while( rr[0]<9.22337203685477478e+17 ){ + exp -= 1; + dekkerMul2(rr, 1.0e+01, 0.0); + } + } + v = rr[1]<0.0 ? (u64)rr[0]-(u64)(-rr[1]) : (u64)rr[0]+(u64)rr[1]; + } + + + /* Extract significant digits. */ + i = sizeof(p->zBuf)-1; + assert( v>0 ); + while( v ){ p->zBuf[i--] = (v%10) + '0'; v /= 10; } + assert( i>=0 && izBuf)-1 ); + p->n = sizeof(p->zBuf) - 1 - i; + assert( p->n>0 ); + assert( p->nzBuf) ); + p->iDP = p->n + exp; + if( iRound<0 ){ + iRound = p->iDP - iRound; + if( iRound==0 && p->zBuf[i+1]>='5' ){ + iRound = 1; + p->zBuf[i--] = '0'; + p->n++; + p->iDP++; + } + } + if( iRound>0 && (iRoundn || p->n>mxRound) ){ + char *z = &p->zBuf[i+1]; + if( iRound>mxRound ) iRound = mxRound; + p->n = iRound; + if( z[iRound]>='5' ){ + int j = iRound-1; + while( 1 /*exit-by-break*/ ){ + z[j]++; + if( z[j]<='9' ) break; + z[j] = '0'; + if( j==0 ){ + p->z[i--] = '1'; + p->n++; + p->iDP++; + break; + }else{ + j--; + } + } + } + } + p->z = &p->zBuf[i+1]; + assert( i+p->n < sizeof(p->zBuf) ); + while( ALWAYS(p->n>0) && p->z[p->n-1]=='0' ){ p->n--; } +} + +/* ** Try to convert z into an unsigned 32-bit integer. Return true on ** success and false if there is an error. ** @@ -986,7 +1162,7 @@ v >>= 7; } return 9; - } + } n = 0; do{ buf[n++] = (u8)((v & 0x7f) | 0x80); @@ -1186,126 +1362,37 @@ ** If the varint stored in p[0] is larger than can fit in a 32-bit unsigned ** integer, then set *v to 0xffffffff. ** -** A MACRO version, getVarint32, is provided which inlines the -** single-byte case. All code should use the MACRO version as +** A MACRO version, getVarint32, is provided which inlines the +** single-byte case. All code should use the MACRO version as ** this function assumes the single-byte case has already been handled. */ u8 sqlite3GetVarint32(const unsigned char *p, u32 *v){ - u32 a,b; + u64 v64; + u8 n; - /* The 1-byte case. Overwhelmingly the most common. Handled inline - ** by the getVarin32() macro */ - a = *p; - /* a: p0 (unmasked) */ -#ifndef getVarint32 - if (!(a&0x80)) - { - /* Values between 0 and 127 */ - *v = a; - return 1; - } -#endif - - /* The 2-byte case */ - p++; - b = *p; - /* b: p1 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 128 and 16383 */ - a &= 0x7f; - a = a<<7; - *v = a | b; + /* Assume that the single-byte case has already been handled by + ** the getVarint32() macro */ + assert( (p[0] & 0x80)!=0 ); + + if( (p[1] & 0x80)==0 ){ + /* This is the two-byte case */ + *v = ((p[0]&0x7f)<<7) | p[1]; return 2; } - - /* The 3-byte case */ - p++; - a = a<<14; - a |= *p; - /* a: p0<<14 | p2 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 16384 and 2097151 */ - a &= (0x7f<<14)|(0x7f); - b &= 0x7f; - b = b<<7; - *v = a | b; + if( (p[2] & 0x80)==0 ){ + /* This is the three-byte case */ + *v = ((p[0]&0x7f)<<14) | ((p[1]&0x7f)<<7) | p[2]; return 3; } - - /* A 32-bit varint is used to store size information in btrees. - ** Objects are rarely larger than 2MiB limit of a 3-byte varint. - ** A 3-byte varint is sufficient, for example, to record the size - ** of a 1048569-byte BLOB or string. - ** - ** We only unroll the first 1-, 2-, and 3- byte cases. The very - ** rare larger cases can be handled by the slower 64-bit varint - ** routine. - */ -#if 1 - { - u64 v64; - u8 n; - - n = sqlite3GetVarint(p-2, &v64); - assert( n>3 && n<=9 ); - if( (v64 & SQLITE_MAX_U32)!=v64 ){ - *v = 0xffffffff; - }else{ - *v = (u32)v64; - } - return n; - } - -#else - /* For following code (kept for historical record only) shows an - ** unrolling for the 3- and 4-byte varint cases. This code is - ** slightly faster, but it is also larger and much harder to test. - */ - p++; - b = b<<14; - b |= *p; - /* b: p1<<14 | p3 (unmasked) */ - if (!(b&0x80)) - { - /* Values between 2097152 and 268435455 */ - b &= (0x7f<<14)|(0x7f); - a &= (0x7f<<14)|(0x7f); - a = a<<7; - *v = a | b; - return 4; - } - - p++; - a = a<<14; - a |= *p; - /* a: p0<<28 | p2<<14 | p4 (unmasked) */ - if (!(a&0x80)) - { - /* Values between 268435456 and 34359738367 */ - a &= SLOT_4_2_0; - b &= SLOT_4_2_0; - b = b<<7; - *v = a | b; - return 5; - } - - /* We can only reach this point when reading a corrupt database - ** file. In that case we are not in any hurry. Use the (relatively - ** slow) general-purpose sqlite3GetVarint() routine to extract the - ** value. */ - { - u64 v64; - u8 n; - - p -= 4; - n = sqlite3GetVarint(p, &v64); - assert( n>5 && n<=9 ); + /* four or more bytes */ + n = sqlite3GetVarint(p, &v64); + assert( n>3 && n<=9 ); + if( (v64 & SQLITE_MAX_U32)!=v64 ){ + *v = 0xffffffff; + }else{ *v = (u32)v64; - return n; } -#endif + return n; } /* @@ -1404,7 +1491,7 @@ ** argument. The zType is a word like "NULL" or "closed" or "invalid". */ static void logBadConnection(const char *zType){ - sqlite3_log(SQLITE_MISUSE, + sqlite3_log(SQLITE_MISUSE, "API call with %s database connection pointer", zType ); @@ -1456,7 +1543,7 @@ } /* -** Attempt to add, substract, or multiply the 64-bit signed value iB against +** Attempt to add, subtract, or multiply the 64-bit signed value iB against ** the other 64-bit signed integer at *pA and store the result in *pA. ** Return 0 on success. Or if the operation would have resulted in an ** overflow, leave *pA unchanged and return 1. @@ -1478,7 +1565,7 @@ if( iA<0 && -(iA + LARGEST_INT64) > iB + 1 ) return 1; } *pA += iB; - return 0; + return 0; #endif } int sqlite3SubInt64(i64 *pA, i64 iB){ @@ -1519,7 +1606,7 @@ } /* -** Compute the absolute value of a 32-bit signed integer, of possible. Or +** Compute the absolute value of a 32-bit signed integer, of possible. Or ** if the integer has a value of -2147483648, return +2147483647 */ int sqlite3AbsInt32(int x){ @@ -1559,11 +1646,11 @@ } #endif -/* +/* ** Find (an approximate) sum of two LogEst values. This computation is ** not a simple "+" operator because LogEst is stored as a logarithmic ** value. -** +** */ LogEst sqlite3LogEstAdd(LogEst a, LogEst b){ static const unsigned char x[] = { @@ -1661,8 +1748,8 @@ ** Conceptually: ** ** struct VList { -** int nAlloc; // Number of allocated slots -** int nUsed; // Number of used slots +** int nAlloc; // Number of allocated slots +** int nUsed; // Number of used slots ** struct VListEntry { ** int iValue; // Value for this entry ** int nSlot; // Slots used by this entry @@ -1671,7 +1758,7 @@ ** } ** ** During code generation, pointers to the variable names within the -** VList are taken. When that happens, nAlloc is set to zero as an +** VList are taken. When that happens, nAlloc is set to zero as an ** indication that the VList may never again be enlarged, since the ** accompanying realloc() would invalidate the pointers. */ @@ -1747,6 +1834,6 @@ */ #if defined(VDBE_PROFILE) \ || defined(SQLITE_PERFORMANCE_TRACE) \ - || defined(SQLITE_ENABLE_STMT_SCANSTATUS) + || defined(SQLITE_ENABLE_STMT_SCANSTATUS) # include "hwtime.h" #endif diff -Nru sqlite3-3.42.0/src/vacuum.c sqlite3-3.44.0-0/src/vacuum.c --- sqlite3-3.42.0/src/vacuum.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vacuum.c 2023-11-04 14:23:58.000000000 +0000 @@ -208,7 +208,7 @@ ** (possibly synchronous) transaction opened on the main database before ** sqlite3BtreeCopyFile() is called. ** - ** An optimisation would be to use a non-journaled pager. + ** An optimization would be to use a non-journaled pager. ** (Later:) I tried setting "PRAGMA vacuum_db.journal_mode=OFF" but ** that actually made the VACUUM run slower. Very little journalling ** actually occurs when doing a vacuum since the vacuum_db is initially diff -Nru sqlite3-3.42.0/src/vdbeapi.c sqlite3-3.44.0-0/src/vdbeapi.c --- sqlite3-3.42.0/src/vdbeapi.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbeapi.c 2023-11-04 14:23:58.000000000 +0000 @@ -364,7 +364,7 @@ void sqlite3_value_free(sqlite3_value *pOld){ sqlite3ValueFree(pOld); } - + /**************************** sqlite3_result_ ******************************* ** The following routines are used by user-defined functions to specify @@ -375,7 +375,7 @@ ** is too big or if an OOM occurs. ** ** The invokeValueDestructor(P,X) routine invokes destructor function X() -** on value P is not going to be used and need to be destroyed. +** on value P if P is not going to be used and need to be destroyed. */ static void setResultStrOrError( sqlite3_context *pCtx, /* Function context */ @@ -405,7 +405,7 @@ static int invokeValueDestructor( const void *p, /* Value to destroy */ void (*xDel)(void*), /* The destructor */ - sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if no NULL */ + sqlite3_context *pCtx /* Set a SQLITE_TOOBIG error if not NULL */ ){ assert( xDel!=SQLITE_DYNAMIC ); if( xDel==0 ){ @@ -415,27 +415,46 @@ }else{ xDel((void*)p); } +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx!=0 ){ + sqlite3_result_error_toobig(pCtx); + } +#else + assert( pCtx!=0 ); sqlite3_result_error_toobig(pCtx); +#endif return SQLITE_TOOBIG; } void sqlite3_result_blob( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 || n<0 ){ + invokeValueDestructor(z, xDel, pCtx); + return; + } +#endif assert( n>=0 ); assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, 0, xDel); } void sqlite3_result_blob64( - sqlite3_context *pCtx, - const void *z, + sqlite3_context *pCtx, + const void *z, sqlite3_uint64 n, void (*xDel)(void *) ){ - assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif + assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( n>0x7fffffff ){ (void)invokeValueDestructor(z, xDel, pCtx); }else{ @@ -443,30 +462,48 @@ } } void sqlite3_result_double(sqlite3_context *pCtx, double rVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetDouble(pCtx->pOut, rVal); } void sqlite3_result_error(sqlite3_context *pCtx, const char *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF8, SQLITE_TRANSIENT); } #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_error16(sqlite3_context *pCtx, const void *z, int n){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_ERROR; sqlite3VdbeMemSetStr(pCtx->pOut, z, n, SQLITE_UTF16NATIVE, SQLITE_TRANSIENT); } #endif void sqlite3_result_int(sqlite3_context *pCtx, int iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, (i64)iVal); } void sqlite3_result_int64(sqlite3_context *pCtx, i64 iVal){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetInt64(pCtx->pOut, iVal); } void sqlite3_result_null(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); } @@ -476,34 +513,57 @@ const char *zPType, void (*xDestructor)(void*) ){ - Mem *pOut = pCtx->pOut; + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(pPtr, xDestructor, 0); + return; + } +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); sqlite3VdbeMemRelease(pOut); pOut->flags = MEM_Null; sqlite3VdbeMemSetPointer(pOut, pPtr, zPType, xDestructor); } void sqlite3_result_subtype(sqlite3_context *pCtx, unsigned int eSubtype){ - Mem *pOut = pCtx->pOut; + Mem *pOut; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); pOut->eSubtype = eSubtype & 0xff; pOut->flags |= MEM_Subtype; } void sqlite3_result_text( - sqlite3_context *pCtx, - const char *z, + sqlite3_context *pCtx, + const char *z, int n, void (*xDel)(void *) ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n, SQLITE_UTF8, xDel); } void sqlite3_result_text64( - sqlite3_context *pCtx, - const char *z, + sqlite3_context *pCtx, + const char *z, sqlite3_uint64 n, void (*xDel)(void *), unsigned char enc ){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ){ + invokeValueDestructor(z, xDel, 0); + return; + } +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); assert( xDel!=SQLITE_DYNAMIC ); if( enc!=SQLITE_UTF8 ){ @@ -514,31 +574,32 @@ (void)invokeValueDestructor(z, xDel, pCtx); }else{ setResultStrOrError(pCtx, z, (int)n, enc, xDel); + sqlite3VdbeMemZeroTerminateIfAble(pCtx->pOut); } } #ifndef SQLITE_OMIT_UTF16 void sqlite3_result_text16( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16NATIVE, xDel); } void sqlite3_result_text16be( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); setResultStrOrError(pCtx, z, n & ~(u64)1, SQLITE_UTF16BE, xDel); } void sqlite3_result_text16le( - sqlite3_context *pCtx, - const void *z, - int n, + sqlite3_context *pCtx, + const void *z, + int n, void (*xDel)(void *) ){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); @@ -546,7 +607,16 @@ } #endif /* SQLITE_OMIT_UTF16 */ void sqlite3_result_value(sqlite3_context *pCtx, sqlite3_value *pValue){ - Mem *pOut = pCtx->pOut; + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; + if( pValue==0 ){ + sqlite3_result_null(pCtx); + return; + } +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemCopy(pOut, pValue); sqlite3VdbeChangeEncoding(pOut, pCtx->enc); @@ -558,7 +628,12 @@ sqlite3_result_zeroblob64(pCtx, n>0 ? n : 0); } int sqlite3_result_zeroblob64(sqlite3_context *pCtx, u64 n){ - Mem *pOut = pCtx->pOut; + Mem *pOut; + +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return SQLITE_MISUSE_BKPT; +#endif + pOut = pCtx->pOut; assert( sqlite3_mutex_held(pOut->db->mutex) ); if( n>(u64)pOut->db->aLimit[SQLITE_LIMIT_LENGTH] ){ sqlite3_result_error_toobig(pCtx); @@ -572,6 +647,9 @@ #endif } void sqlite3_result_error_code(sqlite3_context *pCtx, int errCode){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif pCtx->isError = errCode ? errCode : -1; #ifdef SQLITE_DEBUG if( pCtx->pVdbe ) pCtx->pVdbe->rcApp = errCode; @@ -584,14 +662,20 @@ /* Force an SQLITE_TOOBIG error. */ void sqlite3_result_error_toobig(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); pCtx->isError = SQLITE_TOOBIG; - sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, + sqlite3VdbeMemSetStr(pCtx->pOut, "string or blob too big", -1, SQLITE_UTF8, SQLITE_STATIC); } /* An SQLITE_NOMEM error. */ void sqlite3_result_error_nomem(sqlite3_context *pCtx){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); sqlite3VdbeMemSetNull(pCtx->pOut); pCtx->isError = SQLITE_NOMEM_BKPT; @@ -603,7 +687,7 @@ ** a MEM_IntReal value. See the SQLITE_TESTCTRL_RESULT_INTREAL ** test-control. */ -void sqlite3ResultIntReal(sqlite3_context *pCtx){ +void sqlite3ResultIntReal(sqlite3_context *pCtx){ assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); if( pCtx->pOut->flags & MEM_Int ){ pCtx->pOut->flags &= ~MEM_Int; @@ -614,7 +698,7 @@ /* -** This function is called after a transaction has been committed. It +** This function is called after a transaction has been committed. It ** invokes callbacks registered with sqlite3_wal_hook() as required. */ static int doWalCallbacks(sqlite3 *db){ @@ -643,7 +727,7 @@ ** statement is completely executed or an error occurs. ** ** This routine implements the bulk of the logic behind the sqlite_step() -** API. The only thing omitted is the automatic recompile if a +** API. The only thing omitted is the automatic recompile if a ** schema change has occurred. That detail is handled by the ** outer sqlite3_step() wrapper procedure. */ @@ -660,11 +744,11 @@ p->rc = SQLITE_SCHEMA; rc = SQLITE_ERROR; if( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ - /* If this statement was prepared using saved SQL and an + /* If this statement was prepared using saved SQL and an ** error has occurred, then return the error code in p->rc to the ** caller. Set the error code in the database handle to the same ** value. - */ + */ rc = sqlite3VdbeTransferError(p); } goto end_of_step; @@ -678,7 +762,7 @@ AtomicStore(&db->u1.isInterrupted, 0); } - assert( db->nVdbeWrite>0 || db->autoCommit==0 + assert( db->nVdbeWrite>0 || db->autoCommit==0 || (db->nDeferredCons==0 && db->nDeferredImmCons==0) ); @@ -703,15 +787,15 @@ ** sqlite3_step() after any error or after SQLITE_DONE. But beginning ** with version 3.7.0, we changed this so that sqlite3_reset() would ** be called automatically instead of throwing the SQLITE_MISUSE error. - ** This "automatic-reset" change is not technically an incompatibility, + ** This "automatic-reset" change is not technically an incompatibility, ** since any application that receives an SQLITE_MISUSE is broken by ** definition. ** ** Nevertheless, some published applications that were originally written - ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE + ** for version 3.6.23 or earlier do in fact depend on SQLITE_MISUSE ** returns, and those were broken by the automatic-reset change. As a ** a work-around, the SQLITE_OMIT_AUTORESET compile-time restores the - ** legacy behavior of returning SQLITE_MISUSE for cases where the + ** legacy behavior of returning SQLITE_MISUSE for cases where the ** previous sqlite3_step() returned something other than a SQLITE_LOCKED ** or SQLITE_BUSY error. */ @@ -761,10 +845,10 @@ rc = SQLITE_ERROR; } }else if( rc!=SQLITE_DONE && (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 ){ - /* If this statement was prepared using saved SQL and an + /* If this statement was prepared using saved SQL and an ** error has occurred, then return the error code in p->rc to the ** caller. Set the error code in the database handle to the same value. - */ + */ rc = sqlite3VdbeTransferError(p); } } @@ -778,7 +862,7 @@ /* There are only a limited number of result codes allowed from the ** statements prepared using the legacy sqlite3_prepare() interface */ assert( (p->prepFlags & SQLITE_PREPARE_SAVESQL)!=0 - || rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR + || rc==SQLITE_ROW || rc==SQLITE_DONE || rc==SQLITE_ERROR || (rc&0xff)==SQLITE_BUSY || rc==SQLITE_MISUSE ); return (rc&db->errMask); @@ -805,15 +889,15 @@ int savedPc = v->pc; rc = sqlite3Reprepare(v); if( rc!=SQLITE_OK ){ - /* This case occurs after failing to recompile an sql statement. - ** The error message from the SQL compiler has already been loaded - ** into the database handle. This block copies the error message + /* This case occurs after failing to recompile an sql statement. + ** The error message from the SQL compiler has already been loaded + ** into the database handle. This block copies the error message ** from the database handle into the statement and sets the statement - ** program counter to 0 to ensure that when the statement is + ** program counter to 0 to ensure that when the statement is ** finalized or reset the parser error message is available via ** sqlite3_errmsg() and sqlite3_errcode(). */ - const char *zErr = (const char *)sqlite3_value_text(db->pErr); + const char *zErr = (const char *)sqlite3_value_text(db->pErr); sqlite3DbFree(db, v->zErrMsg); if( !db->mallocFailed ){ v->zErrMsg = sqlite3DbStrDup(db, zErr); @@ -844,7 +928,11 @@ ** pointer to it. */ void *sqlite3_user_data(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p && p->pFunc ); +#endif return p->pFunc->pUserData; } @@ -859,7 +947,11 @@ ** application defined function. */ sqlite3 *sqlite3_context_db_handle(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p && p->pOut ); +#endif return p->pOut->db; } @@ -878,7 +970,11 @@ ** value, as a signal to the xUpdate routine that the column is unchanged. */ int sqlite3_vtab_nochange(sqlite3_context *p){ +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return 0; +#else assert( p ); +#endif return sqlite3_value_nochange(p->pOut); } @@ -886,7 +982,7 @@ ** The destructor function for a ValueList object. This needs to be ** a separate function, unknowable to the application, to ensure that ** calls to sqlite3_vtab_in_first()/sqlite3_vtab_in_next() that are not -** preceeded by activation of IN processing via sqlite3_vtab_int() do not +** preceded by activation of IN processing via sqlite3_vtab_int() do not ** try to access a fake ValueList object inserted by a hostile extension. */ void sqlite3VdbeValueListFree(void *pToDelete){ @@ -906,7 +1002,7 @@ ValueList *pRhs; *ppOut = 0; - if( pVal==0 ) return SQLITE_MISUSE; + if( pVal==0 ) return SQLITE_MISUSE_BKPT; if( (pVal->flags & MEM_Dyn)==0 || pVal->xDel!=sqlite3VdbeValueListFree ){ return SQLITE_ERROR; }else{ @@ -1037,6 +1133,9 @@ void *sqlite3_get_auxdata(sqlite3_context *pCtx, int iArg){ AuxData *pAuxData; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return 0; +#endif assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #if SQLITE_ENABLE_STAT4 if( pCtx->pVdbe==0 ) return 0; @@ -1063,14 +1162,18 @@ ** access code. */ void sqlite3_set_auxdata( - sqlite3_context *pCtx, - int iArg, - void *pAux, + sqlite3_context *pCtx, + int iArg, + void *pAux, void (*xDelete)(void*) ){ AuxData *pAuxData; - Vdbe *pVdbe = pCtx->pVdbe; + Vdbe *pVdbe; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pCtx==0 ) return; +#endif + pVdbe= pCtx->pVdbe; assert( sqlite3_mutex_held(pCtx->pOut->db->mutex) ); #ifdef SQLITE_ENABLE_STAT4 if( pVdbe==0 ) goto failed; @@ -1107,7 +1210,7 @@ #ifndef SQLITE_OMIT_DEPRECATED /* -** Return the number of times the Step function of an aggregate has been +** Return the number of times the Step function of an aggregate has been ** called. ** ** This function is deprecated. Do not use it for new code. It is @@ -1126,7 +1229,8 @@ */ int sqlite3_column_count(sqlite3_stmt *pStmt){ Vdbe *pVm = (Vdbe *)pStmt; - return pVm ? pVm->nResColumn : 0; + if( pVm==0 ) return 0; + return pVm->nResColumn; } /* @@ -1152,9 +1256,9 @@ ** these assert()s from failing, when building with SQLITE_DEBUG defined ** using gcc, we force nullMem to be 8-byte aligned using the magical ** __attribute__((aligned(8))) macro. */ - static const Mem nullMem + static const Mem nullMem #if defined(SQLITE_DEBUG) && defined(__GNUC__) - __attribute__((aligned(8))) + __attribute__((aligned(8))) #endif = { /* .u = */ {0}, @@ -1200,9 +1304,9 @@ } /* -** This function is called after invoking an sqlite3_value_XXX function on a +** This function is called after invoking an sqlite3_value_XXX function on a ** column value (i.e. a value returned by evaluating an SQL expression in the -** select list of a SELECT statement) that may cause a malloc() failure. If +** select list of a SELECT statement) that may cause a malloc() failure. If ** malloc() has failed, the threads mallocFailed flag is cleared and the result ** code of statement pStmt set to SQLITE_NOMEM. ** @@ -1215,7 +1319,7 @@ ** sqlite3_column_real() ** sqlite3_column_bytes() ** sqlite3_column_bytes16() -** sqiite3_column_blob() +** sqlite3_column_blob() */ static void columnMallocFailure(sqlite3_stmt *pStmt) { @@ -1241,8 +1345,8 @@ const void *val; val = sqlite3_value_blob( columnMem(pStmt,i) ); /* Even though there is no encoding conversion, value_blob() might - ** need to call malloc() to expand the result of a zeroblob() - ** expression. + ** need to call malloc() to expand the result of a zeroblob() + ** expression. */ columnMallocFailure(pStmt); return val; @@ -1300,6 +1404,32 @@ } /* +** Column names appropriate for EXPLAIN or EXPLAIN QUERY PLAN. +*/ +static const char * const azExplainColNames8[] = { + "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", /* EXPLAIN */ + "id", "parent", "notused", "detail" /* EQP */ +}; +static const u16 azExplainColNames16data[] = { + /* 0 */ 'a', 'd', 'd', 'r', 0, + /* 5 */ 'o', 'p', 'c', 'o', 'd', 'e', 0, + /* 12 */ 'p', '1', 0, + /* 15 */ 'p', '2', 0, + /* 18 */ 'p', '3', 0, + /* 21 */ 'p', '4', 0, + /* 24 */ 'p', '5', 0, + /* 27 */ 'c', 'o', 'm', 'm', 'e', 'n', 't', 0, + /* 35 */ 'i', 'd', 0, + /* 38 */ 'p', 'a', 'r', 'e', 'n', 't', 0, + /* 45 */ 'n', 'o', 't', 'u', 's', 'e', 'd', 0, + /* 53 */ 'd', 'e', 't', 'a', 'i', 'l', 0 +}; +static const u8 iExplainColNames16[] = { + 0, 5, 12, 15, 18, 21, 24, 27, + 35, 38, 45, 53 +}; + +/* ** Convert the N-th element of pStmt->pColName[] into a string using ** xFunc() then return that string. If N is out of range, return 0. ** @@ -1331,15 +1461,29 @@ return 0; } #endif + if( N<0 ) return 0; ret = 0; p = (Vdbe *)pStmt; db = p->db; assert( db!=0 ); - n = sqlite3_column_count(pStmt); - if( N=0 ){ + sqlite3_mutex_enter(db->mutex); + + if( p->explain ){ + if( useType>0 ) goto columnName_end; + n = p->explain==1 ? 8 : 4; + if( N>=n ) goto columnName_end; + if( useUtf16 ){ + int i = iExplainColNames16[N + 8*p->explain - 8]; + ret = (void*)&azExplainColNames16data[i]; + }else{ + ret = (void*)azExplainColNames8[N + 8*p->explain - 8]; + } + goto columnName_end; + } + n = p->nResColumn; + if( NmallocFailed; N += useType*n; - sqlite3_mutex_enter(db->mutex); #ifndef SQLITE_OMIT_UTF16 if( useUtf16 ){ ret = sqlite3_value_text16((sqlite3_value*)&p->aColName[N]); @@ -1356,8 +1500,9 @@ sqlite3OomClear(db); ret = 0; } - sqlite3_mutex_leave(db->mutex); } +columnName_end: + sqlite3_mutex_leave(db->mutex); return ret; } @@ -1444,13 +1589,13 @@ /******************************* 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 +** 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. Othewise SQLITE_OK. +** 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. @@ -1465,9 +1610,9 @@ } sqlite3_mutex_enter(p->db->mutex); if( p->eVdbeState!=VDBE_READY_STATE ){ - sqlite3Error(p->db, SQLITE_MISUSE); + sqlite3Error(p->db, SQLITE_MISUSE_BKPT); sqlite3_mutex_leave(p->db->mutex); - sqlite3_log(SQLITE_MISUSE, + sqlite3_log(SQLITE_MISUSE, "bind on a busy prepared statement: [%s]", p->zSql); return SQLITE_MISUSE_BKPT; } @@ -1481,7 +1626,7 @@ pVar->flags = MEM_Null; p->db->errCode = SQLITE_OK; - /* If the bit corresponding to this variable in Vdbe.expmask is set, then + /* If the bit corresponding to this variable in Vdbe.expmask is set, then ** binding a new value to this variable invalidates the current query plan. ** ** IMPLEMENTATION-OF: R-57496-20354 If the specific value bound to a host @@ -1537,10 +1682,10 @@ ** Bind a blob value to an SQL statement variable. */ int sqlite3_bind_blob( - sqlite3_stmt *pStmt, - int i, - const void *zData, - int nData, + sqlite3_stmt *pStmt, + int i, + const void *zData, + int nData, void (*xDel)(void*) ){ #ifdef SQLITE_ENABLE_API_ARMOR @@ -1549,10 +1694,10 @@ return bindText(pStmt, i, zData, nData, xDel, 0); } int sqlite3_bind_blob64( - sqlite3_stmt *pStmt, - int i, - const void *zData, - sqlite3_uint64 nData, + sqlite3_stmt *pStmt, + int i, + const void *zData, + sqlite3_uint64 nData, void (*xDel)(void*) ){ assert( xDel!=SQLITE_DYNAMIC ); @@ -1608,20 +1753,20 @@ } return rc; } -int sqlite3_bind_text( - sqlite3_stmt *pStmt, - int i, - const char *zData, - int nData, +int sqlite3_bind_text( + sqlite3_stmt *pStmt, + int i, + const char *zData, + int nData, void (*xDel)(void*) ){ return bindText(pStmt, i, zData, nData, xDel, SQLITE_UTF8); } -int sqlite3_bind_text64( - sqlite3_stmt *pStmt, - int i, - const char *zData, - sqlite3_uint64 nData, +int sqlite3_bind_text64( + sqlite3_stmt *pStmt, + int i, + const char *zData, + sqlite3_uint64 nData, void (*xDel)(void*), unsigned char enc ){ @@ -1634,10 +1779,10 @@ } #ifndef SQLITE_OMIT_UTF16 int sqlite3_bind_text16( - sqlite3_stmt *pStmt, - int i, - const void *zData, - int n, + sqlite3_stmt *pStmt, + int i, + const void *zData, + int n, void (*xDel)(void*) ){ return bindText(pStmt, i, zData, n & ~(u64)1, xDel, SQLITE_UTF16NATIVE); @@ -1652,7 +1797,7 @@ } case SQLITE_FLOAT: { assert( pValue->flags & (MEM_Real|MEM_IntReal) ); - rc = sqlite3_bind_double(pStmt, i, + rc = sqlite3_bind_double(pStmt, i, (pValue->flags & MEM_Real) ? pValue->u.r : (double)pValue->u.i ); break; @@ -1694,6 +1839,9 @@ int sqlite3_bind_zeroblob64(sqlite3_stmt *pStmt, int i, sqlite3_uint64 n){ int rc; Vdbe *p = (Vdbe *)pStmt; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 ) return SQLITE_MISUSE_BKPT; +#endif sqlite3_mutex_enter(p->db->mutex); if( n>(u64)p->db->aLimit[SQLITE_LIMIT_LENGTH] ){ rc = SQLITE_TOOBIG; @@ -1708,7 +1856,7 @@ /* ** Return the number of wildcards that can be potentially bound to. -** This routine is added to support DBD::SQLite. +** This routine is added to support DBD::SQLite. */ int sqlite3_bind_parameter_count(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; @@ -1815,6 +1963,42 @@ } /* +** Set the explain mode for a statement. +*/ +int sqlite3_stmt_explain(sqlite3_stmt *pStmt, int eMode){ + Vdbe *v = (Vdbe*)pStmt; + int rc; +#ifdef SQLITE_ENABLE_API_ARMOR + if( pStmt==0 ) return SQLITE_MISUSE_BKPT; +#endif + sqlite3_mutex_enter(v->db->mutex); + if( ((int)v->explain)==eMode ){ + rc = SQLITE_OK; + }else if( eMode<0 || eMode>2 ){ + rc = SQLITE_ERROR; + }else if( (v->prepFlags & SQLITE_PREPARE_SAVESQL)==0 ){ + rc = SQLITE_ERROR; + }else if( v->eVdbeState!=VDBE_READY_STATE ){ + rc = SQLITE_BUSY; + }else if( v->nMem>=10 && (eMode!=2 || v->haveEqpOps) ){ + /* No reprepare necessary */ + v->explain = eMode; + rc = SQLITE_OK; + }else{ + v->explain = eMode; + rc = sqlite3Reprepare(v); + v->haveEqpOps = eMode==2; + } + if( v->explain ){ + v->nResColumn = 12 - 4*v->explain; + }else{ + v->nResColumn = v->nResAlloc; + } + sqlite3_mutex_leave(v->db->mutex); + return rc; +} + +/* ** Return true if the prepared statement is in need of being reset. */ int sqlite3_stmt_busy(sqlite3_stmt *pStmt){ @@ -1853,7 +2037,7 @@ Vdbe *pVdbe = (Vdbe*)pStmt; u32 v; #ifdef SQLITE_ENABLE_API_ARMOR - if( !pStmt + if( !pStmt || (op!=SQLITE_STMTSTATUS_MEMUSED && (op<0||op>=ArraySize(pVdbe->aCounter))) ){ (void)SQLITE_MISUSE_BKPT; @@ -1934,8 +2118,8 @@ ** if successful, or a NULL pointer if an OOM error is encountered. */ static UnpackedRecord *vdbeUnpackRecord( - KeyInfo *pKeyInfo, - int nKey, + KeyInfo *pKeyInfo, + int nKey, const void *pKey ){ UnpackedRecord *pRet; /* Return value */ @@ -1953,10 +2137,16 @@ ** a field of the row currently being updated or deleted. */ int sqlite3_preupdate_old(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; Mem *pMem; int rc = SQLITE_OK; +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; /* Test that this call is being made from within an SQLITE_DELETE or ** SQLITE_UPDATE pre-update callback, and that iIdx is within range. */ if( !p || p->op==SQLITE_INSERT ){ @@ -2017,7 +2207,12 @@ ** the number of columns in the row being updated, deleted or inserted. */ int sqlite3_preupdate_count(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->keyinfo.nKeyField : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -2028,14 +2223,19 @@ ** only. It returns zero if the change that caused the callback was made ** immediately by a user SQL statement. Or, if the change was made by a ** trigger program, it returns the number of trigger programs currently -** on the stack (1 for a top-level trigger, 2 for a trigger fired by a +** on the stack (1 for a top-level trigger, 2 for a trigger fired by a ** top-level trigger etc.). ** ** For the purposes of the previous paragraph, a foreign key CASCADE, SET NULL ** or SET DEFAULT action is considered a trigger. */ int sqlite3_preupdate_depth(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->v->nFrame : 0); } #endif /* SQLITE_ENABLE_PREUPDATE_HOOK */ @@ -2043,10 +2243,15 @@ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* ** This function is designed to be called from within a pre-update callback -** only. +** only. */ int sqlite3_preupdate_blobwrite(sqlite3 *db){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; +#ifdef SQLITE_ENABLE_API_ARMOR + p = db!=0 ? db->pPreUpdate : 0; +#else + p = db->pPreUpdate; +#endif return (p ? p->iBlobWrite : -1); } #endif @@ -2057,10 +2262,16 @@ ** a field of the row currently being updated or inserted. */ int sqlite3_preupdate_new(sqlite3 *db, int iIdx, sqlite3_value **ppValue){ - PreUpdate *p = db->pPreUpdate; + PreUpdate *p; int rc = SQLITE_OK; Mem *pMem; +#ifdef SQLITE_ENABLE_API_ARMOR + if( db==0 || ppValue==0 ){ + return SQLITE_MISUSE_BKPT; + } +#endif + p = db->pPreUpdate; if( !p || p->op==SQLITE_DELETE ){ rc = SQLITE_MISUSE_BKPT; goto preupdate_new_out; @@ -2139,11 +2350,20 @@ void *pOut /* OUT: Write the answer here */ ){ Vdbe *p = (Vdbe*)pStmt; - VdbeOp *aOp = p->aOp; - int nOp = p->nOp; + VdbeOp *aOp; + int nOp; ScanStatus *pScan = 0; int idx; +#ifdef SQLITE_ENABLE_API_ARMOR + if( p==0 || pOut==0 + || iScanStatusOpSQLITE_SCANSTAT_NCYCLE ){ + return 1; + } +#endif + aOp = p->aOp; + nOp = p->nOp; if( p->pFrame ){ VdbeFrame *pFrame; for(pFrame=p->pFrame; pFrame->pParent; pFrame=pFrame->pParent); @@ -2167,7 +2387,7 @@ idx = iScan; pScan = &p->aScan[idx]; }else{ - /* If the COMPLEX flag is clear, then this function must ignore any + /* If the COMPLEX flag is clear, then this function must ignore any ** ScanStatus structures with ScanStatus.addrLoop set to 0. */ for(idx=0; idxnScan; idx++){ pScan = &p->aScan[idx]; @@ -2290,7 +2510,7 @@ void sqlite3_stmt_scanstatus_reset(sqlite3_stmt *pStmt){ Vdbe *p = (Vdbe*)pStmt; int ii; - for(ii=0; iinOp; ii++){ + for(ii=0; p!=0 && iinOp; ii++){ Op *pOp = &p->aOp[ii]; pOp->nExec = 0; pOp->nCycle = 0; diff -Nru sqlite3-3.42.0/src/vdbeaux.c sqlite3-3.44.0-0/src/vdbeaux.c --- sqlite3-3.42.0/src/vdbeaux.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbeaux.c 2023-11-04 14:23:58.000000000 +0000 @@ -10,7 +10,7 @@ ** ************************************************************************* ** This file contains code used for creating, destroying, and populating -** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) +** a VDBE (or an "sqlite3_stmt" as it is known to the outside world.) */ #include "sqliteInt.h" #include "vdbeInt.h" @@ -152,13 +152,13 @@ } /* -** Resize the Vdbe.aOp array so that it is at least nOp elements larger +** Resize the Vdbe.aOp array so that it is at least nOp elements larger ** than its current size. nOp is guaranteed to be less than or equal ** to 1024/sizeof(Op). ** ** If an out-of-memory error occurs while resizing the array, return -** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain -** unchanged (this is so that any opcodes already allocated can be +** SQLITE_NOMEM. In this case Vdbe.aOp and Vdbe.nOpAlloc remain +** unchanged (this is so that any opcodes already allocated can be ** correctly deallocated along with the rest of the Vdbe). */ static int growOpArray(Vdbe *v, int nOp){ @@ -166,7 +166,7 @@ Parse *p = v->pParse; /* The SQLITE_TEST_REALLOC_STRESS compile-time option is designed to force - ** more frequent reallocs and hence provide more opportunities for + ** more frequent reallocs and hence provide more opportunities for ** simulated OOM faults. SQLITE_TEST_REALLOC_STRESS is generally used ** during testing only. With SQLITE_TEST_REALLOC_STRESS grow the op array ** by the minimum* amount required until the size reaches 512. Normal @@ -219,6 +219,35 @@ #endif /* +** Slow paths for sqlite3VdbeAddOp3() and sqlite3VdbeAddOp4Int() for the +** unusual case when we need to increase the size of the Vdbe.aOp[] array +** before adding the new opcode. +*/ +static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ + assert( p->nOpAlloc<=p->nOp ); + if( growOpArray(p, 1) ) return 1; + assert( p->nOpAlloc>p->nOp ); + return sqlite3VdbeAddOp3(p, op, p1, p2, p3); +} +static SQLITE_NOINLINE int addOp4IntSlow( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + int p4 /* The P4 operand as an integer */ +){ + int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); + if( p->db->mallocFailed==0 ){ + VdbeOp *pOp = &p->aOp[addr]; + pOp->p4type = P4_INT32; + pOp->p4.i = p4; + } + return addr; +} + + +/* ** Add a new instruction to the list of instructions current in the ** VDBE. Return the address of the new instruction. ** @@ -228,17 +257,16 @@ ** ** op The opcode for this instruction ** -** p1, p2, p3 Operands -** -** Use the sqlite3VdbeResolveLabel() function to fix an address and -** the sqlite3VdbeChangeP4() function to change the value of the P4 -** operand. +** p1, p2, p3, p4 Operands */ -static SQLITE_NOINLINE int growOp3(Vdbe *p, int op, int p1, int p2, int p3){ - assert( p->nOpAlloc<=p->nOp ); - if( growOpArray(p, 1) ) return 1; - assert( p->nOpAlloc>p->nOp ); - return sqlite3VdbeAddOp3(p, op, p1, p2, p3); +int sqlite3VdbeAddOp0(Vdbe *p, int op){ + return sqlite3VdbeAddOp3(p, op, 0, 0, 0); +} +int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ + return sqlite3VdbeAddOp3(p, op, p1, 0, 0); +} +int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ + return sqlite3VdbeAddOp3(p, op, p1, p2, 0); } int sqlite3VdbeAddOp3(Vdbe *p, int op, int p1, int p2, int p3){ int i; @@ -261,6 +289,9 @@ pOp->p3 = p3; pOp->p4.p = 0; pOp->p4type = P4_NOTUSED; + + /* Replicate this logic in sqlite3VdbeAddOp4Int() + ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS pOp->zComment = 0; #endif @@ -277,16 +308,59 @@ #ifdef SQLITE_VDBE_COVERAGE pOp->iSrcLine = 0; #endif + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ** Replicate in sqlite3VdbeAddOp4Int() */ + return i; } -int sqlite3VdbeAddOp0(Vdbe *p, int op){ - return sqlite3VdbeAddOp3(p, op, 0, 0, 0); -} -int sqlite3VdbeAddOp1(Vdbe *p, int op, int p1){ - return sqlite3VdbeAddOp3(p, op, p1, 0, 0); -} -int sqlite3VdbeAddOp2(Vdbe *p, int op, int p1, int p2){ - return sqlite3VdbeAddOp3(p, op, p1, p2, 0); +int sqlite3VdbeAddOp4Int( + Vdbe *p, /* Add the opcode to this VM */ + int op, /* The new opcode */ + int p1, /* The P1 operand */ + int p2, /* The P2 operand */ + int p3, /* The P3 operand */ + int p4 /* The P4 operand as an integer */ +){ + int i; + VdbeOp *pOp; + + i = p->nOp; + if( p->nOpAlloc<=i ){ + return addOp4IntSlow(p, op, p1, p2, p3, p4); + } + p->nOp++; + pOp = &p->aOp[i]; + assert( pOp!=0 ); + pOp->opcode = (u8)op; + pOp->p5 = 0; + pOp->p1 = p1; + pOp->p2 = p2; + pOp->p3 = p3; + pOp->p4.i = p4; + pOp->p4type = P4_INT32; + + /* Replicate this logic in sqlite3VdbeAddOp3() + ** vvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvvv */ +#ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS + pOp->zComment = 0; +#endif +#if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) + pOp->nExec = 0; + pOp->nCycle = 0; +#endif +#ifdef SQLITE_DEBUG + if( p->db->flags & SQLITE_VdbeAddopTrace ){ + sqlite3VdbePrintOp(0, i, &p->aOp[i]); + test_addop_breakpoint(i, &p->aOp[i]); + } +#endif +#ifdef SQLITE_VDBE_COVERAGE + pOp->iSrcLine = 0; +#endif + /* ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + ** Replicate in sqlite3VdbeAddOp3() */ + + return i; } /* Generate code for an unconditional jump to instruction iDest @@ -464,7 +538,7 @@ if( bPush){ pParse->addrExplain = iThis; } - sqlite3VdbeScanStatus(v, iThis, 0, 0, 0, 0); + sqlite3VdbeScanStatus(v, iThis, -1, -1, 0, 0); } return addr; } @@ -494,26 +568,6 @@ sqlite3MayAbort(p->pParse); } -/* -** Add an opcode that includes the p4 value as an integer. -*/ -int sqlite3VdbeAddOp4Int( - Vdbe *p, /* Add the opcode to this VM */ - int op, /* The new opcode */ - int p1, /* The P1 operand */ - int p2, /* The P2 operand */ - int p3, /* The P3 operand */ - int p4 /* The P4 operand as an integer */ -){ - int addr = sqlite3VdbeAddOp3(p, op, p1, p2, p3); - if( p->db->mallocFailed==0 ){ - VdbeOp *pOp = &p->aOp[addr]; - pOp->p4type = P4_INT32; - pOp->p4.i = p4; - } - return addr; -} - /* Insert the end of a co-routine */ void sqlite3VdbeEndCoroutine(Vdbe *v, int regYield){ @@ -624,19 +678,19 @@ /* ** The following type and function are used to iterate through all opcodes -** in a Vdbe main program and each of the sub-programs (triggers) it may +** in a Vdbe main program and each of the sub-programs (triggers) it may ** invoke directly or indirectly. It should be used as follows: ** ** Op *pOp; ** VdbeOpIter sIter; ** ** memset(&sIter, 0, sizeof(sIter)); -** sIter.v = v; // v is of type Vdbe* +** sIter.v = v; // v is of type Vdbe* ** while( (pOp = opIterNext(&sIter)) ){ ** // Do something with pOp ** } ** sqlite3DbFree(v->db, sIter.apSub); -** +** */ typedef struct VdbeOpIter VdbeOpIter; struct VdbeOpIter { @@ -669,7 +723,7 @@ p->iSub++; p->iAddr = 0; } - + if( pRet->p4type==P4_SUBPROGRAM ){ int nByte = (p->nSub+1)*sizeof(SubProgram*); int j; @@ -703,7 +757,7 @@ ** * OP_VCreate ** * OP_VRename ** * OP_FkCounter with P2==0 (immediate foreign key constraint) -** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine +** * OP_CreateBtree/BTREE_INTKEY and OP_InitCoroutine ** (for CREATE TABLE AS SELECT ...) ** ** Then check that the value of Parse.mayAbort is true if an @@ -728,12 +782,12 @@ while( (pOp = opIterNext(&sIter))!=0 ){ int opcode = pOp->opcode; - if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename + if( opcode==OP_Destroy || opcode==OP_VUpdate || opcode==OP_VRename || opcode==OP_VDestroy || opcode==OP_VCreate || opcode==OP_ParseSchema || opcode==OP_Function || opcode==OP_PureFunc - || ((opcode==OP_Halt || opcode==OP_HaltIfNull) + || ((opcode==OP_Halt || opcode==OP_HaltIfNull) && ((pOp->p1)!=SQLITE_OK && pOp->p2==OE_Abort)) ){ hasAbort = 1; @@ -742,7 +796,7 @@ if( opcode==OP_CreateBtree && pOp->p3==BTREE_INTKEY ) hasCreateTable = 1; if( mayAbort ){ /* hasCreateIndex may also be set for some DELETE statements that use - ** OP_Clear. So this routine may end up returning true in the case + ** OP_Clear. So this routine may end up returning true in the case ** where a "DELETE FROM tbl" has a statement-journal but does not ** require one. This is not so bad - it is an inefficiency, not a bug. */ if( opcode==OP_CreateBtree && pOp->p3==BTREE_BLOBKEY ) hasCreateIndex = 1; @@ -826,7 +880,7 @@ p->bIsReader = 0; pOp = &p->aOp[p->nOp-1]; assert( p->aOp[0].opcode==OP_Init ); - while( 1 /* Loop termates when it reaches the OP_Init opcode */ ){ + while( 1 /* Loop terminates when it reaches the OP_Init opcode */ ){ /* Only JUMP opcodes and the short list of special opcodes in the switch ** below need to be considered. The mkopcodeh.tcl generator script groups ** all these opcodes together near the front of the opcode list. Skip @@ -892,7 +946,7 @@ ** have non-negative values for P2. */ assert( (sqlite3OpcodeProperty[pOp->opcode]&OPFLG_JUMP)==0 || pOp->p2>=0); } - assert( pOp>p->aOp ); + assert( pOp>p->aOp ); pOp--; } resolve_p2_values_loop_exit: @@ -948,6 +1002,10 @@ int iDest = pOp->p2; /* Jump destination */ if( iDest==0 ) continue; if( pOp->opcode==OP_Gosub ) continue; + if( pOp->p3==20230325 && pOp->opcode==OP_NotNull ){ + /* This is a deliberately taken illegal branch. tag-20230325-2 */ + continue; + } if( iDest<0 ){ int j = ADDR(iDest); assert( j>=0 ); @@ -1041,12 +1099,12 @@ /* ** This function returns a pointer to the array of opcodes associated with ** the Vdbe passed as the first argument. It is the callers responsibility -** to arrange for the returned array to be eventually freed using the +** to arrange for the returned array to be eventually freed using the ** vdbeFreeOpArray() function. ** ** Before returning, *pnOp is set to the number of entries in the returned -** array. Also, *pnMaxArg is set to the larger of its current value and -** the number of entries in the Vdbe.apArg[] array required to execute the +** array. Also, *pnMaxArg is set to the larger of its current value and +** the number of entries in the Vdbe.apArg[] array required to execute the ** returned program. */ VdbeOp *sqlite3VdbeTakeOpArray(Vdbe *p, int *pnOp, int *pnMaxArg){ @@ -1120,7 +1178,7 @@ void sqlite3VdbeScanStatus( Vdbe *p, /* VM to add scanstatus() to */ int addrExplain, /* Address of OP_Explain (or 0) */ - int addrLoop, /* Address of loop counter */ + int addrLoop, /* Address of loop counter */ int addrVisit, /* Address of rows visited counter */ LogEst nEst, /* Estimated number of output rows */ const char *zName /* Name of table or index being scanned */ @@ -1146,13 +1204,13 @@ ** Add the range of instructions from addrStart to addrEnd (inclusive) to ** the set of those corresponding to the sqlite3_stmt_scanstatus() counters ** associated with the OP_Explain instruction at addrExplain. The -** sum of the sqlite3Hwtime() values for each of these instructions +** sum of the sqlite3Hwtime() values for each of these instructions ** will be returned for SQLITE_SCANSTAT_NCYCLE requests. */ void sqlite3VdbeScanStatusRange( - Vdbe *p, - int addrExplain, - int addrStart, + Vdbe *p, + int addrExplain, + int addrStart, int addrEnd ){ if( IS_STMT_SCANSTATUS(p->db) ){ @@ -1182,9 +1240,9 @@ ** addrExplain. */ void sqlite3VdbeScanStatusCounters( - Vdbe *p, - int addrExplain, - int addrLoop, + Vdbe *p, + int addrExplain, + int addrLoop, int addrVisit ){ if( IS_STMT_SCANSTATUS(p->db) ){ @@ -1196,8 +1254,8 @@ pScan = 0; } if( pScan ){ - pScan->addrLoop = addrLoop; - pScan->addrVisit = addrVisit; + if( addrLoop>0 ) pScan->addrLoop = addrLoop; + if( addrVisit>0 ) pScan->addrVisit = addrVisit; } } } @@ -1280,7 +1338,7 @@ /* ** If the input FuncDef structure is ephemeral, then free it. If -** the FuncDef is not ephermal, then do nothing. +** the FuncDef is not ephemeral, then do nothing. */ static void freeEphemeralFunction(sqlite3 *db, FuncDef *pDef){ assert( db!=0 ); @@ -1346,8 +1404,8 @@ /* ** Free the space allocated for aOp and any p4 values allocated for the -** opcodes contained within. If aOp is not NULL it is assumed to contain -** nOp entries. +** opcodes contained within. If aOp is not NULL it is assumed to contain +** nOp entries. */ static void vdbeFreeOpArray(sqlite3 *db, Op *aOp, int nOp){ assert( nOp>=0 ); @@ -1358,7 +1416,7 @@ if( pOp->p4type <= P4_FREE_IF_LE ) freeP4(db, pOp->p4type, pOp->p4.p); #ifdef SQLITE_ENABLE_EXPLAIN_COMMENTS sqlite3DbFree(db, pOp->zComment); -#endif +#endif if( pOp==aOp ) break; pOp--; } @@ -1444,7 +1502,6 @@ } #endif /* SQLITE_DEBUG */ - /* ** Change the value of the P4 operand for a specific instruction. ** This routine is useful when a large program is loaded from a @@ -1455,7 +1512,7 @@ ** the string is made into memory obtained from sqlite3_malloc(). ** A value of n==0 means copy bytes of zP4 up to and including the ** first null byte. If n>0 then copy n+1 bytes of zP4. -** +** ** Other values of n (P4_STATIC, P4_COLLSEQ etc.) indicate that zP4 points ** to a string or structure that is guaranteed to exist for the lifetime of ** the Vdbe. In these cases we can just copy the pointer. @@ -1516,7 +1573,7 @@ } /* -** Change the P4 operand of the most recently coded instruction +** Change the P4 operand of the most recently coded instruction ** to the value defined by the arguments. This is a high-speed ** version of sqlite3VdbeChangeP4(). ** @@ -1605,7 +1662,7 @@ ** routine, then a pointer to a dummy VdbeOp will be returned. That opcode ** is readable but not writable, though it is cast to a writable value. ** The return of a dummy opcode allows the call to continue functioning -** after an OOM fault without having to check to see if the return from +** after an OOM fault without having to check to see if the return from ** this routine is a valid pointer. But because the dummy.opcode is 0, ** dummy will never be written to. This is verified by code inspection and ** by running with Valgrind. @@ -1835,9 +1892,9 @@ CollSeq *pColl = pKeyInfo->aColl[j]; const char *zColl = pColl ? pColl->zName : ""; if( strcmp(zColl, "BINARY")==0 ) zColl = "B"; - sqlite3_str_appendf(&x, ",%s%s%s", - (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", - (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", + sqlite3_str_appendf(&x, ",%s%s%s", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_DESC) ? "-" : "", + (pKeyInfo->aSortFlags[j] & KEYINFO_ORDER_BIGNULL)? "N." : "", zColl); } sqlite3_str_append(&x, ")", 1); @@ -1960,13 +2017,13 @@ ** ** If SQLite is not threadsafe but does support shared-cache mode, then ** sqlite3BtreeEnter() is invoked to set the BtShared.db variables -** of all of BtShared structures accessible via the database handle +** of all of BtShared structures accessible via the database handle ** associated with the VM. ** ** If SQLite is not threadsafe and does not support shared-cache mode, this ** function is a no-op. ** -** The p->btreeMask field is a bitmask of all btrees that the prepared +** The p->btreeMask field is a bitmask of all btrees that the prepared ** statement p will ever use. Let N be the number of bits in p->btreeMask ** corresponding to btrees that use shared cache. Then the runtime of ** this routine is N*N. But as N is rarely more than 1, this should not @@ -2034,8 +2091,8 @@ /* NB: The sqlite3OpcodeName() function is implemented by code created ** by the mkopcodeh.awk and mkopcodec.awk scripts which extract the ** information from the vdbe.c source text */ - fprintf(pOut, zFormat1, pc, - sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, + fprintf(pOut, zFormat1, pc, + sqlite3OpcodeName(pOp->opcode), pOp->p1, pOp->p2, pOp->p3, zP4 ? zP4 : "", pOp->p5, zCom ? zCom : "" ); @@ -2098,15 +2155,15 @@ assert( sqlite3VdbeCheckMemInvariants(p) ); /* This block is really an inlined version of sqlite3VdbeMemRelease() - ** that takes advantage of the fact that the memory cell value is + ** that takes advantage of the fact that the memory cell value is ** being set to NULL after releasing any dynamic resources. ** - ** The justification for duplicating code is that according to - ** callgrind, this causes a certain test case to hit the CPU 4.7 - ** percent less (x86 linux, gcc version 4.1.2, -O6) than if + ** The justification for duplicating code is that according to + ** callgrind, this causes a certain test case to hit the CPU 4.7 + ** percent less (x86 linux, gcc version 4.1.2, -O6) than if ** sqlite3MemRelease() were called from here. With -O2, this jumps - ** to 6.6 percent. The test case is inserting 1000 rows into a table - ** with no indexes using a single prepared INSERT statement, bind() + ** to 6.6 percent. The test case is inserting 1000 rows into a table + ** with no indexes using a single prepared INSERT statement, bind() ** and reset(). Inserts are grouped into a transaction. */ testcase( p->flags & MEM_Agg ); @@ -2256,7 +2313,7 @@ Op *pOp = aOp + i; if( pOp->opcode==OP_OpenRead ) break; if( pOp->opcode==OP_OpenWrite && (pOp->p5 & OPFLAG_P2ISREG)==0 ) break; - if( pOp->opcode==OP_ReopenIdx ) break; + if( pOp->opcode==OP_ReopenIdx ) break; }else #endif { @@ -2364,8 +2421,8 @@ sqlite3VdbeMemSetInt64(pMem, pOp->p1); sqlite3VdbeMemSetInt64(pMem+1, pOp->p2); sqlite3VdbeMemSetInt64(pMem+2, pOp->p3); - sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free); - p->nResColumn = 4; + sqlite3VdbeMemSetStr(pMem+3, zP4, -1, SQLITE_UTF8, sqlite3_free); + assert( p->nResColumn==4 ); }else{ sqlite3VdbeMemSetInt64(pMem+0, i); sqlite3VdbeMemSetStr(pMem+1, (char*)sqlite3OpcodeName(pOp->opcode), @@ -2384,7 +2441,7 @@ sqlite3VdbeMemSetNull(pMem+7); #endif sqlite3VdbeMemSetStr(pMem+5, zP4, -1, SQLITE_UTF8, sqlite3_free); - p->nResColumn = 8; + assert( p->nResColumn==8 ); } p->pResultRow = pMem; if( db->mallocFailed ){ @@ -2537,11 +2594,11 @@ ** creating the virtual machine. This involves things such ** as allocating registers and initializing the program counter. ** After the VDBE has be prepped, it can be executed by one or more -** calls to sqlite3VdbeExec(). +** calls to sqlite3VdbeExec(). ** ** This function may be called exactly once on each virtual machine. ** After this routine is called the VM has been "packaged" and is ready -** to run. After this routine is called, further calls to +** to run. After this routine is called, further calls to ** sqlite3VdbeAddOp() functions are prohibited. This routine disconnects ** the Vdbe from the Parse object that helped generate it so that the ** the Vdbe becomes an independent entity and the Parse object can be @@ -2575,7 +2632,7 @@ nMem = pParse->nMem; nCursor = pParse->nTab; nArg = pParse->nMaxArg; - + /* Each cursor uses a memory cell. The first cursor (cursor 0) can ** use aMem[0] which is not otherwise used by the VDBE program. Allocate ** space at the end of aMem[] for cursors 1 and greater. @@ -2598,34 +2655,17 @@ resolveP2Values(p, &nArg); p->usesStmtJournal = (u8)(pParse->isMultiWrite && pParse->mayAbort); if( pParse->explain ){ - static const char * const azColName[] = { - "addr", "opcode", "p1", "p2", "p3", "p4", "p5", "comment", - "id", "parent", "notused", "detail" - }; - int iFirst, mx, i; if( nMem<10 ) nMem = 10; p->explain = pParse->explain; - if( pParse->explain==2 ){ - sqlite3VdbeSetNumCols(p, 4); - iFirst = 8; - mx = 12; - }else{ - sqlite3VdbeSetNumCols(p, 8); - iFirst = 0; - mx = 8; - } - for(i=iFirst; inResColumn = 12 - 4*p->explain; } p->expired = 0; /* Memory for registers, parameters, cursor, etc, is allocated in one or two - ** passes. On the first pass, we try to reuse unused memory at the + ** passes. On the first pass, we try to reuse unused memory at the ** end of the opcode array. If we are unable to satisfy all memory ** requirements by reusing the opcode array tail, then the second - ** pass will fill in the remainder using a fresh memory allocation. + ** pass will fill in the remainder using a fresh memory allocation. ** ** This two-pass approach that reuses as much memory as possible from ** the leftover memory at the end of the opcode array. This can significantly @@ -2663,13 +2703,29 @@ } /* -** Close a VDBE cursor and release all the resources that cursor +** Close a VDBE cursor and release all the resources that cursor ** happens to hold. */ void sqlite3VdbeFreeCursor(Vdbe *p, VdbeCursor *pCx){ if( pCx ) sqlite3VdbeFreeCursorNN(p,pCx); } +static SQLITE_NOINLINE void freeCursorWithCache(Vdbe *p, VdbeCursor *pCx){ + VdbeTxtBlbCache *pCache = pCx->pCache; + assert( pCx->colCache ); + pCx->colCache = 0; + pCx->pCache = 0; + if( pCache->pCValue ){ + sqlite3RCStrUnref(pCache->pCValue); + pCache->pCValue = 0; + } + sqlite3DbFree(p->db, pCache); + sqlite3VdbeFreeCursorNN(p, pCx); +} void sqlite3VdbeFreeCursorNN(Vdbe *p, VdbeCursor *pCx){ + if( pCx->colCache ){ + freeCursorWithCache(p, pCx); + return; + } switch( pCx->eCurType ){ case CURTYPE_SORTER: { sqlite3VdbeSorterClose(p->db, pCx); @@ -2733,7 +2789,7 @@ /* ** Close all cursors. ** -** Also release any dynamic memory held by the VM in the Vdbe.aMem memory +** Also release any dynamic memory held by the VM in the Vdbe.aMem memory ** cell array. This is necessary as the memory cell array may contain ** pointers to VdbeFrame objects, which may in turn contain pointers to ** open cursors. @@ -2770,12 +2826,12 @@ int n; sqlite3 *db = p->db; - if( p->nResColumn ){ - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + if( p->nResAlloc ){ + releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); sqlite3DbFree(db, p->aColName); } n = nResColumn*COLNAME_N; - p->nResColumn = (u16)nResColumn; + p->nResColumn = p->nResAlloc = (u16)nResColumn; p->aColName = (Mem*)sqlite3DbMallocRawNN(db, sizeof(Mem)*n ); if( p->aColName==0 ) return; initMemArray(p->aColName, n, db, MEM_Null); @@ -2800,14 +2856,14 @@ ){ int rc; Mem *pColName; - assert( idxnResColumn ); + assert( idxnResAlloc ); assert( vardb->mallocFailed ){ assert( !zName || xDel!=SQLITE_DYNAMIC ); return SQLITE_NOMEM_BKPT; } assert( p->aColName!=0 ); - pColName = &(p->aColName[idx+var*p->nResColumn]); + pColName = &(p->aColName[idx+var*p->nResAlloc]); rc = sqlite3VdbeMemSetStr(pColName, zName, -1, SQLITE_UTF8, xDel); assert( rc!=0 || !zName || (pColName->flags&MEM_Term)!=0 ); return rc; @@ -2828,27 +2884,27 @@ int needXcommit = 0; #ifdef SQLITE_OMIT_VIRTUALTABLE - /* With this option, sqlite3VtabSync() is defined to be simply - ** SQLITE_OK so p is not used. + /* With this option, sqlite3VtabSync() is defined to be simply + ** SQLITE_OK so p is not used. */ UNUSED_PARAMETER(p); #endif /* Before doing anything else, call the xSync() callback for any ** virtual module tables written in this transaction. This has to - ** be done before determining whether a super-journal file is + ** be done before determining whether a super-journal file is ** required, as an xSync() callback may add an attached database ** to the transaction. */ rc = sqlite3VtabSync(db, p); /* This loop determines (a) if the commit hook should be invoked and - ** (b) how many database files have open write transactions, not - ** including the temp database. (b) is important because if more than + ** (b) how many database files have open write transactions, not + ** including the temp database. (b) is important because if more than ** one database file has an open write transaction, a super-journal ** file is required for an atomic commit. - */ - for(i=0; rc==SQLITE_OK && inDb; i++){ + */ + for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ){ /* Whether or not a database might need a super-journal depends upon @@ -2869,7 +2925,7 @@ if( db->aDb[i].safety_level!=PAGER_SYNCHRONOUS_OFF && aMJNeeded[sqlite3PagerGetJournalMode(pPager)] && sqlite3PagerIsMemdb(pPager)==0 - ){ + ){ assert( i!=1 ); nTrans++; } @@ -2894,8 +2950,8 @@ ** super-journal. ** ** If the return value of sqlite3BtreeGetFilename() is a zero length - ** string, it means the main database is :memory: or a temp file. In - ** that case we do not support atomic multi-file commits, so use the + ** string, it means the main database is :memory: or a temp file. In + ** that case we do not support atomic multi-file commits, so use the ** simple case then too. */ if( 0==sqlite3Strlen30(sqlite3BtreeGetFilename(db->aDb[0].pBt)) @@ -2908,7 +2964,7 @@ } } - /* Do the commit only if all databases successfully complete phase 1. + /* Do the commit only if all databases successfully complete phase 1. ** If one of the BtreeCommitPhaseOne() calls fails, this indicates an ** IO error while deleting or truncating a journal file. It is unlikely, ** but could happen. In this case abandon processing and return the error. @@ -2967,7 +3023,7 @@ }while( rc==SQLITE_OK && res ); if( rc==SQLITE_OK ){ /* Open the super-journal. */ - rc = sqlite3OsOpenMalloc(pVfs, zSuper, &pSuperJrnl, + rc = sqlite3OsOpenMalloc(pVfs, zSuper, &pSuperJrnl, SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE| SQLITE_OPEN_EXCLUSIVE|SQLITE_OPEN_SUPER_JOURNAL, 0 ); @@ -2976,7 +3032,7 @@ sqlite3DbFree(db, zSuper-4); return rc; } - + /* Write the name of each database file in the transaction into the new ** super-journal file. If an error occurs at this point close ** and delete the super-journal file. All the individual journal files @@ -3024,7 +3080,7 @@ ** in case the super-journal file name was written into the journal ** file before the failure occurred. */ - for(i=0; rc==SQLITE_OK && inDb; i++){ + for(i=0; rc==SQLITE_OK && inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ rc = sqlite3BtreeCommitPhaseOne(pBt, zSuper); @@ -3057,7 +3113,7 @@ */ disable_simulated_io_errors(); sqlite3BeginBenignMalloc(); - for(i=0; inDb; i++){ + for(i=0; inDb; i++){ Btree *pBt = db->aDb[i].pBt; if( pBt ){ sqlite3BtreeCommitPhaseTwo(pBt, 1); @@ -3073,7 +3129,7 @@ return rc; } -/* +/* ** This routine checks that the sqlite3.nVdbeActive count variable ** matches the number of vdbe's in the list sqlite3.pVdbe that are ** currently active. An assertion fails if the two counts do not match. @@ -3109,10 +3165,10 @@ ** If the Vdbe passed as the first argument opened a statement-transaction, ** close it now. Argument eOp must be either SAVEPOINT_ROLLBACK or ** SAVEPOINT_RELEASE. If it is SAVEPOINT_ROLLBACK, then the statement -** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the +** transaction is rolled back. If eOp is SAVEPOINT_RELEASE, then the ** statement transaction is committed. ** -** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. +** If an IO error occurs, an SQLITE_IOERR_XXX error code is returned. ** Otherwise SQLITE_OK. */ static SQLITE_NOINLINE int vdbeCloseStatement(Vdbe *p, int eOp){ @@ -3125,7 +3181,7 @@ assert( db->nStatement>0 ); assert( p->iStatement==(db->nStatement+db->nSavepoint) ); - for(i=0; inDb; i++){ + for(i=0; inDb; i++){ int rc2 = SQLITE_OK; Btree *pBt = db->aDb[i].pBt; if( pBt ){ @@ -3152,8 +3208,8 @@ } } - /* If the statement transaction is being rolled back, also restore the - ** database handles deferred constraint counter to the value it had when + /* If the statement transaction is being rolled back, also restore the + ** database handles deferred constraint counter to the value it had when ** the statement transaction was opened. */ if( eOp==SAVEPOINT_ROLLBACK ){ db->nDeferredCons = p->nStmtDefCons; @@ -3170,20 +3226,20 @@ /* -** This function is called when a transaction opened by the database -** handle associated with the VM passed as an argument is about to be +** This function is called when a transaction opened by the database +** handle associated with the VM passed as an argument is about to be ** committed. If there are outstanding deferred foreign key constraint ** violations, return SQLITE_ERROR. Otherwise, SQLITE_OK. ** -** If there are outstanding FK violations and this function returns +** If there are outstanding FK violations and this function returns ** SQLITE_ERROR, set the result of the VM to SQLITE_CONSTRAINT_FOREIGNKEY ** and write an error message to it. Then return SQLITE_ERROR. */ #ifndef SQLITE_OMIT_FOREIGN_KEY int sqlite3VdbeCheckFk(Vdbe *p, int deferred){ sqlite3 *db = p->db; - if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) - || (!deferred && p->nFkConstraint>0) + if( (deferred && (db->nDeferredCons+db->nDeferredImmCons)>0) + || (!deferred && p->nFkConstraint>0) ){ p->rc = SQLITE_CONSTRAINT_FOREIGNKEY; p->errorAction = OE_Abort; @@ -3214,7 +3270,7 @@ /* This function contains the logic that determines if a statement or ** transaction will be committed or rolled back as a result of the - ** execution of this virtual machine. + ** execution of this virtual machine. ** ** If any of the following errors occur: ** @@ -3256,16 +3312,16 @@ mrc = isSpecialError = 0; } if( isSpecialError ){ - /* If the query was read-only and the error code is SQLITE_INTERRUPT, - ** no rollback is necessary. Otherwise, at least a savepoint - ** transaction must be rolled back to restore the database to a + /* If the query was read-only and the error code is SQLITE_INTERRUPT, + ** no rollback is necessary. Otherwise, at least a savepoint + ** transaction must be rolled back to restore the database to a ** consistent state. ** ** Even if the statement is read-only, it is important to perform - ** a statement or transaction rollback operation. If the error + ** a statement or transaction rollback operation. If the error ** occurred while writing to the journal, sub-journal or database ** file as part of an effort to free up cache space (see function - ** pagerStress() in pager.c), the rollback is required to restore + ** pagerStress() in pager.c), the rollback is required to restore ** the pager to a consistent state. */ if( !p->readOnly || mrc!=SQLITE_INTERRUPT ){ @@ -3287,16 +3343,16 @@ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ sqlite3VdbeCheckFk(p, 0); } - - /* If the auto-commit flag is set and this is the only active writer - ** VM, then we do either a commit or rollback of the current transaction. + + /* If the auto-commit flag is set and this is the only active writer + ** VM, then we do either a commit or rollback of the current transaction. ** - ** Note: This block also runs if one of the special errors handled - ** above has occurred. + ** Note: This block also runs if one of the special errors handled + ** above has occurred. */ - if( !sqlite3VtabInSync(db) - && db->autoCommit - && db->nVdbeWrite==(p->readOnly==0) + if( !sqlite3VtabInSync(db) + && db->autoCommit + && db->nVdbeWrite==(p->readOnly==0) ){ if( p->rc==SQLITE_OK || (p->errorAction==OE_Fail && !isSpecialError) ){ rc = sqlite3VdbeCheckFk(p, 1); @@ -3309,10 +3365,10 @@ }else if( db->flags & SQLITE_CorruptRdOnly ){ rc = SQLITE_CORRUPT; db->flags &= ~SQLITE_CorruptRdOnly; - }else{ - /* The auto-commit flag is true, the vdbe program was successful + }else{ + /* The auto-commit flag is true, the vdbe program was successful ** or hit an 'OR FAIL' constraint and there are no deferred foreign - ** key constraints to hold up the transaction. This means a commit + ** key constraints to hold up the transaction. This means a commit ** is required. */ rc = vdbeCommit(db, p); } @@ -3320,6 +3376,7 @@ sqlite3VdbeLeave(p); return SQLITE_BUSY; }else if( rc!=SQLITE_OK ){ + sqlite3SystemError(db, rc); p->rc = rc; sqlite3RollbackAll(db, SQLITE_OK); p->nChange = 0; @@ -3348,7 +3405,7 @@ p->nChange = 0; } } - + /* If eStatementOp is non-zero, then a statement transaction needs to ** be committed or rolled back. Call sqlite3VdbeCloseStatement() to ** do so. If this operation returns an error, and the current statement @@ -3369,9 +3426,9 @@ p->nChange = 0; } } - + /* If this was an INSERT, UPDATE or DELETE and no statement transaction - ** has been rolled back, update the database connection change-counter. + ** has been rolled back, update the database connection change-counter. */ if( p->changeCntOn ){ if( eStatementOp!=SAVEPOINT_ROLLBACK ){ @@ -3400,7 +3457,7 @@ } /* If the auto-commit flag is set to true, then any locks that were held - ** by connection db have now been released. Call sqlite3ConnectionUnlocked() + ** by connection db have now been released. Call sqlite3ConnectionUnlocked() ** to invoke any required unlock-notify callbacks. */ if( db->autoCommit ){ @@ -3422,7 +3479,7 @@ /* ** Copy the error code and error message belonging to the VDBE passed -** as the first argument to its database handle (so that they will be +** as the first argument to its database handle (so that they will be ** returned by calls to sqlite3_errcode() and sqlite3_errmsg()). ** ** This function does not clear the VDBE error code or message, just @@ -3448,7 +3505,7 @@ #ifdef SQLITE_ENABLE_SQLLOG /* -** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, +** If an SQLITE_CONFIG_SQLLOG hook is registered and the VM has been run, ** invoke it. */ static void vdbeInvokeSqllog(Vdbe *v){ @@ -3509,7 +3566,7 @@ /* Reset register contents and reclaim error message memory. */ #ifdef SQLITE_DEBUG - /* Execute assert() statements to ensure that the Vdbe.apCsr[] and + /* Execute assert() statements to ensure that the Vdbe.apCsr[] and ** Vdbe.aMem[] arrays have already been cleaned up. */ if( p->apCsr ) for(i=0; inCursor; i++) assert( p->apCsr[i]==0 ); if( p->aMem ){ @@ -3564,7 +3621,7 @@ #endif return p->rc & db->errMask; } - + /* ** Clean up and delete a VDBE after execution. Return an integer which is ** the result code. Write any error message text into *pzErrMsg. @@ -3588,8 +3645,8 @@ ** the first argument. ** ** Or, if iOp is greater than or equal to zero, then the destructor is -** only invoked for those auxiliary data pointers created by the user -** function invoked by the OP_Function opcode at instruction iOp of +** only invoked for those auxiliary data pointers created by the user +** function invoked by the OP_Function opcode at instruction iOp of ** VM pVdbe, and only then if: ** ** * the associated function parameter is the 32nd or later (counting @@ -3631,7 +3688,7 @@ assert( db!=0 ); assert( p->db==0 || p->db==db ); if( p->aColName ){ - releaseMemArray(p->aColName, p->nResColumn*COLNAME_N); + releaseMemArray(p->aColName, p->nResAlloc*COLNAME_N); sqlite3DbNNFreeNN(db, p->aColName); } for(pSub=p->pProgram; pSub; pSub=pNext){ @@ -3861,7 +3918,7 @@ ** The sizes for serial types less than 128 */ const u8 sqlite3SmallTypeSizes[128] = { - /* 0 1 2 3 4 5 6 7 8 9 */ + /* 0 1 2 3 4 5 6 7 8 9 */ /* 0 */ 0, 1, 2, 3, 4, 6, 8, 8, 0, 0, /* 10 */ 0, 0, 0, 0, 1, 1, 2, 2, 3, 3, /* 20 */ 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, @@ -3884,19 +3941,19 @@ if( serial_type>=128 ){ return (serial_type-12)/2; }else{ - assert( serial_type<12 + assert( serial_type<12 || sqlite3SmallTypeSizes[serial_type]==(serial_type - 12)/2 ); return sqlite3SmallTypeSizes[serial_type]; } } u8 sqlite3VdbeOneByteSerialTypeLen(u8 serial_type){ assert( serial_type<128 ); - return sqlite3SmallTypeSizes[serial_type]; + return sqlite3SmallTypeSizes[serial_type]; } /* -** If we are on an architecture with mixed-endian floating -** points (ex: ARM7) then swap the lower 4 bytes with the +** If we are on an architecture with mixed-endian floating +** points (ex: ARM7) then swap the lower 4 bytes with the ** upper 4 bytes. Return the result. ** ** For most architectures, this is a no-op. @@ -3918,7 +3975,7 @@ ** (2007-08-30) Frank van Vugt has studied this problem closely ** and has send his findings to the SQLite developers. Frank ** writes that some Linux kernels offer floating point hardware -** emulation that uses only 32-bit mantissas instead of a full +** emulation that uses only 32-bit mantissas instead of a full ** 48-bits as required by the IEEE standard. (This is the ** CONFIG_FPE_FASTFPE option.) On such systems, floating point ** byte swapping becomes very complicated. To avoid problems, @@ -3962,7 +4019,7 @@ ** The few cases that require local variables are broken out into a separate ** routine so that in most cases the overhead of moving the stack pointer ** is avoided. -*/ +*/ static void serialGet( const unsigned char *buf, /* Buffer to deserialize from */ u32 serial_type, /* Serial type to deserialize */ @@ -4045,7 +4102,7 @@ /* EVIDENCE-OF: R-01849-26079 Value is a big-endian 32-bit ** twos-complement integer. */ pMem->u.i = FOUR_BYTE_INT(buf); -#ifdef __HP_cc +#ifdef __HP_cc /* Work around a sign-extension bug in the HP compiler for HP/UX */ if( buf[0]&0x80 ) pMem->u.i |= 0xffffffff80000000LL; #endif @@ -4098,7 +4155,7 @@ ** The space is either allocated using sqlite3DbMallocRaw() or from within ** the unaligned buffer passed via the second and third arguments (presumably ** stack space). If the former, then *ppFree is set to a pointer that should -** be eventually freed by the caller using sqlite3DbFree(). Or, if the +** be eventually freed by the caller using sqlite3DbFree(). Or, if the ** allocation comes from the pSpace/szSpace buffer, *ppFree is set to NULL ** before returning. ** @@ -4120,10 +4177,10 @@ } /* -** Given the nKey-byte encoding of a record in pKey[], populate the +** Given the nKey-byte encoding of a record in pKey[], populate the ** UnpackedRecord structure indicated by the fourth argument with the ** contents of the decoded record. -*/ +*/ void sqlite3VdbeRecordUnpack( KeyInfo *pKeyInfo, /* Information about the record format */ int nKey, /* Size of the binary record */ @@ -4131,7 +4188,7 @@ UnpackedRecord *p /* Populate this structure before returning. */ ){ const unsigned char *aKey = (const unsigned char *)pKey; - u32 d; + u32 d; u32 idx; /* Offset in aKey[] to read from */ u16 u; /* Unsigned loop counter */ u32 szHdr; @@ -4158,7 +4215,7 @@ } if( d>(u32)nKey && u ){ assert( CORRUPT_DB ); - /* In a corrupt record entry, the last pMem might have been set up using + /* In a corrupt record entry, the last pMem might have been set up using ** uninitialized memory. Overwrite its value with NULL, to prevent ** warnings from MSAN. */ sqlite3VdbeMemSetNull(pMem-1); @@ -4202,13 +4259,13 @@ /* Compilers may complain that mem1.u.i is potentially uninitialized. ** We could initialize it, as shown here, to silence those complaints. - ** But in fact, mem1.u.i will never actually be used uninitialized, and doing + ** But in fact, mem1.u.i will never actually be used uninitialized, and doing ** the unnecessary initialization has a measurable negative performance ** impact, since this routine is a very high runner. And so, we choose ** to ignore the compiler warnings and leave this variable uninitialized. */ /* mem1.u.i = 0; // not needed, here to silence compiler warning */ - + idx1 = getVarint32(aKey1, szHdr1); if( szHdr1>98307 ) return SQLITE_CORRUPT; d1 = szHdr1; @@ -4229,8 +4286,17 @@ ** sqlite3VdbeSerialTypeLen() in the common case. */ if( d1+(u64)serial_type1+2>(u64)nKey1 - && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)>(u64)nKey1 ){ + if( serial_type1>=1 + && serial_type1<=7 + && d1+(u64)sqlite3VdbeSerialTypeLen(serial_type1)<=(u64)nKey1+8 + && CORRUPT_DB + ){ + return 1; /* corrupt record not detected by + ** sqlite3VdbeRecordCompareWithSkip(). Return true + ** to avoid firing the assert() */ + } break; } @@ -4246,7 +4312,7 @@ if( rc!=0 ){ assert( mem1.szMalloc==0 ); /* See comment below */ if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) - && ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null)) + && ((mem1.flags & MEM_Null) || (pPKey2->aMem[i].flags & MEM_Null)) ){ rc = -rc; } @@ -4292,7 +4358,7 @@ ** incorrectly. */ static void vdbeAssertFieldCountWithinLimits( - int nKey, const void *pKey, /* The record to verify */ + int nKey, const void *pKey, /* The record to verify */ const KeyInfo *pKeyInfo /* Compare size with this KeyInfo */ ){ int nField = 0; @@ -4318,7 +4384,7 @@ /* ** Both *pMem1 and *pMem2 contain string values. Compare the two values ** using the collation sequence pColl. As usual, return a negative , zero -** or positive value if *pMem1 is less than, equal to or greater than +** or positive value if *pMem1 is less than, equal to or greater than ** *pMem2, respectively. Similar in spirit to "rc = (*pMem1) - (*pMem2);". */ static int vdbeCompareMemString( @@ -4399,20 +4465,33 @@ return n1 - n2; } +/* The following two functions are used only within testcase() to prove +** test coverage. These functions do no exist for production builds. +** We must use separate SQLITE_NOINLINE functions here, since otherwise +** optimizer code movement causes gcov to become very confused. +*/ +#if defined(SQLITE_COVERAGE_TEST) || defined(SQLITE_DEBUG) +static int SQLITE_NOINLINE doubleLt(double a, double b){ return a8 ){ + if( sqlite3IsNaN(r) ){ + /* SQLite considers NaN to be a NULL. And all integer values are greater + ** than NULL */ + return 1; + } + if( sqlite3Config.bUseLongDouble ){ LONGDOUBLE_TYPE x = (LONGDOUBLE_TYPE)i; testcase( xr ); testcase( x==r ); - if( xr ) return +1; /*NO_TEST*/ /* work around bugs in gcov */ - return 0; /*NO_TEST*/ /* work around bugs in gcov */ + return (xr); }else{ i64 y; double s; @@ -4422,9 +4501,10 @@ if( iy ) return +1; s = (double)i; - if( sr ) return +1; - return 0; + testcase( doubleLt(s,r) ); + testcase( doubleLt(r,s) ); + testcase( doubleEq(r,s) ); + return (sr); } } @@ -4445,7 +4525,7 @@ f2 = pMem2->flags; combined_flags = f1|f2; assert( !sqlite3VdbeMemIsRowSet(pMem1) && !sqlite3VdbeMemIsRowSet(pMem2) ); - + /* If one value is NULL, it is less than the other. If both values ** are NULL, return 0. */ @@ -4508,7 +4588,7 @@ } assert( pMem1->enc==pMem2->enc || pMem1->db->mallocFailed ); - assert( pMem1->enc==SQLITE_UTF8 || + assert( pMem1->enc==SQLITE_UTF8 || pMem1->enc==SQLITE_UTF16LE || pMem1->enc==SQLITE_UTF16BE ); /* The collation sequence must be defined at this point, even if @@ -4523,7 +4603,7 @@ /* If a NULL pointer was passed as the collate function, fall through ** to the blob case and use memcmp(). */ } - + /* Both values must be blobs. Compare using memcmp(). */ return sqlite3BlobCompare(pMem1, pMem2); } @@ -4531,7 +4611,7 @@ /* ** The first argument passed to this function is a serial-type that -** corresponds to an integer - all values between 1 and 9 inclusive +** corresponds to an integer - all values between 1 and 9 inclusive ** except 7. The second points to a buffer containing an integer value ** serialized according to serial_type. This function deserializes ** and returns the value. @@ -4573,7 +4653,7 @@ /* ** This function compares the two table rows or index records ** specified by {nKey1, pKey1} and pPKey2. It returns a negative, zero -** or positive integer if key1 is less than, equal to or +** or positive integer if key1 is less than, equal to or ** greater than key2. The {nKey1, pKey1} key must be a blob ** created by the OP_MakeRecord opcode of the VDBE. The pPKey2 ** key must be a parsed key such as obtained from @@ -4582,12 +4662,12 @@ ** If argument bSkip is non-zero, it is assumed that the caller has already ** determined that the first fields of the keys are equal. ** -** Key1 and Key2 do not have to contain the same number of fields. If all -** fields that appear in both keys are equal, then pPKey2->default_rc is +** Key1 and Key2 do not have to contain the same number of fields. If all +** fields that appear in both keys are equal, then pPKey2->default_rc is ** returned. ** -** If database corruption is discovered, set pPKey2->errCode to -** SQLITE_CORRUPT and return 0. If an OOM error is encountered, +** If database corruption is discovered, set pPKey2->errCode to +** SQLITE_CORRUPT and return 0. If an OOM error is encountered, ** pPKey2->errCode is set to SQLITE_NOMEM and, if it is not NULL, the ** malloc-failed flag set on database handle (pPKey2->pKeyInfo->db). */ @@ -4629,13 +4709,13 @@ d1 = szHdr1; i = 0; } - if( d1>(unsigned)nKey1 ){ + if( d1>(unsigned)nKey1 ){ pPKey2->errCode = (u8)SQLITE_CORRUPT_BKPT; return 0; /* Corruption */ } VVA_ONLY( mem1.szMalloc = 0; ) /* Only needed by assert() statements */ - assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField + assert( pPKey2->pKeyInfo->nAllField>=pPKey2->nField || CORRUPT_DB ); assert( pPKey2->pKeyInfo->aSortFlags!=0 ); assert( pPKey2->pKeyInfo->nKeyField>0 ); @@ -4672,9 +4752,9 @@ 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 + ** numbers). Types 10 and 11 are currently "reserved for future ** use", so it doesn't really matter what the results of comparing - ** them to numberic values are. */ + ** them to numeric values are. */ rc = serial_type==10 ? -1 : +1; }else if( serial_type==0 ){ rc = -1; @@ -4720,7 +4800,7 @@ }else{ int nCmp = MIN(mem1.n, pRhs->n); rc = memcmp(&aKey1[d1], pRhs->z, nCmp); - if( rc==0 ) rc = mem1.n - pRhs->n; + if( rc==0 ) rc = mem1.n - pRhs->n; } } } @@ -4794,8 +4874,8 @@ /* rc==0 here means that one or both of the keys ran out of fields and ** all the fields up to that point were equal. Return the default_rc ** value. */ - assert( CORRUPT_DB - || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) + assert( CORRUPT_DB + || vdbeRecordCompareDebug(nKey1, pKey1, pPKey2, pPKey2->default_rc) || pPKey2->pKeyInfo->db->mallocFailed ); pPKey2->eqSeen = 1; @@ -4810,8 +4890,8 @@ /* -** This function is an optimized version of sqlite3VdbeRecordCompare() -** that (a) the first field of pPKey2 is an integer, and (b) the +** This function is an optimized version of sqlite3VdbeRecordCompare() +** that (a) the first field of pPKey2 is an integer, and (b) the ** size-of-header varint at the start of (pKey1/nKey1) fits in a single ** byte (i.e. is less than 128). ** @@ -4866,7 +4946,7 @@ testcase( lhs<0 ); break; } - case 8: + case 8: lhs = 0; break; case 9: @@ -4874,11 +4954,11 @@ break; /* This case could be removed without changing the results of running - ** this code. Including it causes gcc to generate a faster switch + ** this code. Including it causes gcc to generate a faster switch ** statement (since the range of switch targets now starts at zero and ** is contiguous) but does not cause any duplicate code to be generated - ** (as gcc is clever enough to combine the two like cases). Other - ** compilers might be similar. */ + ** (as gcc is clever enough to combine the two like cases). Other + ** compilers might be similar. */ case 0: case 7: return sqlite3VdbeRecordCompare(nKey1, pKey1, pPKey2); @@ -4893,7 +4973,7 @@ }else if( vr2; }else if( pPKey2->nField>1 ){ - /* The first fields of the two keys are equal. Compare the trailing + /* The first fields of the two keys are equal. Compare the trailing ** fields. */ res = sqlite3VdbeRecordCompareWithSkip(nKey1, pKey1, pPKey2, 1); }else{ @@ -4908,9 +4988,9 @@ } /* -** This function is an optimized version of sqlite3VdbeRecordCompare() +** This function is an optimized version of sqlite3VdbeRecordCompare() ** that (a) the first field of pPKey2 is a string, that (b) the first field -** uses the collation sequence BINARY and (c) that the size-of-header varint +** uses the collation sequence BINARY and (c) that the size-of-header varint ** at the start of (pKey1/nKey1) fits in a single byte. */ static int vdbeRecordCompareString( @@ -4935,7 +5015,7 @@ assert( CORRUPT_DB ); } res = pPKey2->r1; /* (pKey1/nKey1) is a number or a null */ - }else if( !(serial_type & 0x01) ){ + }else if( !(serial_type & 0x01) ){ res = pPKey2->r2; /* (pKey1/nKey1) is a blob */ }else{ int nCmp; @@ -4987,7 +5067,7 @@ /* varintRecordCompareInt() and varintRecordCompareString() both assume ** that the size-of-header varint that occurs at the start of each record ** fits in a single byte (i.e. is 127 or less). varintRecordCompareInt() - ** also assumes that it is safe to overread a buffer by at least the + ** also assumes that it is safe to overread a buffer by at least the ** maximum possible legal header size plus 8 bytes. Because there is ** guaranteed to be at least 74 (but not 136) bytes of padding following each ** buffer passed to varintRecordCompareInt() this makes it convenient to @@ -5048,7 +5128,7 @@ /* Get the size of the index entry. Only indices entries of less ** than 2GiB are support - anything large must be database corruption. ** Any corruption is detected in sqlite3BtreeParseCellPtr(), though, so - ** this code can safely assume that nCellKey is 32-bits + ** this code can safely assume that nCellKey is 32-bits */ assert( sqlite3BtreeCursorIsValid(pCur) ); nCellKey = sqlite3BtreePayloadSize(pCur); @@ -5113,7 +5193,7 @@ ** ** pUnpacked is either created without a rowid or is truncated so that it ** omits the rowid at the end. The rowid at the end of the index entry -** is ignored as well. Hence, this routine only compares the prefixes +** is ignored as well. Hence, this routine only compares the prefixes ** of the keys prior to the final rowid, not the entire key. */ int sqlite3VdbeIdxKeyCompare( @@ -5149,7 +5229,7 @@ /* ** This routine sets the value to be returned by subsequent calls to -** sqlite3_changes() on the database handle 'db'. +** sqlite3_changes() on the database handle 'db'. */ void sqlite3VdbeSetChanges(sqlite3 *db, i64 nChange){ assert( sqlite3_mutex_held(db->mutex) ); @@ -5206,7 +5286,7 @@ /* ** Return a pointer to an sqlite3_value structure containing the value bound -** parameter iVar of VM v. Except, if the value is an SQL NULL, return +** parameter iVar of VM v. Except, if the value is an SQL NULL, return ** 0 instead. Unless it is NULL, apply affinity aff (one of the SQLITE_AFF_* ** constants) to the value before returning it. ** @@ -5281,7 +5361,7 @@ #if defined(SQLITE_ENABLE_CURSOR_HINTS) && defined(SQLITE_DEBUG) /* ** This Walker callback is used to help verify that calls to -** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have +** sqlite3BtreeCursorHint() with opcode BTREE_HINT_RANGE have ** byte-code register values correctly initialized. */ int sqlite3CursorRangeHintExprCheck(Walker *pWalker, Expr *pExpr){ @@ -5312,7 +5392,7 @@ #ifdef SQLITE_ENABLE_PREUPDATE_HOOK /* -** If the second argument is not NULL, release any allocations associated +** If the second argument is not NULL, release any allocations associated ** with the memory cells in the p->aMem[] array. Also free the UnpackedRecord ** structure itself, using sqlite3DbFree(). ** @@ -5380,7 +5460,7 @@ assert( pCsr!=0 ); assert( pCsr->eCurType==CURTYPE_BTREE ); - assert( pCsr->nField==nRealCol + assert( pCsr->nField==nRealCol || (pCsr->nField==nRealCol+1 && op==SQLITE_DELETE && iReg==-1) ); diff -Nru sqlite3-3.42.0/src/vdbeblob.c sqlite3-3.44.0-0/src/vdbeblob.c --- sqlite3-3.42.0/src/vdbeblob.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbeblob.c 2023-11-04 14:23:58.000000000 +0000 @@ -59,8 +59,7 @@ /* Set the value of register r[1] in the SQL statement to integer iRow. ** This is done directly as a performance optimization */ - v->aMem[1].flags = MEM_Int; - v->aMem[1].u.i = iRow; + sqlite3VdbeMemSetInt64(&v->aMem[1], iRow); /* If the statement has been run before (and is paused at the OP_ResultRow) ** then back it up to the point where it does the OP_NotExists. This could @@ -143,7 +142,7 @@ #endif *ppBlob = 0; #ifdef SQLITE_ENABLE_API_ARMOR - if( !sqlite3SafetyCheckOk(db) || zTable==0 ){ + if( !sqlite3SafetyCheckOk(db) || zTable==0 || zColumn==0 ){ return SQLITE_MISUSE_BKPT; } #endif diff -Nru sqlite3-3.42.0/src/vdbe.c sqlite3-3.44.0-0/src/vdbe.c --- sqlite3-3.42.0/src/vdbe.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbe.c 2023-11-04 14:23:58.000000000 +0000 @@ -154,7 +154,7 @@ ** ** In other words, if M is 2, then I is either 0 (for fall-through) or ** 1 (for when the branch is taken). If M is 3, the I is 0 for an -** ordinary fall-through, I is 1 if the branch was taken, and I is 2 +** ordinary fall-through, I is 1 if the branch was taken, and I is 2 ** if the result of comparison is NULL. For M=3, I=2 the jump may or ** may not be taken, depending on the SQLITE_JUMPIFNULL flags in p5. ** When M is 4, that means that an OP_Jump is being run. I is 0, 1, or 2 @@ -247,7 +247,7 @@ u8 eCurType /* Type of the new cursor */ ){ /* Find the memory cell that will be used to store the blob of memory - ** required for this VdbeCursor structure. It is convenient to use a + ** required for this VdbeCursor structure. It is convenient to use a ** vdbe memory cell to manage the memory allocation required for a ** VdbeCursor structure for the following reasons: ** @@ -268,8 +268,8 @@ int nByte; VdbeCursor *pCx = 0; - nByte = - ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + + nByte = + ROUND8P(sizeof(VdbeCursor)) + 2*sizeof(u32)*nField + (eCurType==CURTYPE_BTREE?sqlite3BtreeCursorSize():0); assert( iCur>=0 && iCurnCursor ); @@ -368,7 +368,7 @@ ** SQLITE_AFF_INTEGER: ** SQLITE_AFF_REAL: ** SQLITE_AFF_NUMERIC: -** Try to convert pRec to an integer representation or a +** Try to convert pRec to an integer representation or a ** floating-point representation if an integer representation ** is not possible. Note that the integer representation is ** always preferred, even if the affinity is REAL, because @@ -403,7 +403,7 @@ }else if( affinity==SQLITE_AFF_TEXT ){ /* Only attempt the conversion to TEXT if there is an integer or real ** representation (blob and NULL do not get converted) but no string - ** representation. It would be harmless to repeat the conversion if + ** representation. It would be harmless to repeat the conversion if ** there is already a string rep, but it is pointless to waste those ** CPU cycles. */ if( 0==(pRec->flags&MEM_Str) ){ /*OPTIMIZATION-IF-FALSE*/ @@ -435,12 +435,12 @@ } /* -** Exported version of applyAffinity(). This one works on sqlite3_value*, +** Exported version of applyAffinity(). This one works on sqlite3_value*, ** not the internal Mem* type. */ void sqlite3ValueApplyAffinity( - sqlite3_value *pVal, - u8 affinity, + sqlite3_value *pVal, + u8 affinity, u8 enc ){ applyAffinity((Mem *)pVal, affinity, enc); @@ -478,7 +478,7 @@ /* ** Return the numeric type for pMem, either MEM_Int or MEM_Real or both or -** none. +** none. ** ** Unlike applyNumericAffinity(), this routine does not modify pMem->flags. ** But it does set pMem->u.r and pMem->u.i appropriately. @@ -556,6 +556,9 @@ sqlite3_str_appendchar(pStr, 1, (c>=0x20&&c<=0x7f) ? c : '.'); } sqlite3_str_appendf(pStr, "]%s", encnames[pMem->enc]); + if( f & MEM_Term ){ + sqlite3_str_appendf(pStr, "(0-term)"); + } } } #endif @@ -628,9 +631,9 @@ /* ** This function is only called from within an assert() expression. It ** checks that the sqlite3.nTransaction variable is correctly set to -** the number of non-transaction savepoints currently in the +** the number of non-transaction savepoints currently in the ** linked list starting at sqlite3.pSavepoint. -** +** ** Usage: ** ** assert( checkSavepointCount(db) ); @@ -692,6 +695,93 @@ return h; } + +/* +** For OP_Column, factor out the case where content is loaded from +** overflow pages, so that the code to implement this case is separate +** the common case where all content fits on the page. Factoring out +** the code reduces register pressure and helps the common case +** to run faster. +*/ +static SQLITE_NOINLINE int vdbeColumnFromOverflow( + VdbeCursor *pC, /* The BTree cursor from which we are reading */ + int iCol, /* The column to read */ + int t, /* The serial-type code for the column value */ + i64 iOffset, /* Offset to the start of the content value */ + u32 cacheStatus, /* Current Vdbe.cacheCtr value */ + u32 colCacheCtr, /* Current value of the column cache counter */ + Mem *pDest /* Store the value into this register. */ +){ + int rc; + sqlite3 *db = pDest->db; + int encoding = pDest->enc; + int len = sqlite3VdbeSerialTypeLen(t); + assert( pC->eCurType==CURTYPE_BTREE ); + if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) return SQLITE_TOOBIG; + if( len > 4000 && pC->pKeyInfo==0 ){ + /* Cache large column values that are on overflow pages using + ** an RCStr (reference counted string) so that if they are reloaded, + ** that do not have to be copied a second time. The overhead of + ** creating and managing the cache is such that this is only + ** profitable for larger TEXT and BLOB values. + ** + ** Only do this on table-btrees so that writes to index-btrees do not + ** need to clear the cache. This buys performance in the common case + ** in exchange for generality. + */ + VdbeTxtBlbCache *pCache; + char *pBuf; + if( pC->colCache==0 ){ + pC->pCache = sqlite3DbMallocZero(db, sizeof(VdbeTxtBlbCache) ); + if( pC->pCache==0 ) return SQLITE_NOMEM; + pC->colCache = 1; + } + pCache = pC->pCache; + if( pCache->pCValue==0 + || pCache->iCol!=iCol + || pCache->cacheStatus!=cacheStatus + || pCache->colCacheCtr!=colCacheCtr + || pCache->iOffset!=sqlite3BtreeOffset(pC->uc.pCursor) + ){ + if( pCache->pCValue ) sqlite3RCStrUnref(pCache->pCValue); + pBuf = pCache->pCValue = sqlite3RCStrNew( len+3 ); + if( pBuf==0 ) return SQLITE_NOMEM; + rc = sqlite3BtreePayload(pC->uc.pCursor, iOffset, len, pBuf); + if( rc ) return rc; + pBuf[len] = 0; + pBuf[len+1] = 0; + pBuf[len+2] = 0; + pCache->iCol = iCol; + pCache->cacheStatus = cacheStatus; + pCache->colCacheCtr = colCacheCtr; + pCache->iOffset = sqlite3BtreeOffset(pC->uc.pCursor); + }else{ + pBuf = pCache->pCValue; + } + assert( t>=12 ); + sqlite3RCStrRef(pBuf); + if( t&1 ){ + rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, encoding, + sqlite3RCStrUnref); + pDest->flags |= MEM_Term; + }else{ + rc = sqlite3VdbeMemSetStr(pDest, pBuf, len, 0, + sqlite3RCStrUnref); + } + }else{ + rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, iOffset, len, pDest); + if( rc ) return rc; + sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); + if( (t&1)!=0 && encoding==SQLITE_UTF8 ){ + pDest->z[len] = 0; + pDest->flags |= MEM_Term; + } + } + pDest->flags &= ~MEM_Ephem; + return rc; +} + + /* ** Return the symbolic name for the data type of a pMem */ @@ -708,7 +798,7 @@ /* ** Execute as much of a VDBE program as we can. -** This is the core of sqlite3_step(). +** This is the core of sqlite3_step(). */ int sqlite3VdbeExec( Vdbe *p /* The VDBE */ @@ -734,6 +824,7 @@ Mem *pIn2 = 0; /* 2nd input operand */ Mem *pIn3 = 0; /* 3rd input operand */ Mem *pOut = 0; /* Output operand */ + u32 colCacheCtr = 0; /* Column cache counter */ #if defined(SQLITE_ENABLE_STMT_SCANSTATUS) || defined(VDBE_PROFILE) u64 *pnCycle = 0; int bStmtScanStatus = IS_STMT_SCANSTATUS(db)!=0; @@ -822,7 +913,7 @@ test_trace_breakpoint((int)(pOp - aOp),pOp,p); } #endif - + /* Check to see if we need to simulate an interrupt. This only happens ** if we have a special test build. @@ -876,7 +967,7 @@ #ifdef SQLITE_DEBUG pOrigOp = pOp; #endif - + switch( pOp->opcode ){ /***************************************************************************** @@ -917,7 +1008,7 @@ /* Opcode: Goto * P2 * * * ** ** An unconditional jump to address P2. -** The next instruction executed will be +** The next instruction executed will be ** the one at index P2 from the beginning of ** the program. ** @@ -929,8 +1020,8 @@ case OP_Goto: { /* jump */ #ifdef SQLITE_DEBUG - /* In debuggging mode, when the p5 flags is set on an OP_Goto, that - ** means we should really jump back to the preceeding OP_ReleaseReg + /* In debugging mode, when the p5 flags is set on an OP_Goto, that + ** means we should really jump back to the preceding OP_ReleaseReg ** instruction. */ if( pOp->p5 ){ assert( pOp->p2 < (int)(pOp - aOp) ); @@ -947,7 +1038,7 @@ /* Opcodes that are used as the bottom of a loop (OP_Next, OP_Prev, ** OP_VNext, or OP_SorterNext) all jump here upon ** completion. Check to see if sqlite3_interrupt() has been called - ** or if the progress callback needs to be invoked. + ** or if the progress callback needs to be invoked. ** ** This code uses unstructured "goto" statements and does not look clean. ** But that is not due to sloppy coding habits. The code is written this @@ -973,7 +1064,7 @@ } } #endif - + break; } @@ -1131,14 +1222,14 @@ ** whether or not to rollback the current transaction. Do not rollback ** if P2==OE_Fail. Do the rollback if P2==OE_Rollback. If P2==OE_Abort, ** then back out all changes that have occurred during this execution of the -** VDBE, but do not rollback the transaction. +** 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 contraint failed: P4 +** 1: NOT NULL constraint failed: P4 ** 2: UNIQUE constraint failed: P4 ** 3: CHECK constraint failed: P4 ** 4: FOREIGN KEY constraint failed: P4 @@ -1171,7 +1262,7 @@ sqlite3VdbeSetChanges(db, p->nChange); pcx = sqlite3VdbeFrameRestore(pFrame); if( pOp->p2==OE_Ignore ){ - /* Instruction pcx is the OP_Program that invoked the sub-program + /* Instruction pcx is the OP_Program that invoked the sub-program ** currently being halted. If the p2 instruction of this OP_Halt ** instruction is set to OE_Ignore, then the sub-program is throwing ** an IGNORE exception. In this case jump to the address specified @@ -1259,7 +1350,7 @@ /* Opcode: String8 * P2 * P4 * ** Synopsis: r[P2]='P4' ** -** P4 points to a nul terminated UTF-8 string. This opcode is transformed +** P4 points to a nul terminated UTF-8 string. This opcode is transformed ** into a String opcode before it is executed for the first time. During ** this transformation, the length of string P4 is computed and stored ** as the P1 parameter. @@ -1295,7 +1386,7 @@ /* Fall through to the next case, OP_String */ /* no break */ deliberate_fall_through } - + /* Opcode: String P1 P2 P3 P4 P5 ** Synopsis: r[P2]='P4' (len=P1) ** @@ -1579,7 +1670,7 @@ ** ** FK constraint violations are also checked when the prepared statement ** exits. This opcode is used to raise foreign key constraint errors prior -** to returning results such as a row change count or the result of a +** to returning results such as a row change count or the result of a ** RETURNING clause. */ case OP_FkCheck: { @@ -1727,15 +1818,15 @@ ** Synopsis: r[P3]=r[P2]/r[P1] ** ** Divide the value in register P1 by the value in register P2 -** and store the result in register P3 (P3=P2/P1). If the value in -** register P1 is zero, then the result is NULL. If either input is +** and store the result in register P3 (P3=P2/P1). If the value in +** register P1 is zero, then the result is NULL. If either input is ** NULL, the result is NULL. */ /* Opcode: Remainder P1 P2 P3 * * ** Synopsis: r[P3]=r[P2]%r[P1] ** -** Compute the remainder after integer register P2 is divided by -** register P1 and store the result in register P3. +** Compute the remainder after integer register P2 is divided by +** register P1 and store the result in register P3. ** If the value in register P1 is zero the result is NULL. ** If either operand is NULL, the result is NULL. */ @@ -1932,7 +2023,7 @@ /* Opcode: AddImm P1 P2 * * * ** Synopsis: r[P1]=r[P1]+P2 -** +** ** Add the constant P2 to the value in register P1. ** The result is always an integer. ** @@ -1947,7 +2038,7 @@ } /* Opcode: MustBeInt P1 P2 * * * -** +** ** Force the value in register P1 to be an integer. If the value ** in P1 is not an integer and cannot be converted into an integer ** without data loss, then jump immediately to P2, or if P2==0 @@ -1999,7 +2090,7 @@ ** Synopsis: affinity(r[P1]) ** ** Force the value in register P1 to be the type defined by P2. -** +** **
      **
    • P2=='A' → BLOB **
    • P2=='B' → TEXT @@ -2033,17 +2124,17 @@ ** Synopsis: IF r[P3]==r[P1] ** ** Compare the values in register P1 and P3. If reg(P3)==reg(P1) then -** jump to address P2. +** jump to address P2. ** ** The SQLITE_AFF_MASK portion of P5 must be an affinity character - -** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made +** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made ** to coerce both inputs according to this affinity before the ** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric ** affinity is used. Note that the affinity conversions are stored ** back into the input registers P1 and P3. So this opcode can cause ** persistent changes to registers P1 and P3. ** -** Once any conversions have taken place, and neither value is NULL, +** Once any conversions have taken place, and neither value is NULL, ** the values are compared. If both values are blobs then memcmp() is ** used to determine the results of the comparison. If both values ** are text, then the appropriate collating function specified in @@ -2076,18 +2167,18 @@ ** jump to address P2. ** ** If the SQLITE_JUMPIFNULL bit of P5 is set and either reg(P1) or -** reg(P3) is NULL then the take the jump. If the SQLITE_JUMPIFNULL +** reg(P3) is NULL then the take the jump. If the SQLITE_JUMPIFNULL ** bit is clear then fall through if either operand is NULL. ** ** The SQLITE_AFF_MASK portion of P5 must be an affinity character - -** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made +** SQLITE_AFF_TEXT, SQLITE_AFF_INTEGER, and so forth. An attempt is made ** to coerce both inputs according to this affinity before the ** comparison is made. If the SQLITE_AFF_MASK is 0x00, then numeric ** affinity is used. Note that the affinity conversions are stored ** back into the input registers P1 and P3. So this opcode can cause ** persistent changes to registers P1 and P3. ** -** Once any conversions have taken place, and neither value is NULL, +** Once any conversions have taken place, and neither value is NULL, ** the values are compared. If both values are blobs then memcmp() is ** used to determine the results of the comparison. If both values ** are text, then the appropriate collating function specified in @@ -2267,12 +2358,12 @@ ** This opcode must follow an OP_Lt or OP_Gt comparison operator. There ** can be zero or more OP_ReleaseReg opcodes intervening, but no other ** opcodes are allowed to occur between this instruction and the previous -** OP_Lt or OP_Gt. +** OP_Lt or OP_Gt. ** -** If result of an OP_Eq comparison on the same two operands as the -** prior OP_Lt or OP_Gt would have been true, then jump to P2. -** If the result of an OP_Eq comparison on the two previous -** operands would have been false or NULL, then fall through. +** If the result of an OP_Eq comparison on the same two operands as +** the prior OP_Lt or OP_Gt would have been true, then jump to P2. If +** the result of an OP_Eq comparison on the two previous operands +** would have been false or NULL, then fall through. */ case OP_ElseEq: { /* same as TK_ESCAPE, jump */ @@ -2383,7 +2474,7 @@ iCompare = sqlite3MemCompare(&aMem[p1+idx], &aMem[p2+idx], pColl); VVA_ONLY( iCompareIsInit = 1; ) if( iCompare ){ - if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) + if( (pKeyInfo->aSortFlags[i] & KEYINFO_ORDER_BIGNULL) && ((aMem[p1+idx].flags & MEM_Null) || (aMem[p2+idx].flags & MEM_Null)) ){ iCompare = -iCompare; @@ -2468,13 +2559,13 @@ ** IS NOT FALSE operators. ** ** Interpret the value in register P1 as a boolean value. Store that -** boolean (a 0 or 1) in register P2. Or if the value in register P1 is +** boolean (a 0 or 1) in register P2. Or if the value in register P1 is ** NULL, then the P3 is stored in register P2. Invert the answer if P4 ** is 1. ** ** The logic is summarized like this: ** -**
        +**
          **
        • If P3==0 and P4==0 then r[P2] := r[P1] IS TRUE **
        • If P3==1 and P4==1 then r[P2] := r[P1] IS FALSE **
        • If P3==0 and P4==1 then r[P2] := r[P1] IS NOT TRUE @@ -2494,7 +2585,7 @@ ** Synopsis: r[P2]= !r[P1] ** ** Interpret the value in register P1 as a boolean value. Store the -** boolean complement in register P2. If the value in register P1 is +** boolean complement in register P2. If the value in register P1 is ** NULL, then a NULL is stored in P2. */ case OP_Not: { /* same as TK_NOT, in1, out2 */ @@ -2702,7 +2793,7 @@ /* Opcode: ZeroOrNull P1 P2 P3 * * ** Synopsis: r[P2] = 0 OR NULL ** -** If all both registers P1 and P3 are NOT NULL, then store a zero in +** If both registers P1 and P3 are NOT NULL, then store a zero in ** register P2. If either registers P1 or P3 are NULL then put ** a NULL in register P2. */ @@ -2720,7 +2811,7 @@ /* Opcode: NotNull P1 P2 * * * ** Synopsis: if r[P1]!=NULL goto P2 ** -** Jump to P2 if the value in register P1 is not NULL. +** Jump to P2 if the value in register P1 is not NULL. */ case OP_NotNull: { /* same as TK_NOTNULL, jump, in1 */ pIn1 = &aMem[pOp->p1]; @@ -2796,7 +2887,7 @@ ** Interpret the data that cursor P1 points to as a structure built using ** the MakeRecord instruction. (See the MakeRecord opcode for additional ** information about the format of the data.) Extract the P2-th column -** from this record. If there are less than (P2+1) +** from this record. If there are less than (P2+1) ** values in the record, extract a NULL. ** ** The value extracted is stored in register P3. @@ -2942,7 +3033,7 @@ */ if( pC->nHdrParsed<=p2 ){ /* If there is more header available for parsing in the record, try - ** to extract additional fields up through the p2+1-th field + ** to extract additional fields up through the p2+1-th field */ if( pC->iHdrOffsetaRow; } - + /* Fill in pC->aType[i] and aOffset[i] values through the p2-th field. */ op_column_read_header: i = pC->nHdrParsed; @@ -3056,18 +3147,23 @@ pDest->flags = aFlag[t&1]; } }else{ + u8 p5; pDest->enc = encoding; + assert( pDest->db==db ); /* This branch happens only when content is on overflow pages */ - if( ((pOp->p5 & (OPFLAG_LENGTHARG|OPFLAG_TYPEOFARG))!=0 - && ((t>=12 && (t&1)==0) || (pOp->p5 & OPFLAG_TYPEOFARG)!=0)) - || (len = sqlite3VdbeSerialTypeLen(t))==0 + if( ((p5 = (pOp->p5 & OPFLAG_BYTELENARG))!=0 + && (p5==OPFLAG_TYPEOFARG + || (t>=12 && ((t&1)==0 || p5==OPFLAG_BYTELENARG)) + ) + ) + || sqlite3VdbeSerialTypeLen(t)==0 ){ /* Content is irrelevant for ** 1. the typeof() function, ** 2. the length(X) function if X is a blob, and ** 3. if the content length is zero. ** So we might as well use bogus content rather than reading - ** content from disk. + ** content from disk. ** ** Although sqlite3VdbeSerialGet() may read at most 8 bytes from the ** buffer passed to it, debugging function VdbeMemPrettyPrint() may @@ -3077,11 +3173,13 @@ */ sqlite3VdbeSerialGet((u8*)sqlite3CtypeMap, t, pDest); }else{ - if( len>db->aLimit[SQLITE_LIMIT_LENGTH] ) goto too_big; - rc = sqlite3VdbeMemFromBtree(pC->uc.pCursor, aOffset[p2], len, pDest); - if( rc!=SQLITE_OK ) goto abort_due_to_error; - sqlite3VdbeSerialGet((const u8*)pDest->z, t, pDest); - pDest->flags &= ~MEM_Ephem; + rc = vdbeColumnFromOverflow(pC, p2, t, aOffset[p2], + p->cacheCtr, colCacheCtr, pDest); + if( rc ){ + if( rc==SQLITE_NOMEM ) goto no_mem; + if( rc==SQLITE_TOOBIG ) goto too_big; + goto abort_due_to_error; + } } } @@ -3298,13 +3396,13 @@ ** like this: ** ** ------------------------------------------------------------------------ - ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | + ** | hdr-size | type 0 | type 1 | ... | type N-1 | data0 | ... | data N-1 | ** ------------------------------------------------------------------------ ** ** Data(0) is taken from register P1. Data(1) comes from register P1+1 ** and so forth. ** - ** Each type field is a varint representing the serial type of the + ** Each type field is a varint representing the serial type of the ** corresponding data element (see sqlite3VdbeSerialType()). The ** hdr-size field is also a varint which is the offset from the beginning ** of the record to data0. @@ -3494,7 +3592,7 @@ } nByte = nHdr+nData; - /* Make sure the output register has a buffer large enough to store + /* Make sure the output register has a buffer large enough to store ** the new record. The output register (pOp->p3) is not allowed to ** be one of the input registers (because the following call to ** sqlite3VdbeMemClearAndResize() could clobber the value before it is used). @@ -3543,7 +3641,6 @@ /* NULL value. No change in zPayload */ }else{ u64 v; - u32 i; if( serial_type==7 ){ assert( sizeof(v)==sizeof(pRec->u.r) ); memcpy(&v, &pRec->u.r, sizeof(v)); @@ -3551,12 +3648,17 @@ }else{ v = pRec->u.i; } - len = i = sqlite3SmallTypeSizes[serial_type]; - assert( i>0 ); - while( 1 /*exit-by-break*/ ){ - zPayload[--i] = (u8)(v&0xFF); - if( i==0 ) break; - v >>= 8; + len = sqlite3SmallTypeSizes[serial_type]; + assert( len>=1 && len<=8 && len!=5 && len!=7 ); + switch( len ){ + default: zPayload[7] = (u8)(v&0xff); v >>= 8; + zPayload[6] = (u8)(v&0xff); v >>= 8; + case 6: zPayload[5] = (u8)(v&0xff); v >>= 8; + zPayload[4] = (u8)(v&0xff); v >>= 8; + case 4: zPayload[3] = (u8)(v&0xff); v >>= 8; + case 3: zPayload[2] = (u8)(v&0xff); v >>= 8; + case 2: zPayload[1] = (u8)(v&0xff); v >>= 8; + case 1: zPayload[0] = (u8)(v&0xff); } zPayload += len; } @@ -3589,12 +3691,12 @@ /* Opcode: Count P1 P2 P3 * * ** Synopsis: r[P2]=count() ** -** Store the number of entries (an integer value) in the table or index +** Store the number of entries (an integer value) in the table or index ** opened by cursor P1 in register P2. ** ** If P3==0, then an exact count is obtained, which involves visiting ** every btree page of the table. But if P3 is non-zero, an estimate -** is returned based on the current cursor position. +** is returned based on the current cursor position. */ case OP_Count: { /* out2 */ i64 nEntry; @@ -3636,7 +3738,7 @@ zName = pOp->p4.z; /* Assert that the p1 parameter is valid. Also that if there is no open - ** transaction, then there cannot be any savepoints. + ** transaction, then there cannot be any savepoints. */ assert( db->pSavepoint==0 || db->autoCommit==0 ); assert( p1==SAVEPOINT_BEGIN||p1==SAVEPOINT_RELEASE||p1==SAVEPOINT_ROLLBACK ); @@ -3646,7 +3748,7 @@ if( p1==SAVEPOINT_BEGIN ){ if( db->nVdbeWrite>0 ){ - /* A new savepoint cannot be created if there are active write + /* A new savepoint cannot be created if there are active write ** statements (i.e. open read/write incremental blob handles). */ sqlite3VdbeError(p, "cannot open savepoint - SQL statements in progress"); @@ -3670,7 +3772,7 @@ if( pNew ){ pNew->zName = (char *)&pNew[1]; memcpy(pNew->zName, zName, nName+1); - + /* If there is no open transaction, then mark this as a special ** "transaction savepoint". */ if( db->autoCommit ){ @@ -3694,7 +3796,7 @@ /* Find the named savepoint. If there is no such savepoint, then an ** an error is returned to the user. */ for( - pSavepoint = db->pSavepoint; + pSavepoint = db->pSavepoint; pSavepoint && sqlite3StrICmp(pSavepoint->zName, zName); pSavepoint = pSavepoint->pNext ){ @@ -3704,7 +3806,7 @@ sqlite3VdbeError(p, "no such savepoint: %s", zName); rc = SQLITE_ERROR; }else if( db->nVdbeWrite>0 && p1==SAVEPOINT_RELEASE ){ - /* It is not possible to release (commit) a savepoint if there are + /* It is not possible to release (commit) a savepoint if there are ** active write statements. */ sqlite3VdbeError(p, "cannot release savepoint - " @@ -3713,8 +3815,8 @@ }else{ /* Determine whether or not this is a transaction savepoint. If so, - ** and this is a RELEASE command, then the current transaction - ** is committed. + ** and this is a RELEASE command, then the current transaction + ** is committed. */ int isTransaction = pSavepoint->pNext==0 && db->isTransactionSavepoint; if( isTransaction && p1==SAVEPOINT_RELEASE ){ @@ -3762,8 +3864,8 @@ } } if( rc ) goto abort_due_to_error; - - /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all + + /* Regardless of whether this is a RELEASE or ROLLBACK, destroy all ** savepoints nested inside of the savepoint being operated on. */ while( db->pSavepoint!=pSavepoint ){ pTmp = db->pSavepoint; @@ -3772,8 +3874,8 @@ db->nSavepoint--; } - /* If it is a RELEASE, then destroy the savepoint being operated on - ** too. If it is a ROLLBACK TO, then set the number of deferred + /* If it is a RELEASE, then destroy the savepoint being operated on + ** too. If it is a ROLLBACK TO, then set the number of deferred ** constraint violations present in the database to the value stored ** when the savepoint was created. */ if( p1==SAVEPOINT_RELEASE ){ @@ -3830,7 +3932,7 @@ db->autoCommit = 1; }else if( desiredAutoCommit && db->nVdbeWrite>0 ){ /* If this instruction implements a COMMIT and other VMs are writing - ** return an error indicating that the other VMs must complete first. + ** return an error indicating that the other VMs must complete first. */ sqlite3VdbeError(p, "cannot commit transaction - " "SQL statements in progress"); @@ -3859,7 +3961,7 @@ (!desiredAutoCommit)?"cannot start a transaction within a transaction":( (iRollback)?"cannot rollback - no transaction is active": "cannot commit - no transaction is active")); - + rc = SQLITE_ERROR; goto abort_due_to_error; } @@ -3870,7 +3972,7 @@ ** ** Begin a transaction on database P1 if a transaction is not already ** active. -** If P2 is non-zero, then a write-transaction is started, or if a +** If P2 is non-zero, then a write-transaction is started, or if a ** read-transaction is already active, it is upgraded to a write-transaction. ** If P2 is zero, then a read-transaction is started. If P2 is 2 or more ** then an exclusive transaction is started. @@ -3941,12 +4043,12 @@ if( p->usesStmtJournal && pOp->p2 - && (db->autoCommit==0 || db->nVdbeRead>1) + && (db->autoCommit==0 || db->nVdbeRead>1) ){ assert( sqlite3BtreeTxnState(pBt)==SQLITE_TXN_WRITE ); if( p->iStatement==0 ){ assert( db->nStatement>=0 && db->nSavepoint>=0 ); - db->nStatement++; + db->nStatement++; p->iStatement = db->nSavepoint + db->nStatement; } @@ -3974,7 +4076,7 @@ */ sqlite3DbFree(db, p->zErrMsg); p->zErrMsg = sqlite3DbStrDup(db, "database schema has changed"); - /* If the schema-cookie from the database file matches the cookie + /* If the schema-cookie from the database file matches the cookie ** stored with the in-memory representation of the schema, do ** not reload the schema from the database file. ** @@ -3984,7 +4086,7 @@ ** prepared queries. If such a query is out-of-date, we do not want to ** discard the database schema, as the user code implementing the ** v-table would have to be ready for the sqlite3_vtab structure itself - ** to be invalidated whenever sqlite3_step() is called from within + ** to be invalidated whenever sqlite3_step() is called from within ** a v-table method. */ if( db->aDb[pOp->p1].pSchema->schema_cookie!=iMeta ){ @@ -4037,8 +4139,8 @@ ** ** Write the integer value P3 into cookie number P2 of database P1. ** P2==1 is the schema version. P2==2 is the database format. -** P2==3 is the recommended pager cache -** size, and so forth. P1==0 is the main database file and P1==1 is the +** P2==3 is the recommended pager cache +** size, and so forth. P1==0 is the main database file and P1==1 is the ** database file used to store temporary tables. ** ** A transaction must be started before executing this opcode. @@ -4084,8 +4186,8 @@ ** Synopsis: root=P2 iDb=P3 ** ** Open a read-only cursor for the database table whose root page is -** P2 in a database file. The database file is determined by P3. -** P3==0 means the main database, P3==1 means the database used for +** P2 in a database file. The database file is determined by P3. +** P3==0 means the main database, P3==1 means the database used for ** temporary tables, and P3>1 means used the corresponding attached ** database. Give the new cursor an identifier of P1. The P1 ** values need not be contiguous but all P1 values should be small integers. @@ -4099,10 +4201,10 @@ **
        ** ** The P4 value may be either an integer (P4_INT32) or a pointer to -** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo ** object, then table being opened must be an [index b-tree] where the -** KeyInfo object defines the content and collating -** sequence of that index b-tree. Otherwise, if P4 is an integer +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer ** value, then the table being opened must be a [table b-tree] with a ** number of columns no less than the value of P4. ** @@ -4138,10 +4240,10 @@ ** OPFLAG_P2ISREG bit is set in P5 - see below). ** ** The P4 value may be either an integer (P4_INT32) or a pointer to -** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo +** a KeyInfo structure (P4_KEYINFO). If it is a pointer to a KeyInfo ** object, then table being opened must be an [index b-tree] where the -** KeyInfo object defines the content and collating -** sequence of that index b-tree. Otherwise, if P4 is an integer +** KeyInfo object defines the content and collating +** sequence of that index b-tree. Otherwise, if P4 is an integer ** value, then the table being opened must be a [table b-tree] with a ** number of columns no less than the value of P4. ** @@ -4257,7 +4359,7 @@ /* Set the VdbeCursor.isTable variable. Previous versions of ** SQLite used to check if the root-page flags were sane at this point ** and report database corruption if they were not, but this check has - ** since moved into the btree layer. */ + ** since moved into the btree layer. */ pCur->isTable = pOp->p4type!=P4_KEYINFO; open_cursor_set_hints: @@ -4298,7 +4400,7 @@ pCx->ub.pBtx = pOrig->ub.pBtx; pCx->noReuse = 1; pOrig->noReuse = 1; - rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, + rc = sqlite3BtreeCursor(pCx->ub.pBtx, pCx->pgnoRoot, BTREE_WRCSR, pCx->pKeyInfo, pCx->uc.pCursor); /* The sqlite3BtreeCursor() routine can only fail for the first cursor ** opened for a database. Since there is already an open cursor when this @@ -4312,7 +4414,7 @@ ** Synopsis: nColumn=P2 ** ** Open a new cursor P1 to a transient table. -** The cursor is always opened read/write even if +** The cursor is always opened read/write even if ** the main database is read-only. The ephemeral ** table is deleted automatically when the cursor is closed. ** @@ -4346,7 +4448,7 @@ VdbeCursor *pCx; KeyInfo *pKeyInfo; - static const int vfsFlags = + static const int vfsFlags = SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE | SQLITE_OPEN_EXCLUSIVE | @@ -4365,7 +4467,7 @@ } pCx = p->apCsr[pOp->p1]; if( pCx && !pCx->noReuse && ALWAYS(pOp->p2<=pCx->nField) ){ - /* If the ephermeral table is already open and has no duplicates from + /* If the ephemeral table is already open and has no duplicates from ** OP_OpenDup, then erase all existing content so that the table is ** empty again, rather than creating a new table. */ assert( pCx->isEphemeral ); @@ -4376,7 +4478,7 @@ pCx = allocateCursor(p, pOp->p1, pOp->p2, CURTYPE_BTREE); if( pCx==0 ) goto no_mem; pCx->isEphemeral = 1; - rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, + rc = sqlite3BtreeOpen(db->pVfs, 0, db, &pCx->ub.pBtx, BTREE_OMIT_JOURNAL | BTREE_SINGLE | pOp->p5, vfsFlags); if( rc==SQLITE_OK ){ @@ -4390,7 +4492,7 @@ if( (pCx->pKeyInfo = pKeyInfo = pOp->p4.pKeyInfo)!=0 ){ assert( pOp->p4type==P4_KEYINFO ); rc = sqlite3BtreeCreateTable(pCx->ub.pBtx, &pCx->pgnoRoot, - BTREE_BLOBKEY | pOp->p5); + BTREE_BLOBKEY | pOp->p5); if( rc==SQLITE_OK ){ assert( pCx->pgnoRoot==SCHEMA_ROOT+1 ); assert( pKeyInfo->db==db ); @@ -4465,7 +4567,7 @@ ** ** Open a new cursor that points to a fake table that contains a single ** row of data. The content of that one row is the content of memory -** register P2. In other words, cursor P1 becomes an alias for the +** register P2. In other words, cursor P1 becomes an alias for the ** MEM_Blob content contained in register P2. ** ** A pseudo-table created by this opcode is used to hold a single @@ -4530,13 +4632,13 @@ /* Opcode: SeekGE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as the key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as the key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the smallest entry that -** is greater than or equal to the key value. If there are no records +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than or equal to the key value. If there are no records ** greater than or equal to the key and P2 is not zero, then jump to P2. ** ** If the cursor P1 was opened using the OPFLAG_SEEKEQ flag, then this @@ -4544,7 +4646,7 @@ ** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ, ** this opcode must be followed by an IdxLE opcode with the same arguments. ** The IdxGT opcode will be skipped if this opcode succeeds, but the -** IdxGT opcode will be used on subsequent loop iterations. The +** IdxGT opcode will be used on subsequent loop iterations. The ** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this ** is an equality search. ** @@ -4557,13 +4659,13 @@ /* Opcode: SeekGT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the smallest entry that -** is greater than the key value. If there are no records greater than +** Reposition cursor P1 so that it points to the smallest entry that +** is greater than the key value. If there are no records greater than ** the key and P2 is not zero, then jump to P2. ** ** This opcode leaves the cursor configured to move in forward order, @@ -4572,16 +4674,16 @@ ** ** See also: Found, NotFound, SeekLt, SeekGe, SeekLe */ -/* Opcode: SeekLT P1 P2 P3 P4 * +/* Opcode: SeekLT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the largest entry that -** is less than the key value. If there are no records less than +** Reposition cursor P1 so that it points to the largest entry that +** is less than the key value. If there are no records less than ** the key and P2 is not zero, then jump to P2. ** ** This opcode leaves the cursor configured to move in reverse order, @@ -4593,13 +4695,13 @@ /* Opcode: SeekLE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), -** use the value in register P3 as a key. If cursor P1 refers -** to an SQL index, then P3 is the first in an array of P4 registers -** that are used as an unpacked index key. +** If cursor P1 refers to an SQL table (B-Tree that uses integer keys), +** use the value in register P3 as a key. If cursor P1 refers +** to an SQL index, then P3 is the first in an array of P4 registers +** that are used as an unpacked index key. ** -** Reposition cursor P1 so that it points to the largest entry that -** is less than or equal to the key value. If there are no records +** Reposition cursor P1 so that it points to the largest entry that +** is less than or equal to the key value. If there are no records ** less than or equal to the key and P2 is not zero, then jump to P2. ** ** This opcode leaves the cursor configured to move in reverse order, @@ -4611,7 +4713,7 @@ ** else it will cause a jump to P2. When the cursor is OPFLAG_SEEKEQ, ** this opcode must be followed by an IdxLE opcode with the same arguments. ** The IdxGE opcode will be skipped if this opcode succeeds, but the -** IdxGE opcode will be used on subsequent loop iterations. The +** IdxGE opcode will be used on subsequent loop iterations. The ** OPFLAG_SEEKEQ flags is a hint to the btree layer to say that this ** is an equality search. ** @@ -4856,7 +4958,7 @@ ** row. If This.P5 is false (0) then a jump is made to SeekGE.P2. If ** This.P5 is true (non-zero) then a jump is made to This.P2. The P5==0 ** case occurs when there are no inequality constraints to the right of -** the IN constraing. The jump to SeekGE.P2 ends the loop. The P5!=0 case +** the IN constraint. The jump to SeekGE.P2 ends the loop. The P5!=0 case ** occurs when there are inequality constraints to the right of the IN ** operator. In that case, the This.P2 will point either directly to or ** to setup code prior to the OP_IdxGT or OP_IdxGE opcode that checks for @@ -4864,7 +4966,7 @@ ** ** Possible outcomes from this opcode:
          ** -**
        1. If the cursor is initally not pointed to any valid row, then +**
        2. If the cursor is initially not pointed to any valid row, then ** fall through into the subsequent OP_SeekGE opcode. ** **
        3. If the cursor is left pointing to a row that is before the target @@ -4881,7 +4983,7 @@ ** (indicating that the target row definitely does not exist in the ** btree) then jump to SeekGE.P2, ending the loop. ** -**
        4. If the cursor ends up on a valid row that is past the target row +**
        5. If the cursor ends up on a valid row that is past the target row ** (indicating that the target row does not exist in the btree) then ** jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0. **
        @@ -4904,7 +5006,7 @@ assert( pOp[1].p1==aOp[pOp->p2-1].p1 ); assert( pOp[1].p2==aOp[pOp->p2-1].p2 ); assert( pOp[1].p3==aOp[pOp->p2-1].p3 ); - assert( aOp[pOp->p2-1].opcode==OP_IdxGT + assert( aOp[pOp->p2-1].opcode==OP_IdxGT || aOp[pOp->p2-1].opcode==OP_IdxGE ); testcase( aOp[pOp->p2-1].opcode==OP_IdxGE ); }else{ @@ -4923,7 +5025,7 @@ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... cursor not valid - fall through\n"); - } + } #endif break; } @@ -4952,7 +5054,7 @@ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... %d steps and then skip\n", pOp->p1 - nStep); - } + } #endif VdbeBranchTaken(1,3); pOp++; @@ -4963,7 +5065,7 @@ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... %d steps and then success\n", pOp->p1 - nStep); - } + } #endif VdbeBranchTaken(2,3); goto jump_to_p2; @@ -4973,7 +5075,7 @@ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("... fall through after %d steps\n", pOp->p1); - } + } #endif VdbeBranchTaken(0,3); break; @@ -4990,7 +5092,7 @@ } } } - + break; } @@ -5019,14 +5121,14 @@ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p2); - } + } #endif pC->seekHit = pOp->p2; }else if( pC->seekHit>pOp->p3 ){ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("seekHit changes from %d to %d\n", pC->seekHit, pOp->p3); - } + } #endif pC->seekHit = pOp->p3; } @@ -5074,9 +5176,9 @@ ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If ** P4>0 then register P3 is the first of P4 registers that form an unpacked ** record. -** +** ** Cursor P1 is on an index btree. If the record identified by P3 and P4 -** is not the prefix of any entry in P1 then a jump is made to P2. If P1 +** is not the prefix of any entry in P1 then a jump is made to P2. If P1 ** does contain an entry whose prefix matches the P3/P4 record then control ** falls through to the next instruction and P1 is left pointing at the ** matching entry. @@ -5096,13 +5198,13 @@ ** operands to OP_NotFound and OP_IdxGT. ** ** This opcode is an optimization attempt only. If this opcode always -** falls through, the correct answer is still obtained, but extra works +** falls through, the correct answer is still obtained, but extra work ** is performed. ** ** A value of N in the seekHit flag of cursor P1 means that there exists ** a key P3:N that will match some record in the index. We want to know ** if it is possible for a record P3:P4 to match some record in the -** index. If it is not possible, we can skips some work. So if seekHit +** index. If it is not possible, we can skip some work. So if seekHit ** is less than P4, attempt to find out if a match is possible by running ** OP_NotFound. ** @@ -5124,7 +5226,7 @@ ** If P4==0 then register P3 holds a blob constructed by MakeRecord. If ** P4>0 then register P3 is the first of P4 registers that form an unpacked ** record. -** +** ** Cursor P1 is on an index btree. If the record identified by P3 and P4 ** contains any NULL value, jump immediately to P2. If all terms of the ** record are not-NULL then a check is done to determine if any row in the @@ -5149,7 +5251,7 @@ #ifdef SQLITE_DEBUG if( db->flags&SQLITE_VdbeTrace ){ printf("seekHit is %d\n", pC->seekHit); - } + } #endif if( pC->seekHit>=pOp->p4.i ) break; /* Fall through into OP_NotFound */ @@ -5245,9 +5347,9 @@ ** ** P1 is the index of a cursor open on an SQL table btree (with integer ** keys). If register P3 does not contain an integer or if P1 does not -** contain a record with rowid P3 then jump immediately to P2. +** contain a record with rowid P3 then jump immediately to P2. ** Or, if P2 is 0, raise an SQLITE_CORRUPT error. If P1 does contain -** a record with rowid P3 then +** a record with rowid P3 then ** leave the cursor pointing at that record and fall through to the next ** instruction. ** @@ -5270,7 +5372,7 @@ ** P1 is the index of a cursor open on an SQL table btree (with integer ** keys). P3 is an integer rowid. If P1 does not contain a record with ** rowid P3 then jump immediately to P2. Or, if P2 is 0, raise an -** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then +** SQLITE_CORRUPT error. If P1 does contain a record with rowid P3 then ** leave the cursor pointing at that record and fall through to the next ** instruction. ** @@ -5354,7 +5456,7 @@ ** Find the next available sequence number for cursor P1. ** Write the sequence number into register P2. ** The sequence number on the cursor is incremented after this -** instruction. +** instruction. */ case OP_Sequence: { /* out2 */ assert( pOp->p1>=0 && pOp->p1nCursor ); @@ -5374,9 +5476,9 @@ ** table that cursor P1 points to. The new record number is written ** written to register P2. ** -** If P3>0 then P3 is a register in the root frame of this VDBE that holds +** If P3>0 then P3 is a register in the root frame of this VDBE that holds ** the largest previously generated record number. No new record numbers are -** allowed to be less than this value. When this value reaches its maximum, +** allowed to be less than this value. When this value reaches its maximum, ** an SQLITE_FULL error is generated. The P3 register is updated with the ' ** generated record number. This P3 mechanism is used to help implement the ** AUTOINCREMENT feature. @@ -5527,8 +5629,8 @@ ** is part of an INSERT operation. The difference is only important to ** the update hook. ** -** Parameter P4 may point to a Table structure, or may be NULL. If it is -** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked +** Parameter P4 may point to a Table structure, or may be NULL. If it is +** not NULL, then the update-hook (sqlite3.xUpdateCallback) is invoked ** following a successful insert. ** ** (WARNING/TODO: If P1 is a pseudo-cursor and P2 is dynamically @@ -5609,11 +5711,12 @@ x.pKey = 0; assert( BTREE_PREFORMAT==OPFLAG_PREFORMAT ); rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), seekResult ); pC->deferredMoveto = 0; pC->cacheStatus = CACHE_STALE; + colCacheCtr++; /* Invoke the update-hook if required. */ if( rc ) goto abort_due_to_error; @@ -5662,27 +5765,32 @@ ** the cursor will be left pointing at either the next or the previous ** record in the table. If it is left pointing at the next record, then ** the next Next instruction will be a no-op. As a result, in this case -** it is ok to delete a record from within a Next loop. If +** it is ok to delete a record from within a Next loop. If ** OPFLAG_SAVEPOSITION bit of P5 is clear, then the cursor will be ** left in an undefined state. ** ** If the OPFLAG_AUXDELETE bit is set on P5, that indicates that this -** delete one of several associated with deleting a table row and all its -** associated index entries. Exactly one of those deletes is the "primary" -** delete. The others are all on OPFLAG_FORDELETE cursors or else are -** marked with the AUXDELETE flag. -** -** If the OPFLAG_NCHANGE flag of P2 (NB: P2 not P5) is set, then the row -** change count is incremented (otherwise not). +** delete is one of several associated with deleting a table row and +** all its associated index entries. Exactly one of those deletes is +** the "primary" delete. The others are all on OPFLAG_FORDELETE +** cursors or else are marked with the AUXDELETE flag. +** +** If the OPFLAG_NCHANGE (0x01) flag of P2 (NB: P2 not P5) is set, then +** the row change count is incremented (otherwise not). +** +** If the OPFLAG_ISNOOP (0x40) flag of P2 (not P5!) is set, then the +** pre-update-hook for deletes is run, but the btree is otherwise unchanged. +** This happens when the OP_Delete is to be shortly followed by an OP_Insert +** with the same key, causing the btree entry to be overwritten. ** ** P1 must not be pseudo-table. It has to be a real table with ** multiple rows. ** -** If P4 is not NULL then it points to a Table object. In this case either +** If P4 is not NULL then it points to a Table object. In this case either ** the update or pre-update hook, or both, may be invoked. The P1 cursor must -** have been positioned using OP_NotFound prior to invoking this opcode in -** this case. Specifically, if one is configured, the pre-update hook is -** invoked if P4 is not NULL. The update-hook is invoked if one is configured, +** have been positioned using OP_NotFound prior to invoking this opcode in +** this case. Specifically, if one is configured, the pre-update hook is +** invoked if P4 is not NULL. The update-hook is invoked if one is configured, ** P4 is not NULL, and the OPFLAG_NCHANGE flag is set in P2. ** ** If the OPFLAG_ISUPDATE flag is set in P2, then P3 contains the address @@ -5721,7 +5829,7 @@ /* If the update-hook or pre-update-hook will be invoked, set zDb to ** the name of the db to pass as to it. Also set local pTab to a copy ** of p4.pTab. Finally, if p5 is true, indicating that this cursor was - ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set + ** last moved with OP_Next or OP_Prev, not Seek or NotFound, set ** VdbeCursor.movetoTarget to the current rowid. */ if( pOp->p4type==P4_TABLE && HAS_UPDATE_HOOK(db) ){ assert( pC->iDb>=0 ); @@ -5740,20 +5848,20 @@ /* Invoke the pre-update-hook if required. */ assert( db->xPreUpdateCallback==0 || pTab==pOp->p4.pTab ); if( db->xPreUpdateCallback && pTab ){ - assert( !(opflags & OPFLAG_ISUPDATE) - || HasRowid(pTab)==0 - || (aMem[pOp->p3].flags & MEM_Int) + assert( !(opflags & OPFLAG_ISUPDATE) + || HasRowid(pTab)==0 + || (aMem[pOp->p3].flags & MEM_Int) ); sqlite3VdbePreUpdateHook(p, pC, - (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, + (opflags & OPFLAG_ISUPDATE) ? SQLITE_UPDATE : SQLITE_DELETE, zDb, pTab, pC->movetoTarget, pOp->p3, -1 ); } if( opflags & OPFLAG_ISNOOP ) break; #endif - - /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ + + /* Only flags that can be set are SAVEPOISTION and AUXDELETE */ assert( (pOp->p5 & ~(OPFLAG_SAVEPOSITION|OPFLAG_AUXDELETE))==0 ); assert( OPFLAG_SAVEPOSITION==BTREE_SAVEPOSITION ); assert( OPFLAG_AUXDELETE==BTREE_AUXDELETE ); @@ -5774,6 +5882,7 @@ rc = sqlite3BtreeDelete(pC->uc.pCursor, pOp->p5); pC->cacheStatus = CACHE_STALE; + colCacheCtr++; pC->seekResult = 0; if( rc ) goto abort_due_to_error; @@ -5806,7 +5915,7 @@ ** Synopsis: if key(P1)!=trim(r[P3],P4) goto P2 ** ** P1 is a sorter cursor. This instruction compares a prefix of the -** record blob in register P3 against a prefix of the entry that +** record blob in register P3 against a prefix of the entry that ** the sorter cursor currently points to. Only the first P4 fields ** of r[P3] and the sorter record are compared. ** @@ -5841,13 +5950,13 @@ ** Write into register P2 the current sorter data for sorter cursor P1. ** Then clear the column header cache on cursor P3. ** -** This opcode is normally use to move a record out of the sorter and into +** This opcode is normally used to move a record out of the sorter and into ** a register that is the source for a pseudo-table cursor created using ** OpenPseudo. That pseudo-table cursor is the one that is identified by ** parameter P3. Clearing the P3 column cache as part of this opcode saves ** us from having to issue a separate NullRow instruction to clear that cache. */ -case OP_SorterData: { +case OP_SorterData: { /* ncycle */ VdbeCursor *pC; pOut = &aMem[pOp->p2]; @@ -5864,10 +5973,10 @@ /* Opcode: RowData P1 P2 P3 * * ** Synopsis: r[P2]=data ** -** Write into register P2 the complete row content for the row at +** Write into register P2 the complete row content for the row at ** which cursor P1 is currently pointing. -** There is no interpretation of the data. -** It is just copied onto the P2 register exactly as +** There is no interpretation of the data. +** It is just copied onto the P2 register exactly as ** it is found in the database file. ** ** If cursor P1 is an index, then the content is the key of the row. @@ -6028,7 +6137,7 @@ */ /* Opcode: Last P1 P2 * * * ** -** The next use of the Rowid or Column or Prev instruction for P1 +** The next use of the Rowid or Column or Prev instruction for P1 ** will refer to the last entry in the database table or index. ** If the table or index is empty and P2>0, then jump immediately to P2. ** If P2 is 0 or if the table or index is not empty, fall through @@ -6122,8 +6231,8 @@ ** regression tests can determine whether or not the optimizer is ** correctly optimizing out sorts. */ -case OP_SorterSort: /* jump */ -case OP_Sort: { /* jump */ +case OP_SorterSort: /* jump ncycle */ +case OP_Sort: { /* jump ncycle */ #ifdef SQLITE_TEST sqlite3_sort_count++; sqlite3_search_count--; @@ -6134,10 +6243,10 @@ } /* Opcode: Rewind P1 P2 * * * ** -** The next use of the Rowid or Column or Next instruction for P1 +** The next use of the Rowid or Column or Next instruction for P1 ** will refer to the first entry in the database table or index. ** If the table or index is empty, jump immediately to P2. -** If the table or index is not empty, fall through to the following +** If the table or index is not empty, fall through to the following ** instruction. ** ** If P2 is zero, that is an assertion that the P1 table is never @@ -6314,7 +6423,7 @@ ** run faster by avoiding an unnecessary seek on cursor P1. However, ** the OPFLAG_USESEEKRESULT flag must only be set if there have been no prior ** seeks on the cursor or if the most recent seek used a key equivalent -** to P2. +** to P2. ** ** This instruction only works for indices. The equivalent instruction ** for tables is OP_Insert. @@ -6340,7 +6449,7 @@ x.aMem = aMem + pOp->p3; x.nMem = (u16)pOp->p4.i; rc = sqlite3BtreeInsert(pC->uc.pCursor, &x, - (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), + (pOp->p5 & (OPFLAG_APPEND|OPFLAG_SAVEPOSITION|OPFLAG_PREFORMAT)), ((pOp->p5 & OPFLAG_USESEEKRESULT) ? pC->seekResult : 0) ); assert( pC->deferredMoveto==0 ); @@ -6378,7 +6487,7 @@ ** Synopsis: key=r[P2@P3] ** ** The content of P3 registers starting at register P2 form -** an unpacked index key. This opcode removes that entry from the +** an unpacked index key. This opcode removes that entry from the ** index opened by cursor P1. ** ** If P5 is not zero, then raise an SQLITE_CORRUPT_INDEX error @@ -6436,8 +6545,8 @@ ** ** P4 may be an array of integers (type P4_INTARRAY) containing ** one entry for each column in the P3 table. If array entry a(i) -** is non-zero, then reading column a(i)-1 from cursor P3 is -** equivalent to performing the deferred seek and then reading column i +** is non-zero, then reading column a(i)-1 from cursor P3 is +** equivalent to performing the deferred seek and then reading column i ** from P1. This information is stored in P3 and used to redirect ** reads against P3 over to P1, thus possibly avoiding the need to ** seek and read cursor P3. @@ -6509,7 +6618,7 @@ } /* Opcode: FinishSeek P1 * * * * -** +** ** If cursor P1 was previously moved via OP_DeferredSeek, complete that ** seek operation now, without further delay. If the cursor seek has ** already occurred, this instruction is a no-op. @@ -6529,9 +6638,9 @@ /* Opcode: IdxGE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the PRIMARY KEY. Compare this key value against the index -** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID ** fields at the end. ** ** If the P1 index entry is greater than or equal to the key value @@ -6540,9 +6649,9 @@ /* Opcode: IdxGT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** The P4 register values beginning with P3 form an unpacked index -** key that omits the PRIMARY KEY. Compare this key value against the index -** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID +** The P4 register values beginning with P3 form an unpacked index +** key that omits the PRIMARY KEY. Compare this key value against the index +** that P1 is currently pointing to, ignoring the PRIMARY KEY or ROWID ** fields at the end. ** ** If the P1 index entry is greater than the key value @@ -6551,7 +6660,7 @@ /* Opcode: IdxLT P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** The P4 register values beginning with P3 form an unpacked index +** The P4 register values beginning with P3 form an unpacked index ** key that omits the PRIMARY KEY or ROWID. Compare this key value against ** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or ** ROWID on the P1 index. @@ -6562,7 +6671,7 @@ /* Opcode: IdxLE P1 P2 P3 P4 * ** Synopsis: key=r[P3@P4] ** -** The P4 register values beginning with P3 form an unpacked index +** The P4 register values beginning with P3 form an unpacked index ** key that omits the PRIMARY KEY or ROWID. Compare this key value against ** the index that P1 is currently pointing to, ignoring the PRIMARY KEY or ** ROWID on the P1 index. @@ -6650,7 +6759,7 @@ ** file is given by P1. ** ** The table being destroyed is in the main database file if P3==0. If -** P3==1 then the table to be clear is in the auxiliary database file +** P3==1 then the table to be destroyed is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** ** If AUTOVACUUM is enabled then it is possible that another root page @@ -6658,15 +6767,15 @@ ** root pages contiguous at the beginning of the database. The former ** value of the root page that moved - its value before the move occurred - ** is stored in register P2. If no page movement was required (because the -** table being dropped was already the last one in the database) then a -** zero is stored in register P2. If AUTOVACUUM is disabled then a zero +** table being dropped was already the last one in the database) then a +** zero is stored in register P2. If AUTOVACUUM is disabled then a zero ** is stored in register P2. ** ** This opcode throws an error if there are any active reader VMs when -** it is invoked. This is done to avoid the difficulty associated with -** updating existing cursors when a root page is moved in an AUTOVACUUM -** database. This error is thrown even if the database is not an AUTOVACUUM -** db in order to avoid introducing an incompatibility between autovacuum +** it is invoked. This is done to avoid the difficulty associated with +** updating existing cursors when a root page is moved in an AUTOVACUUM +** database. This error is thrown even if the database is not an AUTOVACUUM +** db in order to avoid introducing an incompatibility between autovacuum ** and non-autovacuum modes. ** ** See also: Clear @@ -6710,8 +6819,8 @@ ** in the database file is given by P1. But, unlike Destroy, do not ** remove the table or index from the database file. ** -** The table being clear is in the main database file if P2==0. If -** P2==1 then the table to be clear is in the auxiliary database file +** The table being cleared is in the main database file if P2==0. If +** P2==1 then the table to be cleared is in the auxiliary database file ** that is used to store tables create using CREATE TEMPORARY TABLE. ** ** If the P3 value is non-zero, then the row change count is incremented @@ -6723,7 +6832,7 @@ */ case OP_Clear: { i64 nChange; - + sqlite3VdbeIncrWriteCounter(p, 0); nChange = 0; assert( p->readOnly==0 ); @@ -6751,7 +6860,7 @@ */ case OP_ResetSorter: { VdbeCursor *pC; - + assert( pOp->p1>=0 && pOp->p1nCursor ); pC = p->apCsr[pOp->p1]; assert( pC!=0 ); @@ -6797,13 +6906,41 @@ /* Opcode: SqlExec * * * P4 * ** ** Run the SQL statement or statements specified in the P4 string. +** Disable Auth and Trace callbacks while those statements are running if +** P1 is true. */ case OP_SqlExec: { + char *zErr; +#ifndef SQLITE_OMIT_AUTHORIZATION + sqlite3_xauth xAuth; +#endif + u8 mTrace; + sqlite3VdbeIncrWriteCounter(p, 0); db->nSqlExec++; - rc = sqlite3_exec(db, pOp->p4.z, 0, 0, 0); + zErr = 0; +#ifndef SQLITE_OMIT_AUTHORIZATION + xAuth = db->xAuth; +#endif + mTrace = db->mTrace; + if( pOp->p1 ){ +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = 0; +#endif + db->mTrace = 0; + } + rc = sqlite3_exec(db, pOp->p4.z, 0, 0, &zErr); db->nSqlExec--; - if( rc ) goto abort_due_to_error; +#ifndef SQLITE_OMIT_AUTHORIZATION + db->xAuth = xAuth; +#endif + db->mTrace = mTrace; + if( zErr || rc ){ + sqlite3VdbeError(p, "%s", zErr); + sqlite3_free(zErr); + if( rc==SQLITE_NOMEM ) goto no_mem; + goto abort_due_to_error; + } break; } @@ -6823,7 +6960,7 @@ InitData initData; /* Any prepared statement that invokes this opcode will hold mutexes - ** on every btree. This is a prerequisite for invoking + ** on every btree. This is a prerequisite for invoking ** sqlite3InitCallback(). */ #ifdef SQLITE_DEBUG @@ -6884,7 +7021,7 @@ } goto abort_due_to_error; } - break; + break; } #if !defined(SQLITE_OMIT_ANALYZE) @@ -6898,7 +7035,7 @@ assert( pOp->p1>=0 && pOp->p1nDb ); rc = sqlite3AnalysisLoad(db, pOp->p1); if( rc ) goto abort_due_to_error; - break; + break; } #endif /* !defined(SQLITE_OMIT_ANALYZE) */ @@ -6906,7 +7043,7 @@ ** ** Remove the internal (in-memory) data structures that describe ** the table named P4 in database P1. This is called after a table -** is dropped from disk (using the Destroy opcode) in order to keep +** is dropped from disk (using the Destroy opcode) in order to keep ** the internal representation of the ** schema consistent with what is on disk. */ @@ -6934,7 +7071,7 @@ ** ** Remove the internal (in-memory) data structures that describe ** the trigger named P4 in database P1. This is called after a trigger -** is dropped from disk (using the Destroy opcode) in order to keep +** is dropped from disk (using the Destroy opcode) in order to keep ** the internal representation of the ** schema consistent with what is on disk. */ @@ -6954,7 +7091,7 @@ ** ** The register P3 contains one less than the maximum number of allowed errors. ** At most reg(P3) errors will be reported. -** In other words, the analysis stops as soon as reg(P1) errors are +** In other words, the analysis stops as soon as reg(P1) errors are ** seen. Reg(P1) is updated with the number of errors remaining. ** ** The root page numbers of all tables in the database are integers @@ -7035,7 +7172,7 @@ pIn1 = &aMem[pOp->p1]; assert( (pIn1->flags & MEM_Blob)==0 || sqlite3VdbeMemIsRowSet(pIn1) ); - if( (pIn1->flags & MEM_Blob)==0 + if( (pIn1->flags & MEM_Blob)==0 || sqlite3RowSetNext((RowSet*)pIn1->z, &val)==0 ){ /* The boolean index is empty */ @@ -7107,13 +7244,13 @@ /* Opcode: Program P1 P2 P3 P4 P5 ** -** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). +** Execute the trigger program passed as P4 (type P4_SUBPROGRAM). ** -** P1 contains the address of the memory cell that contains the first memory -** cell in an array of values used as arguments to the sub-program. P2 -** contains the address to jump to if the sub-program throws an IGNORE -** exception using the RAISE() function. Register P3 contains the address -** of a memory cell in this (the parent) VM that is used to allocate the +** P1 contains the address of the memory cell that contains the first memory +** cell in an array of values used as arguments to the sub-program. P2 +** contains the address to jump to if the sub-program throws an IGNORE +** exception using the RAISE() function. Register P3 contains the address +** of a memory cell in this (the parent) VM that is used to allocate the ** memory required by the sub-vdbe at runtime. ** ** P4 is a pointer to the VM containing the trigger program. @@ -7133,17 +7270,17 @@ pProgram = pOp->p4.pProgram; pRt = &aMem[pOp->p3]; assert( pProgram->nOp>0 ); - - /* If the p5 flag is clear, then recursive invocation of triggers is + + /* If the p5 flag is clear, then recursive invocation of triggers is ** disabled for backwards compatibility (p5 is set if this sub-program ** is really a trigger, not a foreign key action, and the flag set ** and cleared by the "PRAGMA recursive_triggers" command is clear). - ** - ** It is recursive invocation of triggers, at the SQL level, that is - ** disabled. In some cases a single trigger may generate more than one - ** SubProgram (if the trigger may be executed with more than one different + ** + ** It is recursive invocation of triggers, at the SQL level, that is + ** disabled. In some cases a single trigger may generate more than one + ** SubProgram (if the trigger may be executed with more than one different ** ON CONFLICT algorithm). SubProgram structures associated with a - ** single trigger all have the same value for the SubProgram.token + ** single trigger all have the same value for the SubProgram.token ** variable. */ if( pOp->p5 ){ t = pProgram->token; @@ -7159,10 +7296,10 @@ /* Register pRt is used to store the memory required to save the state ** of the current program, and the memory required at runtime to execute - ** the trigger program. If this trigger has been fired before, then pRt + ** the trigger program. If this trigger has been fired before, then pRt ** is already allocated. Otherwise, it must be initialized. */ if( (pRt->flags&MEM_Blob)==0 ){ - /* SubProgram.nMem is set to the number of memory cells used by the + /* SubProgram.nMem is set to the number of memory cells used by the ** program stored in SubProgram.aOp. As well as these, one memory ** cell is required for each cursor used by the program. Set local ** variable nMem (and later, VdbeFrame.nChildMem) to this value. @@ -7207,7 +7344,7 @@ }else{ pFrame = (VdbeFrame*)pRt->z; assert( pRt->xDel==sqlite3VdbeFrameMemDel ); - assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem + assert( pProgram->nMem+pProgram->nCsr==pFrame->nChildMem || (pProgram->nCsr==0 && pProgram->nMem+1==pFrame->nChildMem) ); assert( pProgram->nCsr==pFrame->nChildCsr ); assert( (int)(pOp - aOp)==pFrame->pc ); @@ -7248,10 +7385,10 @@ /* Opcode: Param P1 P2 * * * ** -** This opcode is only ever present in sub-programs called via the -** OP_Program instruction. Copy a value currently stored in a memory -** cell of the calling (parent) frame to cell P2 in the current frames -** address space. This is used by trigger programs to access the new.* +** This opcode is only ever present in sub-programs called via the +** OP_Program instruction. Copy a value currently stored in a memory +** cell of the calling (parent) frame to cell P2 in the current frames +** address space. This is used by trigger programs to access the new.* ** and old.* values. ** ** The address of the cell in the parent frame is determined by adding @@ -7263,7 +7400,7 @@ Mem *pIn; pOut = out2Prerelease(p, pOp); pFrame = p->pFrame; - pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; + pIn = &pFrame->aMem[pOp->p1 + pFrame->aOp[pFrame->pc].p1]; sqlite3VdbeMemShallowCopy(pOut, pIn, MEM_Ephem); break; } @@ -7275,8 +7412,8 @@ ** Synopsis: fkctr[P1]+=P2 ** ** Increment a "constraint counter" by P2 (P2 may be negative or positive). -** If P1 is non-zero, the database constraint counter is incremented -** (deferred foreign key constraints). Otherwise, if P1 is zero, the +** If P1 is non-zero, the database constraint counter is incremented +** (deferred foreign key constraints). Otherwise, if P1 is zero, the ** statement counter is incremented (immediate foreign key constraints). */ case OP_FkCounter: { @@ -7294,7 +7431,7 @@ ** Synopsis: if fkctr[P1]==0 goto P2 ** ** This opcode tests if a foreign key constraint-counter is currently zero. -** If so, jump to instruction P2. Otherwise, fall through to the next +** If so, jump to instruction P2. Otherwise, fall through to the next ** instruction. ** ** If P1 is non-zero, then the jump is taken if the database constraint-counter @@ -7320,7 +7457,7 @@ ** ** P1 is a register in the root frame of this VM (the root frame is ** different from the current frame if this instruction is being executed -** within a sub-program). Set the value of register P1 to the maximum of +** within a sub-program). Set the value of register P1 to the maximum of ** its current value and the value in register P2. ** ** This instruction throws an error if the memory cell is not initially @@ -7380,7 +7517,7 @@ ** and r[P2] is set to be the value of the LIMIT, r[P1]. ** ** if r[P1] is zero or negative, that means there is no LIMIT -** and r[P2] is set to -1. +** and r[P2] is set to -1. ** ** Otherwise, r[P2] is set to the sum of r[P1] and r[P3]. */ @@ -7412,7 +7549,7 @@ ** ** Register P1 must contain an integer. If the content of register P1 is ** initially greater than zero, then decrement the value in register P1. -** If it is non-zero (negative or positive) and then also jump to P2. +** If it is non-zero (negative or positive) and then also jump to P2. ** If register P1 is initially zero, leave it unchanged and fall through. */ case OP_IfNotZero: { /* jump, in1 */ @@ -7446,7 +7583,7 @@ ** Synopsis: accum=r[P3] step(r[P2@P5]) ** ** Execute the xStep function for an aggregate. -** The function has P5 arguments. P4 is a pointer to the +** The function has P5 arguments. P4 is a pointer to the ** FuncDef structure that specifies the function. Register P3 is the ** accumulator. ** @@ -7457,7 +7594,7 @@ ** Synopsis: accum=r[P3] inverse(r[P2@P5]) ** ** Execute the xInverse function for an aggregate. -** The function has P5 arguments. P4 is a pointer to the +** The function has P5 arguments. P4 is a pointer to the ** FuncDef structure that specifies the function. Register P3 is the ** accumulator. ** @@ -7468,7 +7605,7 @@ ** Synopsis: accum=r[P3] step(r[P2@P5]) ** ** Execute the xStep (if P1==0) or xInverse (if P1!=0) function for an -** aggregate. The function has P5 arguments. P4 is a pointer to the +** aggregate. The function has P5 arguments. P4 is a pointer to the ** FuncDef structure that specifies the function. Register P3 is the ** accumulator. ** @@ -7537,7 +7674,7 @@ /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it - ** reinitializes the relavant parts of the sqlite3_context object */ + ** 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]; @@ -7586,7 +7723,7 @@ ** Synopsis: accum=r[P1] N=P2 ** ** P1 is the memory location that is the accumulator for an aggregate -** or window function. Execute the finalizer function +** or window function. Execute the finalizer function ** for an aggregate and store the result in P1. ** ** P2 is the number of arguments that the step function takes and @@ -7625,7 +7762,7 @@ { rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc); } - + if( rc ){ sqlite3VdbeError(p, "%s", sqlite3_value_text(pMem)); goto abort_due_to_error; @@ -7669,9 +7806,9 @@ } for(i=0, pMem = &aMem[pOp->p3]; i<3; i++, pMem++){ sqlite3VdbeMemSetInt64(pMem, (i64)aRes[i]); - } + } break; -}; +}; #endif #ifndef SQLITE_OMIT_PRAGMA @@ -7697,9 +7834,9 @@ pOut = out2Prerelease(p, pOp); eNew = pOp->p3; - assert( eNew==PAGER_JOURNALMODE_DELETE - || eNew==PAGER_JOURNALMODE_TRUNCATE - || eNew==PAGER_JOURNALMODE_PERSIST + assert( eNew==PAGER_JOURNALMODE_DELETE + || eNew==PAGER_JOURNALMODE_TRUNCATE + || eNew==PAGER_JOURNALMODE_PERSIST || eNew==PAGER_JOURNALMODE_OFF || eNew==PAGER_JOURNALMODE_MEMORY || eNew==PAGER_JOURNALMODE_WAL @@ -7719,7 +7856,7 @@ zFilename = sqlite3PagerFilename(pPager, 1); /* Do not allow a transition to journal_mode=WAL for a database - ** in temporary storage or if the VFS does not support shared memory + ** in temporary storage or if the VFS does not support shared memory */ if( eNew==PAGER_JOURNALMODE_WAL && (sqlite3Strlen30(zFilename)==0 /* Temp file */ @@ -7739,12 +7876,12 @@ ); goto abort_due_to_error; }else{ - + if( eOld==PAGER_JOURNALMODE_WAL ){ /* If leaving WAL mode, close the log file. If successful, the call - ** to PagerCloseWal() checkpoints and deletes the write-ahead-log - ** file. An EXCLUSIVE lock may still be held on the database file - ** after a successful return. + ** to PagerCloseWal() checkpoints and deletes the write-ahead-log + ** file. An EXCLUSIVE lock may still be held on the database file + ** after a successful return. */ rc = sqlite3PagerCloseWal(pPager, db); if( rc==SQLITE_OK ){ @@ -7755,7 +7892,7 @@ ** as an intermediate */ sqlite3PagerSetJournalMode(pPager, PAGER_JOURNALMODE_OFF); } - + /* Open a transaction on the database file. Regardless of the journal ** mode, this transaction always uses a rollback journal. */ @@ -7830,7 +7967,7 @@ ** is executed using sqlite3_step() it will either automatically ** reprepare itself (if it was originally created using sqlite3_prepare_v2()) ** or it will fail with SQLITE_SCHEMA. -** +** ** If P1 is 0, then all SQL statements become expired. If P1 is non-zero, ** then only the currently executing statement is expired. ** @@ -7885,7 +8022,7 @@ ** Synopsis: iDb=P1 root=P2 write=P3 ** ** Obtain a lock on a particular table. This instruction is only used when -** the shared-cache feature is enabled. +** the shared-cache feature is enabled. ** ** P1 is the index of the database in sqlite3.aDb[] of the database ** on which the lock is acquired. A readlock is obtained if P3==0 or @@ -7899,7 +8036,7 @@ case OP_TableLock: { u8 isWriteLock = (u8)pOp->p3; if( isWriteLock || 0==(db->flags&SQLITE_ReadUncommit) ){ - int p1 = pOp->p1; + int p1 = pOp->p1; assert( p1>=0 && p1nDb ); assert( DbMaskTest(p->btreeMask, p1) ); assert( isWriteLock==0 || isWriteLock==1 ); @@ -7919,7 +8056,7 @@ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VBegin * * * P4 * ** -** P4 may be a pointer to an sqlite3_vtab structure. If so, call the +** P4 may be a pointer to an sqlite3_vtab structure. If so, call the ** xBegin method for that table. ** ** Also, whether or not P4 is set, check that this is not being called from @@ -7939,7 +8076,7 @@ #ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VCreate P1 P2 * * * ** -** P2 is a register that holds the name of a virtual table in database +** P2 is a register that holds the name of a virtual table in database ** P1. Call the xCreate method for that table. */ case OP_VCreate: { @@ -8025,6 +8162,53 @@ #endif /* SQLITE_OMIT_VIRTUALTABLE */ #ifndef SQLITE_OMIT_VIRTUALTABLE +/* Opcode: VCheck P1 P2 P3 P4 * +** +** P4 is a pointer to a Table object that is a virtual table in schema P1 +** that supports the xIntegrity() method. This opcode runs the xIntegrity() +** method for that virtual table, using P3 as the integer argument. If +** an error is reported back, the table name is prepended to the error +** message and that message is stored in P2. If no errors are seen, +** register P2 is set to NULL. +*/ +case OP_VCheck: { /* out2 */ + Table *pTab; + sqlite3_vtab *pVtab; + const sqlite3_module *pModule; + char *zErr = 0; + + pOut = &aMem[pOp->p2]; + sqlite3VdbeMemSetNull(pOut); /* Innocent until proven guilty */ + assert( pOp->p4type==P4_TABLE ); + pTab = pOp->p4.pTab; + assert( pTab!=0 ); + assert( IsVirtual(pTab) ); + assert( pTab->u.vtab.p!=0 ); + pVtab = pTab->u.vtab.p->pVtab; + assert( pVtab!=0 ); + pModule = pVtab->pModule; + assert( pModule!=0 ); + assert( pModule->iVersion>=4 ); + assert( pModule->xIntegrity!=0 ); + pTab->nTabRef++; + sqlite3VtabLock(pTab->u.vtab.p); + assert( pOp->p1>=0 && pOp->p1nDb ); + rc = pModule->xIntegrity(pVtab, db->aDb[pOp->p1].zDbSName, pTab->zName, + pOp->p3, &zErr); + sqlite3VtabUnlock(pTab->u.vtab.p); + sqlite3DeleteTable(db, pTab); + if( rc ){ + sqlite3_free(zErr); + goto abort_due_to_error; + } + if( zErr ){ + sqlite3VdbeMemSetStr(pOut, zErr, -1, SQLITE_UTF8, sqlite3_free); + } + break; +} +#endif /* SQLITE_OMIT_VIRTUALTABLE */ + +#ifndef SQLITE_OMIT_VIRTUALTABLE /* Opcode: VInitIn P1 P2 P3 * * ** Synopsis: r[P2]=ValueList(P1,P3) ** @@ -8202,7 +8386,7 @@ /* Invoke the xNext() method of the module. There is no way for the ** underlying implementation to return an error if one occurs during - ** xNext(). Instead, if an error occurs, true is returned (indicating that + ** xNext(). Instead, if an error occurs, true is returned (indicating that ** data is available) and the error code returned when xColumn or ** some other method is next invoked on the save virtual table cursor. */ @@ -8230,7 +8414,7 @@ sqlite3_vtab *pVtab; Mem *pName; int isLegacy; - + isLegacy = (db->flags & SQLITE_LegacyAlter); db->flags |= SQLITE_LegacyAlter; pVtab = pOp->p4.pVtab->pVtab; @@ -8260,23 +8444,23 @@ ** ** P4 is a pointer to a virtual table object, an sqlite3_vtab structure. ** This opcode invokes the corresponding xUpdate method. P2 values -** are contiguous memory cells starting at P3 to pass to the xUpdate -** invocation. The value in register (P3+P2-1) corresponds to the +** are contiguous memory cells starting at P3 to pass to the xUpdate +** invocation. The value in register (P3+P2-1) corresponds to the ** p2th element of the argv array passed to xUpdate. ** ** The xUpdate method will do a DELETE or an INSERT or both. ** The argv[0] element (which corresponds to memory cell P3) -** is the rowid of a row to delete. If argv[0] is NULL then no -** deletion occurs. The argv[1] element is the rowid of the new -** row. This can be NULL to have the virtual table select the new -** rowid for itself. The subsequent elements in the array are +** is the rowid of a row to delete. If argv[0] is NULL then no +** deletion occurs. The argv[1] element is the rowid of the new +** row. This can be NULL to have the virtual table select the new +** rowid for itself. The subsequent elements in the array are ** the values of columns in the new row. ** ** If P2==1 then no insert is performed. argv[0] is the rowid of ** a row to delete. ** ** P1 is a boolean flag. If it is set to true and the xUpdate call -** is successful, then the value returned by sqlite3_last_insert_rowid() +** is successful, then the value returned by sqlite3_last_insert_rowid() ** is set to the value of the rowid for the row just inserted. ** ** P5 is the error actions (OE_Replace, OE_Fail, OE_Ignore, etc) to @@ -8291,7 +8475,7 @@ Mem **apArg; Mem *pX; - assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback + assert( pOp->p2==1 || pOp->p5==OE_Fail || pOp->p5==OE_Rollback || pOp->p5==OE_Abort || pOp->p5==OE_Ignore || pOp->p5==OE_Replace ); assert( p->readOnly==0 ); @@ -8386,7 +8570,7 @@ ** The result of the function is stored ** in register P3. Register P3 must not be one of the function inputs. ** -** P1 is a 32-bit bitmask indicating whether or not each argument to the +** P1 is a 32-bit bitmask indicating whether or not each argument to the ** function was determined to be constant at compile time. If the first ** argument was constant then bit 0 of P1 is set. This is used to determine ** whether meta data associated with a user function argument using the @@ -8405,7 +8589,7 @@ ** The result of the function is stored ** in register P3. Register P3 must not be one of the function inputs. ** -** P1 is a 32-bit bitmask indicating whether or not each argument to the +** P1 is a 32-bit bitmask indicating whether or not each argument to the ** function was determined to be constant at compile time. If the first ** argument was constant then bit 0 of P1 is set. This is used to determine ** whether meta data associated with a user function argument using the @@ -8415,7 +8599,7 @@ ** 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 determinitic of non-deterministic, depending on their arguments. +** either deterministic of non-deterministic, depending on their arguments. ** When those function are used in a non-deterministic way, they will check ** to see if they were called using OP_PureFunc instead of OP_Function, and ** if they were, they throw an error. @@ -8433,7 +8617,7 @@ /* If this function is inside of a trigger, the register array in aMem[] ** might change from one evaluation to the next. The next block of code ** checks to see if the register array has changed, and if so it - ** reinitializes the relavant parts of the sqlite3_context object */ + ** reinitializes the relevant parts of the sqlite3_context object */ pOut = &aMem[pOp->p3]; if( pCtx->pOut != pOut ){ pCtx->pVdbe = p; @@ -8465,7 +8649,7 @@ if( rc ) goto abort_due_to_error; } - assert( (pOut->flags&MEM_Str)==0 + assert( (pOut->flags&MEM_Str)==0 || pOut->enc==encoding || db->mallocFailed ); assert( !sqlite3VdbeMemTooBig(pOut) ); @@ -8509,7 +8693,7 @@ printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); } #endif - h %= pIn1->n; + h %= (pIn1->n*8); pIn1->z[h/8] |= 1<<(h&7); break; } @@ -8545,7 +8729,7 @@ printf("hash: %llu modulo %d -> %u\n", h, pIn1->n, (int)(h%pIn1->n)); } #endif - h %= pIn1->n; + h %= (pIn1->n*8); if( (pIn1->z[h/8] & (1<<(h&7)))==0 ){ VdbeBranchTaken(1, 2); p->aCounter[SQLITE_STMTSTATUS_FILTER_HIT]++; @@ -8797,7 +8981,7 @@ } if( opProperty==0xff ){ /* Never happens. This code exists to avoid a harmless linkage - ** warning aboud sqlite3VdbeRegisterDump() being defined but not + ** warning about sqlite3VdbeRegisterDump() being defined but not ** used. */ sqlite3VdbeRegisterDump(p); } @@ -8834,7 +9018,7 @@ p->rc = rc; sqlite3SystemError(db, rc); testcase( sqlite3GlobalConfig.xLog!=0 ); - sqlite3_log(rc, "statement aborts at %d: [%s] %s", + sqlite3_log(rc, "statement aborts at %d: [%s] %s", (int)(pOp - aOp), p->zSql, p->zErrMsg); if( p->eVdbeState==VDBE_RUN_STATE ) sqlite3VdbeHalt(p); if( rc==SQLITE_IOERR_NOMEM ) sqlite3OomFault(db); @@ -8876,8 +9060,8 @@ if( DbMaskNonZero(p->lockMask) ){ sqlite3VdbeLeave(p); } - assert( rc!=SQLITE_OK || nExtraDelete==0 - || sqlite3_strlike("DELETE%",p->zSql,0)!=0 + assert( rc!=SQLITE_OK || nExtraDelete==0 + || sqlite3_strlike("DELETE%",p->zSql,0)!=0 ); return rc; diff -Nru sqlite3-3.42.0/src/vdbe.h sqlite3-3.44.0-0/src/vdbe.h --- sqlite3-3.42.0/src/vdbe.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbe.h 2023-11-04 14:23:58.000000000 +0000 @@ -327,7 +327,7 @@ ** 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 amalagmation build. That's ok since a VDBE branch +** 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. ** @@ -345,7 +345,7 @@ ** // NULL option is not possible ** ** VdbeCoverageEqNe(v) // Previous OP_Jump is only interested -** // in distingishing equal and not-equal. +** // 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 @@ -355,7 +355,7 @@ ** During testing, the test application will invoke ** sqlite3_test_control(SQLITE_TESTCTRL_VDBE_COVERAGE,...) to set a callback ** routine that is invoked as each bytecode branch is taken. The callback -** contains the sqlite3.c source line number ov the VdbeCoverage macro and +** contains the sqlite3.c source line number of the VdbeCoverage macro and ** flags to indicate whether or not the branch was taken. The test application ** is responsible for keeping track of this and reporting byte-code branches ** that are never taken. diff -Nru sqlite3-3.42.0/src/vdbeInt.h sqlite3-3.44.0-0/src/vdbeInt.h --- sqlite3-3.42.0/src/vdbeInt.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbeInt.h 2023-11-04 14:23:58.000000000 +0000 @@ -56,6 +56,9 @@ /* Elements of the linked list at Vdbe.pAuxData */ typedef struct AuxData AuxData; +/* A cache of large TEXT or BLOB values in a VdbeCursor */ +typedef struct VdbeTxtBlbCache VdbeTxtBlbCache; + /* Types of VDBE cursors */ #define CURTYPE_BTREE 0 #define CURTYPE_SORTER 1 @@ -87,6 +90,7 @@ Bool useRandomRowid:1; /* Generate new record numbers semi-randomly */ Bool isOrdered:1; /* True if the table is not BTREE_UNORDERED */ Bool noReuse:1; /* OpenEphemeral may not reuse this cursor */ + Bool colCache:1; /* pCache pointer is initialized and non-NULL */ u16 seekHit; /* See the OP_SeekHit and OP_IfNoHope opcodes */ union { /* pBtx for isEphermeral. pAltMap otherwise */ Btree *pBtx; /* Separate file holding temporary table */ @@ -127,6 +131,7 @@ #ifdef SQLITE_ENABLE_COLUMN_USED_MASK u64 maskUsed; /* Mask of columns used by this cursor */ #endif + VdbeTxtBlbCache *pCache; /* Cache of large TEXT or BLOB values */ /* 2*nField extra array elements allocated for aType[], beyond the one ** static element declared in the structure. nField total array slots for @@ -139,17 +144,30 @@ #define IsNullCursor(P) \ ((P)->eCurType==CURTYPE_PSEUDO && (P)->nullRow && (P)->seekResult==0) - /* ** A value for VdbeCursor.cacheStatus that means the cache is always invalid. */ #define CACHE_STALE 0 /* +** Large TEXT or BLOB values can be slow to load, so we want to avoid +** loading them more than once. For that reason, large TEXT and BLOB values +** can be stored in a cache defined by this object, and attached to the +** VdbeCursor using the pCache field. +*/ +struct VdbeTxtBlbCache { + char *pCValue; /* A RCStr buffer to hold the value */ + i64 iOffset; /* File offset of the row being cached */ + int iCol; /* Column for which the cache is valid */ + u32 cacheStatus; /* Vdbe.cacheCtr value */ + u32 colCacheCtr; /* Column cache counter */ +}; + +/* ** When a sub-program is executed (OP_Program), a structure of this type ** is allocated to store the current value of the program counter, as ** well as the current memory cell array and various other frame specific -** values stored in the Vdbe struct. When the sub-program is finished, +** values stored in the Vdbe struct. When the sub-program is finished, ** these values are copied back to the Vdbe from the VdbeFrame structure, ** restoring the state of the VM to as it was before the sub-program ** began executing. @@ -263,7 +281,7 @@ ** ** * MEM_Blob|MEM_Zero A blob in Mem.z of length Mem.n plus ** MEM.u.i extra 0x00 bytes at the end. -** +** ** * MEM_Int Integer stored in Mem.u.i. ** ** * MEM_Real Real stored in Mem.u.r. @@ -277,7 +295,7 @@ ** If the MEM_Str flag is set then Mem.z points at a string representation. ** Usually this is encoded in the same unicode encoding as the main ** database (see below for exceptions). If the MEM_Term flag is also -** set, then the string is nul terminated. The MEM_Int and MEM_Real +** set, then the string is nul terminated. The MEM_Int and MEM_Real ** flags may coexist with the MEM_Str flag. */ #define MEM_Undefined 0x0000 /* Value is undefined */ @@ -330,7 +348,7 @@ ** Return true if a memory cell has been initialized and is valid. ** is for use inside assert() statements only. ** -** A Memory cell is initialized if at least one of the +** A Memory cell is initialized if at least one of the ** MEM_Null, MEM_Str, MEM_Int, MEM_Real, MEM_Blob, or MEM_IntReal bits ** is set. It is "undefined" if all those bits are zero. */ @@ -339,7 +357,7 @@ #endif /* -** Each auxiliary data pointer stored by a user defined function +** Each auxiliary data pointer stored by a user defined function ** implementation calling sqlite3_set_auxdata() is stored in an instance ** of this structure. All such structures associated with a single VM ** are stored in a linked list headed at Vdbe.pAuxData. All are destroyed @@ -388,7 +406,7 @@ ** sqlite3_stmt_scanstatus() interface. ** ** aAddrRange[]: -** This array is used by ScanStatus elements associated with EQP +** This array is used by ScanStatus elements associated with EQP ** notes that make an SQLITE_SCANSTAT_NCYCLE value available. It is ** an array of up to 3 ranges of VM addresses for which the Vdbe.anCycle[] ** values should be summed to calculate the NCYCLE value. Each pair of @@ -465,16 +483,18 @@ u32 nWrite; /* Number of write operations that have occurred */ #endif u16 nResColumn; /* Number of columns in one row of the result set */ + u16 nResAlloc; /* Column slots allocated to aColName[] */ u8 errorAction; /* Recovery action to do in case of an error */ u8 minWriteFileFormat; /* Minimum file format for writable database files */ u8 prepFlags; /* SQLITE_PREPARE_* flags */ u8 eVdbeState; /* On of the VDBE_*_STATE values */ bft expired:2; /* 1: recompile VM immediately 2: when convenient */ - bft explain:2; /* True if EXPLAIN present on SQL command */ + bft explain:2; /* 0: normal, 1: EXPLAIN, 2: EXPLAIN QUERY PLAN */ bft changeCntOn:1; /* True to update the change-counter */ bft usesStmtJournal:1; /* True if uses a statement journal */ bft readOnly:1; /* True for statements that do not write */ bft bIsReader:1; /* True for statements that read */ + bft haveEqpOps:1; /* Bytecode supports EXPLAIN QUERY PLAN */ yDbMask btreeMask; /* Bitmask of db->aDb[] entries referenced */ yDbMask lockMask; /* Subset of btreeMask that requires a lock */ u32 aCounter[9]; /* Counters used by sqlite3_stmt_status() */ @@ -505,7 +525,7 @@ #define VDBE_HALT_STATE 3 /* Finished. Need reset() or finalize() */ /* -** Structure used to store the context required by the +** Structure used to store the context required by the ** sqlite3_preupdate_*() API functions. */ struct PreUpdate { @@ -521,7 +541,7 @@ i64 iKey1; /* First key value passed to hook */ i64 iKey2; /* Second key value passed to hook */ Mem *aNew; /* Array of new.* values */ - Table *pTab; /* Schema object being upated */ + Table *pTab; /* Schema object being updated */ Index *pPk; /* PK index if pTab is WITHOUT ROWID */ }; @@ -611,6 +631,7 @@ int sqlite3VdbeMemIsRowSet(const Mem*); #endif int sqlite3VdbeMemSetRowSet(Mem*); +void sqlite3VdbeMemZeroTerminateIfAble(Mem*); int sqlite3VdbeMemMakeWriteable(Mem*); int sqlite3VdbeMemStringify(Mem*, u8, u8); int sqlite3IntFloatCompare(i64,double); @@ -667,7 +688,7 @@ # define sqlite3VdbeAssertAbortable(V) #endif -#if !defined(SQLITE_OMIT_SHARED_CACHE) +#if !defined(SQLITE_OMIT_SHARED_CACHE) void sqlite3VdbeEnter(Vdbe*); #else # define sqlite3VdbeEnter(X) diff -Nru sqlite3-3.42.0/src/vdbemem.c sqlite3-3.44.0-0/src/vdbemem.c --- sqlite3-3.42.0/src/vdbemem.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbemem.c 2023-11-04 14:23:58.000000000 +0000 @@ -315,6 +315,40 @@ } /* +** If pMem is already a string, detect if it is a zero-terminated +** string, or make it into one if possible, and mark it as such. +** +** This is an optimization. Correct operation continues even if +** this routine is a no-op. +*/ +void sqlite3VdbeMemZeroTerminateIfAble(Mem *pMem){ + if( (pMem->flags & (MEM_Str|MEM_Term|MEM_Ephem|MEM_Static))!=MEM_Str ){ + /* pMem must be a string, and it cannot be an ephemeral or static string */ + return; + } + if( pMem->enc!=SQLITE_UTF8 ) return; + if( NEVER(pMem->z==0) ) return; + if( pMem->flags & MEM_Dyn ){ + if( pMem->xDel==sqlite3_free + && sqlite3_msize(pMem->z) >= (u64)(pMem->n+1) + ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; + return; + } + if( pMem->xDel==sqlite3RCStrUnref ){ + /* Blindly assume that all RCStr objects are zero-terminated */ + pMem->flags |= MEM_Term; + return; + } + }else if( pMem->szMalloc >= pMem->n+1 ){ + pMem->z[pMem->n] = 0; + pMem->flags |= MEM_Term; + return; + } +} + +/* ** It is already known that pMem contains an unterminated string. ** Add the zero terminator. ** @@ -576,36 +610,6 @@ } /* -** Convert a 64-bit IEEE double into a 64-bit signed integer. -** If the double is out of range of a 64-bit signed integer then -** return the closest available 64-bit signed integer. -*/ -static SQLITE_NOINLINE i64 doubleToInt64(double r){ -#ifdef SQLITE_OMIT_FLOATING_POINT - /* When floating-point is omitted, double and int64 are the same thing */ - return r; -#else - /* - ** Many compilers we encounter do not define constants for the - ** minimum and maximum 64-bit integers, or they define them - ** inconsistently. And many do not understand the "LL" notation. - ** So we define our own static constants here using nothing - ** larger than a 32-bit integer constant. - */ - static const i64 maxInt = LARGEST_INT64; - static const i64 minInt = SMALLEST_INT64; - - if( r<=(double)minInt ){ - return minInt; - }else if( r>=(double)maxInt ){ - return maxInt; - }else{ - return (i64)r; - } -#endif -} - -/* ** Return some kind of integer value which is the best we can do ** at representing the value that *pMem describes as an integer. ** If pMem is an integer, then the value is exact. If pMem is @@ -631,7 +635,7 @@ testcase( flags & MEM_IntReal ); return pMem->u.i; }else if( flags & MEM_Real ){ - return doubleToInt64(pMem->u.r); + return sqlite3RealToI64(pMem->u.r); }else if( (flags & (MEM_Str|MEM_Blob))!=0 && pMem->z!=0 ){ return memIntValue(pMem); }else{ @@ -693,7 +697,7 @@ if( pMem->flags & MEM_IntReal ){ MemSetTypeFlag(pMem, MEM_Int); }else{ - i64 ix = doubleToInt64(pMem->u.r); + i64 ix = sqlite3RealToI64(pMem->u.r); /* Only mark the value as an integer if ** @@ -761,8 +765,8 @@ ** from UBSAN. */ i64 sqlite3RealToI64(double r){ - if( r<=(double)SMALLEST_INT64 ) return SMALLEST_INT64; - if( r>=(double)LARGEST_INT64) return LARGEST_INT64; + if( r<-9223372036854774784.0 ) return SMALLEST_INT64; + if( r>+9223372036854774784.0 ) return LARGEST_INT64; return (i64)r; } @@ -833,6 +837,7 @@ break; } default: { + int rc; assert( aff==SQLITE_AFF_TEXT ); assert( MEM_Str==(MEM_Blob>>3) ); pMem->flags |= (pMem->flags&MEM_Blob)>>3; @@ -840,7 +845,9 @@ assert( pMem->flags & MEM_Str || pMem->db->mallocFailed ); pMem->flags &= ~(MEM_Int|MEM_Real|MEM_IntReal|MEM_Blob|MEM_Zero); if( encoding!=SQLITE_UTF8 ) pMem->n &= ~1; - return sqlite3VdbeChangeEncoding(pMem, encoding); + rc = sqlite3VdbeChangeEncoding(pMem, encoding); + if( rc ) return rc; + sqlite3VdbeMemZeroTerminateIfAble(pMem); } } return SQLITE_OK; @@ -1364,6 +1371,24 @@ return valueToText(pVal, enc); } +/* Return true if sqlit3_value object pVal is a string or blob value +** that uses the destructor specified in the second argument. +** +** TODO: Maybe someday promote this interface into a published API so +** that third-party extensions can get access to it? +*/ +int sqlite3ValueIsOfClass(const sqlite3_value *pVal, void(*xFree)(void*)){ + if( ALWAYS(pVal!=0) + && ALWAYS((pVal->flags & (MEM_Str|MEM_Blob))!=0) + && (pVal->flags & MEM_Dyn)!=0 + && pVal->xDel==xFree + ){ + return 1; + }else{ + return 0; + } +} + /* ** Create a new sqlite3_value object. */ @@ -1431,6 +1456,7 @@ } pRec->nField = p->iVal+1; + sqlite3VdbeMemSetNull(&pRec->aMem[p->iVal]); return &pRec->aMem[p->iVal]; } #else @@ -1690,6 +1716,7 @@ if( pVal ){ pVal->flags = MEM_Int; pVal->u.i = pExpr->u.zToken[4]==0; + sqlite3ValueApplyAffinity(pVal, affinity, enc); } } diff -Nru sqlite3-3.42.0/src/vdbesort.c sqlite3-3.44.0-0/src/vdbesort.c --- sqlite3-3.42.0/src/vdbesort.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbesort.c 2023-11-04 14:23:58.000000000 +0000 @@ -55,7 +55,7 @@ ** is like Close() followed by Init() only ** much faster. ** -** The interfaces above must be called in a particular order. Write() can +** The interfaces above must be called in a particular order. Write() can ** only occur in between Init()/Reset() and Rewind(). Next(), Rowkey(), and ** Compare() can only occur in between Rewind() and Close()/Reset(). i.e. ** @@ -63,16 +63,16 @@ ** for each record: Write() ** Rewind() ** Rowkey()/Compare() -** Next() +** Next() ** Close() ** ** Algorithm: ** -** Records passed to the sorter via calls to Write() are initially held +** Records passed to the sorter via calls to Write() are initially held ** unsorted in main memory. Assuming the amount of memory used never exceeds ** a threshold, when Rewind() is called the set of records is sorted using ** an in-memory merge sort. In this case, no temporary files are required -** and subsequent calls to Rowkey(), Next() and Compare() read records +** and subsequent calls to Rowkey(), Next() and Compare() read records ** directly from main memory. ** ** If the amount of space used to store records in main memory exceeds the @@ -82,10 +82,10 @@ ** 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 +** 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" multipled by +** 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 @@ -102,28 +102,28 @@ ** than zero, and (b) worker threads have been enabled at runtime by calling ** "PRAGMA threads=N" with some value of N greater than 0. ** -** When Rewind() is called, any data remaining in memory is flushed to a +** 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 retreived from the sorter by the VDBE. The +** 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 +** merged T bytes of data into a single sorted PMA, the main thread ** begins reading keys from that PMA while the background thread proceeds ** with merging the next T bytes of data. And so on. ** -** Parameter T is set to half the value of the memory threshold used +** Parameter T is set to half the value of the memory threshold used ** by Write() above to determine when to create a new PMA. ** -** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when -** Rewind() is called, then a hierarchy of incremental-merges is used. -** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on +** If there are more than SORTER_MAX_MERGE_COUNT PMAs in total when +** Rewind() is called, then a hierarchy of incremental-merges is used. +** First, T bytes of data from the first SORTER_MAX_MERGE_COUNT PMAs on ** disk are merged together. Then T bytes of data from the second set, and ** so on, such that no operation ever merges more than SORTER_MAX_MERGE_COUNT ** PMAs at a time. This done is to improve locality. @@ -138,7 +138,7 @@ #include "sqliteInt.h" #include "vdbeInt.h" -/* +/* ** If SQLITE_DEBUG_SORTER_THREADS is defined, this module outputs various ** messages to stderr that may be helpful in understanding the performance ** characteristics of the sorter in multi-threaded mode. @@ -167,7 +167,7 @@ typedef struct IncrMerger IncrMerger; /* Read & merge multiple PMAs */ /* -** A container for a temp file handle and the current amount of data +** A container for a temp file handle and the current amount of data ** stored in the file. */ struct SorterFile { @@ -186,7 +186,7 @@ struct SorterList { SorterRecord *pList; /* Linked list of records */ u8 *aMemory; /* If non-NULL, bulk memory to hold pList */ - int szPMA; /* Size of pList as PMA in bytes */ + i64 szPMA; /* Size of pList as PMA in bytes */ }; /* @@ -207,17 +207,17 @@ ** the MergeEngine.nTree variable. ** ** The final (N/2) elements of aTree[] contain the results of comparing -** pairs of PMA keys together. Element i contains the result of +** pairs of PMA keys together. Element i contains the result of ** comparing aReadr[2*i-N] and aReadr[2*i-N+1]. Whichever key is smaller, the -** aTree element is set to the index of it. +** aTree element is set to the index of it. ** ** For the purposes of this comparison, EOF is considered greater than any ** other key value. If the keys are equal (only possible with two EOF ** values), it doesn't matter which index is stored. ** -** The (N/4) elements of aTree[] that precede the final (N/2) described +** The (N/4) elements of aTree[] that precede the final (N/2) described ** above contains the index of the smallest of each block of 4 PmaReaders -** And so on. So that aTree[1] contains the index of the PmaReader that +** And so on. So that aTree[1] contains the index of the PmaReader that ** currently points to the smallest key value. aTree[0] is unused. ** ** Example: @@ -233,7 +233,7 @@ ** ** aTree[] = { X, 5 0, 5 0, 3, 5, 6 } ** -** The current element is "Apple" (the value of the key indicated by +** The current element is "Apple" (the value of the key indicated by ** PmaReader 5). When the Next() operation is invoked, PmaReader 5 will ** be advanced to the next key in its segment. Say the next key is ** "Eggplant": @@ -271,11 +271,11 @@ ** ** Essentially, this structure contains all those fields of the VdbeSorter ** structure for which each thread requires a separate instance. For example, -** each thread requries its own UnpackedRecord object to unpack records in +** each thread requeries 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 +** 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 @@ -295,10 +295,10 @@ struct SortSubtask { SQLiteThread *pThread; /* Background thread, if any */ int bDone; /* Set if thread is finished but not joined */ + int nPMA; /* Number of PMAs currently in file */ VdbeSorter *pSorter; /* Sorter that owns this sub-task */ UnpackedRecord *pUnpacked; /* Space to unpack a record */ SorterList list; /* List for thread to write to a PMA */ - int nPMA; /* Number of PMAs currently in file */ SorterCompare xCompare; /* Compare function to use */ SorterFile file; /* Temp file for level-0 PMAs */ SorterFile file2; /* Space for other PMAs */ @@ -306,7 +306,7 @@ /* -** Main sorter structure. A single instance of this is allocated for each +** Main sorter structure. A single instance of this is allocated for each ** sorter cursor created by the VDBE. ** ** mxKeysize: @@ -343,7 +343,7 @@ ** PMA, in sorted order. The next key to be read is cached in nKey/aKey. ** aKey might point into aMap or into aBuffer. If neither of those locations ** contain a contiguous representation of the key, then aAlloc is allocated -** and the key is copied into aAlloc and aKey is made to poitn to aAlloc. +** and the key is copied into aAlloc and aKey is made to point to aAlloc. ** ** pFd==0 at EOF. */ @@ -362,21 +362,21 @@ }; /* -** Normally, a PmaReader object iterates through an existing PMA stored +** Normally, a PmaReader object iterates through an existing PMA stored ** within a temp file. However, if the PmaReader.pIncr variable points to ** an object of the following type, it may be used to iterate/merge through ** multiple PMAs simultaneously. ** -** There are two types of IncrMerger object - single (bUseThread==0) and -** multi-threaded (bUseThread==1). +** There are two types of IncrMerger object - single (bUseThread==0) and +** multi-threaded (bUseThread==1). ** -** A multi-threaded IncrMerger object uses two temporary files - aFile[0] -** and aFile[1]. Neither file is allowed to grow to more than mxSz bytes in -** size. When the IncrMerger is initialized, it reads enough data from -** pMerger to populate aFile[0]. It then sets variables within the -** corresponding PmaReader object to read from that file and kicks off -** a background thread to populate aFile[1] with the next mxSz bytes of -** sorted record data from pMerger. +** A multi-threaded IncrMerger object uses two temporary files - aFile[0] +** and aFile[1]. Neither file is allowed to grow to more than mxSz bytes in +** size. When the IncrMerger is initialized, it reads enough data from +** pMerger to populate aFile[0]. It then sets variables within the +** corresponding PmaReader object to read from that file and kicks off +** a background thread to populate aFile[1] with the next mxSz bytes of +** sorted record data from pMerger. ** ** When the PmaReader reaches the end of aFile[0], it blocks until the ** background thread has finished populating aFile[1]. It then exchanges @@ -387,7 +387,7 @@ ** ** A single-threaded IncrMerger does not open any temporary files of its ** own. Instead, it has exclusive access to mxSz bytes of space beginning -** at offset iStartOff of file pTask->file2. And instead of using a +** at offset iStartOff of file pTask->file2. And instead of using a ** background thread to prepare data for the PmaReader, with a single ** threaded IncrMerger the allocate part of pTask->file2 is "refilled" with ** keys from pMerger by the calling thread whenever the PmaReader runs out @@ -499,7 +499,7 @@ assert( p->aBuffer ); - /* If there is no more data to be read from the buffer, read the next + /* If there is no more data to be read from the buffer, read the next ** p->nBuffer bytes of data from the file into it. Or, if there are less ** than p->nBuffer bytes remaining in the PMA, read all remaining data. */ iBuf = p->iReadOff % p->nBuffer; @@ -520,11 +520,11 @@ assert( rc!=SQLITE_IOERR_SHORT_READ ); if( rc!=SQLITE_OK ) return rc; } - nAvail = p->nBuffer - iBuf; + nAvail = p->nBuffer - iBuf; if( nByte<=nAvail ){ /* The requested data is available in the in-memory buffer. In this - ** case there is no need to make a copy of the data, just return a + ** case there is no need to make a copy of the data, just return a ** pointer into the buffer to the caller. */ *ppOut = &p->aBuffer[iBuf]; p->iReadOff += nByte; @@ -603,7 +603,7 @@ /* ** Attempt to memory map file pFile. If successful, set *pp to point to the -** new mapping and return SQLITE_OK. If the mapping is not attempted +** new mapping and return SQLITE_OK. If the mapping is not attempted ** (because the file is too large or the VFS layer is configured not to use ** mmap), return SQLITE_OK and set *pp to NULL. ** @@ -624,7 +624,7 @@ /* ** Attach PmaReader pReadr to file pFile (if it is not already attached to -** that file) and seek it to offset iOff within the file. Return SQLITE_OK +** that file) and seek it to offset iOff within the file. Return SQLITE_OK ** if successful, or an SQLite error code if an error occurs. */ static int vdbePmaReaderSeek( @@ -714,11 +714,11 @@ /* ** Initialize PmaReader pReadr to scan through the PMA stored in file pFile -** starting at offset iStart and ending at offset iEof-1. This function -** leaves the PmaReader pointing to the first key in the PMA (or EOF if the +** starting at offset iStart and ending at offset iEof-1. This function +** leaves the PmaReader pointing to the first key in the PMA (or EOF if the ** PMA is empty). ** -** If the pnByte parameter is NULL, then it is assumed that the file +** If the pnByte parameter is NULL, then it is assumed that the file ** contains a single PMA, and that that PMA omits the initial length varint. */ static int vdbePmaReaderInit( @@ -751,7 +751,7 @@ /* ** A version of vdbeSorterCompare() that assumes that it has already been -** determined that the first field of key1 is equal to the first field of +** determined that the first field of key1 is equal to the first field of ** key2. */ static int vdbeSorterCompareTail( @@ -769,7 +769,7 @@ } /* -** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, +** Compare key1 (buffer pKey1, size nKey1 bytes) with key2 (buffer pKey2, ** size nKey2 bytes). Use (pTask->pKeyInfo) for the collation sequences ** used by the comparison. Return the result of the comparison. ** @@ -915,7 +915,7 @@ ** is non-zero and the sorter is able to guarantee a stable sort, nField ** is used instead. This is used when sorting records for a CREATE INDEX ** statement. In this case, keys are always delivered to the sorter in -** order of the primary key, which happens to be make up the final part +** order of the primary key, which happens to be make up the final part ** of the records being sorted. So if the sort is stable, there is never ** any reason to compare PK fields and they can be ignored for a small ** performance boost. @@ -1016,7 +1016,7 @@ } } - if( pKeyInfo->nAllField<13 + if( pKeyInfo->nAllField<13 && (pKeyInfo->aColl[0]==0 || pKeyInfo->aColl[0]==db->pDfltColl) && (pKeyInfo->aSortFlags[0] & KEYINFO_ORDER_BIGNULL)==0 ){ @@ -1041,7 +1041,7 @@ } /* -** Free all resources owned by the object indicated by argument pTask. All +** Free all resources owned by the object indicated by argument pTask. All ** fields of *pTask are zeroed before returning. */ static void vdbeSortSubtaskCleanup(sqlite3 *db, SortSubtask *pTask){ @@ -1141,7 +1141,7 @@ } /* -** Join all outstanding threads launched by SorterWrite() to create +** Join all outstanding threads launched by SorterWrite() to create ** level-0 PMAs. */ static int vdbeSorterJoinAll(VdbeSorter *pSorter, int rcin){ @@ -1150,10 +1150,10 @@ /* This function is always called by the main user thread. ** - ** If this function is being called after SorterRewind() has been called, + ** If this function is being called after SorterRewind() has been called, ** it is possible that thread pSorter->aTask[pSorter->nTask-1].pThread ** is currently attempt to join one of the other threads. To avoid a race - ** condition where this thread also attempts to join the same object, join + ** condition where this thread also attempts to join the same object, join ** thread pSorter->aTask[pSorter->nTask-1].pThread first. */ for(i=pSorter->nTask-1; i>=0; i--){ SortSubtask *pTask = &pSorter->aTask[i]; @@ -1325,8 +1325,8 @@ } /* -** If it has not already been allocated, allocate the UnpackedRecord -** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or +** If it has not already been allocated, allocate the UnpackedRecord +** structure at pTask->pUnpacked. Return SQLITE_OK if successful (or ** if no allocation was required), or SQLITE_NOMEM otherwise. */ static int vdbeSortAllocUnpacked(SortSubtask *pTask){ @@ -1389,14 +1389,14 @@ if( p->typeMask==SORTER_TYPE_INTEGER ){ return vdbeSorterCompareInt; }else if( p->typeMask==SORTER_TYPE_TEXT ){ - return vdbeSorterCompareText; + return vdbeSorterCompareText; } return vdbeSorterCompare; } /* -** Sort the linked list of records headed at pTask->pList. Return -** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if +** Sort the linked list of records headed at pTask->pList. Return +** SQLITE_OK if successful, or an SQLite error code (i.e. SQLITE_NOMEM) if ** an error occurs. */ static int vdbeSorterSort(SortSubtask *pTask, SorterList *pList){ @@ -1441,8 +1441,8 @@ } pList->pList = p; - assert( pTask->pUnpacked->errCode==SQLITE_OK - || pTask->pUnpacked->errCode==SQLITE_NOMEM + assert( pTask->pUnpacked->errCode==SQLITE_OK + || pTask->pUnpacked->errCode==SQLITE_NOMEM ); return pTask->pUnpacked->errCode; } @@ -1483,8 +1483,8 @@ memcpy(&p->aBuffer[p->iBufEnd], &pData[nData-nRem], nCopy); p->iBufEnd += nCopy; if( p->iBufEnd==p->nBuffer ){ - p->eFWErr = sqlite3OsWrite(p->pFd, - &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, p->iWriteOff + p->iBufStart ); p->iBufStart = p->iBufEnd = 0; @@ -1499,7 +1499,7 @@ /* ** Flush any buffered data to disk and clean up the PMA-writer object. ** The results of using the PMA-writer after this call are undefined. -** Return SQLITE_OK if flushing the buffered data succeeds or is not +** Return SQLITE_OK if flushing the buffered data succeeds or is not ** required. Otherwise, return an SQLite error code. ** ** Before returning, set *piEof to the offset immediately following the @@ -1508,8 +1508,8 @@ static int vdbePmaWriterFinish(PmaWriter *p, i64 *piEof){ int rc; if( p->eFWErr==0 && ALWAYS(p->aBuffer) && p->iBufEnd>p->iBufStart ){ - p->eFWErr = sqlite3OsWrite(p->pFd, - &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, + p->eFWErr = sqlite3OsWrite(p->pFd, + &p->aBuffer[p->iBufStart], p->iBufEnd - p->iBufStart, p->iWriteOff + p->iBufStart ); } @@ -1521,11 +1521,11 @@ } /* -** Write value iVal encoded as a varint to the PMA. Return +** Write value iVal encoded as a varint to the PMA. Return ** SQLITE_OK if successful, or an SQLite error code if an error occurs. */ static void vdbePmaWriteVarint(PmaWriter *p, u64 iVal){ - int nByte; + int nByte; u8 aByte[10]; nByte = sqlite3PutVarint(aByte, iVal); vdbePmaWriteBlob(p, aByte, nByte); @@ -1533,7 +1533,7 @@ /* ** Write the current contents of in-memory linked-list pList to a level-0 -** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if +** PMA in the temp file belonging to sub-task pTask. Return SQLITE_OK if ** successful, or an SQLite error code otherwise. ** ** The format of a PMA is: @@ -1541,8 +1541,8 @@ ** * A varint. This varint contains the total number of bytes of content ** in the PMA (not including the varint itself). ** -** * One or more records packed end-to-end in order of ascending keys. -** Each record consists of a varint followed by a blob of data (the +** * One or more records packed end-to-end in order of ascending keys. +** Each record consists of a varint followed by a blob of data (the ** key). The varint is the number of bytes in the blob of data. */ static int vdbeSorterListToPMA(SortSubtask *pTask, SorterList *pList){ @@ -1551,7 +1551,7 @@ PmaWriter writer; /* Object used to write to the file */ #ifdef SQLITE_DEBUG - /* Set iSz to the expected size of file pTask->file after writing the PMA. + /* Set iSz to the expected size of file pTask->file after writing the PMA. ** This is used by an assert() statement at the end of this function. */ i64 iSz = pList->szPMA + sqlite3VarintLen(pList->szPMA) + pTask->file.iEof; #endif @@ -1704,7 +1704,7 @@ SortSubtask *pTask = 0; /* Thread context used to create new PMA */ int nWorker = (pSorter->nTask-1); - /* Set the flag to indicate that at least one PMA has been written. + /* Set the flag to indicate that at least one PMA has been written. ** Or will be, anyhow. */ pSorter->bUsePMA = 1; @@ -1714,7 +1714,7 @@ ** the background thread from a sub-tasks previous turn is still running, ** skip it. If the first (pSorter->nTask-1) sub-tasks are all still busy, ** fall back to using the final sub-task. The first (pSorter->nTask-1) - ** sub-tasks are prefered as they use background threads - the final + ** sub-tasks are preferred as they use background threads - the final ** sub-task uses the main thread. */ for(i=0; iiPrev + i + 1) % nWorker; @@ -1772,8 +1772,8 @@ int rc = SQLITE_OK; /* Return Code */ SorterRecord *pNew; /* New list element */ int bFlush; /* True to flush contents of memory to PMA */ - int nReq; /* Bytes of memory required */ - int nPMA; /* Bytes of PMA space required */ + i64 nReq; /* Bytes of memory required */ + i64 nPMA; /* Bytes of PMA space required */ int t; /* serial type of first record field */ assert( pCsr->eCurType==CURTYPE_SORTER ); @@ -1795,14 +1795,14 @@ ** If using the single large allocation mode (pSorter->aMemory!=0), then ** flush the contents of memory to a new PMA if (a) at least one value is ** already in memory and (b) the new value will not fit in memory. - ** + ** ** Or, if using separate allocations for each record, flush the contents ** of memory to a PMA if either of the following are true: ** - ** * The total memory allocated for the in-memory list is greater + ** * The total memory allocated for the in-memory list is greater ** than (page-size * cache-size), or ** - ** * The total memory allocated for the in-memory list is greater + ** * The total memory allocated for the in-memory list is greater ** than (page-size * 10) and sqlite3HeapNearlyFull() returns true. */ nReq = pVal->n + sizeof(SorterRecord); @@ -1941,11 +1941,11 @@ ** aFile[0] such that the PmaReader should start rereading it from the ** beginning. ** -** For single-threaded objects, this is accomplished by literally reading -** keys from pIncr->pMerger and repopulating aFile[0]. +** For single-threaded objects, this is accomplished by literally reading +** keys from pIncr->pMerger and repopulating aFile[0]. ** -** For multi-threaded objects, all that is required is to wait until the -** background thread is finished (if it is not already) and then swap +** For multi-threaded objects, all that is required is to wait until the +** background thread is finished (if it is not already) and then swap ** aFile[0] and aFile[1] in place. If the contents of pMerger have not ** been exhausted, this function also launches a new background thread ** to populate the new aFile[1]. @@ -2086,7 +2086,7 @@ #define INCRINIT_TASK 1 #define INCRINIT_ROOT 2 -/* +/* ** Forward reference required as the vdbeIncrMergeInit() and ** vdbePmaReaderIncrInit() routines are called mutually recursively when ** building a merge tree. @@ -2095,7 +2095,7 @@ /* ** Initialize the MergeEngine object passed as the second argument. Once this -** function returns, the first key of merged data may be read from the +** function returns, the first key of merged data may be read from the ** MergeEngine object in the usual fashion. ** ** If argument eMode is INCRINIT_ROOT, then it is assumed that any IncrMerge @@ -2105,8 +2105,8 @@ ** required is to call vdbePmaReaderNext() on each PmaReader to point it at ** its first key. ** -** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use -** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data +** Otherwise, if eMode is any value other than INCRINIT_ROOT, then use +** vdbePmaReaderIncrMergeInit() to initialize each PmaReader that feeds data ** to pMerger. ** ** SQLITE_OK is returned if successful, or an SQLite error code otherwise. @@ -2161,19 +2161,19 @@ ** object at (pReadr->pIncr). ** ** If argument eMode is set to INCRINIT_NORMAL, then all PmaReaders -** in the sub-tree headed by pReadr are also initialized. Data is then -** loaded into the buffers belonging to pReadr and it is set to point to +** in the sub-tree headed by pReadr are also initialized. Data is then +** loaded into the buffers belonging to pReadr and it is set to point to ** the first key in its range. ** ** If argument eMode is set to INCRINIT_TASK, then pReadr is guaranteed ** to be a multi-threaded PmaReader and this function is being called in a -** background thread. In this case all PmaReaders in the sub-tree are +** background thread. In this case all PmaReaders in the sub-tree are ** initialized as for INCRINIT_NORMAL and the aFile[1] buffer belonging to ** pReadr is populated. However, pReadr itself is not set up to point ** to its first key. A call to vdbePmaReaderNext() is still required to do -** that. +** that. ** -** The reason this function does not call vdbePmaReaderNext() immediately +** The reason this function does not call vdbePmaReaderNext() immediately ** in the INCRINIT_TASK case is that vdbePmaReaderNext() assumes that it has ** to block on thread (pTask->thread) before accessing aFile[1]. But, since ** this entire function is being run by thread (pTask->thread), that will @@ -2198,7 +2198,7 @@ rc = vdbeMergeEngineInit(pTask, pIncr->pMerger, eMode); - /* Set up the required files for pIncr. A multi-theaded IncrMerge object + /* 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 ){ @@ -2229,12 +2229,12 @@ if( rc==SQLITE_OK && pIncr->bUseThread ){ /* Use the current thread to populate aFile[1], even though this ** PmaReader is multi-threaded. If this is an INCRINIT_TASK object, - ** then this function is already running in background thread - ** pIncr->pTask->thread. + ** then this function is already running in background thread + ** pIncr->pTask->thread. ** - ** If this is the INCRINIT_ROOT object, then it is running in the + ** If this is the INCRINIT_ROOT object, then it is running in the ** main VDBE thread. But that is Ok, as that thread cannot return - ** control to the VDBE or proceed with anything useful until the + ** control to the VDBE or proceed with anything useful until the ** first results are ready from this merger object anyway. */ assert( eMode==INCRINIT_ROOT || eMode==INCRINIT_TASK ); @@ -2251,7 +2251,7 @@ #if SQLITE_MAX_WORKER_THREADS>0 /* -** The main routine for vdbePmaReaderIncrMergeInit() operations run in +** The main routine for vdbePmaReaderIncrMergeInit() operations run in ** background threads. */ static void *vdbePmaReaderBgIncrInit(void *pCtx){ @@ -2269,8 +2269,8 @@ ** (if pReadr->pIncr==0), then this function is a no-op. Otherwise, it invokes ** the vdbePmaReaderIncrMergeInit() function with the parameters passed to ** this routine to initialize the incremental merge. -** -** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), +** +** If the IncrMerger object is multi-threaded (IncrMerger.bUseThread==1), ** then a background thread is launched to call vdbePmaReaderIncrMergeInit(). ** Or, if the IncrMerger is single threaded, the same function is called ** using the current thread. @@ -2300,7 +2300,7 @@ ** to NULL and return an SQLite error code. ** ** When this function is called, *piOffset is set to the offset of the -** first PMA to read from pTask->file. Assuming no error occurs, it is +** first PMA to read from pTask->file. Assuming no error occurs, it is ** set to the offset immediately following the last byte of the last ** PMA before returning. If an error does occur, then the final value of ** *piOffset is undefined. @@ -2410,12 +2410,12 @@ /* ** This function is called as part of a SorterRewind() operation on a sorter ** that has already written two or more level-0 PMAs to one or more temp -** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that +** files. It builds a tree of MergeEngine/IncrMerger/PmaReader objects that ** can be used to incrementally merge all PMAs on disk. ** ** If successful, SQLITE_OK is returned and *ppOut set to point to the ** MergeEngine object at the root of the tree before returning. Or, if an -** error occurs, an SQLite error code is returned and the final value +** error occurs, an SQLite error code is returned and the final value ** of *ppOut is undefined. */ static int vdbeSorterMergeTreeBuild( @@ -2427,8 +2427,8 @@ int iTask; #if SQLITE_MAX_WORKER_THREADS>0 - /* If the sorter uses more than one task, then create the top-level - ** MergeEngine here. This MergeEngine will read data from exactly + /* If the sorter uses more than one task, then create the top-level + ** MergeEngine here. This MergeEngine will read data from exactly ** one PmaReader per sub-task. */ assert( pSorter->bUseThreads || pSorter->nTask==1 ); if( pSorter->nTask>1 ){ @@ -2537,7 +2537,7 @@ } for(iTask=0; rc==SQLITE_OK && iTasknTask; iTask++){ /* Check that: - ** + ** ** a) The incremental merge object is configured to use the ** right task, and ** b) If it is using task (nTask-1), it is configured to run @@ -2600,7 +2600,7 @@ return rc; } - /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() + /* Write the current in-memory list to a PMA. When the VdbeSorterWrite() ** function flushes the contents of memory to disk, it immediately always ** creates a new list consisting of a single key immediately afterwards. ** So the list is never empty at this point. */ @@ -2612,7 +2612,7 @@ vdbeSorterRewindDebug("rewind"); - /* Assuming no errors have occurred, set up a merger structure to + /* Assuming no errors have occurred, set up a merger structure to ** incrementally read and merge all remaining PMAs. */ assert( pSorter->pReader==0 ); if( rc==SQLITE_OK ){ @@ -2666,7 +2666,7 @@ } /* -** Return a pointer to a buffer owned by the sorter that contains the +** Return a pointer to a buffer owned by the sorter that contains the ** current key. */ static void *vdbeSorterRowkey( diff -Nru sqlite3-3.42.0/src/vdbevtab.c sqlite3-3.44.0-0/src/vdbevtab.c --- sqlite3-3.42.0/src/vdbevtab.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vdbevtab.c 2023-11-04 14:23:58.000000000 +0000 @@ -69,6 +69,8 @@ "p5 INT," "comment TEXT," "subprog TEXT," + "nexec INT," + "ncycle INT," "stmt HIDDEN" ");", @@ -231,7 +233,7 @@ } } } - i += 10; + i += 20; } } switch( i ){ @@ -281,16 +283,31 @@ } break; } - case 10: /* tables_used.type */ + +#ifdef SQLITE_ENABLE_STMT_SCANSTATUS + case 9: /* nexec */ + sqlite3_result_int(ctx, pOp->nExec); + break; + case 10: /* ncycle */ + sqlite3_result_int(ctx, pOp->nCycle); + break; +#else + case 9: /* nexec */ + case 10: /* ncycle */ + sqlite3_result_int(ctx, 0); + break; +#endif + + case 20: /* tables_used.type */ sqlite3_result_text(ctx, pCur->zType, -1, SQLITE_STATIC); break; - case 11: /* tables_used.schema */ + case 21: /* tables_used.schema */ sqlite3_result_text(ctx, pCur->zSchema, -1, SQLITE_STATIC); break; - case 12: /* tables_used.name */ + case 22: /* tables_used.name */ sqlite3_result_text(ctx, pCur->zName, -1, SQLITE_STATIC); break; - case 13: /* tables_used.wr */ + case 23: /* tables_used.wr */ sqlite3_result_int(ctx, pOp->opcode==OP_OpenWrite); break; } @@ -364,7 +381,7 @@ int rc = SQLITE_CONSTRAINT; struct sqlite3_index_constraint *p; bytecodevtab *pVTab = (bytecodevtab*)tab; - int iBaseCol = pVTab->bTablesUsed ? 4 : 8; + int iBaseCol = pVTab->bTablesUsed ? 4 : 10; pIdxInfo->estimatedCost = (double)100; pIdxInfo->estimatedRows = 100; pIdxInfo->idxNum = 0; @@ -411,7 +428,8 @@ /* xSavepoint */ 0, /* xRelease */ 0, /* xRollbackTo */ 0, - /* xShadowName */ 0 + /* xShadowName */ 0, + /* xIntegrity */ 0 }; diff -Nru sqlite3-3.42.0/src/vtab.c sqlite3-3.44.0-0/src/vtab.c --- sqlite3-3.42.0/src/vtab.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/vtab.c 2023-11-04 14:23:58.000000000 +0000 @@ -17,7 +17,7 @@ /* ** Before a virtual table xCreate() or xConnect() method is invoked, the ** sqlite3.pVtabCtx member variable is set to point to an instance of -** this struct allocated on the stack. It is used by the implementation of +** this struct allocated on the stack. It is used by the implementation of ** the sqlite3_declare_vtab() and sqlite3_vtab_config() APIs, both of which ** are invoked only from within xCreate and xConnect methods. */ @@ -174,7 +174,7 @@ /* ** Lock the virtual table so that it cannot be disconnected. ** Locks nest. Every lock should have a corresponding unlock. -** If an unlock is omitted, resources leaks will occur. +** If an unlock is omitted, resources leaks will occur. ** ** If a disconnect is attempted while a virtual table is locked, ** the disconnect is deferred until all locks have been removed. @@ -186,7 +186,7 @@ /* ** pTab is a pointer to a Table structure representing a virtual-table. -** Return a pointer to the VTable object used by connection db to access +** Return a pointer to the VTable object used by connection db to access ** this virtual-table, if one has been created, or NULL otherwise. */ VTable *sqlite3GetVTable(sqlite3 *db, Table *pTab){ @@ -222,7 +222,7 @@ /* ** Table p is a virtual table. This function moves all elements in the ** p->u.vtab.p list to the sqlite3.pDisconnect lists of their associated -** database connections to be disconnected at the next opportunity. +** database connections to be disconnected at the next opportunity. ** Except, if argument db is not NULL, then the entry associated with ** connection db is left in the p->u.vtab.p list. */ @@ -234,8 +234,8 @@ pVTable = p->u.vtab.p; p->u.vtab.p = 0; - /* Assert that the mutex (if any) associated with the BtShared database - ** that contains table p is held by the caller. See header comments + /* Assert that the mutex (if any) associated with the BtShared database + ** that contains table p is held by the caller. See header comments ** above function sqlite3VtabUnlockList() for an explanation of why ** this makes it safe to access the sqlite3.pDisconnect list of any ** database connection that may have an entry in the p->u.vtab.p list. @@ -291,7 +291,7 @@ ** Disconnect all the virtual table objects in the sqlite3.pDisconnect list. ** ** This function may only be called when the mutexes associated with all -** shared b-tree databases opened using connection db are held by the +** shared b-tree databases opened using connection db are held by the ** caller. This is done to protect the sqlite3.pDisconnect list. The ** sqlite3.pDisconnect list is accessed only as follows: ** @@ -304,7 +304,7 @@ ** or, if the virtual table is stored in a non-sharable database, then ** the database handle mutex is held. ** -** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously +** As a result, a sqlite3.pDisconnect cannot be accessed simultaneously ** by multiple threads. It is thread-safe. */ void sqlite3VtabUnlockList(sqlite3 *db){ @@ -330,12 +330,12 @@ ** record. ** ** Since it is a virtual-table, the Table structure contains a pointer -** to the head of a linked list of VTable structures. Each VTable +** to the head of a linked list of VTable structures. Each VTable ** structure is associated with a single sqlite3* user of the schema. -** The reference count of the VTable structure associated with database -** connection db is decremented immediately (which may lead to the +** The reference count of the VTable structure associated with database +** connection db is decremented immediately (which may lead to the ** structure being xDisconnected and free). Any other VTable structures -** in the list are moved to the sqlite3.pDisconnect list of the associated +** in the list are moved to the sqlite3.pDisconnect list of the associated ** database connection. */ void sqlite3VtabClear(sqlite3 *db, Table *p){ @@ -421,7 +421,7 @@ if( pTable->u.vtab.azArg ){ int iDb = sqlite3SchemaToIndex(db, pTable->pSchema); assert( iDb>=0 ); /* The database the table is being created in */ - sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, + sqlite3AuthCheck(pParse, SQLITE_CREATE_VTABLE, pTable->zName, pTable->u.vtab.azArg[0], pParse->db->aDb[iDb].zDbSName); } #endif @@ -454,7 +454,7 @@ addArgumentToVtab(pParse); pParse->sArg.z = 0; if( pTab->u.vtab.nArg<1 ) return; - + /* If the CREATE VIRTUAL TABLE statement is being entered for the ** first time (in other words if the virtual table is actually being ** created now instead of just being read out of sqlite_schema) then @@ -476,12 +476,12 @@ } zStmt = sqlite3MPrintf(db, "CREATE VIRTUAL TABLE %T", &pParse->sNameToken); - /* A slot for the record has already been allocated in the + /* A slot for the record has already been allocated in the ** schema table. We just need to update that slot with all - ** the information we've collected. + ** the information we've collected. ** ** The VM register number pParse->regRowid holds the rowid of an - ** entry in the sqlite_schema table tht was created for this vtab + ** entry in the sqlite_schema table that was created for this vtab ** by sqlite3StartTable(). */ iDb = sqlite3SchemaToIndex(db, pTab->pSchema); @@ -555,7 +555,7 @@ ** to this procedure. */ static int vtabCallConstructor( - sqlite3 *db, + sqlite3 *db, Table *pTab, Module *pMod, int (*xConstruct)(sqlite3*,void*,int,const char*const*,sqlite3_vtab**,char**), @@ -577,7 +577,7 @@ /* Check that the virtual-table is not already being initialized */ for(pCtx=db->pVtabCtx; pCtx; pCtx=pCtx->pPrior){ if( pCtx->pTab==pTab ){ - *pzErr = sqlite3MPrintf(db, + *pzErr = sqlite3MPrintf(db, "vtable constructor called recursively: %s", pTab->zName ); return SQLITE_LOCKED; @@ -641,7 +641,7 @@ int iCol; u16 oooHidden = 0; /* If everything went according to plan, link the new VTable structure - ** into the linked list headed by pTab->u.vtab.p. Then loop through the + ** into the linked list headed by pTab->u.vtab.p. Then loop through the ** columns of the table to see if any of them contain the token "hidden". ** If so, set the Column COLFLAG_HIDDEN flag and remove the token from ** the type string. */ @@ -687,7 +687,7 @@ /* ** This function is invoked by the parser to call the xConnect() method -** of the virtual table pTab. If an error occurs, an error code is returned +** of the virtual table pTab. If an error occurs, an error code is returned ** and an error left in pParse. ** ** This call is a no-op if table pTab is not a virtual table. @@ -759,7 +759,7 @@ /* ** This function is invoked by the vdbe to call the xCreate method -** of the virtual table named zTab in database iDb. +** of the virtual table named zTab in database iDb. ** ** If an error occurs, *pzErr is set to point to an English language ** description of the error and an SQLITE_XXX error code is returned. @@ -778,8 +778,8 @@ zMod = pTab->u.vtab.azArg[0]; pMod = (Module*)sqlite3HashFind(&db->aModule, zMod); - /* If the module has been registered and includes a Create method, - ** invoke it now. If the module has not been registered, return an + /* If the module has been registered and includes a Create method, + ** invoke it now. If the module has not been registered, return an ** error. Otherwise, do nothing. */ if( pMod==0 || pMod->pModule->xCreate==0 || pMod->pModule->xDestroy==0 ){ @@ -821,7 +821,7 @@ sqlite3_mutex_enter(db->mutex); pCtx = db->pVtabCtx; if( !pCtx || pCtx->bDeclared ){ - sqlite3Error(db, SQLITE_MISUSE); + sqlite3Error(db, SQLITE_MISUSE_BKPT); sqlite3_mutex_leave(db->mutex); return SQLITE_MISUSE_BKPT; } @@ -838,7 +838,7 @@ initBusy = db->init.busy; db->init.busy = 0; sParse.nQueryLoop = 1; - if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) + if( SQLITE_OK==sqlite3RunParser(&sParse, zCreateTable) && ALWAYS(sParse.pNewTable!=0) && ALWAYS(!db->mallocFailed) && IsOrdinaryTable(sParse.pNewTable) @@ -942,7 +942,7 @@ ** called is identified by the second argument, "offset", which is ** the offset of the method to call in the sqlite3_module structure. ** -** The array is cleared after invoking the callbacks. +** The array is cleared after invoking the callbacks. */ static void callFinaliser(sqlite3 *db, int offset){ int i; @@ -991,7 +991,7 @@ } /* -** Invoke the xRollback method of all virtual tables in the +** Invoke the xRollback method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself. */ int sqlite3VtabRollback(sqlite3 *db){ @@ -1000,7 +1000,7 @@ } /* -** Invoke the xCommit method of all virtual tables in the +** Invoke the xCommit method of all virtual tables in the ** sqlite3.aVTrans array. Then clear the array itself. */ int sqlite3VtabCommit(sqlite3 *db){ @@ -1022,7 +1022,7 @@ /* Special case: If db->aVTrans is NULL and db->nVTrans is greater ** than zero, then this function is being called from within a - ** virtual module xSync() callback. It is illegal to write to + ** virtual module xSync() callback. It is illegal to write to ** virtual module tables in this case, so return SQLITE_LOCKED. */ if( sqlite3VtabInSync(db) ){ @@ -1030,7 +1030,7 @@ } if( !pVTab ){ return SQLITE_OK; - } + } pModule = pVTab->pVtab->pModule; if( pModule->xBegin ){ @@ -1043,7 +1043,7 @@ } } - /* Invoke the xBegin method. If successful, add the vtab to the + /* Invoke the xBegin method. If successful, add the vtab to the ** sqlite3.aVTrans[] array. */ rc = growVTrans(db); if( rc==SQLITE_OK ){ @@ -1067,11 +1067,11 @@ ** as the second argument to the virtual table method invoked. ** ** If op is SAVEPOINT_BEGIN, the xSavepoint method is invoked. If it is -** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is +** SAVEPOINT_ROLLBACK, the xRollbackTo method. Otherwise, if op is ** SAVEPOINT_RELEASE, then the xRelease method of each virtual table with ** an open transaction is invoked. ** -** If any virtual table method returns an error code other than SQLITE_OK, +** If any virtual table method returns an error code other than SQLITE_OK, ** processing is abandoned and the error returned to the caller of this ** function immediately. If all calls to virtual table methods are successful, ** SQLITE_OK is returned. @@ -1123,7 +1123,7 @@ ** This routine is used to allow virtual table implementations to ** overload MATCH, LIKE, GLOB, and REGEXP operators. ** -** Return either the pDef argument (indicating no change) or a +** Return either the pDef argument (indicating no change) or a ** new FuncDef structure that is marked as ephemeral using the ** SQLITE_FUNC_EPHEM flag. */ @@ -1153,7 +1153,7 @@ assert( pVtab->pModule!=0 ); pMod = (sqlite3_module *)pVtab->pModule; if( pMod->xFindFunction==0 ) return pDef; - + /* Call the xFindFunction method on the virtual table implementation ** to see if the implementation wants to overload this function. ** @@ -1219,13 +1219,13 @@ /* ** 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 either the eponymous virtual table instance +** exist. Return non-zero if either the eponymous virtual table instance ** exists when this routine returns or if an attempt to create it failed ** and an error message was left in pParse. ** ** 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 existance. Eponymous 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 @@ -1273,7 +1273,7 @@ Table *pTab = pMod->pEpoTab; if( pTab!=0 ){ /* Mark the table as Ephemeral prior to deleting it, so that the - ** sqlite3DeleteTable() routine will know that it is not stored in + ** sqlite3DeleteTable() routine will know that it is not stored in ** the schema. */ pTab->tabFlags |= TF_Ephemeral; sqlite3DeleteTable(db, pTab); @@ -1289,8 +1289,8 @@ ** within an xUpdate method. */ int sqlite3_vtab_on_conflict(sqlite3 *db){ - static const unsigned char aMap[] = { - SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE + static const unsigned char aMap[] = { + SQLITE_ROLLBACK, SQLITE_ABORT, SQLITE_FAIL, SQLITE_IGNORE, SQLITE_REPLACE }; #ifdef SQLITE_ENABLE_API_ARMOR if( !sqlite3SafetyCheckOk(db) ) return SQLITE_MISUSE_BKPT; @@ -1302,7 +1302,7 @@ } /* -** Call from within the xCreate() or xConnect() methods to provide +** Call from within the xCreate() or xConnect() methods to provide ** the SQLite core with additional information about the behavior ** of the virtual table being implemented. */ diff -Nru sqlite3-3.42.0/src/wal.c sqlite3-3.44.0-0/src/wal.c --- sqlite3-3.42.0/src/wal.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/wal.c 2023-11-04 14:23:58.000000000 +0000 @@ -10,7 +10,7 @@ ** ************************************************************************* ** -** This file contains the implementation of a write-ahead log (WAL) used in +** This file contains the implementation of a write-ahead log (WAL) used in ** "journal_mode=WAL" mode. ** ** WRITE-AHEAD LOG (WAL) FILE FORMAT @@ -19,7 +19,7 @@ ** Each frame records the revised content of a single page from the ** database file. All changes to the database are recorded by writing ** frames into the WAL. Transactions commit when a frame is written that -** contains a commit marker. A single WAL can and usually does record +** contains a commit marker. A single WAL can and usually does record ** multiple transactions. Periodically, the content of the WAL is ** transferred back into the database file in an operation called a ** "checkpoint". @@ -45,11 +45,11 @@ ** ** Immediately following the wal-header are zero or more frames. Each ** frame consists of a 24-byte frame-header followed by a bytes -** of page data. The frame-header is six big-endian 32-bit unsigned +** of page data. The frame-header is six big-endian 32-bit unsigned ** integer values, as follows: ** ** 0: Page number. -** 4: For commit records, the size of the database image in pages +** 4: For commit records, the size of the database image in pages ** after the commit. For all other records, zero. ** 8: Salt-1 (copied from the header) ** 12: Salt-2 (copied from the header) @@ -75,7 +75,7 @@ ** the checksum. The checksum is computed by interpreting the input as ** an even number of unsigned 32-bit integers: x[0] through x[N]. The ** algorithm used for the checksum is as follows: -** +** ** for i from 0 to n-1 step 2: ** s0 += x[i] + s1; ** s1 += x[i+1] + s0; @@ -83,7 +83,7 @@ ** ** Note that s0 and s1 are both weighted checksums using fibonacci weights ** in reverse order (the largest fibonacci weight occurs on the first element -** of the sequence being summed.) The s1 value spans all 32-bit +** of the sequence being summed.) The s1 value spans all 32-bit ** terms of the sequence whereas s0 omits the final term. ** ** On a checkpoint, the WAL is first VFS.xSync-ed, then valid content of the @@ -116,19 +116,19 @@ ** multiple concurrent readers to view different versions of the database ** content simultaneously. ** -** The reader algorithm in the previous paragraphs works correctly, but +** The reader algorithm in the previous paragraphs works correctly, but ** because frames for page P can appear anywhere within the WAL, the ** reader has to scan the entire WAL looking for page P frames. If the ** WAL is large (multiple megabytes is typical) that scan can be slow, ** and read performance suffers. To overcome this problem, a separate ** data structure called the wal-index is maintained to expedite the ** search for frames of a particular page. -** +** ** WAL-INDEX FORMAT ** ** Conceptually, the wal-index is shared memory, though VFS implementations ** might choose to implement the wal-index using a mmapped file. Because -** the wal-index is shared memory, SQLite does not support journal_mode=WAL +** the wal-index is shared memory, SQLite does not support journal_mode=WAL ** on a network filesystem. All users of the database must be able to ** share memory. ** @@ -146,19 +146,19 @@ ** byte order of the host computer. ** ** The purpose of the wal-index is to answer this question quickly: Given -** a page number P and a maximum frame index M, return the index of the +** a page number P and a maximum frame index M, return the index of the ** last frame in the wal before frame M for page P in the WAL, or return ** NULL if there are no frames for page P in the WAL prior to M. ** ** The wal-index consists of a header region, followed by an one or -** more index blocks. +** more index blocks. ** ** The wal-index header contains the total number of frames within the WAL ** in the mxFrame field. ** -** Each index block except for the first contains information on +** Each index block except for the first contains information on ** HASHTABLE_NPAGE frames. The first index block contains information on -** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and +** HASHTABLE_NPAGE_ONE frames. The values of HASHTABLE_NPAGE_ONE and ** HASHTABLE_NPAGE are selected so that together the wal-index header and ** first index block are the same size as all other index blocks in the ** wal-index. The values are: @@ -167,10 +167,10 @@ ** HASHTABLE_NPAGE_ONE 4062 ** ** Each index block contains two sections, a page-mapping that contains the -** database page number associated with each wal frame, and a hash-table +** database page number associated with each wal frame, and a hash-table ** that allows readers to query an index block for a specific page number. ** The page-mapping is an array of HASHTABLE_NPAGE (or HASHTABLE_NPAGE_ONE -** for the first index block) 32-bit page numbers. The first entry in the +** for the first index block) 32-bit page numbers. The first entry in the ** first index-block contains the database page number corresponding to the ** first frame in the WAL file. The first entry in the second index block ** in the WAL file corresponds to the (HASHTABLE_NPAGE_ONE+1)th frame in @@ -191,8 +191,8 @@ ** ** The hash table consists of HASHTABLE_NSLOT 16-bit unsigned integers. ** HASHTABLE_NSLOT = 2*HASHTABLE_NPAGE, and there is one entry in the -** hash table for each page number in the mapping section, so the hash -** table is never more than half full. The expected number of collisions +** hash table for each page number in the mapping section, so the hash +** table is never more than half full. The expected number of collisions ** prior to finding a match is 1. Each entry of the hash table is an ** 1-based index of an entry in the mapping section of the same ** index block. Let K be the 1-based index of the largest entry in @@ -211,12 +211,12 @@ ** reached) until an unused hash slot is found. Let the first unused slot ** be at index iUnused. (iUnused might be less than iKey if there was ** wrap-around.) Because the hash table is never more than half full, -** the search is guaranteed to eventually hit an unused entry. Let +** the search is guaranteed to eventually hit an unused entry. Let ** iMax be the value between iKey and iUnused, closest to iUnused, ** where aHash[iMax]==P. If there is no iMax entry (if there exists ** no hash slot such that aHash[i]==p) then page P is not in the ** current index block. Otherwise the iMax-th mapping entry of the -** current index block corresponds to the last entry that references +** current index block corresponds to the last entry that references ** page P. ** ** A hash search begins with the last index block and moves toward the @@ -241,7 +241,7 @@ ** if no values greater than K0 had ever been inserted into the hash table ** in the first place - which is what reader one wants. Meanwhile, the ** second reader using K1 will see additional values that were inserted -** later, which is exactly what reader two wants. +** later, which is exactly what reader two wants. ** ** When a rollback occurs, the value of K is decreased. Hash table entries ** that correspond to frames greater than the new K value are removed @@ -269,7 +269,7 @@ ** values in the wal-header are correct and (b) the version field is not ** WAL_MAX_VERSION, recovery fails and SQLite returns SQLITE_CANTOPEN. ** -** Similarly, if a client successfully reads a wal-index header (i.e. the +** Similarly, if a client successfully reads a wal-index header (i.e. the ** checksum test is successful) and finds that the version field is not ** WALINDEX_MAX_VERSION, then no read-transaction is opened and SQLite ** returns SQLITE_CANTOPEN. @@ -284,7 +284,7 @@ ** ** Technically, the various VFSes are free to implement these locks however ** they see fit. However, compatibility is encouraged so that VFSes can -** interoperate. The standard implemention used on both unix and windows +** 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 @@ -316,7 +316,7 @@ ** ** The szPage value can be any power of 2 between 512 and 32768, inclusive. ** Or it can be 1 to represent a 65536-byte page. The latter case was -** added in 3.7.1 when support for 64K pages was added. +** added in 3.7.1 when support for 64K pages was added. */ struct WalIndexHdr { u32 iVersion; /* Wal-index version */ @@ -358,9 +358,9 @@ ** There is one entry in aReadMark[] for each reader lock. If a reader ** holds read-lock K, then the value in aReadMark[K] is no greater than ** the mxFrame for that reader. The value READMARK_NOT_USED (0xffffffff) -** for any aReadMark[] means that entry is unused. aReadMark[0] is +** for any aReadMark[] means that entry is unused. aReadMark[0] is ** a special case; its value is never used and it exists as a place-holder -** to avoid having to offset aReadMark[] indexs by one. Readers holding +** to avoid having to offset aReadMark[] indexes by one. Readers holding ** WAL_READ_LOCK(0) always ignore the entire WAL and read all content ** directly from the database. ** @@ -378,7 +378,7 @@ ** previous sentence is when nBackfill equals mxFrame (meaning that everything ** in the WAL has been backfilled into the database) then new readers ** will choose aReadMark[0] which has value 0 and hence such reader will -** get all their all content directly from the database file and ignore +** get all their all content directly from the database file and ignore ** the WAL. ** ** Writers normally append new frames to the end of the WAL. However, @@ -484,14 +484,14 @@ ** big-endian format in the first 4 bytes of a WAL file. ** ** If the LSB is set, then the checksums for each frame within the WAL -** file are calculated by treating all data as an array of 32-bit -** big-endian words. Otherwise, they are calculated by interpreting +** file are calculated by treating all data as an array of 32-bit +** big-endian words. Otherwise, they are calculated by interpreting ** all data as 32-bit little-endian words. */ #define WAL_MAGIC 0x377f0682 /* -** Return the offset of frame iFrame in the write-ahead log file, +** Return the offset of frame iFrame in the write-ahead log file, ** assuming a database page size of szPage bytes. The offset returned ** is to the start of the write-ahead log frame-header. */ @@ -528,7 +528,15 @@ u32 iReCksum; /* On commit, recalculate checksums from here */ const char *zWalName; /* Name of WAL file */ u32 nCkpt; /* Checkpoint sequence counter in the wal-header */ +#ifdef SQLITE_USE_SEH + u32 lockMask; /* Mask of locks held */ + void *pFree; /* Pointer to sqlite3_free() if exception thrown */ + u32 *pWiValue; /* Value to write into apWiData[iWiPg] */ + int iWiPg; /* Write pWiValue into apWiData[iWiPg] */ + int iSysErrno; /* System error code following exception */ +#endif #ifdef SQLITE_DEBUG + int nSehTry; /* Number of nested SEH_TRY{} blocks */ u8 lockError; /* True if a locking error has occurred */ #endif #ifdef SQLITE_ENABLE_SNAPSHOT @@ -543,7 +551,7 @@ ** Candidate values for Wal.exclusiveMode. */ #define WAL_NORMAL_MODE 0 -#define WAL_EXCLUSIVE_MODE 1 +#define WAL_EXCLUSIVE_MODE 1 #define WAL_HEAPMEMORY_MODE 2 /* @@ -562,7 +570,7 @@ /* ** This structure is used to implement an iterator that loops through ** all frames in the WAL in database page order. Where two or more frames -** correspond to the same database page, the iterator visits only the +** correspond to the same database page, the iterator visits only the ** frame most recently written to the WAL (in other words, the frame with ** the largest index). ** @@ -598,7 +606,7 @@ #define HASHTABLE_HASH_1 383 /* Should be prime */ #define HASHTABLE_NSLOT (HASHTABLE_NPAGE*2) /* Must be a power of 2 */ -/* +/* ** The block of page numbers associated with the first hash-table in a ** wal-index is smaller than usual. This is so that there is a complete ** hash-table on each aligned 32KB page of the wal-index. @@ -611,6 +619,113 @@ ) /* +** Structured Exception Handling (SEH) is a Windows-specific technique +** for catching exceptions raised while accessing memory-mapped files. +** +** The -DSQLITE_USE_SEH compile-time option means to use SEH to catch and +** deal with system-level errors that arise during WAL -shm file processing. +** Without this compile-time option, any system-level faults that appear +** while accessing the memory-mapped -shm file will cause a process-wide +** signal to be deliver, which will more than likely cause the entire +** process to exit. +*/ +#ifdef SQLITE_USE_SEH +#include + +/* Beginning of a block of code in which an exception might occur */ +# define SEH_TRY __try { \ + assert( walAssertLockmask(pWal) && pWal->nSehTry==0 ); \ + VVA_ONLY(pWal->nSehTry++); + +/* The end of a block of code in which an exception might occur */ +# define SEH_EXCEPT(X) \ + VVA_ONLY(pWal->nSehTry--); \ + assert( pWal->nSehTry==0 ); \ + } __except( sehExceptionFilter(pWal, GetExceptionCode(), GetExceptionInformation() ) ){ X } + +/* Simulate a memory-mapping fault in the -shm file for testing purposes */ +# define SEH_INJECT_FAULT sehInjectFault(pWal) + +/* +** The second argument is the return value of GetExceptionCode() for the +** current exception. Return EXCEPTION_EXECUTE_HANDLER if the exception code +** indicates that the exception may have been caused by accessing the *-shm +** file mapping. Or EXCEPTION_CONTINUE_SEARCH otherwise. +*/ +static int sehExceptionFilter(Wal *pWal, int eCode, EXCEPTION_POINTERS *p){ + VVA_ONLY(pWal->nSehTry--); + if( eCode==EXCEPTION_IN_PAGE_ERROR ){ + if( p && p->ExceptionRecord && p->ExceptionRecord->NumberParameters>=3 ){ + /* From MSDN: For this type of exception, the first element of the + ** ExceptionInformation[] array is a read-write flag - 0 if the exception + ** was thrown while reading, 1 if while writing. The second element is + ** the virtual address being accessed. The "third array element specifies + ** the underlying NTSTATUS code that resulted in the exception". */ + pWal->iSysErrno = (int)p->ExceptionRecord->ExceptionInformation[2]; + } + return EXCEPTION_EXECUTE_HANDLER; + } + return EXCEPTION_CONTINUE_SEARCH; +} + +/* +** If one is configured, invoke the xTestCallback callback with 650 as +** the argument. If it returns true, throw the same exception that is +** thrown by the system if the *-shm file mapping is accessed after it +** has been invalidated. +*/ +static void sehInjectFault(Wal *pWal){ + int res; + assert( pWal->nSehTry>0 ); + + res = sqlite3FaultSim(650); + if( res!=0 ){ + ULONG_PTR aArg[3]; + aArg[0] = 0; + aArg[1] = 0; + aArg[2] = (ULONG_PTR)res; + RaiseException(EXCEPTION_IN_PAGE_ERROR, 0, 3, (const ULONG_PTR*)aArg); + } +} + +/* +** There are two ways to use this macro. To set a pointer to be freed +** if an exception is thrown: +** +** SEH_FREE_ON_ERROR(0, pPtr); +** +** and to cancel the same: +** +** SEH_FREE_ON_ERROR(pPtr, 0); +** +** In the first case, there must not already be a pointer registered to +** be freed. In the second case, pPtr must be the registered pointer. +*/ +#define SEH_FREE_ON_ERROR(X,Y) \ + assert( (X==0 || Y==0) && pWal->pFree==X ); pWal->pFree = Y + +/* +** There are two ways to use this macro. To arrange for pWal->apWiData[iPg] +** to be set to pValue if an exception is thrown: +** +** SEH_SET_ON_ERROR(iPg, pValue); +** +** and to cancel the same: +** +** SEH_SET_ON_ERROR(0, 0); +*/ +#define SEH_SET_ON_ERROR(X,Y) pWal->iWiPg = X; pWal->pWiValue = Y + +#else +# define SEH_TRY VVA_ONLY(pWal->nSehTry++); +# define SEH_EXCEPT(X) VVA_ONLY(pWal->nSehTry--); assert( pWal->nSehTry==0 ); +# define SEH_INJECT_FAULT assert( pWal->nSehTry>0 ); +# define SEH_FREE_ON_ERROR(X,Y) +# define SEH_SET_ON_ERROR(X,Y) +#endif /* ifdef SQLITE_USE_SEH */ + + +/* ** Obtain a pointer to the iPage'th page of the wal-index. The wal-index ** is broken into pages of WALINDEX_PGSZ bytes. Wal-index pages are ** numbered from zero. @@ -624,7 +739,7 @@ ** ** (1) rc==SQLITE_OK and *ppPage==Requested-Wal-Index-Page ** (2) rc>=SQLITE_ERROR and *ppPage==NULL -** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0 +** (3) rc==SQLITE_OK and *ppPage==NULL // only if iPage==0 ** ** Scenario (3) can only occur when pWal->writeLock is false and iPage==0 */ @@ -656,7 +771,7 @@ pWal->apWiData[iPage] = (u32 volatile *)sqlite3MallocZero(WALINDEX_PGSZ); if( !pWal->apWiData[iPage] ) rc = SQLITE_NOMEM_BKPT; }else{ - rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, + rc = sqlite3OsShmMap(pWal->pDbFd, iPage, WALINDEX_PGSZ, pWal->writeLock, (void volatile **)&pWal->apWiData[iPage] ); assert( pWal->apWiData[iPage]!=0 @@ -682,6 +797,7 @@ int iPage, /* The page we seek */ volatile u32 **ppPage /* Write the page pointer here */ ){ + SEH_INJECT_FAULT; if( pWal->nWiData<=iPage || (*ppPage = pWal->apWiData[iPage])==0 ){ return walIndexPageRealloc(pWal, iPage, ppPage); } @@ -693,6 +809,7 @@ */ static volatile WalCkptInfo *walCkptInfo(Wal *pWal){ assert( pWal->nWiData>0 && pWal->apWiData[0] ); + SEH_INJECT_FAULT; return (volatile WalCkptInfo*)&(pWal->apWiData[0][sizeof(WalIndexHdr)/2]); } @@ -701,6 +818,7 @@ */ static volatile WalIndexHdr *walIndexHdr(Wal *pWal){ assert( pWal->nWiData>0 && pWal->apWiData[0] ); + SEH_INJECT_FAULT; return (volatile WalIndexHdr*)pWal->apWiData[0]; } @@ -717,7 +835,7 @@ ) /* -** Generate or extend an 8 byte checksum based on the data in +** Generate or extend an 8 byte checksum based on the data in ** array aByte[] and the initial values of aIn[0] and aIn[1] (or ** initial values of 0 and 0 if aIn==NULL). ** @@ -829,11 +947,11 @@ /* ** This function encodes a single frame header and writes it to a buffer -** supplied by the caller. A frame-header is made up of a series of +** supplied by the caller. A frame-header is made up of a series of ** 4-byte big-endian integers, as follows: ** ** 0: Page number. -** 4: For commit records, the size of the database image in pages +** 4: For commit records, the size of the database image in pages ** after the commit. For all other records, zero. ** 8: Salt-1 (copied from the wal-header) ** 12: Salt-2 (copied from the wal-header) @@ -884,13 +1002,13 @@ assert( WAL_FRAME_HDRSIZE==24 ); /* A frame is only valid if the salt values in the frame-header - ** match the salt values in the wal-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 creater than zero. + /* A frame is only valid if the page number is greater than zero. */ pgno = sqlite3Get4byte(&aFrame[0]); if( pgno==0 ){ @@ -898,15 +1016,15 @@ } /* A frame is only valid if a checksum of the WAL header, - ** all prior frams, the first 16 bytes of this frame-header, - ** and the frame-data matches the checksum in the last 8 + ** 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]) - || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) + if( aCksum[0]!=sqlite3Get4byte(&aFrame[16]) + || aCksum[1]!=sqlite3Get4byte(&aFrame[20]) ){ /* Checksum failed. */ return 0; @@ -941,7 +1059,7 @@ } } #endif /*defined(SQLITE_TEST) || defined(SQLITE_DEBUG) */ - + /* ** Set or release locks on the WAL. Locks are either shared or exclusive. @@ -958,12 +1076,18 @@ WALTRACE(("WAL%p: acquire SHARED-%s %s\n", pWal, walLockName(lockIdx), rc ? "failed" : "ok")); VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_OK ) pWal->lockMask |= (1 << lockIdx); +#endif return rc; } static void walUnlockShared(Wal *pWal, int lockIdx){ if( pWal->exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, 1, SQLITE_SHM_UNLOCK | SQLITE_SHM_SHARED); +#ifdef SQLITE_USE_SEH + pWal->lockMask &= ~(1 << lockIdx); +#endif WALTRACE(("WAL%p: release SHARED-%s\n", pWal, walLockName(lockIdx))); } static int walLockExclusive(Wal *pWal, int lockIdx, int n){ @@ -974,12 +1098,20 @@ WALTRACE(("WAL%p: acquire EXCLUSIVE-%s cnt=%d %s\n", pWal, walLockName(lockIdx), n, rc ? "failed" : "ok")); VVA_ONLY( pWal->lockError = (u8)(rc!=SQLITE_OK && (rc&0xFF)!=SQLITE_BUSY); ) +#ifdef SQLITE_USE_SEH + if( rc==SQLITE_OK ){ + pWal->lockMask |= (((1<exclusiveMode ) return; (void)sqlite3OsShmLock(pWal->pDbFd, lockIdx, n, SQLITE_SHM_UNLOCK | SQLITE_SHM_EXCLUSIVE); +#ifdef SQLITE_USE_SEH + pWal->lockMask &= ~(((1<aHash to point to the start of the hash table -** in the wal-index file. Set pLoc->iZero to one less than the frame +** in the wal-index file. Set pLoc->iZero to one less than the frame ** number of the first frame indexed by this hash table. If a -** slot in the hash table is set to N, it refers to frame number +** slot in the hash table is set to N, it refers to frame number ** (pLoc->iZero+N) in the log. ** ** Finally, set pLoc->aPgno so that pLoc->aPgno[0] is the page number of the @@ -1051,7 +1183,7 @@ /* ** Return the number of the wal-index page that contains the hash-table ** and page-number array that contain entries corresponding to WAL frame -** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages +** iFrame. The wal-index is broken up into 32KB pages. Wal-index pages ** are numbered starting from 0. */ static int walFramePage(u32 iFrame){ @@ -1071,6 +1203,7 @@ */ static u32 walFramePgno(Wal *pWal, u32 iFrame){ int iHash = walFramePage(iFrame); + SEH_INJECT_FAULT; if( iHash==0 ){ return pWal->apWiData[0][WALINDEX_HDR_SIZE/sizeof(u32) + iFrame - 1]; } @@ -1102,7 +1235,7 @@ if( pWal->hdr.mxFrame==0 ) return; - /* Obtain pointers to the hash-table and page-number array containing + /* Obtain pointers to the hash-table and page-number array containing ** the entry that corresponds to frame pWal->hdr.mxFrame. It is guaranteed ** that the page said hash-table and array reside on is already mapped.(1) */ @@ -1121,9 +1254,9 @@ sLoc.aHash[i] = 0; } } - + /* Zero the entries in the aPgno array that correspond to frames with - ** frame numbers greater than pWal->hdr.mxFrame. + ** frame numbers greater than pWal->hdr.mxFrame. */ nByte = (int)((char *)sLoc.aHash - (char *)&sLoc.aPgno[iLimit]); assert( nByte>=0 ); @@ -1167,9 +1300,9 @@ idx = iFrame - sLoc.iZero; assert( idx <= HASHTABLE_NSLOT/2 + 1 ); - + /* If this is the first entry to be added to this hash-table, zero the - ** entire hash table and aPgno[] array before proceeding. + ** entire hash table and aPgno[] array before proceeding. */ if( idx==1 ){ int nByte = (int)((u8*)&sLoc.aHash[HASHTABLE_NSLOT] - (u8*)sLoc.aPgno); @@ -1179,8 +1312,8 @@ /* If the entry in aPgno[] is already set, then the previous writer ** must have exited unexpectedly in the middle of a transaction (after - ** writing one or more dirty pages to the WAL to free up memory). - ** Remove the remnants of that writers uncommitted transaction from + ** writing one or more dirty pages to the WAL to free up memory). + ** Remove the remnants of that writers uncommitted transaction from ** the hash-table before writing any new entries. */ if( sLoc.aPgno[idx-1] ){ @@ -1231,7 +1364,7 @@ /* -** Recover the wal-index by reading the write-ahead log file. +** Recover the wal-index by reading the write-ahead log file. ** ** This routine first tries to establish an exclusive lock on the ** wal-index to prevent other threads/processes from doing anything @@ -1291,16 +1424,16 @@ } /* If the database page size is not a power of two, or is greater than - ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid + ** SQLITE_MAX_PAGE_SIZE, conclude that the WAL file contains no valid ** data. Similarly, if the 'magic' value is invalid, ignore the whole ** WAL file. */ magic = sqlite3Get4byte(&aBuf[0]); szPage = sqlite3Get4byte(&aBuf[8]); - if( (magic&0xFFFFFFFE)!=WAL_MAGIC - || szPage&(szPage-1) - || szPage>SQLITE_MAX_PAGE_SIZE - || szPage<512 + if( (magic&0xFFFFFFFE)!=WAL_MAGIC + || szPage&(szPage-1) + || szPage>SQLITE_MAX_PAGE_SIZE + || szPage<512 ){ goto finished; } @@ -1310,7 +1443,7 @@ memcpy(&pWal->hdr.aSalt, &aBuf[16], 8); /* Verify that the WAL header checksum is correct */ - walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, + walChecksumBytes(pWal->hdr.bigEndCksum==SQLITE_BIGENDIAN, aBuf, WAL_HDRSIZE-2*4, 0, pWal->hdr.aFrameCksum ); if( pWal->hdr.aFrameCksum[0]!=sqlite3Get4byte(&aBuf[24]) @@ -1330,6 +1463,7 @@ /* Malloc a buffer to read frames into. */ szFrame = szPage + WAL_FRAME_HDRSIZE; aFrame = (u8 *)sqlite3_malloc64(szFrame + WALINDEX_PGSZ); + SEH_FREE_ON_ERROR(0, aFrame); if( !aFrame ){ rc = SQLITE_NOMEM_BKPT; goto recovery_error; @@ -1348,8 +1482,9 @@ rc = walIndexPage(pWal, iPg, (volatile u32**)&aShare); assert( aShare!=0 || rc!=SQLITE_OK ); if( aShare==0 ) break; + SEH_SET_ON_ERROR(iPg, aShare); pWal->apWiData[iPg] = aPrivate; - + for(iFrame=iFirst; iFrame<=iLast; iFrame++){ i64 iOffset = walFrameOffset(iFrame, szPage); u32 pgno; /* Database page number for frame */ @@ -1375,6 +1510,7 @@ } } pWal->apWiData[iPg] = aShare; + SEH_SET_ON_ERROR(0,0); nHdr = (iPg==0 ? WALINDEX_HDR_SIZE : 0); nHdr32 = nHdr / sizeof(u32); #ifndef SQLITE_SAFER_WALINDEX_RECOVERY @@ -1405,9 +1541,11 @@ } } #endif + SEH_INJECT_FAULT; if( iFrame<=iLast ) break; } + SEH_FREE_ON_ERROR(aFrame, 0); sqlite3_free(aFrame); } @@ -1419,8 +1557,8 @@ pWal->hdr.aFrameCksum[1] = aFrameCksum[1]; walIndexWriteHdr(pWal); - /* Reset the checkpoint-header. This is safe because this thread is - ** currently holding locks that exclude all other writers and + /* Reset the checkpoint-header. This is safe because this thread is + ** currently holding locks that exclude all other writers and ** checkpointers. Then set the values of read-mark slots 1 through N. */ pInfo = walCkptInfo(pWal); @@ -1435,6 +1573,7 @@ }else{ pInfo->aReadMark[i] = READMARK_NOT_USED; } + SEH_INJECT_FAULT; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc!=SQLITE_BUSY ){ goto recovery_error; @@ -1476,8 +1615,8 @@ } } -/* -** Open a connection to the WAL file zWalName. The database file must +/* +** Open a connection to the WAL file zWalName. The database file must ** already be opened on connection pDbFd. The buffer that zWalName points ** to must remain valid for the lifetime of the returned Wal* handle. ** @@ -1487,7 +1626,7 @@ ** were to do this just after this client opened one of these files, the ** system would be badly broken. ** -** If the log file is successfully opened, SQLITE_OK is returned and +** If the log file is successfully opened, SQLITE_OK is returned and ** *ppWal is set to point to a new WAL handle. If an error occurs, ** an SQLite error code is returned and *ppWal is left unmodified. */ @@ -1592,7 +1731,7 @@ } /* -** Change the size to which the WAL file is trucated on each reset. +** Change the size to which the WAL file is truncated on each reset. */ void sqlite3WalLimit(Wal *pWal, i64 iLimit){ if( pWal ) pWal->mxWalSize = iLimit; @@ -1680,7 +1819,7 @@ ht_slot logpage; Pgno dbpage; - if( (iLeft=nRight || aContent[aLeft[iLeft]]HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) + ); if( !p ){ return SQLITE_NOMEM_BKPT; } memset(p, 0, nByte); p->nSegment = nSegment; - - /* Allocate temporary space used by the merge-sort routine. This block - ** of memory will be freed before this function returns. - */ - aTmp = (ht_slot *)sqlite3_malloc64( - sizeof(ht_slot) * (iLast>HASHTABLE_NPAGE?HASHTABLE_NPAGE:iLast) - ); - if( !aTmp ){ - rc = SQLITE_NOMEM_BKPT; - } - + aTmp = (ht_slot*)&(((u8*)p)[nByte]); + SEH_FREE_ON_ERROR(0, p); for(i=walFramePage(nBackfill+1); rc==SQLITE_OK && iaSegment[p->nSegment])[sLoc.iZero]; sLoc.iZero++; - + for(j=0; jaSegment[i].aPgno = (u32 *)sLoc.aPgno; } } - sqlite3_free(aTmp); - if( rc!=SQLITE_OK ){ + SEH_FREE_ON_ERROR(p, 0); walIteratorFree(p); p = 0; } @@ -1875,8 +2006,8 @@ #ifdef SQLITE_ENABLE_SETLK_TIMEOUT /* ** Attempt to enable blocking locks. Blocking locks are enabled only if (a) -** they are supported by the VFS, and (b) the database handle is configured -** with a busy-timeout. Return 1 if blocking locks are successfully enabled, +** they are supported by the VFS, and (b) the database handle is configured +** with a busy-timeout. Return 1 if blocking locks are successfully enabled, ** or 0 otherwise. */ static int walEnableBlocking(Wal *pWal){ @@ -1905,7 +2036,7 @@ /* ** If parameter bLock is true, attempt to enable blocking locks, take ** the WRITER lock, and then disable blocking locks. If blocking locks -** cannot be enabled, no attempt to obtain the WRITER lock is made. Return +** cannot be enabled, no attempt to obtain the WRITER lock is made. Return ** an SQLite error code if an error occurs, or SQLITE_OK otherwise. It is not ** an error if blocking locks can not be enabled. ** @@ -2002,8 +2133,8 @@ ** client to write to the database (which may be this one) does so by ** writing frames into the start of the log file. ** -** The value of parameter salt1 is used as the aSalt[1] value in the -** new wal-index header. It should be passed a pseudo-random value (i.e. +** The value of parameter salt1 is used as the aSalt[1] value in the +** new wal-index header. It should be passed a pseudo-random value (i.e. ** one obtained from sqlite3_randomness()). */ static void walRestartHdr(Wal *pWal, u32 salt1){ @@ -2031,8 +2162,8 @@ ** that a concurrent reader might be using. ** ** All I/O barrier operations (a.k.a fsyncs) occur in this routine when -** SQLite is in WAL-mode in synchronous=NORMAL. That means that if -** checkpoints are always run by a background thread or background +** SQLite is in WAL-mode in synchronous=NORMAL. That means that if +** checkpoints are always run by a background thread or background ** process, foreground threads will never block on a lengthy fsync call. ** ** Fsync is called on the WAL before writing content out of the WAL and @@ -2045,7 +2176,7 @@ ** database file. ** ** This routine uses and updates the nBackfill field of the wal-index header. -** This is the only routine that will increase the value of nBackfill. +** This is the only routine that will increase the value of nBackfill. ** (A WAL reset or recovery will revert nBackfill to zero, but not increase ** its value.) ** @@ -2090,13 +2221,13 @@ mxSafeFrame = pWal->hdr.mxFrame; mxPage = pWal->hdr.nPage; for(i=1; iaReadMark+i); + u32 y = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; if( mxSafeFrame>y ){ assert( y<=pWal->hdr.mxFrame ); rc = walBusyLock(pWal, xBusy, pBusyArg, WAL_READ_LOCK(i), 1); if( rc==SQLITE_OK ){ u32 iMark = (i==1 ? mxSafeFrame : READMARK_NOT_USED); - AtomicStore(pInfo->aReadMark+i, iMark); + AtomicStore(pInfo->aReadMark+i, iMark); SEH_INJECT_FAULT; walUnlockExclusive(pWal, WAL_READ_LOCK(i), 1); }else if( rc==SQLITE_BUSY ){ mxSafeFrame = y; @@ -2117,8 +2248,7 @@ && (rc = walBusyLock(pWal,xBusy,pBusyArg,WAL_READ_LOCK(0),1))==SQLITE_OK ){ u32 nBackfill = pInfo->nBackfill; - - pInfo->nBackfillAttempted = mxSafeFrame; + pInfo->nBackfillAttempted = mxSafeFrame; SEH_INJECT_FAULT; /* Sync the WAL to disk */ rc = sqlite3OsSync(pWal->pWalFd, CKPT_SYNC_FLAGS(sync_flags)); @@ -2135,7 +2265,7 @@ if( (nSize+65536+(i64)pWal->hdr.mxFrame*szPage)u1.isInterrupted) ){ rc = db->mallocFailed ? SQLITE_NOMEM_BKPT : SQLITE_INTERRUPT; break; @@ -2178,7 +2309,7 @@ } } if( rc==SQLITE_OK ){ - AtomicStore(&pInfo->nBackfill, mxSafeFrame); + AtomicStore(&pInfo->nBackfill, mxSafeFrame); SEH_INJECT_FAULT; } } @@ -2194,12 +2325,13 @@ } /* If this is an SQLITE_CHECKPOINT_RESTART or TRUNCATE operation, and the - ** entire wal file has been copied into the database file, then block - ** until all readers have finished using the wal file. This ensures that + ** entire wal file has been copied into the database file, then block + ** until all readers have finished using the wal file. This ensures that ** the next process to write to the database restarts the wal file. */ if( rc==SQLITE_OK && eMode!=SQLITE_CHECKPOINT_PASSIVE ){ assert( pWal->writeLock ); + SEH_INJECT_FAULT; if( pInfo->nBackfillhdr.mxFrame ){ rc = SQLITE_BUSY; }else if( eMode>=SQLITE_CHECKPOINT_RESTART ){ @@ -2219,7 +2351,7 @@ ** writer clients should see that the entire log file has been ** checkpointed and behave accordingly. This seems unsafe though, ** as it would leave the system in a state where the contents of - ** the wal-index header do not match the contents of the + ** the wal-index header do not match the contents of the ** file-system. To avoid this, update the wal-index header to ** indicate that the log file contains zero valid frames. */ walRestartHdr(pWal, salt1); @@ -2231,6 +2363,7 @@ } walcheckpoint_out: + SEH_FREE_ON_ERROR(pIter, 0); walIteratorFree(pIter); return rc; } @@ -2253,6 +2386,93 @@ } } +#ifdef SQLITE_USE_SEH +/* +** This is the "standard" exception handler used in a few places to handle +** an exception thrown by reading from the *-shm mapping after it has become +** invalid in SQLITE_USE_SEH builds. It is used as follows: +** +** SEH_TRY { ... } +** SEH_EXCEPT( rc = walHandleException(pWal); ) +** +** This function does three things: +** +** 1) Determines the locks that should be held, based on the contents of +** the Wal.readLock, Wal.writeLock and Wal.ckptLock variables. All other +** held locks are assumed to be transient locks that would have been +** released had the exception not been thrown and are dropped. +** +** 2) Frees the pointer at Wal.pFree, if any, using sqlite3_free(). +** +** 3) Set pWal->apWiData[pWal->iWiPg] to pWal->pWiValue if not NULL +** +** 4) Returns SQLITE_IOERR. +*/ +static int walHandleException(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<lockMask & ~( + (pWal->readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) + ); + for(ii=0; iipFree); + pWal->pFree = 0; + if( pWal->pWiValue ){ + pWal->apWiData[pWal->iWiPg] = pWal->pWiValue; + pWal->pWiValue = 0; + } + return SQLITE_IOERR_IN_PAGE; +} + +/* +** Assert that the Wal.lockMask mask, which indicates the locks held +** by the connenction, is consistent with the Wal.readLock, Wal.writeLock +** and Wal.ckptLock variables. To be used as: +** +** assert( walAssertLockmask(pWal) ); +*/ +static int walAssertLockmask(Wal *pWal){ + if( pWal->exclusiveMode==0 ){ + static const int S = 1; + static const int E = (1<readLock<0 ? 0 : (S << WAL_READ_LOCK(pWal->readLock))) + | (pWal->writeLock ? (E << WAL_WRITE_LOCK) : 0) + | (pWal->ckptLock ? (E << WAL_CKPT_LOCK) : 0) +#ifdef SQLITE_ENABLE_SNAPSHOT + | (pWal->pSnapshot ? (pWal->lockMask & (1 << WAL_CKPT_LOCK)) : 0) +#endif + ); + assert( mExpect==pWal->lockMask ); + } + return 1; +} + +/* +** Return and zero the "system error" field set when an +** EXCEPTION_IN_PAGE_ERROR exception is caught. +*/ +int sqlite3WalSystemErrno(Wal *pWal){ + int iRet = 0; + if( pWal ){ + iRet = pWal->iSysErrno; + pWal->iSysErrno = 0; + } + return iRet; +} + +#else +# define walAssertLockmask(x) 1 +#endif /* ifdef SQLITE_USE_SEH */ + /* ** Close a connection to a log file. */ @@ -2267,6 +2487,8 @@ if( pWal ){ int isDelete = 0; /* True to unlink wal and wal-index files */ + assert( walAssertLockmask(pWal) ); + /* If an EXCLUSIVE lock can be obtained on the database file (using the ** ordinary, rollback-mode locking methods, this guarantees that the ** connection associated with this log file is the only connection to @@ -2281,7 +2503,7 @@ if( pWal->exclusiveMode==WAL_NORMAL_MODE ){ pWal->exclusiveMode = WAL_EXCLUSIVE_MODE; } - rc = sqlite3WalCheckpoint(pWal, db, + rc = sqlite3WalCheckpoint(pWal, db, SQLITE_CHECKPOINT_PASSIVE, 0, 0, sync_flags, nBuf, zBuf, 0, 0 ); if( rc==SQLITE_OK ){ @@ -2291,7 +2513,7 @@ ); if( bPersist!=1 ){ /* Try to delete the WAL file if the checkpoint completed and - ** fsyned (rc==SQLITE_OK) and if we are not in persistent-wal + ** fsynced (rc==SQLITE_OK) and if we are not in persistent-wal ** mode (!bPersist) */ isDelete = 1; }else if( pWal->mxWalSize>=0 ){ @@ -2358,7 +2580,7 @@ ** give false-positive warnings about these accesses because the tools do not ** account for the double-read and the memory barrier. The use of mutexes ** here would be problematic as the memory being accessed is potentially - ** shared among multiple processes and not all mutex implementions work + ** shared among multiple processes and not all mutex implementations work ** reliably in that environment. */ aHdr = walIndexHdr(pWal); @@ -2368,7 +2590,7 @@ if( memcmp(&h1, &h2, sizeof(h1))!=0 ){ return 1; /* Dirty read */ - } + } if( h1.isInit==0 ){ return 1; /* Malformed header - probably all zeros */ } @@ -2404,7 +2626,7 @@ ** changed by this operation. If pWal->hdr is unchanged, set *pChanged ** to 0. ** -** If the wal-index header is successfully read, return SQLITE_OK. +** If the wal-index header is successfully read, return SQLITE_OK. ** Otherwise an SQLite error code. */ static int walIndexReadHdr(Wal *pWal, int *pChanged){ @@ -2412,7 +2634,7 @@ int badHdr; /* True if a header read failed */ volatile u32 *page0; /* Chunk of wal-index containing header */ - /* Ensure that page 0 of the wal-index (the page that contains the + /* Ensure that page 0 of the wal-index (the page that contains the ** wal-index header) is mapped. Return early if an error occurs here. */ assert( pChanged ); @@ -2444,7 +2666,7 @@ /* If the first page of the wal-index has been mapped, try to read the ** wal-index header immediately, without holding any lock. This usually - ** works, but may fail if the wal-index header is corrupt or currently + ** works, but may fail if the wal-index header is corrupt or currently ** being modified by another thread or process. */ badHdr = (page0 ? walIndexTryHdr(pWal, pChanged) : 1); @@ -2519,15 +2741,15 @@ ** ** The *-wal file has been read and an appropriate wal-index has been ** constructed in pWal->apWiData[] using heap memory instead of shared -** memory. +** memory. ** ** If this function returns SQLITE_OK, then the read transaction has -** been successfully opened. In this case output variable (*pChanged) +** been successfully opened. In this case output variable (*pChanged) ** is set to true before returning if the caller should discard the -** contents of the page cache before proceeding. Or, if it returns -** WAL_RETRY, then the heap memory wal-index has been discarded and -** the caller should retry opening the read transaction from the -** beginning (including attempting to map the *-shm file). +** contents of the page cache before proceeding. Or, if it returns +** WAL_RETRY, then the heap memory wal-index has been discarded and +** the caller should retry opening the read transaction from the +** beginning (including attempting to map the *-shm file). ** ** If an error occurs, an SQLite error code is returned. */ @@ -2640,8 +2862,8 @@ ** the caller. */ aSaveCksum[0] = pWal->hdr.aFrameCksum[0]; aSaveCksum[1] = pWal->hdr.aFrameCksum[1]; - for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage); - iOffset+szFrame<=szWal; + for(iOffset=walFrameOffset(pWal->hdr.mxFrame+1, pWal->szPage); + iOffset+szFrame<=szWal; iOffset+=szFrame ){ u32 pgno; /* Database page number for frame */ @@ -2689,10 +2911,10 @@ ** ** The useWal parameter is true to force the use of the WAL and disable ** the case where the WAL is bypassed because it has been completely -** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() -** to make a copy of the wal-index header into pWal->hdr. If the -** wal-index header has changed, *pChanged is set to 1 (as an indication -** to the caller that the local page cache is obsolete and needs to be +** checkpointed. If useWal==0 then this routine calls walIndexReadHdr() +** to make a copy of the wal-index header into pWal->hdr. If the +** wal-index header has changed, *pChanged is set to 1 (as an indication +** to the caller that the local page cache is obsolete and needs to be ** flushed.) When useWal==1, the wal-index header is assumed to already ** be loaded and the pChanged parameter is unused. ** @@ -2707,7 +2929,7 @@ ** bad luck when there is lots of contention for the wal-index, but that ** possibility is so small that it can be safely neglected, we believe. ** -** On success, this routine obtains a read lock on +** On success, this routine obtains a read lock on ** WAL_READ_LOCK(pWal->readLock). The pWal->readLock integer is ** in the range 0 <= pWal->readLock < WAL_NREADER. If pWal->readLock==(-1) ** that means the Wal does not hold any read lock. The reader must not @@ -2745,16 +2967,16 @@ ** ** Circumstances that cause a RETRY should only last for the briefest ** instances of time. No I/O or other system calls are done while the - ** locks are held, so the locks should not be held for very long. But + ** locks are held, so the locks should not be held for very long. But ** if we are unlucky, another process that is holding a lock might get - ** paged out or take a page-fault that is time-consuming to resolve, + ** paged out or take a page-fault that is time-consuming to resolve, ** during the few nanoseconds that it is holding the lock. In that case, ** it might take longer than normal for the lock to free. ** ** After 5 RETRYs, we begin calling sqlite3OsSleep(). The first few ** calls to sqlite3OsSleep() have a delay of 1 microsecond. Really this ** is more of a scheduler yield than an actual delay. But on the 10th - ** an subsequent retries, the delays start becoming longer and longer, + ** an subsequent retries, the delays start becoming longer and longer, ** so that on the 100th (and last) RETRY we delay for 323 milliseconds. ** The total delay time before giving up is less than 10 seconds. */ @@ -2785,9 +3007,9 @@ if( pWal->apWiData[0]==0 ){ /* This branch is taken when the xShmMap() method returns SQLITE_BUSY. ** We assume this is a transient condition, so return WAL_RETRY. The - ** xShmMap() implementation used by the default unix and win32 VFS - ** modules may return SQLITE_BUSY due to a race condition in the - ** code that determines whether or not the shared-memory region + ** xShmMap() implementation used by the default unix and win32 VFS + ** modules may return SQLITE_BUSY due to a race condition in the + ** code that determines whether or not the shared-memory region ** must be zeroed before the requested page is returned. */ rc = WAL_RETRY; @@ -2809,6 +3031,7 @@ assert( pWal->nWiData>0 ); assert( pWal->apWiData[0]!=0 ); pInfo = walCkptInfo(pWal); + SEH_INJECT_FAULT; if( !useWal && AtomicLoad(&pInfo->nBackfill)==pWal->hdr.mxFrame #ifdef SQLITE_ENABLE_SNAPSHOT && (pWal->pSnapshot==0 || pWal->hdr.mxFrame==0) @@ -2828,7 +3051,7 @@ ** snapshot. Since holding READ_LOCK(0) prevents a checkpoint from ** happening, this is usually correct. ** - ** However, if frames have been appended to the log (or if the log + ** However, if frames have been appended to the log (or if the log ** is wrapped and written for that matter) before the READ_LOCK(0) ** is obtained, that is not necessarily true. A checkpointer may ** have started to backfill the appended frames but crashed before @@ -2858,7 +3081,7 @@ } #endif for(i=1; iaReadMark+i); + u32 thisMark = AtomicLoad(pInfo->aReadMark+i); SEH_INJECT_FAULT; if( mxReadMark<=thisMark && thisMark<=mxFrame ){ assert( thisMark!=READMARK_NOT_USED ); mxReadMark = thisMark; @@ -2910,9 +3133,9 @@ ** to read any frames earlier than minFrame from the wal file - they ** can be safely read directly from the database file. ** - ** Because a ShmBarrier() call is made between taking the copy of + ** Because a ShmBarrier() call is made between taking the copy of ** nBackfill and checking that the wal-header in shared-memory still - ** matches the one cached in pWal->hdr, it is guaranteed that the + ** matches the one cached in pWal->hdr, it is guaranteed that the ** checkpointer that set nBackfill was not working with a wal-index ** header newer than that cached in pWal->hdr. If it were, that could ** cause a problem. The checkpointer could omit to checkpoint @@ -2924,7 +3147,7 @@ ** we can guarantee that the checkpointer that set nBackfill could not ** see any pages past pWal->hdr.mxFrame, this problem does not come up. */ - pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; + pWal->minFrame = AtomicLoad(&pInfo->nBackfill)+1; SEH_INJECT_FAULT; walShmBarrier(pWal); if( AtomicLoad(pInfo->aReadMark+mxI)!=mxReadMark || memcmp((void *)walIndexHdr(pWal), &pWal->hdr, sizeof(WalIndexHdr)) @@ -2940,15 +3163,63 @@ #ifdef SQLITE_ENABLE_SNAPSHOT /* -** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted +** This function does the work of sqlite3WalSnapshotRecover(). +*/ +static int walSnapshotRecover( + Wal *pWal, /* WAL handle */ + void *pBuf1, /* Temp buffer pWal->szPage bytes in size */ + void *pBuf2 /* Temp buffer pWal->szPage bytes in size */ +){ + int szPage = (int)pWal->szPage; + int rc; + i64 szDb; /* Size of db file in bytes */ + + rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); + if( rc==SQLITE_OK ){ + volatile WalCkptInfo *pInfo = walCkptInfo(pWal); + u32 i = pInfo->nBackfillAttempted; + for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ + WalHashLoc sLoc; /* Hash table location */ + u32 pgno; /* Page number in db file */ + i64 iDbOff; /* Offset of db file entry */ + i64 iWalOff; /* Offset of wal file entry */ + + rc = walHashGet(pWal, walFramePage(i), &sLoc); + if( rc!=SQLITE_OK ) break; + assert( i - sLoc.iZero - 1 >=0 ); + pgno = sLoc.aPgno[i-sLoc.iZero-1]; + iDbOff = (i64)(pgno-1) * szPage; + + if( iDbOff+szPage<=szDb ){ + iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; + rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); + + if( rc==SQLITE_OK ){ + rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); + } + + if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ + break; + } + } + + pInfo->nBackfillAttempted = i-1; + } + } + + return rc; +} + +/* +** Attempt to reduce the value of the WalCkptInfo.nBackfillAttempted ** variable so that older snapshots can be accessed. To do this, loop -** through all wal frames from nBackfillAttempted to (nBackfill+1), +** through all wal frames from nBackfillAttempted to (nBackfill+1), ** comparing their content to the corresponding page with the database ** file, if any. Set nBackfillAttempted to the frame number of the ** first frame for which the wal file content matches the db file. ** -** This is only really safe if the file-system is such that any page -** writes made by earlier checkpointers were atomic operations, which +** This is only really safe if the file-system is such that any page +** writes made by earlier checkpointers were atomic operations, which ** is not always true. It is also possible that nBackfillAttempted ** may be left set to a value larger than expected, if a wal frame ** contains content that duplicate of an earlier version of the same @@ -2964,50 +3235,21 @@ assert( pWal->readLock>=0 ); rc = walLockExclusive(pWal, WAL_CKPT_LOCK, 1); if( rc==SQLITE_OK ){ - volatile WalCkptInfo *pInfo = walCkptInfo(pWal); - int szPage = (int)pWal->szPage; - i64 szDb; /* Size of db file in bytes */ - - rc = sqlite3OsFileSize(pWal->pDbFd, &szDb); - if( rc==SQLITE_OK ){ - void *pBuf1 = sqlite3_malloc(szPage); - void *pBuf2 = sqlite3_malloc(szPage); - if( pBuf1==0 || pBuf2==0 ){ - rc = SQLITE_NOMEM; - }else{ - u32 i = pInfo->nBackfillAttempted; - for(i=pInfo->nBackfillAttempted; i>AtomicLoad(&pInfo->nBackfill); i--){ - WalHashLoc sLoc; /* Hash table location */ - u32 pgno; /* Page number in db file */ - i64 iDbOff; /* Offset of db file entry */ - i64 iWalOff; /* Offset of wal file entry */ - - rc = walHashGet(pWal, walFramePage(i), &sLoc); - if( rc!=SQLITE_OK ) break; - assert( i - sLoc.iZero - 1 >=0 ); - pgno = sLoc.aPgno[i-sLoc.iZero-1]; - iDbOff = (i64)(pgno-1) * szPage; - - if( iDbOff+szPage<=szDb ){ - iWalOff = walFrameOffset(i, szPage) + WAL_FRAME_HDRSIZE; - rc = sqlite3OsRead(pWal->pWalFd, pBuf1, szPage, iWalOff); - - if( rc==SQLITE_OK ){ - rc = sqlite3OsRead(pWal->pDbFd, pBuf2, szPage, iDbOff); - } - - if( rc!=SQLITE_OK || 0==memcmp(pBuf1, pBuf2, szPage) ){ - break; - } - } - - pInfo->nBackfillAttempted = i-1; - } + void *pBuf1 = sqlite3_malloc(pWal->szPage); + void *pBuf2 = sqlite3_malloc(pWal->szPage); + if( pBuf1==0 || pBuf2==0 ){ + rc = SQLITE_NOMEM; + }else{ + pWal->ckptLock = 1; + SEH_TRY { + rc = walSnapshotRecover(pWal, pBuf1, pBuf2); } - - sqlite3_free(pBuf1); - sqlite3_free(pBuf2); + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + pWal->ckptLock = 0; } + + sqlite3_free(pBuf1); + sqlite3_free(pBuf2); walUnlockExclusive(pWal, WAL_CKPT_LOCK, 1); } @@ -3016,28 +3258,20 @@ #endif /* SQLITE_ENABLE_SNAPSHOT */ /* -** Begin a read transaction on the database. -** -** This routine used to be called sqlite3OpenSnapshot() and with good reason: -** it takes a snapshot of the state of the WAL and wal-index for the current -** instant in time. The current thread will continue to use this snapshot. -** Other threads might append new content to the WAL and wal-index but -** that extra content is ignored by the current thread. -** -** If the database contents have changes since the previous read -** transaction, then *pChanged is set to 1 before returning. The -** Pager layer will use this to know that its cache is stale and -** needs to be flushed. +** This function does the work of sqlite3WalBeginReadTransaction() (see +** below). That function simply calls this one inside an SEH_TRY{...} block. */ -int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ +static int walBeginReadTransaction(Wal *pWal, int *pChanged){ int rc; /* Return code */ int cnt = 0; /* Number of TryBeginRead attempts */ #ifdef SQLITE_ENABLE_SNAPSHOT + int ckptLock = 0; int bChanged = 0; WalIndexHdr *pSnapshot = pWal->pSnapshot; #endif assert( pWal->ckptLock==0 ); + assert( pWal->nSehTry>0 ); #ifdef SQLITE_ENABLE_SNAPSHOT if( pSnapshot ){ @@ -3045,13 +3279,13 @@ bChanged = 1; } - /* It is possible that there is a checkpointer thread running + /* It is possible that there is a checkpointer thread running ** concurrent with this code. If this is the case, it may be that the - ** checkpointer has already determined that it will checkpoint - ** snapshot X, where X is later in the wal file than pSnapshot, but - ** has not yet set the pInfo->nBackfillAttempted variable to indicate + ** checkpointer has already determined that it will checkpoint + ** snapshot X, where X is later in the wal file than pSnapshot, but + ** has not yet set the pInfo->nBackfillAttempted variable to indicate ** its intent. To avoid the race condition this leads to, ensure that - ** there is no checkpointer process by taking a shared CKPT lock + ** there is no checkpointer process by taking a shared CKPT lock ** before checking pInfo->nBackfillAttempted. */ (void)walEnableBlocking(pWal); rc = walLockShared(pWal, WAL_CKPT_LOCK); @@ -3060,7 +3294,7 @@ if( rc!=SQLITE_OK ){ return rc; } - pWal->ckptLock = 1; + ckptLock = 1; } #endif @@ -3112,7 +3346,7 @@ /* A client using a non-current snapshot may not ignore any frames ** from the start of the wal file. This is because, for a system ** where (minFrame < iSnapshot < maxFrame), a checkpointer may - ** have omitted to checkpoint a frame earlier than minFrame in + ** have omitted to checkpoint a frame earlier than minFrame in ** the file because there exists a frame after iSnapshot that ** is the same database page. */ pWal->minFrame = 1; @@ -3124,16 +3358,38 @@ } /* Release the shared CKPT lock obtained above. */ - if( pWal->ckptLock ){ + if( ckptLock ){ assert( pSnapshot ); walUnlockShared(pWal, WAL_CKPT_LOCK); - pWal->ckptLock = 0; } #endif return rc; } /* +** Begin a read transaction on the database. +** +** This routine used to be called sqlite3OpenSnapshot() and with good reason: +** it takes a snapshot of the state of the WAL and wal-index for the current +** instant in time. The current thread will continue to use this snapshot. +** Other threads might append new content to the WAL and wal-index but +** that extra content is ignored by the current thread. +** +** If the database contents have changes since the previous read +** transaction, then *pChanged is set to 1 before returning. The +** Pager layer will use this to know that its cache is stale and +** needs to be flushed. +*/ +int sqlite3WalBeginReadTransaction(Wal *pWal, int *pChanged){ + int rc; + SEH_TRY { + rc = walBeginReadTransaction(pWal, pChanged); + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* ** Finish with a read transaction. All this does is release the ** read-lock. */ @@ -3153,7 +3409,7 @@ ** Return SQLITE_OK if successful, or an error code if an error occurs. If an ** error does occur, the final value of *piRead is undefined. */ -int sqlite3WalFindFrame( +static int walFindFrame( Wal *pWal, /* WAL handle */ Pgno pgno, /* Database page number to read data for */ u32 *piRead /* OUT: Frame number (or zero) */ @@ -3168,8 +3424,8 @@ /* If the "last page" field of the wal-index header snapshot is 0, then ** no data will be read from the wal under any circumstances. Return early - ** in this case as an optimization. Likewise, if pWal->readLock==0, - ** then the WAL is ignored by the reader so return early, as if the + ** in this case as an optimization. Likewise, if pWal->readLock==0, + ** then the WAL is ignored by the reader so return early, as if the ** WAL were empty. */ if( iLast==0 || (pWal->readLock==0 && pWal->bShmUnreliable==0) ){ @@ -3182,9 +3438,9 @@ ** hash table (each hash table indexes up to HASHTABLE_NPAGE frames). ** ** This code might run concurrently to the code in walIndexAppend() - ** that adds entries to the wal-index (and possibly to this hash - ** table). This means the value just read from the hash - ** slot (aHash[iKey]) may have been added before or after the + ** that adds entries to the wal-index (and possibly to this hash + ** table). This means the value just read from the hash + ** slot (aHash[iKey]) may have been added before or after the ** current read transaction was opened. Values added after the ** read transaction was opened may have been written incorrectly - ** i.e. these slots may contain garbage data. However, we assume @@ -3192,13 +3448,13 @@ ** opened remain unmodified. ** ** For the reasons above, the if(...) condition featured in the inner - ** loop of the following block is more stringent that would be required + ** loop of the following block is more stringent that would be required ** if we had exclusive access to the hash-table: ** - ** (aPgno[iFrame]==pgno): + ** (aPgno[iFrame]==pgno): ** This condition filters out normal hash-table collisions. ** - ** (iFrame<=iLast): + ** (iFrame<=iLast): ** This condition filters out entries that were added to the hash ** table after the current read-transaction had started. */ @@ -3216,6 +3472,7 @@ } nCollide = HASHTABLE_NSLOT; iKey = walHash(pgno); + SEH_INJECT_FAULT; while( (iH = AtomicLoad(&sLoc.aHash[iKey]))!=0 ){ u32 iFrame = iH + sLoc.iZero; if( iFrame<=iLast && iFrame>=pWal->minFrame && sLoc.aPgno[iH-1]==pgno ){ @@ -3253,6 +3510,30 @@ } /* +** Search the wal file for page pgno. If found, set *piRead to the frame that +** contains the page. Otherwise, if pgno is not in the wal file, set *piRead +** to zero. +** +** Return SQLITE_OK if successful, or an error code if an error occurs. If an +** error does occur, the final value of *piRead is undefined. +** +** The difference between this function and walFindFrame() is that this +** function wraps walFindFrame() in an SEH_TRY{...} block. +*/ +int sqlite3WalFindFrame( + Wal *pWal, /* WAL handle */ + Pgno pgno, /* Database page number to read data for */ + u32 *piRead /* OUT: Frame number (or zero) */ +){ + int rc; + SEH_TRY { + rc = walFindFrame(pWal, pgno, piRead); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + return rc; +} + +/* ** Read the contents of frame iRead from the wal file into buffer pOut ** (which is nOut bytes in size). Return SQLITE_OK if successful, or an ** error code otherwise. @@ -3274,7 +3555,7 @@ return sqlite3OsRead(pWal->pWalFd, pOut, (nOut>sz ? sz : nOut), iOffset); } -/* +/* ** Return the size of the database in pages (or zero, if unknown). */ Pgno sqlite3WalDbsize(Wal *pWal){ @@ -3285,7 +3566,7 @@ } -/* +/* ** This function starts a write transaction on the WAL. ** ** A read transaction must have already been started by a prior call @@ -3333,12 +3614,17 @@ ** time the read transaction on this connection was started, then ** the write is disallowed. */ - if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ + SEH_TRY { + if( memcmp(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr))!=0 ){ + rc = SQLITE_BUSY_SNAPSHOT; + } + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) + + if( rc!=SQLITE_OK ){ walUnlockExclusive(pWal, WAL_WRITE_LOCK, 1); pWal->writeLock = 0; - rc = SQLITE_BUSY_SNAPSHOT; } - return rc; } @@ -3373,39 +3659,42 @@ if( ALWAYS(pWal->writeLock) ){ Pgno iMax = pWal->hdr.mxFrame; Pgno iFrame; - - /* Restore the clients cache of the wal-index header to the state it - ** was in before the client began writing to the database. - */ - memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); - for(iFrame=pWal->hdr.mxFrame+1; - ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; - iFrame++ - ){ - /* This call cannot fail. Unless the page for which the page number - ** is passed as the second argument is (a) in the cache and - ** (b) has an outstanding reference, then xUndo is either a no-op - ** (if (a) is false) or simply expels the page from the cache (if (b) - ** is false). - ** - ** If the upper layer is doing a rollback, it is guaranteed that there - ** are no outstanding references to any page other than page 1. And - ** page 1 is never written to the log until the transaction is - ** committed. As a result, the call to xUndo may not fail. + SEH_TRY { + /* Restore the clients cache of the wal-index header to the state it + ** was in before the client began writing to the database. */ - assert( walFramePgno(pWal, iFrame)!=1 ); - rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); + memcpy(&pWal->hdr, (void *)walIndexHdr(pWal), sizeof(WalIndexHdr)); + + for(iFrame=pWal->hdr.mxFrame+1; + ALWAYS(rc==SQLITE_OK) && iFrame<=iMax; + iFrame++ + ){ + /* This call cannot fail. Unless the page for which the page number + ** is passed as the second argument is (a) in the cache and + ** (b) has an outstanding reference, then xUndo is either a no-op + ** (if (a) is false) or simply expels the page from the cache (if (b) + ** is false). + ** + ** If the upper layer is doing a rollback, it is guaranteed that there + ** are no outstanding references to any page other than page 1. And + ** page 1 is never written to the log until the transaction is + ** committed. As a result, the call to xUndo may not fail. + */ + assert( walFramePgno(pWal, iFrame)!=1 ); + rc = xUndo(pUndoCtx, walFramePgno(pWal, iFrame)); + } + if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); } - if( iMax!=pWal->hdr.mxFrame ) walCleanupHash(pWal); + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) } return rc; } -/* -** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 -** values. This function populates the array with values required to -** "rollback" the write position of the WAL handle back to the current +/* +** Argument aWalData must point to an array of WAL_SAVEPOINT_NDATA u32 +** values. This function populates the array with values required to +** "rollback" the write position of the WAL handle back to the current ** point in the event of a savepoint rollback (via WalSavepointUndo()). */ void sqlite3WalSavepoint(Wal *pWal, u32 *aWalData){ @@ -3416,7 +3705,7 @@ aWalData[3] = pWal->nCkpt; } -/* +/* ** Move the write position of the WAL back to the point identified by ** the values in the aWalData[] array. aWalData must point to an array ** of WAL_SAVEPOINT_NDATA u32 values that has been previously populated @@ -3441,7 +3730,10 @@ pWal->hdr.mxFrame = aWalData[0]; pWal->hdr.aFrameCksum[0] = aWalData[1]; pWal->hdr.aFrameCksum[1] = aWalData[2]; - walCleanupHash(pWal); + SEH_TRY { + walCleanupHash(pWal); + } + SEH_EXCEPT( rc = SQLITE_IOERR_IN_PAGE; ) } return rc; @@ -3618,11 +3910,11 @@ return rc; } -/* +/* ** Write a set of frames to the log. The caller must hold the write-lock ** on the log file (obtained using sqlite3WalBeginWriteTransaction()). */ -int sqlite3WalFrames( +static int walFrames( Wal *pWal, /* Wal handle to write to */ int szPage, /* Database page-size in bytes */ PgHdr *pList, /* List of dirty pages to write */ @@ -3685,7 +3977,7 @@ walChecksumBytes(1, aWalHdr, WAL_HDRSIZE-2*4, 0, aCksum); sqlite3Put4byte(&aWalHdr[24], aCksum[0]); sqlite3Put4byte(&aWalHdr[28], aCksum[1]); - + pWal->szPage = szPage; pWal->hdr.bigEndCksum = SQLITE_BIGENDIAN; pWal->hdr.aFrameCksum[0] = aCksum[0]; @@ -3729,11 +4021,11 @@ /* Check if this page has already been written into the wal file by ** the current transaction. If so, overwrite the existing frame and - ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that + ** set Wal.writeLock to WAL_WRITELOCK_RECKSUM - indicating that ** checksums must be recomputed when the transaction is committed. */ if( iFirst && (p->pDirty || isCommit==0) ){ u32 iWrite = 0; - VVA_ONLY(rc =) sqlite3WalFindFrame(pWal, p->pgno, &iWrite); + VVA_ONLY(rc =) walFindFrame(pWal, p->pgno, &iWrite); assert( rc==SQLITE_OK || iWrite==0 ); if( iWrite>=iFirst ){ i64 iOff = walFrameOffset(iWrite, szPage) + WAL_FRAME_HDRSIZE; @@ -3813,7 +4105,7 @@ pWal->truncateOnCommit = 0; } - /* Append data to the wal-index. It is not necessary to lock the + /* Append data to the wal-index. It is not necessary to lock the ** wal-index to do this as the SQLITE_SHM_WRITE lock held on the wal-index ** guarantees that there are no other writers, and no data that may ** be in use by existing readers is being overwritten. @@ -3853,6 +4145,29 @@ } /* +** Write a set of frames to the log. The caller must hold the write-lock +** on the log file (obtained using sqlite3WalBeginWriteTransaction()). +** +** The difference between this function and walFrames() is that this +** function wraps walFrames() in an SEH_TRY{...} block. +*/ +int sqlite3WalFrames( + Wal *pWal, /* Wal handle to write to */ + int szPage, /* Database page-size in bytes */ + PgHdr *pList, /* List of dirty pages to write */ + Pgno nTruncate, /* Database size after this commit */ + int isCommit, /* True if this is a commit */ + int sync_flags /* Flags to pass to OsSync() (or 0) */ +){ + int rc; + SEH_TRY { + rc = walFrames(pWal, szPage, pList, nTruncate, isCommit, sync_flags); + } + SEH_EXCEPT( rc = walHandleException(pWal); ) + return rc; +} + +/* ** This routine is called to implement sqlite3_wal_checkpoint() and ** related interfaces. ** @@ -3894,7 +4209,7 @@ sqlite3WalDb(pWal, db); (void)walEnableBlocking(pWal); - /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive + /* IMPLEMENTATION-OF: R-62028-47212 All calls obtain an exclusive ** "checkpoint" lock on the database file. ** EVIDENCE-OF: R-10421-19736 If any other process is running a ** checkpoint operation at the same time, the lock cannot be obtained and @@ -3931,33 +4246,36 @@ /* Read the wal-index header. */ - if( rc==SQLITE_OK ){ - walDisableBlocking(pWal); - rc = walIndexReadHdr(pWal, &isChanged); - (void)walEnableBlocking(pWal); - if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ - sqlite3OsUnfetch(pWal->pDbFd, 0, 0); - } - } - - /* Copy data from the log to the database file. */ - if( rc==SQLITE_OK ){ - - if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ - rc = SQLITE_CORRUPT_BKPT; - }else{ - rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags, zBuf); + SEH_TRY { + if( rc==SQLITE_OK ){ + walDisableBlocking(pWal); + rc = walIndexReadHdr(pWal, &isChanged); + (void)walEnableBlocking(pWal); + if( isChanged && pWal->pDbFd->pMethods->iVersion>=3 ){ + sqlite3OsUnfetch(pWal->pDbFd, 0, 0); + } } + + /* Copy data from the log to the database file. */ + if( rc==SQLITE_OK ){ + if( pWal->hdr.mxFrame && walPagesize(pWal)!=nBuf ){ + rc = SQLITE_CORRUPT_BKPT; + }else{ + rc = walCheckpoint(pWal, db, eMode2, xBusy2, pBusyArg, sync_flags,zBuf); + } - /* If no error occurred, set the output variables. */ - if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ - if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; - if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); + /* If no error occurred, set the output variables. */ + if( rc==SQLITE_OK || rc==SQLITE_BUSY ){ + if( pnLog ) *pnLog = (int)pWal->hdr.mxFrame; + SEH_INJECT_FAULT; + if( pnCkpt ) *pnCkpt = (int)(walCkptInfo(pWal)->nBackfill); + } } } + SEH_EXCEPT( rc = walHandleException(pWal); ) if( isChanged ){ - /* If a new wal-index header was loaded before the checkpoint was + /* If a new wal-index header was loaded before the checkpoint was ** performed, then the pager-cache associated with pWal is now ** out of date. So zero the cached wal-index header to ensure that ** next time the pager opens a snapshot on this database it knows that @@ -4008,7 +4326,7 @@ ** operation must occur while the pager is still holding the exclusive ** lock on the main database file. ** -** If op is one, then change from locking_mode=NORMAL into +** If op is one, then change from locking_mode=NORMAL into ** locking_mode=EXCLUSIVE. This means that the pWal->readLock must ** be released. Return 1 if the transition is made and 0 if the ** WAL is already in exclusive-locking mode - meaning that this @@ -4025,13 +4343,15 @@ assert( pWal->writeLock==0 ); assert( pWal->exclusiveMode!=WAL_HEAPMEMORY_MODE || op==-1 ); - /* pWal->readLock is usually set, but might be -1 if there was a - ** prior error while attempting to acquire are read-lock. This cannot + /* pWal->readLock is usually set, but might be -1 if there was a + ** prior error while attempting to acquire are read-lock. This cannot ** happen if the connection is actually in exclusive mode (as no xShmLock ** locks are taken in this case). Nor should the pager attempt to ** upgrade to exclusive-mode following such an error. */ +#ifndef SQLITE_USE_SEH assert( pWal->readLock>=0 || pWal->lockError ); +#endif assert( pWal->readLock>=0 || (op<=0 && pWal->exclusiveMode==0) ); if( op==0 ){ @@ -4057,10 +4377,10 @@ return rc; } -/* +/* ** Return true if the argument is non-NULL and the WAL module is using ** heap-memory for the wal-index. Otherwise, if the argument is NULL or the -** WAL module is using shared-memory, return false. +** WAL module is using shared-memory, return false. */ int sqlite3WalHeapMemory(Wal *pWal){ return (pWal && pWal->exclusiveMode==WAL_HEAPMEMORY_MODE ); @@ -4096,13 +4416,13 @@ /* Try to open on pSnapshot when the next read-transaction starts */ void sqlite3WalSnapshotOpen( - Wal *pWal, + Wal *pWal, sqlite3_snapshot *pSnapshot ){ pWal->pSnapshot = (WalIndexHdr*)pSnapshot; } -/* +/* ** Return a +ve value if snapshot p1 is newer than p2. A -ve value if ** p1 is older than p2 and zero if p1 and p2 are the same snapshot. */ @@ -4122,7 +4442,7 @@ /* ** The caller currently has a read transaction open on the database. ** This function takes a SHARED lock on the CHECKPOINTER slot and then -** checks if the snapshot passed as the second argument is still +** checks if the snapshot passed as the second argument is still ** available. If so, SQLITE_OK is returned. ** ** If the snapshot is not available, SQLITE_ERROR is returned. Or, if @@ -4132,16 +4452,19 @@ */ int sqlite3WalSnapshotCheck(Wal *pWal, sqlite3_snapshot *pSnapshot){ int rc; - rc = walLockShared(pWal, WAL_CKPT_LOCK); - if( rc==SQLITE_OK ){ - WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; - if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) - || pNew->mxFramenBackfillAttempted - ){ - rc = SQLITE_ERROR_SNAPSHOT; - walUnlockShared(pWal, WAL_CKPT_LOCK); + SEH_TRY { + rc = walLockShared(pWal, WAL_CKPT_LOCK); + if( rc==SQLITE_OK ){ + WalIndexHdr *pNew = (WalIndexHdr*)pSnapshot; + if( memcmp(pNew->aSalt, pWal->hdr.aSalt, sizeof(pWal->hdr.aSalt)) + || pNew->mxFramenBackfillAttempted + ){ + rc = SQLITE_ERROR_SNAPSHOT; + walUnlockShared(pWal, WAL_CKPT_LOCK); + } } } + SEH_EXCEPT( rc = walHandleException(pWal); ) return rc; } diff -Nru sqlite3-3.42.0/src/wal.h sqlite3-3.44.0-0/src/wal.h --- sqlite3-3.42.0/src/wal.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/wal.h 2023-11-04 14:23:58.000000000 +0000 @@ -45,6 +45,7 @@ # define sqlite3WalFramesize(z) 0 # define sqlite3WalFindFrame(x,y,z) 0 # define sqlite3WalFile(x) 0 +# undef SQLITE_USE_SEH #else #define WAL_SAVEPOINT_NDATA 4 @@ -151,5 +152,9 @@ void sqlite3WalDb(Wal *pWal, sqlite3 *db); #endif +#ifdef SQLITE_USE_SEH +int sqlite3WalSystemErrno(Wal*); +#endif + #endif /* ifndef SQLITE_OMIT_WAL */ #endif /* SQLITE_WAL_H */ diff -Nru sqlite3-3.42.0/src/walker.c sqlite3-3.44.0-0/src/walker.c --- sqlite3-3.42.0/src/walker.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/walker.c 2023-11-04 14:23:58.000000000 +0000 @@ -61,7 +61,7 @@ ** The return value from this routine is WRC_Abort to abandon the tree walk ** and WRC_Continue to continue. */ -static SQLITE_NOINLINE int walkExpr(Walker *pWalker, Expr *pExpr){ +SQLITE_NOINLINE int sqlite3WalkExprNN(Walker *pWalker, Expr *pExpr){ int rc; testcase( ExprHasProperty(pExpr, EP_TokenOnly) ); testcase( ExprHasProperty(pExpr, EP_Reduced) ); @@ -70,7 +70,9 @@ if( rc ) return rc & WRC_Abort; if( !ExprHasProperty(pExpr,(EP_TokenOnly|EP_Leaf)) ){ assert( pExpr->x.pList==0 || pExpr->pRight==0 ); - if( pExpr->pLeft && walkExpr(pWalker, pExpr->pLeft) ) return WRC_Abort; + if( pExpr->pLeft && sqlite3WalkExprNN(pWalker, pExpr->pLeft) ){ + return WRC_Abort; + } if( pExpr->pRight ){ assert( !ExprHasProperty(pExpr, EP_WinFunc) ); pExpr = pExpr->pRight; @@ -94,7 +96,7 @@ return WRC_Continue; } int sqlite3WalkExpr(Walker *pWalker, Expr *pExpr){ - return pExpr ? walkExpr(pWalker,pExpr) : WRC_Continue; + return pExpr ? sqlite3WalkExprNN(pWalker,pExpr) : WRC_Continue; } /* @@ -220,7 +222,7 @@ } /* Increase the walkerDepth when entering a subquery, and -** descrease when leaving the subquery. +** decrease when leaving the subquery. */ int sqlite3WalkerDepthIncrease(Walker *pWalker, Select *pSelect){ UNUSED_PARAMETER(pSelect); diff -Nru sqlite3-3.42.0/src/where.c sqlite3-3.44.0-0/src/where.c --- sqlite3-3.42.0/src/where.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/where.c 2023-11-04 14:23:58.000000000 +0000 @@ -88,7 +88,7 @@ ** be the continuation for the inner-most loop. ** ** It is always safe for this routine to return the continuation of the -** inner-most loop, in the sense that a correct answer will result. +** inner-most loop, in the sense that a correct answer will result. ** Returning the continuation the second inner loop is an optimization ** that might make the code run a little faster, but should not change ** the final answer. @@ -96,7 +96,7 @@ int sqlite3WhereOrderByLimitOptLabel(WhereInfo *pWInfo){ WhereLevel *pInner; if( !pWInfo->bOrderedInnerLoop ){ - /* The ORDER BY LIMIT optimization does not apply. Jump to the + /* The ORDER BY LIMIT optimization does not apply. Jump to the ** continuation of the inner-most loop. */ return pWInfo->iContinue; } @@ -153,7 +153,7 @@ ** operate directly on the rowids returned by a WHERE clause. Return ** ONEPASS_SINGLE (1) if the statement can operation directly because only ** a single row is to be changed. Return ONEPASS_MULTI (2) if the one-pass -** optimization can be used on multiple +** optimization can be used on multiple ** ** If the ONEPASS optimization is used (if this routine returns true) ** then also write the indices of open cursors used by ONEPASS @@ -478,7 +478,7 @@ ** if pIdx!=0 and is one of the WO_xx operator codes specified by ** the op parameter. Return a pointer to the term. Return 0 if not found. ** -** If pIdx!=0 then it must be one of the indexes of table iCur. +** If pIdx!=0 then it must be one of the indexes of table iCur. ** Search for terms matching the iColumn-th column of pIdx ** rather than the iColumn-th column of table iCur. ** @@ -592,17 +592,17 @@ ){ Table *pTab; Index *pIdx; - int i; + int i; int iBase; /* If there is more than one table or sub-select in the FROM clause of - ** this query, then it will not be possible to show that the DISTINCT + ** this query, then it will not be possible to show that the DISTINCT ** clause is redundant. */ if( pTabList->nSrc!=1 ) return 0; iBase = pTabList->a[0].iCursor; pTab = pTabList->a[0].pTab; - /* If any of the expressions is an IPK column on table iBase, then return + /* If any of the expressions is an IPK column on table iBase, then return ** true. Note: The (p->iTable==iBase) part of this test may be false if the ** current SELECT is a correlated sub-query. */ @@ -656,7 +656,7 @@ ** Convert OP_Column opcodes to OP_Copy in previously generated code. ** ** This routine runs over generated VDBE code and translates OP_Column -** opcodes into OP_Copy when the table is being accessed via co-routine +** opcodes into OP_Copy when the table is being accessed via co-routine ** instead of via table lookup. ** ** If the iAutoidxCur is not zero, then any OP_Rowid instructions on @@ -777,7 +777,7 @@ } return 1; } - + #ifndef SQLITE_OMIT_AUTOMATIC_INDEX @@ -822,7 +822,7 @@ ** ** This is only required if sqlite3_stmt_scanstatus() is enabled, to ** associate an SQLITE_SCANSTAT_NCYCLE and SQLITE_SCANSTAT_NLOOP -** values with. In order to avoid breaking legacy code and test cases, +** values with. In order to avoid breaking legacy code and test cases, ** the OP_Explain is not added if this is an EXPLAIN QUERY PLAN command. */ static void explainAutomaticIndex( @@ -1096,7 +1096,7 @@ } sqlite3VdbeJumpHere(v, addrTop); sqlite3ReleaseTempReg(pParse, regRecord); - + /* Jump here when skipping the initialization */ sqlite3VdbeJumpHere(v, addrInit); sqlite3VdbeScanStatusRange(v, addrExp, addrExp, -1); @@ -1142,13 +1142,17 @@ WhereLoop *pLoop = pLevel->pWLoop; /* The loop being coded */ int iCur; /* Cursor for table getting the filter */ IndexedExpr *saved_pIdxEpr; /* saved copy of Parse.pIdxEpr */ + IndexedExpr *saved_pIdxPartExpr; /* saved copy of Parse.pIdxPartExpr */ saved_pIdxEpr = pParse->pIdxEpr; + saved_pIdxPartExpr = pParse->pIdxPartExpr; pParse->pIdxEpr = 0; + pParse->pIdxPartExpr = 0; assert( pLoop!=0 ); assert( v!=0 ); assert( pLoop->wsFlags & WHERE_BLOOMFILTER ); + assert( (pLoop->wsFlags & WHERE_IDX_ONLY)==0 ); addrOnce = sqlite3VdbeAddOp0(v, OP_Once); VdbeCoverage(v); do{ @@ -1238,12 +1242,13 @@ }while( iLevel < pWInfo->nLevel ); sqlite3VdbeJumpHere(v, addrOnce); pParse->pIdxEpr = saved_pIdxEpr; + pParse->pIdxPartExpr = saved_pIdxPartExpr; } #ifndef SQLITE_OMIT_VIRTUALTABLE /* -** Allocate and populate an sqlite3_index_info structure. It is the +** Allocate and populate an sqlite3_index_info structure. It is the ** responsibility of the caller to eventually release the structure ** by passing the pointer returned by this function to freeIndexInfo(). */ @@ -1268,7 +1273,7 @@ const Table *pTab; int eDistinct = 0; ExprList *pOrderBy = pWInfo->pOrderBy; - + assert( pSrc!=0 ); pTab = pSrc->pTab; assert( pTab!=0 ); @@ -1302,7 +1307,7 @@ pTerm->wtFlags |= TERM_OK; } - /* If the ORDER BY clause contains only columns in the current + /* If the ORDER BY clause contains only columns in the current ** virtual table then allocate space for the aOrderBy part of ** the sqlite3_index_info structure. */ @@ -1411,7 +1416,7 @@ assert( pTerm->eOperator&(WO_IN|WO_EQ|WO_LT|WO_LE|WO_GT|WO_GE|WO_AUX) ); if( op & (WO_LT|WO_LE|WO_GT|WO_GE) - && sqlite3ExprIsVector(pTerm->pExpr->pRight) + && sqlite3ExprIsVector(pTerm->pExpr->pRight) ){ testcase( j!=i ); if( j<16 ) mNoOmit |= (1 << j); @@ -1513,8 +1518,8 @@ ** Return the index of the sample that is the smallest sample that ** is greater than or equal to pRec. Note that this index is not an index ** into the aSample[] array - it is an index into a virtual set of samples -** based on the contents of aSample[] and the number of fields in record -** pRec. +** based on the contents of aSample[] and the number of fields in record +** pRec. */ static int whereKeyStats( Parse *pParse, /* Database connection */ @@ -1539,7 +1544,7 @@ assert( pRec!=0 ); assert( pIdx->nSample>0 ); assert( pRec->nField>0 ); - + /* Do a binary search to find the first sample greater than or equal ** to pRec. If pRec contains a single field, the set of samples to search @@ -1551,38 +1556,38 @@ ** consider prefixes of those samples. For example, if the set of samples ** in aSample is: ** - ** aSample[0] = (a, 5) - ** aSample[1] = (a, 10) - ** aSample[2] = (b, 5) - ** aSample[3] = (c, 100) + ** aSample[0] = (a, 5) + ** aSample[1] = (a, 10) + ** aSample[2] = (b, 5) + ** aSample[3] = (c, 100) ** aSample[4] = (c, 105) ** - ** Then the search space should ideally be the samples above and the - ** unique prefixes [a], [b] and [c]. But since that is hard to organize, + ** Then the search space should ideally be the samples above and the + ** unique prefixes [a], [b] and [c]. But since that is hard to organize, ** the code actually searches this set: ** - ** 0: (a) - ** 1: (a, 5) - ** 2: (a, 10) - ** 3: (a, 10) - ** 4: (b) - ** 5: (b, 5) - ** 6: (c) - ** 7: (c, 100) + ** 0: (a) + ** 1: (a, 5) + ** 2: (a, 10) + ** 3: (a, 10) + ** 4: (b) + ** 5: (b, 5) + ** 6: (c) + ** 7: (c, 100) ** 8: (c, 105) ** 9: (c, 105) ** ** For each sample in the aSample[] array, N samples are present in the - ** effective sample array. In the above, samples 0 and 1 are based on + ** effective sample array. In the above, samples 0 and 1 are based on ** sample aSample[0]. Samples 2 and 3 on aSample[1] etc. ** ** Often, sample i of each block of N effective samples has (i+1) fields. ** Except, each sample may be extended to ensure that it is greater than or - ** equal to the previous sample in the array. For example, in the above, - ** sample 2 is the first sample of a block of N samples, so at first it - ** appears that it should be 1 field in size. However, that would make it - ** smaller than sample 1, so the binary search would not work. As a result, - ** it is extended to two fields. The duplicates that this creates do not + ** equal to the previous sample in the array. For example, in the above, + ** sample 2 is the first sample of a block of N samples, so at first it + ** appears that it should be 1 field in size. However, that would make it + ** smaller than sample 1, so the binary search would not work. As a result, + ** it is extended to two fields. The duplicates that this creates do not ** cause any problems. */ if( !HasRowid(pIdx->pTable) && IsPrimaryKeyIndex(pIdx) ){ @@ -1601,7 +1606,7 @@ iSamp = iTest / nField; if( iSamp>0 ){ /* The proposed effective sample is a prefix of sample aSample[iSamp]. - ** Specifically, the shortest prefix of at least (1 + iTest%nField) + ** Specifically, the shortest prefix of at least (1 + iTest%nField) ** fields that is greater than the previous effective sample. */ for(n=(iTest % nField) + 1; nnSample ); assert( iCol==nField-1 ); pRec->nField = nField; - assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) - || pParse->db->mallocFailed + assert( 0==sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec) + || pParse->db->mallocFailed ); }else{ /* Unless i==pIdx->nSample, indicating that pRec is larger than @@ -1645,7 +1650,7 @@ ** (iCol+1) field prefix of sample i. */ assert( i<=pIdx->nSample && i>=0 ); pRec->nField = iCol+1; - assert( i==pIdx->nSample + assert( i==pIdx->nSample || sqlite3VdbeRecordCompare(aSample[i].n, aSample[i].p, pRec)>0 || pParse->db->mallocFailed ); @@ -1673,7 +1678,7 @@ aStat[0] = aSample[i].anLt[iCol]; aStat[1] = aSample[i].anEq[iCol]; }else{ - /* At this point, the (iCol+1) field prefix of aSample[i] is the first + /* At this point, the (iCol+1) field prefix of aSample[i] is the first ** sample that is greater than pRec. Or, if i==pIdx->nSample then pRec ** is larger than all samples in the array. */ tRowcnt iUpper, iGap; @@ -1705,7 +1710,7 @@ /* ** If it is not NULL, pTerm is a term that provides an upper or lower -** bound on a range scan. Without considering pTerm, it is estimated +** bound on a range scan. Without considering pTerm, it is estimated ** that the scan will visit nNew rows. This function returns the number ** estimated to be visited after taking pTerm into account. ** @@ -1743,18 +1748,18 @@ #ifdef SQLITE_ENABLE_STAT4 -/* +/* ** This function is called to estimate the number of rows visited by a ** range-scan on a skip-scan index. For example: ** ** CREATE INDEX i1 ON t1(a, b, c); ** SELECT * FROM t1 WHERE a=? AND c BETWEEN ? AND ?; ** -** Value pLoop->nOut is currently set to the estimated number of rows -** visited for scanning (a=? AND b=?). This function reduces that estimate +** 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 peformed multiple -** times (once for each (a,b) combination that matches a=?) is dealt with +** 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 @@ -1775,7 +1780,7 @@ ** estimate of the number of rows delivered remains unchanged), *pbDone ** is left as is. ** -** If an error occurs, an SQLite error code is returned. Otherwise, +** If an error occurs, an SQLite error code is returned. Otherwise, ** SQLITE_OK. */ static int whereRangeSkipScanEst( @@ -1793,7 +1798,7 @@ int rc = SQLITE_OK; u8 aff = sqlite3IndexColumnAffinity(db, p, nEq); CollSeq *pColl; - + sqlite3_value *p1 = 0; /* Value extracted from pLower */ sqlite3_value *p2 = 0; /* Value extracted from pUpper */ sqlite3_value *pVal = 0; /* Value extracted from record */ @@ -1825,7 +1830,7 @@ nDiff = (nUpper - nLower); if( nDiff<=0 ) nDiff = 1; - /* If there is both an upper and lower bound specified, and the + /* If there is both an upper and lower bound specified, and the ** comparisons indicate that they are close together, use the fallback ** method (assume that the scan visits 1/64 of the rows) for estimating ** the number of rows visited. Otherwise, estimate the number of rows @@ -1872,7 +1877,7 @@ ** ** ... FROM t1 WHERE a = ? AND b > ? AND b < ? ... ** -** then nEq is set to 1 (as the range restricted column, b, is the second +** then nEq is set to 1 (as the range restricted column, b, is the second ** left-most column of the index). Or, if the query is: ** ** ... FROM t1 WHERE a > ? AND a < ? ... @@ -1880,13 +1885,13 @@ ** then nEq is set to 0. ** ** When this function is called, *pnOut is set to the sqlite3LogEst() of the -** number of rows that the index scan is expected to visit without -** considering the range constraints. If nEq is 0, then *pnOut is the number of +** number of rows that the index scan is expected to visit without +** considering the range constraints. If nEq is 0, then *pnOut is the number of ** rows in the index. Assuming no error occurs, *pnOut is adjusted (reduced) ** to account for the range constraints pLower and pUpper. -** +** ** In the absence of sqlite_stat4 ANALYZE data, or if such data cannot be -** used, a single range inequality reduces the search space by a factor of 4. +** used, a single range inequality reduces the search space by a factor of 4. ** and a pair of constraints (x>? AND xu.btree.nBtm; int nTop = pLoop->u.btree.nTop; - /* Variable iLower will be set to the estimate of the number of rows in + /* Variable iLower will be set to the estimate of the number of rows in ** the index that are less than the lower bound of the range query. The ** lower bound being the concatenation of $P and $L, where $P is the ** key-prefix formed by the nEq values matched against the nEq left-most @@ -1923,7 +1928,7 @@ ** Or, if pLower is NULL or $L cannot be extracted from it (because it ** is not a simple variable or literal value), the lower bound of the ** range is $P. Due to a quirk in the way whereKeyStats() works, even - ** if $L is available, whereKeyStats() is called for both ($P) and + ** if $L is available, whereKeyStats() is called for both ($P) and ** ($P:$L) and the larger of the two returned values is used. ** ** Similarly, iUpper is to be set to the estimate of the number of rows @@ -1947,7 +1952,7 @@ iLower = 0; iUpper = p->nRowEst0; }else{ - /* Note: this call could be optimized away - since the same values must + /* Note: this call could be optimized away - since the same values must ** have been requested when testing key $P in whereEqualScanEst(). */ whereKeyStats(pParse, p, pRec, 0, a); iLower = a[0]; @@ -2035,7 +2040,7 @@ ** reduced by an additional 75%. This means that, by default, an open-ended ** range query (e.g. col > ?) is assumed to match 1/4 of the rows in the ** index. While a closed range (e.g. col BETWEEN ? AND ?) is estimated to - ** match 1/64 of the index. */ + ** match 1/64 of the index. */ if( pLower && pLower->truthProb>0 && pUpper && pUpper->truthProb>0 ){ nNew -= 20; } @@ -2062,7 +2067,7 @@ ** for that index. When pExpr==NULL that means the constraint is ** "x IS NULL" instead of "x=VALUE". ** -** Write the estimated row count into *pnRow and return SQLITE_OK. +** Write the estimated row count into *pnRow and return SQLITE_OK. ** If unable to make an estimate, leave *pnRow unchanged and return ** non-zero. ** @@ -2113,7 +2118,7 @@ WHERETRACE(0x20,("equality scan regions %s(%d): %d\n", p->zName, nEq-1, (int)a[1])); *pnRow = a[1]; - + return rc; } #endif /* SQLITE_ENABLE_STAT4 */ @@ -2126,7 +2131,7 @@ ** ** WHERE x IN (1,2,3,4) ** -** Write the estimated row count into *pnRow and return SQLITE_OK. +** Write the estimated row count into *pnRow and return SQLITE_OK. ** If unable to make an estimate, leave *pnRow unchanged and return ** non-zero. ** @@ -2188,7 +2193,7 @@ sqlite3_snprintf(sizeof(zLeft),zLeft,"left={%d:%d}", pTerm->leftCursor, pTerm->u.x.leftColumn); }else if( (pTerm->eOperator & WO_OR)!=0 && pTerm->u.pOrInfo!=0 ){ - sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", + sqlite3_snprintf(sizeof(zLeft),zLeft,"indexable=0x%llx", pTerm->u.pOrInfo->indexable); }else{ sqlite3_snprintf(sizeof(zLeft),zLeft,"left=%d", pTerm->leftCursor); @@ -2390,7 +2395,7 @@ /* ** Return TRUE if all of the following are true: ** -** (1) X has the same or lower cost, or returns the same or fewer rows, +** (1) X has the same or lower cost, or returns the same or fewer rows, ** than Y. ** (2) X uses fewer WHERE clause terms than Y ** (3) Every WHERE clause term used by X is also used by Y @@ -2399,7 +2404,7 @@ ** ** Conditions (2) and (3) mean that X is a "proper subset" of Y. ** If X is a proper subset of Y then Y is a better choice and ought -** to have a lower cost. This routine returns TRUE when that cost +** to have a lower cost. This routine returns TRUE when that cost ** relationship is inverted and needs to be adjusted. Constraint (4) ** was added because if X uses skip-scan less than Y it still might ** deserve a lower cost even if it is a proper subset of Y. Constraint (5) @@ -2423,7 +2428,7 @@ } if( j<0 ) return 0; /* X not a subset of Y since term X[i] not used by Y */ } - if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 + if( (pX->wsFlags&WHERE_IDX_ONLY)!=0 && (pY->wsFlags&WHERE_IDX_ONLY)==0 ){ return 0; /* Constraint (5) */ } @@ -2450,10 +2455,10 @@ if( p->iTab!=pTemplate->iTab ) continue; if( (p->wsFlags & WHERE_INDEXED)==0 ) continue; if( whereLoopCheaperProperSubset(p, pTemplate) ){ - /* Adjust pTemplate cost downward so that it is cheaper than its + /* Adjust pTemplate cost downward so that it is cheaper than its ** subset p. */ WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", - pTemplate->rRun, pTemplate->nOut, + pTemplate->rRun, pTemplate->nOut, MIN(p->rRun, pTemplate->rRun), MIN(p->nOut - 1, pTemplate->nOut))); pTemplate->rRun = MIN(p->rRun, pTemplate->rRun); @@ -2462,7 +2467,7 @@ /* Adjust pTemplate cost upward so that it is costlier than p since ** pTemplate is a proper subset of p */ WHERETRACE(0x80,("subset cost adjustment %d,%d to %d,%d\n", - pTemplate->rRun, pTemplate->nOut, + pTemplate->rRun, pTemplate->nOut, MAX(p->rRun, pTemplate->rRun), MAX(p->nOut + 1, pTemplate->nOut))); pTemplate->rRun = MAX(p->rRun, pTemplate->rRun); @@ -2500,7 +2505,7 @@ /* In the current implementation, the rSetup value is either zero ** or the cost of building an automatic index (NlogN) and the NlogN ** is the same for compatible WhereLoops. */ - assert( p->rSetup==0 || pTemplate->rSetup==0 + assert( p->rSetup==0 || pTemplate->rSetup==0 || p->rSetup==pTemplate->rSetup ); /* whereLoopAddBtree() always generates and inserts the automatic index @@ -2508,7 +2513,7 @@ ** rSetup. Call this SETUP-INVARIANT */ assert( p->rSetup>=pTemplate->rSetup ); - /* Any loop using an appliation-defined index (or PRIMARY KEY or + /* 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 @@ -2535,7 +2540,7 @@ /* If pTemplate is always better than p, then cause p to be overwritten ** with pTemplate. pTemplate is better than p if: - ** (1) pTemplate has no more dependences than p, and + ** (1) pTemplate has no more dependencies than p, and ** (2) pTemplate has an equal or lower cost than p. */ if( (p->prereq & pTemplate->prereq)==pTemplate->prereq /* (1) */ @@ -2565,7 +2570,7 @@ ** ** When accumulating multiple loops (when pBuilder->pOrSet is NULL) we ** still might overwrite similar loops with the new template if the -** new template is better. Loops may be overwritten if the following +** new template is better. Loops may be overwritten if the following ** conditions are met: ** ** (1) They have the same iTab. @@ -2623,7 +2628,7 @@ sqlite3WhereLoopPrint(pTemplate, pBuilder->pWC); } #endif - return SQLITE_OK; + return SQLITE_OK; }else{ p = *ppPrev; } @@ -2653,7 +2658,7 @@ }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 supplated by pTemplate */ + ** p[] that are also supplanted by pTemplate */ WhereLoop **ppTail = &p->pNextLoop; WhereLoop *pToDel; while( *ppTail ){ @@ -2783,7 +2788,7 @@ } } -/* +/* ** Term pTerm is a vector range comparison operation. The first comparison ** in the vector can be optimized using column nEq of the index. This ** function returns the total number of vector elements that can be used @@ -2812,7 +2817,7 @@ nCmp = MIN(nCmp, (pIdx->nColumn - nEq)); for(i=1; iop!=TK_COLUMN - || pLhs->iTable!=iCur - || pLhs->iColumn!=pIdx->aiColumn[i+nEq] + if( pLhs->op!=TK_COLUMN + || pLhs->iTable!=iCur + || pLhs->iColumn!=pIdx->aiColumn[i+nEq] || pIdx->aSortOrder[i+nEq]!=pIdx->aSortOrder[nEq] ){ break; @@ -2853,7 +2858,7 @@ } /* -** Adjust the cost C by the costMult facter T. This only occurs if +** Adjust the cost C by the costMult factor T. This only occurs if ** compiled with -DSQLITE_ENABLE_COSTMULT */ #ifdef SQLITE_ENABLE_COSTMULT @@ -2863,15 +2868,15 @@ #endif /* -** We have so far matched pBuilder->pNew->u.btree.nEq terms of the +** We have so far matched pBuilder->pNew->u.btree.nEq terms of the ** index pIndex. Try to match one more. ** -** When this function is called, pBuilder->pNew->nOut contains the -** number of rows expected to be visited by filtering using the nEq -** terms only. If it is modified, this value is restored before this +** When this function is called, pBuilder->pNew->nOut contains the +** number of rows expected to be visited by filtering using the nEq +** terms only. If it is modified, this value is restored before this ** function returns. ** -** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is +** If pProbe->idxType==SQLITE_IDXTYPE_IPK, that means pIndex is ** a fake index used for the INTEGER PRIMARY KEY. */ static int whereLoopAddBtreeIndex( @@ -2880,7 +2885,7 @@ Index *pProbe, /* An index on pSrc */ LogEst nInMul /* log(Number of iterations due to IN) */ ){ - WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyse context */ + WhereInfo *pWInfo = pBuilder->pWInfo; /* WHERE analyze context */ Parse *pParse = pWInfo->pParse; /* Parsing context */ sqlite3 *db = pParse->db; /* Database connection malloc context */ WhereLoop *pNew; /* Template WhereLoop under construction */ @@ -2979,9 +2984,9 @@ pNew->prereq = (saved_prereq | pTerm->prereqRight) & ~pNew->maskSelf; assert( nInMul==0 - || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 - || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 - || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 + || (pNew->wsFlags & WHERE_COLUMN_NULL)!=0 + || (pNew->wsFlags & WHERE_COLUMN_IN)!=0 + || (pNew->wsFlags & WHERE_SKIPSCAN)!=0 ); if( eOp & WO_IN ){ @@ -3008,7 +3013,7 @@ /* Let: ** N = the total number of rows in the table ** K = the number of entries on the RHS of the IN operator - ** M = the number of rows in the table that match terms to the + ** M = the number of rows in the table that match terms to the ** to the left in the same index. If the IN operator is on ** the left-most index column, M==N. ** @@ -3053,11 +3058,11 @@ int iCol = pProbe->aiColumn[saved_nEq]; pNew->wsFlags |= WHERE_COLUMN_EQ; assert( saved_nEq==pNew->u.btree.nEq ); - if( iCol==XN_ROWID + if( iCol==XN_ROWID || (iCol>=0 && nInMul==0 && saved_nEq==pProbe->nKeyCol-1) ){ - if( iCol==XN_ROWID || pProbe->uniqNotNull - || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) + if( iCol==XN_ROWID || pProbe->uniqNotNull + || (pProbe->nKeyCol==1 && pProbe->onError && eOp==WO_EQ) ){ pNew->wsFlags |= WHERE_ONEROW; }else{ @@ -3104,7 +3109,7 @@ /* At this point pNew->nOut is set to the number of rows expected to ** be visited by the index scan before considering term pTerm, or the - ** values of nIn and nInMul. In other words, assuming that all + ** values of nIn and nInMul. In other words, assuming that all ** "x IN(...)" terms are replaced with "x = ?". This block updates ** the value of pNew->nOut to account for pTerm (but not nIn/nInMul). */ assert( pNew->nOut==saved_nOut ); @@ -3125,8 +3130,8 @@ }else{ #ifdef SQLITE_ENABLE_STAT4 tRowcnt nOut = 0; - if( nInMul==0 - && pProbe->nSample + if( nInMul==0 + && pProbe->nSample && ALWAYS(pNew->u.btree.nEq<=pProbe->nSampleCol) && ((eOp & WO_IN)==0 || ExprUseXList(pTerm->pExpr)) && OptimizationEnabled(db, SQLITE_Stat4) @@ -3174,8 +3179,8 @@ { pNew->nOut += (pProbe->aiRowLogEst[nEq] - pProbe->aiRowLogEst[nEq-1]); if( eOp & WO_ISNULL ){ - /* TUNING: If there is no likelihood() value, assume that a - ** "col IS NULL" expression matches twice as many rows + /* TUNING: If there is no likelihood() value, assume that a + ** "col IS NULL" expression matches twice as many rows ** as (col=?). */ pNew->nOut += 10; } @@ -3190,7 +3195,7 @@ assert( pSrc->pTab->szTabRow>0 ); if( pProbe->idxType==SQLITE_IDXTYPE_IPK ){ /* The pProbe->szIdxRow is low for an IPK table since the interior - ** pages are small. Thuse szIdxRow gives a good estimate of seek cost. + ** pages are small. Thus szIdxRow gives a good estimate of seek cost. ** But the leaf pages are full-size, so pProbe->szIdxRow would badly ** under-estimate the scanning cost. */ rCostIdx = pNew->nOut + 16; @@ -3241,12 +3246,12 @@ /* Consider using a skip-scan if there are no WHERE clause constraints ** available for the left-most terms of the index, and if the average - ** number of repeats in the left-most terms is at least 18. + ** number of repeats in the left-most terms is at least 18. ** ** The magic number 18 is selected on the basis that scanning 17 rows ** is almost always quicker than an index seek (even though if the index ** contains fewer than 2^17 rows we assume otherwise in other parts of - ** the code). And, even if it is not, it should not be too much slower. + ** the code). And, even if it is not, it should not be too much slower. ** On the other hand, the extra seeks could end up being significantly ** more expensive. */ assert( 42==sqlite3LogEst(18) ); @@ -3393,7 +3398,7 @@ ** all columns less than 63 (really BMS-1) are covered, so we don't need ** to check them. But we do need to check any column at 63 or greater. ** -** If the index does not cover the column, then set pWalk->eCode to +** If the index does not cover the column, then set pWalk->eCode to ** non-zero and return WRC_Abort to stop the search. ** ** If this node does not disprove that the index can be a covering index, @@ -3498,6 +3503,100 @@ } /* +** This is an sqlite3ParserAddCleanup() callback that is invoked to +** free the Parse->pIdxEpr list when the Parse object is destroyed. +*/ +static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ + IndexedExpr **pp = (IndexedExpr**)pObject; + while( *pp!=0 ){ + IndexedExpr *p = *pp; + *pp = p->pIENext; + sqlite3ExprDelete(db, p->pExpr); + sqlite3DbFreeNN(db, p); + } +} + +/* +** This function is called for a partial index - one with a WHERE clause - in +** two scenarios. In both cases, it determines whether or not the WHERE +** clause on the index implies that a column of the table may be safely +** replaced by a constant expression. For example, in the following +** SELECT: +** +** CREATE INDEX i1 ON t1(b, c) WHERE a=; +** SELECT a, b, c FROM t1 WHERE a= AND b=?; +** +** The "a" in the select-list may be replaced by , iff: +** +** (a) is a constant expression, and +** (b) The (a=) comparison uses the BINARY collation sequence, and +** (c) Column "a" has an affinity other than NONE or BLOB. +** +** If argument pItem is NULL, then pMask must not be NULL. In this case this +** function is being called as part of determining whether or not pIdx +** is a covering index. This function clears any bits in (*pMask) +** corresponding to columns that may be replaced by constants as described +** above. +** +** Otherwise, if pItem is not NULL, then this function is being called +** as part of coding a loop that uses index pIdx. In this case, add entries +** to the Parse.pIdxPartExpr list for each column that can be replaced +** by a constant. +*/ +static void wherePartIdxExpr( + Parse *pParse, /* Parse context */ + Index *pIdx, /* Partial index being processed */ + Expr *pPart, /* WHERE clause being processed */ + Bitmask *pMask, /* Mask to clear bits in */ + int iIdxCur, /* Cursor number for index */ + SrcItem *pItem /* The FROM clause entry for the table */ +){ + assert( pItem==0 || (pItem->fg.jointype & JT_RIGHT)==0 ); + assert( (pItem==0 || pMask==0) && (pMask!=0 || pItem!=0) ); + + if( pPart->op==TK_AND ){ + wherePartIdxExpr(pParse, pIdx, pPart->pRight, pMask, iIdxCur, pItem); + pPart = pPart->pLeft; + } + + if( (pPart->op==TK_EQ || pPart->op==TK_IS) ){ + Expr *pLeft = pPart->pLeft; + Expr *pRight = pPart->pRight; + u8 aff; + + if( pLeft->op!=TK_COLUMN ) return; + if( !sqlite3ExprIsConstant(pRight) ) return; + if( !sqlite3IsBinary(sqlite3ExprCompareCollSeq(pParse, pPart)) ) return; + if( pLeft->iColumn<0 ) return; + aff = pIdx->pTable->aCol[pLeft->iColumn].affinity; + if( aff>=SQLITE_AFF_TEXT ){ + if( pItem ){ + sqlite3 *db = pParse->db; + IndexedExpr *p = (IndexedExpr*)sqlite3DbMallocRaw(db, sizeof(*p)); + if( p ){ + int bNullRow = (pItem->fg.jointype&(JT_LEFT|JT_LTORJ))!=0; + p->pExpr = sqlite3ExprDup(db, pRight, 0); + p->iDataCur = pItem->iCursor; + p->iIdxCur = iIdxCur; + p->iIdxCol = pLeft->iColumn; + p->bMaybeNullRow = bNullRow; + p->pIENext = pParse->pIdxPartExpr; + p->aff = aff; + pParse->pIdxPartExpr = p; + if( p->pIENext==0 ){ + void *pArg = (void*)&pParse->pIdxPartExpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } + }else if( pLeft->iColumn<(BMS-1) ){ + *pMask &= ~((Bitmask)1 << pLeft->iColumn); + } + } + } +} + + +/* ** Add all WhereLoop objects for a single table of the join where the table ** is identified by pBuilder->pNew->iTab. That table is guaranteed to be ** a b-tree table, not a virtual table. @@ -3511,18 +3610,18 @@ ** cost = nRow * K // scan of covering index ** cost = nRow * (K+3.0) // scan of non-covering index ** -** where K is a value between 1.1 and 3.0 set based on the relative +** where K is a value between 1.1 and 3.0 set based on the relative ** estimated average size of the index and table records. ** ** For an index scan, where nVisit is the number of index rows visited -** by the scan, and nSeek is the number of seek operations required on +** by the scan, and nSeek is the number of seek operations required on ** the index b-tree: ** ** cost = nSeek * (log(nRow) + K * nVisit) // covering index ** cost = nSeek * (log(nRow) + (K+3.0) * nVisit) // non-covering index ** -** Normally, nSeek is 1. nSeek values greater than 1 come about if the -** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when +** Normally, nSeek is 1. nSeek values greater than 1 come about if the +** WHERE clause includes "x IN (....)" terms used in place of "x=?". Or when ** implicit "x IN (SELECT x FROM tbl)" terms are added for skip-scans. ** ** The estimated values (nRow, nVisit, nSeek) often contain a large amount @@ -3535,7 +3634,7 @@ */ static int whereLoopAddBtree( WhereLoopBuilder *pBuilder, /* WHERE clause information */ - Bitmask mPrereq /* Extra prerequesites for using this table */ + Bitmask mPrereq /* Extra prerequisites for using this table */ ){ WhereInfo *pWInfo; /* WHERE analysis context */ Index *pProbe; /* An index we are evaluating */ @@ -3551,7 +3650,7 @@ LogEst rSize; /* number of rows in the table */ WhereClause *pWC; /* The parsed WHERE clause */ Table *pTab; /* Table being queried */ - + pNew = pBuilder->pNew; pWInfo = pBuilder->pWInfo; pTabList = pWInfo->pTabList; @@ -3649,9 +3748,9 @@ } #endif /* SQLITE_OMIT_AUTOMATIC_INDEX */ - /* Loop over all indices. If there was an INDEXED BY clause, then only + /* Loop over all indices. If there was an INDEXED BY clause, then only ** consider index pProbe. */ - for(; rc==SQLITE_OK && pProbe; + for(; rc==SQLITE_OK && pProbe; pProbe=(pSrc->fg.isIndexedBy ? 0 : pProbe->pNext), iSortIdx++ ){ if( pProbe->pPartIdxWhere!=0 @@ -3700,9 +3799,6 @@ #else pNew->rRun = rSize + 16; #endif - if( IsView(pTab) || (pTab->tabFlags & TF_Ephemeral)!=0 ){ - pNew->wsFlags |= WHERE_VIEWSCAN; - } ApplyCostMultiplier(pNew->rRun, pTab->costMult); whereLoopOutputAdjust(pWC, pNew, rSize); rc = whereLoopInsert(pBuilder, pNew); @@ -3715,6 +3811,11 @@ pNew->wsFlags = WHERE_IDX_ONLY | WHERE_INDEXED; }else{ m = pSrc->colUsed & pProbe->colNotIdxed; + if( pProbe->pPartIdxWhere ){ + wherePartIdxExpr( + pWInfo->pParse, pProbe, pProbe->pPartIdxWhere, &m, 0, 0 + ); + } pNew->wsFlags = WHERE_INDEXED; if( m==TOPBIT || (pProbe->bHasExpr && !pProbe->bHasVCol && m!=0) ){ u32 isCov = whereIsCoveringIndex(pWInfo, pProbe, pSrc->iCursor); @@ -3788,7 +3889,7 @@ if( pTerm->eOperator & (WO_EQ|WO_IS) ) nLookup -= 19; } } - + pNew->rRun = sqlite3LogEstAdd(pNew->rRun, nLookup); } ApplyCostMultiplier(pNew->rRun, pTab->costMult); @@ -3831,7 +3932,7 @@ */ static int isLimitTerm(WhereTerm *pTerm){ assert( pTerm->eOperator==WO_AUX || pTerm->eMatchOp==0 ); - return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT + return pTerm->eMatchOp>=SQLITE_INDEX_CONSTRAINT_LIMIT && pTerm->eMatchOp<=SQLITE_INDEX_CONSTRAINT_OFFSET; } @@ -3881,13 +3982,13 @@ *pbIn = 0; pNew->prereq = mPrereq; - /* Set the usable flag on the subset of constraints identified by + /* Set the usable flag on the subset of constraints identified by ** arguments mUsable and mExclude. */ pIdxCons = *(struct sqlite3_index_constraint**)&pIdxInfo->aConstraint; for(i=0; ia[pIdxCons->iTermOffset]; pIdxCons->usable = 0; - if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight + if( (pTerm->prereqRight & mUsable)==pTerm->prereqRight && (pTerm->eOperator & mExclude)==0 && (pbRetryLimit || !isLimitTerm(pTerm)) ){ @@ -3962,7 +4063,7 @@ pNew->u.vtab.bOmitOffset = 1; } } - if( SMASKBIT32(i) & pHidden->mHandleIn ){ + if( SMASKBIT32(i) & pHidden->mHandleIn ){ pNew->u.vtab.mHandleIn |= MASKBIT32(iTerm); }else if( (pTerm->eOperator & WO_IN)!=0 ){ /* A virtual table that is constrained by an IN clause may not @@ -4042,7 +4143,7 @@ ** ** Return a pointer to the collation name: ** -** 1. If there is an explicit COLLATE operator on the constaint, return it. +** 1. If there is an explicit COLLATE operator on the constraint, return it. ** ** 2. Else, if the column has an alternative collation, return that. ** @@ -4072,7 +4173,7 @@ HiddenIndexInfo *pHidden = (HiddenIndexInfo*)&pIdxInfo[1]; u32 m = SMASKBIT32(iCons); if( m & pHidden->mIn ){ - if( bHandle==0 ){ + if( bHandle==0 ){ pHidden->mHandleIn &= ~m; }else if( bHandle>0 ){ pHidden->mHandleIn |= m; @@ -4085,7 +4186,7 @@ /* ** This interface is callable from within the xBestIndex callback only. ** -** If possible, set (*ppVal) to point to an object containing the value +** If possible, set (*ppVal) to point to an object containing the value ** on the right-hand-side of constraint iCons. */ int sqlite3_vtab_rhs_value( @@ -4097,7 +4198,7 @@ sqlite3_value *pVal = 0; int rc = SQLITE_OK; if( iCons<0 || iCons>=pIdxInfo->nConstraint ){ - rc = SQLITE_MISUSE; /* EV: R-30545-25046 */ + rc = SQLITE_MISUSE_BKPT; /* EV: R-30545-25046 */ }else{ if( pH->aRhs[iCons]==0 ){ WhereTerm *pTerm = &pH->pWC->a[pIdxInfo->aConstraint[iCons].iTermOffset]; @@ -4158,8 +4259,8 @@ ** entries that occur before the virtual table in the FROM clause and are ** separated from it by at least one LEFT or CROSS JOIN. Similarly, the ** mUnusable mask contains all FROM clause entries that occur after the -** virtual table and are separated from it by at least one LEFT or -** CROSS JOIN. +** virtual table and are separated from it by at least one LEFT or +** CROSS JOIN. ** ** For example, if the query were: ** @@ -4167,9 +4268,9 @@ ** ** then mPrereq corresponds to (t1, t2) and mUnusable to (t5, t6). ** -** All the tables in mPrereq must be scanned before the current virtual -** table. So any terms for which all prerequisites are satisfied by -** mPrereq may be specified as "usable" in all calls to xBestIndex. +** All the tables in mPrereq must be scanned before the current virtual +** table. So any terms for which all prerequisites are satisfied by +** mPrereq may be specified as "usable" in all calls to xBestIndex. ** Conversely, all tables in mUnusable must be scanned after the current ** virtual table, so any terms for which the prerequisites overlap with ** mUnusable should always be configured as "not-usable" for xBestIndex. @@ -4226,7 +4327,7 @@ /* If the call to xBestIndex() with all terms enabled produced a plan ** that does not require any source tables (IOW: a plan with mBest==0) - ** and does not use an IN(...) operator, then there is no point in making + ** and does not use an IN(...) operator, then there is no point in making ** any further calls to xBestIndex() since they will all return the same ** result (if the xBestIndex() implementation is sane). */ if( rc==SQLITE_OK && ((mBest = (pNew->prereq & ~mPrereq))!=0 || bIn) ){ @@ -4249,7 +4350,7 @@ } } - /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) + /* Call xBestIndex once for each distinct value of (prereqRight & ~mPrereq) ** in the set of terms that apply to the current virtual table. */ while( rc==SQLITE_OK ){ int i; @@ -4306,8 +4407,8 @@ ** btrees or virtual tables. */ static int whereLoopAddOr( - WhereLoopBuilder *pBuilder, - Bitmask mPrereq, + WhereLoopBuilder *pBuilder, + Bitmask mPrereq, Bitmask mUnusable ){ WhereInfo *pWInfo = pBuilder->pWInfo; @@ -4320,7 +4421,7 @@ WhereLoopBuilder sSubBuild; WhereOrSet sSum, sCur; SrcItem *pItem; - + pWC = pBuilder->pWC; pWCEnd = pWC->a + pWC->nTerm; pNew = pBuilder->pNew; @@ -4333,14 +4434,14 @@ for(pTerm=pWC->a; pTermeOperator & WO_OR)!=0 - && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 + && (pTerm->u.pOrInfo->indexable & pNew->maskSelf)!=0 ){ WhereClause * const pOrWC = &pTerm->u.pOrInfo->wc; WhereTerm * const pOrWCEnd = &pOrWC->a[pOrWC->nTerm]; WhereTerm *pOrTerm; int once = 1; int i, j; - + sSubBuild = *pBuilder; sSubBuild.pOrSet = &sCur; @@ -4361,7 +4462,7 @@ } sCur.n = 0; #ifdef WHERETRACE_ENABLED - WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", + WHERETRACE(0x400, ("OR-term %d of %p has %d subterms:\n", (int)(pOrTerm-pOrWC->a), pTerm, sSubBuild.pWC->nTerm)); if( sqlite3WhereTrace & 0x20000 ){ sqlite3WhereClausePrint(sSubBuild.pWC); @@ -4409,8 +4510,8 @@ /* TUNING: Currently sSum.a[i].rRun is set to the sum of the costs ** of all sub-scans required by the OR-scan. However, due to rounding ** errors, it may be that the cost of the OR-scan is equal to its - ** most expensive sub-scan. Add the smallest possible penalty - ** (equivalent to multiplying the cost by 1.07) to ensure that + ** most expensive sub-scan. Add the smallest possible penalty + ** (equivalent to multiplying the cost by 1.07) to ensure that ** this does not happen. Otherwise, for WHERE clauses such as the ** following where there is an index on "y": ** @@ -4430,7 +4531,7 @@ } /* -** Add all WhereLoop objects for all tables +** Add all WhereLoop objects for all tables */ static int whereLoopAddAll(WhereLoopBuilder *pBuilder){ WhereInfo *pWInfo = pBuilder->pWInfo; @@ -4462,7 +4563,7 @@ pNew->iTab = iTab; pBuilder->iPlanLimit += SQLITE_QUERY_PLANNER_LIMIT_INCR; pNew->maskSelf = sqlite3WhereGetMask(&pWInfo->sMaskSet, pItem->iCursor); - if( bFirstPastRJ + if( bFirstPastRJ || (pItem->fg.jointype & (JT_OUTER|JT_CROSS|JT_LTORJ))!=0 ){ /* Add prerequisites to prevent reordering of FROM clause terms @@ -4518,17 +4619,17 @@ ** Examine a WherePath (with the addition of the extra WhereLoop of the 6th ** parameters) to see if it outputs rows in the requested ORDER BY ** (or GROUP BY) without requiring a separate sort operation. Return N: -** +** ** N>0: N terms of the ORDER BY clause are satisfied ** N==0: No terms of the ORDER BY clause are satisfied -** N<0: Unknown yet how many terms of ORDER BY might be satisfied. +** N<0: Unknown yet how many terms of ORDER BY might be satisfied. ** ** Note that processing for WHERE_GROUPBY and WHERE_DISTINCTBY is not as ** strict. With GROUP BY and DISTINCT the only requirement is that ** equivalent rows appear immediately adjacent to one another. GROUP BY ** and DISTINCT do not require rows to appear in any particular order as long ** as equivalent rows are grouped together. Thus for GROUP BY and DISTINCT -** the pOrderBy terms can be matched in any order. With ORDER BY, the +** the pOrderBy terms can be matched in any order. With ORDER BY, the ** pOrderBy terms must be matched in strict left-to-right order. */ static i8 wherePathSatisfiesOrderBy( @@ -4578,7 +4679,7 @@ ** row of the WhereLoop. Every one-row WhereLoop is automatically ** order-distinct. A WhereLoop that has no columns in the ORDER BY clause ** is not order-distinct. To be order-distinct is not quite the same as being - ** UNIQUE since a UNIQUE column or index can have multiple rows that + ** UNIQUE since a UNIQUE column or index can have multiple rows that ** are NULL and NULL values are equivalent for the purpose of order-distinct. ** To be order-distinct, the columns must be UNIQUE and NOT NULL. ** @@ -4610,7 +4711,7 @@ pLoop = pLast; } if( pLoop->wsFlags & WHERE_VIRTUALTABLE ){ - if( pLoop->u.vtab.isOrdered + if( pLoop->u.vtab.isOrdered && ((wctrlFlags&(WHERE_DISTINCTBY|WHERE_SORTBYGROUP))!=WHERE_DISTINCTBY) ){ obSat = obDone; @@ -4636,10 +4737,10 @@ ~ready, eqOpMask, 0); if( pTerm==0 ) continue; if( pTerm->eOperator==WO_IN ){ - /* IN terms are only valid for sorting in the ORDER BY LIMIT + /* IN terms are only valid for sorting in the ORDER BY LIMIT ** optimization, and then only if they are actually used ** by the query plan */ - assert( wctrlFlags & + assert( wctrlFlags & (WHERE_ORDERBY_LIMIT|WHERE_ORDERBY_MIN|WHERE_ORDERBY_MAX) ); for(j=0; jnLTerm && pTerm!=pLoop->aLTerm[j]; j++){} if( j>=pLoop->nLTerm ) continue; @@ -4686,7 +4787,7 @@ for(j=0; j=pLoop->u.btree.nEq + assert( j>=pLoop->u.btree.nEq || (pLoop->aLTerm[j]==0)==(jnSkip) ); if( ju.btree.nEq && j>=pLoop->nSkip ){ @@ -4698,7 +4799,7 @@ ** the loop need to be marked as not order-distinct because it can ** have repeated NULL rows. ** - ** If the current term is a column of an ((?,?) IN (SELECT...)) + ** If the current term is a column of an ((?,?) IN (SELECT...)) ** expression for which the SELECT returns more than one column, ** check that it is the only column used by this loop. Otherwise, ** if it is one of two or more, none of the columns can be @@ -4711,7 +4812,7 @@ testcase( isOrderDistinct ); isOrderDistinct = 0; } - continue; + continue; }else if( ALWAYS(eOp & WO_IN) ){ /* ALWAYS() justification: eOp is an equality operator due to the ** ju.btree.nEq constraint above. Any equality other @@ -4753,10 +4854,10 @@ if( iColumn==XN_EXPR ){ isOrderDistinct = 0; } - } + } /* Find the ORDER BY term that corresponds to the j-th column - ** of the index and mark that ORDER BY term off + ** of the index and mark that ORDER BY term off */ isMatch = 0; for(i=0; bOnce && ia[i].fg.sortFlags&KEYINFO_ORDER_DESC) ){ isMatch = 0; @@ -4899,7 +5000,7 @@ #endif /* -** Return the cost of sorting nRow rows, assuming that the keys have +** Return the cost of sorting nRow rows, assuming that the keys have ** nOrderby columns and that the first nSorted columns are already in ** order. */ @@ -4909,13 +5010,13 @@ int nOrderBy, /* Number of ORDER BY clause terms */ int nSorted /* Number of initial ORDER BY terms naturally in order */ ){ - /* Estimated cost of a full external sort, where N is + /* Estimated cost of a full external sort, where N is ** the number of rows to sort is: ** ** cost = (K * N * log(N)). - ** - ** Or, if the order-by clause has X terms but only the last Y - ** terms are out of order, then block-sorting will reduce the + ** + ** Or, if the order-by clause has X terms but only the last Y + ** terms are out of order, then block-sorting will reduce the ** sorting cost to: ** ** cost = (K * N * log(N)) * (Y/X) @@ -4923,8 +5024,8 @@ ** The constant K is at least 2.0 but will be larger if there are a ** large number of columns to be sorted, as the sorting time is ** proportional to the amount of content to be sorted. The algorithm - ** does not currently distinguish between fat columns (BLOBs and TEXTs) - ** and skinny columns (INTs). It just uses the number of columns as + ** does not currently distinguish between fat columns (BLOBs and TEXTs) + ** and skinny columns (INTs). It just uses the number of columns as ** an approximation for the row width. ** ** And extra factor of 2.0 or 3.0 is added to the sorting cost if the sort @@ -5003,7 +5104,8 @@ ** For joins of 3 or more tables, track the 10 best paths */ mxChoice = (nLoop<=1) ? 1 : (nLoop==2 ? 5 : 10); assert( nLoop<=pWInfo->pTabList->nSrc ); - WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d)\n", nRowEst)); + WHERETRACE(0x002, ("---- begin solver. (nRowEst=%d, nQueryLoop=%d)\n", + nRowEst, pParse->nQueryLoop)); /* If nRowEst is zero and there is an ORDER BY clause, ignore it. In this ** case the purpose of this call is to estimate the number of rows returned @@ -5033,7 +5135,7 @@ ** space for the aSortCost[] array. Each element of the aSortCost array ** is either zero - meaning it has not yet been initialized - or the ** cost of sorting nRowEst rows of data where the first X terms of - ** the ORDER BY clause are already in order, where X is the array + ** the ORDER BY clause are already in order, where X is the array ** index. */ aSortCost = (LogEst*)pX; memset(aSortCost, 0, sizeof(LogEst) * nOrderBy); @@ -5054,7 +5156,7 @@ ** in this case the query may return a maximum of one row, the results ** are already in the requested order. Set isOrdered to nOrderBy to ** indicate this. Or, if nLoop is greater than zero, set isOrdered to - ** -1, indicating that the result set may or may not be ordered, + ** -1, indicating that the result set may or may not be ordered, ** depending on the loops added to the current plan. */ aFrom[0].isOrdered = nLoop>0 ? -1 : nOrderBy; } @@ -5084,7 +5186,7 @@ continue; } - /* At this point, pWLoop is a candidate to be the next loop. + /* At this point, pWLoop is a candidate to be the next loop. ** Compute its cost */ rUnsorted = sqlite3LogEstAdd(pWLoop->rSetup,pWLoop->rRun + pFrom->nRow); rUnsorted = sqlite3LogEstAdd(rUnsorted, pFrom->rUnsorted); @@ -5106,27 +5208,20 @@ ); } /* TUNING: Add a small extra penalty (3) to sorting as an - ** extra encouragment to the query planner to select a plan + ** 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]) + 3; WHERETRACE(0x002, ("---- sort cost=%-3d (%d/%d) increases cost %3d to %-3d\n", - aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy, + aSortCost[isOrdered], (nOrderBy-isOrdered), nOrderBy, rUnsorted, rCost)); }else{ rCost = rUnsorted; rUnsorted -= 2; /* TUNING: Slight bias in favor of no-sort plans */ } - /* TUNING: A full-scan of a VIEW or subquery in the outer loop - ** is not so bad. */ - if( iLoop==0 && (pWLoop->wsFlags & WHERE_VIEWSCAN)!=0 ){ - rCost += -10; - nOut += -30; - } - /* Check to see if pWLoop should be added to the set of ** mxChoice best-so-far paths. ** @@ -5185,11 +5280,11 @@ ** same set of loops and has the same isOrdered setting as the ** candidate path. Check to see if the candidate should replace ** pTo or if the candidate should be skipped. - ** + ** ** The conditional is an expanded vector comparison equivalent to: ** (pTo->rCost,pTo->nRow,pTo->rUnsorted) <= (rCost,nOut,rUnsorted) */ - if( pTo->rCostrCostrCost==rCost && (pTo->nRownRow==nOut && pTo->rUnsorted<=rUnsorted) @@ -5240,8 +5335,8 @@ mxCost = aTo[0].rCost; mxUnsorted = aTo[0].nRow; for(jj=1, pTo=&aTo[1]; jjrCost>mxCost - || (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted) + if( pTo->rCost>mxCost + || (pTo->rCost==mxCost && pTo->rUnsorted>mxUnsorted) ){ mxCost = pTo->rCost; mxUnsorted = pTo->rUnsorted; @@ -5280,7 +5375,7 @@ sqlite3StackFreeNN(pParse->db, pSpace); return SQLITE_ERROR; } - + /* Find the lowest cost path. pFrom will be left pointing to that path */ pFrom = aFrom; for(ii=1; iinOBSat = 0; if( nLoop>0 ){ u32 wsFlags = pFrom->aLoop[nLoop-1]->wsFlags; - if( (wsFlags & WHERE_ONEROW)==0 + if( (wsFlags & WHERE_ONEROW)==0 && (wsFlags&(WHERE_IPK|WHERE_COLUMN_IN))!=(WHERE_IPK|WHERE_COLUMN_IN) ){ Bitmask m = 0; @@ -5348,7 +5443,7 @@ && pWInfo->nOBSat==pWInfo->pOrderBy->nExpr && nLoop>0 ){ Bitmask revMask = 0; - int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, + int nOrder = wherePathSatisfiesOrderBy(pWInfo, pWInfo->pOrderBy, pFrom, 0, nLoop-1, pFrom->aLoop[nLoop-1], &revMask ); assert( pWInfo->sorted==0 ); @@ -5375,7 +5470,7 @@ ** times for the common case. ** ** Return non-zero on success, if this query can be handled by this -** no-frills query planner. Return zero if this query needs the +** no-frills query planner. Return zero if this query needs the ** general-purpose query planner. */ static int whereShortCut(WhereLoopBuilder *pBuilder){ @@ -5421,8 +5516,8 @@ int opMask; assert( pLoop->aLTermSpace==pLoop->aLTerm ); if( !IsUniqueIndex(pIdx) - || pIdx->pPartIdxWhere!=0 - || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) + || pIdx->pPartIdxWhere!=0 + || pIdx->nKeyCol>ArraySize(pLoop->aLTermSpace) ) continue; opMask = pIdx->uniqNotNull ? (WO_EQ|WO_IS) : WO_EQ; for(j=0; jnKeyCol; j++){ @@ -5482,8 +5577,8 @@ } /* -** Return true if the expression contains no non-deterministic SQL -** functions. Do not consider non-deterministic SQL functions that are +** Return true if the expression contains no non-deterministic SQL +** functions. Do not consider non-deterministic SQL functions that are ** part of sub-select statements. */ static int exprIsDeterministic(Expr *p){ @@ -5496,7 +5591,7 @@ return w.eCode; } - + #ifdef WHERETRACE_ENABLED /* ** Display all WhereLoops in pWInfo @@ -5524,7 +5619,7 @@ ** 1) The query must not be an aggregate. ** 2) The table must be the RHS of a LEFT JOIN. ** 3) Either the query must be DISTINCT, or else the ON or USING clause -** must contain a constraint that limits the scan of the table to +** must contain a constraint that limits the scan of the table to ** at most a single row. ** 4) The table must not be referenced by any part of the query apart ** from its own USING or ON clause. @@ -5544,13 +5639,13 @@ ** ** then table t2 can be omitted from the following: ** -** SELECT v1, v3 FROM t1 +** SELECT v1, v3 FROM t1 ** LEFT JOIN t2 ON (t1.ipk=t2.ipk) ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) ** ** or from: ** -** SELECT DISTINCT v1, v3 FROM t1 +** SELECT DISTINCT v1, v3 FROM t1 ** LEFT JOIN t2 ** LEFT JOIN t3 ON (t1.ipk=t3.ipk) */ @@ -5677,20 +5772,6 @@ } /* -** This is an sqlite3ParserAddCleanup() callback that is invoked to -** free the Parse->pIdxEpr list when the Parse object is destroyed. -*/ -static void whereIndexedExprCleanup(sqlite3 *db, void *pObject){ - Parse *pParse = (Parse*)pObject; - while( pParse->pIdxEpr!=0 ){ - IndexedExpr *p = pParse->pIdxEpr; - pParse->pIdxEpr = p->pIENext; - sqlite3ExprDelete(db, p->pExpr); - sqlite3DbFreeNN(db, p); - } -} - -/* ** The index pIdx is used by a query and contains one or more expressions. ** In other words pIdx is an index on an expression. iIdxCur is the cursor ** number for the index and iDataCur is the cursor number for the corresponding @@ -5751,7 +5832,30 @@ #endif pParse->pIdxEpr = p; if( p->pIENext==0 ){ - sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pParse); + void *pArg = (void*)&pParse->pIdxEpr; + sqlite3ParserAddCleanup(pParse, whereIndexedExprCleanup, pArg); + } + } +} + +/* +** Set the reverse-scan order mask to one for all tables in the query +** with the exception of MATERIALIZED common table expressions that have +** their own internal ORDER BY clauses. +** +** This implements the PRAGMA reverse_unordered_selects=ON setting. +** (Also SQLITE_DBCONFIG_REVERSE_SCANORDER). +*/ +static SQLITE_NOINLINE void whereReverseScanOrder(WhereInfo *pWInfo){ + int ii; + for(ii=0; iipTabList->nSrc; ii++){ + SrcItem *pItem = &pWInfo->pTabList->a[ii]; + if( !pItem->fg.isCte + || pItem->u2.pCteUse->eM10d!=M10d_Yes + || NEVER(pItem->pSelect==0) + || pItem->pSelect->pOrderBy==0 + ){ + pWInfo->revMask |= MASKBIT(ii); } } } @@ -5814,7 +5918,7 @@ ** ** OUTER JOINS ** -** An outer join of tables t1 and t2 is conceptally coded as follows: +** An outer join of tables t1 and t2 is conceptually coded as follows: ** ** foreach row1 in t1 do ** flag = 0 @@ -5836,7 +5940,7 @@ ** if there is one. If there is no ORDER BY clause or if this routine ** is called from an UPDATE or DELETE statement, then pOrderBy is NULL. ** -** The iIdxCur parameter is the cursor number of an index. If +** The iIdxCur parameter is the cursor number of an index. If ** WHERE_OR_SUBCLAUSE is set, iIdxCur is the cursor number of an index ** to use for OR clause processing. The WHERE clause should use this ** specific cursor. If WHERE_ONEPASS_DESIRED is set, then iIdxCur is @@ -5870,8 +5974,8 @@ u8 bFordelete = 0; /* OPFLAG_FORDELETE or zero, as appropriate */ assert( (wctrlFlags & WHERE_ONEPASS_MULTIROW)==0 || ( - (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 - && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 + (wctrlFlags & WHERE_ONEPASS_DESIRED)!=0 + && (wctrlFlags & WHERE_OR_SUBCLAUSE)==0 )); /* Only one of WHERE_OR_SUBCLAUSE or WHERE_USE_LIMIT */ @@ -5887,7 +5991,7 @@ if( pOrderBy && pOrderBy->nExpr>=BMS ) pOrderBy = 0; /* The number of tables in the FROM clause is limited by the number of - ** bits in a Bitmask + ** bits in a Bitmask */ testcase( pTabList->nSrc==BMS ); if( pTabList->nSrc>BMS ){ @@ -5895,7 +5999,7 @@ return 0; } - /* This function normally generates a nested loop for all tables in + /* This function normally generates a nested loop for all tables in ** pTabList. But if the WHERE_OR_SUBCLAUSE flag is set, then we should ** only generate code for the first table in pTabList and assume that ** any cursors associated with subsequent tables are uninitialized. @@ -5930,7 +6034,7 @@ pWInfo->iLimit = iAuxArg; pWInfo->savedNQueryLoop = pParse->nQueryLoop; pWInfo->pSelect = pSelect; - memset(&pWInfo->nOBSat, 0, + memset(&pWInfo->nOBSat, 0, offsetof(WhereInfo,sWC) - offsetof(WhereInfo,nOBSat)); memset(&pWInfo->a[0], 0, sizeof(WhereLoop)+nTabList*sizeof(WhereLevel)); assert( pWInfo->eOnePass==ONEPASS_OFF ); /* ONEPASS defaults to OFF */ @@ -5953,7 +6057,7 @@ */ sqlite3WhereClauseInit(&pWInfo->sWC, pWInfo); sqlite3WhereSplit(&pWInfo->sWC, pWhere, TK_AND); - + /* Special case: No FROM clause */ if( nTabList==0 ){ @@ -5969,7 +6073,7 @@ ** ** The N-th term of the FROM clause is assigned a bitmask of 1<sWC); if( pSelect && pSelect->pLimit ){ @@ -6099,7 +6203,7 @@ ** loops will be built using the revised truthProb values. */ if( sWLB.bldFlags2 & SQLITE_BLDF2_2NDPASS ){ WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); - WHERETRACE(0xffffffff, + WHERETRACE(0xffffffff, ("**** Redo all loop computations due to" " TERM_HIGHTRUTH changes ****\n")); while( pWInfo->pLoops ){ @@ -6112,16 +6216,27 @@ } #endif WHERETRACE_ALL_LOOPS(pWInfo, sWLB.pWC); - + wherePathSolver(pWInfo, 0); if( db->mallocFailed ) goto whereBeginError; if( pWInfo->pOrderBy ){ wherePathSolver(pWInfo, pWInfo->nRowOut+1); if( db->mallocFailed ) goto whereBeginError; } + + /* TUNING: Assume that a DISTINCT clause on a subquery reduces + ** the output size by a factor of 8 (LogEst -30). + */ + if( (pWInfo->wctrlFlags & WHERE_WANT_DISTINCT)!=0 ){ + WHERETRACE(0x0080,("nRowOut reduced from %d to %d due to DISTINCT\n", + pWInfo->nRowOut, pWInfo->nRowOut-30)); + pWInfo->nRowOut -= 30; + } + } + assert( pWInfo->pTabList!=0 ); if( pWInfo->pOrderBy==0 && (db->flags & SQLITE_ReverseOrder)!=0 ){ - pWInfo->revMask = ALLBITS; + whereReverseScanOrder(pWInfo); } if( pParse->nErr ){ goto whereBeginError; @@ -6160,7 +6275,7 @@ ** This query optimization is factored out into a separate "no-inline" ** procedure to keep the sqlite3WhereBegin() procedure from becoming ** too large. If sqlite3WhereBegin() becomes too large, that prevents - ** some C-compiler optimizers from in-lining the + ** some C-compiler optimizers from in-lining the ** sqlite3WhereCodeOneLoopStart() procedure, and it is important to ** in-line sqlite3WhereCodeOneLoopStart() for performance reasons. */ @@ -6221,6 +6336,7 @@ 0!=(wctrlFlags & WHERE_ONEPASS_MULTIROW) && !IsVirtual(pTabList->a[0].pTab) && (0==(wsFlags & WHERE_MULTI_OR) || (wctrlFlags & WHERE_DUPLICATES_OK)) + && OptimizationEnabled(db, SQLITE_OnePass) )){ pWInfo->eOnePass = bOnerow ? ONEPASS_SINGLE : ONEPASS_MULTI; if( HasRowid(pTabList->a[0].pTab) && (wsFlags & WHERE_IDX_ONLY) ){ @@ -6269,7 +6385,7 @@ assert( pTabItem->iCursor==pLevel->iTabCur ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS-1 ); testcase( pWInfo->eOnePass==ONEPASS_OFF && pTab->nCol==BMS ); - if( pWInfo->eOnePass==ONEPASS_OFF + if( pWInfo->eOnePass==ONEPASS_OFF && pTab->nColtabFlags & (TF_HasGenerated|TF_WithoutRowid))==0 && (pLoop->wsFlags & (WHERE_AUTO_INDEX|WHERE_BLOOMFILTER))==0 @@ -6329,6 +6445,11 @@ if( pIx->bHasExpr && OptimizationEnabled(db, SQLITE_IndexedExpr) ){ whereAddIndexedExpr(pParse, pIx, iIndexCur, pTabItem); } + if( pIx->pPartIdxWhere && (pTabItem->fg.jointype & JT_RIGHT)==0 ){ + wherePartIdxExpr( + pParse, pIx, pIx->pPartIdxWhere, 0, iIndexCur, pTabItem + ); + } } pLevel->iIdxCur = iIndexCur; assert( pIx!=0 ); @@ -6498,7 +6619,7 @@ #endif /* SQLITE_DEBUG */ /* -** Generate the end of the WHERE loop. See comments on +** Generate the end of the WHERE loop. See comments on ** sqlite3WhereBegin() for additional information. */ void sqlite3WhereEnd(WhereInfo *pWInfo){ @@ -6584,7 +6705,7 @@ sqlite3VdbeJumpHere(v, pIn->addrInTop+1); if( pIn->eEndLoopOp!=OP_Noop ){ if( pIn->nPrefix ){ - int bEarlyOut = + int bEarlyOut = (pLoop->wsFlags & WHERE_VIRTUALTABLE)==0 && (pLoop->wsFlags & WHERE_IN_EARLYOUT)!=0; if( pLevel->iLeftJoin ){ @@ -6596,7 +6717,7 @@ ** return the null-row. So, if the cursor is not open yet, ** jump over the OP_Next or OP_Prev instruction about to ** be coded. */ - sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, + sqlite3VdbeAddOp2(v, OP_IfNotOpen, pIn->iCur, sqlite3VdbeCurrentAddr(v) + 2 + bEarlyOut); VdbeCoverage(v); } @@ -6605,7 +6726,7 @@ sqlite3VdbeCurrentAddr(v)+2, pIn->iBase, pIn->nPrefix); VdbeCoverage(v); - /* Retarget the OP_IsNull against the left operand of IN so + /* Retarget the OP_IsNull against the left operand of IN so ** it jumps past the OP_IfNoHope. This is because the ** OP_IsNull also bypasses the OP_Affinity opcode that is ** required by OP_IfNoHope. */ @@ -6646,8 +6767,8 @@ assert( pLevel->iTabCur==pTabList->a[pLevel->iFrom].iCursor ); sqlite3VdbeAddOp1(v, OP_NullRow, pLevel->iTabCur); } - if( (ws & WHERE_INDEXED) - || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx) + if( (ws & WHERE_INDEXED) + || ((ws & WHERE_MULTI_OR) && pLevel->u.pCoveringIdx) ){ if( ws & WHERE_MULTI_OR ){ Index *pIx = pLevel->u.pCoveringIdx; @@ -6702,7 +6823,7 @@ ** from the index instead of from the table where possible. In some cases ** this optimization prevents the table from ever being read, which can ** yield a significant performance boost. - ** + ** ** Calls to the code generator in between sqlite3WhereBegin and ** sqlite3WhereEnd will have created code that references the table ** directly. This loop scans all that code looking for opcodes diff -Nru sqlite3-3.42.0/src/wherecode.c sqlite3-3.44.0-0/src/wherecode.c --- sqlite3-3.42.0/src/wherecode.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/wherecode.c 2023-11-04 14:23:58.000000000 +0000 @@ -71,7 +71,7 @@ } /* -** Argument pLevel describes a strategy for scanning table pTab. This +** Argument pLevel describes a strategy for scanning table pTab. This ** function appends text to pStr that describes the subset of table ** rows scanned by the strategy in the form of an SQL expression. ** @@ -111,7 +111,7 @@ /* ** This function is a no-op unless currently processing an EXPLAIN QUERY PLAN -** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG +** command, or if stmt_scanstatus_v2() stats are enabled, or if SQLITE_DEBUG ** was defined at compile-time. If it is not a no-op, a single OP_Explain ** opcode is added to the output to describe the table scan strategy in pLevel. ** @@ -279,11 +279,11 @@ #ifdef SQLITE_ENABLE_STMT_SCANSTATUS /* ** Configure the VM passed as the first argument with an -** sqlite3_stmt_scanstatus() entry corresponding to the scan used to -** implement level pLvl. Argument pSrclist is a pointer to the FROM +** sqlite3_stmt_scanstatus() entry corresponding to the scan used to +** implement level pLvl. Argument pSrclist is a pointer to the FROM ** clause that the scan reads data from. ** -** If argument addrExplain is not 0, it must be the address of an +** If argument addrExplain is not 0, it must be the address of an ** OP_Explain instruction that describes the same loop. */ void sqlite3WhereAddScanStatus( @@ -315,6 +315,12 @@ if( wsFlags & WHERE_INDEXED ){ sqlite3VdbeScanStatusRange(v, addrExplain, -1, pLvl->iIdxCur); } + }else{ + int addr = pSrclist->a[pLvl->iFrom].addrFillSub; + VdbeOp *pOp = sqlite3VdbeGetOp(v, addr-1); + assert( sqlite3VdbeDb(v)->mallocFailed || pOp->opcode==OP_InitCoroutine ); + assert( sqlite3VdbeDb(v)->mallocFailed || pOp->p2>addr ); + sqlite3VdbeScanStatusRange(v, addrExplain, addr, pOp->p2-1); } } } @@ -354,7 +360,7 @@ ** ** Only the parent term was in the original WHERE clause. The child1 ** and child2 terms were added by the LIKE optimization. If both of -** the virtual child terms are valid, then testing of the parent can be +** the virtual child terms are valid, then testing of the parent can be ** skipped. ** ** Usually the parent term is marked as TERM_CODED. But if the parent @@ -392,7 +398,7 @@ /* ** Code an OP_Affinity opcode to apply the column affinity string zAff -** to the n registers starting at base. +** to the n registers starting at base. ** ** As an optimization, SQLITE_AFF_BLOB and SQLITE_AFF_NONE entries (which ** are no-ops) at the beginning and end of zAff are ignored. If all entries @@ -429,7 +435,7 @@ } /* -** Expression pRight, which is the RHS of a comparison operation, is +** Expression pRight, which is the RHS of a comparison operation, is ** either a vector of n elements or, if n==1, a scalar expression. ** Before the comparison operation, affinity zAff is to be applied ** to the pRight values. This function modifies characters within the @@ -540,12 +546,12 @@ pNew->pLeft = p; } if( pSelect->pOrderBy ){ - /* If the SELECT statement has an ORDER BY clause, zero the - ** iOrderByCol variables. These are set to non-zero when an - ** ORDER BY term exactly matches one of the terms of the + /* If the SELECT statement has an ORDER BY clause, zero the + ** iOrderByCol variables. These are set to non-zero when an + ** ORDER BY term exactly matches one of the terms of the ** result-set. Since the result-set of the SELECT statement may - ** have been modified or reordered, these variables are no longer - ** set correctly. Since setting them is just an optimization, + ** have been modified or reordered, these variables are no longer + ** set correctly. Since setting them is just an optimization, ** it's easiest just to zero them here. */ ExprList *pOrderBy = pSelect->pOrderBy; for(i=0; inExpr; i++){ @@ -567,7 +573,7 @@ /* ** Generate code for a single equality term of the WHERE clause. An equality -** term can be either X=expr or X IN (...). pTerm is the term to be +** term can be either X=expr or X IN (...). pTerm is the term to be ** coded. ** ** The current value for the constraint is left in a register, the index @@ -708,7 +714,7 @@ testcase( iEq>0 && (pLoop->wsFlags & WHERE_IN_SEEKSCAN)==0 && (pLoop->wsFlags & WHERE_VIRTUALTABLE)!=0 ); - if( iEq>0 + if( iEq>0 && (pLoop->wsFlags & (WHERE_IN_SEEKSCAN|WHERE_VIRTUALTABLE))==0 ){ sqlite3VdbeAddOp3(v, OP_SeekHit, pLevel->iIdxCur, 0, iEq); @@ -745,7 +751,7 @@ ** For example, consider table t1(a,b,c,d,e,f) with index i1(a,b,c). ** Suppose the WHERE clause is this: a==5 AND b IN (1,2,3) AND c>5 AND c<10 ** The index has as many as three equality constraints, but in this -** example, the third "c" value is an inequality. So only two +** example, the third "c" value is an inequality. So only two ** constraints are coded. This routine will generate code to evaluate ** a==5 and b IN (1,2,3). The current values for a and b will be stored ** in consecutive registers and the index of the first register is returned. @@ -812,7 +818,7 @@ /* Figure out how many memory cells we will need then allocate them. */ regBase = pParse->nMem + 1; - nReg = pLoop->u.btree.nEq + nExtraReg; + nReg = nEq + nExtraReg; pParse->nMem += nReg; zAff = sqlite3DbStrDup(pParse->db,sqlite3IndexAffinityStr(pParse->db,pIdx)); @@ -837,7 +843,7 @@ testcase( pIdx->aiColumn[j]==XN_EXPR ); VdbeComment((v, "%s", explainIndexColumnName(pIdx, j))); } - } + } /* Evaluate the equality constraints */ @@ -846,7 +852,7 @@ int r1; pTerm = pLoop->aLTerm[j]; assert( pTerm!=0 ); - /* The following testcase is true for indices with redundant columns. + /* The following testcase is true for indices with redundant columns. ** Ex: CREATE INDEX i1 ON t1(a,b,a); SELECT * FROM t1 WHERE a=0 AND b=0; */ testcase( (pTerm->wtFlags & TERM_CODED)!=0 ); testcase( pTerm->wtFlags & TERM_VIRTUAL ); @@ -859,14 +865,11 @@ sqlite3VdbeAddOp2(v, OP_Copy, r1, regBase+j); } } - } - for(j=nSkip; jaLTerm[j]; if( pTerm->eOperator & WO_IN ){ if( pTerm->pExpr->flags & EP_xIsSelect ){ /* No affinity ever needs to be (or should be) applied to a value - ** from the RHS of an "? IN (SELECT ...)" expression. The - ** sqlite3FindInIndex() routine has already ensured that the + ** from the RHS of an "? IN (SELECT ...)" expression. The + ** sqlite3FindInIndex() routine has already ensured that the ** affinity of the comparison has been applied to the value. */ if( zAff ) zAff[j] = SQLITE_AFF_BLOB; } @@ -894,7 +897,7 @@ #ifndef SQLITE_LIKE_DOESNT_MATCH_BLOBS /* ** If the most recently coded instruction is a constant range constraint -** (a string literal) that originated from the LIKE optimization, then +** (a string literal) that originated from the LIKE optimization, then ** set P3 and P5 on the OP_String opcode so that the string will be cast ** to a BLOB at appropriate times. ** @@ -919,7 +922,7 @@ assert( pLevel->iLikeRepCntr>0 ); pOp = sqlite3VdbeGetLastOp(v); assert( pOp!=0 ); - assert( pOp->opcode==OP_String8 + assert( pOp->opcode==OP_String8 || pTerm->pWC->pWInfo->pParse->db->mallocFailed ); pOp->p3 = (int)(pLevel->iLikeRepCntr>>1); /* Register holding counter */ pOp->p5 = (u8)(pLevel->iLikeRepCntr&1); /* ASC or DESC */ @@ -962,7 +965,7 @@ /* ** Test whether or not expression pExpr, which was part of a WHERE clause, ** should be included in the cursor-hint for a table that is on the rhs -** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the +** of a LEFT JOIN. Set Walker.eCode to non-zero before returning if the ** expression is not suitable. ** ** An expression is unsuitable if it might evaluate to non NULL even if @@ -975,9 +978,9 @@ ** CASE WHEN col THEN 0 ELSE 1 END */ static int codeCursorHintIsOrFunction(Walker *pWalker, Expr *pExpr){ - if( pExpr->op==TK_IS - || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT - || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE + if( pExpr->op==TK_IS + || pExpr->op==TK_ISNULL || pExpr->op==TK_ISNOT + || pExpr->op==TK_NOTNULL || pExpr->op==TK_CASE ){ pWalker->eCode = 1; }else if( pExpr->op==TK_FUNCTION ){ @@ -998,13 +1001,13 @@ ** that accesses any table other than the one identified by ** CCurHint.iTabCur, then do the following: ** -** 1) allocate a register and code an OP_Column instruction to read +** 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 +** 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 idenified +** 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. @@ -1073,18 +1076,18 @@ if( pTerm->wtFlags & (TERM_VIRTUAL|TERM_CODED) ) continue; if( pTerm->prereqAll & pLevel->notReady ) continue; - /* Any terms specified as part of the ON(...) clause for any LEFT + /* Any terms specified as part of the ON(...) clause for any LEFT ** JOIN for which the current table is not the rhs are omitted - ** from the cursor-hint. + ** from the cursor-hint. ** - ** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms + ** If this table is the rhs of a LEFT JOIN, "IS" or "IS NULL" terms ** that were specified as part of the WHERE clause must be excluded. ** This is to address the following: ** ** SELECT ... t1 LEFT JOIN t2 ON (t1.a=t2.b) WHERE t2.c IS NULL; ** ** Say there is a single row in t2 that matches (t1.a=t2.b), but its - ** t2.c values is not NULL. If the (t2.c IS NULL) constraint is + ** t2.c values is not NULL. If the (t2.c IS NULL) constraint is ** pushed down to the cursor, this row is filtered out, causing ** SQLite to synthesize a row of NULL values. Which does match the ** WHERE clause, and so the query returns a row. Which is incorrect. @@ -1097,7 +1100,7 @@ */ if( pTabItem->fg.jointype & JT_LEFT ){ Expr *pExpr = pTerm->pExpr; - if( !ExprHasProperty(pExpr, EP_OuterON) + if( !ExprHasProperty(pExpr, EP_OuterON) || pExpr->w.iJoin!=pTabItem->iCursor ){ sWalker.eCode = 0; @@ -1135,7 +1138,7 @@ if( pExpr!=0 ){ sWalker.xExprCallback = codeCursorHintFixExpr; if( pParse->nErr==0 ) sqlite3WalkExpr(&sWalker, pExpr); - sqlite3VdbeAddOp4(v, OP_CursorHint, + sqlite3VdbeAddOp4(v, OP_CursorHint, (sHint.pIdx ? sHint.iIdxCur : sHint.iTabCur), 0, 0, (const char*)pExpr, P4_EXPR); } @@ -1147,7 +1150,7 @@ /* ** Cursor iCur is open on an intkey b-tree (a table). Register iRowid contains ** a rowid value just read from cursor iIdxCur, open on index pIdx. This -** function generates code to do a deferred seek of cursor iCur to the +** function generates code to do a deferred seek of cursor iCur to the ** rowid stored in register iRowid. ** ** Normally, this is just: @@ -1181,7 +1184,7 @@ assert( iIdxCur>0 ); assert( pIdx->aiColumn[pIdx->nColumn-1]==-1 ); - + pWInfo->bDeferredSeek = 1; sqlite3VdbeAddOp3(v, OP_DeferredSeek, iIdxCur, 0, iCur); if( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN)) @@ -1518,7 +1521,7 @@ } } - /* Generate code that will continue to the next row if + /* Generate code that will continue to the next row if ** the IN constraint is not satisfied */ pCompare = sqlite3PExpr(pParse, TK_EQ, 0, 0); @@ -1611,7 +1614,7 @@ int r1, rTemp; /* Registers for holding the start boundary */ int op; /* Cursor seek operation */ - /* The following constant maps TK_xx codes into corresponding + /* The following constant maps TK_xx codes into corresponding ** seek opcodes. It depends on a particular ordering of TK_xx */ const u8 aMoveOp[] = { @@ -1622,7 +1625,7 @@ }; 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 correcct. */ + assert( TK_GE==TK_GT+3 ); /* ... is correct. */ assert( (pStart->wtFlags & TERM_VNULL)==0 ); testcase( pStart->wtFlags & TERM_VIRTUAL ); @@ -1667,8 +1670,8 @@ testcase( pEnd->wtFlags & TERM_VIRTUAL ); memEndValue = ++pParse->nMem; codeExprOrVector(pParse, pX->pRight, memEndValue, 1); - if( 0==sqlite3ExprIsVector(pX->pRight) - && (pX->op==TK_LT || pX->op==TK_GT) + if( 0==sqlite3ExprIsVector(pX->pRight) + && (pX->op==TK_LT || pX->op==TK_GT) ){ testOp = bRev ? OP_Le : OP_Ge; }else{ @@ -1696,14 +1699,14 @@ }else if( pLoop->wsFlags & WHERE_INDEXED ){ /* Case 4: A scan using an index. ** - ** The WHERE clause may contain zero or more equality + ** The WHERE clause may contain zero or more equality ** terms ("==" or "IN" operators) that refer to the N ** left-most columns of the index. It may also contain ** inequality constraints (>, <, >= or <=) on the indexed - ** column that immediately follows the N equalities. Only + ** column that immediately follows the N equalities. Only ** the right-most column can be an inequality - the rest must - ** use the "==" and "IN" operators. For example, if the - ** index is on (x,y,z), then the following clauses are all + ** use the "==" and "IN" operators. For example, if the + ** index is on (x,y,z), then the following clauses are all ** optimized: ** ** x=5 @@ -1724,7 +1727,7 @@ ** This case is also used when there are no WHERE clause ** constraints but an index is selected anyway, in order ** to force the output order to conform to an ORDER BY. - */ + */ static const u8 aStartOp[] = { 0, 0, @@ -1766,15 +1769,15 @@ iIdxCur = pLevel->iIdxCur; assert( nEq>=pLoop->nSkip ); - /* Find any inequality constraint terms for the start and end - ** of the range. + /* Find any inequality constraint terms for the start and end + ** of the range. */ j = nEq; if( pLoop->wsFlags & WHERE_BTM_LIMIT ){ pRangeStart = pLoop->aLTerm[j++]; nExtraReg = MAX(nExtraReg, pLoop->u.btree.nBtm); /* Like optimization range constraints always occur in pairs */ - assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || + assert( (pRangeStart->wtFlags & TERM_LIKEOPT)==0 || (pLoop->wsFlags & WHERE_TOP_LIMIT)!=0 ); } if( pLoop->wsFlags & WHERE_TOP_LIMIT ){ @@ -1807,7 +1810,7 @@ assert( pRangeEnd==0 || (pRangeEnd->wtFlags & TERM_VNULL)==0 ); /* If the WHERE_BIGNULL_SORT flag is set, then index column nEq uses - ** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS + ** a non-default "big-null" sort (either ASC NULLS LAST or DESC NULLS ** FIRST). In both cases separate ordered scans are made of those ** index entries for which the column is null and for those for which ** it is not. For an ASC sort, the non-NULL entries are scanned first. @@ -1829,7 +1832,7 @@ } /* If we are doing a reverse order scan on an ascending index, or - ** a forward order scan on a descending index, interchange the + ** a forward order scan on a descending index, interchange the ** start and end terms (pRangeStart and pRangeEnd). */ if( (nEqnColumn && bRev==(pIdx->aSortOrder[nEq]==SQLITE_SO_ASC)) ){ @@ -1878,7 +1881,7 @@ } if( zStartAff ){ updateRangeAffinityStr(pRight, nBtm, &zStartAff[nEq]); - } + } nConstraint += nBtm; testcase( pRangeStart->wtFlags & TERM_VIRTUAL ); if( sqlite3ExprIsVector(pRight)==0 ){ @@ -1926,7 +1929,7 @@ ** of entries in the tree, so basing the number of steps to try ** on the estimated number of rows in the btree seems like a good ** guess. */ - addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, + addrSeekScan = sqlite3VdbeAddOp1(v, OP_SeekScan, (pIdx->aiRowLogEst[0]+9)/10); if( pRangeStart || pRangeEnd ){ sqlite3VdbeChangeP5(v, 1); @@ -1951,7 +1954,7 @@ assert( bStopAtNull==startEq ); sqlite3VdbeAddOp2(v, OP_Goto, 0, sqlite3VdbeCurrentAddr(v)+2); op = aStartOp[(nConstraint>1)*4 + 2 + bRev]; - sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, + sqlite3VdbeAddOp4Int(v, op, iIdxCur, addrNxt, regBase, nConstraint-startEq); VdbeCoverage(v); VdbeCoverageIf(v, op==OP_Rewind); testcase( op==OP_Rewind ); @@ -2044,7 +2047,7 @@ } /* Seek the table cursor, if required */ - omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 + omitTable = (pLoop->wsFlags & WHERE_IDX_ONLY)!=0 && (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0; if( omitTable ){ /* pIdx is a covering index. No need to access the main table. */ @@ -2079,7 +2082,7 @@ ** a LEFT JOIN: */ assert( (pWInfo->wctrlFlags & (WHERE_OR_SUBCLAUSE|WHERE_RIGHT_JOIN))==0 ); } - + /* Record the instruction used to terminate the loop. */ if( pLoop->wsFlags & WHERE_ONEROW ){ pLevel->op = OP_Noop; @@ -2188,15 +2191,15 @@ pOrTab = pWInfo->pTabList; } - /* Initialize the rowset register to contain NULL. An SQL NULL is + /* Initialize the rowset register to contain NULL. An SQL NULL is ** equivalent to an empty rowset. Or, create an ephemeral index ** capable of holding primary keys in the case of a WITHOUT ROWID. ** - ** Also initialize regReturn to contain the address of the instruction + ** Also initialize regReturn to contain the address of the instruction ** immediately following the OP_Return at the bottom of the loop. This ** is required in a few obscure LEFT JOIN cases where control jumps - ** over the top of the loop into the body of it. In this case the - ** correct response for the end-of-loop code (the OP_Return) is to + ** over the top of the loop into the body of it. In this case the + ** correct response for the end-of-loop code (the OP_Return) is to ** fall through to the next instruction, just as an OP_Next does if ** called on an uninitialized cursor. */ @@ -2221,7 +2224,7 @@ ** ** Actually, each subexpression is converted to "xN AND w" where w is ** the "interesting" terms of z - terms that did not originate in the - ** ON or USING clause of a LEFT JOIN, and terms that are usable as + ** ON or USING clause of a LEFT JOIN, and terms that are usable as ** indices. ** ** This optimization also only applies if the (x1 OR x2 OR ...) term @@ -2262,7 +2265,7 @@ /* The extra 0x10000 bit on the opcode is masked off and does not ** become part of the new Expr.op. However, it does make the ** op==TK_AND comparison inside of sqlite3PExpr() false, and this - ** prevents sqlite3PExpr() from applying the AND short-circuit + ** prevents sqlite3PExpr() from applying the AND short-circuit ** optimization, which we do not want here. */ pAndExpr = sqlite3PExpr(pParse, TK_AND|0x10000, 0, pAndExpr); } @@ -2338,9 +2341,9 @@ ** ** Use some of the same optimizations as OP_RowSetTest: If iSet ** is zero, assume that the key cannot already be present in - ** the temp table. And if iSet is -1, assume that there is no - ** need to insert the key into the temp table, as it will never - ** be tested for. */ + ** the temp table. And if iSet is -1, assume that there is no + ** need to insert the key into the temp table, as it will never + ** be tested for. */ if( iSet ){ jmp1 = sqlite3VdbeAddOp4Int(v, OP_Found, regRowset, 0, r, nPk); VdbeCoverage(v); @@ -2379,8 +2382,8 @@ ** If the call to sqlite3WhereBegin() above resulted in a scan that ** uses an index, and this is either the first OR-connected term ** processed or the index is the same as that used by all previous - ** terms, set pCov to the candidate covering index. Otherwise, set - ** pCov to NULL to indicate that no candidate covering index will + ** terms, set pCov to the candidate covering index. Otherwise, set + ** pCov to NULL to indicate that no candidate covering index will ** be available. */ pSubLoop = pSubWInfo->a[0].pWLoop; @@ -2467,7 +2470,7 @@ ** ** iLoop==1: Code only expressions that are entirely covered by pIdx. ** iLoop==2: Code remaining expressions that do not contain correlated - ** sub-queries. + ** sub-queries. ** iLoop==3: Code all remaining expressions. ** ** An effort is made to skip unnecessary iterations of the loop. @@ -2578,7 +2581,7 @@ WO_EQ|WO_IN|WO_IS, 0); if( pAlt==0 ) continue; if( pAlt->wtFlags & (TERM_CODED) ) continue; - if( (pAlt->eOperator & WO_IN) + if( (pAlt->eOperator & WO_IN) && ExprUseXSelect(pAlt->pExpr) && (pAlt->pExpr->x.pSelect->pEList->nExpr>1) ){ @@ -2636,7 +2639,7 @@ } /* For a LEFT OUTER JOIN, generate code that will record the fact that - ** at least one row of the right table has matched the left table. + ** at least one row of the right table has matched the left table. */ if( pLevel->iLeftJoin ){ pLevel->addrFirst = sqlite3VdbeCurrentAddr(v); diff -Nru sqlite3-3.42.0/src/whereexpr.c sqlite3-3.44.0-0/src/whereexpr.c --- sqlite3-3.42.0/src/whereexpr.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/whereexpr.c 2023-11-04 14:23:58.000000000 +0000 @@ -13,7 +13,7 @@ ** the WHERE clause of SQL statements. ** ** This file was originally part of where.c but was split out to improve -** readability and editabiliity. This file contains utility routines for +** readability and editability. This file contains utility routines for ** analyzing Expr objects in the WHERE clause. */ #include "sqliteInt.h" @@ -229,7 +229,7 @@ ** range search. The third is because the caller assumes that the pattern ** consists of at least one character after all escapes have been ** removed. */ - if( cnt!=0 && 255!=(u8)z[cnt-1] && (cnt>1 || z[0]!=wc[3]) ){ + if( (cnt>1 || (cnt>0 && z[0]!=wc[3])) && 255!=(u8)z[cnt-1] ){ Expr *pPrefix; /* A "complete" match if the pattern ends with "*" or "%" */ @@ -263,8 +263,8 @@ ** 2019-06-14 https://sqlite.org/src/info/ce8717f0885af975 ** 2019-09-03 https://sqlite.org/src/info/0f0428096f17252a */ - if( pLeft->op!=TK_COLUMN - || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT + if( pLeft->op!=TK_COLUMN + || sqlite3ExprAffinity(pLeft)!=SQLITE_AFF_TEXT || (ALWAYS( ExprUseYTab(pLeft) ) && ALWAYS(pLeft->y.pTab) && IsVirtual(pLeft->y.pTab)) /* Might be numeric */ @@ -302,7 +302,7 @@ ** function, then no OP_Variable will be added to the program. ** This causes problems for the sqlite3_bind_parameter_name() ** API. To work around them, add a dummy OP_Variable here. - */ + */ int r1 = sqlite3GetTempReg(pParse); sqlite3ExprCodeTarget(pParse, pRight, r1); sqlite3VdbeChangeP3(v, sqlite3VdbeCurrentAddr(v)-1, 0); @@ -339,7 +339,7 @@ ** 9. column IS NOT NULL SQLITE_INDEX_CONSTRAINT_ISNOTNULL ** ** In every case, "column" must be a column of a virtual table. If there -** is a match, set *ppLeft to the "column" expression, set *ppRight to the +** is a match, set *ppLeft to the "column" expression, set *ppRight to the ** "expr" expression (even though in forms (6) and (8) the column is on the ** right and the expression is on the left). Also set *peOp2 to the ** appropriate virtual table operator. The return value is 1 or 2 if there @@ -507,7 +507,7 @@ ** ** The following is NOT generated: ** -** xy --> x!=y +** xy --> x!=y */ static void whereCombineDisjuncts( SrcList *pSrc, /* the FROM clause */ @@ -605,10 +605,10 @@ ** WhereTerm.u.pOrInfo->indexable |= the cursor number for table T ** ** A subterm is "indexable" if it is of the form -** "T.C " where C is any column of table T and +** "T.C " where C is any column of table T and ** is one of "=", "<", "<=", ">", ">=", "IS NULL", or "IN". ** A subterm is also indexable if it is an AND of two or more -** subsubterms at least one of which is indexable. Indexable AND +** subsubterms at least one of which is indexable. Indexable AND ** subterms have their eOperator set to WO_AND and they have ** u.pAndInfo set to a dynamically allocated WhereAndTerm object. ** @@ -700,7 +700,7 @@ if( !db->mallocFailed ){ for(j=0, pAndTerm=pAndWC->a; jnTerm; j++, pAndTerm++){ assert( pAndTerm->pExpr ); - if( allowedOp(pAndTerm->pExpr->op) + if( allowedOp(pAndTerm->pExpr->op) || pAndTerm->eOperator==WO_AUX ){ b |= sqlite3WhereGetMask(&pWInfo->sMaskSet, pAndTerm->leftCursor); @@ -802,7 +802,7 @@ 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 follwed by an inverted copy (t2.b==t1.a). Skip this term + ** 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 ); @@ -833,7 +833,7 @@ assert( (pOrTerm->eOperator & (WO_OR|WO_AND))==0 ); if( pOrTerm->leftCursor!=iCursor ){ pOrTerm->wtFlags &= ~TERM_OK; - }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR + }else if( pOrTerm->u.x.leftColumn!=iColumn || (iColumn==XN_EXPR && sqlite3ExprCompare(pParse, pOrTerm->pExpr->pLeft, pLeft, -1) )){ okToChngToIN = 0; @@ -855,7 +855,7 @@ } /* At this point, okToChngToIN is true if original pTerm satisfies - ** case 1. In that case, construct a new virtual term that is + ** case 1. In that case, construct a new virtual term that is ** pTerm converted into an IN operator. */ if( okToChngToIN ){ @@ -988,7 +988,7 @@ for(i=0; inKeyCol; i++){ if( pIdx->aiColumn[i]!=XN_EXPR ) continue; assert( pIdx->bHasExpr ); - if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 + if( sqlite3ExprCompareSkip(pExpr,pIdx->aColExpr->a[i].pExpr,iCur)==0 && pExpr->op!=TK_STRING ){ aiCurCol[0] = iCur; @@ -1008,8 +1008,8 @@ ){ int i; - /* If this expression is a vector to the left or right of a - ** inequality constraint (>, <, >= or <=), perform the processing + /* If this expression is a vector to the left or right of a + ** inequality constraint (>, <, >= or <=), perform the processing ** on the first element of the vector. */ assert( TK_GT+1==TK_LE && TK_GT+2==TK_LT && TK_GT+3==TK_GE ); assert( TK_ISpLeft */ - Bitmask prereqAll; /* Prerequesites of pExpr */ + Bitmask prereqLeft; /* Prerequisites of the pExpr->pLeft */ + Bitmask prereqAll; /* Prerequisites of pExpr */ Bitmask extraRight = 0; /* Extra dependencies on LEFT JOIN */ Expr *pStr1 = 0; /* RHS of LIKE/GLOB operator */ int isComplete = 0; /* RHS of LIKE/GLOB ends with wildcard */ @@ -1166,7 +1166,7 @@ pTerm->eOperator = operatorMask(op) & opMask; } if( op==TK_IS ) pTerm->wtFlags |= TERM_IS; - if( pRight + if( pRight && exprMightBeIndexed(pSrc, aiCurCol, pRight, op) && !ExprHasProperty(pRight, EP_FixedCol) ){ @@ -1205,7 +1205,7 @@ pNew->prereqRight = prereqLeft | extraRight; pNew->prereqAll = prereqAll; pNew->eOperator = (operatorMask(pDup->op) + eExtraOp) & opMask; - }else + }else if( op==TK_ISNULL && !ExprHasProperty(pExpr,EP_OuterON) && 0==sqlite3ExprCanBeNull(pLeft) @@ -1246,7 +1246,7 @@ for(i=0; i<2; i++){ Expr *pNewExpr; int idxNew; - pNewExpr = sqlite3PExpr(pParse, ops[i], + pNewExpr = sqlite3PExpr(pParse, ops[i], sqlite3ExprDup(db, pExpr->pLeft, 0), sqlite3ExprDup(db, pList->a[i].pExpr, 0)); transferJoinMarkings(pNewExpr, pExpr); @@ -1284,11 +1284,11 @@ Expr *pLeft = pExpr->pLeft; int idxNew; WhereTerm *pNewTerm; - + pNewExpr = sqlite3PExpr(pParse, TK_GT, sqlite3ExprDup(db, pLeft, 0), sqlite3ExprAlloc(db, TK_NULL, 0, 0)); - + idxNew = whereClauseInsert(pWC, pNewExpr, TERM_VIRTUAL|TERM_DYNAMIC|TERM_VNULL); if( idxNew ){ @@ -1338,7 +1338,7 @@ pStr2 = sqlite3ExprDup(db, pStr1, 0); assert( pStr1==0 || !ExprHasProperty(pStr1, EP_IntValue) ); assert( pStr2==0 || !ExprHasProperty(pStr2, EP_IntValue) ); - + /* Convert the lower bound to upper-case and the upper bound to ** lower-case (upper-case is less than lower-case in ASCII) so that @@ -1361,7 +1361,7 @@ if( noCase ){ /* The point is to increment the last character before the first ** wildcard. But if we increment '@', that will push it into the - ** alphabetic range where case conversions will mess up the + ** alphabetic range where case conversions will mess up the ** inequality. To avoid this, make sure to also run the full ** LIKE on all candidate expressions by clearing the isComplete flag */ @@ -1408,7 +1408,7 @@ if( (pExpr->op==TK_EQ || pExpr->op==TK_IS) && (nLeft = sqlite3ExprVectorSize(pExpr->pLeft))>1 && sqlite3ExprVectorSize(pExpr->pRight)==nLeft - && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 + && ( (pExpr->pLeft->flags & EP_xIsSelect)==0 || (pExpr->pRight->flags & EP_xIsSelect)==0) && pWC->op==TK_AND ){ @@ -1431,7 +1431,7 @@ /* If there is a vector IN term - e.g. "(a, b) IN (SELECT ...)" - create ** a virtual term for each vector component. The expression object - ** used by each such virtual term is pExpr (the full vector IN(...) + ** used by each such virtual term is pExpr (the full vector IN(...) ** expression). The WhereTerm.u.x.iField variable identifies the index within ** the vector on the LHS that the virtual term represents. ** @@ -1480,7 +1480,7 @@ prereqColumn = sqlite3WhereExprUsage(pMaskSet, pLeft); if( (prereqExpr & prereqColumn)==0 ){ Expr *pNewExpr; - pNewExpr = sqlite3PExpr(pParse, TK_MATCH, + pNewExpr = sqlite3PExpr(pParse, TK_MATCH, 0, sqlite3ExprDup(db, pRight, 0)); if( ExprHasProperty(pExpr, EP_OuterON) && pNewExpr ){ ExprSetProperty(pNewExpr, EP_OuterON); @@ -1548,12 +1548,12 @@ } /* -** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or -** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the +** Add either a LIMIT (if eMatchOp==SQLITE_INDEX_CONSTRAINT_LIMIT) or +** OFFSET (if eMatchOp==SQLITE_INDEX_CONSTRAINT_OFFSET) term to the ** where-clause passed as the first argument. The value for the term ** is found in register iReg. ** -** In the common case where the value is a simple integer +** In the common case where the value is a simple integer ** (example: "LIMIT 5 OFFSET 10") then the expression codes as a ** TK_INTEGER so that it will be available to sqlite3_vtab_rhs_value(). ** If not, then it codes as a TK_REGISTER expression. @@ -1633,7 +1633,7 @@ if( pWC->a[ii].nChild ){ /* If this term has child terms, then they are also part of the ** pWC->a[] array. So this term can be ignored, as a LIMIT clause - ** will only be added if each of the child terms passes the + ** will only be added if each of the child terms passes the ** (leftCursor==iCsr) test below. */ continue; } @@ -1798,7 +1798,7 @@ /* -** Call exprAnalyze on all terms in a WHERE clause. +** Call exprAnalyze on all terms in a WHERE clause. ** ** Note that exprAnalyze() might add new virtual terms onto the ** end of the WHERE clause. We do not want to analyze these new @@ -1817,7 +1817,7 @@ /* ** For table-valued-functions, transform the function arguments into -** new WHERE clause terms. +** new WHERE clause terms. ** ** Each function argument translates into an equality constraint against ** a HIDDEN column in the table. @@ -1853,7 +1853,7 @@ assert( ExprUseYTab(pColRef) ); pColRef->y.pTab = pTab; pItem->colUsed |= sqlite3ExprColUsed(pColRef); - pRhs = sqlite3PExpr(pParse, TK_UPLUS, + pRhs = sqlite3PExpr(pParse, TK_UPLUS, sqlite3ExprDup(pParse->db, pArgs->a[j].pExpr, 0), 0); pTerm = sqlite3PExpr(pParse, TK_EQ, pColRef, pRhs); if( pItem->fg.jointype & (JT_LEFT|JT_RIGHT) ){ diff -Nru sqlite3-3.42.0/src/whereInt.h sqlite3-3.44.0-0/src/whereInt.h --- sqlite3-3.42.0/src/whereInt.h 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/whereInt.h 2023-11-04 14:23:58.000000000 +0000 @@ -37,7 +37,7 @@ /* ** This object is a header on a block of allocated memory that will be -** automatically freed when its WInfo oject is destructed. +** automatically freed when its WInfo object is destructed. */ struct WhereMemBlock { WhereMemBlock *pNext; /* Next block in the chain */ @@ -98,7 +98,7 @@ int iCur; /* The VDBE cursor used by this IN operator */ int addrInTop; /* Top of the IN loop */ int iBase; /* Base register of multi-key index record */ - int nPrefix; /* Number of prior entires in the key */ + int nPrefix; /* Number of prior entries in the key */ u8 eEndLoopOp; /* IN Loop terminator. OP_Next or OP_Prev */ } *aInLoop; /* Information about each nested IN operator */ } in; /* Used when pWLoop->wsFlags&WHERE_IN_ABLE */ @@ -167,7 +167,7 @@ /* This object holds the prerequisites and the cost of running a ** subquery on one operand of an OR operator in the WHERE clause. -** See WhereOrSet for additional information +** See WhereOrSet for additional information */ struct WhereOrCost { Bitmask prereq; /* Prerequisites */ @@ -219,7 +219,7 @@ ** clause subexpression is separated from the others by AND operators, ** usually, or sometimes subexpressions separated by OR. ** -** All WhereTerms are collected into a single WhereClause structure. +** All WhereTerms are collected into a single WhereClause structure. ** The following identity holds: ** ** WhereTerm.pWC->a[WhereTerm.idx] == WhereTerm @@ -348,7 +348,7 @@ int nTerm; /* Number of terms */ int nSlot; /* Number of entries in a[] */ int nBase; /* Number of terms through the last non-Virtual */ - WhereTerm *a; /* Each a[] describes a term of the WHERE cluase */ + WhereTerm *a; /* Each a[] describes a term of the WHERE clause */ #if defined(SQLITE_SMALL_STACK) WhereTerm aStatic[1]; /* Initial static space for a[] */ #else @@ -377,8 +377,8 @@ ** An instance of the following structure keeps track of a mapping ** between VDBE cursor numbers and bits of the bitmasks in WhereTerm. ** -** The VDBE cursor numbers are small integers contained in -** SrcItem.iCursor and Expr.iTable fields. For any given WHERE +** The VDBE cursor numbers are small integers contained in +** SrcItem.iCursor and Expr.iTable fields. For any given WHERE ** clause, the cursor numbers might not begin with 0 and they might ** contain gaps in the numbering sequence. But we want to make maximum ** use of the bits in our bitmasks. This structure provides a mapping @@ -633,7 +633,7 @@ #define WHERE_BLOOMFILTER 0x00400000 /* Consider using a Bloom-filter */ #define WHERE_SELFCULL 0x00800000 /* nOut reduced by extra WHERE terms */ #define WHERE_OMIT_OFFSET 0x01000000 /* Set offset counter to zero */ -#define WHERE_VIEWSCAN 0x02000000 /* A full-scan of a VIEW or subquery */ + /* 0x02000000 -- available for reuse */ #define WHERE_EXPRIDX 0x04000000 /* Uses an index-on-expressions */ #endif /* !defined(SQLITE_WHEREINT_H) */ diff -Nru sqlite3-3.42.0/src/window.c sqlite3-3.44.0-0/src/window.c --- sqlite3-3.42.0/src/window.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/src/window.c 2023-11-04 14:23:58.000000000 +0000 @@ -40,12 +40,12 @@ ** (in this case max()) to process rows sorted in order of (c, d), which ** makes things easier for obvious reasons. More generally: ** -** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to +** * FROM, WHERE, GROUP BY and HAVING clauses are all moved to ** the sub-query. ** ** * ORDER BY, LIMIT and OFFSET remain part of the parent query. ** -** * Terminals from each of the expression trees that make up the +** * Terminals from each of the expression trees that make up the ** select-list and ORDER BY expressions in the parent query are ** selected by the sub-query. For the purposes of the transformation, ** terminals are column references and aggregate functions. @@ -54,14 +54,14 @@ ** the same window declaration (the OVER bit), then a single scan may ** be used to process more than one window function. For example: ** -** SELECT max(b) OVER (PARTITION BY c ORDER BY d), -** min(e) OVER (PARTITION BY c ORDER BY d) +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY c ORDER BY d) ** FROM t1; ** ** is transformed in the same way as the example above. However: ** -** SELECT max(b) OVER (PARTITION BY c ORDER BY d), -** min(e) OVER (PARTITION BY a ORDER BY b) +** SELECT max(b) OVER (PARTITION BY c ORDER BY d), +** min(e) OVER (PARTITION BY a ORDER BY b) ** FROM t1; ** ** Must be transformed to: @@ -114,15 +114,15 @@ ** first_value(expr) ** last_value(expr) ** nth_value(expr, N) -** -** These are the same built-in window functions supported by Postgres. +** +** These are the same built-in window functions supported by Postgres. ** Although the behaviour of aggregate window functions (functions that -** can be used as either aggregates or window funtions) allows them to +** 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()) +** 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 +** window functions and some are implemented directly using VDBE ** instructions. Additionally, for those functions that use the API, the ** window frame is sometimes modified before the SELECT statement is ** rewritten. For example, regardless of the specified window frame, the @@ -134,7 +134,7 @@ ** ** As well as some of the built-in window functions, aggregate window ** functions min() and max() are implemented using VDBE instructions if -** the start of the window frame is declared as anything other than +** the start of the window frame is declared as anything other than ** UNBOUNDED PRECEDING. */ @@ -145,7 +145,7 @@ ** ROWS BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW */ static void row_numberStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -173,10 +173,10 @@ ** Implementation of built-in window function dense_rank(). Assumes that ** the window frame has been set to: ** -** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW */ static void dense_rankStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -208,7 +208,7 @@ sqlite3_value *pValue; }; static void nth_valueStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -261,7 +261,7 @@ #define nth_valueValueFunc noopValueFunc static void first_valueStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -292,10 +292,10 @@ ** Implementation of built-in window function rank(). Assumes that ** the window frame has been set to: ** -** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW +** RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW */ static void rankStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -326,7 +326,7 @@ ** GROUPS BETWEEN CURRENT ROW AND UNBOUNDED FOLLOWING */ static void percent_rankStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -339,7 +339,7 @@ } } static void percent_rankInvFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -371,7 +371,7 @@ ** GROUPS BETWEEN 1 FOLLOWING AND UNBOUNDED FOLLOWING */ static void cume_distStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -384,7 +384,7 @@ } } static void cume_distInvFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -420,7 +420,7 @@ ** ROWS CURRENT ROW AND UNBOUNDED FOLLOWING */ static void ntileStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -440,7 +440,7 @@ } } static void ntileInvFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -486,7 +486,7 @@ ** Implementation of last_value(). */ static void last_valueStepFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -504,7 +504,7 @@ } } static void last_valueInvFunc( - sqlite3_context *pCtx, + sqlite3_context *pCtx, int nArg, sqlite3_value **apArg ){ @@ -647,7 +647,7 @@ ** is the Window object representing the associated OVER clause. This ** function updates the contents of pWin as follows: ** -** * If the OVER clause refered to a named window (as in "max(x) OVER win"), +** * If the OVER clause referred to a named window (as in "max(x) OVER win"), ** search list pList for a matching WINDOW definition, and update pWin ** accordingly. If no such WINDOW clause can be found, leave an error ** in pParse. @@ -657,7 +657,7 @@ ** of this file), pWin is updated here. */ void sqlite3WindowUpdate( - Parse *pParse, + Parse *pParse, Window *pList, /* List of named windows for this SELECT */ Window *pWin, /* Window frame to update */ FuncDef *pFunc /* Window function definition */ @@ -677,17 +677,17 @@ sqlite3WindowChain(pParse, pWin, pList); } if( (pWin->eFrmType==TK_RANGE) - && (pWin->pStart || pWin->pEnd) + && (pWin->pStart || pWin->pEnd) && (pWin->pOrderBy==0 || pWin->pOrderBy->nExpr!=1) ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "RANGE with offset PRECEDING/FOLLOWING requires one ORDER BY expression" ); }else if( pFunc->funcFlags & SQLITE_FUNC_WINDOW ){ sqlite3 *db = pParse->db; if( pWin->pFilter ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "FILTER clause may only be used with aggregate window functions" ); }else{ @@ -697,14 +697,14 @@ int eStart; int eEnd; } aUp[] = { - { row_numberName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, - { dense_rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, - { rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, - { percent_rankName, TK_GROUPS, TK_CURRENT, TK_UNBOUNDED }, - { cume_distName, TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, - { ntileName, TK_ROWS, TK_CURRENT, TK_UNBOUNDED }, - { leadName, TK_ROWS, TK_UNBOUNDED, TK_UNBOUNDED }, - { lagName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, + { row_numberName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, + { dense_rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, + { rankName, TK_RANGE, TK_UNBOUNDED, TK_CURRENT }, + { percent_rankName, TK_GROUPS, TK_CURRENT, TK_UNBOUNDED }, + { cume_distName, TK_GROUPS, TK_FOLLOWING, TK_UNBOUNDED }, + { ntileName, TK_ROWS, TK_CURRENT, TK_UNBOUNDED }, + { leadName, TK_ROWS, TK_UNBOUNDED, TK_UNBOUNDED }, + { lagName, TK_ROWS, TK_UNBOUNDED, TK_CURRENT }, }; int i; for(i=0; iiEphCsr, where N is the number of elements in (*ppSub) after ** appending the new one. */ static void selectWindowRewriteEList( - Parse *pParse, + Parse *pParse, Window *pWin, SrcList *pSrc, ExprList *pEList, /* Rewrite expressions in this list */ @@ -950,7 +950,7 @@ /* ** If the SELECT statement passed as the second argument does not invoke -** any SQL window functions, this function is a no-op. Otherwise, it +** any SQL window functions, this function is a no-op. Otherwise, it ** rewrites the SELECT statement so that window function xStep functions ** are invoked in the correct order as described under "SELECT REWRITING" ** at the top of this file. @@ -1023,8 +1023,8 @@ selectWindowRewriteEList(pParse, pMWin, pSrc, p->pOrderBy, pTab, &pSublist); pMWin->nBufferCol = (pSublist ? pSublist->nExpr : 0); - /* Append the PARTITION BY and ORDER BY expressions to the to the - ** sub-select expression list. They are required to figure out where + /* Append the PARTITION BY and ORDER BY expressions to the to the + ** sub-select expression list. They are required to figure out where ** boundaries for partitions and sets of peer rows lie. */ pSublist = exprListAppendList(pParse, pSublist, pMWin->pPartition, 0); pSublist = exprListAppendList(pParse, pSublist, pMWin->pOrderBy, 0); @@ -1058,11 +1058,11 @@ /* If there is no ORDER BY or PARTITION BY clause, and the window ** function accepts zero arguments, and there are no other columns ** selected (e.g. "SELECT row_number() OVER () FROM t1"), it is possible - ** that pSublist is still NULL here. Add a constant expression here to - ** keep everything legal in this case. + ** that pSublist is still NULL here. Add a constant expression here to + ** keep everything legal in this case. */ if( pSublist==0 ){ - pSublist = sqlite3ExprListAppend(pParse, 0, + pSublist = sqlite3ExprListAppend(pParse, 0, sqlite3Expr(db, TK_INTEGER, "0") ); } @@ -1248,10 +1248,10 @@ ** equivalent nul-terminated string. */ Window *sqlite3WindowAssemble( - Parse *pParse, - Window *pWin, - ExprList *pPartition, - ExprList *pOrderBy, + Parse *pParse, + Window *pWin, + ExprList *pPartition, + ExprList *pOrderBy, Token *pBase ){ if( pWin ){ @@ -1268,7 +1268,7 @@ } /* -** Window *pWin has just been created from a WINDOW clause. Tokne pBase +** 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 @@ -1289,7 +1289,7 @@ zErr = "frame specification"; } if( zErr ){ - sqlite3ErrorMsg(pParse, + sqlite3ErrorMsg(pParse, "cannot override %s of window: %s", zErr, pWin->zBase ); }else{ @@ -1312,8 +1312,9 @@ if( p ){ assert( p->op==TK_FUNCTION ); assert( pWin ); + assert( ExprIsFullSize(p) ); p->y.pWin = pWin; - ExprSetProperty(p, EP_WinFunc); + ExprSetProperty(p, EP_WinFunc|EP_FullSize); pWin->pOwner = p; if( (p->flags & EP_Distinct) && pWin->eFrmType!=TK_FILTER ){ sqlite3ErrorMsg(pParse, @@ -1540,7 +1541,7 @@ }; /* -** A single instance of this structure is allocated on the stack by +** A single instance of this structure is allocated on the stack by ** sqlite3WindowCodeStep() and a pointer to it passed to the various helper ** routines. This is to reduce the number of arguments required by each ** helper function. @@ -1574,7 +1575,7 @@ ** ** (ORDER BY a, b GROUPS BETWEEN 2 PRECEDING AND 2 FOLLOWING) ** -** The windows functions implmentation caches the input rows in a temp +** 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 @@ -1587,7 +1588,7 @@ ** ** Each cursor (start, current and end) consists of a VDBE cursor ** (WindowCsrAndReg.csr) and an array of registers (starting at -** WindowCodeArg.reg) that always contains a copy of the peer values +** WindowCodeArg.reg) that always contains a copy of the peer values ** read from the corresponding cursor. ** ** Depending on the window-frame in question, all three cursors may not @@ -1632,8 +1633,8 @@ } /* -** Generate VM code to invoke either xStep() (if bInverse is 0) or -** xInverse (if bInverse is non-zero) for each window function in the +** Generate VM code to invoke either xStep() (if bInverse is 0) or +** xInverse (if bInverse is non-zero) for each window function in the ** linked list starting at pMWin. Or, for built-in window functions ** that do not use the standard function API, generate the required ** inline VM code. @@ -1682,7 +1683,7 @@ regArg = reg; if( pMWin->regStartRowid==0 - && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) + && (pFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) ){ int addrIsNull = sqlite3VdbeAddOp1(v, OP_IsNull, regArg); @@ -1718,7 +1719,7 @@ VdbeCoverage(v); sqlite3ReleaseTempReg(pParse, regTmp); } - + if( pWin->bExprArgs ){ int iOp = sqlite3VdbeCurrentAddr(v); int iEnd; @@ -1742,7 +1743,7 @@ pColl = sqlite3ExprNNCollSeq(pParse, pWin->pOwner->x.pList->a[0].pExpr); sqlite3VdbeAddOp4(v, OP_CollSeq, 0,0,0, (const char*)pColl, P4_COLLSEQ); } - sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, + sqlite3VdbeAddOp3(v, bInverse? OP_AggInverse : OP_AggStep, bInverse, regArg, pWin->regAccum); sqlite3VdbeAppendP4(v, pFunc, P4_FUNCDEF); sqlite3VdbeChangeP5(v, (u8)nArg); @@ -1775,7 +1776,7 @@ for(pWin=pMWin; pWin; pWin=pWin->pNextWin){ if( pMWin->regStartRowid==0 - && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX) + && (pWin->pWFunc->funcFlags & SQLITE_FUNC_MINMAX) && (pWin->eStart!=TK_UNBOUNDED) ){ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); @@ -1932,7 +1933,7 @@ int lbl = sqlite3VdbeMakeLabel(pParse); int tmpReg = sqlite3GetTempReg(pParse); sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); - + if( pFunc->zName==nth_valueName ){ sqlite3VdbeAddOp3(v, OP_Column,pMWin->iEphCsr,pWin->iArgCol+1,tmpReg); windowCheckValue(pParse, tmpReg, 2); @@ -1954,7 +1955,7 @@ int lbl = sqlite3VdbeMakeLabel(pParse); int tmpReg = sqlite3GetTempReg(pParse); int iEph = pMWin->iEphCsr; - + if( nArg<3 ){ sqlite3VdbeAddOp2(v, OP_Null, 0, pWin->regResult); }else{ @@ -1971,7 +1972,7 @@ sqlite3VdbeAddOp3(v, op, tmpReg2, tmpReg, tmpReg); sqlite3ReleaseTempReg(pParse, tmpReg2); } - + sqlite3VdbeAddOp3(v, OP_SeekRowid, csr, lbl, tmpReg); VdbeCoverage(v); sqlite3VdbeAddOp3(v, OP_Column, csr, pWin->iArgCol, pWin->regResult); @@ -2017,7 +2018,7 @@ return regArg; } -/* +/* ** Return true if the current frame should be cached in the ephemeral table, ** even if there are no xInverse() calls required. */ @@ -2041,9 +2042,9 @@ ** regOld and regNew are each the first register in an array of size ** pOrderBy->nExpr. This function generates code to compare the two ** arrays of registers using the collation sequences and other comparison -** parameters specified by pOrderBy. +** parameters specified by pOrderBy. ** -** If the two arrays are not equal, the contents of regNew is copied to +** If the two arrays are not equal, the contents of regNew is copied to ** regOld and control falls through. Otherwise, if the contents of the arrays ** are equal, an OP_Goto is executed. The address of the OP_Goto is returned. */ @@ -2060,7 +2061,7 @@ KeyInfo *pKeyInfo = sqlite3KeyInfoFromExprList(pParse, pOrderBy, 0, 0); sqlite3VdbeAddOp3(v, OP_Compare, regOld, regNew, nVal); sqlite3VdbeAppendP4(v, (void*)pKeyInfo, P4_KEYINFO); - sqlite3VdbeAddOp3(v, OP_Jump, + sqlite3VdbeAddOp3(v, OP_Jump, sqlite3VdbeCurrentAddr(v)+1, addr, sqlite3VdbeCurrentAddr(v)+1 ); VdbeCoverageEqNe(v); @@ -2094,7 +2095,7 @@ ** or subtraction is a a copy of csr1.peerVal. */ static void windowCodeRangeTest( - WindowCodeArg *p, + WindowCodeArg *p, int op, /* OP_Ge, OP_Gt, or OP_Le */ int csr1, /* Cursor number for cursor 1 */ int regVal, /* Register containing non-negative number */ @@ -2132,8 +2133,8 @@ ((op==OP_Ge) ? ">=" : (op==OP_Le) ? "<=" : (op==OP_Gt) ? ">" : "<"), reg2 )); - /* If the BIGNULL flag is set for the ORDER BY, then it is required to - ** consider NULL values to be larger than all other values, instead of + /* If the BIGNULL flag is set for the ORDER BY, then it is required to + ** consider NULL values to be larger than all other values, instead of ** the usual smaller. The VDBE opcodes OP_Ge and so on do not handle this ** (and adding that capability causes a performance regression), so ** instead if the BIGNULL flag is set then cases where either reg1 or @@ -2148,23 +2149,23 @@ ** if( op==OP_Le ) goto lbl; ** } ** - ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is + ** Additionally, if either reg1 or reg2 are NULL but the jump to lbl is ** not taken, control jumps over the comparison operator coded below this ** block. */ if( pOrderBy->a[0].fg.sortFlags & KEYINFO_ORDER_BIGNULL ){ /* This block runs if reg1 contains a NULL. */ int addr = sqlite3VdbeAddOp1(v, OP_NotNull, reg1); VdbeCoverage(v); switch( op ){ - case OP_Ge: - sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); + case OP_Ge: + sqlite3VdbeAddOp2(v, OP_Goto, 0, lbl); break; - case OP_Gt: - sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); - VdbeCoverage(v); + case OP_Gt: + sqlite3VdbeAddOp2(v, OP_NotNull, reg2, lbl); + VdbeCoverage(v); break; - case OP_Le: - sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); - VdbeCoverage(v); + case OP_Le: + sqlite3VdbeAddOp2(v, OP_IsNull, reg2, lbl); + VdbeCoverage(v); break; default: assert( op==OP_Lt ); /* no-op */ break; } @@ -2221,7 +2222,7 @@ /* ** Helper function for sqlite3WindowCodeStep(). Each call to this function -** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE +** generates VM code for a single RETURN_ROW, AGGSTEP or AGGINVERSE ** operation. Refer to the header comment for sqlite3WindowCodeStep() for ** details. */ @@ -2280,8 +2281,8 @@ addrContinue = sqlite3VdbeCurrentAddr(v); /* If this is a (RANGE BETWEEN a FOLLOWING AND b FOLLOWING) or - ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the - ** start cursor does not advance past the end cursor within the + ** (RANGE BETWEEN b PRECEDING AND a PRECEDING) frame, ensure the + ** start cursor does not advance past the end cursor within the ** temporary table. It otherwise might, if (a>b). Also ensure that, ** if the input cursor is still finding new rows, that the end ** cursor does not go past it to EOF. */ @@ -2422,11 +2423,11 @@ } /* -** Return true if it can be determined at compile time that expression -** pExpr evaluates to a value that, when cast to an integer, is greater +** Return true if it can be determined at compile time that expression +** pExpr evaluates to a value that, when cast to an integer, is greater ** than zero. False otherwise. ** -** If an OOM error occurs, this function sets the Parse.db.mallocFailed +** If an OOM error occurs, this function sets the Parse.db.mallocFailed ** flag and returns zero. */ static int windowExprGtZero(Parse *pParse, Expr *pExpr){ @@ -2442,11 +2443,11 @@ } /* -** sqlite3WhereBegin() has already been called for the SELECT statement +** sqlite3WhereBegin() has already been called for the SELECT statement ** passed as the second argument when this function is invoked. It generates -** code to populate the Window.regResult register for each window function +** code to populate the Window.regResult register for each window function ** and invoke the sub-routine at instruction addrGosub once for each row. -** sqlite3WhereEnd() is always called before returning. +** sqlite3WhereEnd() is always called before returning. ** ** This function handles several different types of window frames, which ** require slightly different processing. The following pseudo code is @@ -2461,17 +2462,17 @@ ** Gosub flush ** } ** Insert new row into eph table. -** +** ** if( first row of partition ){ ** // Rewind three cursors, all open on the eph table. ** Rewind(csrEnd); ** Rewind(csrStart); ** Rewind(csrCurrent); -** +** ** regEnd = // FOLLOWING expression ** regStart = // PRECEDING expression ** }else{ -** // First time this branch is taken, the eph table contains two +** // First time this branch is taken, the eph table contains two ** // rows. The first row in the partition, which all three cursors ** // currently point to, and the following row. ** AGGSTEP @@ -2500,17 +2501,17 @@ ** with arguments read from the current row of cursor csrEnd, then ** step cursor csrEnd forward one row (i.e. sqlite3BtreeNext()). ** -** RETURN_ROW: return a row to the caller based on the contents of the -** current row of csrCurrent and the current state of all +** RETURN_ROW: return a row to the caller based on the contents of the +** current row of csrCurrent and the current state of all ** aggregates. Then step cursor csrCurrent forward one row. ** -** AGGINVERSE: invoke the aggregate xInverse() function for each window +** AGGINVERSE: invoke the aggregate xInverse() function for each window ** functions with arguments read from the current row of cursor ** csrStart. Then step csrStart forward one row. ** ** There are two other ROWS window frames that are handled significantly ** differently from the above - "BETWEEN PRECEDING AND PRECEDING" -** and "BETWEEN FOLLOWING AND FOLLOWING". These are special +** and "BETWEEN FOLLOWING AND FOLLOWING". These are special ** cases because they change the order in which the three cursors (csrStart, ** csrCurrent and csrEnd) iterate through the ephemeral table. Cases that ** use UNBOUNDED or CURRENT ROW are much simpler variations on one of these @@ -2583,7 +2584,7 @@ ** ** 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 equivilent to "0 PRECEDING/FOLLOWING". +** 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: @@ -2660,15 +2661,15 @@ ** regEnd = ** regStart = ** }else if( new group ){ -** ... +** ... ** } ** } ** -** 2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or +** 2. Instead of processing a single row, each RETURN_ROW, AGGSTEP or ** AGGINVERSE step processes the current row of the relevant cursor and ** all subsequent rows belonging to the same group. ** -** RANGE window frames are a little different again. As for GROUPS, the +** RANGE window frames are a little different again. As for GROUPS, the ** main loop runs once per group only. And RETURN_ROW, AGGSTEP and AGGINVERSE ** deal in groups instead of rows. As for ROWS and GROUPS, there are three ** basic cases: @@ -2705,7 +2706,7 @@ ** } ** } ** -** In the above notation, "csr.key" means the current value of the ORDER BY +** In the above notation, "csr.key" means the current value of the ORDER BY ** expression (there is only ever 1 for a RANGE that uses an FOLLOWING ** or PRECEDING */ int regEnd = 0; /* Value of FOLLOWING */ - assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT - || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED + assert( pMWin->eStart==TK_PRECEDING || pMWin->eStart==TK_CURRENT + || pMWin->eStart==TK_FOLLOWING || pMWin->eStart==TK_UNBOUNDED ); - assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT - || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING + assert( pMWin->eEnd==TK_FOLLOWING || pMWin->eEnd==TK_CURRENT + || pMWin->eEnd==TK_UNBOUNDED || pMWin->eEnd==TK_PRECEDING ); assert( pMWin->eExclude==0 || pMWin->eExclude==TK_CURRENT || pMWin->eExclude==TK_GROUP || pMWin->eExclude==TK_TIES @@ -2830,9 +2831,9 @@ s.end.csr = s.current.csr+3; /* Figure out when rows may be deleted from the ephemeral table. There - ** are four options - they may never be deleted (eDelete==0), they may + ** are four options - they may never be deleted (eDelete==0), they may ** be deleted as soon as they are no longer part of the window frame - ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row + ** (eDelete==WINDOW_AGGINVERSE), they may be deleted as after the row ** has been returned to the caller (WINDOW_RETURN_ROW), or they may ** be deleted after they enter the frame (WINDOW_AGGSTEP). */ switch( pMWin->eStart ){ @@ -2862,7 +2863,7 @@ } /* Allocate registers for the array of values from the sub-query, the - ** samve values in record form, and the rowid used to insert said record + ** same values in record form, and the rowid used to insert said record ** into the ephemeral table. */ regNew = pParse->nMem+1; pParse->nMem += nInput; @@ -2880,7 +2881,7 @@ } /* If this is not a "ROWS BETWEEN ..." frame, then allocate arrays of - ** registers to store copies of the ORDER BY expressions (peer values) + ** registers to store copies of the ORDER BY expressions (peer values) ** for the main loop, and for each cursor (start, current and end). */ if( pMWin->eFrmType!=TK_ROWS ){ int nPeer = (pOrderBy ? pOrderBy->nExpr : 0); @@ -2901,7 +2902,7 @@ sqlite3VdbeAddOp3(v, OP_MakeRecord, regNew, nInput, regRecord); /* An input row has just been read into an array of registers starting - ** at regNew. If the window has a PARTITION clause, this block generates + ** at regNew. If the window has a PARTITION clause, this block generates ** VM code to check if the input row is the start of a new partition. ** If so, it does an OP_Gosub to an address to be filled in later. The ** address of the OP_Gosub is stored in local variable addrGosubFlush. */ diff -Nru sqlite3-3.42.0/test/aggnested.test sqlite3-3.44.0-0/test/aggnested.test --- sqlite3-3.42.0/test/aggnested.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/aggnested.test 2023-11-04 14:23:58.000000000 +0000 @@ -25,19 +25,19 @@ INSERT INTO t1 VALUES(1), (2), (3); CREATE TABLE t2(b1 INTEGER); INSERT INTO t2 VALUES(4), (5); - SELECT (SELECT group_concat(a1,'x') FROM t2) FROM t1; + SELECT (SELECT string_agg(a1,'x') FROM t2) FROM t1; } } {1x2x3} do_test aggnested-1.2 { db eval { SELECT - (SELECT group_concat(a1,'x') || '-' || group_concat(b1,'y') FROM t2) + (SELECT string_agg(a1,'x') || '-' || string_agg(b1,'y') FROM t2) FROM t1; } } {1x2x3-4y5} do_test aggnested-1.3 { db eval { - SELECT (SELECT group_concat(b1,a1) FROM t2) FROM t1; + SELECT (SELECT string_agg(b1,a1) FROM t2) FROM t1; } } {415 425 435} do_test aggnested-1.4 { @@ -309,7 +309,7 @@ do_execsql_test 5.5 { CREATE TABLE a(b); WITH c AS(SELECT a) - SELECT(SELECT(SELECT group_concat(b, b) + SELECT(SELECT(SELECT string_agg(b, b) LIMIT(SELECT 0.100000 * AVG(DISTINCT(SELECT 0 FROM a ORDER BY b, b, b)))) FROM a GROUP BY b, diff -Nru sqlite3-3.42.0/test/aggorderby.test sqlite3-3.44.0-0/test/aggorderby.test --- sqlite3-3.42.0/test/aggorderby.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/aggorderby.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,122 @@ +# 2023-10-18 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements tests for ORDER BY on aggregate functions. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test aggorderby-1.1 { + CREATE TABLE t1(a TEXT,b INT,c INT,d INT); + WITH RECURSIVE c(x) AS (VALUES(0) UNION ALL SELECT x+1 FROM c WHERE x<9) + INSERT INTO t1(a,b,c,d) SELECT printf('%d',(x*7)%10),1,x,10-x FROM c; + INSERT INTO t1(a,b,c,d) SELECT a, 2, c, 10-d FROM t1; + CREATE INDEX t1b ON t1(b); +} +do_catchsql_test aggorderby-1.2 { + SELECT b, group_concat(a ORDER BY max(d)) FROM t1 GROUP BY b; +} {1 {misuse of aggregate function max()}} +do_catchsql_test aggorderby-1.3 { + SELECT abs(a ORDER BY max(d)) FROM t1; +} {1 {ORDER BY may not be used with non-aggregate abs()}} + +do_execsql_test aggorderby-2.0 { + SELECT group_concat(a ORDER BY a) FROM t1 WHERE b=1; +} {0,1,2,3,4,5,6,7,8,9} +do_execsql_test aggorderby-2.1 { + SELECT group_concat(a ORDER BY c) FROM t1 WHERE b=1; +} {0,7,4,1,8,5,2,9,6,3} +do_execsql_test aggorderby-2.2 { + SELECT group_concat(a ORDER BY b, d) FROM t1; +} {3,6,9,2,5,8,1,4,7,0,0,7,4,1,8,5,2,9,6,3} +do_execsql_test aggorderby-2.3 { + SELECT string_agg(a, ',' ORDER BY b DESC, d) FROM t1; +} {0,7,4,1,8,5,2,9,6,3,3,6,9,2,5,8,1,4,7,0} +do_execsql_test aggorderby-2.4 { + SELECT b, group_concat(a ORDER BY d) FROM t1 GROUP BY b ORDER BY b; +} {1 3,6,9,2,5,8,1,4,7,0 2 0,7,4,1,8,5,2,9,6,3} + +do_execsql_test aggorderby-3.0 { + SELECT group_concat(DISTINCT a ORDER BY a) FROM t1; +} {0,1,2,3,4,5,6,7,8,9} +do_execsql_test aggorderby-3.1 { + SELECT group_concat(DISTINCT a ORDER BY c) FROM t1; +} {0,7,4,1,8,5,2,9,6,3} + +do_execsql_test aggorderby-4.0 { + SELECT count(ORDER BY a) FROM t1; +} 20 +do_execsql_test aggorderby-4.1 { + SELECT c, max(a ORDER BY a) FROM t1; +} {7 9} + + +do_execsql_test aggorderby-5.0 { + DROP TABLE IF EXISTS t1; + DROP TABLE IF EXISTS t3; + CREATE TABLE t1(a TEXT); INSERT INTO t1 VALUES('aaa'),('bbb'); + CREATE TABLE t3(d TEXT); INSERT INTO t3 VALUES('/'),('-'); + SELECT (SELECT string_agg(a,d) FROM t3) FROM t1; +} {aaa-aaa bbb-bbb} +do_execsql_test aggorderby-5.1 { + SELECT (SELECT group_concat(a,d ORDER BY d) FROM t3) FROM t1; +} {aaa/aaa bbb/bbb} +do_execsql_test aggorderby-5.2 { + SELECT (SELECT string_agg(a,d ORDER BY d DESC) FROM t3) FROM t1; +} {aaa-aaa bbb-bbb} +do_execsql_test aggorderby-5.3 { + SELECT (SELECT string_agg(a,'#' ORDER BY d) FROM t3) FROM t1; +} {aaa#aaa bbb#bbb} + +# COLLATE works on the ORDER BY. +# +do_execsql_test aggorderby-6.0 { + WITH c(x) AS (VALUES('abc'),('DEF'),('xyz'),('ABC'),('XYZ')) + SELECT string_agg(x,',' ORDER BY x COLLATE nocase), + string_agg(x,',' ORDER BY x) FROM c; +} {abc,ABC,DEF,xyz,XYZ ABC,DEF,XYZ,abc,xyz} +do_execsql_test aggorderby-6.1 { + WITH c(x,y) AS (VALUES(1,'a'),(2,'B'),(3,'c'),(4,'D')) + SELECT group_concat(x ORDER BY y COLLATE nocase), + group_concat(x ORDER BY y COLLATE binary) FROM c; +} {1,2,3,4 2,4,1,3} + +# NULLS FIRST and NULLS LAST work on the ORDER BY +# +do_execsql_test aggorderby-7.0 { + WITH c(x) AS (VALUES(1),(NULL),(2.5),(NULL),('three')) + SELECT json_group_array(x ORDER BY x NULLS FIRST), + json_group_array(x ORDER BY x NULLS LAST) FROM c; +} {[null,null,1,2.5,"three"] [1,2.5,"three",null,null]} +do_execsql_test aggorderby-7.1 { + WITH c(x,y) AS (VALUES(1,9),(2,null),(3,5),(4,null),(5,1)) + SELECT json_group_array(x ORDER BY y NULLS FIRST, x), + json_group_array(x ORDER BY y NULLS LAST, x) FROM c; +} {[2,4,5,3,1] [5,3,1,2,4]} + +# The DISTINCT only applies to the function arguments, not to the +# ORDER BY arguments. +# +do_execsql_test aggorderby-8.0 { + WITH c(x,y,z) AS (VALUES('a',4,5),('b',3,6),('c',2,7),('c',1,8)) + SELECT group_concat(DISTINCT x ORDER BY y, z) FROM c; +} {c,b,a} +do_execsql_test aggorderby-8.1 { + WITH c(x,y,z) AS (VALUES('a',4,5),('b',3,6),('b',2,7),('c',1,8)) + SELECT group_concat(DISTINCT x ORDER BY y, z) FROM c; +} {c,b,a} +do_execsql_test aggorderby-8.2 { + WITH c(x,y) AS (VALUES(1,1),(2,2),(3,3),(3,4),(3,5),(3,6)) + SELECT sum(DISTINCT x ORDER BY y) FROM c; +} 6 + + +finish_test diff -Nru sqlite3-3.42.0/test/altercol.test sqlite3-3.44.0-0/test/altercol.test --- sqlite3-3.42.0/test/altercol.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/altercol.test 2023-11-04 14:23:58.000000000 +0000 @@ -343,6 +343,21 @@ ALTER TABLE b1 RENAME a TO aaa; } {1 {error in view zzz: no such column: george}} +do_execsql_test 8.5 { + DROP VIEW zzz; + CREATE TABLE t5(a TEXT, b INT); + INSERT INTO t5(a,b) VALUES('aaa',7),('bbb',3),('ccc',4); + CREATE VIEW vt5(x) AS SELECT group_concat(a ORDER BY b) FROM t5; + SELECT x FROM vt5; +} {bbb,ccc,aaa} +do_execsql_test 8.5.1 { + ALTER TABLE t5 RENAME COLUMN b TO bbb; + SELECT sql FROM sqlite_schema WHERE name='vt5'; +} {{CREATE VIEW vt5(x) AS SELECT group_concat(a ORDER BY bbb) FROM t5}} +do_execsql_test 8.5.2 { + SELECT x FROM vt5; +} {bbb,ccc,aaa} + #------------------------------------------------------------------------- # More triggers. # diff -Nru sqlite3-3.42.0/test/altermalloc3.test sqlite3-3.44.0-0/test/altermalloc3.test --- sqlite3-3.42.0/test/altermalloc3.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/altermalloc3.test 2023-11-04 14:23:58.000000000 +0000 @@ -26,6 +26,7 @@ {unable to open a temporary database file for storing temporary tables} ] +sqlite3_db_config db SQLITE_DBCONFIG_DQS_DDL 1 do_execsql_test 1.0 { CREATE TABLE x1( one, two, three, PRIMARY KEY(one), diff -Nru sqlite3-3.42.0/test/alterqf.test sqlite3-3.44.0-0/test/alterqf.test --- sqlite3-3.42.0/test/alterqf.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/alterqf.test 2023-11-04 14:23:58.000000000 +0000 @@ -65,7 +65,7 @@ 11 {CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN SELECT max("str", new."a") FROM t1 - WHERE group_concat("b", ",") OVER (ORDER BY c||"str"); + WHERE string_agg("b", ",") OVER (ORDER BY c||"str"); UPDATE t1 SET c= b + "str"; DELETE FROM t1 WHERE EXISTS ( SELECT 1 FROM t1 AS o WHERE o."a" = "o.a" AND t1.b IN("t1.b") @@ -73,7 +73,7 @@ END; } {CREATE TRIGGER ott AFTER UPDATE ON t1 BEGIN SELECT max('str', new."a") FROM t1 - WHERE group_concat("b", ',') OVER (ORDER BY c||'str'); + WHERE string_agg("b", ',') OVER (ORDER BY c||'str'); UPDATE t1 SET c= b + 'str'; DELETE FROM t1 WHERE EXISTS ( SELECT 1 FROM t1 AS o WHERE o."a" = 'o.a' AND t1.b IN('t1.b') diff -Nru sqlite3-3.42.0/test/alter.test sqlite3-3.44.0-0/test/alter.test --- sqlite3-3.42.0/test/alter.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/alter.test 2023-11-04 14:23:58.000000000 +0000 @@ -934,5 +934,24 @@ SELECT name FROM sqlite_schema WHERE sql LIKE '%t3%' ORDER BY name; } {r1 t3} +# 2023-10-14 +# On an ALTER TABLE ADD COLUMN with a DEFAULT clause on a STRICT table +# make sure that the DEFAULT has a compatible type. +# +reset_db +do_execsql_test alter-20.1 { + CREATE TABLE t1(a INT) STRICT; + INSERT INTO t1(a) VALUES(45); +} {} +do_catchsql_test alter-20.2 { + ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT x'313233'; +} {1 {type mismatch on DEFAULT}} +do_execsql_test alter-20.2 { + DELETE FROM t1; + ALTER TABLE t1 ADD COLUMN b TEXT DEFAULT x'313233'; +} {} +do_catchsql_test alter-20.3 { + INSERT INTO t1(a) VALUES(45); +} {1 {cannot store BLOB value in TEXT column t1.b}} finish_test diff -Nru sqlite3-3.42.0/test/altertrig.test sqlite3-3.44.0-0/test/altertrig.test --- sqlite3-3.42.0/test/altertrig.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/altertrig.test 2023-11-04 14:23:58.000000000 +0000 @@ -160,4 +160,3 @@ } finish_test - diff -Nru sqlite3-3.42.0/test/analyze.test sqlite3-3.44.0-0/test/analyze.test --- sqlite3-3.42.0/test/analyze.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/analyze.test 2023-11-04 14:23:58.000000000 +0000 @@ -377,4 +377,23 @@ SELECT tbl FROM sqlite_stat1 WHERE idx IS NULL ORDER BY tbl; } {SQLiteDemo2 sqliteDemo t1} +# The following caused a small buffer overread in STAT4 processing prior +# to check-in [b99135288b157044]. +# +ifcapable stat4 { + reset_db + database_may_be_corrupt + do_execsql_test analyze-7.1 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INTEGER); + INSERT INTO t1 VALUES(1, 7223372036854775); + INSERT INTO t1 VALUES(2, 7223372036854776); + INSERT INTO t1 VALUES(3, 7223372036854777); + CREATE INDEX i1 ON t1(b); + ANALYZE; + UPDATE sqlite_stat4 SET sample = substr(sample, 0, 4); + ANALYZE sqlite_schema; + SELECT * FROM t1 WHERE b>7223372036854775 + } {2 7223372036854776 3 7223372036854777} +} + finish_test diff -Nru sqlite3-3.42.0/test/atof1.test sqlite3-3.44.0-0/test/atof1.test --- sqlite3-3.42.0/test/atof1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/atof1.test 2023-11-04 14:23:58.000000000 +0000 @@ -15,18 +15,10 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl -if {$::longdouble_size<=8} { - finish_test - return -} -if {$::tcl_platform(machine)!="x86_64"} { - finish_test - return -} - +set mxpow [expr {[use_long_double]?100:35}] expr srand(1) for {set i 1} {$i<20000} {incr i} { - set pow [expr {int((rand()-0.5)*100)}] + set pow [expr {int((rand()-0.5)*$mxpow)}] set x [expr {pow((rand()-0.5)*2*rand(),$pow)}] set xf [format %.32e $x] @@ -51,10 +43,16 @@ set y [db eval {SELECT $x=CAST(quote($x) AS real)}] if {!$y} { db eval {SELECT real2hex($x) a, real2hex(CAST(quote($x) AS real)) b} {} - puts "\nIN: $a $xf" - puts [format {QUOTE: %16s %s} {} [db eval {SELECT quote($x)}]] + puts "" + if {$x<0} { + puts "[format {!SCALE: %17s 1 23456789 123456789 123456789} {}]" + } else { + puts "[format {!SCALE: %16s 1 23456789 123456789 123456789} {}]" + } + puts "!IN: $a $xf" + puts [format {!QUOTE: %16s %s} {} [db eval {SELECT quote($x)}]] db eval {SELECT CAST(quote($x) AS real) c} {} - puts "OUT: $b [format %.32e $c]" + puts "!OUT: $b [format %.32e $c]" } set y } {1} diff -Nru sqlite3-3.42.0/test/autoindex4.test sqlite3-3.44.0-0/test/autoindex4.test --- sqlite3-3.42.0/test/autoindex4.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/autoindex4.test 2023-11-04 14:23:58.000000000 +0000 @@ -141,7 +141,7 @@ {coalesce(y,4)==4} {3 4 3 4} - 5 + 5.1 VALUES(1,2),(3,4),(NULL,4) VALUES(1,2),(3,4) {LEFT JOIN} @@ -149,6 +149,22 @@ {y=4 OR y IS NULL} {3 4 3 4 {} 4 {} {}} + 5.2 + VALUES(1,2),(3,4),(NULL,4) + VALUES(1,2),(3,4) + {LEFT JOIN} + a=x + {y NOT IN ()} + {1 2 1 2 3 4 3 4 {} 4 {} {}} + + 5.3 + VALUES(1,2),(3,4),(NULL,4) + VALUES(1,2),(3,4) + {LEFT JOIN} + a=x + {y NOT IN (SELECT 1 WHERE false)} + {1 2 1 2 3 4 3 4 {} 4 {} {}} + 6 VALUES(1,2),(3,4) VALUES(1,2),(3,4),(NULL,4) @@ -193,6 +209,12 @@ db eval {PRAGMA automatic_index=OFF;} db eval $sql } $answer + do_test autoindex4-4.$id.3 { + db eval {PRAGMA automatic_index=ON;} + optimization_control db all 0 + db eval $sql + } $answer + optimization_control db all 1 } diff -Nru sqlite3-3.42.0/test/bestindex9.test sqlite3-3.44.0-0/test/bestindex9.test --- sqlite3-3.42.0/test/bestindex9.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/bestindex9.test 2023-11-04 14:23:58.000000000 +0000 @@ -102,7 +102,3 @@ finish_test - - - - diff -Nru sqlite3-3.42.0/test/bestindexA.test sqlite3-3.44.0-0/test/bestindexA.test --- sqlite3-3.42.0/test/bestindexA.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/bestindexA.test 2023-11-04 14:23:58.000000000 +0000 @@ -133,6 +133,3 @@ finish_test - - - diff -Nru sqlite3-3.42.0/test/bestindexB.test sqlite3-3.44.0-0/test/bestindexB.test --- sqlite3-3.42.0/test/bestindexB.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/bestindexB.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,87 @@ +# 2023-10-26 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +set testprefix bestindexB + +ifcapable !vtab { + finish_test + return +} + +register_tcl_module db + +proc vtab_command {method args} { + switch -- $method { + xConnect { + return "CREATE TABLE t1(a, b, c)" + } + + xBestIndex { + set hdl [lindex $args 0] + set clist [$hdl constraints] + set orderby [$hdl orderby] + + if {[info exists ::xbestindex_sql]} { + explain_i $::xbestindex_sql + set ::xbestindex_res [ execsql $::xbestindex_sql ] + } + + return "cost 1000000 rows 1000000 idxnum 0 idxstr hello" + } + + xFilter { + return "sql {SELECT 0, 1, 2, 3}" + } + } + + return {} +} + +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE x1 USING tcl(vtab_command); + CREATE TABLE y1(a, b); + CREATE TABLE y2(a, b); +} {} + +do_execsql_test 1.1 { + SELECT * FROM x1 +} {1 2 3} + +do_execsql_test 1.2 { + INSERT INTO y1 VALUES(1, 2) RETURNING rowid; +} {1} + +do_execsql_test 1.3 { + CREATE TRIGGER y1tr BEFORE INSERT ON y1 BEGIN + SELECT * FROM x1; + END; + INSERT INTO y1 VALUES(3, 4) RETURNING rowid; +} {2} + + +# This time, rig the xBestIndex() method of the vtab to invoke an SQL +# statement that uses RETURNING. +set ::xbestindex_sql { + INSERT INTO y2 VALUES(NULL, NULL) RETURNING rowid; +} +do_execsql_test 1.4 { + INSERT INTO y1 VALUES(5, 6) RETURNING rowid; +} {3} + +do_test 1.5 { + set ::xbestindex_res +} {1} + +finish_test diff -Nru sqlite3-3.42.0/test/changes2.test sqlite3-3.44.0-0/test/changes2.test --- sqlite3-3.42.0/test/changes2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/changes2.test 2023-11-04 14:23:58.000000000 +0000 @@ -92,4 +92,3 @@ } {{2 changes} {2 changes}} finish_test - diff -Nru sqlite3-3.42.0/test/changes.test sqlite3-3.44.0-0/test/changes.test --- sqlite3-3.42.0/test/changes.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/changes.test 2023-11-04 14:23:58.000000000 +0000 @@ -86,5 +86,3 @@ } finish_test - - diff -Nru sqlite3-3.42.0/test/corrupt2.test sqlite3-3.44.0-0/test/corrupt2.test --- sqlite3-3.42.0/test/corrupt2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/corrupt2.test 2023-11-04 14:23:58.000000000 +0000 @@ -248,7 +248,7 @@ } set result } {{*** in database main *** -Tree 11 page 2 cell 0: 2nd reference to page 10 +Tree 2 page 2 cell 0: 2nd reference to page 10 Page 4: never used}} db2 close diff -Nru sqlite3-3.42.0/test/corruptL.test sqlite3-3.44.0-0/test/corruptL.test --- sqlite3-3.42.0/test/corruptL.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/corruptL.test 2023-11-04 14:23:58.000000000 +0000 @@ -1269,6 +1269,7 @@ }]} {} extra_schema_checks 0 +optimization_control db one-pass off do_catchsql_test 15.1 { PRAGMA cell_size_check = 0; UPDATE c1 SET c= NOT EXISTS(SELECT 1 FROM c1 ORDER BY (SELECT 1 FROM c1 ORDER BY a)) +10 WHERE d BETWEEN 4 AND 7; diff -Nru sqlite3-3.42.0/test/date4.test sqlite3-3.44.0-0/test/date4.test --- sqlite3-3.42.0/test/date4.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/date4.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,38 @@ +# 2023-08-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. +# +#*********************************************************************** +# +# Test cases for the strftime() SQL function. Comparisons against the +# C-library strftime() function. + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Skip this whole file if date and time functions are omitted +# at compile-time +# +ifcapable {!datetime} { + finish_test + return +} + +if {$tcl_platform(os)=="Linux"} { + set FMT {%d,%e,%F,%H,%k,%I,%l,%j,%m,%M,%u,%w,%W,%Y,%%,%P,%p} +} else { + set FMT {%d,%e,%F,%H,%I,%j,%p,%R,%u,%w,%W,%%} +} +for {set i 0} {$i<=24854} {incr i} { + set TS [expr {$i*86401}] + do_execsql_test date4-$i { + SELECT strftime($::FMT,$::TS,'unixepoch'); + } [list [strftime $FMT $TS]] +} + +finish_test diff -Nru sqlite3-3.42.0/test/date.test sqlite3-3.44.0-0/test/date.test --- sqlite3-3.42.0/test/date.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/date.test 2023-11-04 14:23:58.000000000 +0000 @@ -207,15 +207,33 @@ datetest 3.17 "strftime('[repeat 200 abc%m123]','2003-10-31')" \ [repeat 200 abc10123] -foreach c {a b c e g h i k l n o p q r t v x y z - A B C D E F G I K L N O P Q R T U V Z +foreach c {a b c g h i n o q r t v x y z + A B C D E G K L N O Q V Z 0 1 2 3 4 5 6 6 7 9 _} { datetest 3.18.$c "strftime('%$c','2003-10-31')" NULL } +datetest 3.20 {strftime('%e','2023-08-09')} { 9} +datetest 3.21 {strftime('%F %T','2023-08-09 01:23')} {2023-08-09 01:23:00} +datetest 3.22 {strftime('%k','2023-08-09 04:59:59')} { 4} +datetest 3.23 {strftime('%I%P','2023-08-09 11:59:59')} {11am} +datetest 3.24 {strftime('%I%p','2023-08-09 12:00:00')} {12PM} +datetest 3.25 {strftime('%I%P','2023-08-09 12:59:59.9')} {12pm} +datetest 3.26 {strftime('%I%p','2023-08-09 13:00:00')} {01PM} +datetest 3.27 {strftime('%I%P','2023-08-09 23:59:59')} {11pm} +datetest 3.28 {strftime('%I%p','2023-08-09 00:00:00')} {12AM} +datetest 3.29 {strftime('%l:%M%P','2023-08-09 13:00:00')} { 1:00pm} +datetest 3.30 {strftime('%F %R','2023-08-09 12:34:56')} {2023-08-09 12:34} +datetest 3.31 {strftime('%w %u','2023-01-01')} {0 7} +datetest 3.32 {strftime('%w %u','2023-01-02')} {1 1} +datetest 3.33 {strftime('%w %u','2023-01-03')} {2 2} +datetest 3.34 {strftime('%w %u','2023-01-04')} {3 3} +datetest 3.35 {strftime('%w %u','2023-01-05')} {4 4} +datetest 3.36 {strftime('%w %u','2023-01-06')} {5 5} +datetest 3.37 {strftime('%w %u','2023-01-07')} {6 6} # Ticket #2276. Make sure leading zeros are inserted where appropriate. # -datetest 3.20 \ +datetest 3.40 \ {strftime('%d/%f/%H/%W/%j/%m/%M/%S/%Y','0421-01-02 03:04:05.006')} \ 02/05.006/03/00/002/01/04/05/0421 diff -Nru sqlite3-3.42.0/test/dbfuzz001.test sqlite3-3.44.0-0/test/dbfuzz001.test --- sqlite3-3.42.0/test/dbfuzz001.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/dbfuzz001.test 2023-11-04 14:23:58.000000000 +0000 @@ -371,4 +371,27 @@ } {1 {database disk image is malformed}} extra_schema_checks 1 +#------------------------------------------------------------------------- +reset_db + +do_execsql_test dbfuzz001-430 { + CREATE TABLE t1(a INTEGER, b INT, c DEFAULT 0); +} + +do_execsql_test dbfuzz001-420 { + PRAGMA locking_mode=EXCLUSIVE; + PRAGMA journal_mode = memory; + INSERT INTO t1 VALUES(1,2,3); + PRAGMA journal_mode=PERSIST; +} {exclusive memory persist} + +do_execsql_test dbfuzz001-430 { + INSERT INTO t1 VALUES(4, 5, 6); +} + +do_execsql_test dbfuzz001-440 { + PRAGMA journal_mode=MEMORY; + INSERT INTO t1 VALUES(7, 8, 9); +} {memory} + finish_test diff -Nru sqlite3-3.42.0/test/dbpagefault.test sqlite3-3.44.0-0/test/dbpagefault.test --- sqlite3-3.42.0/test/dbpagefault.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/dbpagefault.test 2023-11-04 14:23:58.000000000 +0000 @@ -84,5 +84,3 @@ finish_test - - diff -Nru sqlite3-3.42.0/test/decimal.test sqlite3-3.44.0-0/test/decimal.test --- sqlite3-3.42.0/test/decimal.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/decimal.test 2023-11-04 14:23:58.000000000 +0000 @@ -23,31 +23,34 @@ SELECT decimal(1); } {1} do_execsql_test 1010 { - SELECT decimal(1.0); + SELECT decimal('1.0'); } {1.0} do_execsql_test 1020 { - SELECT decimal(0001.0); + SELECT decimal('0001.0'); } {1.0} do_execsql_test 1030 { - SELECT decimal(+0001.0); + SELECT decimal('+0001.0'); } {1.0} do_execsql_test 1040 { - SELECT decimal(-0001.0); + SELECT decimal('-0001.0'); } {-1.0} do_execsql_test 1050 { - SELECT decimal(1.0e72); + SELECT decimal('1.0e72'); } {1000000000000000000000000000000000000000000000000000000000000000000000000} # 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123 do_execsql_test 1060 { - SELECT decimal(1.0e-72); + SELECT decimal('1.0e-72'); } {0.0000000000000000000000000000000000000000000000000000000000000000000000010} # 123456789 123456789 123456789 123456789 123456789 123456789 123456789 123 do_execsql_test 1070 { - SELECT decimal(-123e-4); + SELECT decimal('-123e-4'); } {-0.0123} do_execsql_test 1080 { - SELECT decimal(+123e+4); -} {1230000.0} + SELECT decimal('+123e+4'); +} {1230000} +do_execsql_test 1081 { + SELECT decimal_exp('+123e+4'); +} {+1.23e+06} do_execsql_test 2000 { @@ -161,6 +164,10 @@ SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v) FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n); } {0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625} +do_execsql_test 6011 { + WITH c(n) AS (SELECT ieee754_from_blob(x'0000000000000001')) +SELECT decimal(c.n) FROM c; +} {0.000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000004940656458412465441765687928682213723650598026143247644255856825006755072702087518652998363616359923797965646954457177309266567103559397963987747960107818781263007131903114045278458171678489821036887186360569987307230500063874091535649843873124733972731696151400317153853980741262385655911710266585566867681870395603106249319452715914924553293054565444011274801297099995419319894090804165633245247571478690147267801593552386115501348035264934720193790268107107491703332226844753335720832431936092382893458368060106011506169809753078342277318329247904982524730776375927247874656084778203734469699533647017972677717585125660551199131504891101451037862738167250955837389733598993664809941164205702637090279242767544565229087538682506419718265533447265625} do_execsql_test 6020 { WITH c(n) AS (SELECT ieee754_from_blob(x'7fefffffffffffff')) SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v) diff -Nru sqlite3-3.42.0/test/distinctagg.test sqlite3-3.44.0-0/test/distinctagg.test --- sqlite3-3.42.0/test/distinctagg.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/distinctagg.test 2023-11-04 14:23:58.000000000 +0000 @@ -56,7 +56,7 @@ } {1 {DISTINCT aggregates must have exactly one argument}} do_test distinctagg-2.2 { catchsql { - SELECT group_concat(distinct a,b) FROM t1; + SELECT string_agg(distinct a,b) FROM t1; } } {1 {DISTINCT aggregates must have exactly one argument}} @@ -215,4 +215,3 @@ finish_test - diff -Nru sqlite3-3.42.0/test/e_expr.test sqlite3-3.44.0-0/test/e_expr.test --- sqlite3-3.42.0/test/e_expr.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/e_expr.test 2023-11-04 14:23:58.000000000 +0000 @@ -1930,7 +1930,7 @@ 6 { ( SELECT y FROM t4 ORDER BY y DESC ) } text two 7 { ( SELECT sum(x) FROM t4 ) } integer 6 - 8 { ( SELECT group_concat(y,'') FROM t4 ) } text onetwothree + 8 { ( SELECT string_agg(y,'') FROM t4 ) } text onetwothree 9 { ( SELECT max(x) FROM t4 WHERE y LIKE '___') } integer 2 } { diff -Nru sqlite3-3.42.0/test/e_select.test sqlite3-3.44.0-0/test/e_select.test --- sqlite3-3.42.0/test/e_select.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/e_select.test 2023-11-04 14:23:58.000000000 +0000 @@ -943,7 +943,7 @@ 4 "SELECT *, count(*) FROM a1 JOIN a2" {1 1 1 1 16} 5 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} 6 "SELECT *, sum(three) FROM a1 NATURAL JOIN a2" {1 1 1 3} - 7 "SELECT group_concat(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 1 1} + 7 "SELECT string_agg(three, ''), a1.* FROM a1 NATURAL JOIN a2" {12 1 1} } # EVIDENCE-OF: R-04486-07266 Or, if the dataset contains zero rows, then diff -Nru sqlite3-3.42.0/test/filter2.test sqlite3-3.44.0-0/test/filter2.test --- sqlite3-3.42.0/test/filter2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/filter2.test 2023-11-04 14:23:58.000000000 +0000 @@ -113,7 +113,7 @@ do_execsql_test 1.13 { SELECT - group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0), + string_agg(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=0), group_concat(CAST(b AS TEXT), '_') FILTER (WHERE b%2!=1), count(*) FILTER (WHERE b%2!=0), count(*) FILTER (WHERE b%2!=1) diff -Nru sqlite3-3.42.0/test/fpconv1.test sqlite3-3.44.0-0/test/fpconv1.test --- sqlite3-3.42.0/test/fpconv1.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/fpconv1.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,44 @@ +# 2023-07-03 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# This file contains a test that attempts to verify the claim that the +# floatpoint-to-text conversion routines built into SQLite maintain at +# least 15 significant digits of accuracy. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +if {[catch {load_static_extension db decimal} error]} { + puts "Skipping decimal tests, hit load error: $error" + finish_test; return +} + +sqlite3_create_function db +do_execsql_test fpconv1-1.0 { + WITH RECURSIVE + /* Number of random floating-point values to try. + ** On a circa 2016 x64 linux box, this test runs at + ** about 80000 cases per second -------------------vvvvvv */ + c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<100000), + fp(y) AS MATERIALIZED ( + SELECT CAST( format('%+d.%019d0e%+03d', + random()%10,abs(random()),random()%200) AS real) + FROM c + ) + SELECT y FROM fp + WHERE -log10(abs(decimal_sub(dtostr(y,24),format('%!.24e',y))/y))<15.0; + /* Number of digits of accuracy required -------^^^^ */ +} {} +# ^---- Expect a empty set as the result. The output is all tested numbers +# that fail to preserve at least 15 significant digits of accuracy. + +finish_test diff -Nru sqlite3-3.42.0/test/fp-speed-1.c sqlite3-3.44.0-0/test/fp-speed-1.c --- sqlite3-3.42.0/test/fp-speed-1.c 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/fp-speed-1.c 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,164 @@ +/* +** Performance testing of floating-point binary-to-decimal conversion for +** SQLite versus the standard library. +** +** To compile: +** +** make sqlite3.c +** gcc -Os -c sqlite3.c +** gcc -I. -Os test/fp-speed-1.c sqlite3.o -ldl -lm -lpthread +** +** To run the test: +** +** time ./a.out 0 10000000 <-- standard library +** time ./a.out 1 10000000 <-- SQLite +** time ./a.out 2 10000000 <-- SQLite with long-double disabled +*/ +static double aVal[] = { + -1.0163830486285643089e+063, + +0.0049243807391586981e-019, + +7.3818732407343994867e-095, + +7.0678595219225717143e+000, + +9.2807266319850025655e+120, + +5.8871050861933394663e+135, + -2.2998023621259662805e-168, + -1.5903581924910847482e+181, + +2.4313441816844978216e-001, + -3.8290987328945399091e-147, + +1.8787914062744001349e-009, + +0.7270653560487146653e-014, + +0.0639577697913183665e+107, + +5.2292338879315861930e-103, + +6.3747682672872231319e-021, + +8.6972339538329106984e-129, + -9.5074486051597691937e-026, + -8.6480257845368753018e-005, + -3.5657595775797470332e+017, + -7.8323106179731761351e+161, + +7.7813875274120800372e+077, + -1.8739718928360196596e-050, + +8.6898145915593357218e-051, + +6.0566766359877837871e+002, + +4.1703379217148160678e+199, + +2.1283871288746651560e+150, + -6.8395236083891810637e+128, + -6.2114299763939529155e-147, + -2.0753525742614637350e-149, + +5.8727459803944290257e-007, + +8.5888991062002101817e+010, + +6.8624461031355917632e+026, + -3.3053986756670905167e-075, + -4.3596843152763444945e-108, + +0.0834139520104099673e+098, + -8.8581986548904222440e-192, + -3.6622095428727698202e+038, + -6.6965852297025063260e+005, + +1.8204169347406488441e-054, + +6.5234508038649000384e-065, + +1.5923006018219011453e+083, + +1.7362555291656389480e+018, + +7.2875431976854785882e+160, + +1.2835880105958926748e-146, + +8.0516253320320819420e-113, + +6.6324633399381145440e-030, + -1.7126500070280062058e-149, + +1.6995738341583712335e+042, + +7.6048766923738663725e-112, + +0.6159117235449455043e-004, + +5.7544894355415943289e-135, + +8.2970228592690581890e-023, + -6.5531925360163067447e+020, + +5.8321334606187030050e+120, + +5.6557166509571891727e+095, + +0.3322789708438408704e-114, + -7.1210648776698686623e-050, + -9.6721262526706343301e+179, + -3.4583916571377395084e-106, + +4.7896094323214750793e-172, + -9.6926028040004137875e-056, + +7.0683848275381385483e-198, + -5.2970114182162961964e-007, + -4.4287021200905393271e-170, + +0.0728891155732808799e-189, + -9.1855462025879447465e+175, + +3.7294126234131007796e+015, + +2.6857421882792719241e+003, + -4.7070607333624685339e+039, + +7.2175820768279334274e+136, + -8.3678412534261163481e-115, + +2.2174844304241822163e+019, + +0.1949824588606861016e+112, + -9.7334052955672071912e+151, + -9.7793887766936999879e-142, + -5.1561164587416931561e+139, + -7.5048993577765174789e-022, + +7.3556076568687784568e+107, + -5.0681628575533599865e-144, + +1.5209705642027747811e+165, + -7.5989782535048296040e-101, + +1.3654137203389775871e-016, + -1.6441720554651372066e+087, + -4.9042433196141125923e+000, + -7.7063611961649130777e+118, + +0.1699427460930766201e+174, + +8.3374317849572216870e-145, + -5.2355330480469580072e+081, + -3.8510045942194147919e+141, + -6.3513622544326339887e-147, + +2.3869303484454428988e+049, + +3.8352715871620360268e-165, + -3.1263120493136887902e+035, + -5.5794797002556490823e+051, + -8.8109874479595604379e+142, + -4.3727360120203216922e+070, + -3.1109951189668539974e+170, + -9.4841878031704268232e+011, + -3.7398451668304407277e+067, + +4.8984042008915959963e-091, +}; +#define NN (sizeof(aVal)/sizeof(aVal[0])) + +#include "sqlite3.h" +#include +#include + +int main(int argc, char **argv){ + int i; + int cnt; + int fg; + char zBuf[1000]; + + if( argc!=3 ){ + fprintf(stderr, "Usage: %s FLAG COUNT\n", argv[0]); + return 1; + } + cnt = atoi(argv[2]); + fg = atoi(argv[1]); + + switch( fg % 3 ){ + case 0: { + printf("Doing %d calls to C-lib sprintf()\n", cnt); + for(i=0; i> - CC02.06.02', 'The following expense report is ready for approval: - -Employee Name: Christopher F. Calger -Status last changed by: Mollie E. Gustafson Ms -Expense Report Name: CC02.06.02 -Report Total: $3,972.93 -Amount Due Employee: $3,972.93 - - -To approve this expense report, click on the following link for Concur Expense. -http://expensexms.enron.com'); -INSERT INTO email([from],[to],subject,body) VALUES('jeff.duff@enron.com', 'julie.johnson@enron.com', 'Work request', 'Julie, - -Could you print off the current work request report by 1:30 today? - -Gentlemen, - -I''d like to review this today at 1:30 in our office. Also, could you provide -me with your activity reports so I can have Julie enter this information. - -JD'); -INSERT INTO email([from],[to],subject,body) VALUES('v.weldon@enron.com', 'gary.l.carrier@usa.dupont.com, scott.joyce@bankofamerica.com', 'Enron News', 'This could turn into something big.... -http://biz.yahoo.com/rf/010129/n29305829.html'); -INSERT INTO email([from],[to],subject,body) VALUES('mark.haedicke@enron.com', 'paul.simons@enron.com', 'Re: First Polish Deal!', 'Congrats! Things seem to be building rapidly now on the Continent. Mark'); -INSERT INTO email([from],[to],subject,body) VALUES('e..carter@enron.com', 't..robinson@enron.com', 'FW: Producers Newsletter 9-24-2001', ' -The producer lumber pricing sheet. - -----Original Message----- -From: Johnson, Jay -Sent: Tuesday, October 16, 2001 3:42 PM -To: Carter, Karen E. -Subject: FW: Producers Newsletter 9-24-2001 - - - - -----Original Message----- -From: Daigre, Sergai -Sent: Friday, September 21, 2001 8:33 PM -Subject: Producers Newsletter 9-24-2001 - - '); -INSERT INTO email([from],[to],subject,body) VALUES('david.delainey@enron.com', 'kenneth.lay@enron.com', 'Greater Houston Partnership', 'Ken, in response to the letter from Mr Miguel San Juan, my suggestion would -be to offer up the Falcon for their use; however, given the tight time frame -and your recent visit with Mr. Fox that it would be difficult for either you -or me to participate. - -I spoke to Max and he agrees with this approach. - -I hope this meets with your approval. - -Regards -Delainey'); -INSERT INTO email([from],[to],subject,body) VALUES('lachandra.fenceroy@enron.com', 'lindy.donoho@enron.com', 'FW: Bus Applications Meeting Follow Up', 'Lindy, - -Here is the original memo we discussed earlier. Please provide any information that you may have. - -Your cooperation is greatly appreciated. - -Thanks, - -lachandra.fenceroy@enron.com -713.853.3884 -877.498.3401 Pager - - -----Original Message----- -From: Bisbee, Joanne -Sent: Wednesday, September 26, 2001 7:50 AM -To: Fenceroy, LaChandra -Subject: FW: Bus Applications Meeting Follow Up - -Lachandra, Please get with David Duff today and see what this is about. Who are our TW accounting business users? - - -----Original Message----- -From: Koh, Wendy -Sent: Tuesday, September 25, 2001 2:41 PM -To: Bisbee, Joanne -Subject: Bus Applications Meeting Follow Up - -Lisa brought up a TW change effective Nov 1. It involves eliminating a turnback surcharge. I have no other information, but you might check with the business folks for any system changes required. - -Wendy'); -INSERT INTO email([from],[to],subject,body) VALUES('danny.mccarty@enron.com', 'fran.fagan@enron.com', 'RE: worksheets', 'Fran, - If Julie''s merit needs to be lump sum, just move it over to that column. Also, send me Eric Gadd''s sheets as well. Thanks. -Dan - - -----Original Message----- -From: Fagan, Fran -Sent: Thursday, December 20, 2001 11:10 AM -To: McCarty, Danny -Subject: worksheets - -As discussed, attached are your sheets for bonus and merit. - -Thanks, - -Fran Fagan -Sr. HR Rep -713.853.5219 - - - << File: McCartyMerit.xls >> << File: mccartyBonusCommercial_UnP.xls >> - -'); -INSERT INTO email([from],[to],subject,body) VALUES('bert.meyers@enron.com', 'shift.dl-portland@enron.com', 'OCTOBER SCHEDULE', 'TEAM, - -PLEASE SEND ME ANY REQUESTS THAT YOU HAVE FOR OCTOBER. SO FAR I HAVE THEM FOR LEAF. I WOULD LIKE TO HAVE IT DONE BY THE 15TH OF THE MONTH. ANY QUESTIONS PLEASE GIVE ME A CALL. - -BERT'); -INSERT INTO email([from],[to],subject,body) VALUES('errol.mclaughlin@enron.com', 'john.arnold@enron.com, bilal.bajwa@enron.com, john.griffith@enron.com,', 'TRV Notification: (NG - PROPT P/L - 09/27/2001)', 'The report named: NG - PROPT P/L , published as of 09/27/2001 is now available for viewing on the website.'); -INSERT INTO email([from],[to],subject,body) VALUES('patrice.mims@enron.com', 'calvin.eakins@enron.com', 'Re: Small business supply assistance', 'Hi Calvin - - -I spoke with Rickey (boy, is he long-winded!!). Gave him the name of our -credit guy, Russell Diamond. - -Thank for your help!'); -INSERT INTO email([from],[to],subject,body) VALUES('legal <.hall@enron.com>', 'stephanie.panus@enron.com', 'Termination update', 'City of Vernon and Salt River Project terminated their contracts. I will fax these notices to you.'); -INSERT INTO email([from],[to],subject,body) VALUES('d..steffes@enron.com', 'richard.shapiro@enron.com', 'EES / ENA Government Affairs Staffing & Outside Services', 'Rick -- - -Here is the information on staffing and outside services. Call if you need anything else. - -Jim - - '); -INSERT INTO email([from],[to],subject,body) VALUES('gelliott@industrialinfo.com', 'pcopello@industrialinfo.com', 'ECAAR (Gavin), WSCC (Diablo Canyon), & NPCC (Seabrook)', 'Dear Power Outage Database Customer, -Attached you will find an excel document. The outages contained within are forced or rescheduled outages. Your daily delivery will still contain these outages. -In addition to the two excel documents, there is a dbf file that is formatted like your daily deliveries you receive nightly. This will enable you to load the data into your regular database. Any questions please let me know. Thanks. -Greg Elliott -IIR, Inc. -713-783-5147 x 3481 -outages@industrialinfo.com -THE INFORMATION CONTAINED IN THIS E-MAIL IS LEGALLY PRIVILEGED AND CONFIDENTIAL INFORMATION INTENDED ONLY FOR THE USE OF THE INDIVIDUAL OR ENTITY NAMED ABOVE. YOU ARE HEREBY NOTIFIED THAT ANY DISSEMINATION, DISTRIBUTION, OR COPY OF THIS E-MAIL TO UNAUTHORIZED ENTITIES IS STRICTLY PROHIBITED. IF YOU HAVE RECEIVED THIS -E-MAIL IN ERROR, PLEASE DELETE IT. - - OUTAGE.dbf - - 111201R.xls - - 111201.xls '); -INSERT INTO email([from],[to],subject,body) VALUES('enron.announcements@enron.com', 'all_ena_egm_eim@enron.com', 'EWS Brown Bag', 'MARK YOUR LUNCH CALENDARS NOW ! - -You are invited to attend the EWS Brown Bag Lunch Series - -Featuring: RAY BOWEN, COO - -Topic: Enron Industrial Markets - -Thursday, March 15, 2001 -11:30 am - 12:30 pm -EB 5 C2 - - -You bring your lunch, Limited Seating -We provide drinks and dessert. RSVP x 3-9610'); -INSERT INTO email([from],[to],subject,body) VALUES('chris.germany@enron.com', 'ingrid.immer@williams.com', 'Re: About St Pauls', 'Sounds good to me. I bet this is next to the Warick?? Hotel. - - - - -"Immer, Ingrid" on 12/21/2000 11:48:47 AM -To: "''chris.germany@enron.com''" -cc: -Subject: About St Pauls - - - - - <> -? -?http://www.stpaulshouston.org/about.html - -Chris, - -I like the looks of this place.? What do you think about going here Christmas -eve?? They have an 11:00 a.m. service and a candlelight service at 5:00 p.m., -among others. - -Let me know.?? ii - - - About St Pauls.url - -'); -INSERT INTO email([from],[to],subject,body) VALUES('nas@cpuc.ca.gov', 'skatz@sempratrading.com, kmccrea@sablaw.com, thompson@wrightlaw.com,', 'Reply Brief filed July 31, 2000', ' - CPUC01-#76371-v1-Revised_Reply_Brief__Due_today_7_31_.doc'); -INSERT INTO email([from],[to],subject,body) VALUES('gascontrol@aglresources.com', 'dscott4@enron.com, lcampbel@enron.com', 'Alert Posted 10:00 AM November 20,2000: E-GAS Request Reminder', 'Alert Posted 10:00 AM November 20,2000: E-GAS Request Reminder -As discussed in the Winter Operations Meeting on Sept.29,2000, -E-Gas(Emergency Gas) will not be offered this winter as a service from AGLC. -Marketers and Poolers can receive gas via Peaking and IBSS nominations(daisy -chain) from other marketers up to the 6 p.m. Same Day 2 nomination cycle. -'); -INSERT INTO email([from],[to],subject,body) VALUES('dutch.quigley@enron.com', 'rwolkwitz@powermerchants.com', '', ' - -Here is a goody for you'); -INSERT INTO email([from],[to],subject,body) VALUES('ryan.o''rourke@enron.com', 'k..allen@enron.com, randy.bhatia@enron.com, frank.ermis@enron.com,', 'TRV Notification: (West VaR - 11/07/2001)', 'The report named: West VaR , published as of 11/07/2001 is now available for viewing on the website.'); -INSERT INTO email([from],[to],subject,body) VALUES('mjones7@txu.com', 'cstone1@txu.com, ggreen2@txu.com, timpowell@txu.com,', 'Enron / HPL Actuals for July 10, 2000', 'Teco Tap 10.000 / Enron ; 110.000 / HPL IFERC - -LS HPL LSK IC 30.000 / Enron -'); -INSERT INTO email([from],[to],subject,body) VALUES('susan.pereira@enron.com', 'kkw816@aol.com', 'soccer practice', 'Kathy- - -Is it safe to assume that practice is cancelled for tonight?? - -Susan Pereira'); -INSERT INTO email([from],[to],subject,body) VALUES('mark.whitt@enron.com', 'barry.tycholiz@enron.com', 'Huber Internal Memo', 'Please look at this. I didn''t know how deep to go with the desk. Do you think this works. - - '); -INSERT INTO email([from],[to],subject,body) VALUES('m..forney@enron.com', 'george.phillips@enron.com', '', 'George, -Give me a call and we will further discuss opportunities on the 13st floor. - -Thanks, -JMForney -3-7160'); -INSERT INTO email([from],[to],subject,body) VALUES('brad.mckay@enron.com', 'angusmcka@aol.com', 'Re: (no subject)', 'not yet'); -INSERT INTO email([from],[to],subject,body) VALUES('adam.bayer@enron.com', 'jonathan.mckay@enron.com', 'FW: Curve Fetch File', 'Here is the curve fetch file sent to me. It has plenty of points in it. If you give me a list of which ones you need we may be able to construct a secondary worksheet to vlookup the values. - -adam -35227 - - - -----Original Message----- -From: Royed, Jeff -Sent: Tuesday, September 25, 2001 11:37 AM -To: Bayer, Adam -Subject: Curve Fetch File - -Let me know if it works. It may be required to have a certain version of Oracle for it to work properly. - - - -Jeff Royed -Enron -Energy Operations -Phone: 713-853-5295'); -INSERT INTO email([from],[to],subject,body) VALUES('matt.smith@enron.com', 'yan.wang@enron.com', 'Report Formats', 'Yan, - -The merged reports look great. I believe the only orientation changes are to -"unmerge" the following six reports: - -31 Keystone Receipts -15 Questar Pipeline -40 Rockies Production -22 West_2 -23 West_3 -25 CIG_WIC - -The orientation of the individual reports should be correct. Thanks. - -Mat - -PS. Just a reminder to add the "*" by the title of calculated points.'); -INSERT INTO email([from],[to],subject,body) VALUES('michelle.lokay@enron.com', 'jimboman@bigfoot.com', 'Egyptian Festival', '---------------------- Forwarded by Michelle Lokay/ET&S/Enron on 09/07/2000 -10:08 AM --------------------------- - - -"Karkour, Randa" on 09/07/2000 09:01:04 AM -To: "''Agheb (E-mail)" , "Leila Mankarious (E-mail)" -, "''Marymankarious (E-mail)" -, "Michelle lokay (E-mail)" , "Ramy -Mankarious (E-mail)" -cc: - -Subject: Egyptian Festival - - - <> - - http://www.egyptianfestival.com/ - - - Egyptian Festival.url -'); -INSERT INTO email([from],[to],subject,body) VALUES('errol.mclaughlin@enron.com', 'sherry.dawson@enron.com', 'Urgent!!! --- New EAST books', 'This has to be done.................................. - -Thanks ----------------------- Forwarded by Errol McLaughlin/Corp/Enron on 12/20/2000 -08:39 AM --------------------------- - - - - From: William Kelly @ ECT 12/20/2000 08:31 AM - - -To: Kam Keiser/HOU/ECT@ECT, Darron C Giron/HOU/ECT@ECT, David -Baumbach/HOU/ECT@ECT, Errol McLaughlin/Corp/Enron@ENRON -cc: Kimat Singla/HOU/ECT@ECT, Kulvinder Fowler/NA/Enron@ENRON, Kyle R -Lilly/HOU/ECT@ECT, Jeff Royed/Corp/Enron@ENRON, Alejandra -Chavez/NA/Enron@ENRON, Crystal Hyde/HOU/ECT@ECT - -Subject: New EAST books - -We have new book names in TAGG for our intramonth portfolios and it is -extremely important that any deal booked to the East is communicated quickly -to someone on my team. I know it will take some time for the new names to -sink in and I do not want us to miss any positions or P&L. - -Thanks for your help on this. - -New: -Scott Neal : East Northeast -Dick Jenkins: East Marketeast - -WK -'); -INSERT INTO email([from],[to],subject,body) VALUES('david.forster@enron.com', 'eol.wide@enron.com', 'Change to Stack Manager', 'Effective immediately, there is a change to the Stack Manager which will -affect any Inactive Child. - -An inactive Child with links to Parent products will not have their -calculated prices updated until the Child product is Activated. - -When the Child Product is activated, the price will be recalculated and -updated BEFORE it is displayed on the web. - -This means that if you are inputting a basis price on a Child product, you -will not see the final, calculated price until you Activate the product, at -which time the customer will also see it. - -If you have any questions, please contact the Help Desk on: - -Americas: 713 853 4357 -Europe: + 44 (0) 20 7783 7783 -Asia/Australia: +61 2 9229 2300 - -Dave'); -INSERT INTO email([from],[to],subject,body) VALUES('vince.kaminski@enron.com', 'jhh1@email.msn.com', 'Re: Light reading - see pieces beginning on page 7', 'John, - -I saw it. Very interesting. - -Vince - - - - - -"John H Herbert" on 07/28/2000 08:38:08 AM -To: "Vince J Kaminski" -cc: -Subject: Light reading - see pieces beginning on page 7 - - -Cheers and have a nice weekend, - - -JHHerbert - - - - - - gd000728.pdf - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('matthew.lenhart@enron.com', 'mmmarcantel@equiva.com', 'RE:', 'i will try to line up a pig for you '); -INSERT INTO email([from],[to],subject,body) VALUES('jae.black@enron.com', 'claudette.harvey@enron.com, chaun.roberts@enron.com, judy.martinez@enron.com,', 'Disaster Recovery Equipment', 'As a reminder...there are several pieces of equipment that are set up on the 30th Floor, as well as on our floor, for the Disaster Recovery Team. PLEASE DO NOT TAKE, BORROW OR USE this equipment. Should you need to use another computer system, other than yours, or make conference calls please work with your Assistant to help find or set up equipment for you to use. - -Thanks for your understanding in this matter. - -T.Jae Black -East Power Trading -Assistant to Kevin Presto -off. 713-853-5800 -fax 713-646-8272 -cell 713-539-4760'); -INSERT INTO email([from],[to],subject,body) VALUES('eric.bass@enron.com', 'dale.neuner@enron.com', '5 X 24', 'Dale, - -Have you heard anything more on the 5 X 24s? We would like to get this -product out ASAP. - - -Thanks, - -Eric'); -INSERT INTO email([from],[to],subject,body) VALUES('messenger@smartreminders.com', 'm..tholt@enron.com', '10% Coupon - PrintPal Printer Cartridges - 100% Guaranteed', '[IMAGE] -[IMAGE][IMAGE][IMAGE] -Dear SmartReminders Member, - [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] - - - - - - - - - - - - - - - - - - - - - -We respect your privacy and are a Certified Participant of the BBBOnLine - Privacy Program. To be removed from future offers,click here. -SmartReminders.com is a permission based service. To unsubscribe click here . '); -INSERT INTO email([from],[to],subject,body) VALUES('benjamin.rogers@enron.com', 'mark.bernstein@enron.com', '', 'The guy you are talking about left CIN under a "cloud of suspicion" sort of -speak. He was the one who got into several bad deals and PPA''s in California -for CIN, thus he left on a bad note. Let me know if you need more detail -than that, I felt this was the type of info you were looking for. Thanks! -Ben'); -INSERT INTO email([from],[to],subject,body) VALUES('enron_update@concureworkplace.com', 'michelle.cash@enron.com', 'Expense Report Receipts Not Received', 'Employee Name: Michelle Cash -Report Name: Houston Cellular 8-11-01 -Report Date: 12/13/01 -Report ID: 594D37C9ED2111D5B452 -Submitted On: 12/13/01 - -You are only allowed 2 reports with receipts outstanding. Your expense reports will not be paid until you meet this requirement.'); -INSERT INTO email([from],[to],subject,body) VALUES('susan.mara@enron.com', 'ray.alvarez@enron.com, mark.palmer@enron.com, karen.denne@enron.com,', 'CAISO Emergency Motion -- to discontinue market-based rates for', 'FYI. the latest broadside against the generators. - -Sue Mara -Enron Corp. -Tel: (415) 782-7802 -Fax:(415) 782-7854 ------ Forwarded by Susan J Mara/NA/Enron on 06/08/2001 12:24 PM ----- - - - "Milner, Marcie" 06/08/2001 11:13 AM To: "''smara@enron.com''" cc: Subject: CAISO Emergency Motion - - -Sue, did you see this emergency motion the CAISO filed today? Apparently -they are requesting that FERC discontinue market-based rates immediately and -grant refunds plus interest on the difference between cost-based rates and -market revenues received back to May 2000. They are requesting the -commission act within 14 days. Have you heard anything about what they are -doing? - -Marcie - -http://www.caiso.com/docs/2001/06/08/200106081005526469.pdf -'); -INSERT INTO email([from],[to],subject,body) VALUES('fletcher.sturm@enron.com', 'eloy.escobar@enron.com', 'Re: General Brinks Position Meeting', 'Eloy, - -Who is General Brinks? - -Fletch'); -INSERT INTO email([from],[to],subject,body) VALUES('nailia.dindarova@enron.com', 'richard.shapiro@enron.com', 'Documents for Mark Frevert (on EU developments and lessons from', 'Rick, - -Here are the documents that Peter has prepared for Mark Frevert. - -Nailia ----------------------- Forwarded by Nailia Dindarova/LON/ECT on 25/06/2001 -16:36 --------------------------- - - -Nailia Dindarova -25/06/2001 15:36 -To: Michael Brown/Enron@EUEnronXGate -cc: Ross Sankey/Enron@EUEnronXGate, Eric Shaw/ENRON@EUEnronXGate, Peter -Styles/LON/ECT@ECT - -Subject: Documents for Mark Frevert (on EU developments and lessons from -California) - -Michael, - - -These are the documents that Peter promised to give to you for Mark Frevert. -He has now handed them to him in person but asked me to transmit them -electronically to you, as well as Eric and Ross. - -Nailia - - - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('peggy.a.kostial@accenture.com', 'dave.samuels@enron.com', 'EOL-Accenture Deal Sheet', 'Dave - - -Attached are our comments and suggested changes. Please call to review. - -On the time line for completion, we have four critical steps to complete: - Finalize market analysis to refine business case, specifically - projected revenue stream - Complete counterparty surveying, including targeting 3 CPs for letters - of intent - Review Enron asset base for potential reuse/ licensing - Contract negotiations - -Joe will come back to us with an updated time line, but it is my -expectation that we are still on the same schedule (we just begun week -three) with possibly a week or so slippage.....contract negotiations will -probably be the critical path. - -We will send our cut at the actual time line here shortly. Thanks, - -Peggy - -(See attached file: accenture-dealpoints v2.doc) - - accenture-dealpoints v2.doc '); -INSERT INTO email([from],[to],subject,body) VALUES('thomas.martin@enron.com', 'thomas.martin@enron.com', 'Re: Guadalupe Power Partners LP', '---------------------- Forwarded by Thomas A Martin/HOU/ECT on 03/20/2001 -03:49 PM --------------------------- - - -Thomas A Martin -10/11/2000 03:55 PM -To: Patrick Wade/HOU/ECT@ECT -cc: -Subject: Re: Guadalupe Power Partners LP - -The deal is physically served at Oasis Waha or Oasis Katy and is priced at -either HSC, Waha or Katytailgate GD at buyers option three days prior to -NYMEX close. - -'); -INSERT INTO email([from],[to],subject,body) VALUES('judy.townsend@enron.com', 'dan.junek@enron.com, chris.germany@enron.com', 'Columbia Distribution''s Capacity Available for Release - Sum', '---------------------- Forwarded by Judy Townsend/HOU/ECT on 03/09/2001 11:04 -AM --------------------------- - - -agoddard@nisource.com on 03/08/2001 09:16:57 AM -To: " - *Koch, Kent" , " - -*Millar, Debra" , " - *Burke, Lynn" - -cc: " - *Heckathorn, Tom" -Subject: Columbia Distribution''s Capacity Available for Release - Sum - - -Attached is Columbia Distribution''s notice of capacity available for release -for -the summer of 2001 (Apr. 2001 through Oct. 2001). - -Please note that the deadline for bids is 3:00pm EST on March 20, 2001. - -If you have any questions, feel free to contact any of the representatives -listed -at the bottom of the attachment. - -Aaron Goddard - - - - - - 2001Summer.doc -'); -INSERT INTO email([from],[to],subject,body) VALUES('rhonda.denton@enron.com', 'tim.belden@enron.com, dana.davis@enron.com, genia.fitzgerald@enron.com,', 'Split Rock Energy LLC', 'We have received the executed EEI contract from this CP dated 12/12/2000. -Copies will be distributed to Legal and Credit.'); -INSERT INTO email([from],[to],subject,body) VALUES('kerrymcelroy@dwt.com', 'jack.speer@alcoa.com, crow@millernash.com, michaelearly@earthlink.net,', 'Oral Argument Request', ' - Oral Argument Request.doc'); -INSERT INTO email([from],[to],subject,body) VALUES('mike.carson@enron.com', 'rlmichaelis@hormel.com', '', 'Did you come in town this wk end..... My new number at our house is : -713-668-3712...... my cell # is 281-381-7332 - -the kid'); -INSERT INTO email([from],[to],subject,body) VALUES('cooper.richey@enron.com', 'trycooper@hotmail.com', 'FW: Contact Info', ' - ------Original Message----- -From: Punja, Karim -Sent: Thursday, December 13, 2001 2:35 PM -To: Richey, Cooper -Subject: Contact Info - - -Cooper, - -Its been a real pleasure working with you (even though it was for only a small amount of time) -I hope we can stay in touch. - -Home# 234-0249 -email: kpunja@hotmail.com - -Take Care, - -Karim. - '); -INSERT INTO email([from],[to],subject,body) VALUES('bjm30@earthlink.net', 'mcguinn.k@enron.com, mcguinn.ian@enron.com, mcguinn.stephen@enron.com,', 'email address change', 'Hello all. - -I haven''t talked to many of you via email recently but I do want to give you -my new address for your email file: - - bjm30@earthlink.net - -I hope all is well. - -Brian McGuinn'); -INSERT INTO email([from],[to],subject,body) VALUES('shelley.corman@enron.com', 'steve.hotte@enron.com', 'Flat Panels', 'Can you please advise what is going on with the flat panels that we had planned to distribute to our gas logistics team. It was in the budget and we had the okay, but now I''m hearing there is some hold-up & the units are stored on 44. - -Shelley'); -INSERT INTO email([from],[to],subject,body) VALUES('sara.davidson@enron.com', 'john.schwartzenburg@enron.com, scott.dieball@enron.com, recipients@enron.com,', '2001 Enron Law Conference (Distribution List 2)', ' Enron Law Conference - -San Antonio, Texas May 2-4, 2001 Westin Riverwalk - - See attached memo for more details!! - - -? Registration for the law conference this year will be handled through an -Online RSVP Form on the Enron Law Conference Website at -http://lawconference.corp.enron.com. The website is still under construction -and will not be available until Thursday, March 15, 2001. - -? We will send you another e-mail to confirm when the Law Conference Website -is operational. - -? Please complete the Online RSVP Form as soon as it is available and submit -it no later than Friday, March 30th. - - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('tori.kuykendall@enron.com', 'heath.b.taylor@accenture.com', 'Re:', 'hey - thats funny about john - he definitely remembers him - i''ll call pat -and let him know - we are coming on saturday - i just havent had a chance to -call you guys back -- looking forward to it -- i probably need the -directions again though'); -INSERT INTO email([from],[to],subject,body) VALUES('darron.giron@enron.com', 'bryce.baxter@enron.com', 'Re: Feedback for Audrey Cook', 'Bryce, - -I''ll get it done today. - -DG 3-9573 - - - - - - From: Bryce Baxter 06/12/2000 07:15 PM - - -To: Darron C Giron/HOU/ECT@ECT -cc: -Subject: Feedback for Audrey Cook - -You were identified as a reviewer for Audrey Cook. If possible, could you -complete her feedback by end of business Wednesday? It will really help me -in the PRC process to have your input. Thanks. - -'); -INSERT INTO email([from],[to],subject,body) VALUES('casey.evans@enron.com', 'stephanie.sever@enron.com', 'Gas EOL ID', 'Stephanie, - -In conjunction with the recent movement of several power traders, they are changing the names of their gas books as well. The names of the new gas books and traders are as follows: - -PWR-NG-LT-SPP: Mike Carson -PWR-NG-LT-SERC: Jeff King - -If you need to know their power desk to map their ID to their gas books, those desks are as follows: - -EPMI-LT-SPP: Mike Carson -EPMI-LT-SERC: Jeff King - -I will be in training this afternoon, but will be back when class is over. Let me know if you have any questions. - -Thanks for your help! -Casey'); -INSERT INTO email([from],[to],subject,body) VALUES('darrell.schoolcraft@enron.com', 'david.roensch@enron.com, kimberly.watson@enron.com, michelle.lokay@enron.com,', 'Postings', 'Please see the attached. - - -ds - - - - - '); -INSERT INTO email([from],[to],subject,body) VALUES('mcominsky@aol.com', 'cpatman@bracepatt.com, james_derrick@enron.com', 'Jurisprudence Luncheon', 'Carrin & Jim -- - -It was an honor and a pleasure to meet both of you yesterday. I know we will -have fun working together on this very special event. - -Jeff left the jurisprudence luncheon lists for me before he left on vacation. - I wasn''t sure whether he transmitted them to you as well. Would you please -advise me if you would like them sent to you? I can email the MS Excel files -or I can fax the hard copies to you. Please advise what is most convenient. - -I plan to be in town through the holidays and can be reached by phone, email, -or cell phone at any time. My cell phone number is 713/705-4829. - -Thanks again for your interest in the ADL''s work. Martin. - -Martin B. Cominsky -Director, Southwest Region -Anti-Defamation League -713/627-3490, ext. 122 -713/627-2011 (fax) -MCominsky@aol.com'); -INSERT INTO email([from],[to],subject,body) VALUES('phillip.love@enron.com', 'todagost@utmb.edu, gbsonnta@utmb.edu', 'New President', 'I had a little bird put a word in my ear. Is there any possibility for Ben -Raimer to be Bush''s secretary of HHS? Just curious about that infamous UTMB -rumor mill. Hope things are well, happy holidays. -PL'); -INSERT INTO email([from],[to],subject,body) VALUES('marie.heard@enron.com', 'ehamilton@fna.com', 'ISDA Master Agreement', 'Erin: - -Pursuant to your request, attached are the Schedule to the ISDA Master Agreement, together with Paragraph 13 to the ISDA Credit Support Annex. Please let me know if you need anything else. We look forward to hearing your comments. - -Marie - -Marie Heard -Senior Legal Specialist -Enron North America Corp. -Phone: (713) 853-3907 -Fax: (713) 646-3490 -marie.heard@enron.com - - '); -INSERT INTO email([from],[to],subject,body) VALUES('andrea.ring@enron.com', 'beverly.beaty@enron.com', 'Re: Tennessee Buy - Louis Dreyfus', 'Beverly - once again thanks so much for your help on this. - - - - '); -INSERT INTO email([from],[to],subject,body) VALUES('karolyn.criado@enron.com', 'j..bonin@enron.com, felicia.case@enron.com, b..clapp@enron.com,', 'Price List week of Oct. 8-9, 2001', ' -Please contact me if you have any questions regarding last weeks prices. - -Thank you, -Karolyn Criado -3-9441 - - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('kevin.presto@enron.com', 'edward.baughman@enron.com, billy.braddock@enron.com', 'Associated', 'Please begin working on filling our Associated short position in 02. I would like to take this risk off the books. - -In addition, please find out what a buy-out of VEPCO would cost us. With Rogers transitioning to run our retail risk management, I would like to clean up our customer positions. - -We also need to continue to explore a JEA buy-out. - -Thanks.'); -INSERT INTO email([from],[to],subject,body) VALUES('stacy.dickson@enron.com', 'gregg.penman@enron.com', 'RE: Constellation TC 5-7-01', 'Gregg, - -I am at home with a sick baby. (Lots of fun!) I will call you about this -tomorrow. - -Stacy'); -INSERT INTO email([from],[to],subject,body) VALUES('joe.quenet@enron.com', 'dfincher@utilicorp.com', '', 'hey big guy.....check this out..... - - w ww.gorelieberman-2000.com/'); -INSERT INTO email([from],[to],subject,body) VALUES('k..allen@enron.com', 'jacqestc@aol.com', '', 'Jacques, - -I sent you a fax of Kevin Kolb''s comments on the release. The payoff on the note would be $36,248 ($36090(principal) + $158 (accrued interest)). -This is assuming we wrap this up on Tuesday. - -Please email to confirm that their changes are ok so I can set up a meeting on Tuesday to reach closure. - -Phillip'); -INSERT INTO email([from],[to],subject,body) VALUES('kourtney.nelson@enron.com', 'mike.swerzbin@enron.com', 'Adjusted L/R Balance', 'Mike, - -I placed the adjusted L/R Balance on the Enronwest site. It is under the "Staff/Kourtney Nelson". There are two links: - -1) "Adj L_R" is the same data/format from the weekly strategy meeting. -2) "New Gen 2001_2002" link has all of the supply side info that is used to calculate the L/R balance - -Please note the Data Flag column, a value of "3" indicates the project was cancelled, on hold, etc and is not included in the calc. - -Both of these sheets are interactive Excel spreadsheets and thus you can play around with the data as you please. Also, James Bruce is working to get his gen report on the web. That will help with your access to information on new gen. - -Please let me know if you have any questions or feedback, - -Kourtney - - - -Kourtney Nelson -Fundamental Analysis -Enron North America -(503) 464-8280 -kourtney.nelson@enron.com'); -INSERT INTO email([from],[to],subject,body) VALUES('d..thomas@enron.com', 'naveed.ahmed@enron.com', 'FW: Current Enron TCC Portfolio', ' - ------Original Message----- -From: Grace, Rebecca M. -Sent: Monday, December 17, 2001 9:44 AM -To: Thomas, Paul D. -Cc: Cashion, Jim; Allen, Thresa A.; May, Tom -Subject: RE: Current Enron TCC Portfolio - - -Paul, - -I reviewed NY''s list. I agree with all of their contracts numbers and mw amounts. - -Call if you have any more questions. - -Rebecca - - - - -----Original Message----- -From: Thomas, Paul D. -Sent: Monday, December 17, 2001 9:08 AM -To: Grace, Rebecca M. -Subject: FW: Current Enron TCC Portfolio - - << File: enrontccs.xls >> -Rebecca, -Let me know if you see any differences. - -Paul -X 3-0403 ------Original Message----- -From: Thomas, Paul D. -Sent: Monday, December 17, 2001 9:04 AM -To: Ahmed, Naveed -Subject: FW: Current Enron TCC Portfolio - - - - ------Original Message----- -From: Thomas, Paul D. -Sent: Thursday, December 13, 2001 10:01 AM -To: Baughman, Edward D. -Subject: Current Enron TCC Portfolio - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('stephanie.panus@enron.com', 'william.bradford@enron.com, debbie.brackett@enron.com,', 'Coastal Merchant Energy/El Paso Merchant Energy', 'Coastal Merchant Energy, L.P. merged with and into El Paso Merchant Energy, -L.P., effective February 1, 2001, with the surviving entity being El Paso -Merchant Energy, L.P. We currently have ISDA Master Agreements with both -counterparties. Please see the attached memo regarding the existing Masters -and let us know which agreement should be terminated. - -Thanks, -Stephanie -'); -INSERT INTO email([from],[to],subject,body) VALUES('kam.keiser@enron.com', 'c..kenne@enron.com', 'RE: What about this too???', ' - - -----Original Message----- -From: Kenne, Dawn C. -Sent: Wednesday, February 06, 2002 11:50 AM -To: Keiser, Kam -Subject: What about this too??? - - - << File: Netco Trader Matrix.xls >> - '); -INSERT INTO email([from],[to],subject,body) VALUES('chris.meyer@enron.com', 'joe.parks@enron.com', 'Centana', 'Talked to Chip. We do need Cash Committe approval given the netting feature of your deal, which means Batch Funding Request. Please update per my previous e-mail and forward. - -Thanks - -chris -x31666'); -INSERT INTO email([from],[to],subject,body) VALUES('debra.perlingiere@enron.com', 'jworman@academyofhealth.com', '', 'Have a great weekend! Happy Fathers Day! - - -Debra Perlingiere -Enron North America Corp. -1400 Smith Street, EB 3885 -Houston, Texas 77002 -dperlin@enron.com -Phone 713-853-7658 -Fax 713-646-3490'); -INSERT INTO email([from],[to],subject,body) VALUES('outlook.team@enron.com', '', 'Demo by Martha Janousek of Dashboard & Pipeline Profile / Julia &', 'CALENDAR ENTRY: APPOINTMENT - -Description: - Demo by Martha Janousek of Dashboard & Pipeline Profile / Julia & Dir Rpts. - 4102 - -Date: 1/5/2001 -Time: 9:00 AM - 10:00 AM (Central Standard Time) - -Chairperson: Outlook Migration Team - -Detailed Description:'); -INSERT INTO email([from],[to],subject,body) VALUES('diana.seifert@enron.com', 'mark.taylor@enron.com', 'Guest access Chile', 'Hello Mark, - -Justin Boyd told me that your can help me with questions regarding Chile. -We got a request for guest access through MG. -The company is called Escondida and is a subsidiary of BHP Australia. - -Please advise if I can set up a guest account or not. -F.Y.I.: MG is planning to put a "in w/h Chile" contract for Copper on-line as -soon as Enron has done the due diligence for this country. -Thanks ! - - -Best regards - -Diana Seifert -EOL PCG'); -INSERT INTO email([from],[to],subject,body) VALUES('enron_update@concureworkplace.com', 'mark.whitt@enron.com', '<> - 121001', 'The Approval status has changed on the following report: - -Status last changed by: Barry L. Tycholiz -Expense Report Name: 121001 -Report Total: $198.98 -Amount Due Employee: $198.98 -Amount Approved: $198.98 -Amount Paid: $0.00 -Approval Status: Approved -Payment Status: Pending - - -To review this expense report, click on the following link for Concur Expense. -http://expensexms.enron.com'); -INSERT INTO email([from],[to],subject,body) VALUES('kevin.hyatt@enron.com', '', 'Technical Support', 'Outside the U.S., please refer to the list below: - -Australia: -1800 678-515 -support@palm-au.com - -Canada: -1905 305-6530 -support@palm.com - -New Zealand: -0800 446-398 -support@palm-nz.com - -U.K.: -0171 867 0108 -eurosupport@palm.3com.com - -Please refer to the Worldwide Customer Support card for a complete technical support contact list.'); -INSERT INTO email([from],[to],subject,body) VALUES('geoff.storey@enron.com', 'dutch.quigley@enron.com', 'RE:', 'duke contact? - - -----Original Message----- -From: Quigley, Dutch -Sent: Wednesday, October 31, 2001 10:14 AM -To: Storey, Geoff -Subject: RE: - -bp corp Albert LaMore 281-366-4962 - -running the reports now - - - -----Original Message----- -From: Storey, Geoff -Sent: Wednesday, October 31, 2001 10:10 AM -To: Quigley, Dutch -Subject: RE: - -give me a contact over there too -BP - - - -----Original Message----- -From: Quigley, Dutch -Sent: Wednesday, October 31, 2001 9:42 AM -To: Storey, Geoff -Subject: - -Coral Jeff Whitnah 713-767-5374 -Relaint Steve McGinn 713-207-4000'); -INSERT INTO email([from],[to],subject,body) VALUES('pete.davis@enron.com', 'pete.davis@enron.com', 'Start Date: 4/22/01; HourAhead hour: 3; ', 'Start Date: 4/22/01; HourAhead hour: 3; No ancillary schedules awarded. -Variances detected. -Variances detected in Load schedule. - - LOG MESSAGES: - -PARSING FILE -->> O:\Portland\WestDesk\California Scheduling\ISO Final -Schedules\2001042203.txt - ----- Load Schedule ---- -$$$ Variance found in table tblLoads. - Details: (Hour: 3 / Preferred: 1.92 / Final: 1.89) - TRANS_TYPE: FINAL - LOAD_ID: PGE4 - MKT_TYPE: 2 - TRANS_DATE: 4/22/01 - SC_ID: EPMI - -'); -INSERT INTO email([from],[to],subject,body) VALUES('john.postlethwaite@enron.com', 'john.zufferli@enron.com', 'Reference', 'John, hope things are going well up there for you. The big day is almost here for you and Jessica. I was wondering if I could use your name as a job reference if need be. I am just trying to get everything in order just in case something happens. - -John'); -INSERT INTO email([from],[to],subject,body) VALUES('jeffrey.shankman@enron.com', 'lschiffm@jonesday.com', 'Re:', 'I saw you called on the cell this a.m. Sorry I missed you. (I was in the -shower). I have had a shitty week--I suspect my silence (not only to you, -but others) after our phone call is a result of the week. I''m seeing Glen at -11:15....talk to you'); -INSERT INTO email([from],[to],subject,body) VALUES('litebytz@enron.com', '', 'Lite Bytz RSVP', ' -This week''s Lite Bytz presentation will feature the following TOOLZ speaker: - -Richard McDougall -Solaris 8 -Thursday, June 7, 2001 - -If you have not already signed up, please RSVP via email to litebytz@enron.com by the end of the day Tuesday, June 5, 2001. - -*Remember: this is now a Brown Bag Event--so bring your lunch and we will provide cookies and drinks. - -Click below for more details. - -http://home.enron.com:84/messaging/litebytztoolzprint.jpg'); - COMMIT; - } -} {} - -############################################################################### -# Everything above just builds an interesting test database. The actual -# tests come after this comment. -############################################################################### - -do_test fts1c-1.2 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark' - } -} {6 17 25 38 40 42 73 74} -do_test fts1c-1.3 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'susan' - } -} {24 40} -do_test fts1c-1.4 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark susan' - } -} {40} -do_test fts1c-1.5 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'susan mark' - } -} {40} -do_test fts1c-1.6 { - execsql { - SELECT rowid FROM email WHERE email MATCH '"mark susan"' - } -} {} -do_test fts1c-1.7 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark -susan' - } -} {6 17 25 38 42 73 74} -do_test fts1c-1.8 { - execsql { - SELECT rowid FROM email WHERE email MATCH '-mark susan' - } -} {24} -do_test fts1c-1.9 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark OR susan' - } -} {6 17 24 25 38 40 42 73 74} - -# Some simple tests of the automatic "offsets(email)" column. In the sample -# data set above, only one message, number 20, contains the words -# "gas" and "reminder" in both body and subject. -# -do_test fts1c-2.1 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE email MATCH 'gas reminder' - } -} {20 {2 0 42 3 2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}} -do_test fts1c-2.2 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE email MATCH 'subject:gas reminder' - } -} {20 {2 0 42 3 2 1 54 8 3 1 54 8}} -do_test fts1c-2.3 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE email MATCH 'body:gas reminder' - } -} {20 {2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}} -do_test fts1c-2.4 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE subject MATCH 'gas reminder' - } -} {20 {2 0 42 3 2 1 54 8}} -do_test fts1c-2.5 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE body MATCH 'gas reminder' - } -} {20 {3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}} - -# Document 32 contains 5 instances of the world "child". But only -# 3 of them are paired with "product". Make sure only those instances -# that match the phrase appear in the offsets(email) list. -# -do_test fts1c-3.1 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE body MATCH 'child product' AND +rowid=32 - } -} {32 {3 0 94 5 3 0 114 5 3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7 3 1 493 7}} -do_test fts1c-3.2 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE body MATCH '"child product"' - } -} {32 {3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7}} - -# Snippet generator tests -# -do_test fts1c-4.1 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'subject:gas reminder' - } -} {{Alert Posted 10:00 AM November 20,2000: E-GAS Request Reminder}} -do_test fts1c-4.2 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'christmas candlelight' - } -} {{... place.? What do you think about going here Christmas -eve?? They have an 11:00 a.m. service and a candlelight service at 5:00 p.m., -among others. ...}} - -do_test fts1c-4.3 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'deal sheet potential reuse' - } -} {{EOL-Accenture Deal Sheet ... intent - Review Enron asset base for potential reuse/ licensing - Contract negotiations ...}} -do_test fts1c-4.4 { - execsql { - SELECT snippet(email,'<<<','>>>',' ') FROM email - WHERE email MATCH 'deal sheet potential reuse' - } -} {{EOL-Accenture <<>> <<>> intent - Review Enron asset base for <<>> <<>>/ licensing - Contract negotiations }} -do_test fts1c-4.5 { - execsql { - SELECT snippet(email,'<<<','>>>',' ') FROM email - WHERE email MATCH 'first things' - } -} {{Re: <<>> Polish Deal! Congrats! <<>> seem to be building rapidly now on the }} -do_test fts1c-4.6 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'chris is here' - } -} {{chris.germany@enron.com ... Sounds good to me. I bet this is next to the Warick?? Hotel. ... place.? What do you think about going here Christmas -eve?? They have an 11:00 a.m. ...}} -do_test fts1c-4.7 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH '"pursuant to"' - } -} {{Erin: - -Pursuant to your request, attached are the Schedule to ...}} -do_test fts1c-4.8 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'ancillary load davis' - } -} {{pete.davis@enron.com ... Start Date: 4/22/01; HourAhead hour: 3; No ancillary schedules awarded. -Variances detected. -Variances detected in Load schedule. - - LOG MESSAGES: - -PARSING ...}} - -# Combinations of AND and OR operators: -# -do_test fts1c-5.1 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'questar enron OR com' - } -} {{matt.smith@enron.com ... six reports: - -31 Keystone Receipts -15 Questar Pipeline -40 Rockies Production -22 West_2 ...}} -do_test fts1c-5.2 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'enron OR com questar' - } -} {{matt.smith@enron.com ... six reports: - -31 Keystone Receipts -15 Questar Pipeline -40 Rockies Production -22 West_2 ...}} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1d.test sqlite3-3.44.0-0/test/fts1d.test --- sqlite3-3.42.0/test/fts1d.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1d.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -# 2006 October 1 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing the FTS1 module, and in particular -# the Porter stemmer. -# -# $Id: fts1d.test,v 1.1 2006/10/01 18:41:21 drh Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -do_test fts1d-1.1 { - execsql { - CREATE VIRTUAL TABLE t1 USING fts1(content, tokenize porter); - INSERT INTO t1(rowid, content) VALUES(1, 'running and jumping'); - SELECT rowid FROM t1 WHERE content MATCH 'run jump'; - } -} {1} -do_test fts1d-1.2 { - execsql { - SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'run jump'; - } -} {{running and jumping}} -do_test fts1d-1.3 { - execsql { - INSERT INTO t1(rowid, content) - VALUES(2, 'abcdefghijklmnopqrstuvwyxz'); - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijqrstuvwyxz' - } -} {2 abcdefghijklmnopqrstuvwyxz} -do_test fts1d-1.4 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijXXXXqrstuvwyxz' - } -} {2 abcdefghijklmnopqrstuvwyxz} -do_test fts1d-1.5 { - execsql { - INSERT INTO t1(rowid, content) - VALUES(3, 'The value is 123456789'); - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123789' - } -} {3 {The value is 123456789}} -do_test fts1d-1.6 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123000000789' - } -} {3 {The value is 123456789}} - - -finish_test diff -Nru sqlite3-3.42.0/test/fts1e.test sqlite3-3.44.0-0/test/fts1e.test --- sqlite3-3.42.0/test/fts1e.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1e.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -# 2006 October 19 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing deletions in the FTS1 module. -# -# $Id: fts1e.test,v 1.1 2006/10/19 23:28:35 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -# Construct a full-text search table containing keywords which are the -# ordinal numbers of the bit positions set for a sequence of integers, -# which are used for the rowid. There are a total of 30 INSERT and -# DELETE statements, so that we'll test both the segmentMerge() merge -# (over the first 16) and the termSelect() merge (over the level-1 -# segment and 14 level-0 segments). -db eval { - CREATE VIRTUAL TABLE t1 USING fts1(content); - INSERT INTO t1 (rowid, content) VALUES(1, 'one'); - INSERT INTO t1 (rowid, content) VALUES(2, 'two'); - INSERT INTO t1 (rowid, content) VALUES(3, 'one two'); - INSERT INTO t1 (rowid, content) VALUES(4, 'three'); - DELETE FROM t1 WHERE rowid = 1; - INSERT INTO t1 (rowid, content) VALUES(5, 'one three'); - INSERT INTO t1 (rowid, content) VALUES(6, 'two three'); - INSERT INTO t1 (rowid, content) VALUES(7, 'one two three'); - DELETE FROM t1 WHERE rowid = 4; - INSERT INTO t1 (rowid, content) VALUES(8, 'four'); - INSERT INTO t1 (rowid, content) VALUES(9, 'one four'); - INSERT INTO t1 (rowid, content) VALUES(10, 'two four'); - DELETE FROM t1 WHERE rowid = 7; - INSERT INTO t1 (rowid, content) VALUES(11, 'one two four'); - INSERT INTO t1 (rowid, content) VALUES(12, 'three four'); - INSERT INTO t1 (rowid, content) VALUES(13, 'one three four'); - DELETE FROM t1 WHERE rowid = 10; - INSERT INTO t1 (rowid, content) VALUES(14, 'two three four'); - INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four'); - INSERT INTO t1 (rowid, content) VALUES(16, 'five'); - DELETE FROM t1 WHERE rowid = 13; - INSERT INTO t1 (rowid, content) VALUES(17, 'one five'); - INSERT INTO t1 (rowid, content) VALUES(18, 'two five'); - INSERT INTO t1 (rowid, content) VALUES(19, 'one two five'); - DELETE FROM t1 WHERE rowid = 16; - INSERT INTO t1 (rowid, content) VALUES(20, 'three five'); - INSERT INTO t1 (rowid, content) VALUES(21, 'one three five'); - INSERT INTO t1 (rowid, content) VALUES(22, 'two three five'); - DELETE FROM t1 WHERE rowid = 19; - DELETE FROM t1 WHERE rowid = 22; -} - -do_test fts1f-1.1 { - execsql {SELECT COUNT(*) FROM t1} -} {14} - -do_test fts1e-2.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'} -} {3 5 9 11 15 17 21} - -do_test fts1e-2.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'} -} {2 3 6 11 14 15 18} - -do_test fts1e-2.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'} -} {5 6 12 14 15 20 21} - -do_test fts1e-2.4 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'} -} {8 9 11 12 14 15} - -do_test fts1e-2.5 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'} -} {17 18 20 21} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1f.test sqlite3-3.44.0-0/test/fts1f.test --- sqlite3-3.42.0/test/fts1f.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1f.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -# 2006 October 19 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing updates in the FTS1 module. -# -# $Id: fts1f.test,v 1.2 2007/02/23 00:14:06 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -# Construct a full-text search table containing keywords which are the -# ordinal numbers of the bit positions set for a sequence of integers, -# which are used for the rowid. There are a total of 31 INSERT, -# UPDATE, and DELETE statements, so that we'll test both the -# segmentMerge() merge (over the first 16) and the termSelect() merge -# (over the level-1 segment and 15 level-0 segments). -db eval { - CREATE VIRTUAL TABLE t1 USING fts1(content); - INSERT INTO t1 (rowid, content) VALUES(1, 'one'); - INSERT INTO t1 (rowid, content) VALUES(2, 'two'); - INSERT INTO t1 (rowid, content) VALUES(3, 'one two'); - INSERT INTO t1 (rowid, content) VALUES(4, 'three'); - INSERT INTO t1 (rowid, content) VALUES(5, 'one three'); - INSERT INTO t1 (rowid, content) VALUES(6, 'two three'); - INSERT INTO t1 (rowid, content) VALUES(7, 'one two three'); - DELETE FROM t1 WHERE rowid = 4; - INSERT INTO t1 (rowid, content) VALUES(8, 'four'); - UPDATE t1 SET content = 'update one three' WHERE rowid = 1; - INSERT INTO t1 (rowid, content) VALUES(9, 'one four'); - INSERT INTO t1 (rowid, content) VALUES(10, 'two four'); - DELETE FROM t1 WHERE rowid = 7; - INSERT INTO t1 (rowid, content) VALUES(11, 'one two four'); - INSERT INTO t1 (rowid, content) VALUES(12, 'three four'); - INSERT INTO t1 (rowid, content) VALUES(13, 'one three four'); - DELETE FROM t1 WHERE rowid = 10; - INSERT INTO t1 (rowid, content) VALUES(14, 'two three four'); - INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four'); - UPDATE t1 SET content = 'update two five' WHERE rowid = 8; - INSERT INTO t1 (rowid, content) VALUES(16, 'five'); - DELETE FROM t1 WHERE rowid = 13; - INSERT INTO t1 (rowid, content) VALUES(17, 'one five'); - INSERT INTO t1 (rowid, content) VALUES(18, 'two five'); - INSERT INTO t1 (rowid, content) VALUES(19, 'one two five'); - DELETE FROM t1 WHERE rowid = 16; - INSERT INTO t1 (rowid, content) VALUES(20, 'three five'); - INSERT INTO t1 (rowid, content) VALUES(21, 'one three five'); - INSERT INTO t1 (rowid, content) VALUES(22, 'two three five'); - DELETE FROM t1 WHERE rowid = 19; - UPDATE t1 SET content = 'update' WHERE rowid = 15; -} - -do_test fts1f-1.1 { - execsql {SELECT COUNT(*) FROM t1} -} {16} - -do_test fts1f-2.0 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'update'} -} {1 8 15} - -do_test fts1f-2.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'} -} {1 3 5 9 11 17 21} - -do_test fts1f-2.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'} -} {2 3 6 8 11 14 18 22} - -do_test fts1f-2.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'} -} {1 5 6 12 14 20 21 22} - -do_test fts1f-2.4 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'} -} {9 11 12 14} - -do_test fts1f-2.5 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'} -} {8 17 18 20 21 22} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1i.test sqlite3-3.44.0-0/test/fts1i.test --- sqlite3-3.42.0/test/fts1i.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1i.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,88 +0,0 @@ -# 2007 January 17 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite fts1 library. The -# focus here is testing handling of UPDATE when using UTF-16-encoded -# databases. -# -# $Id: fts1i.test,v 1.2 2007/01/24 03:43:20 drh Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - - -# Return the UTF-16 representation of the supplied UTF-8 string $str. -# If $nt is true, append two 0x00 bytes as a nul terminator. -# NOTE(shess) Copied from capi3.test. -proc utf16 {str {nt 1}} { - set r [encoding convertto unicode $str] - if {$nt} { - append r "\x00\x00" - } - return $r -} - -db eval { - PRAGMA encoding = "UTF-16le"; - CREATE VIRTUAL TABLE t1 USING fts1(content); -} - -do_test fts1i-1.0 { - execsql {PRAGMA encoding} -} {UTF-16le} - -do_test fts1i-1.1 { - execsql {INSERT INTO t1 (rowid, content) VALUES(1, 'one')} - execsql {SELECT content FROM t1 WHERE rowid = 1} -} {one} - -do_test fts1i-1.2 { - set sql "INSERT INTO t1 (rowid, content) VALUES(2, 'two')" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 2} -} {two} - -do_test fts1i-1.3 { - set sql "INSERT INTO t1 (rowid, content) VALUES(3, 'three')" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - set sql "UPDATE t1 SET content = 'trois' WHERE rowid = 3" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 3} -} {trois} - -do_test fts1i-1.4 { - set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(4, 'four')}] - set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 4} -} {four} - -do_test fts1i-1.5 { - set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(5, 'five')}] - set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - set sql "UPDATE t1 SET content = 'cinq' WHERE rowid = 5" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 5} -} {cinq} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1j.test sqlite3-3.44.0-0/test/fts1j.test --- sqlite3-3.42.0/test/fts1j.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1j.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -# 2007 February 6 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. This -# tests creating fts1 tables in an attached database. -# -# $Id: fts1j.test,v 1.1 2007/02/07 01:01:18 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -# Clean up anything left over from a previous pass. -forcedelete test2.db -forcedelete test2.db-journal -sqlite3 db2 test2.db - -db eval { - CREATE VIRTUAL TABLE t3 USING fts1(content); - INSERT INTO t3 (rowid, content) VALUES(1, "hello world"); -} - -db2 eval { - CREATE VIRTUAL TABLE t1 USING fts1(content); - INSERT INTO t1 (rowid, content) VALUES(1, "hello world"); - INSERT INTO t1 (rowid, content) VALUES(2, "hello there"); - INSERT INTO t1 (rowid, content) VALUES(3, "cruel world"); -} - -# This has always worked because the t1_* tables used by fts1 will be -# the defaults. -do_test fts1j-1.1 { - execsql { - ATTACH DATABASE 'test2.db' AS two; - SELECT rowid FROM t1 WHERE t1 MATCH 'hello'; - DETACH DATABASE two; - } -} {1 2} -# Make certain we're detached if there was an error. -catch {db eval {DETACH DATABASE two}} - -# In older code, this appears to work fine, but the t2_* tables used -# by fts1 will be created in database 'main' instead of database -# 'two'. It appears to work fine because the tables end up being the -# defaults, but obviously is badly broken if you hope to use things -# other than in the exact same ATTACH setup. -do_test fts1j-1.2 { - execsql { - ATTACH DATABASE 'test2.db' AS two; - CREATE VIRTUAL TABLE two.t2 USING fts1(content); - INSERT INTO t2 (rowid, content) VALUES(1, "hello world"); - INSERT INTO t2 (rowid, content) VALUES(2, "hello there"); - INSERT INTO t2 (rowid, content) VALUES(3, "cruel world"); - SELECT rowid FROM t2 WHERE t2 MATCH 'hello'; - DETACH DATABASE two; - } -} {1 2} -catch {db eval {DETACH DATABASE two}} - -# In older code, this broke because the fts1 code attempted to create -# t3_* tables in database 'main', but they already existed. Normally -# this wouldn't happen without t3 itself existing, in which case the -# fts1 code would never be called in the first place. -do_test fts1j-1.3 { - execsql { - ATTACH DATABASE 'test2.db' AS two; - - CREATE VIRTUAL TABLE two.t3 USING fts1(content); - INSERT INTO two.t3 (rowid, content) VALUES(2, "hello there"); - INSERT INTO two.t3 (rowid, content) VALUES(3, "cruel world"); - SELECT rowid FROM two.t3 WHERE t3 MATCH 'hello'; - - DETACH DATABASE two; - } db2 -} {2} -catch {db eval {DETACH DATABASE two}} - -catch {db2 close} -forcedelete test2.db - -finish_test diff -Nru sqlite3-3.42.0/test/fts1k.test sqlite3-3.44.0-0/test/fts1k.test --- sqlite3-3.42.0/test/fts1k.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1k.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -# 2007 March 28 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing isspace/isalnum/tolower problems with the -# FTS1 module. Unfortunately, this code isn't a really principled set -# of tests, because it is impossible to know where new uses of these -# functions might appear. -# -# $Id: fts1k.test,v 1.2 2007/12/13 21:54:11 drh Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -# Tests that startsWith() (calls isspace, tolower, isalnum) can handle -# hi-bit chars. parseSpec() also calls isalnum here. -do_test fts1k-1.1 { - execsql "CREATE VIRTUAL TABLE t1 USING fts1(content, \x80)" -} {} - -# Additionally tests isspace() call in getToken(), and isalnum() call -# in tokenListToIdList(). -do_test fts1k-1.2 { - catch { - execsql "CREATE VIRTUAL TABLE t2 USING fts1(content, tokenize \x80)" - } - sqlite3_errmsg $DB -} "unknown tokenizer: \x80" - -# Additionally test final isalnum() in startsWith(). -do_test fts1k-1.3 { - execsql "CREATE VIRTUAL TABLE t3 USING fts1(content, tokenize\x80)" -} {} - -# The snippet-generation code has calls to isspace() which are sort of -# hard to get to. It finds convenient breakpoints by starting ~40 -# chars before and after the matched term, and scanning ~10 chars -# around that position for isspace() characters. The long word with -# embedded hi-bit chars causes one of these isspace() calls to be -# exercised. The version with a couple extra spaces should cause the -# other isspace() call to be exercised. [Both cases have been tested -# in the debugger, but I'm hoping to continue to catch it if simple -# constant changes change things slightly. -# -# The trailing and leading hi-bit chars help with code which tests for -# isspace() to coalesce multiple spaces. - -set word "\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80" -set phrase1 "$word $word $word target $word $word $word" -set phrase2 "$word $word $word target $word $word $word" - -db eval {CREATE VIRTUAL TABLE t4 USING fts1(content)} -db eval "INSERT INTO t4 (content) VALUES ('$phrase1')" -db eval "INSERT INTO t4 (content) VALUES ('$phrase2')" - -do_test fts1k-1.4 { - execsql {SELECT rowid, length(snippet(t4)) FROM t4 WHERE t4 MATCH 'target'} -} {1 111 2 117} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1l.test sqlite3-3.44.0-0/test/fts1l.test --- sqlite3-3.42.0/test/fts1l.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1l.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -# 2007 April 9 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. fts1 -# DELETE handling assumed all fields were non-null. This was not -# the intention at all. -# -# $Id: fts1l.test,v 1.1 2007/04/09 20:45:42 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -db eval { - CREATE VIRTUAL TABLE t1 USING fts1(col_a, col_b); - - INSERT INTO t1(rowid, col_a, col_b) VALUES(1, 'testing', 'testing'); - INSERT INTO t1(rowid, col_a, col_b) VALUES(2, 'only a', null); - INSERT INTO t1(rowid, col_a, col_b) VALUES(3, null, 'only b'); - INSERT INTO t1(rowid, col_a, col_b) VALUES(4, null, null); -} - -do_test fts1m-1.0 { - execsql { - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {2 2 4} - -do_test fts1m-1.1 { - execsql { - DELETE FROM t1 WHERE rowid = 1; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {1 1 3} - -do_test fts1m-1.2 { - execsql { - DELETE FROM t1 WHERE rowid = 2; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {0 1 2} - -do_test fts1m-1.3 { - execsql { - DELETE FROM t1 WHERE rowid = 3; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {0 0 1} - -do_test fts1m-1.4 { - execsql { - DELETE FROM t1 WHERE rowid = 4; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {0 0 0} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1m.test sqlite3-3.44.0-0/test/fts1m.test --- sqlite3-3.42.0/test/fts1m.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1m.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,50 +0,0 @@ -# 2007 July 27 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing the FTS1 module, specifically snippet -# generation. Extracted from fts2o.test. -# -# $Id: fts1m.test,v 1.1 2007/07/25 00:25:20 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is not defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -#--------------------------------------------------------------------- -# These tests, fts1m-1.*, test that ticket #2429 is fixed. -# -db eval { - CREATE VIRTUAL TABLE t1 USING fts1(a, b, c); - INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one four two'); -} -do_test fts1m-1.1 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE c MATCH 'four'; - } -} {1 {one four two}} -do_test fts1m-1.2 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE b MATCH 'four'; - } -} {1 {one four}} -do_test fts1m-1.3 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE a MATCH 'four'; - } -} {1 {one three four}} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1n.test sqlite3-3.44.0-0/test/fts1n.test --- sqlite3-3.42.0/test/fts1n.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1n.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,45 +0,0 @@ -# 2007 July 24 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing the FTS1 module for errors in the handling -# of SQLITE_SCHEMA. -# -# $Id: fts1n.test,v 1.1 2007/07/25 00:38:06 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is not defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -do_test fts1m-1.1 { - execsql { - CREATE VIRTUAL TABLE t1 USING fts1(a, b, c); - INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one two'); - SELECT a, b, c FROM t1 WHERE c MATCH 'two'; - } -} {{one three four} {one four} {one two}} - -# This test was crashing at one point. -# -do_test fts1m-1.2 { - execsql { - SELECT a, b, c FROM t1 WHERE c MATCH 'two'; - CREATE TABLE t3(a, b, c); - SELECT a, b, c FROM t1 WHERE c MATCH 'two'; - } -} {{one three four} {one four} {one two} {one three four} {one four} {one two}} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1o.test sqlite3-3.44.0-0/test/fts1o.test --- sqlite3-3.42.0/test/fts1o.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1o.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,138 +0,0 @@ -# 2007 July 24 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing the FTS1 module rename functionality. Mostly -# copied from fts2o.test. -# -# $Id: fts1o.test,v 1.2 2007/08/30 20:01:33 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is not defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -db eval { - CREATE VIRTUAL TABLE t1 USING fts1(a, b, c); - INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one four two'); -} - -#--------------------------------------------------------------------- -# Test that it is possible to rename an fts1 table. -# -do_test fts1o-1.1 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {t1 t1_content t1_term} -do_test fts1o-1.2 { - execsql { ALTER TABLE t1 RENAME to fts_t1; } -} {} -do_test fts1o-1.3 { - execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } -} {1 {one three four}} -do_test fts1o-1.4 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {fts_t1 fts_t1_content fts_t1_term} - -# See what happens when renaming the fts1 table fails. -# -do_test fts1o-2.1 { - catchsql { - CREATE TABLE t1_term(a, b, c); - ALTER TABLE fts_t1 RENAME to t1; - } -} {1 {SQL logic error}} -do_test fts1o-2.2 { - execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } -} {1 {one three four}} -do_test fts1o-2.3 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {fts_t1 fts_t1_content fts_t1_term t1_term} - -# See what happens when renaming the fts1 table fails inside a transaction. -# -do_test fts1o-3.1 { - execsql { - BEGIN; - INSERT INTO fts_t1(a, b, c) VALUES('one two three', 'one four', 'one two'); - } -} {} -do_test fts1o-3.2 { - catchsql { - ALTER TABLE fts_t1 RENAME to t1; - } -} {1 {SQL logic error}} -# NOTE(shess) rowid AS rowid to defeat caching. Otherwise, this -# seg-faults, I suspect that there's something up with a stale -# virtual-table reference, but I'm not quite sure how it happens here -# but not for fts2o.test. -do_test fts1o-3.3 { - execsql { SELECT rowid AS rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } -} {1 {one three four}} -do_test fts1o-3.4 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {fts_t1 fts_t1_content fts_t1_term t1_term} -do_test fts1o-3.5 { - execsql COMMIT - execsql {SELECT a FROM fts_t1} -} {{one three four} {one two three}} -do_test fts1o-3.6 { - execsql { SELECT a, b, c FROM fts_t1 WHERE c MATCH 'four'; } -} {{one three four} {one four} {one four two}} - -#--------------------------------------------------------------------- -# Test that it is possible to rename an fts1 table in an attached -# database. -# -forcedelete test2.db test2.db-journal - -do_test fts1o-4.1 { - execsql { - DROP TABLE t1_term; - ALTER TABLE fts_t1 RENAME to t1; - SELECT a, b, c FROM t1 WHERE c MATCH 'two'; - } -} {{one three four} {one four} {one four two} {one two three} {one four} {one two}} - -do_test fts1o-4.2 { - execsql { - ATTACH 'test2.db' AS aux; - CREATE VIRTUAL TABLE aux.t1 USING fts1(a, b, c); - INSERT INTO aux.t1(a, b, c) VALUES( - 'neung song sahm', 'neung see', 'neung see song' - ); - } -} {} - -do_test fts1o-4.3 { - execsql { SELECT a, b, c FROM aux.t1 WHERE a MATCH 'song'; } -} {{neung song sahm} {neung see} {neung see song}} - -do_test fts1o-4.4 { - execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; } -} {{one three four} {one four} {one four two} {one two three} {one four} {one two}} - -do_test fts1o-4.5 { - execsql { ALTER TABLE aux.t1 RENAME TO t2 } -} {} - -do_test fts1o-4.6 { - execsql { SELECT a, b, c FROM t2 WHERE a MATCH 'song'; } -} {{neung song sahm} {neung see} {neung see song}} - -do_test fts1o-4.7 { - execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; } -} {{one three four} {one four} {one four two} {one two three} {one four} {one two}} - -finish_test diff -Nru sqlite3-3.42.0/test/fts1porter.test sqlite3-3.44.0-0/test/fts1porter.test --- sqlite3-3.42.0/test/fts1porter.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts1porter.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,23590 +0,0 @@ -# 2006 October 1 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing the FTS1 module, and in particular -# the Porter stemmer. -# -# $Id: fts1porter.test,v 1.5 2006/10/03 19:37:37 drh Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS1 is defined, omit this file. -ifcapable !fts1 { - finish_test - return -} - -# Test data for the Porter stemmer. The first word of each line -# is the input. The second word is the desired output. -# -# This test data is taken from http://www.tartarus.org/martin/PorterStemmer/ -# There is no claim of copyright made on that page, but you should -# probably contact the author (Martin Porter - the inventor of the -# Porter Stemmer algorithm) if you want to use this test data in a -# commerical product of some kind. The stemmer code in FTS1 is a -# complete rewrite from scratch based on the algorithm specification -# and does not contain any code under copyright. -# -set porter_test_data { - a a - aaron aaron - abaissiez abaissiez - abandon abandon - abandoned abandon - abase abas - abash abash - abate abat - abated abat - abatement abat - abatements abat - abates abat - abbess abbess - abbey abbei - abbeys abbei - abbominable abbomin - abbot abbot - abbots abbot - abbreviated abbrevi - abed ab - abel abel - aberga aberga - abergavenny abergavenni - abet abet - abetting abet - abhominable abhomin - abhor abhor - abhorr abhorr - abhorred abhor - abhorring abhor - abhors abhor - abhorson abhorson - abide abid - abides abid - abilities abil - ability abil - abject abject - abjectly abjectli - abjects abject - abjur abjur - abjure abjur - able abl - abler abler - aboard aboard - abode abod - aboded abod - abodements abod - aboding abod - abominable abomin - abominably abomin - abominations abomin - abortive abort - abortives abort - abound abound - abounding abound - about about - above abov - abr abr - abraham abraham - abram abram - abreast abreast - abridg abridg - abridge abridg - abridged abridg - abridgment abridg - abroach abroach - abroad abroad - abrogate abrog - abrook abrook - abrupt abrupt - abruption abrupt - abruptly abruptli - absence absenc - absent absent - absey absei - absolute absolut - absolutely absolut - absolv absolv - absolver absolv - abstains abstain - abstemious abstemi - abstinence abstin - abstract abstract - absurd absurd - absyrtus absyrtu - abundance abund - abundant abund - abundantly abundantli - abus abu - abuse abus - abused abus - abuser abus - abuses abus - abusing abus - abutting abut - aby abi - abysm abysm - ac ac - academe academ - academes academ - accent accent - accents accent - accept accept - acceptable accept - acceptance accept - accepted accept - accepts accept - access access - accessary accessari - accessible access - accidence accid - accident accid - accidental accident - accidentally accident - accidents accid - accite accit - accited accit - accites accit - acclamations acclam - accommodate accommod - accommodated accommod - accommodation accommod - accommodations accommod - accommodo accommodo - accompanied accompani - accompany accompani - accompanying accompani - accomplices accomplic - accomplish accomplish - accomplished accomplish - accomplishing accomplish - accomplishment accomplish - accompt accompt - accord accord - accordant accord - accorded accord - accordeth accordeth - according accord - accordingly accordingli - accords accord - accost accost - accosted accost - account account - accountant account - accounted account - accounts account - accoutred accoutr - accoutrement accoutr - accoutrements accoutr - accrue accru - accumulate accumul - accumulated accumul - accumulation accumul - accurs accur - accursed accurs - accurst accurst - accus accu - accusation accus - accusations accus - accusative accus - accusativo accusativo - accuse accus - accused accus - accuser accus - accusers accus - accuses accus - accuseth accuseth - accusing accus - accustom accustom - accustomed accustom - ace ac - acerb acerb - ache ach - acheron acheron - aches ach - achiev achiev - achieve achiev - achieved achiev - achievement achiev - achievements achiev - achiever achiev - achieves achiev - achieving achiev - achilles achil - aching ach - achitophel achitophel - acknowledg acknowledg - acknowledge acknowledg - acknowledged acknowledg - acknowledgment acknowledg - acknown acknown - acold acold - aconitum aconitum - acordo acordo - acorn acorn - acquaint acquaint - acquaintance acquaint - acquainted acquaint - acquaints acquaint - acquir acquir - acquire acquir - acquisition acquisit - acquit acquit - acquittance acquitt - acquittances acquitt - acquitted acquit - acre acr - acres acr - across across - act act - actaeon actaeon - acted act - acting act - action action - actions action - actium actium - active activ - actively activ - activity activ - actor actor - actors actor - acts act - actual actual - acture actur - acute acut - acutely acut - ad ad - adage adag - adallas adalla - adam adam - adamant adam - add add - added ad - adder adder - adders adder - addeth addeth - addict addict - addicted addict - addiction addict - adding ad - addition addit - additions addit - addle addl - address address - addressing address - addrest addrest - adds add - adhere adher - adheres adher - adieu adieu - adieus adieu - adjacent adjac - adjoin adjoin - adjoining adjoin - adjourn adjourn - adjudg adjudg - adjudged adjudg - adjunct adjunct - administer administ - administration administr - admir admir - admirable admir - admiral admir - admiration admir - admire admir - admired admir - admirer admir - admiring admir - admiringly admiringli - admission admiss - admit admit - admits admit - admittance admitt - admitted admit - admitting admit - admonish admonish - admonishing admonish - admonishment admonish - admonishments admonish - admonition admonit - ado ado - adonis adoni - adopt adopt - adopted adopt - adoptedly adoptedli - adoption adopt - adoptious adopti - adopts adopt - ador ador - adoration ador - adorations ador - adore ador - adorer ador - adores ador - adorest adorest - adoreth adoreth - adoring ador - adorn adorn - adorned adorn - adornings adorn - adornment adorn - adorns adorn - adown adown - adramadio adramadio - adrian adrian - adriana adriana - adriano adriano - adriatic adriat - adsum adsum - adulation adul - adulterate adulter - adulterates adulter - adulterers adulter - adulteress adulteress - adulteries adulteri - adulterous adulter - adultery adulteri - adultress adultress - advanc advanc - advance advanc - advanced advanc - advancement advanc - advancements advanc - advances advanc - advancing advanc - advantage advantag - advantageable advantag - advantaged advantag - advantageous advantag - advantages advantag - advantaging advantag - advent advent - adventur adventur - adventure adventur - adventures adventur - adventuring adventur - adventurous adventur - adventurously adventur - adversaries adversari - adversary adversari - adverse advers - adversely advers - adversities advers - adversity advers - advertis adverti - advertise advertis - advertised advertis - advertisement advertis - advertising advertis - advice advic - advis advi - advise advis - advised advis - advisedly advisedli - advises advis - advisings advis - advocate advoc - advocation advoc - aeacida aeacida - aeacides aeacid - aedile aedil - aediles aedil - aegeon aegeon - aegion aegion - aegles aegl - aemelia aemelia - aemilia aemilia - aemilius aemiliu - aeneas aenea - aeolus aeolu - aer aer - aerial aerial - aery aeri - aesculapius aesculapiu - aeson aeson - aesop aesop - aetna aetna - afar afar - afear afear - afeard afeard - affability affabl - affable affabl - affair affair - affaire affair - affairs affair - affect affect - affectation affect - affectations affect - affected affect - affectedly affectedli - affecteth affecteth - affecting affect - affection affect - affectionate affection - affectionately affection - affections affect - affects affect - affeer affeer - affianc affianc - affiance affianc - affianced affianc - affied affi - affin affin - affined affin - affinity affin - affirm affirm - affirmation affirm - affirmatives affirm - afflict afflict - afflicted afflict - affliction afflict - afflictions afflict - afflicts afflict - afford afford - affordeth affordeth - affords afford - affray affrai - affright affright - affrighted affright - affrights affright - affront affront - affronted affront - affy affi - afield afield - afire afir - afloat afloat - afoot afoot - afore afor - aforehand aforehand - aforesaid aforesaid - afraid afraid - afresh afresh - afric afric - africa africa - african african - afront afront - after after - afternoon afternoon - afterward afterward - afterwards afterward - ag ag - again again - against against - agamemmon agamemmon - agamemnon agamemnon - agate agat - agaz agaz - age ag - aged ag - agenor agenor - agent agent - agents agent - ages ag - aggravate aggrav - aggrief aggrief - agile agil - agincourt agincourt - agitation agit - aglet aglet - agnize agniz - ago ago - agone agon - agony agoni - agree agre - agreed agre - agreeing agre - agreement agreement - agrees agre - agrippa agrippa - aground aground - ague agu - aguecheek aguecheek - agued agu - agueface aguefac - agues agu - ah ah - aha aha - ahungry ahungri - ai ai - aialvolio aialvolio - aiaria aiaria - aid aid - aidance aidanc - aidant aidant - aided aid - aiding aid - aidless aidless - aids aid - ail ail - aim aim - aimed aim - aimest aimest - aiming aim - aims aim - ainsi ainsi - aio aio - air air - aired air - airless airless - airs air - airy airi - ajax ajax - akilling akil - al al - alabaster alabast - alack alack - alacrity alacr - alarbus alarbu - alarm alarm - alarms alarm - alarum alarum - alarums alarum - alas ala - alb alb - alban alban - albans alban - albany albani - albeit albeit - albion albion - alchemist alchemist - alchemy alchemi - alcibiades alcibiad - alcides alcid - alder alder - alderman alderman - aldermen aldermen - ale al - alecto alecto - alehouse alehous - alehouses alehous - alencon alencon - alengon alengon - aleppo aleppo - ales al - alewife alewif - alexander alexand - alexanders alexand - alexandria alexandria - alexandrian alexandrian - alexas alexa - alias alia - alice alic - alien alien - aliena aliena - alight alight - alighted alight - alights alight - aliis alii - alike alik - alisander alisand - alive aliv - all all - alla alla - allay allai - allayed allai - allaying allai - allayment allay - allayments allay - allays allai - allegation alleg - allegations alleg - allege alleg - alleged alleg - allegiance allegi - allegiant allegi - alley allei - alleys allei - allhallowmas allhallowma - alliance allianc - allicholy allicholi - allied alli - allies alli - alligant allig - alligator allig - allons allon - allot allot - allots allot - allotted allot - allottery allotteri - allow allow - allowance allow - allowed allow - allowing allow - allows allow - allur allur - allure allur - allurement allur - alluring allur - allusion allus - ally alli - allycholly allycholli - almain almain - almanac almanac - almanack almanack - almanacs almanac - almighty almighti - almond almond - almost almost - alms alm - almsman almsman - aloes alo - aloft aloft - alone alon - along along - alonso alonso - aloof aloof - aloud aloud - alphabet alphabet - alphabetical alphabet - alphonso alphonso - alps alp - already alreadi - also also - alt alt - altar altar - altars altar - alter alter - alteration alter - altered alter - alters alter - althaea althaea - although although - altitude altitud - altogether altogeth - alton alton - alway alwai - always alwai - am am - amaimon amaimon - amain amain - amaking amak - amamon amamon - amaz amaz - amaze amaz - amazed amaz - amazedly amazedli - amazedness amazed - amazement amaz - amazes amaz - amazeth amazeth - amazing amaz - amazon amazon - amazonian amazonian - amazons amazon - ambassador ambassador - ambassadors ambassador - amber amber - ambiguides ambiguid - ambiguities ambigu - ambiguous ambigu - ambition ambit - ambitions ambit - ambitious ambiti - ambitiously ambiti - amble ambl - ambled ambl - ambles ambl - ambling ambl - ambo ambo - ambuscadoes ambuscado - ambush ambush - amen amen - amend amend - amended amend - amendment amend - amends amend - amerce amerc - america america - ames am - amiable amiabl - amid amid - amidst amidst - amiens amien - amis ami - amiss amiss - amities amiti - amity amiti - amnipotent amnipot - among among - amongst amongst - amorous amor - amorously amor - amort amort - amount amount - amounts amount - amour amour - amphimacus amphimacu - ample ampl - ampler ampler - amplest amplest - amplified amplifi - amplify amplifi - amply ampli - ampthill ampthil - amurath amurath - amyntas amynta - an an - anatomiz anatomiz - anatomize anatom - anatomy anatomi - ancestor ancestor - ancestors ancestor - ancestry ancestri - anchises anchis - anchor anchor - anchorage anchorag - anchored anchor - anchoring anchor - anchors anchor - anchovies anchovi - ancient ancient - ancientry ancientri - ancients ancient - ancus ancu - and and - andirons andiron - andpholus andpholu - andren andren - andrew andrew - andromache andromach - andronici andronici - andronicus andronicu - anew anew - ang ang - angel angel - angelica angelica - angelical angel - angelo angelo - angels angel - anger anger - angerly angerli - angers anger - anges ang - angiers angier - angl angl - anglais anglai - angle angl - angler angler - angleterre angleterr - angliae anglia - angling angl - anglish anglish - angrily angrili - angry angri - anguish anguish - angus angu - animal anim - animals anim - animis animi - anjou anjou - ankle ankl - anna anna - annals annal - anne ann - annex annex - annexed annex - annexions annexion - annexment annex - annothanize annothan - announces announc - annoy annoi - annoyance annoy - annoying annoi - annual annual - anoint anoint - anointed anoint - anon anon - another anoth - anselmo anselmo - answer answer - answerable answer - answered answer - answerest answerest - answering answer - answers answer - ant ant - ante ant - antenor antenor - antenorides antenorid - anteroom anteroom - anthem anthem - anthems anthem - anthony anthoni - anthropophagi anthropophagi - anthropophaginian anthropophaginian - antiates antiat - antic antic - anticipate anticip - anticipates anticip - anticipatest anticipatest - anticipating anticip - anticipation anticip - antick antick - anticly anticli - antics antic - antidote antidot - antidotes antidot - antigonus antigonu - antiopa antiopa - antipathy antipathi - antipholus antipholu - antipholuses antipholus - antipodes antipod - antiquary antiquari - antique antiqu - antiquity antiqu - antium antium - antoniad antoniad - antonio antonio - antonius antoniu - antony antoni - antres antr - anvil anvil - any ani - anybody anybodi - anyone anyon - anything anyth - anywhere anywher - ap ap - apace apac - apart apart - apartment apart - apartments apart - ape ap - apemantus apemantu - apennines apennin - apes ap - apiece apiec - apish apish - apollinem apollinem - apollo apollo - apollodorus apollodoru - apology apolog - apoplex apoplex - apoplexy apoplexi - apostle apostl - apostles apostl - apostrophas apostropha - apoth apoth - apothecary apothecari - appal appal - appall appal - appalled appal - appals appal - apparel apparel - apparell apparel - apparelled apparel - apparent appar - apparently appar - apparition apparit - apparitions apparit - appeach appeach - appeal appeal - appeals appeal - appear appear - appearance appear - appeared appear - appeareth appeareth - appearing appear - appears appear - appeas appea - appease appeas - appeased appeas - appelant appel - appele appel - appelee appele - appeles appel - appelez appelez - appellant appel - appellants appel - appelons appelon - appendix appendix - apperil apperil - appertain appertain - appertaining appertain - appertainings appertain - appertains appertain - appertinent appertin - appertinents appertin - appetite appetit - appetites appetit - applaud applaud - applauded applaud - applauding applaud - applause applaus - applauses applaus - apple appl - apples appl - appletart appletart - appliance applianc - appliances applianc - applications applic - applied appli - applies appli - apply appli - applying appli - appoint appoint - appointed appoint - appointment appoint - appointments appoint - appoints appoint - apprehend apprehend - apprehended apprehend - apprehends apprehend - apprehension apprehens - apprehensions apprehens - apprehensive apprehens - apprendre apprendr - apprenne apprenn - apprenticehood apprenticehood - appris appri - approach approach - approachers approach - approaches approach - approacheth approacheth - approaching approach - approbation approb - approof approof - appropriation appropri - approv approv - approve approv - approved approv - approvers approv - approves approv - appurtenance appurten - appurtenances appurten - apricocks apricock - april april - apron apron - aprons apron - apt apt - apter apter - aptest aptest - aptly aptli - aptness apt - aqua aqua - aquilon aquilon - aquitaine aquitain - arabia arabia - arabian arabian - araise arais - arbitrate arbitr - arbitrating arbitr - arbitrator arbitr - arbitrement arbitr - arbors arbor - arbour arbour - arc arc - arch arch - archbishop archbishop - archbishopric archbishopr - archdeacon archdeacon - arched arch - archelaus archelau - archer archer - archers archer - archery archeri - archibald archibald - archidamus archidamu - architect architect - arcu arcu - arde ard - arden arden - ardent ardent - ardour ardour - are ar - argal argal - argier argier - argo argo - argosies argosi - argosy argosi - argu argu - argue argu - argued argu - argues argu - arguing argu - argument argument - arguments argument - argus argu - ariachne ariachn - ariadne ariadn - ariel ariel - aries ari - aright aright - arinado arinado - arinies arini - arion arion - arise aris - arises aris - ariseth ariseth - arising aris - aristode aristod - aristotle aristotl - arithmetic arithmet - arithmetician arithmetician - ark ark - arm arm - arma arma - armado armado - armadoes armado - armagnac armagnac - arme arm - armed arm - armenia armenia - armies armi - armigero armigero - arming arm - armipotent armipot - armor armor - armour armour - armourer armour - armourers armour - armours armour - armoury armouri - arms arm - army armi - arn arn - aroint aroint - arose aros - arouse arous - aroused arous - arragon arragon - arraign arraign - arraigned arraign - arraigning arraign - arraignment arraign - arrant arrant - arras arra - array arrai - arrearages arrearag - arrest arrest - arrested arrest - arrests arrest - arriv arriv - arrival arriv - arrivance arriv - arrive arriv - arrived arriv - arrives arriv - arriving arriv - arrogance arrog - arrogancy arrog - arrogant arrog - arrow arrow - arrows arrow - art art - artemidorus artemidoru - arteries arteri - arthur arthur - article articl - articles articl - articulate articul - artificer artific - artificial artifici - artillery artilleri - artire artir - artist artist - artists artist - artless artless - artois artoi - arts art - artus artu - arviragus arviragu - as as - asaph asaph - ascanius ascaniu - ascend ascend - ascended ascend - ascendeth ascendeth - ascends ascend - ascension ascens - ascent ascent - ascribe ascrib - ascribes ascrib - ash ash - asham asham - ashamed asham - asher asher - ashes ash - ashford ashford - ashore ashor - ashouting ashout - ashy ashi - asia asia - aside asid - ask ask - askance askanc - asked ask - asker asker - asketh asketh - asking ask - asks ask - aslant aslant - asleep asleep - asmath asmath - asp asp - aspect aspect - aspects aspect - aspen aspen - aspersion aspers - aspic aspic - aspicious aspici - aspics aspic - aspir aspir - aspiration aspir - aspire aspir - aspiring aspir - asquint asquint - ass ass - assail assail - assailable assail - assailant assail - assailants assail - assailed assail - assaileth assaileth - assailing assail - assails assail - assassination assassin - assault assault - assaulted assault - assaults assault - assay assai - assaying assai - assays assai - assemblance assembl - assemble assembl - assembled assembl - assemblies assembl - assembly assembl - assent assent - asses ass - assez assez - assign assign - assigned assign - assigns assign - assinico assinico - assist assist - assistance assist - assistances assist - assistant assist - assistants assist - assisted assist - assisting assist - associate associ - associated associ - associates associ - assuage assuag - assubjugate assubjug - assum assum - assume assum - assumes assum - assumption assumpt - assur assur - assurance assur - assure assur - assured assur - assuredly assuredli - assures assur - assyrian assyrian - astonish astonish - astonished astonish - astraea astraea - astray astrai - astrea astrea - astronomer astronom - astronomers astronom - astronomical astronom - astronomy astronomi - asunder asund - at at - atalanta atalanta - ate at - ates at - athenian athenian - athenians athenian - athens athen - athol athol - athversary athversari - athwart athwart - atlas atla - atomies atomi - atomy atomi - atone aton - atonement aton - atonements aton - atropos atropo - attach attach - attached attach - attachment attach - attain attain - attainder attaind - attains attain - attaint attaint - attainted attaint - attainture attaintur - attempt attempt - attemptable attempt - attempted attempt - attempting attempt - attempts attempt - attend attend - attendance attend - attendant attend - attendants attend - attended attend - attendents attend - attendeth attendeth - attending attend - attends attend - attent attent - attention attent - attentive attent - attentivenes attentiven - attest attest - attested attest - attir attir - attire attir - attired attir - attires attir - attorney attornei - attorneyed attornei - attorneys attornei - attorneyship attorneyship - attract attract - attraction attract - attractive attract - attracts attract - attribute attribut - attributed attribut - attributes attribut - attribution attribut - attributive attribut - atwain atwain - au au - aubrey aubrei - auburn auburn - aucun aucun - audacious audaci - audaciously audaci - audacity audac - audible audibl - audience audienc - audis audi - audit audit - auditor auditor - auditors auditor - auditory auditori - audre audr - audrey audrei - aufidius aufidiu - aufidiuses aufidius - auger auger - aught aught - augment augment - augmentation augment - augmented augment - augmenting augment - augurer augur - augurers augur - augures augur - auguring augur - augurs augur - augury auguri - august august - augustus augustu - auld auld - aumerle aumerl - aunchient aunchient - aunt aunt - aunts aunt - auricular auricular - aurora aurora - auspicious auspici - aussi aussi - austere auster - austerely auster - austereness auster - austerity auster - austria austria - aut aut - authentic authent - author author - authorities author - authority author - authorized author - authorizing author - authors author - autolycus autolycu - autre autr - autumn autumn - auvergne auvergn - avail avail - avails avail - avarice avaric - avaricious avarici - avaunt avaunt - ave av - aveng aveng - avenge aveng - avenged aveng - averring aver - avert avert - aves av - avez avez - avis avi - avoid avoid - avoided avoid - avoiding avoid - avoids avoid - avoirdupois avoirdupoi - avouch avouch - avouched avouch - avouches avouch - avouchment avouch - avow avow - aw aw - await await - awaits await - awak awak - awake awak - awaked awak - awaken awaken - awakened awaken - awakens awaken - awakes awak - awaking awak - award award - awards award - awasy awasi - away awai - awe aw - aweary aweari - aweless aweless - awful aw - awhile awhil - awkward awkward - awl awl - awooing awoo - awork awork - awry awri - axe ax - axle axl - axletree axletre - ay ay - aye ay - ayez ayez - ayli ayli - azur azur - azure azur - b b - ba ba - baa baa - babbl babbl - babble babbl - babbling babbl - babe babe - babes babe - babies babi - baboon baboon - baboons baboon - baby babi - babylon babylon - bacare bacar - bacchanals bacchan - bacchus bacchu - bach bach - bachelor bachelor - bachelors bachelor - back back - backbite backbit - backbitten backbitten - backing back - backs back - backward backward - backwardly backwardli - backwards backward - bacon bacon - bacons bacon - bad bad - bade bade - badge badg - badged badg - badges badg - badly badli - badness bad - baes bae - baffl baffl - baffle baffl - baffled baffl - bag bag - baggage baggag - bagot bagot - bagpipe bagpip - bags bag - bail bail - bailiff bailiff - baillez baillez - baily baili - baisant baisant - baisees baise - baiser baiser - bait bait - baited bait - baiting bait - baitings bait - baits bait - bajazet bajazet - bak bak - bake bake - baked bake - baker baker - bakers baker - bakes bake - baking bake - bal bal - balanc balanc - balance balanc - balcony balconi - bald bald - baldrick baldrick - bale bale - baleful bale - balk balk - ball ball - ballad ballad - ballads ballad - ballast ballast - ballasting ballast - ballet ballet - ballow ballow - balls ball - balm balm - balms balm - balmy balmi - balsam balsam - balsamum balsamum - balth balth - balthasar balthasar - balthazar balthazar - bames bame - ban ban - banbury banburi - band band - bandied bandi - banding band - bandit bandit - banditti banditti - banditto banditto - bands band - bandy bandi - bandying bandi - bane bane - banes bane - bang bang - bangor bangor - banish banish - banished banish - banishers banish - banishment banish - banister banist - bank bank - bankrout bankrout - bankrupt bankrupt - bankrupts bankrupt - banks bank - banner banner - bannerets banneret - banners banner - banning ban - banns bann - banquet banquet - banqueted banquet - banqueting banquet - banquets banquet - banquo banquo - bans ban - baptism baptism - baptista baptista - baptiz baptiz - bar bar - barbarian barbarian - barbarians barbarian - barbarism barbar - barbarous barbar - barbary barbari - barbason barbason - barbed barb - barber barber - barbermonger barbermong - bard bard - bardolph bardolph - bards bard - bare bare - bared bare - barefac barefac - barefaced barefac - barefoot barefoot - bareheaded barehead - barely bare - bareness bare - barful bar - bargain bargain - bargains bargain - barge barg - bargulus bargulu - baring bare - bark bark - barking bark - barkloughly barkloughli - barks bark - barky barki - barley barlei - barm barm - barn barn - barnacles barnacl - barnardine barnardin - barne barn - barnes barn - barnet barnet - barns barn - baron baron - barons baron - barony baroni - barr barr - barrabas barraba - barrel barrel - barrels barrel - barren barren - barrenly barrenli - barrenness barren - barricado barricado - barricadoes barricado - barrow barrow - bars bar - barson barson - barter barter - bartholomew bartholomew - bas ba - basan basan - base base - baseless baseless - basely base - baseness base - baser baser - bases base - basest basest - bashful bash - bashfulness bash - basilisco basilisco - basilisk basilisk - basilisks basilisk - basimecu basimecu - basin basin - basingstoke basingstok - basins basin - basis basi - bask bask - basket basket - baskets basket - bass bass - bassanio bassanio - basset basset - bassianus bassianu - basta basta - bastard bastard - bastardizing bastard - bastardly bastardli - bastards bastard - bastardy bastardi - basted bast - bastes bast - bastinado bastinado - basting bast - bat bat - batailles batail - batch batch - bate bate - bated bate - bates bate - bath bath - bathe bath - bathed bath - bathing bath - baths bath - bating bate - batler batler - bats bat - batt batt - battalia battalia - battalions battalion - batten batten - batter batter - battering batter - batters batter - battery batteri - battle battl - battled battl - battlefield battlefield - battlements battlement - battles battl - batty batti - bauble baubl - baubles baubl - baubling baubl - baulk baulk - bavin bavin - bawcock bawcock - bawd bawd - bawdry bawdri - bawds bawd - bawdy bawdi - bawl bawl - bawling bawl - bay bai - baying bai - baynard baynard - bayonne bayonn - bays bai - be be - beach beach - beached beach - beachy beachi - beacon beacon - bead bead - beaded bead - beadle beadl - beadles beadl - beads bead - beadsmen beadsmen - beagle beagl - beagles beagl - beak beak - beaks beak - beam beam - beamed beam - beams beam - bean bean - beans bean - bear bear - beard beard - bearded beard - beardless beardless - beards beard - bearer bearer - bearers bearer - bearest bearest - beareth beareth - bearing bear - bears bear - beast beast - beastliest beastliest - beastliness beastli - beastly beastli - beasts beast - beat beat - beated beat - beaten beaten - beating beat - beatrice beatric - beats beat - beau beau - beaufort beaufort - beaumond beaumond - beaumont beaumont - beauteous beauteou - beautied beauti - beauties beauti - beautified beautifi - beautiful beauti - beautify beautifi - beauty beauti - beaver beaver - beavers beaver - became becam - because becaus - bechanc bechanc - bechance bechanc - bechanced bechanc - beck beck - beckon beckon - beckons beckon - becks beck - becom becom - become becom - becomed becom - becomes becom - becoming becom - becomings becom - bed bed - bedabbled bedabbl - bedash bedash - bedaub bedaub - bedazzled bedazzl - bedchamber bedchamb - bedclothes bedcloth - bedded bed - bedeck bedeck - bedecking bedeck - bedew bedew - bedfellow bedfellow - bedfellows bedfellow - bedford bedford - bedlam bedlam - bedrench bedrench - bedrid bedrid - beds bed - bedtime bedtim - bedward bedward - bee bee - beef beef - beefs beef - beehives beehiv - been been - beer beer - bees bee - beest beest - beetle beetl - beetles beetl - beeves beev - befall befal - befallen befallen - befalls befal - befell befel - befits befit - befitted befit - befitting befit - befor befor - before befor - beforehand beforehand - befortune befortun - befriend befriend - befriended befriend - befriends befriend - beg beg - began began - beget beget - begets beget - begetting beget - begg begg - beggar beggar - beggared beggar - beggarly beggarli - beggarman beggarman - beggars beggar - beggary beggari - begging beg - begin begin - beginners beginn - beginning begin - beginnings begin - begins begin - begnawn begnawn - begone begon - begot begot - begotten begotten - begrimed begrim - begs beg - beguil beguil - beguile beguil - beguiled beguil - beguiles beguil - beguiling beguil - begun begun - behalf behalf - behalfs behalf - behav behav - behaved behav - behavedst behavedst - behavior behavior - behaviors behavior - behaviour behaviour - behaviours behaviour - behead behead - beheaded behead - beheld beheld - behest behest - behests behest - behind behind - behold behold - beholder behold - beholders behold - beholdest beholdest - beholding behold - beholds behold - behoof behoof - behooffull behoofful - behooves behoov - behove behov - behoves behov - behowls behowl - being be - bel bel - belarius belariu - belch belch - belching belch - beldam beldam - beldame beldam - beldams beldam - belee bele - belgia belgia - belie beli - belied beli - belief belief - beliest beliest - believ believ - believe believ - believed believ - believes believ - believest believest - believing believ - belike belik - bell bell - bellario bellario - belle bell - bellied belli - bellies belli - bellman bellman - bellona bellona - bellow bellow - bellowed bellow - bellowing bellow - bellows bellow - bells bell - belly belli - bellyful belly - belman belman - belmont belmont - belock belock - belong belong - belonging belong - belongings belong - belongs belong - belov belov - beloved belov - beloving belov - below below - belt belt - belzebub belzebub - bemadding bemad - bemet bemet - bemete bemet - bemoan bemoan - bemoaned bemoan - bemock bemock - bemoil bemoil - bemonster bemonst - ben ben - bench bench - bencher bencher - benches bench - bend bend - bended bend - bending bend - bends bend - bene bene - beneath beneath - benedicite benedicit - benedick benedick - benediction benedict - benedictus benedictu - benefactors benefactor - benefice benefic - beneficial benefici - benefit benefit - benefited benefit - benefits benefit - benetted benet - benevolence benevol - benevolences benevol - benied beni - benison benison - bennet bennet - bent bent - bentii bentii - bentivolii bentivolii - bents bent - benumbed benumb - benvolio benvolio - bepaint bepaint - bepray beprai - bequeath bequeath - bequeathed bequeath - bequeathing bequeath - bequest bequest - ber ber - berard berard - berattle berattl - beray berai - bere bere - bereave bereav - bereaved bereav - bereaves bereav - bereft bereft - bergamo bergamo - bergomask bergomask - berhym berhym - berhyme berhym - berkeley berkelei - bermoothes bermooth - bernardo bernardo - berod berod - berowne berown - berri berri - berries berri - berrord berrord - berry berri - bertram bertram - berwick berwick - bescreen bescreen - beseech beseech - beseeched beseech - beseechers beseech - beseeching beseech - beseek beseek - beseem beseem - beseemeth beseemeth - beseeming beseem - beseems beseem - beset beset - beshrew beshrew - beside besid - besides besid - besieg besieg - besiege besieg - besieged besieg - beslubber beslubb - besmear besmear - besmeared besmear - besmirch besmirch - besom besom - besort besort - besotted besot - bespake bespak - bespeak bespeak - bespice bespic - bespoke bespok - bespotted bespot - bess bess - bessy bessi - best best - bestained bestain - bested best - bestial bestial - bestir bestir - bestirr bestirr - bestow bestow - bestowed bestow - bestowing bestow - bestows bestow - bestraught bestraught - bestrew bestrew - bestrid bestrid - bestride bestrid - bestrides bestrid - bet bet - betake betak - beteem beteem - bethink bethink - bethought bethought - bethrothed bethroth - bethump bethump - betid betid - betide betid - betideth betideth - betime betim - betimes betim - betoken betoken - betook betook - betossed betoss - betray betrai - betrayed betrai - betraying betrai - betrays betrai - betrims betrim - betroth betroth - betrothed betroth - betroths betroth - bett bett - betted bet - better better - bettered better - bettering better - betters better - betting bet - bettre bettr - between between - betwixt betwixt - bevel bevel - beverage beverag - bevis bevi - bevy bevi - bewail bewail - bewailed bewail - bewailing bewail - bewails bewail - beware bewar - bewasted bewast - beweep beweep - bewept bewept - bewet bewet - bewhored bewhor - bewitch bewitch - bewitched bewitch - bewitchment bewitch - bewray bewrai - beyond beyond - bezonian bezonian - bezonians bezonian - bianca bianca - bianco bianco - bias bia - bibble bibbl - bickerings bicker - bid bid - bidden bidden - bidding bid - biddings bid - biddy biddi - bide bide - bides bide - biding bide - bids bid - bien bien - bier bier - bifold bifold - big big - bigamy bigami - biggen biggen - bigger bigger - bigness big - bigot bigot - bilberry bilberri - bilbo bilbo - bilboes bilbo - bilbow bilbow - bill bill - billeted billet - billets billet - billiards billiard - billing bill - billow billow - billows billow - bills bill - bin bin - bind bind - bindeth bindeth - binding bind - binds bind - biondello biondello - birch birch - bird bird - birding bird - birdlime birdlim - birds bird - birnam birnam - birth birth - birthday birthdai - birthdom birthdom - birthplace birthplac - birthright birthright - birthrights birthright - births birth - bis bi - biscuit biscuit - bishop bishop - bishops bishop - bisson bisson - bit bit - bitch bitch - bite bite - biter biter - bites bite - biting bite - bits bit - bitt bitt - bitten bitten - bitter bitter - bitterest bitterest - bitterly bitterli - bitterness bitter - blab blab - blabb blabb - blabbing blab - blabs blab - black black - blackamoor blackamoor - blackamoors blackamoor - blackberries blackberri - blackberry blackberri - blacker blacker - blackest blackest - blackfriars blackfriar - blackheath blackheath - blackmere blackmer - blackness black - blacks black - bladder bladder - bladders bladder - blade blade - bladed blade - blades blade - blains blain - blam blam - blame blame - blamed blame - blameful blame - blameless blameless - blames blame - blanc blanc - blanca blanca - blanch blanch - blank blank - blanket blanket - blanks blank - blaspheme blasphem - blaspheming blasphem - blasphemous blasphem - blasphemy blasphemi - blast blast - blasted blast - blasting blast - blastments blastment - blasts blast - blaz blaz - blaze blaze - blazes blaze - blazing blaze - blazon blazon - blazoned blazon - blazoning blazon - bleach bleach - bleaching bleach - bleak bleak - blear blear - bleared blear - bleat bleat - bleated bleat - bleats bleat - bled bled - bleed bleed - bleedest bleedest - bleedeth bleedeth - bleeding bleed - bleeds bleed - blemish blemish - blemishes blemish - blench blench - blenches blench - blend blend - blended blend - blent blent - bless bless - blessed bless - blessedly blessedli - blessedness blessed - blesses bless - blesseth blesseth - blessing bless - blessings bless - blest blest - blew blew - blind blind - blinded blind - blindfold blindfold - blinding blind - blindly blindli - blindness blind - blinds blind - blink blink - blinking blink - bliss bliss - blist blist - blister blister - blisters blister - blithe blith - blithild blithild - bloat bloat - block block - blockish blockish - blocks block - blois bloi - blood blood - blooded blood - bloodhound bloodhound - bloodied bloodi - bloodier bloodier - bloodiest bloodiest - bloodily bloodili - bloodless bloodless - bloods blood - bloodshed bloodsh - bloodshedding bloodshed - bloodstained bloodstain - bloody bloodi - bloom bloom - blooms bloom - blossom blossom - blossoming blossom - blossoms blossom - blot blot - blots blot - blotted blot - blotting blot - blount blount - blow blow - blowed blow - blowers blower - blowest blowest - blowing blow - blown blown - blows blow - blowse blows - blubb blubb - blubber blubber - blubbering blubber - blue blue - bluecaps bluecap - bluest bluest - blunt blunt - blunted blunt - blunter blunter - bluntest bluntest - blunting blunt - bluntly bluntli - bluntness blunt - blunts blunt - blur blur - blurr blurr - blurs blur - blush blush - blushes blush - blushest blushest - blushing blush - blust blust - bluster bluster - blusterer bluster - blusters bluster - bo bo - boar boar - board board - boarded board - boarding board - boards board - boarish boarish - boars boar - boast boast - boasted boast - boastful boast - boasting boast - boasts boast - boat boat - boats boat - boatswain boatswain - bob bob - bobb bobb - boblibindo boblibindo - bobtail bobtail - bocchus bocchu - bode bode - boded bode - bodements bodement - bodes bode - bodg bodg - bodied bodi - bodies bodi - bodiless bodiless - bodily bodili - boding bode - bodkin bodkin - body bodi - bodykins bodykin - bog bog - boggle boggl - boggler boggler - bogs bog - bohemia bohemia - bohemian bohemian - bohun bohun - boil boil - boiling boil - boils boil - boist boist - boisterous boister - boisterously boister - boitier boitier - bold bold - bolden bolden - bolder bolder - boldest boldest - boldly boldli - boldness bold - bolds bold - bolingbroke bolingbrok - bolster bolster - bolt bolt - bolted bolt - bolter bolter - bolters bolter - bolting bolt - bolts bolt - bombard bombard - bombards bombard - bombast bombast - bon bon - bona bona - bond bond - bondage bondag - bonded bond - bondmaid bondmaid - bondman bondman - bondmen bondmen - bonds bond - bondslave bondslav - bone bone - boneless boneless - bones bone - bonfire bonfir - bonfires bonfir - bonjour bonjour - bonne bonn - bonnet bonnet - bonneted bonnet - bonny bonni - bonos bono - bonto bonto - bonville bonvil - bood bood - book book - bookish bookish - books book - boon boon - boor boor - boorish boorish - boors boor - boot boot - booted boot - booties booti - bootless bootless - boots boot - booty booti - bor bor - bora bora - borachio borachio - bordeaux bordeaux - border border - bordered border - borderers border - borders border - bore bore - boreas borea - bores bore - boring bore - born born - borne born - borough borough - boroughs borough - borrow borrow - borrowed borrow - borrower borrow - borrowing borrow - borrows borrow - bosko bosko - boskos bosko - bosky boski - bosom bosom - bosoms bosom - boson boson - boss boss - bosworth bosworth - botch botch - botcher botcher - botches botch - botchy botchi - both both - bots bot - bottle bottl - bottled bottl - bottles bottl - bottom bottom - bottomless bottomless - bottoms bottom - bouciqualt bouciqualt - bouge boug - bough bough - boughs bough - bought bought - bounce bounc - bouncing bounc - bound bound - bounded bound - bounden bounden - boundeth boundeth - bounding bound - boundless boundless - bounds bound - bounteous bounteou - bounteously bounteous - bounties bounti - bountiful bounti - bountifully bountifulli - bounty bounti - bourbier bourbier - bourbon bourbon - bourchier bourchier - bourdeaux bourdeaux - bourn bourn - bout bout - bouts bout - bove bove - bow bow - bowcase bowcas - bowed bow - bowels bowel - bower bower - bowing bow - bowl bowl - bowler bowler - bowling bowl - bowls bowl - bows bow - bowsprit bowsprit - bowstring bowstr - box box - boxes box - boy boi - boyet boyet - boyish boyish - boys boi - brabant brabant - brabantio brabantio - brabble brabbl - brabbler brabbler - brac brac - brace brace - bracelet bracelet - bracelets bracelet - brach brach - bracy braci - brag brag - bragg bragg - braggardism braggard - braggards braggard - braggart braggart - braggarts braggart - bragged brag - bragging brag - bragless bragless - brags brag - braid braid - braided braid - brain brain - brained brain - brainford brainford - brainish brainish - brainless brainless - brains brain - brainsick brainsick - brainsickly brainsickli - brake brake - brakenbury brakenburi - brakes brake - brambles brambl - bran bran - branch branch - branches branch - branchless branchless - brand brand - branded brand - brandish brandish - brandon brandon - brands brand - bras bra - brass brass - brassy brassi - brat brat - brats brat - brav brav - brave brave - braved brave - bravely brave - braver braver - bravery braveri - braves brave - bravest bravest - braving brave - brawl brawl - brawler brawler - brawling brawl - brawls brawl - brawn brawn - brawns brawn - bray brai - braying brai - braz braz - brazen brazen - brazier brazier - breach breach - breaches breach - bread bread - breadth breadth - break break - breaker breaker - breakfast breakfast - breaking break - breaks break - breast breast - breasted breast - breasting breast - breastplate breastplat - breasts breast - breath breath - breathe breath - breathed breath - breather breather - breathers breather - breathes breath - breathest breathest - breathing breath - breathless breathless - breaths breath - brecknock brecknock - bred bred - breech breech - breeches breech - breeching breech - breed breed - breeder breeder - breeders breeder - breeding breed - breeds breed - breese brees - breeze breez - breff breff - bretagne bretagn - brethen brethen - bretheren bretheren - brethren brethren - brevis brevi - brevity breviti - brew brew - brewage brewag - brewer brewer - brewers brewer - brewing brew - brews brew - briareus briareu - briars briar - brib brib - bribe bribe - briber briber - bribes bribe - brick brick - bricklayer bricklay - bricks brick - bridal bridal - bride bride - bridegroom bridegroom - bridegrooms bridegroom - brides bride - bridge bridg - bridgenorth bridgenorth - bridges bridg - bridget bridget - bridle bridl - bridled bridl - brief brief - briefer briefer - briefest briefest - briefly briefli - briefness brief - brier brier - briers brier - brigandine brigandin - bright bright - brighten brighten - brightest brightest - brightly brightli - brightness bright - brim brim - brimful brim - brims brim - brimstone brimston - brinded brind - brine brine - bring bring - bringer bringer - bringeth bringeth - bringing bring - bringings bring - brings bring - brinish brinish - brink brink - brisk brisk - brisky briski - bristle bristl - bristled bristl - bristly bristli - bristol bristol - bristow bristow - britain britain - britaine britain - britaines britain - british british - briton briton - britons briton - brittany brittani - brittle brittl - broach broach - broached broach - broad broad - broader broader - broadsides broadsid - brocas broca - brock brock - brogues brogu - broil broil - broiling broil - broils broil - broke broke - broken broken - brokenly brokenli - broker broker - brokers broker - brokes broke - broking broke - brooch brooch - brooches brooch - brood brood - brooded brood - brooding brood - brook brook - brooks brook - broom broom - broomstaff broomstaff - broth broth - brothel brothel - brother brother - brotherhood brotherhood - brotherhoods brotherhood - brotherly brotherli - brothers brother - broths broth - brought brought - brow brow - brown brown - browner browner - brownist brownist - browny browni - brows brow - browse brows - browsing brows - bruis brui - bruise bruis - bruised bruis - bruises bruis - bruising bruis - bruit bruit - bruited bruit - brundusium brundusium - brunt brunt - brush brush - brushes brush - brute brute - brutish brutish - brutus brutu - bubble bubbl - bubbles bubbl - bubbling bubbl - bubukles bubukl - buck buck - bucket bucket - buckets bucket - bucking buck - buckingham buckingham - buckle buckl - buckled buckl - buckler buckler - bucklers buckler - bucklersbury bucklersburi - buckles buckl - buckram buckram - bucks buck - bud bud - budded bud - budding bud - budge budg - budger budger - budget budget - buds bud - buff buff - buffet buffet - buffeting buffet - buffets buffet - bug bug - bugbear bugbear - bugle bugl - bugs bug - build build - builded build - buildeth buildeth - building build - buildings build - builds build - built built - bulk bulk - bulks bulk - bull bull - bullcalf bullcalf - bullen bullen - bullens bullen - bullet bullet - bullets bullet - bullocks bullock - bulls bull - bully bulli - bulmer bulmer - bulwark bulwark - bulwarks bulwark - bum bum - bumbast bumbast - bump bump - bumper bumper - bums bum - bunch bunch - bunches bunch - bundle bundl - bung bung - bunghole bunghol - bungle bungl - bunting bunt - buoy buoi - bur bur - burbolt burbolt - burd burd - burden burden - burdened burden - burdening burden - burdenous burden - burdens burden - burgh burgh - burgher burgher - burghers burgher - burglary burglari - burgomasters burgomast - burgonet burgonet - burgundy burgundi - burial burial - buried buri - burier burier - buriest buriest - burly burli - burn burn - burned burn - burnet burnet - burneth burneth - burning burn - burnish burnish - burns burn - burnt burnt - burr burr - burrows burrow - burs bur - burst burst - bursting burst - bursts burst - burthen burthen - burthens burthen - burton burton - bury buri - burying buri - bush bush - bushels bushel - bushes bush - bushy bushi - busied busi - busily busili - busines busin - business busi - businesses busi - buskin buskin - busky buski - buss buss - busses buss - bussing buss - bustle bustl - bustling bustl - busy busi - but but - butcheed butche - butcher butcher - butchered butcher - butcheries butcheri - butcherly butcherli - butchers butcher - butchery butcheri - butler butler - butt butt - butter butter - buttered butter - butterflies butterfli - butterfly butterfli - butterwoman butterwoman - buttery butteri - buttock buttock - buttocks buttock - button button - buttonhole buttonhol - buttons button - buttress buttress - buttry buttri - butts butt - buxom buxom - buy bui - buyer buyer - buying bui - buys bui - buzz buzz - buzzard buzzard - buzzards buzzard - buzzers buzzer - buzzing buzz - by by - bye bye - byzantium byzantium - c c - ca ca - cabbage cabbag - cabileros cabilero - cabin cabin - cabins cabin - cable cabl - cables cabl - cackling cackl - cacodemon cacodemon - caddis caddi - caddisses caddiss - cade cade - cadence cadenc - cadent cadent - cades cade - cadmus cadmu - caduceus caduceu - cadwal cadwal - cadwallader cadwallad - caelius caeliu - caelo caelo - caesar caesar - caesarion caesarion - caesars caesar - cage cage - caged cage - cagion cagion - cain cain - caithness caith - caitiff caitiff - caitiffs caitiff - caius caiu - cak cak - cake cake - cakes cake - calaber calab - calais calai - calamities calam - calamity calam - calchas calcha - calculate calcul - calen calen - calendar calendar - calendars calendar - calf calf - caliban caliban - calibans caliban - calipolis calipoli - cality caliti - caliver caliv - call call - callat callat - called call - callet callet - calling call - calls call - calm calm - calmest calmest - calmly calmli - calmness calm - calms calm - calpurnia calpurnia - calumniate calumni - calumniating calumni - calumnious calumni - calumny calumni - calve calv - calved calv - calves calv - calveskins calveskin - calydon calydon - cam cam - cambio cambio - cambria cambria - cambric cambric - cambrics cambric - cambridge cambridg - cambyses cambys - came came - camel camel - camelot camelot - camels camel - camest camest - camillo camillo - camlet camlet - camomile camomil - camp camp - campeius campeiu - camping camp - camps camp - can can - canakin canakin - canaries canari - canary canari - cancel cancel - cancell cancel - cancelled cancel - cancelling cancel - cancels cancel - cancer cancer - candidatus candidatu - candied candi - candle candl - candles candl - candlesticks candlestick - candy candi - canidius canidiu - cank cank - canker canker - cankerblossom cankerblossom - cankers canker - cannibally cannib - cannibals cannib - cannon cannon - cannoneer cannon - cannons cannon - cannot cannot - canon canon - canoniz canoniz - canonize canon - canonized canon - canons canon - canopied canopi - canopies canopi - canopy canopi - canst canst - canstick canstick - canterbury canterburi - cantle cantl - cantons canton - canus canu - canvas canva - canvass canvass - canzonet canzonet - cap cap - capability capabl - capable capabl - capacities capac - capacity capac - caparison caparison - capdv capdv - cape cape - capel capel - capels capel - caper caper - capers caper - capet capet - caphis caphi - capilet capilet - capitaine capitain - capital capit - capite capit - capitol capitol - capitulate capitul - capocchia capocchia - capon capon - capons capon - capp capp - cappadocia cappadocia - capriccio capriccio - capricious caprici - caps cap - capt capt - captain captain - captains captain - captainship captainship - captious captiou - captivate captiv - captivated captiv - captivates captiv - captive captiv - captives captiv - captivity captiv - captum captum - capucius capuciu - capulet capulet - capulets capulet - car car - carack carack - caracks carack - carat carat - caraways carawai - carbonado carbonado - carbuncle carbuncl - carbuncled carbuncl - carbuncles carbuncl - carcanet carcanet - carcase carcas - carcases carcas - carcass carcass - carcasses carcass - card card - cardecue cardecu - carded card - carders carder - cardinal cardin - cardinally cardin - cardinals cardin - cardmaker cardmak - cards card - carduus carduu - care care - cared care - career career - careers career - careful care - carefully carefulli - careless careless - carelessly carelessli - carelessness careless - cares care - caret caret - cargo cargo - carl carl - carlisle carlisl - carlot carlot - carman carman - carmen carmen - carnal carnal - carnally carnal - carnarvonshire carnarvonshir - carnation carnat - carnations carnat - carol carol - carous carou - carouse carous - caroused carous - carouses carous - carousing carous - carp carp - carpenter carpent - carper carper - carpet carpet - carpets carpet - carping carp - carriage carriag - carriages carriag - carried carri - carrier carrier - carriers carrier - carries carri - carrion carrion - carrions carrion - carry carri - carrying carri - cars car - cart cart - carters carter - carthage carthag - carts cart - carv carv - carve carv - carved carv - carver carver - carves carv - carving carv - cas ca - casa casa - casaer casaer - casca casca - case case - casement casement - casements casement - cases case - cash cash - cashier cashier - casing case - cask cask - casket casket - casketed casket - caskets casket - casque casqu - casques casqu - cassado cassado - cassandra cassandra - cassibelan cassibelan - cassio cassio - cassius cassiu - cassocks cassock - cast cast - castalion castalion - castaway castawai - castaways castawai - casted cast - caster caster - castigate castig - castigation castig - castile castil - castiliano castiliano - casting cast - castle castl - castles castl - casts cast - casual casual - casually casual - casualties casualti - casualty casualti - cat cat - cataian cataian - catalogue catalogu - cataplasm cataplasm - cataracts cataract - catarrhs catarrh - catastrophe catastroph - catch catch - catcher catcher - catches catch - catching catch - cate cate - catechising catechis - catechism catech - catechize catech - cater cater - caterpillars caterpillar - caters cater - caterwauling caterwaul - cates cate - catesby catesbi - cathedral cathedr - catlike catlik - catling catl - catlings catl - cato cato - cats cat - cattle cattl - caucasus caucasu - caudle caudl - cauf cauf - caught caught - cauldron cauldron - caus cau - cause caus - caused caus - causeless causeless - causer causer - causes caus - causest causest - causeth causeth - cautel cautel - cautelous cautel - cautels cautel - cauterizing cauter - caution caution - cautions caution - cavaleiro cavaleiro - cavalery cavaleri - cavaliers cavali - cave cave - cavern cavern - caverns cavern - caves cave - caveto caveto - caviary caviari - cavil cavil - cavilling cavil - cawdor cawdor - cawdron cawdron - cawing caw - ce ce - ceas cea - cease ceas - ceases ceas - ceaseth ceaseth - cedar cedar - cedars cedar - cedius cediu - celebrate celebr - celebrated celebr - celebrates celebr - celebration celebr - celerity celer - celestial celesti - celia celia - cell cell - cellar cellar - cellarage cellarag - celsa celsa - cement cement - censer censer - censor censor - censorinus censorinu - censur censur - censure censur - censured censur - censurers censur - censures censur - censuring censur - centaur centaur - centaurs centaur - centre centr - cents cent - centuries centuri - centurion centurion - centurions centurion - century centuri - cerberus cerberu - cerecloth cerecloth - cerements cerement - ceremonial ceremoni - ceremonies ceremoni - ceremonious ceremoni - ceremoniously ceremoni - ceremony ceremoni - ceres cere - cerns cern - certain certain - certainer certain - certainly certainli - certainties certainti - certainty certainti - certes cert - certificate certif - certified certifi - certifies certifi - certify certifi - ces ce - cesario cesario - cess cess - cesse cess - cestern cestern - cetera cetera - cette cett - chaces chace - chaf chaf - chafe chafe - chafed chafe - chafes chafe - chaff chaff - chaffless chaffless - chafing chafe - chain chain - chains chain - chair chair - chairs chair - chalic chalic - chalice chalic - chalices chalic - chalk chalk - chalks chalk - chalky chalki - challeng challeng - challenge challeng - challenged challeng - challenger challeng - challengers challeng - challenges challeng - cham cham - chamber chamber - chamberers chamber - chamberlain chamberlain - chamberlains chamberlain - chambermaid chambermaid - chambermaids chambermaid - chambers chamber - chameleon chameleon - champ champ - champagne champagn - champain champain - champains champain - champion champion - champions champion - chanc chanc - chance chanc - chanced chanc - chancellor chancellor - chances chanc - chandler chandler - chang chang - change chang - changeable changeabl - changed chang - changeful chang - changeling changel - changelings changel - changer changer - changes chang - changest changest - changing chang - channel channel - channels channel - chanson chanson - chant chant - chanticleer chanticl - chanting chant - chantries chantri - chantry chantri - chants chant - chaos chao - chap chap - chape chape - chapel chapel - chapeless chapeless - chapels chapel - chaplain chaplain - chaplains chaplain - chapless chapless - chaplet chaplet - chapmen chapmen - chaps chap - chapter chapter - character charact - charactered charact - characterless characterless - characters charact - charactery characteri - characts charact - charbon charbon - chare chare - chares chare - charg charg - charge charg - charged charg - chargeful charg - charges charg - chargeth chargeth - charging charg - chariest chariest - chariness chari - charing chare - chariot chariot - chariots chariot - charitable charit - charitably charit - charities chariti - charity chariti - charlemain charlemain - charles charl - charm charm - charmed charm - charmer charmer - charmeth charmeth - charmian charmian - charming charm - charmingly charmingli - charms charm - charneco charneco - charnel charnel - charolois charoloi - charon charon - charter charter - charters charter - chartreux chartreux - chary chari - charybdis charybdi - chas cha - chase chase - chased chase - chaser chaser - chaseth chaseth - chasing chase - chaste chast - chastely chast - chastis chasti - chastise chastis - chastised chastis - chastisement chastis - chastity chastiti - chat chat - chatham chatham - chatillon chatillon - chats chat - chatt chatt - chattels chattel - chatter chatter - chattering chatter - chattles chattl - chaud chaud - chaunted chaunt - chaw chaw - chawdron chawdron - che che - cheap cheap - cheapen cheapen - cheaper cheaper - cheapest cheapest - cheaply cheapli - cheapside cheapsid - cheat cheat - cheated cheat - cheater cheater - cheaters cheater - cheating cheat - cheats cheat - check check - checked check - checker checker - checking check - checks check - cheek cheek - cheeks cheek - cheer cheer - cheered cheer - cheerer cheerer - cheerful cheer - cheerfully cheerfulli - cheering cheer - cheerless cheerless - cheerly cheerli - cheers cheer - cheese chees - chequer chequer - cher cher - cherish cherish - cherished cherish - cherisher cherish - cherishes cherish - cherishing cherish - cherries cherri - cherry cherri - cherrypit cherrypit - chertsey chertsei - cherub cherub - cherubims cherubim - cherubin cherubin - cherubins cherubin - cheshu cheshu - chess chess - chest chest - chester chester - chestnut chestnut - chestnuts chestnut - chests chest - chetas cheta - chev chev - cheval cheval - chevalier chevali - chevaliers chevali - cheveril cheveril - chew chew - chewed chew - chewet chewet - chewing chew - chez chez - chi chi - chick chick - chicken chicken - chickens chicken - chicurmurco chicurmurco - chid chid - chidden chidden - chide chide - chiders chider - chides chide - chiding chide - chief chief - chiefest chiefest - chiefly chiefli - chien chien - child child - childed child - childeric childer - childhood childhood - childhoods childhood - childing child - childish childish - childishness childish - childlike childlik - childness child - children children - chill chill - chilling chill - chime chime - chimes chime - chimney chimnei - chimneypiece chimneypiec - chimneys chimnei - chimurcho chimurcho - chin chin - china china - chine chine - chines chine - chink chink - chinks chink - chins chin - chipp chipp - chipper chipper - chips chip - chiron chiron - chirping chirp - chirrah chirrah - chirurgeonly chirurgeonli - chisel chisel - chitopher chitoph - chivalrous chivalr - chivalry chivalri - choice choic - choicely choic - choicest choicest - choir choir - choirs choir - chok chok - choke choke - choked choke - chokes choke - choking choke - choler choler - choleric choler - cholers choler - chollors chollor - choose choos - chooser chooser - chooses choos - chooseth chooseth - choosing choos - chop chop - chopine chopin - choplogic choplog - chopp chopp - chopped chop - chopping chop - choppy choppi - chops chop - chopt chopt - chor chor - choristers chorist - chorus choru - chose chose - chosen chosen - chough chough - choughs chough - chrish chrish - christ christ - christen christen - christendom christendom - christendoms christendom - christening christen - christenings christen - christian christian - christianlike christianlik - christians christian - christmas christma - christom christom - christopher christoph - christophero christophero - chronicle chronicl - chronicled chronicl - chronicler chronicl - chroniclers chronicl - chronicles chronicl - chrysolite chrysolit - chuck chuck - chucks chuck - chud chud - chuffs chuff - church church - churches church - churchman churchman - churchmen churchmen - churchyard churchyard - churchyards churchyard - churl churl - churlish churlish - churlishly churlishli - churls churl - churn churn - chus chu - cicatrice cicatric - cicatrices cicatric - cicely cice - cicero cicero - ciceter cicet - ciel ciel - ciitzens ciitzen - cilicia cilicia - cimber cimber - cimmerian cimmerian - cinable cinabl - cincture cinctur - cinders cinder - cine cine - cinna cinna - cinque cinqu - cipher cipher - ciphers cipher - circa circa - circe circ - circle circl - circled circl - circlets circlet - circling circl - circuit circuit - circum circum - circumcised circumcis - circumference circumfer - circummur circummur - circumscrib circumscrib - circumscribed circumscrib - circumscription circumscript - circumspect circumspect - circumstance circumst - circumstanced circumstanc - circumstances circumst - circumstantial circumstanti - circumvent circumv - circumvention circumvent - cistern cistern - citadel citadel - cital cital - cite cite - cited cite - cites cite - cities citi - citing cite - citizen citizen - citizens citizen - cittern cittern - city citi - civet civet - civil civil - civility civil - civilly civilli - clack clack - clad clad - claim claim - claiming claim - claims claim - clamb clamb - clamber clamber - clammer clammer - clamor clamor - clamorous clamor - clamors clamor - clamour clamour - clamours clamour - clang clang - clangor clangor - clap clap - clapp clapp - clapped clap - clapper clapper - clapping clap - claps clap - clare clare - clarence clarenc - claret claret - claribel claribel - clasp clasp - clasps clasp - clatter clatter - claud claud - claudio claudio - claudius claudiu - clause claus - claw claw - clawed claw - clawing claw - claws claw - clay clai - clays clai - clean clean - cleanliest cleanliest - cleanly cleanli - cleans clean - cleanse cleans - cleansing cleans - clear clear - clearer clearer - clearest clearest - clearly clearli - clearness clear - clears clear - cleave cleav - cleaving cleav - clef clef - cleft cleft - cleitus cleitu - clemency clemenc - clement clement - cleomenes cleomen - cleopatpa cleopatpa - cleopatra cleopatra - clepeth clepeth - clept clept - clerestories clerestori - clergy clergi - clergyman clergyman - clergymen clergymen - clerk clerk - clerkly clerkli - clerks clerk - clew clew - client client - clients client - cliff cliff - clifford clifford - cliffords clifford - cliffs cliff - clifton clifton - climate climat - climature climatur - climb climb - climbed climb - climber climber - climbeth climbeth - climbing climb - climbs climb - clime clime - cling cling - clink clink - clinking clink - clinquant clinquant - clip clip - clipp clipp - clipper clipper - clippeth clippeth - clipping clip - clipt clipt - clitus clitu - clo clo - cloak cloak - cloakbag cloakbag - cloaks cloak - clock clock - clocks clock - clod clod - cloddy cloddi - clodpole clodpol - clog clog - clogging clog - clogs clog - cloister cloister - cloistress cloistress - cloquence cloquenc - clos clo - close close - closed close - closely close - closeness close - closer closer - closes close - closest closest - closet closet - closing close - closure closur - cloten cloten - clotens cloten - cloth cloth - clothair clothair - clotharius clothariu - clothe cloth - clothes cloth - clothier clothier - clothiers clothier - clothing cloth - cloths cloth - clotpoles clotpol - clotpoll clotpol - cloud cloud - clouded cloud - cloudiness cloudi - clouds cloud - cloudy cloudi - clout clout - clouted clout - clouts clout - cloven cloven - clover clover - cloves clove - clovest clovest - clowder clowder - clown clown - clownish clownish - clowns clown - cloy cloi - cloyed cloi - cloying cloi - cloyless cloyless - cloyment cloyment - cloys cloi - club club - clubs club - cluck cluck - clung clung - clust clust - clusters cluster - clutch clutch - clyster clyster - cneius cneiu - cnemies cnemi - co co - coach coach - coaches coach - coachmakers coachmak - coact coact - coactive coactiv - coagulate coagul - coal coal - coals coal - coarse coars - coarsely coars - coast coast - coasting coast - coasts coast - coat coat - coated coat - coats coat - cobble cobbl - cobbled cobbl - cobbler cobbler - cobham cobham - cobloaf cobloaf - cobweb cobweb - cobwebs cobweb - cock cock - cockatrice cockatric - cockatrices cockatric - cockle cockl - cockled cockl - cockney cocknei - cockpit cockpit - cocks cock - cocksure cocksur - coctus coctu - cocytus cocytu - cod cod - codding cod - codling codl - codpiece codpiec - codpieces codpiec - cods cod - coelestibus coelestibu - coesar coesar - coeur coeur - coffer coffer - coffers coffer - coffin coffin - coffins coffin - cog cog - cogging cog - cogitation cogit - cogitations cogit - cognition cognit - cognizance cogniz - cogscomb cogscomb - cohabitants cohabit - coher coher - cohere coher - coherence coher - coherent coher - cohorts cohort - coif coif - coign coign - coil coil - coin coin - coinage coinag - coiner coiner - coining coin - coins coin - col col - colbrand colbrand - colchos colcho - cold cold - colder colder - coldest coldest - coldly coldli - coldness cold - coldspur coldspur - colebrook colebrook - colic colic - collar collar - collars collar - collateral collater - colleagued colleagu - collect collect - collected collect - collection collect - college colleg - colleges colleg - collied colli - collier collier - colliers collier - collop collop - collusion collus - colme colm - colmekill colmekil - coloquintida coloquintida - color color - colors color - colossus colossu - colour colour - colourable colour - coloured colour - colouring colour - colours colour - colt colt - colted colt - colts colt - columbine columbin - columbines columbin - colville colvil - com com - comagene comagen - comart comart - comb comb - combat combat - combatant combat - combatants combat - combated combat - combating combat - combin combin - combinate combin - combination combin - combine combin - combined combin - combless combless - combustion combust - come come - comedian comedian - comedians comedian - comedy comedi - comeliness comeli - comely come - comer comer - comers comer - comes come - comest comest - comet comet - cometh cometh - comets comet - comfect comfect - comfit comfit - comfits comfit - comfort comfort - comfortable comfort - comforted comfort - comforter comfort - comforting comfort - comfortless comfortless - comforts comfort - comic comic - comical comic - coming come - comings come - cominius cominiu - comma comma - command command - commande command - commanded command - commander command - commanders command - commanding command - commandment command - commandments command - commands command - comme comm - commenc commenc - commence commenc - commenced commenc - commencement commenc - commences commenc - commencing commenc - commend commend - commendable commend - commendation commend - commendations commend - commended commend - commending commend - commends commend - comment comment - commentaries commentari - commenting comment - comments comment - commerce commerc - commingled commingl - commiseration commiser - commission commiss - commissioners commission - commissions commiss - commit commit - commits commit - committ committ - committed commit - committing commit - commix commix - commixed commix - commixtion commixt - commixture commixtur - commodious commodi - commodities commod - commodity commod - common common - commonalty commonalti - commoner common - commoners common - commonly commonli - commons common - commonweal commonw - commonwealth commonwealth - commotion commot - commotions commot - commune commun - communicat communicat - communicate commun - communication commun - communities commun - community commun - comonty comonti - compact compact - companies compani - companion companion - companions companion - companionship companionship - company compani - compar compar - comparative compar - compare compar - compared compar - comparing compar - comparison comparison - comparisons comparison - compartner compartn - compass compass - compasses compass - compassing compass - compassion compass - compassionate compassion - compeers compeer - compel compel - compell compel - compelled compel - compelling compel - compels compel - compensation compens - competence compet - competency compet - competent compet - competitor competitor - competitors competitor - compil compil - compile compil - compiled compil - complain complain - complainer complain - complainest complainest - complaining complain - complainings complain - complains complain - complaint complaint - complaints complaint - complement complement - complements complement - complete complet - complexion complexion - complexioned complexion - complexions complexion - complices complic - complies compli - compliment compliment - complimental compliment - compliments compliment - complot complot - complots complot - complotted complot - comply compli - compos compo - compose compos - composed compos - composition composit - compost compost - composture compostur - composure composur - compound compound - compounded compound - compounds compound - comprehend comprehend - comprehended comprehend - comprehends comprehend - compremises compremis - compris compri - comprising compris - compromis compromi - compromise compromis - compt compt - comptible comptibl - comptrollers comptrol - compulsatory compulsatori - compulsion compuls - compulsive compuls - compunctious compuncti - computation comput - comrade comrad - comrades comrad - comutual comutu - con con - concave concav - concavities concav - conceal conceal - concealed conceal - concealing conceal - concealment conceal - concealments conceal - conceals conceal - conceit conceit - conceited conceit - conceitless conceitless - conceits conceit - conceiv conceiv - conceive conceiv - conceived conceiv - conceives conceiv - conceiving conceiv - conception concept - conceptions concept - conceptious concepti - concern concern - concernancy concern - concerneth concerneth - concerning concern - concernings concern - concerns concern - conclave conclav - conclud conclud - conclude conclud - concluded conclud - concludes conclud - concluding conclud - conclusion conclus - conclusions conclus - concolinel concolinel - concord concord - concubine concubin - concupiscible concupisc - concupy concupi - concur concur - concurring concur - concurs concur - condemn condemn - condemnation condemn - condemned condemn - condemning condemn - condemns condemn - condescend condescend - condign condign - condition condit - conditionally condition - conditions condit - condole condol - condolement condol - condoling condol - conduce conduc - conduct conduct - conducted conduct - conducting conduct - conductor conductor - conduit conduit - conduits conduit - conected conect - coney conei - confection confect - confectionary confectionari - confections confect - confederacy confederaci - confederate confeder - confederates confeder - confer confer - conference confer - conferr conferr - conferring confer - confess confess - confessed confess - confesses confess - confesseth confesseth - confessing confess - confession confess - confessions confess - confessor confessor - confidence confid - confident confid - confidently confid - confin confin - confine confin - confined confin - confineless confineless - confiners confin - confines confin - confining confin - confirm confirm - confirmation confirm - confirmations confirm - confirmed confirm - confirmer confirm - confirmers confirm - confirming confirm - confirmities confirm - confirms confirm - confiscate confisc - confiscated confisc - confiscation confisc - confixed confix - conflict conflict - conflicting conflict - conflicts conflict - confluence confluenc - conflux conflux - conform conform - conformable conform - confound confound - confounded confound - confounding confound - confounds confound - confront confront - confronted confront - confus confu - confused confus - confusedly confusedli - confusion confus - confusions confus - confutation confut - confutes confut - congeal congeal - congealed congeal - congealment congeal - congee conge - conger conger - congest congest - congied congi - congratulate congratul - congreeing congre - congreeted congreet - congregate congreg - congregated congreg - congregation congreg - congregations congreg - congruent congruent - congruing congru - conies coni - conjectural conjectur - conjecture conjectur - conjectures conjectur - conjoin conjoin - conjoined conjoin - conjoins conjoin - conjointly conjointli - conjunct conjunct - conjunction conjunct - conjunctive conjunct - conjur conjur - conjuration conjur - conjurations conjur - conjure conjur - conjured conjur - conjurer conjur - conjurers conjur - conjures conjur - conjuring conjur - conjuro conjuro - conn conn - connected connect - connive conniv - conqu conqu - conquer conquer - conquered conquer - conquering conquer - conqueror conqueror - conquerors conqueror - conquers conquer - conquest conquest - conquests conquest - conquring conqur - conrade conrad - cons con - consanguineous consanguin - consanguinity consanguin - conscienc conscienc - conscience conscienc - consciences conscienc - conscionable conscion - consecrate consecr - consecrated consecr - consecrations consecr - consent consent - consented consent - consenting consent - consents consent - consequence consequ - consequences consequ - consequently consequ - conserve conserv - conserved conserv - conserves conserv - consider consid - considerance consider - considerate consider - consideration consider - considerations consider - considered consid - considering consid - considerings consid - considers consid - consign consign - consigning consign - consist consist - consisteth consisteth - consisting consist - consistory consistori - consists consist - consolate consol - consolation consol - consonancy conson - consonant conson - consort consort - consorted consort - consortest consortest - conspectuities conspectu - conspir conspir - conspiracy conspiraci - conspirant conspir - conspirator conspir - conspirators conspir - conspire conspir - conspired conspir - conspirers conspir - conspires conspir - conspiring conspir - constable constabl - constables constabl - constance constanc - constancies constanc - constancy constanc - constant constant - constantine constantin - constantinople constantinopl - constantly constantli - constellation constel - constitution constitut - constrain constrain - constrained constrain - constraineth constraineth - constrains constrain - constraint constraint - constring constr - construction construct - construe constru - consul consul - consuls consul - consulship consulship - consulships consulship - consult consult - consulting consult - consults consult - consum consum - consume consum - consumed consum - consumes consum - consuming consum - consummate consumm - consummation consumm - consumption consumpt - consumptions consumpt - contagion contagion - contagious contagi - contain contain - containing contain - contains contain - contaminate contamin - contaminated contamin - contemn contemn - contemned contemn - contemning contemn - contemns contemn - contemplate contempl - contemplation contempl - contemplative contempl - contempt contempt - contemptible contempt - contempts contempt - contemptuous contemptu - contemptuously contemptu - contend contend - contended contend - contending contend - contendon contendon - content content - contenta contenta - contented content - contenteth contenteth - contention content - contentious contenti - contentless contentless - contento contento - contents content - contest contest - contestation contest - continence contin - continency contin - continent contin - continents contin - continu continu - continual continu - continually continu - continuance continu - continuantly continuantli - continuate continu - continue continu - continued continu - continuer continu - continues continu - continuing continu - contract contract - contracted contract - contracting contract - contraction contract - contradict contradict - contradicted contradict - contradiction contradict - contradicts contradict - contraries contrari - contrarieties contrarieti - contrariety contrarieti - contrarious contrari - contrariously contrari - contrary contrari - contre contr - contribution contribut - contributors contributor - contrite contrit - contriv contriv - contrive contriv - contrived contriv - contriver contriv - contrives contriv - contriving contriv - control control - controll control - controller control - controlling control - controlment control - controls control - controversy controversi - contumelious contumeli - contumeliously contumeli - contumely contum - contusions contus - convenience conveni - conveniences conveni - conveniency conveni - convenient conveni - conveniently conveni - convented convent - conventicles conventicl - convents convent - convers conver - conversant convers - conversation convers - conversations convers - converse convers - conversed convers - converses convers - conversing convers - conversion convers - convert convert - converted convert - convertest convertest - converting convert - convertite convertit - convertites convertit - converts convert - convey convei - conveyance convey - conveyances convey - conveyers convey - conveying convei - convict convict - convicted convict - convince convinc - convinced convinc - convinces convinc - convive conviv - convocation convoc - convoy convoi - convulsions convuls - cony coni - cook cook - cookery cookeri - cooks cook - cool cool - cooled cool - cooling cool - cools cool - coop coop - coops coop - cop cop - copatain copatain - cope cope - cophetua cophetua - copied copi - copies copi - copious copiou - copper copper - copperspur copperspur - coppice coppic - copulation copul - copulatives copul - copy copi - cor cor - coragio coragio - coral coral - coram coram - corambus corambu - coranto coranto - corantos coranto - corbo corbo - cord cord - corded cord - cordelia cordelia - cordial cordial - cordis cordi - cords cord - core core - corin corin - corinth corinth - corinthian corinthian - coriolanus coriolanu - corioli corioli - cork cork - corky corki - cormorant cormor - corn corn - cornelia cornelia - cornelius corneliu - corner corner - corners corner - cornerstone cornerston - cornets cornet - cornish cornish - corns corn - cornuto cornuto - cornwall cornwal - corollary corollari - coronal coron - coronation coron - coronet coronet - coronets coronet - corporal corpor - corporals corpor - corporate corpor - corpse corps - corpulent corpul - correct correct - corrected correct - correcting correct - correction correct - correctioner correction - corrects correct - correspondence correspond - correspondent correspond - corresponding correspond - corresponsive correspons - corrigible corrig - corrival corriv - corrivals corriv - corroborate corrobor - corrosive corros - corrupt corrupt - corrupted corrupt - corrupter corrupt - corrupters corrupt - corruptible corrupt - corruptibly corrupt - corrupting corrupt - corruption corrupt - corruptly corruptli - corrupts corrupt - corse cors - corses cors - corslet corslet - cosmo cosmo - cost cost - costard costard - costermongers costermong - costlier costlier - costly costli - costs cost - cot cot - cote cote - coted cote - cotsall cotsal - cotsole cotsol - cotswold cotswold - cottage cottag - cottages cottag - cotus cotu - couch couch - couched couch - couching couch - couchings couch - coude coud - cough cough - coughing cough - could could - couldst couldst - coulter coulter - council council - councillor councillor - councils council - counsel counsel - counsell counsel - counsellor counsellor - counsellors counsellor - counselor counselor - counselors counselor - counsels counsel - count count - counted count - countenanc countenanc - countenance counten - countenances counten - counter counter - counterchange counterchang - countercheck countercheck - counterfeit counterfeit - counterfeited counterfeit - counterfeiting counterfeit - counterfeitly counterfeitli - counterfeits counterfeit - countermand countermand - countermands countermand - countermines countermin - counterpart counterpart - counterpoints counterpoint - counterpois counterpoi - counterpoise counterpois - counters counter - countervail countervail - countess countess - countesses countess - counties counti - counting count - countless countless - countries countri - countrv countrv - country countri - countryman countryman - countrymen countrymen - counts count - county counti - couper couper - couple coupl - coupled coupl - couplement couplement - couples coupl - couplet couplet - couplets couplet - cour cour - courage courag - courageous courag - courageously courag - courages courag - courier courier - couriers courier - couronne couronn - cours cour - course cours - coursed cours - courser courser - coursers courser - courses cours - coursing cours - court court - courted court - courteous courteou - courteously courteous - courtesan courtesan - courtesies courtesi - courtesy courtesi - courtezan courtezan - courtezans courtezan - courtier courtier - courtiers courtier - courtlike courtlik - courtly courtli - courtney courtnei - courts court - courtship courtship - cousin cousin - cousins cousin - couterfeit couterfeit - coutume coutum - covenant coven - covenants coven - covent covent - coventry coventri - cover cover - covered cover - covering cover - coverlet coverlet - covers cover - covert covert - covertly covertli - coverture covertur - covet covet - coveted covet - coveting covet - covetings covet - covetous covet - covetously covet - covetousness covet - covets covet - cow cow - coward coward - cowarded coward - cowardice cowardic - cowardly cowardli - cowards coward - cowardship cowardship - cowish cowish - cowl cowl - cowslip cowslip - cowslips cowslip - cox cox - coxcomb coxcomb - coxcombs coxcomb - coy coi - coystrill coystril - coz coz - cozen cozen - cozenage cozenag - cozened cozen - cozener cozen - cozeners cozen - cozening cozen - coziers cozier - crab crab - crabbed crab - crabs crab - crack crack - cracked crack - cracker cracker - crackers cracker - cracking crack - cracks crack - cradle cradl - cradled cradl - cradles cradl - craft craft - crafted craft - craftied crafti - craftier craftier - craftily craftili - crafts craft - craftsmen craftsmen - crafty crafti - cram cram - cramm cramm - cramp cramp - cramps cramp - crams cram - cranking crank - cranks crank - cranmer cranmer - crannied cranni - crannies cranni - cranny cranni - crants crant - crare crare - crash crash - crassus crassu - crav crav - crave crave - craved crave - craven craven - cravens craven - craves crave - craveth craveth - craving crave - crawl crawl - crawling crawl - crawls crawl - craz craz - crazed craze - crazy crazi - creaking creak - cream cream - create creat - created creat - creates creat - creating creat - creation creation - creator creator - creature creatur - creatures creatur - credence credenc - credent credent - credible credibl - credit credit - creditor creditor - creditors creditor - credo credo - credulity credul - credulous credul - creed creed - creek creek - creeks creek - creep creep - creeping creep - creeps creep - crept crept - crescent crescent - crescive cresciv - cressets cresset - cressid cressid - cressida cressida - cressids cressid - cressy cressi - crest crest - crested crest - crestfall crestfal - crestless crestless - crests crest - cretan cretan - crete crete - crevice crevic - crew crew - crews crew - crib crib - cribb cribb - cribs crib - cricket cricket - crickets cricket - cried cri - criedst criedst - crier crier - cries cri - criest criest - crieth crieth - crime crime - crimeful crime - crimeless crimeless - crimes crime - criminal crimin - crimson crimson - cringe cring - cripple crippl - crisp crisp - crisped crisp - crispian crispian - crispianus crispianu - crispin crispin - critic critic - critical critic - critics critic - croak croak - croaking croak - croaks croak - crocodile crocodil - cromer cromer - cromwell cromwel - crone crone - crook crook - crookback crookback - crooked crook - crooking crook - crop crop - cropp cropp - crosby crosbi - cross cross - crossed cross - crosses cross - crossest crossest - crossing cross - crossings cross - crossly crossli - crossness cross - crost crost - crotchets crotchet - crouch crouch - crouching crouch - crow crow - crowd crowd - crowded crowd - crowding crowd - crowds crowd - crowflowers crowflow - crowing crow - crowkeeper crowkeep - crown crown - crowned crown - crowner crowner - crownet crownet - crownets crownet - crowning crown - crowns crown - crows crow - crudy crudi - cruel cruel - cruell cruell - crueller crueller - cruelly cruelli - cruels cruel - cruelty cruelti - crum crum - crumble crumbl - crumbs crumb - crupper crupper - crusadoes crusado - crush crush - crushed crush - crushest crushest - crushing crush - crust crust - crusts crust - crusty crusti - crutch crutch - crutches crutch - cry cry - crying cry - crystal crystal - crystalline crystallin - crystals crystal - cub cub - cubbert cubbert - cubiculo cubiculo - cubit cubit - cubs cub - cuckold cuckold - cuckoldly cuckoldli - cuckolds cuckold - cuckoo cuckoo - cucullus cucullu - cudgel cudgel - cudgeled cudgel - cudgell cudgel - cudgelling cudgel - cudgels cudgel - cue cue - cues cue - cuff cuff - cuffs cuff - cuique cuiqu - cull cull - culling cull - cullion cullion - cullionly cullionli - cullions cullion - culpable culpabl - culverin culverin - cum cum - cumber cumber - cumberland cumberland - cunning cun - cunningly cunningli - cunnings cun - cuore cuor - cup cup - cupbearer cupbear - cupboarding cupboard - cupid cupid - cupids cupid - cuppele cuppel - cups cup - cur cur - curan curan - curate curat - curb curb - curbed curb - curbing curb - curbs curb - curd curd - curdied curdi - curds curd - cure cure - cured cure - cureless cureless - curer curer - cures cure - curfew curfew - curing cure - curio curio - curiosity curios - curious curiou - curiously curious - curl curl - curled curl - curling curl - curls curl - currance curranc - currants currant - current current - currents current - currish currish - curry curri - curs cur - curse curs - cursed curs - curses curs - cursies cursi - cursing curs - cursorary cursorari - curst curst - curster curster - curstest curstest - curstness curst - cursy cursi - curtail curtail - curtain curtain - curtains curtain - curtal curtal - curtis curti - curtle curtl - curtsied curtsi - curtsies curtsi - curtsy curtsi - curvet curvet - curvets curvet - cushes cush - cushion cushion - cushions cushion - custalorum custalorum - custard custard - custody custodi - custom custom - customary customari - customed custom - customer custom - customers custom - customs custom - custure custur - cut cut - cutler cutler - cutpurse cutpurs - cutpurses cutpurs - cuts cut - cutter cutter - cutting cut - cuttle cuttl - cxsar cxsar - cyclops cyclop - cydnus cydnu - cygnet cygnet - cygnets cygnet - cym cym - cymbals cymbal - cymbeline cymbelin - cyme cyme - cynic cynic - cynthia cynthia - cypress cypress - cypriot cypriot - cyprus cypru - cyrus cyru - cytherea cytherea - d d - dabbled dabbl - dace dace - dad dad - daedalus daedalu - daemon daemon - daff daff - daffed daf - daffest daffest - daffodils daffodil - dagger dagger - daggers dagger - dagonet dagonet - daily daili - daintier daintier - dainties dainti - daintiest daintiest - daintily daintili - daintiness dainti - daintry daintri - dainty dainti - daisied daisi - daisies daisi - daisy daisi - dale dale - dalliance dallianc - dallied dalli - dallies dalli - dally dalli - dallying dalli - dalmatians dalmatian - dam dam - damage damag - damascus damascu - damask damask - damasked damask - dame dame - dames dame - damm damm - damn damn - damnable damnabl - damnably damnabl - damnation damnat - damned damn - damns damn - damoiselle damoisel - damon damon - damosella damosella - damp damp - dams dam - damsel damsel - damsons damson - dan dan - danc danc - dance danc - dancer dancer - dances danc - dancing danc - dandle dandl - dandy dandi - dane dane - dang dang - danger danger - dangerous danger - dangerously danger - dangers danger - dangling dangl - daniel daniel - danish danish - dank dank - dankish dankish - danskers dansker - daphne daphn - dappled dappl - dapples dappl - dar dar - dardan dardan - dardanian dardanian - dardanius dardaniu - dare dare - dared dare - dareful dare - dares dare - darest darest - daring dare - darius dariu - dark dark - darken darken - darkening darken - darkens darken - darker darker - darkest darkest - darkling darkl - darkly darkli - darkness dark - darling darl - darlings darl - darnel darnel - darraign darraign - dart dart - darted dart - darter darter - dartford dartford - darting dart - darts dart - dash dash - dashes dash - dashing dash - dastard dastard - dastards dastard - dat dat - datchet datchet - date date - dated date - dateless dateless - dates date - daub daub - daughter daughter - daughters daughter - daunt daunt - daunted daunt - dauntless dauntless - dauphin dauphin - daventry daventri - davy davi - daw daw - dawn dawn - dawning dawn - daws daw - day dai - daylight daylight - days dai - dazzle dazzl - dazzled dazzl - dazzling dazzl - de de - dead dead - deadly deadli - deaf deaf - deafing deaf - deafness deaf - deafs deaf - deal deal - dealer dealer - dealers dealer - dealest dealest - dealing deal - dealings deal - deals deal - dealt dealt - dean dean - deanery deaneri - dear dear - dearer dearer - dearest dearest - dearly dearli - dearness dear - dears dear - dearth dearth - dearths dearth - death death - deathbed deathb - deathful death - deaths death - deathsman deathsman - deathsmen deathsmen - debarred debar - debase debas - debate debat - debated debat - debatement debat - debateth debateth - debating debat - debauch debauch - debile debil - debility debil - debitor debitor - debonair debonair - deborah deborah - debosh debosh - debt debt - debted debt - debtor debtor - debtors debtor - debts debt - debuty debuti - decay decai - decayed decai - decayer decay - decaying decai - decays decai - deceas decea - decease deceas - deceased deceas - deceit deceit - deceitful deceit - deceits deceit - deceiv deceiv - deceivable deceiv - deceive deceiv - deceived deceiv - deceiver deceiv - deceivers deceiv - deceives deceiv - deceivest deceivest - deceiveth deceiveth - deceiving deceiv - december decemb - decent decent - deceptious decepti - decerns decern - decide decid - decides decid - decimation decim - decipher deciph - deciphers deciph - decision decis - decius deciu - deck deck - decking deck - decks deck - deckt deckt - declare declar - declares declar - declension declens - declensions declens - declin declin - decline declin - declined declin - declines declin - declining declin - decoct decoct - decorum decorum - decreas decrea - decrease decreas - decreasing decreas - decree decre - decreed decre - decrees decre - decrepit decrepit - dedicate dedic - dedicated dedic - dedicates dedic - dedication dedic - deed deed - deedless deedless - deeds deed - deem deem - deemed deem - deep deep - deeper deeper - deepest deepest - deeply deepli - deeps deep - deepvow deepvow - deer deer - deesse deess - defac defac - deface defac - defaced defac - defacer defac - defacers defac - defacing defac - defam defam - default default - defeat defeat - defeated defeat - defeats defeat - defeatures defeatur - defect defect - defective defect - defects defect - defence defenc - defences defenc - defend defend - defendant defend - defended defend - defender defend - defenders defend - defending defend - defends defend - defense defens - defensible defens - defensive defens - defer defer - deferr deferr - defiance defianc - deficient defici - defied defi - defies defi - defil defil - defile defil - defiler defil - defiles defil - defiling defil - define defin - definement defin - definite definit - definitive definit - definitively definit - deflow deflow - deflower deflow - deflowered deflow - deform deform - deformed deform - deformities deform - deformity deform - deftly deftli - defunct defunct - defunction defunct - defuse defus - defy defi - defying defi - degenerate degener - degraded degrad - degree degre - degrees degre - deified deifi - deifying deifi - deign deign - deigned deign - deiphobus deiphobu - deities deiti - deity deiti - deja deja - deject deject - dejected deject - delabreth delabreth - delay delai - delayed delai - delaying delai - delays delai - delectable delect - deliberate deliber - delicate delic - delicates delic - delicious delici - deliciousness delici - delight delight - delighted delight - delightful delight - delights delight - delinquents delinqu - deliv deliv - deliver deliv - deliverance deliver - delivered deliv - delivering deliv - delivers deliv - delivery deliveri - delphos delpho - deluded delud - deluding delud - deluge delug - delve delv - delver delver - delves delv - demand demand - demanded demand - demanding demand - demands demand - demean demean - demeanor demeanor - demeanour demeanour - demerits demerit - demesnes demesn - demetrius demetriu - demi demi - demigod demigod - demise demis - demoiselles demoisel - demon demon - demonstrable demonstr - demonstrate demonstr - demonstrated demonstr - demonstrating demonstr - demonstration demonstr - demonstrative demonstr - demure demur - demurely demur - demuring demur - den den - denay denai - deni deni - denial denial - denials denial - denied deni - denier denier - denies deni - deniest deniest - denis deni - denmark denmark - dennis denni - denny denni - denote denot - denoted denot - denotement denot - denounc denounc - denounce denounc - denouncing denounc - dens den - denunciation denunci - deny deni - denying deni - deo deo - depart depart - departed depart - departest departest - departing depart - departure departur - depeche depech - depend depend - dependant depend - dependants depend - depended depend - dependence depend - dependences depend - dependency depend - dependent depend - dependents depend - depender depend - depending depend - depends depend - deplore deplor - deploring deplor - depopulate depopul - depos depo - depose depos - deposed depos - deposing depos - depositaries depositari - deprav deprav - depravation deprav - deprave deprav - depraved deprav - depraves deprav - depress depress - depriv depriv - deprive depriv - depth depth - depths depth - deputation deput - depute deput - deputed deput - deputies deputi - deputing deput - deputy deputi - deracinate deracin - derby derbi - dercetas derceta - dere dere - derides derid - derision deris - deriv deriv - derivation deriv - derivative deriv - derive deriv - derived deriv - derives deriv - derogate derog - derogately derog - derogation derog - des de - desartless desartless - descant descant - descend descend - descended descend - descending descend - descends descend - descension descens - descent descent - descents descent - describe describ - described describ - describes describ - descried descri - description descript - descriptions descript - descry descri - desdemon desdemon - desdemona desdemona - desert desert - deserts desert - deserv deserv - deserve deserv - deserved deserv - deservedly deservedli - deserver deserv - deservers deserv - deserves deserv - deservest deservest - deserving deserv - deservings deserv - design design - designment design - designments design - designs design - desir desir - desire desir - desired desir - desirers desir - desires desir - desirest desirest - desiring desir - desirous desir - desist desist - desk desk - desolate desol - desolation desol - desp desp - despair despair - despairing despair - despairs despair - despatch despatch - desperate desper - desperately desper - desperation desper - despis despi - despise despis - despised despis - despiser despis - despiseth despiseth - despising despis - despite despit - despiteful despit - despoiled despoil - dest dest - destin destin - destined destin - destinies destini - destiny destini - destitute destitut - destroy destroi - destroyed destroi - destroyer destroy - destroyers destroy - destroying destroi - destroys destroi - destruction destruct - destructions destruct - det det - detain detain - detains detain - detect detect - detected detect - detecting detect - detection detect - detector detector - detects detect - detention detent - determin determin - determinate determin - determination determin - determinations determin - determine determin - determined determin - determines determin - detest detest - detestable detest - detested detest - detesting detest - detests detest - detract detract - detraction detract - detractions detract - deucalion deucalion - deuce deuc - deum deum - deux deux - devant devant - devesting devest - device devic - devices devic - devil devil - devilish devilish - devils devil - devis devi - devise devis - devised devis - devises devis - devising devis - devoid devoid - devonshire devonshir - devote devot - devoted devot - devotion devot - devour devour - devoured devour - devourers devour - devouring devour - devours devour - devout devout - devoutly devoutli - dew dew - dewberries dewberri - dewdrops dewdrop - dewlap dewlap - dewlapp dewlapp - dews dew - dewy dewi - dexter dexter - dexteriously dexteri - dexterity dexter - di di - diable diabl - diablo diablo - diadem diadem - dial dial - dialect dialect - dialogue dialogu - dialogued dialogu - dials dial - diameter diamet - diamond diamond - diamonds diamond - dian dian - diana diana - diaper diaper - dibble dibbl - dic dic - dice dice - dicers dicer - dich dich - dick dick - dickens dicken - dickon dickon - dicky dicki - dictator dictat - diction diction - dictynna dictynna - did did - diddle diddl - didest didest - dido dido - didst didst - die die - died di - diedst diedst - dies di - diest diest - diet diet - dieted diet - dieter dieter - dieu dieu - diff diff - differ differ - difference differ - differences differ - differency differ - different differ - differing differ - differs differ - difficile difficil - difficult difficult - difficulties difficulti - difficulty difficulti - diffidence diffid - diffidences diffid - diffus diffu - diffused diffus - diffusest diffusest - dig dig - digest digest - digested digest - digestion digest - digestions digest - digg digg - digging dig - dighton dighton - dignified dignifi - dignifies dignifi - dignify dignifi - dignities digniti - dignity digniti - digress digress - digressing digress - digression digress - digs dig - digt digt - dilate dilat - dilated dilat - dilations dilat - dilatory dilatori - dild dild - dildos dildo - dilemma dilemma - dilemmas dilemma - diligence dilig - diligent dilig - diluculo diluculo - dim dim - dimension dimens - dimensions dimens - diminish diminish - diminishing diminish - diminution diminut - diminutive diminut - diminutives diminut - dimm dimm - dimmed dim - dimming dim - dimpled dimpl - dimples dimpl - dims dim - din din - dine dine - dined dine - diner diner - dines dine - ding ding - dining dine - dinner dinner - dinners dinner - dinnertime dinnertim - dint dint - diomed diom - diomede diomed - diomedes diomed - dion dion - dip dip - dipp dipp - dipping dip - dips dip - dir dir - dire dire - direct direct - directed direct - directing direct - direction direct - directions direct - directitude directitud - directive direct - directly directli - directs direct - direful dire - direness dire - direst direst - dirge dirg - dirges dirg - dirt dirt - dirty dirti - dis di - disability disabl - disable disabl - disabled disabl - disabling disabl - disadvantage disadvantag - disagree disagre - disallow disallow - disanimates disanim - disannul disannul - disannuls disannul - disappointed disappoint - disarm disarm - disarmed disarm - disarmeth disarmeth - disarms disarm - disaster disast - disasters disast - disastrous disastr - disbench disbench - disbranch disbranch - disburdened disburden - disburs disbur - disburse disburs - disbursed disburs - discandy discandi - discandying discandi - discard discard - discarded discard - discase discas - discased discas - discern discern - discerner discern - discerning discern - discernings discern - discerns discern - discharg discharg - discharge discharg - discharged discharg - discharging discharg - discipled discipl - disciples discipl - disciplin disciplin - discipline disciplin - disciplined disciplin - disciplines disciplin - disclaim disclaim - disclaiming disclaim - disclaims disclaim - disclos disclo - disclose disclos - disclosed disclos - discloses disclos - discolour discolour - discoloured discolour - discolours discolour - discomfit discomfit - discomfited discomfit - discomfiture discomfitur - discomfort discomfort - discomfortable discomfort - discommend discommend - disconsolate disconsol - discontent discont - discontented discont - discontentedly discontentedli - discontenting discont - discontents discont - discontinue discontinu - discontinued discontinu - discord discord - discordant discord - discords discord - discourse discours - discoursed discours - discourser discours - discourses discours - discoursive discours - discourtesy discourtesi - discov discov - discover discov - discovered discov - discoverers discover - discoveries discoveri - discovering discov - discovers discov - discovery discoveri - discredit discredit - discredited discredit - discredits discredit - discreet discreet - discreetly discreetli - discretion discret - discretions discret - discuss discuss - disdain disdain - disdained disdain - disdaineth disdaineth - disdainful disdain - disdainfully disdainfulli - disdaining disdain - disdains disdain - disdnguish disdnguish - diseas disea - disease diseas - diseased diseas - diseases diseas - disedg disedg - disembark disembark - disfigure disfigur - disfigured disfigur - disfurnish disfurnish - disgorge disgorg - disgrac disgrac - disgrace disgrac - disgraced disgrac - disgraceful disgrac - disgraces disgrac - disgracing disgrac - disgracious disgraci - disguis disgui - disguise disguis - disguised disguis - disguiser disguis - disguises disguis - disguising disguis - dish dish - dishabited dishabit - dishclout dishclout - dishearten dishearten - disheartens dishearten - dishes dish - dishonest dishonest - dishonestly dishonestli - dishonesty dishonesti - dishonor dishonor - dishonorable dishonor - dishonors dishonor - dishonour dishonour - dishonourable dishonour - dishonoured dishonour - dishonours dishonour - disinherit disinherit - disinherited disinherit - disjoin disjoin - disjoining disjoin - disjoins disjoin - disjoint disjoint - disjunction disjunct - dislik dislik - dislike dislik - disliken disliken - dislikes dislik - dislimns dislimn - dislocate disloc - dislodg dislodg - disloyal disloy - disloyalty disloyalti - dismal dismal - dismantle dismantl - dismantled dismantl - dismask dismask - dismay dismai - dismayed dismai - dismemb dismemb - dismember dismemb - dismes dism - dismiss dismiss - dismissed dismiss - dismissing dismiss - dismission dismiss - dismount dismount - dismounted dismount - disnatur disnatur - disobedience disobedi - disobedient disobedi - disobey disobei - disobeys disobei - disorb disorb - disorder disord - disordered disord - disorderly disorderli - disorders disord - disparage disparag - disparagement disparag - disparagements disparag - dispark dispark - dispatch dispatch - dispensation dispens - dispense dispens - dispenses dispens - dispers disper - disperse dispers - dispersed dispers - dispersedly dispersedli - dispersing dispers - dispiteous dispit - displac displac - displace displac - displaced displac - displant displant - displanting displant - display displai - displayed displai - displeas displea - displease displeas - displeased displeas - displeasing displeas - displeasure displeasur - displeasures displeasur - disponge dispong - disport disport - disports disport - dispos dispo - dispose dispos - disposed dispos - disposer dispos - disposing dispos - disposition disposit - dispositions disposit - dispossess dispossess - dispossessing dispossess - disprais disprai - dispraise disprais - dispraising disprais - dispraisingly dispraisingli - dispropertied disproperti - disproportion disproport - disproportioned disproport - disprov disprov - disprove disprov - disproved disprov - dispursed dispurs - disputable disput - disputation disput - disputations disput - dispute disput - disputed disput - disputes disput - disputing disput - disquantity disquant - disquiet disquiet - disquietly disquietli - disrelish disrelish - disrobe disrob - disseat disseat - dissemble dissembl - dissembled dissembl - dissembler dissembl - dissemblers dissembl - dissembling dissembl - dissembly dissembl - dissension dissens - dissensions dissens - dissentious dissenti - dissever dissev - dissipation dissip - dissolute dissolut - dissolutely dissolut - dissolution dissolut - dissolutions dissolut - dissolv dissolv - dissolve dissolv - dissolved dissolv - dissolves dissolv - dissuade dissuad - dissuaded dissuad - distaff distaff - distaffs distaff - distain distain - distains distain - distance distanc - distant distant - distaste distast - distasted distast - distasteful distast - distemp distemp - distemper distemp - distemperature distemperatur - distemperatures distemperatur - distempered distemp - distempering distemp - distil distil - distill distil - distillation distil - distilled distil - distills distil - distilment distil - distinct distinct - distinction distinct - distinctly distinctli - distingue distingu - distinguish distinguish - distinguishes distinguish - distinguishment distinguish - distract distract - distracted distract - distractedly distractedli - distraction distract - distractions distract - distracts distract - distrain distrain - distraught distraught - distress distress - distressed distress - distresses distress - distressful distress - distribute distribut - distributed distribut - distribution distribut - distrust distrust - distrustful distrust - disturb disturb - disturbed disturb - disturbers disturb - disturbing disturb - disunite disunit - disvalued disvalu - disvouch disvouch - dit dit - ditch ditch - ditchers ditcher - ditches ditch - dites dite - ditties ditti - ditty ditti - diurnal diurnal - div div - dive dive - diver diver - divers diver - diversely divers - diversity divers - divert divert - diverted divert - diverts divert - dives dive - divest divest - dividable divid - dividant divid - divide divid - divided divid - divides divid - divideth divideth - divin divin - divination divin - divine divin - divinely divin - divineness divin - diviner divin - divines divin - divinest divinest - divining divin - divinity divin - division divis - divisions divis - divorc divorc - divorce divorc - divorced divorc - divorcement divorc - divorcing divorc - divulg divulg - divulge divulg - divulged divulg - divulging divulg - dizy dizi - dizzy dizzi - do do - doating doat - dobbin dobbin - dock dock - docks dock - doct doct - doctor doctor - doctors doctor - doctrine doctrin - document document - dodge dodg - doe doe - doer doer - doers doer - does doe - doest doest - doff doff - dog dog - dogberry dogberri - dogfish dogfish - dogg dogg - dogged dog - dogs dog - doigts doigt - doing do - doings do - doit doit - doits doit - dolabella dolabella - dole dole - doleful dole - doll doll - dollar dollar - dollars dollar - dolor dolor - dolorous dolor - dolour dolour - dolours dolour - dolphin dolphin - dolt dolt - dolts dolt - domestic domest - domestics domest - dominance domin - dominations domin - dominator domin - domine domin - domineer domin - domineering domin - dominical domin - dominion dominion - dominions dominion - domitius domitiu - dommelton dommelton - don don - donalbain donalbain - donation donat - donc donc - doncaster doncast - done done - dong dong - donn donn - donne donn - donner donner - donnerai donnerai - doom doom - doomsday doomsdai - door door - doorkeeper doorkeep - doors door - dorcas dorca - doreus doreu - doricles doricl - dormouse dormous - dorothy dorothi - dorset dorset - dorsetshire dorsetshir - dost dost - dotage dotag - dotant dotant - dotard dotard - dotards dotard - dote dote - doted dote - doters doter - dotes dote - doteth doteth - doth doth - doting dote - double doubl - doubled doubl - doubleness doubl - doubler doubler - doublet doublet - doublets doublet - doubling doubl - doubly doubli - doubt doubt - doubted doubt - doubtful doubt - doubtfully doubtfulli - doubting doubt - doubtless doubtless - doubts doubt - doug doug - dough dough - doughty doughti - doughy doughi - douglas dougla - dout dout - doute dout - douts dout - dove dove - dovehouse dovehous - dover dover - doves dove - dow dow - dowager dowag - dowdy dowdi - dower dower - dowerless dowerless - dowers dower - dowlas dowla - dowle dowl - down down - downfall downfal - downright downright - downs down - downstairs downstair - downtrod downtrod - downward downward - downwards downward - downy downi - dowries dowri - dowry dowri - dowsabel dowsabel - doxy doxi - dozed doze - dozen dozen - dozens dozen - dozy dozi - drab drab - drabbing drab - drabs drab - drachma drachma - drachmas drachma - draff draff - drag drag - dragg dragg - dragged drag - dragging drag - dragon dragon - dragonish dragonish - dragons dragon - drain drain - drained drain - drains drain - drake drake - dram dram - dramatis dramati - drank drank - draught draught - draughts draught - drave drave - draw draw - drawbridge drawbridg - drawer drawer - drawers drawer - draweth draweth - drawing draw - drawling drawl - drawn drawn - draws draw - drayman drayman - draymen draymen - dread dread - dreaded dread - dreadful dread - dreadfully dreadfulli - dreading dread - dreads dread - dream dream - dreamer dreamer - dreamers dreamer - dreaming dream - dreams dream - dreamt dreamt - drearning drearn - dreary dreari - dreg dreg - dregs dreg - drench drench - drenched drench - dress dress - dressed dress - dresser dresser - dressing dress - dressings dress - drest drest - drew drew - dribbling dribbl - dried dri - drier drier - dries dri - drift drift - drily drili - drink drink - drinketh drinketh - drinking drink - drinkings drink - drinks drink - driv driv - drive drive - drivelling drivel - driven driven - drives drive - driveth driveth - driving drive - drizzle drizzl - drizzled drizzl - drizzles drizzl - droit droit - drollery drolleri - dromio dromio - dromios dromio - drone drone - drones drone - droop droop - droopeth droopeth - drooping droop - droops droop - drop drop - dropheir dropheir - droplets droplet - dropp dropp - dropper dropper - droppeth droppeth - dropping drop - droppings drop - drops drop - dropsied dropsi - dropsies dropsi - dropsy dropsi - dropt dropt - dross dross - drossy drossi - drought drought - drove drove - droven droven - drovier drovier - drown drown - drowned drown - drowning drown - drowns drown - drows drow - drowse drows - drowsily drowsili - drowsiness drowsi - drowsy drowsi - drudge drudg - drudgery drudgeri - drudges drudg - drug drug - drugg drugg - drugs drug - drum drum - drumble drumbl - drummer drummer - drumming drum - drums drum - drunk drunk - drunkard drunkard - drunkards drunkard - drunken drunken - drunkenly drunkenli - drunkenness drunken - dry dry - dryness dryness - dst dst - du du - dub dub - dubb dubb - ducat ducat - ducats ducat - ducdame ducdam - duchess duchess - duchies duchi - duchy duchi - duck duck - ducking duck - ducks duck - dudgeon dudgeon - due due - duellist duellist - duello duello - duer duer - dues due - duff duff - dug dug - dugs dug - duke duke - dukedom dukedom - dukedoms dukedom - dukes duke - dulcet dulcet - dulche dulch - dull dull - dullard dullard - duller duller - dullest dullest - dulling dull - dullness dull - dulls dull - dully dulli - dulness dul - duly duli - dumain dumain - dumb dumb - dumbe dumb - dumbly dumbl - dumbness dumb - dump dump - dumps dump - dun dun - duncan duncan - dung dung - dungeon dungeon - dungeons dungeon - dunghill dunghil - dunghills dunghil - dungy dungi - dunnest dunnest - dunsinane dunsinan - dunsmore dunsmor - dunstable dunstabl - dupp dupp - durance duranc - during dure - durst durst - dusky duski - dust dust - dusted dust - dusty dusti - dutch dutch - dutchman dutchman - duteous duteou - duties duti - dutiful duti - duty duti - dwarf dwarf - dwarfish dwarfish - dwell dwell - dwellers dweller - dwelling dwell - dwells dwell - dwelt dwelt - dwindle dwindl - dy dy - dye dye - dyed dy - dyer dyer - dying dy - e e - each each - eager eager - eagerly eagerli - eagerness eager - eagle eagl - eagles eagl - eaning ean - eanlings eanl - ear ear - earing ear - earl earl - earldom earldom - earlier earlier - earliest earliest - earliness earli - earls earl - early earli - earn earn - earned earn - earnest earnest - earnestly earnestli - earnestness earnest - earns earn - ears ear - earth earth - earthen earthen - earthlier earthlier - earthly earthli - earthquake earthquak - earthquakes earthquak - earthy earthi - eas ea - ease eas - eased eas - easeful eas - eases eas - easier easier - easiest easiest - easiliest easiliest - easily easili - easiness easi - easing eas - east east - eastcheap eastcheap - easter easter - eastern eastern - eastward eastward - easy easi - eat eat - eaten eaten - eater eater - eaters eater - eating eat - eats eat - eaux eaux - eaves eav - ebb ebb - ebbing eb - ebbs ebb - ebon ebon - ebony eboni - ebrew ebrew - ecce ecc - echapper echapp - echo echo - echoes echo - eclips eclip - eclipse eclips - eclipses eclips - ecolier ecoli - ecoutez ecoutez - ecstacy ecstaci - ecstasies ecstasi - ecstasy ecstasi - ecus ecu - eden eden - edg edg - edgar edgar - edge edg - edged edg - edgeless edgeless - edges edg - edict edict - edicts edict - edifice edific - edifices edific - edified edifi - edifies edifi - edition edit - edm edm - edmund edmund - edmunds edmund - edmundsbury edmundsburi - educate educ - educated educ - education educ - edward edward - eel eel - eels eel - effect effect - effected effect - effectless effectless - effects effect - effectual effectu - effectually effectu - effeminate effemin - effigies effigi - effus effu - effuse effus - effusion effus - eftest eftest - egal egal - egally egal - eget eget - egeus egeu - egg egg - eggs egg - eggshell eggshel - eglamour eglamour - eglantine eglantin - egma egma - ego ego - egregious egregi - egregiously egregi - egress egress - egypt egypt - egyptian egyptian - egyptians egyptian - eie eie - eight eight - eighteen eighteen - eighth eighth - eightpenny eightpenni - eighty eighti - eisel eisel - either either - eject eject - eke ek - el el - elbe elb - elbow elbow - elbows elbow - eld eld - elder elder - elders elder - eldest eldest - eleanor eleanor - elect elect - elected elect - election elect - elegancy eleg - elegies elegi - element element - elements element - elephant eleph - elephants eleph - elevated elev - eleven eleven - eleventh eleventh - elf elf - elflocks elflock - eliads eliad - elinor elinor - elizabeth elizabeth - ell ell - elle ell - ellen ellen - elm elm - eloquence eloqu - eloquent eloqu - else els - elsewhere elsewher - elsinore elsinor - eltham eltham - elves elv - elvish elvish - ely eli - elysium elysium - em em - emballing embal - embalm embalm - embalms embalm - embark embark - embarked embark - embarquements embarqu - embassade embassad - embassage embassag - embassies embassi - embassy embassi - embattailed embattail - embattl embattl - embattle embattl - embay embai - embellished embellish - embers ember - emblaze emblaz - emblem emblem - emblems emblem - embodied embodi - embold embold - emboldens embolden - emboss emboss - embossed emboss - embounded embound - embowel embowel - embowell embowel - embrac embrac - embrace embrac - embraced embrac - embracement embrac - embracements embrac - embraces embrac - embracing embrac - embrasures embrasur - embroider embroid - embroidery embroideri - emhracing emhrac - emilia emilia - eminence emin - eminent emin - eminently emin - emmanuel emmanuel - emnity emniti - empale empal - emperal emper - emperess emperess - emperial emperi - emperor emperor - empery emperi - emphasis emphasi - empire empir - empirics empir - empiricutic empiricut - empleached empleach - employ emploi - employed emploi - employer employ - employment employ - employments employ - empoison empoison - empress empress - emptied empti - emptier emptier - empties empti - emptiness empti - empty empti - emptying empti - emulate emul - emulation emul - emulations emul - emulator emul - emulous emul - en en - enact enact - enacted enact - enacts enact - enactures enactur - enamell enamel - enamelled enamel - enamour enamour - enamoured enamour - enanmour enanmour - encamp encamp - encamped encamp - encave encav - enceladus enceladu - enchaf enchaf - enchafed enchaf - enchant enchant - enchanted enchant - enchanting enchant - enchantingly enchantingli - enchantment enchant - enchantress enchantress - enchants enchant - enchas encha - encircle encircl - encircled encircl - enclos enclo - enclose enclos - enclosed enclos - encloses enclos - encloseth encloseth - enclosing enclos - enclouded encloud - encompass encompass - encompassed encompass - encompasseth encompasseth - encompassment encompass - encore encor - encorporal encorpor - encount encount - encounter encount - encountered encount - encounters encount - encourage encourag - encouraged encourag - encouragement encourag - encrimsoned encrimson - encroaching encroach - encumb encumb - end end - endamage endamag - endamagement endamag - endanger endang - endart endart - endear endear - endeared endear - endeavour endeavour - endeavours endeavour - ended end - ender ender - ending end - endings end - endite endit - endless endless - endow endow - endowed endow - endowments endow - endows endow - ends end - endu endu - endue endu - endur endur - endurance endur - endure endur - endured endur - endures endur - enduring endur - endymion endymion - eneas enea - enemies enemi - enemy enemi - enernies enerni - enew enew - enfeebled enfeebl - enfeebles enfeebl - enfeoff enfeoff - enfetter enfett - enfoldings enfold - enforc enforc - enforce enforc - enforced enforc - enforcedly enforcedli - enforcement enforc - enforces enforc - enforcest enforcest - enfranched enfranch - enfranchis enfranchi - enfranchise enfranchis - enfranchised enfranchis - enfranchisement enfranchis - enfreed enfre - enfreedoming enfreedom - engag engag - engage engag - engaged engag - engagements engag - engaging engag - engaol engaol - engend engend - engender engend - engenders engend - engilds engild - engine engin - engineer engin - enginer engin - engines engin - engirt engirt - england england - english english - englishman englishman - englishmen englishmen - engluts englut - englutted englut - engraffed engraf - engraft engraft - engrafted engraft - engrav engrav - engrave engrav - engross engross - engrossed engross - engrossest engrossest - engrossing engross - engrossments engross - enguard enguard - enigma enigma - enigmatical enigmat - enjoin enjoin - enjoined enjoin - enjoy enjoi - enjoyed enjoi - enjoyer enjoy - enjoying enjoi - enjoys enjoi - enkindle enkindl - enkindled enkindl - enlard enlard - enlarg enlarg - enlarge enlarg - enlarged enlarg - enlargement enlarg - enlargeth enlargeth - enlighten enlighten - enlink enlink - enmesh enmesh - enmities enmiti - enmity enmiti - ennoble ennobl - ennobled ennobl - enobarb enobarb - enobarbus enobarbu - enon enon - enormity enorm - enormous enorm - enough enough - enow enow - enpatron enpatron - enpierced enpierc - enquir enquir - enquire enquir - enquired enquir - enrag enrag - enrage enrag - enraged enrag - enrages enrag - enrank enrank - enrapt enrapt - enrich enrich - enriched enrich - enriches enrich - enridged enridg - enrings enr - enrob enrob - enrobe enrob - enroll enrol - enrolled enrol - enrooted enroot - enrounded enround - enschedul enschedul - ensconce ensconc - ensconcing ensconc - enseamed enseam - ensear ensear - enseigne enseign - enseignez enseignez - ensemble ensembl - enshelter enshelt - enshielded enshield - enshrines enshrin - ensign ensign - ensigns ensign - enskied enski - ensman ensman - ensnare ensnar - ensnared ensnar - ensnareth ensnareth - ensteep ensteep - ensu ensu - ensue ensu - ensued ensu - ensues ensu - ensuing ensu - enswathed enswath - ent ent - entail entail - entame entam - entangled entangl - entangles entangl - entendre entendr - enter enter - entered enter - entering enter - enterprise enterpris - enterprises enterpris - enters enter - entertain entertain - entertained entertain - entertainer entertain - entertaining entertain - entertainment entertain - entertainments entertain - enthrall enthral - enthralled enthral - enthron enthron - enthroned enthron - entice entic - enticements entic - enticing entic - entire entir - entirely entir - entitle entitl - entitled entitl - entitling entitl - entomb entomb - entombed entomb - entrails entrail - entrance entranc - entrances entranc - entrap entrap - entrapp entrapp - entre entr - entreat entreat - entreated entreat - entreaties entreati - entreating entreat - entreatments entreat - entreats entreat - entreaty entreati - entrench entrench - entry entri - entwist entwist - envelop envelop - envenom envenom - envenomed envenom - envenoms envenom - envied envi - envies envi - envious enviou - enviously envious - environ environ - environed environ - envoy envoi - envy envi - envying envi - enwheel enwheel - enwombed enwomb - enwraps enwrap - ephesian ephesian - ephesians ephesian - ephesus ephesu - epicure epicur - epicurean epicurean - epicures epicur - epicurism epicur - epicurus epicuru - epidamnum epidamnum - epidaurus epidauru - epigram epigram - epilepsy epilepsi - epileptic epilept - epilogue epilogu - epilogues epilogu - epistles epistl - epistrophus epistrophu - epitaph epitaph - epitaphs epitaph - epithet epithet - epitheton epitheton - epithets epithet - epitome epitom - equal equal - equalities equal - equality equal - equall equal - equally equal - equalness equal - equals equal - equinoctial equinocti - equinox equinox - equipage equipag - equity equiti - equivocal equivoc - equivocate equivoc - equivocates equivoc - equivocation equivoc - equivocator equivoc - er er - erbear erbear - erbearing erbear - erbears erbear - erbeat erbeat - erblows erblow - erboard erboard - erborne erborn - ercame ercam - ercast ercast - ercharg ercharg - ercharged ercharg - ercharging ercharg - ercles ercl - ercome ercom - ercover ercov - ercrows ercrow - erdoing erdo - ere er - erebus erebu - erect erect - erected erect - erecting erect - erection erect - erects erect - erewhile erewhil - erflourish erflourish - erflow erflow - erflowing erflow - erflows erflow - erfraught erfraught - erga erga - ergalled ergal - erglanced erglanc - ergo ergo - ergone ergon - ergrow ergrow - ergrown ergrown - ergrowth ergrowth - erhang erhang - erhanging erhang - erhasty erhasti - erhear erhear - erheard erheard - eringoes eringo - erjoy erjoi - erleap erleap - erleaps erleap - erleavens erleaven - erlook erlook - erlooking erlook - ermaster ermast - ermengare ermengar - ermount ermount - ern ern - ernight ernight - eros ero - erpaid erpaid - erparted erpart - erpast erpast - erpays erpai - erpeer erpeer - erperch erperch - erpicturing erpictur - erpingham erpingham - erposting erpost - erpow erpow - erpress erpress - erpressed erpress - err err - errand errand - errands errand - errant errant - errate errat - erraught erraught - erreaches erreach - erred er - errest errest - erring er - erroneous erron - error error - errors error - errs err - errule errul - errun errun - erset erset - ershade ershad - ershades ershad - ershine ershin - ershot ershot - ersized ersiz - erskip erskip - erslips erslip - erspreads erspread - erst erst - erstare erstar - erstep erstep - erstunk erstunk - ersway erswai - ersways erswai - erswell erswel - erta erta - ertake ertak - erteemed erteem - erthrow erthrow - erthrown erthrown - erthrows erthrow - ertook ertook - ertop ertop - ertopping ertop - ertrip ertrip - erturn erturn - erudition erudit - eruption erupt - eruptions erupt - ervalues ervalu - erwalk erwalk - erwatch erwatch - erween erween - erweens erween - erweigh erweigh - erweighs erweigh - erwhelm erwhelm - erwhelmed erwhelm - erworn erworn - es es - escalus escalu - escap escap - escape escap - escaped escap - escapes escap - eschew eschew - escoted escot - esill esil - especial especi - especially especi - esperance esper - espials espial - espied espi - espies espi - espous espou - espouse espous - espy espi - esquire esquir - esquires esquir - essay essai - essays essai - essence essenc - essential essenti - essentially essenti - esses ess - essex essex - est est - establish establish - established establish - estate estat - estates estat - esteem esteem - esteemed esteem - esteemeth esteemeth - esteeming esteem - esteems esteem - estimable estim - estimate estim - estimation estim - estimations estim - estime estim - estranged estrang - estridge estridg - estridges estridg - et et - etc etc - etceteras etcetera - ete et - eternal etern - eternally etern - eterne etern - eternity etern - eterniz eterniz - etes et - ethiop ethiop - ethiope ethiop - ethiopes ethiop - ethiopian ethiopian - etna etna - eton eton - etre etr - eunuch eunuch - eunuchs eunuch - euphrates euphrat - euphronius euphroniu - euriphile euriphil - europa europa - europe europ - ev ev - evade evad - evades evad - evans evan - evasion evas - evasions evas - eve ev - even even - evening even - evenly evenli - event event - eventful event - events event - ever ever - everlasting everlast - everlastingly everlastingli - evermore evermor - every everi - everyone everyon - everything everyth - everywhere everywher - evidence evid - evidences evid - evident evid - evil evil - evilly evilli - evils evil - evitate evit - ewe ew - ewer ewer - ewers ewer - ewes ew - exact exact - exacted exact - exactest exactest - exacting exact - exaction exact - exactions exact - exactly exactli - exacts exact - exalt exalt - exalted exalt - examin examin - examination examin - examinations examin - examine examin - examined examin - examines examin - exampl exampl - example exampl - exampled exampl - examples exampl - exasperate exasper - exasperates exasper - exceed exce - exceeded exceed - exceedeth exceedeth - exceeding exceed - exceedingly exceedingli - exceeds exce - excel excel - excelled excel - excellence excel - excellencies excel - excellency excel - excellent excel - excellently excel - excelling excel - excels excel - except except - excepted except - excepting except - exception except - exceptions except - exceptless exceptless - excess excess - excessive excess - exchang exchang - exchange exchang - exchanged exchang - exchequer exchequ - exchequers exchequ - excite excit - excited excit - excitements excit - excites excit - exclaim exclaim - exclaims exclaim - exclamation exclam - exclamations exclam - excludes exclud - excommunicate excommun - excommunication excommun - excrement excrement - excrements excrement - excursion excurs - excursions excurs - excus excu - excusable excus - excuse excus - excused excus - excuses excus - excusez excusez - excusing excus - execrable execr - execrations execr - execute execut - executed execut - executing execut - execution execut - executioner execution - executioners execution - executor executor - executors executor - exempt exempt - exempted exempt - exequies exequi - exercise exercis - exercises exercis - exeter exet - exeunt exeunt - exhal exhal - exhalation exhal - exhalations exhal - exhale exhal - exhales exhal - exhaust exhaust - exhibit exhibit - exhibiters exhibit - exhibition exhibit - exhort exhort - exhortation exhort - exigent exig - exil exil - exile exil - exiled exil - exion exion - exist exist - exists exist - exit exit - exits exit - exorciser exorcis - exorcisms exorc - exorcist exorcist - expect expect - expectance expect - expectancy expect - expectation expect - expectations expect - expected expect - expecters expect - expecting expect - expects expect - expedience expedi - expedient expedi - expediently expedi - expedition expedit - expeditious expediti - expel expel - expell expel - expelling expel - expels expel - expend expend - expense expens - expenses expens - experienc experienc - experience experi - experiences experi - experiment experi - experimental experiment - experiments experi - expert expert - expertness expert - expiate expiat - expiation expiat - expir expir - expiration expir - expire expir - expired expir - expires expir - expiring expir - explication explic - exploit exploit - exploits exploit - expos expo - expose expos - exposing expos - exposition exposit - expositor expositor - expostulate expostul - expostulation expostul - exposture expostur - exposure exposur - expound expound - expounded expound - express express - expressed express - expresseth expresseth - expressing express - expressive express - expressly expressli - expressure expressur - expuls expul - expulsion expuls - exquisite exquisit - exsufflicate exsuffl - extant extant - extemporal extempor - extemporally extempor - extempore extempor - extend extend - extended extend - extends extend - extent extent - extenuate extenu - extenuated extenu - extenuates extenu - extenuation extenu - exterior exterior - exteriorly exteriorli - exteriors exterior - extermin extermin - extern extern - external extern - extinct extinct - extincted extinct - extincture extinctur - extinguish extinguish - extirp extirp - extirpate extirp - extirped extirp - extol extol - extoll extol - extolment extol - exton exton - extort extort - extorted extort - extortion extort - extortions extort - extra extra - extract extract - extracted extract - extracting extract - extraordinarily extraordinarili - extraordinary extraordinari - extraught extraught - extravagancy extravag - extravagant extravag - extreme extrem - extremely extrem - extremes extrem - extremest extremest - extremities extrem - extremity extrem - exuent exuent - exult exult - exultation exult - ey ey - eyas eya - eyases eyas - eye ey - eyeball eyebal - eyeballs eyebal - eyebrow eyebrow - eyebrows eyebrow - eyed ei - eyeless eyeless - eyelid eyelid - eyelids eyelid - eyes ey - eyesight eyesight - eyestrings eyestr - eying ei - eyne eyn - eyrie eyri - fa fa - fabian fabian - fable fabl - fables fabl - fabric fabric - fabulous fabul - fac fac - face face - faced face - facere facer - faces face - faciant faciant - facile facil - facility facil - facinerious facineri - facing face - facit facit - fact fact - faction faction - factionary factionari - factions faction - factious factiou - factor factor - factors factor - faculties faculti - faculty faculti - fade fade - faded fade - fadeth fadeth - fadge fadg - fading fade - fadings fade - fadom fadom - fadoms fadom - fagot fagot - fagots fagot - fail fail - failing fail - fails fail - fain fain - faint faint - fainted faint - fainter fainter - fainting faint - faintly faintli - faintness faint - faints faint - fair fair - fairer fairer - fairest fairest - fairies fairi - fairing fair - fairings fair - fairly fairli - fairness fair - fairs fair - fairwell fairwel - fairy fairi - fais fai - fait fait - faites fait - faith faith - faithful faith - faithfull faithful - faithfully faithfulli - faithless faithless - faiths faith - faitors faitor - fal fal - falchion falchion - falcon falcon - falconbridge falconbridg - falconer falcon - falconers falcon - fall fall - fallacy fallaci - fallen fallen - falleth falleth - falliable falliabl - fallible fallibl - falling fall - fallow fallow - fallows fallow - falls fall - fally falli - falorous falor - false fals - falsehood falsehood - falsely fals - falseness fals - falser falser - falsify falsifi - falsing fals - falstaff falstaff - falstaffs falstaff - falter falter - fam fam - fame fame - famed fame - familiar familiar - familiarity familiar - familiarly familiarli - familiars familiar - family famili - famine famin - famish famish - famished famish - famous famou - famoused famous - famously famous - fan fan - fanatical fanat - fancies fanci - fancy fanci - fane fane - fanes fane - fang fang - fangled fangl - fangless fangless - fangs fang - fann fann - fanning fan - fans fan - fantasied fantasi - fantasies fantasi - fantastic fantast - fantastical fantast - fantastically fantast - fantasticoes fantastico - fantasy fantasi - fap fap - far far - farborough farborough - farced farc - fardel fardel - fardels fardel - fare fare - fares fare - farewell farewel - farewells farewel - fariner farin - faring fare - farm farm - farmer farmer - farmhouse farmhous - farms farm - farre farr - farrow farrow - farther farther - farthest farthest - farthing farth - farthingale farthingal - farthingales farthingal - farthings farth - fartuous fartuou - fas fa - fashion fashion - fashionable fashion - fashioning fashion - fashions fashion - fast fast - fasted fast - fasten fasten - fastened fasten - faster faster - fastest fastest - fasting fast - fastly fastli - fastolfe fastolf - fasts fast - fat fat - fatal fatal - fatally fatal - fate fate - fated fate - fates fate - father father - fathered father - fatherless fatherless - fatherly fatherli - fathers father - fathom fathom - fathomless fathomless - fathoms fathom - fatigate fatig - fatness fat - fats fat - fatted fat - fatter fatter - fattest fattest - fatting fat - fatuus fatuu - fauconbridge fauconbridg - faulconbridge faulconbridg - fault fault - faultiness faulti - faultless faultless - faults fault - faulty faulti - fausse fauss - fauste faust - faustuses faustus - faut faut - favor favor - favorable favor - favorably favor - favors favor - favour favour - favourable favour - favoured favour - favouredly favouredli - favourer favour - favourers favour - favouring favour - favourite favourit - favourites favourit - favours favour - favout favout - fawn fawn - fawneth fawneth - fawning fawn - fawns fawn - fay fai - fe fe - fealty fealti - fear fear - feared fear - fearest fearest - fearful fear - fearfull fearful - fearfully fearfulli - fearfulness fear - fearing fear - fearless fearless - fears fear - feast feast - feasted feast - feasting feast - feasts feast - feat feat - feated feat - feater feater - feather feather - feathered feather - feathers feather - featly featli - feats feat - featur featur - feature featur - featured featur - featureless featureless - features featur - february februari - fecks feck - fed fed - fedary fedari - federary federari - fee fee - feeble feebl - feebled feebl - feebleness feebl - feebling feebl - feebly feebli - feed feed - feeder feeder - feeders feeder - feedeth feedeth - feeding feed - feeds feed - feel feel - feeler feeler - feeling feel - feelingly feelingli - feels feel - fees fee - feet feet - fehemently fehement - feign feign - feigned feign - feigning feign - feil feil - feith feith - felicitate felicit - felicity felic - fell fell - fellest fellest - fellies felli - fellow fellow - fellowly fellowli - fellows fellow - fellowship fellowship - fellowships fellowship - fells fell - felon felon - felonious feloni - felony feloni - felt felt - female femal - females femal - feminine feminin - fen fen - fenc fenc - fence fenc - fencer fencer - fencing fenc - fends fend - fennel fennel - fenny fenni - fens fen - fenton fenton - fer fer - ferdinand ferdinand - fere fere - fernseed fernse - ferrara ferrara - ferrers ferrer - ferret ferret - ferry ferri - ferryman ferryman - fertile fertil - fertility fertil - fervency fervenc - fervour fervour - fery feri - fest fest - feste fest - fester fester - festinate festin - festinately festin - festival festiv - festivals festiv - fet fet - fetch fetch - fetches fetch - fetching fetch - fetlock fetlock - fetlocks fetlock - fett fett - fetter fetter - fettering fetter - fetters fetter - fettle fettl - feu feu - feud feud - fever fever - feverous fever - fevers fever - few few - fewer fewer - fewest fewest - fewness few - fickle fickl - fickleness fickl - fico fico - fiction fiction - fiddle fiddl - fiddler fiddler - fiddlestick fiddlestick - fidele fidel - fidelicet fidelicet - fidelity fidel - fidius fidiu - fie fie - field field - fielded field - fields field - fiend fiend - fiends fiend - fierce fierc - fiercely fierc - fierceness fierc - fiery fieri - fife fife - fifes fife - fifteen fifteen - fifteens fifteen - fifteenth fifteenth - fifth fifth - fifty fifti - fiftyfold fiftyfold - fig fig - fight fight - fighter fighter - fightest fightest - fighteth fighteth - fighting fight - fights fight - figo figo - figs fig - figur figur - figure figur - figured figur - figures figur - figuring figur - fike fike - fil fil - filberts filbert - filch filch - filches filch - filching filch - file file - filed file - files file - filial filial - filius filiu - fill fill - filled fill - fillet fillet - filling fill - fillip fillip - fills fill - filly filli - film film - fils fil - filth filth - filths filth - filthy filthi - fin fin - finally final - finch finch - find find - finder finder - findeth findeth - finding find - findings find - finds find - fine fine - fineless fineless - finely fine - finem finem - fineness fine - finer finer - fines fine - finest finest - fing fing - finger finger - fingering finger - fingers finger - fingre fingr - fingres fingr - finical finic - finish finish - finished finish - finisher finish - finless finless - finn finn - fins fin - finsbury finsburi - fir fir - firago firago - fire fire - firebrand firebrand - firebrands firebrand - fired fire - fires fire - firework firework - fireworks firework - firing fire - firk firk - firm firm - firmament firmament - firmly firmli - firmness firm - first first - firstlings firstl - fish fish - fisher fisher - fishermen fishermen - fishers fisher - fishes fish - fishified fishifi - fishmonger fishmong - fishpond fishpond - fisnomy fisnomi - fist fist - fisting fist - fists fist - fistula fistula - fit fit - fitchew fitchew - fitful fit - fitly fitli - fitment fitment - fitness fit - fits fit - fitted fit - fitter fitter - fittest fittest - fitteth fitteth - fitting fit - fitzwater fitzwat - five five - fivepence fivep - fives five - fix fix - fixed fix - fixes fix - fixeth fixeth - fixing fix - fixture fixtur - fl fl - flag flag - flagging flag - flagon flagon - flagons flagon - flags flag - flail flail - flakes flake - flaky flaki - flam flam - flame flame - flamen flamen - flamens flamen - flames flame - flaming flame - flaminius flaminiu - flanders flander - flannel flannel - flap flap - flaring flare - flash flash - flashes flash - flashing flash - flask flask - flat flat - flatly flatli - flatness flat - flats flat - flatt flatt - flatter flatter - flattered flatter - flatterer flatter - flatterers flatter - flatterest flatterest - flatteries flatteri - flattering flatter - flatters flatter - flattery flatteri - flaunts flaunt - flavio flavio - flavius flaviu - flaw flaw - flaws flaw - flax flax - flaxen flaxen - flay flai - flaying flai - flea flea - fleance fleanc - fleas flea - flecked fleck - fled fled - fledge fledg - flee flee - fleec fleec - fleece fleec - fleeces fleec - fleer fleer - fleering fleer - fleers fleer - fleet fleet - fleeter fleeter - fleeting fleet - fleming fleme - flemish flemish - flesh flesh - fleshes flesh - fleshly fleshli - fleshment fleshment - fleshmonger fleshmong - flew flew - flexible flexibl - flexure flexur - flibbertigibbet flibbertigibbet - flickering flicker - flidge flidg - fliers flier - flies fli - flieth flieth - flight flight - flights flight - flighty flighti - flinch flinch - fling fling - flint flint - flints flint - flinty flinti - flirt flirt - float float - floated float - floating float - flock flock - flocks flock - flood flood - floodgates floodgat - floods flood - floor floor - flora flora - florence florenc - florentine florentin - florentines florentin - florentius florentiu - florizel florizel - flote flote - floulish floulish - flour flour - flourish flourish - flourishes flourish - flourisheth flourisheth - flourishing flourish - flout flout - flouted flout - flouting flout - flouts flout - flow flow - flowed flow - flower flower - flowerets floweret - flowers flower - flowing flow - flown flown - flows flow - fluellen fluellen - fluent fluent - flung flung - flush flush - flushing flush - fluster fluster - flute flute - flutes flute - flutter flutter - flux flux - fluxive fluxiv - fly fly - flying fly - fo fo - foal foal - foals foal - foam foam - foamed foam - foaming foam - foams foam - foamy foami - fob fob - focative foc - fodder fodder - foe foe - foeman foeman - foemen foemen - foes foe - fog fog - foggy foggi - fogs fog - foh foh - foi foi - foil foil - foiled foil - foils foil - foin foin - foining foin - foins foin - fois foi - foison foison - foisons foison - foist foist - foix foix - fold fold - folded fold - folds fold - folio folio - folk folk - folks folk - follies folli - follow follow - followed follow - follower follow - followers follow - followest followest - following follow - follows follow - folly folli - fond fond - fonder fonder - fondly fondli - fondness fond - font font - fontibell fontibel - food food - fool fool - fooleries fooleri - foolery fooleri - foolhardy foolhardi - fooling fool - foolish foolish - foolishly foolishli - foolishness foolish - fools fool - foot foot - football footbal - footboy footboi - footboys footboi - footed foot - footfall footfal - footing foot - footman footman - footmen footmen - footpath footpath - footsteps footstep - footstool footstool - fopp fopp - fopped fop - foppery fopperi - foppish foppish - fops fop - for for - forage forag - foragers forag - forbade forbad - forbear forbear - forbearance forbear - forbears forbear - forbid forbid - forbidden forbidden - forbiddenly forbiddenli - forbids forbid - forbod forbod - forborne forborn - forc forc - force forc - forced forc - forceful forc - forceless forceless - forces forc - forcible forcibl - forcibly forcibl - forcing forc - ford ford - fordid fordid - fordo fordo - fordoes fordo - fordone fordon - fore fore - forecast forecast - forefather forefath - forefathers forefath - forefinger forefing - forego forego - foregone foregon - forehand forehand - forehead forehead - foreheads forehead - forehorse forehors - foreign foreign - foreigner foreign - foreigners foreign - foreknowing foreknow - foreknowledge foreknowledg - foremost foremost - forenamed forenam - forenoon forenoon - forerun forerun - forerunner forerunn - forerunning forerun - foreruns forerun - foresaid foresaid - foresaw foresaw - foresay foresai - foresee forese - foreseeing forese - foresees forese - foreshow foreshow - foreskirt foreskirt - forespent foresp - forest forest - forestall forestal - forestalled forestal - forester forest - foresters forest - forests forest - foretell foretel - foretelling foretel - foretells foretel - forethink forethink - forethought forethought - foretold foretold - forever forev - foreward foreward - forewarn forewarn - forewarned forewarn - forewarning forewarn - forfeit forfeit - forfeited forfeit - forfeiters forfeit - forfeiting forfeit - forfeits forfeit - forfeiture forfeitur - forfeitures forfeitur - forfend forfend - forfended forfend - forg forg - forgave forgav - forge forg - forged forg - forgeries forgeri - forgery forgeri - forges forg - forget forget - forgetful forget - forgetfulness forget - forgetive forget - forgets forget - forgetting forget - forgive forgiv - forgiven forgiven - forgiveness forgiv - forgo forgo - forgoing forgo - forgone forgon - forgot forgot - forgotten forgotten - fork fork - forked fork - forks fork - forlorn forlorn - form form - formal formal - formally formal - formed form - former former - formerly formerli - formless formless - forms form - fornication fornic - fornications fornic - fornicatress fornicatress - forres forr - forrest forrest - forsake forsak - forsaken forsaken - forsaketh forsaketh - forslow forslow - forsook forsook - forsooth forsooth - forspent forspent - forspoke forspok - forswear forswear - forswearing forswear - forswore forswor - forsworn forsworn - fort fort - forted fort - forth forth - forthcoming forthcom - forthlight forthlight - forthright forthright - forthwith forthwith - fortification fortif - fortifications fortif - fortified fortifi - fortifies fortifi - fortify fortifi - fortinbras fortinbra - fortitude fortitud - fortnight fortnight - fortress fortress - fortresses fortress - forts fort - fortun fortun - fortuna fortuna - fortunate fortun - fortunately fortun - fortune fortun - fortuned fortun - fortunes fortun - fortward fortward - forty forti - forum forum - forward forward - forwarding forward - forwardness forward - forwards forward - forwearied forweari - fosset fosset - fost fost - foster foster - fostered foster - fought fought - foughten foughten - foul foul - fouler fouler - foulest foulest - foully foulli - foulness foul - found found - foundation foundat - foundations foundat - founded found - founder founder - fount fount - fountain fountain - fountains fountain - founts fount - four four - fourscore fourscor - fourteen fourteen - fourth fourth - foutra foutra - fowl fowl - fowler fowler - fowling fowl - fowls fowl - fox fox - foxes fox - foxship foxship - fracted fract - fraction fraction - fractions fraction - fragile fragil - fragment fragment - fragments fragment - fragrant fragrant - frail frail - frailer frailer - frailties frailti - frailty frailti - fram fram - frame frame - framed frame - frames frame - frampold frampold - fran fran - francais francai - france franc - frances franc - franchise franchis - franchised franchis - franchisement franchis - franchises franchis - franciae francia - francis franci - francisca francisca - franciscan franciscan - francisco francisco - frank frank - franker franker - frankfort frankfort - franklin franklin - franklins franklin - frankly frankli - frankness frank - frantic frantic - franticly franticli - frateretto frateretto - fratrum fratrum - fraud fraud - fraudful fraud - fraught fraught - fraughtage fraughtag - fraughting fraught - fray frai - frays frai - freckl freckl - freckled freckl - freckles freckl - frederick frederick - free free - freed freed - freedom freedom - freedoms freedom - freehearted freeheart - freelier freelier - freely freeli - freeman freeman - freemen freemen - freeness freeness - freer freer - frees free - freestone freeston - freetown freetown - freeze freez - freezes freez - freezing freez - freezings freez - french french - frenchman frenchman - frenchmen frenchmen - frenchwoman frenchwoman - frenzy frenzi - frequent frequent - frequents frequent - fresh fresh - fresher fresher - freshes fresh - freshest freshest - freshly freshli - freshness fresh - fret fret - fretful fret - frets fret - fretted fret - fretten fretten - fretting fret - friar friar - friars friar - friday fridai - fridays fridai - friend friend - friended friend - friending friend - friendless friendless - friendliness friendli - friendly friendli - friends friend - friendship friendship - friendships friendship - frieze friez - fright fright - frighted fright - frightened frighten - frightful fright - frighting fright - frights fright - fringe fring - fringed fring - frippery fripperi - frisk frisk - fritters fritter - frivolous frivol - fro fro - frock frock - frog frog - frogmore frogmor - froissart froissart - frolic frolic - from from - front front - fronted front - frontier frontier - frontiers frontier - fronting front - frontlet frontlet - fronts front - frost frost - frosts frost - frosty frosti - froth froth - froward froward - frown frown - frowning frown - frowningly frowningli - frowns frown - froze froze - frozen frozen - fructify fructifi - frugal frugal - fruit fruit - fruiterer fruiter - fruitful fruit - fruitfully fruitfulli - fruitfulness fruit - fruition fruition - fruitless fruitless - fruits fruit - frush frush - frustrate frustrat - frutify frutifi - fry fry - fubb fubb - fuel fuel - fugitive fugit - fulfil fulfil - fulfill fulfil - fulfilling fulfil - fulfils fulfil - full full - fullam fullam - fuller fuller - fullers fuller - fullest fullest - fullness full - fully fulli - fulness ful - fulsome fulsom - fulvia fulvia - fum fum - fumble fumbl - fumbles fumbl - fumblest fumblest - fumbling fumbl - fume fume - fumes fume - fuming fume - fumiter fumit - fumitory fumitori - fun fun - function function - functions function - fundamental fundament - funeral funer - funerals funer - fur fur - furbish furbish - furies furi - furious furiou - furlongs furlong - furnace furnac - furnaces furnac - furnish furnish - furnished furnish - furnishings furnish - furniture furnitur - furnival furniv - furor furor - furr furr - furrow furrow - furrowed furrow - furrows furrow - furth furth - further further - furtherance further - furtherer further - furthermore furthermor - furthest furthest - fury furi - furze furz - furzes furz - fust fust - fustian fustian - fustilarian fustilarian - fusty fusti - fut fut - future futur - futurity futur - g g - gabble gabbl - gaberdine gaberdin - gabriel gabriel - gad gad - gadding gad - gads gad - gadshill gadshil - gag gag - gage gage - gaged gage - gagg gagg - gaging gage - gagne gagn - gain gain - gained gain - gainer gainer - gaingiving gaingiv - gains gain - gainsaid gainsaid - gainsay gainsai - gainsaying gainsai - gainsays gainsai - gainst gainst - gait gait - gaited gait - galathe galath - gale gale - galen galen - gales gale - gall gall - gallant gallant - gallantly gallantli - gallantry gallantri - gallants gallant - galled gall - gallery galleri - galley gallei - galleys gallei - gallia gallia - gallian gallian - galliard galliard - galliasses galliass - gallimaufry gallimaufri - galling gall - gallons gallon - gallop gallop - galloping gallop - gallops gallop - gallow gallow - galloway gallowai - gallowglasses gallowglass - gallows gallow - gallowses gallows - galls gall - gallus gallu - gam gam - gambol gambol - gambold gambold - gambols gambol - gamboys gamboi - game game - gamers gamer - games game - gamesome gamesom - gamester gamest - gaming game - gammon gammon - gamut gamut - gan gan - gangren gangren - ganymede ganymed - gaol gaol - gaoler gaoler - gaolers gaoler - gaols gaol - gap gap - gape gape - gapes gape - gaping gape - gar gar - garb garb - garbage garbag - garboils garboil - garcon garcon - gard gard - garde gard - garden garden - gardener garden - gardeners garden - gardens garden - gardez gardez - gardiner gardin - gardon gardon - gargantua gargantua - gargrave gargrav - garish garish - garland garland - garlands garland - garlic garlic - garment garment - garments garment - garmet garmet - garner garner - garners garner - garnish garnish - garnished garnish - garret garret - garrison garrison - garrisons garrison - gart gart - garter garter - garterd garterd - gartering garter - garters garter - gascony gasconi - gash gash - gashes gash - gaskins gaskin - gasp gasp - gasping gasp - gasted gast - gastness gast - gat gat - gate gate - gated gate - gates gate - gath gath - gather gather - gathered gather - gathering gather - gathers gather - gatories gatori - gatory gatori - gaud gaud - gaudeo gaudeo - gaudy gaudi - gauge gaug - gaul gaul - gaultree gaultre - gaunt gaunt - gauntlet gauntlet - gauntlets gauntlet - gav gav - gave gave - gavest gavest - gawded gawd - gawds gawd - gawsey gawsei - gay gai - gayness gay - gaz gaz - gaze gaze - gazed gaze - gazer gazer - gazers gazer - gazes gaze - gazeth gazeth - gazing gaze - gear gear - geck geck - geese gees - geffrey geffrei - geld geld - gelded geld - gelding geld - gelida gelida - gelidus gelidu - gelt gelt - gem gem - geminy gemini - gems gem - gen gen - gender gender - genders gender - general gener - generally gener - generals gener - generation gener - generations gener - generative gener - generosity generos - generous gener - genitive genit - genitivo genitivo - genius geniu - gennets gennet - genoa genoa - genoux genoux - gens gen - gent gent - gentilhomme gentilhomm - gentility gentil - gentle gentl - gentlefolks gentlefolk - gentleman gentleman - gentlemanlike gentlemanlik - gentlemen gentlemen - gentleness gentl - gentler gentler - gentles gentl - gentlest gentlest - gentlewoman gentlewoman - gentlewomen gentlewomen - gently gentli - gentry gentri - george georg - gerard gerard - germaines germain - germains germain - german german - germane german - germans german - germany germani - gertrude gertrud - gest gest - gests gest - gesture gestur - gestures gestur - get get - getrude getrud - gets get - getter getter - getting get - ghastly ghastli - ghost ghost - ghosted ghost - ghostly ghostli - ghosts ghost - gi gi - giant giant - giantess giantess - giantlike giantlik - giants giant - gib gib - gibber gibber - gibbet gibbet - gibbets gibbet - gibe gibe - giber giber - gibes gibe - gibing gibe - gibingly gibingli - giddily giddili - giddiness giddi - giddy giddi - gift gift - gifts gift - gig gig - giglets giglet - giglot giglot - gilbert gilbert - gild gild - gilded gild - gilding gild - gilliams gilliam - gillian gillian - gills gill - gillyvors gillyvor - gilt gilt - gimmal gimmal - gimmers gimmer - gin gin - ging ging - ginger ginger - gingerbread gingerbread - gingerly gingerli - ginn ginn - gins gin - gioucestershire gioucestershir - gipes gipe - gipsies gipsi - gipsy gipsi - gird gird - girded gird - girdle girdl - girdled girdl - girdles girdl - girdling girdl - girl girl - girls girl - girt girt - girth girth - gis gi - giv giv - give give - given given - giver giver - givers giver - gives give - givest givest - giveth giveth - giving give - givings give - glad glad - gladded glad - gladding glad - gladly gladli - gladness glad - glamis glami - glanc glanc - glance glanc - glanced glanc - glances glanc - glancing glanc - glanders glander - glansdale glansdal - glare glare - glares glare - glass glass - glasses glass - glassy glassi - glaz glaz - glazed glaze - gleams gleam - glean glean - gleaned glean - gleaning glean - gleeful gleeful - gleek gleek - gleeking gleek - gleeks gleek - glend glend - glendower glendow - glib glib - glide glide - glided glide - glides glide - glideth glideth - gliding glide - glimmer glimmer - glimmering glimmer - glimmers glimmer - glimpse glimps - glimpses glimps - glist glist - glistening glisten - glister glister - glistering glister - glisters glister - glitt glitt - glittering glitter - globe globe - globes globe - glooming gloom - gloomy gloomi - glories glori - glorified glorifi - glorify glorifi - glorious gloriou - gloriously glorious - glory glori - glose glose - gloss gloss - glosses gloss - glou glou - glouceste gloucest - gloucester gloucest - gloucestershire gloucestershir - glove glove - glover glover - gloves glove - glow glow - glowed glow - glowing glow - glowworm glowworm - gloz gloz - gloze gloze - glozes gloze - glu glu - glue glue - glued glu - glues glue - glut glut - glutt glutt - glutted glut - glutton glutton - gluttoning glutton - gluttony gluttoni - gnarled gnarl - gnarling gnarl - gnat gnat - gnats gnat - gnaw gnaw - gnawing gnaw - gnawn gnawn - gnaws gnaw - go go - goad goad - goaded goad - goads goad - goal goal - goat goat - goatish goatish - goats goat - gobbets gobbet - gobbo gobbo - goblet goblet - goblets goblet - goblin goblin - goblins goblin - god god - godded god - godden godden - goddess goddess - goddesses goddess - goddild goddild - godfather godfath - godfathers godfath - godhead godhead - godlike godlik - godliness godli - godly godli - godmother godmoth - gods god - godson godson - goer goer - goers goer - goes goe - goest goest - goeth goeth - goffe goff - gogs gog - going go - gold gold - golden golden - goldenly goldenli - goldsmith goldsmith - goldsmiths goldsmith - golgotha golgotha - goliases golias - goliath goliath - gon gon - gondola gondola - gondolier gondoli - gone gone - goneril goneril - gong gong - gonzago gonzago - gonzalo gonzalo - good good - goodfellow goodfellow - goodlier goodlier - goodliest goodliest - goodly goodli - goodman goodman - goodness good - goodnight goodnight - goodrig goodrig - goods good - goodwife goodwif - goodwill goodwil - goodwin goodwin - goodwins goodwin - goodyear goodyear - goodyears goodyear - goose goos - gooseberry gooseberri - goosequills goosequil - goot goot - gor gor - gorbellied gorbelli - gorboduc gorboduc - gordian gordian - gore gore - gored gore - gorg gorg - gorge gorg - gorgeous gorgeou - gorget gorget - gorging gorg - gorgon gorgon - gormandize gormand - gormandizing gormand - gory gori - gosling gosl - gospel gospel - gospels gospel - goss goss - gossamer gossam - gossip gossip - gossiping gossip - gossiplike gossiplik - gossips gossip - got got - goth goth - goths goth - gotten gotten - gourd gourd - gout gout - gouts gout - gouty gouti - govern govern - governance govern - governed govern - governess gover - government govern - governor governor - governors governor - governs govern - gower gower - gown gown - gowns gown - grac grac - grace grace - graced grace - graceful grace - gracefully gracefulli - graceless graceless - graces grace - gracing grace - gracious graciou - graciously gracious - gradation gradat - graff graff - graffing graf - graft graft - grafted graft - grafters grafter - grain grain - grained grain - grains grain - gramercies gramerci - gramercy gramerci - grammar grammar - grand grand - grandam grandam - grandame grandam - grandchild grandchild - grande grand - grandeur grandeur - grandfather grandfath - grandjurors grandjuror - grandmother grandmoth - grandpre grandpr - grandsir grandsir - grandsire grandsir - grandsires grandsir - grange grang - grant grant - granted grant - granting grant - grants grant - grape grape - grapes grape - grapple grappl - grapples grappl - grappling grappl - grasp grasp - grasped grasp - grasps grasp - grass grass - grasshoppers grasshopp - grassy grassi - grate grate - grated grate - grateful grate - grates grate - gratiano gratiano - gratify gratifi - gratii gratii - gratillity gratil - grating grate - gratis grati - gratitude gratitud - gratulate gratul - grav grav - grave grave - gravediggers gravedigg - gravel gravel - graveless graveless - gravell gravel - gravely grave - graven graven - graveness grave - graver graver - graves grave - gravest gravest - gravestone graveston - gravities graviti - gravity graviti - gravy gravi - gray grai - graymalkin graymalkin - graz graz - graze graze - grazed graze - grazing graze - grease greas - greases greas - greasily greasili - greasy greasi - great great - greater greater - greatest greatest - greatly greatli - greatness great - grecian grecian - grecians grecian - gree gree - greece greec - greed greed - greedily greedili - greediness greedi - greedy greedi - greeing gree - greek greek - greekish greekish - greeks greek - green green - greener greener - greenly greenli - greens green - greensleeves greensleev - greenwich greenwich - greenwood greenwood - greet greet - greeted greet - greeting greet - greetings greet - greets greet - greg greg - gregory gregori - gremio gremio - grew grew - grey grei - greybeard greybeard - greybeards greybeard - greyhound greyhound - greyhounds greyhound - grief grief - griefs grief - griev griev - grievance grievanc - grievances grievanc - grieve griev - grieved griev - grieves griev - grievest grievest - grieving griev - grievingly grievingli - grievous grievou - grievously grievous - griffin griffin - griffith griffith - grim grim - grime grime - grimly grimli - grin grin - grind grind - grinding grind - grindstone grindston - grinning grin - grip grip - gripe gripe - gripes gripe - griping gripe - grise grise - grisly grisli - grissel grissel - grize grize - grizzle grizzl - grizzled grizzl - groan groan - groaning groan - groans groan - groat groat - groats groat - groin groin - groom groom - grooms groom - grop grop - groping grope - gros gro - gross gross - grosser grosser - grossly grossli - grossness gross - ground ground - grounded ground - groundlings groundl - grounds ground - grove grove - grovel grovel - grovelling grovel - groves grove - grow grow - groweth groweth - growing grow - grown grown - grows grow - growth growth - grub grub - grubb grubb - grubs grub - grudge grudg - grudged grudg - grudges grudg - grudging grudg - gruel gruel - grumble grumbl - grumblest grumblest - grumbling grumbl - grumblings grumbl - grumio grumio - grund grund - grunt grunt - gualtier gualtier - guard guard - guardage guardag - guardant guardant - guarded guard - guardian guardian - guardians guardian - guards guard - guardsman guardsman - gud gud - gudgeon gudgeon - guerdon guerdon - guerra guerra - guess guess - guesses guess - guessingly guessingli - guest guest - guests guest - guiana guiana - guichard guichard - guide guid - guided guid - guider guider - guiderius guideriu - guides guid - guiding guid - guidon guidon - guienne guienn - guil guil - guildenstern guildenstern - guilders guilder - guildford guildford - guildhall guildhal - guile guil - guiled guil - guileful guil - guilfords guilford - guilt guilt - guiltian guiltian - guiltier guiltier - guiltily guiltili - guiltiness guilti - guiltless guiltless - guilts guilt - guilty guilti - guinea guinea - guinever guinev - guise guis - gul gul - gules gule - gulf gulf - gulfs gulf - gull gull - gulls gull - gum gum - gumm gumm - gums gum - gun gun - gunner gunner - gunpowder gunpowd - guns gun - gurnet gurnet - gurney gurnei - gust gust - gusts gust - gusty gusti - guts gut - gutter gutter - guy gui - guynes guyn - guysors guysor - gypsy gypsi - gyve gyve - gyved gyve - gyves gyve - h h - ha ha - haberdasher haberdash - habiliment habili - habiliments habili - habit habit - habitation habit - habited habit - habits habit - habitude habitud - hack hack - hacket hacket - hackney hacknei - hacks hack - had had - hadst hadst - haec haec - haeres haer - hag hag - hagar hagar - haggard haggard - haggards haggard - haggish haggish - haggled haggl - hags hag - hail hail - hailed hail - hailstone hailston - hailstones hailston - hair hair - hairless hairless - hairs hair - hairy hairi - hal hal - halberd halberd - halberds halberd - halcyon halcyon - hale hale - haled hale - hales hale - half half - halfcan halfcan - halfpence halfpenc - halfpenny halfpenni - halfpennyworth halfpennyworth - halfway halfwai - halidom halidom - hall hall - halloa halloa - halloing hallo - hallond hallond - halloo halloo - hallooing halloo - hallow hallow - hallowed hallow - hallowmas hallowma - hallown hallown - hals hal - halt halt - halter halter - halters halter - halting halt - halts halt - halves halv - ham ham - hames hame - hamlet hamlet - hammer hammer - hammered hammer - hammering hammer - hammers hammer - hamper hamper - hampton hampton - hams ham - hamstring hamstr - hand hand - handed hand - handful hand - handicraft handicraft - handicraftsmen handicraftsmen - handing hand - handiwork handiwork - handkercher handkerch - handkerchers handkerch - handkerchief handkerchief - handle handl - handled handl - handles handl - handless handless - handlest handlest - handling handl - handmaid handmaid - handmaids handmaid - hands hand - handsaw handsaw - handsome handsom - handsomely handsom - handsomeness handsom - handwriting handwrit - handy handi - hang hang - hanged hang - hangers hanger - hangeth hangeth - hanging hang - hangings hang - hangman hangman - hangmen hangmen - hangs hang - hannibal hannib - hap hap - hapless hapless - haply hapli - happ happ - happen happen - happened happen - happier happier - happies happi - happiest happiest - happily happili - happiness happi - happy happi - haps hap - harbinger harbing - harbingers harbing - harbor harbor - harbour harbour - harbourage harbourag - harbouring harbour - harbours harbour - harcourt harcourt - hard hard - harder harder - hardest hardest - hardiest hardiest - hardiment hardiment - hardiness hardi - hardly hardli - hardness hard - hardocks hardock - hardy hardi - hare hare - harelip harelip - hares hare - harfleur harfleur - hark hark - harlot harlot - harlotry harlotri - harlots harlot - harm harm - harmed harm - harmful harm - harming harm - harmless harmless - harmonious harmoni - harmony harmoni - harms harm - harness har - harp harp - harper harper - harpier harpier - harping harp - harpy harpi - harried harri - harrow harrow - harrows harrow - harry harri - harsh harsh - harshly harshli - harshness harsh - hart hart - harts hart - harum harum - harvest harvest - has ha - hast hast - haste hast - hasted hast - hasten hasten - hastes hast - hastily hastili - hasting hast - hastings hast - hasty hasti - hat hat - hatch hatch - hatches hatch - hatchet hatchet - hatching hatch - hatchment hatchment - hate hate - hated hate - hateful hate - hater hater - haters hater - hates hate - hateth hateth - hatfield hatfield - hath hath - hating hate - hatred hatr - hats hat - haud haud - hauf hauf - haught haught - haughtiness haughti - haughty haughti - haunch haunch - haunches haunch - haunt haunt - haunted haunt - haunting haunt - haunts haunt - hautboy hautboi - hautboys hautboi - have have - haven haven - havens haven - haver haver - having have - havings have - havior havior - haviour haviour - havoc havoc - hawk hawk - hawking hawk - hawks hawk - hawthorn hawthorn - hawthorns hawthorn - hay hai - hazard hazard - hazarded hazard - hazards hazard - hazel hazel - hazelnut hazelnut - he he - head head - headborough headborough - headed head - headier headier - heading head - headland headland - headless headless - headlong headlong - heads head - headsman headsman - headstrong headstrong - heady headi - heal heal - healed heal - healing heal - heals heal - health health - healthful health - healths health - healthsome healthsom - healthy healthi - heap heap - heaping heap - heaps heap - hear hear - heard heard - hearer hearer - hearers hearer - hearest hearest - heareth heareth - hearing hear - hearings hear - heark heark - hearken hearken - hearkens hearken - hears hear - hearsay hearsai - hearse hears - hearsed hears - hearst hearst - heart heart - heartache heartach - heartbreak heartbreak - heartbreaking heartbreak - hearted heart - hearten hearten - hearth hearth - hearths hearth - heartily heartili - heartiness hearti - heartless heartless - heartlings heartl - heartly heartli - hearts heart - heartsick heartsick - heartstrings heartstr - hearty hearti - heat heat - heated heat - heath heath - heathen heathen - heathenish heathenish - heating heat - heats heat - heauties heauti - heav heav - heave heav - heaved heav - heaven heaven - heavenly heavenli - heavens heaven - heaves heav - heavier heavier - heaviest heaviest - heavily heavili - heaviness heavi - heaving heav - heavings heav - heavy heavi - hebona hebona - hebrew hebrew - hecate hecat - hectic hectic - hector hector - hectors hector - hecuba hecuba - hedg hedg - hedge hedg - hedgehog hedgehog - hedgehogs hedgehog - hedges hedg - heed heed - heeded heed - heedful heed - heedfull heedful - heedfully heedfulli - heedless heedless - heel heel - heels heel - hefted heft - hefts heft - heifer heifer - heifers heifer - heigh heigh - height height - heighten heighten - heinous heinou - heinously heinous - heir heir - heiress heiress - heirless heirless - heirs heir - held held - helen helen - helena helena - helenus helenu - helias helia - helicons helicon - hell hell - hellespont hellespont - hellfire hellfir - hellish hellish - helm helm - helmed helm - helmet helmet - helmets helmet - helms helm - help help - helper helper - helpers helper - helpful help - helping help - helpless helpless - helps help - helter helter - hem hem - heme heme - hemlock hemlock - hemm hemm - hemp hemp - hempen hempen - hems hem - hen hen - hence henc - henceforth henceforth - henceforward henceforward - henchman henchman - henri henri - henricus henricu - henry henri - hens hen - hent hent - henton henton - her her - herald herald - heraldry heraldri - heralds herald - herb herb - herbert herbert - herblets herblet - herbs herb - herculean herculean - hercules hercul - herd herd - herds herd - herdsman herdsman - herdsmen herdsmen - here here - hereabout hereabout - hereabouts hereabout - hereafter hereaft - hereby herebi - hereditary hereditari - hereford hereford - herefordshire herefordshir - herein herein - hereof hereof - heresies heresi - heresy heresi - heretic heret - heretics heret - hereto hereto - hereupon hereupon - heritage heritag - heritier heriti - hermes herm - hermia hermia - hermione hermion - hermit hermit - hermitage hermitag - hermits hermit - herne hern - hero hero - herod herod - herods herod - heroes hero - heroic heroic - heroical heroic - herring her - herrings her - hers her - herself herself - hesperides hesperid - hesperus hesperu - hest hest - hests hest - heure heur - heureux heureux - hew hew - hewgh hewgh - hewing hew - hewn hewn - hews hew - hey hei - heyday heydai - hibocrates hibocr - hic hic - hiccups hiccup - hick hick - hid hid - hidden hidden - hide hide - hideous hideou - hideously hideous - hideousness hideous - hides hide - hidest hidest - hiding hide - hie hie - hied hi - hiems hiem - hies hi - hig hig - high high - higher higher - highest highest - highly highli - highmost highmost - highness high - hight hight - highway highwai - highways highwai - hilding hild - hildings hild - hill hill - hillo hillo - hilloa hilloa - hills hill - hilt hilt - hilts hilt - hily hili - him him - himself himself - hinc hinc - hinckley hincklei - hind hind - hinder hinder - hindered hinder - hinders hinder - hindmost hindmost - hinds hind - hing hing - hinge hing - hinges hing - hint hint - hip hip - hipp hipp - hipparchus hipparchu - hippolyta hippolyta - hips hip - hir hir - hire hire - hired hire - hiren hiren - hirtius hirtiu - his hi - hisperia hisperia - hiss hiss - hisses hiss - hissing hiss - hist hist - historical histor - history histori - hit hit - hither hither - hitherto hitherto - hitherward hitherward - hitherwards hitherward - hits hit - hitting hit - hive hive - hives hive - hizzing hizz - ho ho - hoa hoa - hoar hoar - hoard hoard - hoarded hoard - hoarding hoard - hoars hoar - hoarse hoars - hoary hoari - hob hob - hobbididence hobbidid - hobby hobbi - hobbyhorse hobbyhors - hobgoblin hobgoblin - hobnails hobnail - hoc hoc - hod hod - hodge hodg - hog hog - hogs hog - hogshead hogshead - hogsheads hogshead - hois hoi - hoise hois - hoist hoist - hoisted hoist - hoists hoist - holborn holborn - hold hold - holden holden - holder holder - holdeth holdeth - holdfast holdfast - holding hold - holds hold - hole hole - holes hole - holidam holidam - holidame holidam - holiday holidai - holidays holidai - holier holier - holiest holiest - holily holili - holiness holi - holla holla - holland holland - hollander holland - hollanders holland - holloa holloa - holloaing holloa - hollow hollow - hollowly hollowli - hollowness hollow - holly holli - holmedon holmedon - holofernes holofern - holp holp - holy holi - homage homag - homager homag - home home - homely home - homes home - homespuns homespun - homeward homeward - homewards homeward - homicide homicid - homicides homicid - homily homili - hominem hominem - hommes homm - homo homo - honest honest - honester honest - honestest honestest - honestly honestli - honesty honesti - honey honei - honeycomb honeycomb - honeying honei - honeyless honeyless - honeysuckle honeysuckl - honeysuckles honeysuckl - honi honi - honneur honneur - honor honor - honorable honor - honorably honor - honorato honorato - honors honor - honour honour - honourable honour - honourably honour - honoured honour - honourest honourest - honourible honour - honouring honour - honours honour - hoo hoo - hood hood - hooded hood - hoodman hoodman - hoods hood - hoodwink hoodwink - hoof hoof - hoofs hoof - hook hook - hooking hook - hooks hook - hoop hoop - hoops hoop - hoot hoot - hooted hoot - hooting hoot - hoots hoot - hop hop - hope hope - hopeful hope - hopeless hopeless - hopes hope - hopest hopest - hoping hope - hopkins hopkin - hoppedance hopped - hor hor - horace horac - horatio horatio - horizon horizon - horn horn - hornbook hornbook - horned horn - horner horner - horning horn - hornpipes hornpip - horns horn - horologe horolog - horrible horribl - horribly horribl - horrid horrid - horrider horrid - horridly horridli - horror horror - horrors horror - hors hor - horse hors - horseback horseback - horsed hors - horsehairs horsehair - horseman horseman - horsemanship horsemanship - horsemen horsemen - horses hors - horseway horsewai - horsing hors - hortensio hortensio - hortensius hortensiu - horum horum - hose hose - hospitable hospit - hospital hospit - hospitality hospit - host host - hostage hostag - hostages hostag - hostess hostess - hostile hostil - hostility hostil - hostilius hostiliu - hosts host - hot hot - hotly hotli - hotspur hotspur - hotter hotter - hottest hottest - hound hound - hounds hound - hour hour - hourly hourli - hours hour - hous hou - house hous - household household - householder household - householders household - households household - housekeeper housekeep - housekeepers housekeep - housekeeping housekeep - houseless houseless - houses hous - housewife housewif - housewifery housewiferi - housewives housew - hovel hovel - hover hover - hovered hover - hovering hover - hovers hover - how how - howbeit howbeit - howe how - howeer howeer - however howev - howl howl - howled howl - howlet howlet - howling howl - howls howl - howsoe howso - howsoever howsoev - howsome howsom - hoxes hox - hoy hoi - hoyday hoydai - hubert hubert - huddled huddl - huddling huddl - hue hue - hued hu - hues hue - hug hug - huge huge - hugely huge - hugeness huge - hugg hugg - hugger hugger - hugh hugh - hugs hug - hujus huju - hulk hulk - hulks hulk - hull hull - hulling hull - hullo hullo - hum hum - human human - humane human - humanely human - humanity human - humble humbl - humbled humbl - humbleness humbl - humbler humbler - humbles humbl - humblest humblest - humbling humbl - humbly humbl - hume hume - humh humh - humidity humid - humility humil - humming hum - humor humor - humorous humor - humors humor - humour humour - humourists humourist - humours humour - humphrey humphrei - humphry humphri - hums hum - hundred hundr - hundreds hundr - hundredth hundredth - hung hung - hungarian hungarian - hungary hungari - hunger hunger - hungerford hungerford - hungerly hungerli - hungry hungri - hunt hunt - hunted hunt - hunter hunter - hunters hunter - hunteth hunteth - hunting hunt - huntington huntington - huntress huntress - hunts hunt - huntsman huntsman - huntsmen huntsmen - hurdle hurdl - hurl hurl - hurling hurl - hurls hurl - hurly hurli - hurlyburly hurlyburli - hurricano hurricano - hurricanoes hurricano - hurried hurri - hurries hurri - hurry hurri - hurt hurt - hurting hurt - hurtled hurtl - hurtless hurtless - hurtling hurtl - hurts hurt - husband husband - husbanded husband - husbandless husbandless - husbandry husbandri - husbands husband - hush hush - hushes hush - husht husht - husks husk - huswife huswif - huswifes huswif - hutch hutch - hybla hybla - hydra hydra - hyen hyen - hymen hymen - hymenaeus hymenaeu - hymn hymn - hymns hymn - hyperboles hyperbol - hyperbolical hyperbol - hyperion hyperion - hypocrisy hypocrisi - hypocrite hypocrit - hypocrites hypocrit - hyrcan hyrcan - hyrcania hyrcania - hyrcanian hyrcanian - hyssop hyssop - hysterica hysterica - i i - iachimo iachimo - iaculis iaculi - iago iago - iament iament - ibat ibat - icarus icaru - ice ic - iceland iceland - ici ici - icicle icicl - icicles icicl - icy ici - idea idea - ideas idea - idem idem - iden iden - ides id - idiot idiot - idiots idiot - idle idl - idleness idl - idles idl - idly idli - idol idol - idolatrous idolatr - idolatry idolatri - ield ield - if if - ifs if - ignis igni - ignoble ignobl - ignobly ignobl - ignominious ignomini - ignominy ignomini - ignomy ignomi - ignorance ignor - ignorant ignor - ii ii - iii iii - iiii iiii - il il - ilbow ilbow - ild ild - ilion ilion - ilium ilium - ill ill - illegitimate illegitim - illiterate illiter - illness ill - illo illo - ills ill - illume illum - illumin illumin - illuminate illumin - illumineth illumineth - illusion illus - illusions illus - illustrate illustr - illustrated illustr - illustrious illustri - illyria illyria - illyrian illyrian - ils il - im im - image imag - imagery imageri - images imag - imagin imagin - imaginary imaginari - imagination imagin - imaginations imagin - imagine imagin - imagining imagin - imaginings imagin - imbar imbar - imbecility imbecil - imbrue imbru - imitari imitari - imitate imit - imitated imit - imitation imit - imitations imit - immaculate immacul - immanity imman - immask immask - immaterial immateri - immediacy immediaci - immediate immedi - immediately immedi - imminence immin - imminent immin - immoderate immoder - immoderately immoder - immodest immodest - immoment immoment - immortal immort - immortaliz immortaliz - immortally immort - immur immur - immured immur - immures immur - imogen imogen - imp imp - impaint impaint - impair impair - impairing impair - impale impal - impaled impal - impanelled impanel - impart impart - imparted impart - impartial imparti - impartment impart - imparts impart - impasted impast - impatience impati - impatient impati - impatiently impati - impawn impawn - impeach impeach - impeached impeach - impeachment impeach - impeachments impeach - impedes imped - impediment impedi - impediments impedi - impenetrable impenetr - imperator imper - imperceiverant imperceiver - imperfect imperfect - imperfection imperfect - imperfections imperfect - imperfectly imperfectli - imperial imperi - imperious imperi - imperiously imperi - impertinency impertin - impertinent impertin - impeticos impetico - impetuosity impetuos - impetuous impetu - impieties impieti - impiety impieti - impious impiou - implacable implac - implements implement - implies impli - implor implor - implorators implor - implore implor - implored implor - imploring implor - impon impon - import import - importance import - importancy import - important import - importantly importantli - imported import - importeth importeth - importing import - importless importless - imports import - importun importun - importunacy importunaci - importunate importun - importune importun - importunes importun - importunity importun - impos impo - impose impos - imposed impos - imposition imposit - impositions imposit - impossibilities imposs - impossibility imposs - impossible imposs - imposthume imposthum - impostor impostor - impostors impostor - impotence impot - impotent impot - impounded impound - impregnable impregn - imprese impres - impress impress - impressed impress - impressest impressest - impression impress - impressure impressur - imprimendum imprimendum - imprimis imprimi - imprint imprint - imprinted imprint - imprison imprison - imprisoned imprison - imprisoning imprison - imprisonment imprison - improbable improb - improper improp - improve improv - improvident improvid - impudence impud - impudency impud - impudent impud - impudently impud - impudique impudiqu - impugn impugn - impugns impugn - impure impur - imputation imput - impute imput - in in - inaccessible inaccess - inaidable inaid - inaudible inaud - inauspicious inauspici - incaged incag - incantations incant - incapable incap - incardinate incardin - incarnadine incarnadin - incarnate incarn - incarnation incarn - incens incen - incense incens - incensed incens - incensement incens - incenses incens - incensing incens - incertain incertain - incertainties incertainti - incertainty incertainti - incessant incess - incessantly incessantli - incest incest - incestuous incestu - inch inch - incharitable incharit - inches inch - incidency incid - incident incid - incision incis - incite incit - incites incit - incivil incivil - incivility incivil - inclin inclin - inclinable inclin - inclination inclin - incline inclin - inclined inclin - inclines inclin - inclining inclin - inclips inclip - include includ - included includ - includes includ - inclusive inclus - incomparable incompar - incomprehensible incomprehens - inconsiderate inconsider - inconstancy inconst - inconstant inconst - incontinency incontin - incontinent incontin - incontinently incontin - inconvenience inconveni - inconveniences inconveni - inconvenient inconveni - incony inconi - incorporate incorpor - incorps incorp - incorrect incorrect - increas increa - increase increas - increases increas - increaseth increaseth - increasing increas - incredible incred - incredulous incredul - incur incur - incurable incur - incurr incurr - incurred incur - incursions incurs - ind ind - inde ind - indebted indebt - indeed inde - indent indent - indented indent - indenture indentur - indentures indentur - index index - indexes index - india india - indian indian - indict indict - indicted indict - indictment indict - indies indi - indifferency indiffer - indifferent indiffer - indifferently indiffer - indigent indig - indigest indigest - indigested indigest - indign indign - indignation indign - indignations indign - indigne indign - indignities indign - indignity indign - indirect indirect - indirection indirect - indirections indirect - indirectly indirectli - indiscreet indiscreet - indiscretion indiscret - indispos indispo - indisposition indisposit - indissoluble indissolubl - indistinct indistinct - indistinguish indistinguish - indistinguishable indistinguish - indited indit - individable individ - indrench indrench - indu indu - indubitate indubit - induc induc - induce induc - induced induc - inducement induc - induction induct - inductions induct - indue indu - indued indu - indues indu - indulgence indulg - indulgences indulg - indulgent indulg - indurance indur - industrious industri - industriously industri - industry industri - inequality inequ - inestimable inestim - inevitable inevit - inexecrable inexecr - inexorable inexor - inexplicable inexplic - infallible infal - infallibly infal - infamonize infamon - infamous infam - infamy infami - infancy infanc - infant infant - infants infant - infect infect - infected infect - infecting infect - infection infect - infections infect - infectious infecti - infectiously infecti - infects infect - infer infer - inference infer - inferior inferior - inferiors inferior - infernal infern - inferr inferr - inferreth inferreth - inferring infer - infest infest - infidel infidel - infidels infidel - infinite infinit - infinitely infinit - infinitive infinit - infirm infirm - infirmities infirm - infirmity infirm - infixed infix - infixing infix - inflam inflam - inflame inflam - inflaming inflam - inflammation inflamm - inflict inflict - infliction inflict - influence influenc - influences influenc - infold infold - inform inform - informal inform - information inform - informations inform - informed inform - informer inform - informs inform - infortunate infortun - infring infr - infringe infring - infringed infring - infus infu - infuse infus - infused infus - infusing infus - infusion infus - ingener ingen - ingenious ingeni - ingeniously ingeni - inglorious inglori - ingots ingot - ingraffed ingraf - ingraft ingraft - ingrate ingrat - ingrated ingrat - ingrateful ingrat - ingratitude ingratitud - ingratitudes ingratitud - ingredient ingredi - ingredients ingredi - ingross ingross - inhabit inhabit - inhabitable inhabit - inhabitants inhabit - inhabited inhabit - inhabits inhabit - inhearse inhears - inhearsed inhears - inherent inher - inherit inherit - inheritance inherit - inherited inherit - inheriting inherit - inheritor inheritor - inheritors inheritor - inheritrix inheritrix - inherits inherit - inhibited inhibit - inhibition inhibit - inhoop inhoop - inhuman inhuman - iniquities iniqu - iniquity iniqu - initiate initi - injointed injoint - injunction injunct - injunctions injunct - injur injur - injure injur - injurer injur - injuries injuri - injurious injuri - injury injuri - injustice injustic - ink ink - inkhorn inkhorn - inkle inkl - inkles inkl - inkling inkl - inky inki - inlaid inlaid - inland inland - inlay inlai - inly inli - inmost inmost - inn inn - inner inner - innkeeper innkeep - innocence innoc - innocency innoc - innocent innoc - innocents innoc - innovation innov - innovator innov - inns inn - innumerable innumer - inoculate inocul - inordinate inordin - inprimis inprimi - inquir inquir - inquire inquir - inquiry inquiri - inquisition inquisit - inquisitive inquisit - inroads inroad - insane insan - insanie insani - insatiate insati - insconce insconc - inscrib inscrib - inscription inscript - inscriptions inscript - inscroll inscrol - inscrutable inscrut - insculp insculp - insculpture insculptur - insensible insens - inseparable insepar - inseparate insepar - insert insert - inserted insert - inset inset - inshell inshel - inshipp inshipp - inside insid - insinewed insinew - insinuate insinu - insinuateth insinuateth - insinuating insinu - insinuation insinu - insisted insist - insisting insist - insisture insistur - insociable insoci - insolence insol - insolent insol - insomuch insomuch - inspir inspir - inspiration inspir - inspirations inspir - inspire inspir - inspired inspir - install instal - installed instal - instalment instal - instance instanc - instances instanc - instant instant - instantly instantli - instate instat - instead instead - insteeped insteep - instigate instig - instigated instig - instigation instig - instigations instig - instigator instig - instinct instinct - instinctively instinct - institute institut - institutions institut - instruct instruct - instructed instruct - instruction instruct - instructions instruct - instructs instruct - instrument instrument - instrumental instrument - instruments instrument - insubstantial insubstanti - insufficience insuffici - insufficiency insuffici - insult insult - insulted insult - insulting insult - insultment insult - insults insult - insupportable insupport - insuppressive insuppress - insurrection insurrect - insurrections insurrect - int int - integer integ - integritas integrita - integrity integr - intellect intellect - intellects intellect - intellectual intellectu - intelligence intellig - intelligencer intelligenc - intelligencing intelligenc - intelligent intellig - intelligis intelligi - intelligo intelligo - intemperance intemper - intemperate intemper - intend intend - intended intend - intendeth intendeth - intending intend - intendment intend - intends intend - intenible inten - intent intent - intention intent - intentively intent - intents intent - inter inter - intercept intercept - intercepted intercept - intercepter intercept - interception intercept - intercepts intercept - intercession intercess - intercessors intercessor - interchained interchain - interchang interchang - interchange interchang - interchangeably interchang - interchangement interchang - interchanging interchang - interdiction interdict - interest interest - interim interim - interims interim - interior interior - interjections interject - interjoin interjoin - interlude interlud - intermingle intermingl - intermission intermiss - intermissive intermiss - intermit intermit - intermix intermix - intermixed intermix - interpose interpos - interposer interpos - interposes interpos - interpret interpret - interpretation interpret - interpreted interpret - interpreter interpret - interpreters interpret - interprets interpret - interr interr - interred inter - interrogatories interrogatori - interrupt interrupt - interrupted interrupt - interrupter interrupt - interruptest interruptest - interruption interrupt - interrupts interrupt - intertissued intertissu - intervallums intervallum - interview interview - intestate intest - intestine intestin - intil intil - intimate intim - intimation intim - intitled intitl - intituled intitul - into into - intolerable intoler - intoxicates intox - intreasured intreasur - intreat intreat - intrench intrench - intrenchant intrench - intricate intric - intrinse intrins - intrinsicate intrins - intrude intrud - intruder intrud - intruding intrud - intrusion intrus - inundation inund - inure inur - inurn inurn - invade invad - invades invad - invasion invas - invasive invas - invectively invect - invectives invect - inveigled inveigl - invent invent - invented invent - invention invent - inventions invent - inventor inventor - inventorially inventori - inventoried inventori - inventors inventor - inventory inventori - inverness inver - invert invert - invest invest - invested invest - investing invest - investments invest - inveterate inveter - invincible invinc - inviolable inviol - invised invis - invisible invis - invitation invit - invite invit - invited invit - invites invit - inviting invit - invitis inviti - invocate invoc - invocation invoc - invoke invok - invoked invok - invulnerable invulner - inward inward - inwardly inwardli - inwardness inward - inwards inward - ionia ionia - ionian ionian - ipse ips - ipswich ipswich - ira ira - irae ira - iras ira - ire ir - ireful ir - ireland ireland - iris iri - irish irish - irishman irishman - irishmen irishmen - irks irk - irksome irksom - iron iron - irons iron - irreconcil irreconcil - irrecoverable irrecover - irregular irregular - irregulous irregul - irreligious irreligi - irremovable irremov - irreparable irrepar - irresolute irresolut - irrevocable irrevoc - is is - isabel isabel - isabella isabella - isbel isbel - isbels isbel - iscariot iscariot - ise is - ish ish - isidore isidor - isis isi - island island - islander island - islanders island - islands island - isle isl - isles isl - israel israel - issu issu - issue issu - issued issu - issueless issueless - issues issu - issuing issu - ist ist - ista ista - it it - italian italian - italy itali - itch itch - itches itch - itching itch - item item - items item - iteration iter - ithaca ithaca - its it - itself itself - itshall itshal - iv iv - ivory ivori - ivy ivi - iwis iwi - ix ix - j j - jacet jacet - jack jack - jackanapes jackanap - jacks jack - jacksauce jacksauc - jackslave jackslav - jacob jacob - jade jade - jaded jade - jades jade - jail jail - jakes jake - jamany jamani - james jame - jamy jami - jane jane - jangled jangl - jangling jangl - january januari - janus janu - japhet japhet - jaquenetta jaquenetta - jaques jaqu - jar jar - jarring jar - jars jar - jarteer jarteer - jasons jason - jaunce jaunc - jauncing jaunc - jaundice jaundic - jaundies jaundi - jaw jaw - jawbone jawbon - jaws jaw - jay jai - jays jai - jc jc - je je - jealous jealou - jealousies jealousi - jealousy jealousi - jeer jeer - jeering jeer - jelly jelli - jenny jenni - jeopardy jeopardi - jephtha jephtha - jephthah jephthah - jerkin jerkin - jerkins jerkin - jerks jerk - jeronimy jeronimi - jerusalem jerusalem - jeshu jeshu - jesses jess - jessica jessica - jest jest - jested jest - jester jester - jesters jester - jesting jest - jests jest - jesu jesu - jesus jesu - jet jet - jets jet - jew jew - jewel jewel - jeweller jewel - jewels jewel - jewess jewess - jewish jewish - jewry jewri - jews jew - jezebel jezebel - jig jig - jigging jig - jill jill - jills jill - jingling jingl - joan joan - job job - jockey jockei - jocund jocund - jog jog - jogging jog - john john - johns john - join join - joinder joinder - joined join - joiner joiner - joineth joineth - joins join - joint joint - jointed joint - jointing joint - jointly jointli - jointress jointress - joints joint - jointure jointur - jollity jolliti - jolly jolli - jolt jolt - joltheads jolthead - jordan jordan - joseph joseph - joshua joshua - jot jot - jour jour - jourdain jourdain - journal journal - journey journei - journeying journei - journeyman journeyman - journeymen journeymen - journeys journei - jove jove - jovem jovem - jovial jovial - jowl jowl - jowls jowl - joy joi - joyed joi - joyful joy - joyfully joyfulli - joyless joyless - joyous joyou - joys joi - juan juan - jud jud - judas juda - judases judas - jude jude - judg judg - judge judg - judged judg - judgement judgement - judges judg - judgest judgest - judging judg - judgment judgment - judgments judgment - judicious judici - jug jug - juggle juggl - juggled juggl - juggler juggler - jugglers juggler - juggling juggl - jugs jug - juice juic - juiced juic - jul jul - jule jule - julia julia - juliet juliet - julietta julietta - julio julio - julius juliu - july juli - jump jump - jumpeth jumpeth - jumping jump - jumps jump - june june - junes june - junior junior - junius juniu - junkets junket - juno juno - jupiter jupit - jure jure - jurement jurement - jurisdiction jurisdict - juror juror - jurors juror - jury juri - jurymen jurymen - just just - justeius justeiu - justest justest - justice justic - justicer justic - justicers justic - justices justic - justification justif - justified justifi - justify justifi - justle justl - justled justl - justles justl - justling justl - justly justli - justness just - justs just - jutting jut - jutty jutti - juvenal juven - kam kam - kate kate - kated kate - kates kate - katharine katharin - katherina katherina - katherine katherin - kecksies kecksi - keech keech - keel keel - keels keel - keen keen - keenness keen - keep keep - keepdown keepdown - keeper keeper - keepers keeper - keepest keepest - keeping keep - keeps keep - keiser keiser - ken ken - kendal kendal - kennel kennel - kent kent - kentish kentish - kentishman kentishman - kentishmen kentishmen - kept kept - kerchief kerchief - kerely kere - kern kern - kernal kernal - kernel kernel - kernels kernel - kerns kern - kersey kersei - kettle kettl - kettledrum kettledrum - kettledrums kettledrum - key kei - keys kei - kibe kibe - kibes kibe - kick kick - kicked kick - kickshaws kickshaw - kickshawses kickshaws - kicky kicki - kid kid - kidney kidnei - kikely kike - kildare kildar - kill kill - killed kill - killer killer - killeth killeth - killing kill - killingworth killingworth - kills kill - kiln kiln - kimbolton kimbolton - kin kin - kind kind - kinder kinder - kindest kindest - kindle kindl - kindled kindl - kindless kindless - kindlier kindlier - kindling kindl - kindly kindli - kindness kind - kindnesses kind - kindred kindr - kindreds kindr - kinds kind - kine kine - king king - kingdom kingdom - kingdoms kingdom - kingly kingli - kings king - kinred kinr - kins kin - kinsman kinsman - kinsmen kinsmen - kinswoman kinswoman - kirtle kirtl - kirtles kirtl - kiss kiss - kissed kiss - kisses kiss - kissing kiss - kitchen kitchen - kitchens kitchen - kite kite - kites kite - kitten kitten - kj kj - kl kl - klll klll - knack knack - knacks knack - knapp knapp - knav knav - knave knave - knaveries knaveri - knavery knaveri - knaves knave - knavish knavish - knead knead - kneaded knead - kneading knead - knee knee - kneel kneel - kneeling kneel - kneels kneel - knees knee - knell knell - knew knew - knewest knewest - knife knife - knight knight - knighted knight - knighthood knighthood - knighthoods knighthood - knightly knightli - knights knight - knit knit - knits knit - knitters knitter - knitteth knitteth - knives knive - knobs knob - knock knock - knocking knock - knocks knock - knog knog - knoll knoll - knot knot - knots knot - knotted knot - knotty knotti - know know - knower knower - knowest knowest - knowing know - knowingly knowingli - knowings know - knowledge knowledg - known known - knows know - l l - la la - laban laban - label label - labell label - labienus labienu - labio labio - labor labor - laboring labor - labors labor - labour labour - laboured labour - labourer labour - labourers labour - labouring labour - labours labour - laboursome laboursom - labras labra - labyrinth labyrinth - lac lac - lace lace - laced lace - lacedaemon lacedaemon - laces lace - lacies laci - lack lack - lackbeard lackbeard - lacked lack - lackey lackei - lackeying lackei - lackeys lackei - lacking lack - lacks lack - lad lad - ladder ladder - ladders ladder - lade lade - laden laden - ladies ladi - lading lade - lads lad - lady ladi - ladybird ladybird - ladyship ladyship - ladyships ladyship - laer laer - laertes laert - lafeu lafeu - lag lag - lagging lag - laid laid - lain lain - laissez laissez - lake lake - lakes lake - lakin lakin - lam lam - lamb lamb - lambert lambert - lambkin lambkin - lambkins lambkin - lambs lamb - lame lame - lamely lame - lameness lame - lament lament - lamentable lament - lamentably lament - lamentation lament - lamentations lament - lamented lament - lamenting lament - lamentings lament - laments lament - lames lame - laming lame - lammas lamma - lammastide lammastid - lamound lamound - lamp lamp - lampass lampass - lamps lamp - lanc lanc - lancaster lancast - lance lanc - lances lanc - lanceth lanceth - lanch lanch - land land - landed land - landing land - landless landless - landlord landlord - landmen landmen - lands land - lane lane - lanes lane - langage langag - langley langlei - langton langton - language languag - languageless languageless - languages languag - langues langu - languish languish - languished languish - languishes languish - languishing languish - languishings languish - languishment languish - languor languor - lank lank - lantern lantern - lanterns lantern - lanthorn lanthorn - lap lap - lapis lapi - lapland lapland - lapp lapp - laps lap - lapse laps - lapsed laps - lapsing laps - lapwing lapw - laquais laquai - larded lard - larder larder - larding lard - lards lard - large larg - largely larg - largeness larg - larger larger - largess largess - largest largest - lark lark - larks lark - larron larron - lartius lartiu - larum larum - larums larum - las la - lascivious lascivi - lash lash - lass lass - lasses lass - last last - lasted last - lasting last - lastly lastli - lasts last - latch latch - latches latch - late late - lated late - lately late - later later - latest latest - lath lath - latin latin - latten latten - latter latter - lattice lattic - laud laud - laudable laudabl - laudis laudi - laugh laugh - laughable laughabl - laughed laugh - laugher laugher - laughest laughest - laughing laugh - laughs laugh - laughter laughter - launce launc - launcelot launcelot - launces launc - launch launch - laund laund - laundress laundress - laundry laundri - laur laur - laura laura - laurel laurel - laurels laurel - laurence laurenc - laus lau - lavache lavach - lave lave - lavee lave - lavender lavend - lavina lavina - lavinia lavinia - lavish lavish - lavishly lavishli - lavolt lavolt - lavoltas lavolta - law law - lawful law - lawfully lawfulli - lawless lawless - lawlessly lawlessli - lawn lawn - lawns lawn - lawrence lawrenc - laws law - lawyer lawyer - lawyers lawyer - lay lai - layer layer - layest layest - laying lai - lays lai - lazar lazar - lazars lazar - lazarus lazaru - lazy lazi - lc lc - ld ld - ldst ldst - le le - lead lead - leaden leaden - leader leader - leaders leader - leadest leadest - leading lead - leads lead - leaf leaf - leagu leagu - league leagu - leagued leagu - leaguer leaguer - leagues leagu - leah leah - leak leak - leaky leaki - lean lean - leander leander - leaner leaner - leaning lean - leanness lean - leans lean - leap leap - leaped leap - leaping leap - leaps leap - leapt leapt - lear lear - learn learn - learned learn - learnedly learnedli - learning learn - learnings learn - learns learn - learnt learnt - leas lea - lease leas - leases leas - leash leash - leasing leas - least least - leather leather - leathern leathern - leav leav - leave leav - leaven leaven - leavening leaven - leaver leaver - leaves leav - leaving leav - leavy leavi - lecher lecher - lecherous lecher - lechers lecher - lechery lecheri - lecon lecon - lecture lectur - lectures lectur - led led - leda leda - leech leech - leeches leech - leek leek - leeks leek - leer leer - leers leer - lees lee - leese lees - leet leet - leets leet - left left - leg leg - legacies legaci - legacy legaci - legate legat - legatine legatin - lege lege - legerity leger - leges lege - legg legg - legion legion - legions legion - legitimate legitim - legitimation legitim - legs leg - leicester leicest - leicestershire leicestershir - leiger leiger - leigers leiger - leisure leisur - leisurely leisur - leisures leisur - leman leman - lemon lemon - lena lena - lend lend - lender lender - lending lend - lendings lend - lends lend - length length - lengthen lengthen - lengthens lengthen - lengths length - lenity leniti - lennox lennox - lent lent - lenten lenten - lentus lentu - leo leo - leon leon - leonardo leonardo - leonati leonati - leonato leonato - leonatus leonatu - leontes leont - leopard leopard - leopards leopard - leper leper - leperous leper - lepidus lepidu - leprosy leprosi - lequel lequel - lers ler - les le - less less - lessen lessen - lessens lessen - lesser lesser - lesson lesson - lessoned lesson - lessons lesson - lest lest - lestrake lestrak - let let - lethargied lethargi - lethargies lethargi - lethargy lethargi - lethe leth - lets let - lett lett - letter letter - letters letter - letting let - lettuce lettuc - leur leur - leve leve - level level - levell level - levelled level - levels level - leven leven - levers lever - leviathan leviathan - leviathans leviathan - levied levi - levies levi - levity leviti - levy levi - levying levi - lewd lewd - lewdly lewdli - lewdness lewd - lewdsters lewdster - lewis lewi - liable liabl - liar liar - liars liar - libbard libbard - libelling libel - libels libel - liberal liber - liberality liber - liberte libert - liberties liberti - libertine libertin - libertines libertin - liberty liberti - library librari - libya libya - licence licenc - licens licen - license licens - licentious licenti - lichas licha - licio licio - lick lick - licked lick - licker licker - lictors lictor - lid lid - lids lid - lie lie - lied li - lief lief - liefest liefest - liege lieg - liegeman liegeman - liegemen liegemen - lien lien - lies li - liest liest - lieth lieth - lieu lieu - lieutenant lieuten - lieutenantry lieutenantri - lieutenants lieuten - lieve liev - life life - lifeblood lifeblood - lifeless lifeless - lifelings lifel - lift lift - lifted lift - lifter lifter - lifteth lifteth - lifting lift - lifts lift - lig lig - ligarius ligariu - liggens liggen - light light - lighted light - lighten lighten - lightens lighten - lighter lighter - lightest lightest - lightly lightli - lightness light - lightning lightn - lightnings lightn - lights light - lik lik - like like - liked like - likeliest likeliest - likelihood likelihood - likelihoods likelihood - likely like - likeness like - liker liker - likes like - likest likest - likewise likewis - liking like - likings like - lilies lili - lily lili - lim lim - limander limand - limb limb - limbeck limbeck - limbecks limbeck - limber limber - limbo limbo - limbs limb - lime lime - limed lime - limehouse limehous - limekilns limekiln - limit limit - limitation limit - limited limit - limits limit - limn limn - limp limp - limping limp - limps limp - lin lin - lincoln lincoln - lincolnshire lincolnshir - line line - lineal lineal - lineally lineal - lineament lineament - lineaments lineament - lined line - linen linen - linens linen - lines line - ling ling - lingare lingar - linger linger - lingered linger - lingers linger - linguist linguist - lining line - link link - links link - linsey linsei - linstock linstock - linta linta - lion lion - lionel lionel - lioness lioness - lions lion - lip lip - lipp lipp - lips lip - lipsbury lipsburi - liquid liquid - liquor liquor - liquorish liquorish - liquors liquor - lirra lirra - lisbon lisbon - lisp lisp - lisping lisp - list list - listen listen - listening listen - lists list - literatured literatur - lither lither - litter litter - little littl - littlest littlest - liv liv - live live - lived live - livelier liveli - livelihood livelihood - livelong livelong - lively live - liver liver - liveries liveri - livers liver - livery liveri - lives live - livest livest - liveth liveth - livia livia - living live - livings live - lizard lizard - lizards lizard - ll ll - lll lll - llous llou - lnd lnd - lo lo - loa loa - loach loach - load load - loaden loaden - loading load - loads load - loaf loaf - loam loam - loan loan - loath loath - loathe loath - loathed loath - loather loather - loathes loath - loathing loath - loathly loathli - loathness loath - loathsome loathsom - loathsomeness loathsom - loathsomest loathsomest - loaves loav - lob lob - lobbies lobbi - lobby lobbi - local local - lochaber lochab - lock lock - locked lock - locking lock - lockram lockram - locks lock - locusts locust - lode lode - lodg lodg - lodge lodg - lodged lodg - lodgers lodger - lodges lodg - lodging lodg - lodgings lodg - lodovico lodovico - lodowick lodowick - lofty lofti - log log - logger logger - loggerhead loggerhead - loggerheads loggerhead - loggets logget - logic logic - logs log - loins loin - loiter loiter - loiterer loiter - loiterers loiter - loitering loiter - lolling loll - lolls loll - lombardy lombardi - london london - londoners london - lone lone - loneliness loneli - lonely lone - long long - longaville longavil - longboat longboat - longed long - longer longer - longest longest - longeth longeth - longing long - longings long - longly longli - longs long - longtail longtail - loo loo - loof loof - look look - looked look - looker looker - lookers looker - lookest lookest - looking look - looks look - loon loon - loop loop - loos loo - loose loos - loosed loos - loosely loos - loosen loosen - loosing loos - lop lop - lopp lopp - loquitur loquitur - lord lord - lorded lord - lording lord - lordings lord - lordliness lordli - lordly lordli - lords lord - lordship lordship - lordships lordship - lorenzo lorenzo - lorn lorn - lorraine lorrain - lorship lorship - los lo - lose lose - loser loser - losers loser - loses lose - losest losest - loseth loseth - losing lose - loss loss - losses loss - lost lost - lot lot - lots lot - lott lott - lottery lotteri - loud loud - louder louder - loudly loudli - lour lour - loureth loureth - louring lour - louse lous - louses lous - lousy lousi - lout lout - louted lout - louts lout - louvre louvr - lov lov - love love - loved love - lovedst lovedst - lovel lovel - lovelier loveli - loveliness loveli - lovell lovel - lovely love - lover lover - lovered lover - lovers lover - loves love - lovest lovest - loveth loveth - loving love - lovingly lovingli - low low - lowe low - lower lower - lowest lowest - lowing low - lowliness lowli - lowly lowli - lown lown - lowness low - loyal loyal - loyally loyal - loyalties loyalti - loyalty loyalti - lozel lozel - lt lt - lubber lubber - lubberly lubberli - luc luc - luccicos luccico - luce luce - lucentio lucentio - luces luce - lucetta lucetta - luciana luciana - lucianus lucianu - lucifer lucif - lucifier lucifi - lucilius luciliu - lucina lucina - lucio lucio - lucius luciu - luck luck - luckier luckier - luckiest luckiest - luckily luckili - luckless luckless - lucky lucki - lucre lucr - lucrece lucrec - lucretia lucretia - lucullius luculliu - lucullus lucullu - lucy luci - lud lud - ludlow ludlow - lug lug - lugg lugg - luggage luggag - luke luke - lukewarm lukewarm - lull lull - lulla lulla - lullaby lullabi - lulls lull - lumbert lumbert - lump lump - lumpish lumpish - luna luna - lunacies lunaci - lunacy lunaci - lunatic lunat - lunatics lunat - lunes lune - lungs lung - lupercal luperc - lurch lurch - lure lure - lurk lurk - lurketh lurketh - lurking lurk - lurks lurk - luscious lusciou - lush lush - lust lust - lusted lust - luster luster - lustful lust - lustier lustier - lustiest lustiest - lustig lustig - lustihood lustihood - lustily lustili - lustre lustr - lustrous lustrou - lusts lust - lusty lusti - lute lute - lutes lute - lutestring lutestr - lutheran lutheran - luxurious luxuri - luxuriously luxuri - luxury luxuri - ly ly - lycaonia lycaonia - lycurguses lycurgus - lydia lydia - lye lye - lyen lyen - lying ly - lym lym - lymoges lymog - lynn lynn - lysander lysand - m m - ma ma - maan maan - mab mab - macbeth macbeth - maccabaeus maccabaeu - macdonwald macdonwald - macduff macduff - mace mace - macedon macedon - maces mace - machiavel machiavel - machination machin - machinations machin - machine machin - mack mack - macmorris macmorri - maculate macul - maculation macul - mad mad - madam madam - madame madam - madams madam - madcap madcap - madded mad - madding mad - made made - madeira madeira - madly madli - madman madman - madmen madmen - madness mad - madonna madonna - madrigals madrig - mads mad - maecenas maecena - maggot maggot - maggots maggot - magic magic - magical magic - magician magician - magistrate magistr - magistrates magistr - magnanimity magnanim - magnanimous magnanim - magni magni - magnifi magnifi - magnificence magnific - magnificent magnific - magnifico magnifico - magnificoes magnifico - magnus magnu - mahomet mahomet - mahu mahu - maid maid - maiden maiden - maidenhead maidenhead - maidenheads maidenhead - maidenhood maidenhood - maidenhoods maidenhood - maidenliest maidenliest - maidenly maidenli - maidens maiden - maidhood maidhood - maids maid - mail mail - mailed mail - mails mail - maim maim - maimed maim - maims maim - main main - maincourse maincours - maine main - mainly mainli - mainmast mainmast - mains main - maintain maintain - maintained maintain - maintains maintain - maintenance mainten - mais mai - maison maison - majestas majesta - majestee majeste - majestic majest - majestical majest - majestically majest - majesties majesti - majesty majesti - major major - majority major - mak mak - make make - makeless makeless - maker maker - makers maker - makes make - makest makest - maketh maketh - making make - makings make - mal mal - mala mala - maladies maladi - malady maladi - malapert malapert - malcolm malcolm - malcontent malcont - malcontents malcont - male male - maledictions maledict - malefactions malefact - malefactor malefactor - malefactors malefactor - males male - malevolence malevol - malevolent malevol - malhecho malhecho - malice malic - malicious malici - maliciously malici - malign malign - malignancy malign - malignant malign - malignantly malignantli - malkin malkin - mall mall - mallard mallard - mallet mallet - mallows mallow - malmsey malmsei - malt malt - maltworms maltworm - malvolio malvolio - mamillius mamilliu - mammering mammer - mammet mammet - mammets mammet - mammock mammock - man man - manacle manacl - manacles manacl - manage manag - managed manag - manager manag - managing manag - manakin manakin - manchus manchu - mandate mandat - mandragora mandragora - mandrake mandrak - mandrakes mandrak - mane mane - manent manent - manes mane - manet manet - manfully manfulli - mangle mangl - mangled mangl - mangles mangl - mangling mangl - mangy mangi - manhood manhood - manhoods manhood - manifest manifest - manifested manifest - manifests manifest - manifold manifold - manifoldly manifoldli - manka manka - mankind mankind - manlike manlik - manly manli - mann mann - manna manna - manner manner - mannerly mannerli - manners manner - manningtree manningtre - mannish mannish - manor manor - manors manor - mans man - mansion mansion - mansionry mansionri - mansions mansion - manslaughter manslaught - mantle mantl - mantled mantl - mantles mantl - mantua mantua - mantuan mantuan - manual manual - manure manur - manured manur - manus manu - many mani - map map - mapp mapp - maps map - mar mar - marble marbl - marbled marbl - marcade marcad - marcellus marcellu - march march - marches march - marcheth marcheth - marching march - marchioness marchio - marchpane marchpan - marcians marcian - marcius marciu - marcus marcu - mardian mardian - mare mare - mares mare - marg marg - margarelon margarelon - margaret margaret - marge marg - margent margent - margery margeri - maria maria - marian marian - mariana mariana - maries mari - marigold marigold - mariner marin - mariners marin - maritime maritim - marjoram marjoram - mark mark - marked mark - market market - marketable market - marketplace marketplac - markets market - marking mark - markman markman - marks mark - marl marl - marle marl - marmoset marmoset - marquess marquess - marquis marqui - marr marr - marriage marriag - marriages marriag - married marri - marries marri - marring mar - marrow marrow - marrowless marrowless - marrows marrow - marry marri - marrying marri - mars mar - marseilles marseil - marsh marsh - marshal marshal - marshalsea marshalsea - marshalship marshalship - mart mart - marted mart - martem martem - martext martext - martial martial - martin martin - martino martino - martius martiu - martlemas martlema - martlet martlet - marts mart - martyr martyr - martyrs martyr - marullus marullu - marv marv - marvel marvel - marvell marvel - marvellous marvel - marvellously marvel - marvels marvel - mary mari - mas ma - masculine masculin - masham masham - mask mask - masked mask - masker masker - maskers masker - masking mask - masks mask - mason mason - masonry masonri - masons mason - masque masqu - masquers masquer - masques masqu - masquing masqu - mass mass - massacre massacr - massacres massacr - masses mass - massy massi - mast mast - mastcr mastcr - master master - masterdom masterdom - masterest masterest - masterless masterless - masterly masterli - masterpiece masterpiec - masters master - mastership mastership - mastic mastic - mastiff mastiff - mastiffs mastiff - masts mast - match match - matches match - matcheth matcheth - matching match - matchless matchless - mate mate - mated mate - mater mater - material materi - mates mate - mathematics mathemat - matin matin - matron matron - matrons matron - matter matter - matters matter - matthew matthew - mattock mattock - mattress mattress - mature matur - maturity matur - maud maud - maudlin maudlin - maugre maugr - maul maul - maund maund - mauri mauri - mauritania mauritania - mauvais mauvai - maw maw - maws maw - maxim maxim - may mai - mayday maydai - mayest mayest - mayor mayor - maypole maypol - mayst mayst - maz maz - maze maze - mazed maze - mazes maze - mazzard mazzard - me me - meacock meacock - mead mead - meadow meadow - meadows meadow - meads mead - meagre meagr - meal meal - meals meal - mealy meali - mean mean - meanders meander - meaner meaner - meanest meanest - meaneth meaneth - meaning mean - meanings mean - meanly meanli - means mean - meant meant - meantime meantim - meanwhile meanwhil - measles measl - measur measur - measurable measur - measure measur - measured measur - measureless measureless - measures measur - measuring measur - meat meat - meats meat - mechanic mechan - mechanical mechan - mechanicals mechan - mechanics mechan - mechante mechant - med med - medal medal - meddle meddl - meddler meddler - meddling meddl - mede mede - medea medea - media media - mediation mediat - mediators mediat - medice medic - medicinal medicin - medicine medicin - medicines medicin - meditate medit - meditates medit - meditating medit - meditation medit - meditations medit - mediterranean mediterranean - mediterraneum mediterraneum - medlar medlar - medlars medlar - meed meed - meeds meed - meek meek - meekly meekli - meekness meek - meet meet - meeter meeter - meetest meetest - meeting meet - meetings meet - meetly meetli - meetness meet - meets meet - meg meg - mehercle mehercl - meilleur meilleur - meiny meini - meisen meisen - melancholies melancholi - melancholy melancholi - melford melford - mell mell - mellifluous melliflu - mellow mellow - mellowing mellow - melodious melodi - melody melodi - melt melt - melted melt - melteth melteth - melting melt - melts melt - melun melun - member member - members member - memento memento - memorable memor - memorandums memorandum - memorial memori - memorials memori - memories memori - memoriz memoriz - memorize memor - memory memori - memphis memphi - men men - menac menac - menace menac - menaces menac - menaphon menaphon - menas mena - mend mend - mended mend - mender mender - mending mend - mends mend - menecrates menecr - menelaus menelau - menenius meneniu - mental mental - menteith menteith - mention mention - mentis menti - menton menton - mephostophilus mephostophilu - mer mer - mercatante mercatant - mercatio mercatio - mercenaries mercenari - mercenary mercenari - mercer mercer - merchandise merchandis - merchandized merchand - merchant merchant - merchants merchant - mercies merci - merciful merci - mercifully mercifulli - merciless merciless - mercurial mercuri - mercuries mercuri - mercury mercuri - mercutio mercutio - mercy merci - mere mere - mered mere - merely mere - merest merest - meridian meridian - merit merit - merited merit - meritorious meritori - merits merit - merlin merlin - mermaid mermaid - mermaids mermaid - merops merop - merrier merrier - merriest merriest - merrily merrili - merriman merriman - merriment merriment - merriments merriment - merriness merri - merry merri - mervailous mervail - mes me - mesh mesh - meshes mesh - mesopotamia mesopotamia - mess mess - message messag - messages messag - messala messala - messaline messalin - messenger messeng - messengers messeng - messes mess - messina messina - met met - metal metal - metals metal - metamorphis metamorphi - metamorphoses metamorphos - metaphor metaphor - metaphysical metaphys - metaphysics metaphys - mete mete - metellus metellu - meteor meteor - meteors meteor - meteyard meteyard - metheglin metheglin - metheglins metheglin - methink methink - methinks methink - method method - methods method - methought methought - methoughts methought - metre metr - metres metr - metropolis metropoli - mette mett - mettle mettl - mettled mettl - meus meu - mew mew - mewed mew - mewling mewl - mexico mexico - mi mi - mice mice - michael michael - michaelmas michaelma - micher micher - miching mich - mickle mickl - microcosm microcosm - mid mid - midas mida - middest middest - middle middl - middleham middleham - midnight midnight - midriff midriff - midst midst - midsummer midsumm - midway midwai - midwife midwif - midwives midwiv - mienne mienn - might might - mightful might - mightier mightier - mightiest mightiest - mightily mightili - mightiness mighti - mightst mightst - mighty mighti - milan milan - milch milch - mild mild - milder milder - mildest mildest - mildew mildew - mildews mildew - mildly mildli - mildness mild - mile mile - miles mile - milford milford - militarist militarist - military militari - milk milk - milking milk - milkmaid milkmaid - milks milk - milksops milksop - milky milki - mill mill - mille mill - miller miller - milliner millin - million million - millioned million - millions million - mills mill - millstones millston - milo milo - mimic mimic - minc minc - mince minc - minces minc - mincing minc - mind mind - minded mind - minding mind - mindless mindless - minds mind - mine mine - mineral miner - minerals miner - minerva minerva - mines mine - mingle mingl - mingled mingl - mingling mingl - minikin minikin - minim minim - minime minim - minimo minimo - minimus minimu - mining mine - minion minion - minions minion - minist minist - minister minist - ministers minist - ministration ministr - minnow minnow - minnows minnow - minola minola - minority minor - minos mino - minotaurs minotaur - minstrel minstrel - minstrels minstrel - minstrelsy minstrelsi - mint mint - mints mint - minute minut - minutely minut - minutes minut - minx minx - mio mio - mir mir - mirable mirabl - miracle miracl - miracles miracl - miraculous miracul - miranda miranda - mire mire - mirror mirror - mirrors mirror - mirth mirth - mirthful mirth - miry miri - mis mi - misadventur misadventur - misadventure misadventur - misanthropos misanthropo - misapplied misappli - misbecame misbecam - misbecom misbecom - misbecome misbecom - misbegot misbegot - misbegotten misbegotten - misbeliever misbeliev - misbelieving misbeliev - misbhav misbhav - miscall miscal - miscalled miscal - miscarried miscarri - miscarries miscarri - miscarry miscarri - miscarrying miscarri - mischance mischanc - mischances mischanc - mischief mischief - mischiefs mischief - mischievous mischiev - misconceived misconceiv - misconst misconst - misconster misconst - misconstruction misconstruct - misconstrued misconstru - misconstrues misconstru - miscreant miscreant - miscreate miscreat - misdeed misde - misdeeds misde - misdemean misdemean - misdemeanours misdemeanour - misdoubt misdoubt - misdoubteth misdoubteth - misdoubts misdoubt - misenum misenum - miser miser - miserable miser - miserably miser - misericorde misericord - miseries miseri - misers miser - misery miseri - misfortune misfortun - misfortunes misfortun - misgive misgiv - misgives misgiv - misgiving misgiv - misgoverned misgovern - misgovernment misgovern - misgraffed misgraf - misguide misguid - mishap mishap - mishaps mishap - misheard misheard - misinterpret misinterpret - mislead mislead - misleader mislead - misleaders mislead - misleading mislead - misled misl - mislike mislik - misord misord - misplac misplac - misplaced misplac - misplaces misplac - mispris mispri - misprised mispris - misprision mispris - misprizing mispriz - misproud misproud - misquote misquot - misreport misreport - miss miss - missed miss - misses miss - misshap misshap - misshapen misshapen - missheathed missheath - missing miss - missingly missingli - missions mission - missive missiv - missives missiv - misspoke misspok - mist mist - mista mista - mistak mistak - mistake mistak - mistaken mistaken - mistakes mistak - mistaketh mistaketh - mistaking mistak - mistakings mistak - mistemp mistemp - mistempered mistemp - misterm misterm - mistful mist - misthink misthink - misthought misthought - mistletoe mistleto - mistook mistook - mistreadings mistread - mistress mistress - mistresses mistress - mistresss mistresss - mistriship mistriship - mistrust mistrust - mistrusted mistrust - mistrustful mistrust - mistrusting mistrust - mists mist - misty misti - misus misu - misuse misus - misused misus - misuses misus - mites mite - mithridates mithrid - mitigate mitig - mitigation mitig - mix mix - mixed mix - mixture mixtur - mixtures mixtur - mm mm - mnd mnd - moan moan - moans moan - moat moat - moated moat - mobled mobl - mock mock - mockable mockabl - mocker mocker - mockeries mockeri - mockers mocker - mockery mockeri - mocking mock - mocks mock - mockvater mockvat - mockwater mockwat - model model - modena modena - moderate moder - moderately moder - moderation moder - modern modern - modest modest - modesties modesti - modestly modestli - modesty modesti - modicums modicum - modo modo - module modul - moe moe - moi moi - moiety moieti - moist moist - moisten moisten - moisture moistur - moldwarp moldwarp - mole mole - molehill molehil - moles mole - molest molest - molestation molest - mollification mollif - mollis molli - molten molten - molto molto - mome mome - moment moment - momentary momentari - moming mome - mon mon - monachum monachum - monarch monarch - monarchies monarchi - monarchize monarch - monarcho monarcho - monarchs monarch - monarchy monarchi - monast monast - monastery monasteri - monastic monast - monday mondai - monde mond - money monei - moneys monei - mong mong - monger monger - mongers monger - monging mong - mongrel mongrel - mongrels mongrel - mongst mongst - monk monk - monkey monkei - monkeys monkei - monks monk - monmouth monmouth - monopoly monopoli - mons mon - monsieur monsieur - monsieurs monsieur - monster monster - monsters monster - monstrous monstrou - monstrously monstrous - monstrousness monstrous - monstruosity monstruos - montacute montacut - montage montag - montague montagu - montagues montagu - montano montano - montant montant - montez montez - montferrat montferrat - montgomery montgomeri - month month - monthly monthli - months month - montjoy montjoi - monument monument - monumental monument - monuments monument - mood mood - moods mood - moody moodi - moon moon - moonbeams moonbeam - moonish moonish - moonlight moonlight - moons moon - moonshine moonshin - moonshines moonshin - moor moor - moorfields moorfield - moors moor - moorship moorship - mop mop - mope mope - moping mope - mopping mop - mopsa mopsa - moral moral - moraler moral - morality moral - moralize moral - mordake mordak - more more - moreover moreov - mores more - morgan morgan - mori mori - morisco morisco - morn morn - morning morn - mornings morn - morocco morocco - morris morri - morrow morrow - morrows morrow - morsel morsel - morsels morsel - mort mort - mortal mortal - mortality mortal - mortally mortal - mortals mortal - mortar mortar - mortgaged mortgag - mortified mortifi - mortifying mortifi - mortimer mortim - mortimers mortim - mortis morti - mortise mortis - morton morton - mose mose - moss moss - mossgrown mossgrown - most most - mote mote - moth moth - mother mother - mothers mother - moths moth - motion motion - motionless motionless - motions motion - motive motiv - motives motiv - motley motlei - mots mot - mought mought - mould mould - moulded mould - mouldeth mouldeth - moulds mould - mouldy mouldi - moult moult - moulten moulten - mounch mounch - mounseur mounseur - mounsieur mounsieur - mount mount - mountain mountain - mountaineer mountain - mountaineers mountain - mountainous mountain - mountains mountain - mountant mountant - mountanto mountanto - mountebank mountebank - mountebanks mountebank - mounted mount - mounteth mounteth - mounting mount - mounts mount - mourn mourn - mourned mourn - mourner mourner - mourners mourner - mournful mourn - mournfully mournfulli - mourning mourn - mourningly mourningli - mournings mourn - mourns mourn - mous mou - mouse mous - mousetrap mousetrap - mousing mous - mouth mouth - mouthed mouth - mouths mouth - mov mov - movables movabl - move move - moveable moveabl - moveables moveabl - moved move - mover mover - movers mover - moves move - moveth moveth - moving move - movingly movingli - movousus movousu - mow mow - mowbray mowbrai - mower mower - mowing mow - mows mow - moy moi - moys moi - moyses moys - mrs mr - much much - muck muck - mud mud - mudded mud - muddied muddi - muddy muddi - muffins muffin - muffl muffl - muffle muffl - muffled muffl - muffler muffler - muffling muffl - mugger mugger - mugs mug - mulberries mulberri - mulberry mulberri - mule mule - mules mule - muleteers mulet - mulier mulier - mulieres mulier - muliteus muliteu - mull mull - mulmutius mulmutiu - multiplied multipli - multiply multipli - multiplying multipli - multipotent multipot - multitude multitud - multitudes multitud - multitudinous multitudin - mum mum - mumble mumbl - mumbling mumbl - mummers mummer - mummy mummi - mun mun - munch munch - muniments muniment - munition munit - murd murd - murder murder - murdered murder - murderer murder - murderers murder - murdering murder - murderous murder - murders murder - mure mure - murk murk - murkiest murkiest - murky murki - murmur murmur - murmurers murmur - murmuring murmur - murrain murrain - murray murrai - murrion murrion - murther murther - murtherer murther - murtherers murther - murthering murther - murtherous murther - murthers murther - mus mu - muscadel muscadel - muscovites muscovit - muscovits muscovit - muscovy muscovi - muse muse - muses muse - mush mush - mushrooms mushroom - music music - musical music - musician musician - musicians musician - musics music - musing muse - musings muse - musk musk - musket musket - muskets musket - muskos musko - muss muss - mussel mussel - mussels mussel - must must - mustachio mustachio - mustard mustard - mustardseed mustardse - muster muster - mustering muster - musters muster - musty musti - mutability mutabl - mutable mutabl - mutation mutat - mutations mutat - mute mute - mutes mute - mutest mutest - mutine mutin - mutineer mutin - mutineers mutin - mutines mutin - mutinies mutini - mutinous mutin - mutiny mutini - mutius mutiu - mutter mutter - muttered mutter - mutton mutton - muttons mutton - mutual mutual - mutualities mutual - mutually mutual - muzzl muzzl - muzzle muzzl - muzzled muzzl - mv mv - mww mww - my my - mynheers mynheer - myrmidon myrmidon - myrmidons myrmidon - myrtle myrtl - myself myself - myst myst - mysteries mysteri - mystery mysteri - n n - nag nag - nage nage - nags nag - naiads naiad - nail nail - nails nail - nak nak - naked nake - nakedness naked - nal nal - nam nam - name name - named name - nameless nameless - namely name - names name - namest namest - naming name - nan nan - nance nanc - nap nap - nape nape - napes nape - napkin napkin - napkins napkin - naples napl - napless napless - napping nap - naps nap - narbon narbon - narcissus narcissu - narines narin - narrow narrow - narrowly narrowli - naso naso - nasty nasti - nathaniel nathaniel - natifs natif - nation nation - nations nation - native nativ - nativity nativ - natur natur - natural natur - naturalize natur - naturally natur - nature natur - natured natur - natures natur - natus natu - naught naught - naughtily naughtili - naughty naughti - navarre navarr - nave nave - navel navel - navigation navig - navy navi - nay nai - nayward nayward - nayword nayword - nazarite nazarit - ne ne - neaf neaf - neamnoins neamnoin - neanmoins neanmoin - neapolitan neapolitan - neapolitans neapolitan - near near - nearer nearer - nearest nearest - nearly nearli - nearness near - neat neat - neatly neatli - neb neb - nebour nebour - nebuchadnezzar nebuchadnezzar - nec nec - necessaries necessari - necessarily necessarili - necessary necessari - necessitied necess - necessities necess - necessity necess - neck neck - necklace necklac - necks neck - nectar nectar - ned ned - nedar nedar - need need - needed need - needer needer - needful need - needfull needful - needing need - needle needl - needles needl - needless needless - needly needli - needs need - needy needi - neer neer - neeze neez - nefas nefa - negation negat - negative neg - negatives neg - neglect neglect - neglected neglect - neglecting neglect - neglectingly neglectingli - neglection neglect - negligence neglig - negligent neglig - negotiate negoti - negotiations negoti - negro negro - neigh neigh - neighbors neighbor - neighbour neighbour - neighbourhood neighbourhood - neighbouring neighbour - neighbourly neighbourli - neighbours neighbour - neighing neigh - neighs neigh - neither neither - nell nell - nemean nemean - nemesis nemesi - neoptolemus neoptolemu - nephew nephew - nephews nephew - neptune neptun - ner ner - nereides nereid - nerissa nerissa - nero nero - neroes nero - ners ner - nerve nerv - nerves nerv - nervii nervii - nervy nervi - nessus nessu - nest nest - nestor nestor - nests nest - net net - nether nether - netherlands netherland - nets net - nettle nettl - nettled nettl - nettles nettl - neuter neuter - neutral neutral - nev nev - never never - nevil nevil - nevils nevil - new new - newborn newborn - newer newer - newest newest - newgate newgat - newly newli - newness new - news new - newsmongers newsmong - newt newt - newts newt - next next - nibbling nibbl - nicanor nicanor - nice nice - nicely nice - niceness nice - nicer nicer - nicety niceti - nicholas nichola - nick nick - nickname nicknam - nicks nick - niece niec - nieces niec - niggard niggard - niggarding niggard - niggardly niggardli - nigh nigh - night night - nightcap nightcap - nightcaps nightcap - nighted night - nightgown nightgown - nightingale nightingal - nightingales nightingal - nightly nightli - nightmare nightmar - nights night - nightwork nightwork - nihil nihil - nile nile - nill nill - nilus nilu - nimble nimbl - nimbleness nimbl - nimbler nimbler - nimbly nimbl - nine nine - nineteen nineteen - ning ning - ningly ningli - ninny ninni - ninth ninth - ninus ninu - niobe niob - niobes niob - nip nip - nipp nipp - nipping nip - nipple nippl - nips nip - nit nit - nly nly - nnight nnight - nnights nnight - no no - noah noah - nob nob - nobility nobil - nobis nobi - noble nobl - nobleman nobleman - noblemen noblemen - nobleness nobl - nobler nobler - nobles nobl - noblesse nobless - noblest noblest - nobly nobli - nobody nobodi - noces noce - nod nod - nodded nod - nodding nod - noddle noddl - noddles noddl - noddy noddi - nods nod - noes noe - nointed noint - nois noi - noise nois - noiseless noiseless - noisemaker noisemak - noises nois - noisome noisom - nole nole - nominate nomin - nominated nomin - nomination nomin - nominativo nominativo - non non - nonage nonag - nonce nonc - none none - nonino nonino - nonny nonni - nonpareil nonpareil - nonsuits nonsuit - nony noni - nook nook - nooks nook - noon noon - noonday noondai - noontide noontid - nor nor - norbery norberi - norfolk norfolk - norman norman - normandy normandi - normans norman - north north - northampton northampton - northamptonshire northamptonshir - northerly northerli - northern northern - northgate northgat - northumberland northumberland - northumberlands northumberland - northward northward - norway norwai - norways norwai - norwegian norwegian - norweyan norweyan - nos no - nose nose - nosegays nosegai - noseless noseless - noses nose - noster noster - nostra nostra - nostril nostril - nostrils nostril - not not - notable notabl - notably notabl - notary notari - notch notch - note note - notebook notebook - noted note - notedly notedli - notes note - notest notest - noteworthy noteworthi - nothing noth - nothings noth - notice notic - notify notifi - noting note - notion notion - notorious notori - notoriously notori - notre notr - notwithstanding notwithstand - nought nought - noun noun - nouns noun - nourish nourish - nourished nourish - nourisher nourish - nourishes nourish - nourisheth nourisheth - nourishing nourish - nourishment nourish - nous nou - novel novel - novelties novelti - novelty novelti - noverbs noverb - novi novi - novice novic - novices novic - novum novum - now now - nowhere nowher - noyance noyanc - ns ns - nt nt - nubibus nubibu - numa numa - numb numb - number number - numbered number - numbering number - numberless numberless - numbers number - numbness numb - nun nun - nuncio nuncio - nuncle nuncl - nunnery nunneri - nuns nun - nuntius nuntiu - nuptial nuptial - nurs nur - nurse nurs - nursed nurs - nurser nurser - nursery nurseri - nurses nurs - nurseth nurseth - nursh nursh - nursing nurs - nurtur nurtur - nurture nurtur - nut nut - nuthook nuthook - nutmeg nutmeg - nutmegs nutmeg - nutriment nutriment - nuts nut - nutshell nutshel - ny ny - nym nym - nymph nymph - nymphs nymph - o o - oak oak - oaken oaken - oaks oak - oared oar - oars oar - oatcake oatcak - oaten oaten - oath oath - oathable oathabl - oaths oath - oats oat - ob ob - obduracy obduraci - obdurate obdur - obedience obedi - obedient obedi - obeisance obeis - oberon oberon - obey obei - obeyed obei - obeying obei - obeys obei - obidicut obidicut - object object - objected object - objections object - objects object - oblation oblat - oblations oblat - obligation oblig - obligations oblig - obliged oblig - oblique obliqu - oblivion oblivion - oblivious oblivi - obloquy obloqui - obscene obscen - obscenely obscen - obscur obscur - obscure obscur - obscured obscur - obscurely obscur - obscures obscur - obscuring obscur - obscurity obscur - obsequies obsequi - obsequious obsequi - obsequiously obsequi - observ observ - observance observ - observances observ - observancy observ - observant observ - observants observ - observation observ - observe observ - observed observ - observer observ - observers observ - observing observ - observingly observingli - obsque obsqu - obstacle obstacl - obstacles obstacl - obstinacy obstinaci - obstinate obstin - obstinately obstin - obstruct obstruct - obstruction obstruct - obstructions obstruct - obtain obtain - obtained obtain - obtaining obtain - occasion occas - occasions occas - occident occid - occidental occident - occulted occult - occupat occupat - occupation occup - occupations occup - occupied occupi - occupies occupi - occupy occupi - occurrence occurr - occurrences occurr - occurrents occurr - ocean ocean - oceans ocean - octavia octavia - octavius octaviu - ocular ocular - od od - odd odd - oddest oddest - oddly oddli - odds odd - ode od - odes od - odious odiou - odoriferous odorifer - odorous odor - odour odour - odours odour - ods od - oeillades oeillad - oes oe - oeuvres oeuvr - of of - ofephesus ofephesu - off off - offal offal - offence offenc - offenceful offenc - offences offenc - offend offend - offended offend - offendendo offendendo - offender offend - offenders offend - offendeth offendeth - offending offend - offendress offendress - offends offend - offense offens - offenseless offenseless - offenses offens - offensive offens - offer offer - offered offer - offering offer - offerings offer - offers offer - offert offert - offic offic - office offic - officed offic - officer offic - officers offic - offices offic - official offici - officious offici - offspring offspr - oft oft - often often - oftener often - oftentimes oftentim - oh oh - oil oil - oils oil - oily oili - old old - oldcastle oldcastl - olden olden - older older - oldest oldest - oldness old - olive oliv - oliver oliv - olivers oliv - olives oliv - olivia olivia - olympian olympian - olympus olympu - oman oman - omans oman - omen omen - ominous omin - omission omiss - omit omit - omittance omitt - omitted omit - omitting omit - omne omn - omnes omn - omnipotent omnipot - on on - once onc - one on - ones on - oneyers oney - ongles ongl - onion onion - onions onion - only onli - onset onset - onward onward - onwards onward - oo oo - ooze ooz - oozes ooz - oozy oozi - op op - opal opal - ope op - open open - opener open - opening open - openly openli - openness open - opens open - operant oper - operate oper - operation oper - operations oper - operative oper - opes op - oph oph - ophelia ophelia - opinion opinion - opinions opinion - opportune opportun - opportunities opportun - opportunity opportun - oppos oppo - oppose oppos - opposed oppos - opposeless opposeless - opposer oppos - opposers oppos - opposes oppos - opposing oppos - opposite opposit - opposites opposit - opposition opposit - oppositions opposit - oppress oppress - oppressed oppress - oppresses oppress - oppresseth oppresseth - oppressing oppress - oppression oppress - oppressor oppressor - opprest opprest - opprobriously opprobri - oppugnancy oppugn - opulency opul - opulent opul - or or - oracle oracl - oracles oracl - orange orang - oration orat - orator orat - orators orat - oratory oratori - orb orb - orbed orb - orbs orb - orchard orchard - orchards orchard - ord ord - ordain ordain - ordained ordain - ordaining ordain - order order - ordered order - ordering order - orderless orderless - orderly orderli - orders order - ordinance ordin - ordinant ordin - ordinaries ordinari - ordinary ordinari - ordnance ordnanc - ords ord - ordure ordur - ore or - organ organ - organs organ - orgillous orgil - orient orient - orifex orifex - origin origin - original origin - orisons orison - ork ork - orlando orlando - orld orld - orleans orlean - ornament ornament - ornaments ornament - orodes orod - orphan orphan - orphans orphan - orpheus orpheu - orsino orsino - ort ort - orthography orthographi - orts ort - oscorbidulchos oscorbidulcho - osier osier - osiers osier - osprey osprei - osr osr - osric osric - ossa ossa - ost ost - ostent ostent - ostentare ostentar - ostentation ostent - ostents ostent - ostler ostler - ostlers ostler - ostrich ostrich - osw osw - oswald oswald - othello othello - other other - othergates otherg - others other - otherwhere otherwher - otherwhiles otherwhil - otherwise otherwis - otter otter - ottoman ottoman - ottomites ottomit - oublie oubli - ouches ouch - ought ought - oui oui - ounce ounc - ounces ounc - ouphes ouph - our our - ours our - ourself ourself - ourselves ourselv - ousel ousel - out out - outbids outbid - outbrave outbrav - outbraves outbrav - outbreak outbreak - outcast outcast - outcries outcri - outcry outcri - outdar outdar - outdare outdar - outdares outdar - outdone outdon - outfac outfac - outface outfac - outfaced outfac - outfacing outfac - outfly outfli - outfrown outfrown - outgo outgo - outgoes outgo - outgrown outgrown - outjest outjest - outlaw outlaw - outlawry outlawri - outlaws outlaw - outliv outliv - outlive outliv - outlives outliv - outliving outliv - outlook outlook - outlustres outlustr - outpriz outpriz - outrage outrag - outrageous outrag - outrages outrag - outran outran - outright outright - outroar outroar - outrun outrun - outrunning outrun - outruns outrun - outscold outscold - outscorn outscorn - outsell outsel - outsells outsel - outside outsid - outsides outsid - outspeaks outspeak - outsport outsport - outstare outstar - outstay outstai - outstood outstood - outstretch outstretch - outstretched outstretch - outstrike outstrik - outstrip outstrip - outstripped outstrip - outswear outswear - outvenoms outvenom - outward outward - outwardly outwardli - outwards outward - outwear outwear - outweighs outweigh - outwent outwent - outworn outworn - outworths outworth - oven oven - over over - overawe overaw - overbear overbear - overblown overblown - overboard overboard - overbold overbold - overborne overborn - overbulk overbulk - overbuys overbui - overcame overcam - overcast overcast - overcharg overcharg - overcharged overcharg - overcome overcom - overcomes overcom - overdone overdon - overearnest overearnest - overfar overfar - overflow overflow - overflown overflown - overglance overgl - overgo overgo - overgone overgon - overgorg overgorg - overgrown overgrown - overhead overhead - overhear overhear - overheard overheard - overhold overhold - overjoyed overjoi - overkind overkind - overland overland - overleather overleath - overlive overl - overlook overlook - overlooking overlook - overlooks overlook - overmaster overmast - overmounting overmount - overmuch overmuch - overpass overpass - overpeer overp - overpeering overp - overplus overplu - overrul overrul - overrun overrun - overscutch overscutch - overset overset - overshades overshad - overshine overshin - overshines overshin - overshot overshot - oversights oversight - overspread overspread - overstain overstain - overswear overswear - overt overt - overta overta - overtake overtak - overtaketh overtaketh - overthrow overthrow - overthrown overthrown - overthrows overthrow - overtook overtook - overtopp overtopp - overture overtur - overturn overturn - overwatch overwatch - overween overween - overweening overween - overweigh overweigh - overwhelm overwhelm - overwhelming overwhelm - overworn overworn - ovid ovid - ovidius ovidiu - ow ow - owe ow - owed ow - owedst owedst - owen owen - owes ow - owest owest - oweth oweth - owing ow - owl owl - owls owl - own own - owner owner - owners owner - owning own - owns own - owy owi - ox ox - oxen oxen - oxford oxford - oxfordshire oxfordshir - oxlips oxlip - oyes oy - oyster oyster - p p - pabble pabbl - pabylon pabylon - pac pac - pace pace - paced pace - paces pace - pacified pacifi - pacify pacifi - pacing pace - pack pack - packet packet - packets packet - packhorses packhors - packing pack - packings pack - packs pack - packthread packthread - pacorus pacoru - paction paction - pad pad - paddle paddl - paddling paddl - paddock paddock - padua padua - pagan pagan - pagans pagan - page page - pageant pageant - pageants pageant - pages page - pah pah - paid paid - pail pail - pailfuls pail - pails pail - pain pain - pained pain - painful pain - painfully painfulli - pains pain - paint paint - painted paint - painter painter - painting paint - paintings paint - paints paint - pair pair - paired pair - pairs pair - pajock pajock - pal pal - palabras palabra - palace palac - palaces palac - palamedes palamed - palate palat - palates palat - palatine palatin - palating palat - pale pale - paled pale - paleness pale - paler paler - pales pale - palestine palestin - palfrey palfrei - palfreys palfrei - palisadoes palisado - pall pall - pallabris pallabri - pallas palla - pallets pallet - palm palm - palmer palmer - palmers palmer - palms palm - palmy palmi - palpable palpabl - palsied palsi - palsies palsi - palsy palsi - palt palt - palter palter - paltry paltri - paly pali - pamp pamp - pamper pamper - pamphlets pamphlet - pan pan - pancackes pancack - pancake pancak - pancakes pancak - pandar pandar - pandars pandar - pandarus pandaru - pander pander - panderly panderli - panders pander - pandulph pandulph - panel panel - pang pang - panging pang - pangs pang - pannier pannier - pannonians pannonian - pansa pansa - pansies pansi - pant pant - pantaloon pantaloon - panted pant - pantheon pantheon - panther panther - panthino panthino - panting pant - pantingly pantingli - pantler pantler - pantry pantri - pants pant - pap pap - papal papal - paper paper - papers paper - paphlagonia paphlagonia - paphos papho - papist papist - paps pap - par par - parable parabl - paracelsus paracelsu - paradise paradis - paradox paradox - paradoxes paradox - paragon paragon - paragons paragon - parallel parallel - parallels parallel - paramour paramour - paramours paramour - parapets parapet - paraquito paraquito - parasite parasit - parasites parasit - parca parca - parcel parcel - parcell parcel - parcels parcel - parch parch - parched parch - parching parch - parchment parchment - pard pard - pardon pardon - pardona pardona - pardoned pardon - pardoner pardon - pardoning pardon - pardonne pardonn - pardonner pardonn - pardonnez pardonnez - pardons pardon - pare pare - pared pare - parel parel - parent parent - parentage parentag - parents parent - parfect parfect - paring pare - parings pare - paris pari - parish parish - parishioners parishion - parisians parisian - paritors paritor - park park - parks park - parle parl - parler parler - parles parl - parley parlei - parlez parlez - parliament parliament - parlors parlor - parlour parlour - parlous parlou - parmacity parmac - parolles parol - parricide parricid - parricides parricid - parrot parrot - parrots parrot - parsley parslei - parson parson - part part - partake partak - partaken partaken - partaker partak - partakers partak - parted part - parthia parthia - parthian parthian - parthians parthian - parti parti - partial partial - partialize partial - partially partial - participate particip - participation particip - particle particl - particular particular - particularities particular - particularize particular - particularly particularli - particulars particular - parties parti - parting part - partisan partisan - partisans partisan - partition partit - partizan partizan - partlet partlet - partly partli - partner partner - partners partner - partridge partridg - parts part - party parti - pas pa - pash pash - pashed pash - pashful pash - pass pass - passable passabl - passado passado - passage passag - passages passag - passant passant - passed pass - passenger passeng - passengers passeng - passes pass - passeth passeth - passing pass - passio passio - passion passion - passionate passion - passioning passion - passions passion - passive passiv - passport passport - passy passi - past past - paste past - pasterns pastern - pasties pasti - pastime pastim - pastimes pastim - pastoral pastor - pastorals pastor - pastors pastor - pastry pastri - pasture pastur - pastures pastur - pasty pasti - pat pat - patay patai - patch patch - patchery patcheri - patches patch - pate pate - pated pate - patent patent - patents patent - paternal patern - pates pate - path path - pathetical pathet - paths path - pathway pathwai - pathways pathwai - patience patienc - patient patient - patiently patient - patients patient - patines patin - patrician patrician - patricians patrician - patrick patrick - patrimony patrimoni - patroclus patroclu - patron patron - patronage patronag - patroness patro - patrons patron - patrum patrum - patter patter - pattern pattern - patterns pattern - pattle pattl - pauca pauca - paucas pauca - paul paul - paulina paulina - paunch paunch - paunches paunch - pause paus - pauser pauser - pauses paus - pausingly pausingli - pauvres pauvr - pav pav - paved pave - pavement pavement - pavilion pavilion - pavilions pavilion - pavin pavin - paw paw - pawn pawn - pawns pawn - paws paw - pax pax - pay pai - payest payest - paying pai - payment payment - payments payment - pays pai - paysan paysan - paysans paysan - pe pe - peace peac - peaceable peaceabl - peaceably peaceabl - peaceful peac - peacemakers peacemak - peaces peac - peach peach - peaches peach - peacock peacock - peacocks peacock - peak peak - peaking peak - peal peal - peals peal - pear pear - peard peard - pearl pearl - pearls pearl - pears pear - peas pea - peasant peasant - peasantry peasantri - peasants peasant - peascod peascod - pease peas - peaseblossom peaseblossom - peat peat - peaten peaten - peating peat - pebble pebbl - pebbled pebbl - pebbles pebbl - peck peck - pecks peck - peculiar peculiar - pecus pecu - pedant pedant - pedantical pedant - pedascule pedascul - pede pede - pedestal pedest - pedigree pedigre - pedlar pedlar - pedlars pedlar - pedro pedro - peds ped - peel peel - peep peep - peeped peep - peeping peep - peeps peep - peer peer - peereth peereth - peering peer - peerless peerless - peers peer - peesel peesel - peevish peevish - peevishly peevishli - peflur peflur - peg peg - pegasus pegasu - pegs peg - peise peis - peised peis - peize peiz - pelf pelf - pelican pelican - pelion pelion - pell pell - pella pella - pelleted pellet - peloponnesus peloponnesu - pelt pelt - pelting pelt - pembroke pembrok - pen pen - penalties penalti - penalty penalti - penance penanc - pence penc - pencil pencil - pencill pencil - pencils pencil - pendant pendant - pendent pendent - pendragon pendragon - pendulous pendul - penelope penelop - penetrable penetr - penetrate penetr - penetrative penetr - penitence penit - penitent penit - penitential penitenti - penitently penit - penitents penit - penker penker - penknife penknif - penn penn - penned pen - penning pen - pennons pennon - penny penni - pennyworth pennyworth - pennyworths pennyworth - pens pen - pense pens - pension pension - pensioners pension - pensive pensiv - pensived pensiv - pensively pensiv - pent pent - pentecost pentecost - penthesilea penthesilea - penthouse penthous - penurious penuri - penury penuri - peopl peopl - people peopl - peopled peopl - peoples peopl - pepin pepin - pepper pepper - peppercorn peppercorn - peppered pepper - per per - peradventure peradventur - peradventures peradventur - perceiv perceiv - perceive perceiv - perceived perceiv - perceives perceiv - perceiveth perceiveth - perch perch - perchance perchanc - percies perci - percussion percuss - percy perci - perdie perdi - perdita perdita - perdition perdit - perdonato perdonato - perdu perdu - perdurable perdur - perdurably perdur - perdy perdi - pere pere - peregrinate peregrin - peremptorily peremptorili - peremptory peremptori - perfect perfect - perfected perfect - perfecter perfect - perfectest perfectest - perfection perfect - perfections perfect - perfectly perfectli - perfectness perfect - perfidious perfidi - perfidiously perfidi - perforce perforc - perform perform - performance perform - performances perform - performed perform - performer perform - performers perform - performing perform - performs perform - perfum perfum - perfume perfum - perfumed perfum - perfumer perfum - perfumes perfum - perge perg - perhaps perhap - periapts periapt - perigort perigort - perigouna perigouna - peril peril - perilous peril - perils peril - period period - periods period - perish perish - perished perish - perishest perishest - perisheth perisheth - perishing perish - periwig periwig - perjur perjur - perjure perjur - perjured perjur - perjuries perjuri - perjury perjuri - perk perk - perkes perk - permafoy permafoi - permanent perman - permission permiss - permissive permiss - permit permit - permitted permit - pernicious pernici - perniciously pernici - peroration peror - perpend perpend - perpendicular perpendicular - perpendicularly perpendicularli - perpetual perpetu - perpetually perpetu - perpetuity perpetu - perplex perplex - perplexed perplex - perplexity perplex - pers per - persecuted persecut - persecutions persecut - persecutor persecutor - perseus perseu - persever persev - perseverance persever - persevers persev - persia persia - persian persian - persist persist - persisted persist - persistency persist - persistive persist - persists persist - person person - personae persona - personage personag - personages personag - personal person - personally person - personate person - personated person - personates person - personating person - persons person - perspective perspect - perspectively perspect - perspectives perspect - perspicuous perspicu - persuade persuad - persuaded persuad - persuades persuad - persuading persuad - persuasion persuas - persuasions persuas - pert pert - pertain pertain - pertaining pertain - pertains pertain - pertaunt pertaunt - pertinent pertin - pertly pertli - perturb perturb - perturbation perturb - perturbations perturb - perturbed perturb - perus peru - perusal perus - peruse perus - perused perus - perusing perus - perverse pervers - perversely pervers - perverseness pervers - pervert pervert - perverted pervert - peseech peseech - pest pest - pester pester - pestiferous pestifer - pestilence pestil - pestilent pestil - pet pet - petar petar - peter peter - petit petit - petition petit - petitionary petitionari - petitioner petition - petitioners petition - petitions petit - peto peto - petrarch petrarch - petruchio petruchio - petter petter - petticoat petticoat - petticoats petticoat - pettiness petti - pettish pettish - pettitoes pettito - petty petti - peu peu - pew pew - pewter pewter - pewterer pewter - phaethon phaethon - phaeton phaeton - phantasime phantasim - phantasimes phantasim - phantasma phantasma - pharamond pharamond - pharaoh pharaoh - pharsalia pharsalia - pheasant pheasant - pheazar pheazar - phebe phebe - phebes phebe - pheebus pheebu - pheeze pheez - phibbus phibbu - philadelphos philadelpho - philario philario - philarmonus philarmonu - philemon philemon - philip philip - philippan philippan - philippe philipp - philippi philippi - phillida phillida - philo philo - philomel philomel - philomela philomela - philosopher philosoph - philosophers philosoph - philosophical philosoph - philosophy philosophi - philostrate philostr - philotus philotu - phlegmatic phlegmat - phoebe phoeb - phoebus phoebu - phoenicia phoenicia - phoenicians phoenician - phoenix phoenix - phorbus phorbu - photinus photinu - phrase phrase - phraseless phraseless - phrases phrase - phrygia phrygia - phrygian phrygian - phrynia phrynia - physic physic - physical physic - physician physician - physicians physician - physics physic - pia pia - pibble pibbl - pible pibl - picardy picardi - pick pick - pickaxe pickax - pickaxes pickax - pickbone pickbon - picked pick - pickers picker - picking pick - pickle pickl - picklock picklock - pickpurse pickpurs - picks pick - pickt pickt - pickthanks pickthank - pictur pictur - picture pictur - pictured pictur - pictures pictur - pid pid - pie pie - piec piec - piece piec - pieces piec - piecing piec - pied pi - piedness pied - pier pier - pierc pierc - pierce pierc - pierced pierc - pierces pierc - pierceth pierceth - piercing pierc - piercy pierci - piers pier - pies pi - piety pieti - pig pig - pigeon pigeon - pigeons pigeon - pight pight - pigmy pigmi - pigrogromitus pigrogromitu - pike pike - pikes pike - pil pil - pilate pilat - pilates pilat - pilchers pilcher - pile pile - piles pile - pilf pilf - pilfering pilfer - pilgrim pilgrim - pilgrimage pilgrimag - pilgrims pilgrim - pill pill - pillage pillag - pillagers pillag - pillar pillar - pillars pillar - pillicock pillicock - pillory pillori - pillow pillow - pillows pillow - pills pill - pilot pilot - pilots pilot - pimpernell pimpernel - pin pin - pinch pinch - pinched pinch - pinches pinch - pinching pinch - pindarus pindaru - pine pine - pined pine - pines pine - pinfold pinfold - pining pine - pinion pinion - pink pink - pinn pinn - pinnace pinnac - pins pin - pinse pins - pint pint - pintpot pintpot - pioned pion - pioneers pioneer - pioner pioner - pioners pioner - pious piou - pip pip - pipe pipe - piper piper - pipers piper - pipes pipe - piping pipe - pippin pippin - pippins pippin - pirate pirat - pirates pirat - pisa pisa - pisanio pisanio - pish pish - pismires pismir - piss piss - pissing piss - pistol pistol - pistols pistol - pit pit - pitch pitch - pitched pitch - pitcher pitcher - pitchers pitcher - pitchy pitchi - piteous piteou - piteously piteous - pitfall pitfal - pith pith - pithless pithless - pithy pithi - pitie piti - pitied piti - pities piti - pitiful piti - pitifully pitifulli - pitiless pitiless - pits pit - pittance pittanc - pittie pitti - pittikins pittikin - pity piti - pitying piti - pius piu - plac plac - place place - placed place - placentio placentio - places place - placeth placeth - placid placid - placing place - plack plack - placket placket - plackets placket - plagu plagu - plague plagu - plagued plagu - plagues plagu - plaguing plagu - plaguy plagui - plain plain - plainer plainer - plainest plainest - plaining plain - plainings plain - plainly plainli - plainness plain - plains plain - plainsong plainsong - plaintful plaint - plaintiff plaintiff - plaintiffs plaintiff - plaints plaint - planched planch - planet planet - planetary planetari - planets planet - planks plank - plant plant - plantage plantag - plantagenet plantagenet - plantagenets plantagenet - plantain plantain - plantation plantat - planted plant - planteth planteth - plants plant - plash plash - plashy plashi - plast plast - plaster plaster - plasterer plaster - plat plat - plate plate - plated plate - plates plate - platform platform - platforms platform - plats plat - platted plat - plausible plausibl - plausive plausiv - plautus plautu - play plai - played plai - player player - players player - playeth playeth - playfellow playfellow - playfellows playfellow - playhouse playhous - playing plai - plays plai - plea plea - pleach pleach - pleached pleach - plead plead - pleaded plead - pleader pleader - pleaders pleader - pleading plead - pleads plead - pleas plea - pleasance pleasanc - pleasant pleasant - pleasantly pleasantli - please pleas - pleased pleas - pleaser pleaser - pleasers pleaser - pleases pleas - pleasest pleasest - pleaseth pleaseth - pleasing pleas - pleasure pleasur - pleasures pleasur - plebeians plebeian - plebeii plebeii - plebs pleb - pledge pledg - pledges pledg - pleines plein - plenitude plenitud - plenteous plenteou - plenteously plenteous - plenties plenti - plentiful plenti - plentifully plentifulli - plenty plenti - pless pless - plessed pless - plessing pless - pliant pliant - plied pli - plies pli - plight plight - plighted plight - plighter plighter - plod plod - plodded plod - plodders plodder - plodding plod - plods plod - plood plood - ploody ploodi - plot plot - plots plot - plotted plot - plotter plotter - plough plough - ploughed plough - ploughman ploughman - ploughmen ploughmen - plow plow - plows plow - pluck pluck - plucked pluck - plucker plucker - plucking pluck - plucks pluck - plue plue - plum plum - plume plume - plumed plume - plumes plume - plummet plummet - plump plump - plumpy plumpi - plums plum - plung plung - plunge plung - plunged plung - plural plural - plurisy plurisi - plus plu - pluto pluto - plutus plutu - ply ply - po po - pocket pocket - pocketing pocket - pockets pocket - pocky pocki - pody podi - poem poem - poesy poesi - poet poet - poetical poetic - poetry poetri - poets poet - poictiers poictier - poinards poinard - poins poin - point point - pointblank pointblank - pointed point - pointing point - points point - pois poi - poise pois - poising pois - poison poison - poisoned poison - poisoner poison - poisoning poison - poisonous poison - poisons poison - poke poke - poking poke - pol pol - polack polack - polacks polack - poland poland - pold pold - pole pole - poleaxe poleax - polecat polecat - polecats polecat - polemon polemon - poles pole - poli poli - policies polici - policy polici - polish polish - polished polish - politic polit - politician politician - politicians politician - politicly politicli - polixenes polixen - poll poll - polluted pollut - pollution pollut - polonius poloniu - poltroons poltroon - polusion polus - polydamus polydamu - polydore polydor - polyxena polyxena - pomander pomand - pomegranate pomegran - pomewater pomewat - pomfret pomfret - pomgarnet pomgarnet - pommel pommel - pomp pomp - pompeius pompeiu - pompey pompei - pompion pompion - pompous pompou - pomps pomp - pond pond - ponder ponder - ponderous ponder - ponds pond - poniard poniard - poniards poniard - pont pont - pontic pontic - pontifical pontif - ponton ponton - pooh pooh - pool pool - poole pool - poop poop - poor poor - poorer poorer - poorest poorest - poorly poorli - pop pop - pope pope - popedom popedom - popilius popiliu - popingay popingai - popish popish - popp popp - poppy poppi - pops pop - popular popular - popularity popular - populous popul - porch porch - porches porch - pore pore - poring pore - pork pork - porn porn - porpentine porpentin - porridge porridg - porringer porring - port port - portable portabl - portage portag - portal portal - portance portanc - portcullis portculli - portend portend - portends portend - portent portent - portentous portent - portents portent - porter porter - porters porter - portia portia - portion portion - portly portli - portotartarossa portotartarossa - portrait portrait - portraiture portraitur - ports port - portugal portug - pose pose - posied posi - posies posi - position posit - positive posit - positively posit - posse poss - possess possess - possessed possess - possesses possess - possesseth possesseth - possessing possess - possession possess - possessions possess - possessor possessor - posset posset - possets posset - possibilities possibl - possibility possibl - possible possibl - possibly possibl - possitable possit - post post - poste post - posted post - posterior posterior - posteriors posterior - posterity poster - postern postern - posterns postern - posters poster - posthorse posthors - posthorses posthors - posthumus posthumu - posting post - postmaster postmast - posts post - postscript postscript - posture postur - postures postur - posy posi - pot pot - potable potabl - potations potat - potato potato - potatoes potato - potch potch - potency potenc - potent potent - potentates potent - potential potenti - potently potent - potents potent - pothecary pothecari - pother pother - potion potion - potions potion - potpan potpan - pots pot - potter potter - potting pot - pottle pottl - pouch pouch - poulter poulter - poultice poultic - poultney poultnei - pouncet pouncet - pound pound - pounds pound - pour pour - pourest pourest - pouring pour - pourquoi pourquoi - pours pour - pout pout - poverty poverti - pow pow - powd powd - powder powder - power power - powerful power - powerfully powerfulli - powerless powerless - powers power - pox pox - poys poi - poysam poysam - prabbles prabbl - practic practic - practice practic - practiced practic - practicer practic - practices practic - practicing practic - practis practi - practisants practis - practise practis - practiser practis - practisers practis - practises practis - practising practis - praeclarissimus praeclarissimu - praemunire praemunir - praetor praetor - praetors praetor - pragging prag - prague pragu - prain prain - prains prain - prais prai - praise prais - praised prais - praises prais - praisest praisest - praiseworthy praiseworthi - praising prais - prancing pranc - prank prank - pranks prank - prat prat - prate prate - prated prate - prater prater - prating prate - prattle prattl - prattler prattler - prattling prattl - prave prave - prawls prawl - prawns prawn - pray prai - prayer prayer - prayers prayer - praying prai - prays prai - pre pre - preach preach - preached preach - preachers preacher - preaches preach - preaching preach - preachment preachment - pread pread - preambulate preambul - precedence preced - precedent preced - preceding preced - precept precept - preceptial precepti - precepts precept - precinct precinct - precious preciou - preciously precious - precipice precipic - precipitating precipit - precipitation precipit - precise precis - precisely precis - preciseness precis - precisian precisian - precor precor - precurse precurs - precursors precursor - predeceased predeceas - predecessor predecessor - predecessors predecessor - predestinate predestin - predicament predica - predict predict - prediction predict - predictions predict - predominance predomin - predominant predomin - predominate predomin - preeches preech - preeminence preemin - preface prefac - prefer prefer - preferment prefer - preferments prefer - preferr preferr - preferreth preferreth - preferring prefer - prefers prefer - prefiguring prefigur - prefix prefix - prefixed prefix - preformed preform - pregnancy pregnanc - pregnant pregnant - pregnantly pregnantli - prejudicates prejud - prejudice prejudic - prejudicial prejudici - prelate prelat - premeditated premedit - premeditation premedit - premised premis - premises premis - prenez prenez - prenominate prenomin - prentice prentic - prentices prentic - preordinance preordin - prepar prepar - preparation prepar - preparations prepar - prepare prepar - prepared prepar - preparedly preparedli - prepares prepar - preparing prepar - prepost prepost - preposterous preposter - preposterously preposter - prerogatifes prerogatif - prerogative prerog - prerogatived prerogativ - presage presag - presagers presag - presages presag - presageth presageth - presaging presag - prescience prescienc - prescribe prescrib - prescript prescript - prescription prescript - prescriptions prescript - prescripts prescript - presence presenc - presences presenc - present present - presentation present - presented present - presenter present - presenters present - presenteth presenteth - presenting present - presently present - presentment present - presents present - preserv preserv - preservation preserv - preservative preserv - preserve preserv - preserved preserv - preserver preserv - preservers preserv - preserving preserv - president presid - press press - pressed press - presser presser - presses press - pressing press - pressure pressur - pressures pressur - prest prest - prester prester - presume presum - presumes presum - presuming presum - presumption presumpt - presumptuous presumptu - presuppos presuppo - pret pret - pretence pretenc - pretences pretenc - pretend pretend - pretended pretend - pretending pretend - pretense pretens - pretext pretext - pretia pretia - prettier prettier - prettiest prettiest - prettily prettili - prettiness pretti - pretty pretti - prevail prevail - prevailed prevail - prevaileth prevaileth - prevailing prevail - prevailment prevail - prevails prevail - prevent prevent - prevented prevent - prevention prevent - preventions prevent - prevents prevent - prey prei - preyful prey - preys prei - priam priam - priami priami - priamus priamu - pribbles pribbl - price price - prick prick - pricked prick - pricket pricket - pricking prick - pricks prick - pricksong pricksong - pride pride - prides pride - pridge pridg - prie prie - pried pri - prief prief - pries pri - priest priest - priesthood priesthood - priests priest - prig prig - primal primal - prime prime - primer primer - primero primero - primest primest - primitive primit - primo primo - primogenity primogen - primrose primros - primroses primros - primy primi - prince princ - princely princ - princes princ - princess princess - principal princip - principalities princip - principality princip - principle principl - principles principl - princox princox - prings pring - print print - printed print - printing print - printless printless - prints print - prioress prioress - priories priori - priority prioriti - priory priori - priscian priscian - prison prison - prisoner prison - prisoners prison - prisonment prison - prisonnier prisonni - prisons prison - pristine pristin - prithe prith - prithee prithe - privacy privaci - private privat - privately privat - privates privat - privilage privilag - privileg privileg - privilege privileg - privileged privileg - privileges privileg - privilegio privilegio - privily privili - privity priviti - privy privi - priz priz - prize prize - prized prize - prizer prizer - prizes prize - prizest prizest - prizing prize - pro pro - probable probabl - probal probal - probation probat - proceed proce - proceeded proceed - proceeders proceed - proceeding proceed - proceedings proceed - proceeds proce - process process - procession process - proclaim proclaim - proclaimed proclaim - proclaimeth proclaimeth - proclaims proclaim - proclamation proclam - proclamations proclam - proconsul proconsul - procrastinate procrastin - procreant procreant - procreants procreant - procreation procreat - procrus procru - proculeius proculeiu - procur procur - procurator procur - procure procur - procured procur - procures procur - procuring procur - prodigal prodig - prodigality prodig - prodigally prodig - prodigals prodig - prodigies prodigi - prodigious prodigi - prodigiously prodigi - prodigy prodigi - proditor proditor - produc produc - produce produc - produced produc - produces produc - producing produc - proface profac - profan profan - profanation profan - profane profan - profaned profan - profanely profan - profaneness profan - profaners profan - profaning profan - profess profess - professed profess - professes profess - profession profess - professions profess - professors professor - proffer proffer - proffered proffer - profferer proffer - proffers proffer - proficient profici - profit profit - profitable profit - profitably profit - profited profit - profiting profit - profitless profitless - profits profit - profound profound - profoundest profoundest - profoundly profoundli - progenitors progenitor - progeny progeni - progne progn - prognosticate prognost - prognostication prognost - progress progress - progression progress - prohibit prohibit - prohibition prohibit - project project - projection project - projects project - prolixious prolixi - prolixity prolix - prologue prologu - prologues prologu - prolong prolong - prolongs prolong - promethean promethean - prometheus prometheu - promis promi - promise promis - promised promis - promises promis - promiseth promiseth - promising promis - promontory promontori - promotion promot - promotions promot - prompt prompt - prompted prompt - promptement promptement - prompter prompter - prompting prompt - prompts prompt - prompture promptur - promulgate promulg - prone prone - prononcer prononc - prononcez prononcez - pronoun pronoun - pronounc pronounc - pronounce pronounc - pronounced pronounc - pronouncing pronounc - pronouns pronoun - proof proof - proofs proof - prop prop - propagate propag - propagation propag - propend propend - propension propens - proper proper - properer proper - properly properli - propertied properti - properties properti - property properti - prophecies propheci - prophecy propheci - prophesied prophesi - prophesier prophesi - prophesy prophesi - prophesying prophesi - prophet prophet - prophetess prophetess - prophetic prophet - prophetically prophet - prophets prophet - propinquity propinqu - propontic propont - proportion proport - proportionable proportion - proportions proport - propos propo - propose propos - proposed propos - proposer propos - proposes propos - proposing propos - proposition proposit - propositions proposit - propounded propound - propp propp - propre propr - propriety proprieti - props prop - propugnation propugn - prorogue prorogu - prorogued prorogu - proscription proscript - proscriptions proscript - prose prose - prosecute prosecut - prosecution prosecut - proselytes proselyt - proserpina proserpina - prosp prosp - prospect prospect - prosper prosper - prosperity prosper - prospero prospero - prosperous prosper - prosperously prosper - prospers prosper - prostitute prostitut - prostrate prostrat - protect protect - protected protect - protection protect - protector protector - protectors protector - protectorship protectorship - protectress protectress - protects protect - protest protest - protestation protest - protestations protest - protested protest - protester protest - protesting protest - protests protest - proteus proteu - protheus protheu - protract protract - protractive protract - proud proud - prouder prouder - proudest proudest - proudlier proudlier - proudly proudli - prouds proud - prov prov - provand provand - prove prove - proved prove - provender provend - proverb proverb - proverbs proverb - proves prove - proveth proveth - provide provid - provided provid - providence provid - provident provid - providently provid - provider provid - provides provid - province provinc - provinces provinc - provincial provinci - proving prove - provision provis - proviso proviso - provocation provoc - provok provok - provoke provok - provoked provok - provoker provok - provokes provok - provoketh provoketh - provoking provok - provost provost - prowess prowess - prudence prudenc - prudent prudent - prun prun - prune prune - prunes prune - pruning prune - pry pry - prying pry - psalm psalm - psalmist psalmist - psalms psalm - psalteries psalteri - ptolemies ptolemi - ptolemy ptolemi - public public - publican publican - publication public - publicly publicli - publicola publicola - publish publish - published publish - publisher publish - publishing publish - publius publiu - pucelle pucel - puck puck - pudder pudder - pudding pud - puddings pud - puddle puddl - puddled puddl - pudency pudenc - pueritia pueritia - puff puff - puffing puf - puffs puff - pugging pug - puis pui - puissance puissanc - puissant puissant - puke puke - puking puke - pulcher pulcher - puling pule - pull pull - puller puller - pullet pullet - pulling pull - pulls pull - pulpit pulpit - pulpiter pulpit - pulpits pulpit - pulse puls - pulsidge pulsidg - pump pump - pumpion pumpion - pumps pump - pun pun - punched punch - punish punish - punished punish - punishes punish - punishment punish - punishments punish - punk punk - punto punto - puny puni - pupil pupil - pupils pupil - puppet puppet - puppets puppet - puppies puppi - puppy puppi - pur pur - purblind purblind - purchas purcha - purchase purchas - purchased purchas - purchases purchas - purchaseth purchaseth - purchasing purchas - pure pure - purely pure - purer purer - purest purest - purg purg - purgation purgat - purgative purg - purgatory purgatori - purge purg - purged purg - purgers purger - purging purg - purifies purifi - purifying purifi - puritan puritan - purity puriti - purlieus purlieu - purple purpl - purpled purpl - purples purpl - purport purport - purpos purpo - purpose purpos - purposed purpos - purposely purpos - purposes purpos - purposeth purposeth - purposing purpos - purr purr - purs pur - purse purs - pursents pursent - purses purs - pursu pursu - pursue pursu - pursued pursu - pursuers pursuer - pursues pursu - pursuest pursuest - pursueth pursueth - pursuing pursu - pursuit pursuit - pursuivant pursuiv - pursuivants pursuiv - pursy pursi - purus puru - purveyor purveyor - push push - pushes push - pusillanimity pusillanim - put put - putrefy putrefi - putrified putrifi - puts put - putter putter - putting put - puttock puttock - puzzel puzzel - puzzle puzzl - puzzled puzzl - puzzles puzzl - py py - pygmalion pygmalion - pygmies pygmi - pygmy pygmi - pyramid pyramid - pyramides pyramid - pyramids pyramid - pyramis pyrami - pyramises pyramis - pyramus pyramu - pyrenean pyrenean - pyrrhus pyrrhu - pythagoras pythagora - qu qu - quadrangle quadrangl - quae quae - quaff quaff - quaffing quaf - quagmire quagmir - quail quail - quailing quail - quails quail - quaint quaint - quaintly quaintli - quak quak - quake quak - quakes quak - qualification qualif - qualified qualifi - qualifies qualifi - qualify qualifi - qualifying qualifi - qualite qualit - qualities qualiti - quality qualiti - qualm qualm - qualmish qualmish - quam quam - quand quand - quando quando - quantities quantiti - quantity quantiti - quare quar - quarrel quarrel - quarrell quarrel - quarreller quarrel - quarrelling quarrel - quarrelous quarrel - quarrels quarrel - quarrelsome quarrelsom - quarries quarri - quarry quarri - quart quart - quarter quarter - quartered quarter - quartering quarter - quarters quarter - quarts quart - quasi quasi - quat quat - quatch quatch - quay quai - que que - quean quean - queas quea - queasiness queasi - queasy queasi - queen queen - queens queen - quell quell - queller queller - quench quench - quenched quench - quenching quench - quenchless quenchless - quern quern - quest quest - questant questant - question question - questionable question - questioned question - questioning question - questionless questionless - questions question - questrists questrist - quests quest - queubus queubu - qui qui - quick quick - quicken quicken - quickens quicken - quicker quicker - quicklier quicklier - quickly quickli - quickness quick - quicksand quicksand - quicksands quicksand - quicksilverr quicksilverr - quid quid - quiddities quidditi - quiddits quiddit - quier quier - quiet quiet - quieter quieter - quietly quietli - quietness quiet - quietus quietu - quill quill - quillets quillet - quills quill - quilt quilt - quinapalus quinapalu - quince quinc - quinces quinc - quintain quintain - quintessence quintess - quintus quintu - quip quip - quips quip - quire quir - quiring quir - quirk quirk - quirks quirk - quis qui - quit quit - quite quit - quits quit - quittance quittanc - quitted quit - quitting quit - quiver quiver - quivering quiver - quivers quiver - quo quo - quod quod - quoifs quoif - quoint quoint - quoit quoit - quoits quoit - quondam quondam - quoniam quoniam - quote quot - quoted quot - quotes quot - quoth quoth - quotidian quotidian - r r - rabbit rabbit - rabble rabbl - rabblement rabblement - race race - rack rack - rackers racker - racket racket - rackets racket - racking rack - racks rack - radiance radianc - radiant radiant - radish radish - rafe rafe - raft raft - rag rag - rage rage - rages rage - rageth rageth - ragg ragg - ragged rag - raggedness ragged - raging rage - ragozine ragozin - rags rag - rah rah - rail rail - railed rail - railer railer - railest railest - raileth raileth - railing rail - rails rail - raiment raiment - rain rain - rainbow rainbow - raineth raineth - raining rain - rainold rainold - rains rain - rainy raini - rais rai - raise rais - raised rais - raises rais - raising rais - raisins raisin - rak rak - rake rake - rakers raker - rakes rake - ral ral - rald rald - ralph ralph - ram ram - rambures rambur - ramm ramm - rampallian rampallian - rampant rampant - ramping ramp - rampir rampir - ramps ramp - rams ram - ramsey ramsei - ramston ramston - ran ran - rance ranc - rancorous rancor - rancors rancor - rancour rancour - random random - rang rang - range rang - ranged rang - rangers ranger - ranges rang - ranging rang - rank rank - ranker ranker - rankest rankest - ranking rank - rankle rankl - rankly rankli - rankness rank - ranks rank - ransack ransack - ransacking ransack - ransom ransom - ransomed ransom - ransoming ransom - ransomless ransomless - ransoms ransom - rant rant - ranting rant - rap rap - rape rape - rapes rape - rapier rapier - rapiers rapier - rapine rapin - raps rap - rapt rapt - rapture raptur - raptures raptur - rar rar - rare rare - rarely rare - rareness rare - rarer rarer - rarest rarest - rarities rariti - rarity rariti - rascal rascal - rascalliest rascalliest - rascally rascal - rascals rascal - rased rase - rash rash - rasher rasher - rashly rashli - rashness rash - rat rat - ratcatcher ratcatch - ratcliff ratcliff - rate rate - rated rate - rately rate - rates rate - rather rather - ratherest ratherest - ratified ratifi - ratifiers ratifi - ratify ratifi - rating rate - rational ration - ratolorum ratolorum - rats rat - ratsbane ratsban - rattle rattl - rattles rattl - rattling rattl - rature ratur - raught raught - rav rav - rave rave - ravel ravel - raven raven - ravening raven - ravenous raven - ravens raven - ravenspurgh ravenspurgh - raves rave - ravin ravin - raving rave - ravish ravish - ravished ravish - ravisher ravish - ravishing ravish - ravishments ravish - raw raw - rawer rawer - rawly rawli - rawness raw - ray rai - rayed rai - rays rai - raz raz - raze raze - razed raze - razes raze - razeth razeth - razing raze - razor razor - razorable razor - razors razor - razure razur - re re - reach reach - reaches reach - reacheth reacheth - reaching reach - read read - reader reader - readiest readiest - readily readili - readiness readi - reading read - readins readin - reads read - ready readi - real real - really realli - realm realm - realms realm - reap reap - reapers reaper - reaping reap - reaps reap - rear rear - rears rear - rearward rearward - reason reason - reasonable reason - reasonably reason - reasoned reason - reasoning reason - reasonless reasonless - reasons reason - reave reav - rebate rebat - rebato rebato - rebeck rebeck - rebel rebel - rebell rebel - rebelling rebel - rebellion rebellion - rebellious rebelli - rebels rebel - rebound rebound - rebuk rebuk - rebuke rebuk - rebukeable rebuk - rebuked rebuk - rebukes rebuk - rebus rebu - recall recal - recant recant - recantation recant - recanter recant - recanting recant - receipt receipt - receipts receipt - receiv receiv - receive receiv - received receiv - receiver receiv - receives receiv - receivest receivest - receiveth receiveth - receiving receiv - receptacle receptacl - rechate rechat - reciprocal reciproc - reciprocally reciproc - recite recit - recited recit - reciterai reciterai - reck reck - recking reck - reckless reckless - reckon reckon - reckoned reckon - reckoning reckon - reckonings reckon - recks reck - reclaim reclaim - reclaims reclaim - reclusive reclus - recognizance recogniz - recognizances recogniz - recoil recoil - recoiling recoil - recollected recollect - recomforted recomfort - recomforture recomfortur - recommend recommend - recommended recommend - recommends recommend - recompens recompen - recompense recompens - reconcil reconcil - reconcile reconcil - reconciled reconcil - reconcilement reconcil - reconciler reconcil - reconciles reconcil - reconciliation reconcili - record record - recordation record - recorded record - recorder record - recorders record - records record - recount recount - recounted recount - recounting recount - recountments recount - recounts recount - recourse recours - recov recov - recover recov - recoverable recover - recovered recov - recoveries recoveri - recovers recov - recovery recoveri - recreant recreant - recreants recreant - recreate recreat - recreation recreat - rectify rectifi - rector rector - rectorship rectorship - recure recur - recured recur - red red - redbreast redbreast - redder redder - reddest reddest - rede rede - redeem redeem - redeemed redeem - redeemer redeem - redeeming redeem - redeems redeem - redeliver redeliv - redemption redempt - redime redim - redness red - redoubled redoubl - redoubted redoubt - redound redound - redress redress - redressed redress - redresses redress - reduce reduc - reechy reechi - reed reed - reeds reed - reek reek - reeking reek - reeks reek - reeky reeki - reel reel - reeleth reeleth - reeling reel - reels reel - refell refel - refer refer - reference refer - referr referr - referred refer - refigured refigur - refin refin - refined refin - reflect reflect - reflecting reflect - reflection reflect - reflex reflex - reform reform - reformation reform - reformed reform - refractory refractori - refrain refrain - refresh refresh - refreshing refresh - reft reft - refts reft - refuge refug - refus refu - refusal refus - refuse refus - refused refus - refusest refusest - refusing refus - reg reg - regal regal - regalia regalia - regan regan - regard regard - regardance regard - regarded regard - regardfully regardfulli - regarding regard - regards regard - regenerate regener - regent regent - regentship regentship - regia regia - regiment regiment - regiments regiment - regina regina - region region - regions region - regist regist - register regist - registers regist - regreet regreet - regreets regreet - regress regress - reguerdon reguerdon - regular regular - rehears rehear - rehearsal rehears - rehearse rehears - reign reign - reigned reign - reignier reignier - reigning reign - reigns reign - rein rein - reinforc reinforc - reinforce reinforc - reinforcement reinforc - reins rein - reiterate reiter - reject reject - rejected reject - rejoic rejoic - rejoice rejoic - rejoices rejoic - rejoiceth rejoiceth - rejoicing rejoic - rejoicingly rejoicingli - rejoindure rejoindur - rejourn rejourn - rel rel - relapse relaps - relate relat - relates relat - relation relat - relations relat - relative rel - releas relea - release releas - released releas - releasing releas - relent relent - relenting relent - relents relent - reliances relianc - relics relic - relief relief - reliev reliev - relieve reliev - relieved reliev - relieves reliev - relieving reliev - religion religion - religions religion - religious religi - religiously religi - relinquish relinquish - reliques reliqu - reliquit reliquit - relish relish - relume relum - rely reli - relying reli - remain remain - remainder remaind - remainders remaind - remained remain - remaineth remaineth - remaining remain - remains remain - remark remark - remarkable remark - remediate remedi - remedied remedi - remedies remedi - remedy remedi - rememb rememb - remember rememb - remembered rememb - remembers rememb - remembrance remembr - remembrancer remembranc - remembrances remembr - remercimens remercimen - remiss remiss - remission remiss - remissness remiss - remit remit - remnant remnant - remnants remnant - remonstrance remonstr - remorse remors - remorseful remors - remorseless remorseless - remote remot - remotion remot - remov remov - remove remov - removed remov - removedness removed - remover remov - removes remov - removing remov - remunerate remuner - remuneration remuner - rence renc - rend rend - render render - rendered render - renders render - rendezvous rendezv - renegado renegado - renege reneg - reneges reneg - renew renew - renewed renew - renewest renewest - renounce renounc - renouncement renounc - renouncing renounc - renowmed renowm - renown renown - renowned renown - rent rent - rents rent - repaid repaid - repair repair - repaired repair - repairing repair - repairs repair - repass repass - repast repast - repasture repastur - repay repai - repaying repai - repays repai - repeal repeal - repealing repeal - repeals repeal - repeat repeat - repeated repeat - repeating repeat - repeats repeat - repel repel - repent repent - repentance repent - repentant repent - repented repent - repenting repent - repents repent - repetition repetit - repetitions repetit - repin repin - repine repin - repining repin - replant replant - replenish replenish - replenished replenish - replete replet - replication replic - replied repli - replies repli - repliest repliest - reply repli - replying repli - report report - reported report - reporter report - reportest reportest - reporting report - reportingly reportingli - reports report - reposal repos - repose repos - reposeth reposeth - reposing repos - repossess repossess - reprehend reprehend - reprehended reprehend - reprehending reprehend - represent repres - representing repres - reprieve repriev - reprieves repriev - reprisal repris - reproach reproach - reproaches reproach - reproachful reproach - reproachfully reproachfulli - reprobate reprob - reprobation reprob - reproof reproof - reprov reprov - reprove reprov - reproveable reprov - reproves reprov - reproving reprov - repugn repugn - repugnancy repugn - repugnant repugn - repulse repuls - repulsed repuls - repurchas repurcha - repured repur - reputation reput - repute reput - reputed reput - reputeless reputeless - reputes reput - reputing reput - request request - requested request - requesting request - requests request - requiem requiem - requir requir - require requir - required requir - requires requir - requireth requireth - requiring requir - requisite requisit - requisites requisit - requit requit - requital requit - requite requit - requited requit - requites requit - rer rer - rere rere - rers rer - rescu rescu - rescue rescu - rescued rescu - rescues rescu - rescuing rescu - resemblance resembl - resemble resembl - resembled resembl - resembles resembl - resembleth resembleth - resembling resembl - reserv reserv - reservation reserv - reserve reserv - reserved reserv - reserves reserv - reside resid - residence resid - resident resid - resides resid - residing resid - residue residu - resign resign - resignation resign - resist resist - resistance resist - resisted resist - resisting resist - resists resist - resolute resolut - resolutely resolut - resolutes resolut - resolution resolut - resolv resolv - resolve resolv - resolved resolv - resolvedly resolvedli - resolves resolv - resolveth resolveth - resort resort - resorted resort - resounding resound - resounds resound - respeaking respeak - respect respect - respected respect - respecting respect - respective respect - respectively respect - respects respect - respice respic - respite respit - respites respit - responsive respons - respose respos - ress ress - rest rest - rested rest - resteth resteth - restful rest - resting rest - restitution restitut - restless restless - restor restor - restoration restor - restorative restor - restore restor - restored restor - restores restor - restoring restor - restrain restrain - restrained restrain - restraining restrain - restrains restrain - restraint restraint - rests rest - resty resti - resum resum - resume resum - resumes resum - resurrections resurrect - retail retail - retails retail - retain retain - retainers retain - retaining retain - retell retel - retention retent - retentive retent - retinue retinu - retir retir - retire retir - retired retir - retirement retir - retires retir - retiring retir - retold retold - retort retort - retorts retort - retourne retourn - retract retract - retreat retreat - retrograde retrograd - rets ret - return return - returned return - returnest returnest - returneth returneth - returning return - returns return - revania revania - reveal reveal - reveals reveal - revel revel - reveler revel - revell revel - reveller revel - revellers revel - revelling revel - revelry revelri - revels revel - reveng reveng - revenge reveng - revenged reveng - revengeful reveng - revengement reveng - revenger reveng - revengers reveng - revenges reveng - revenging reveng - revengingly revengingli - revenue revenu - revenues revenu - reverb reverb - reverberate reverber - reverbs reverb - reverenc reverenc - reverence rever - reverend reverend - reverent rever - reverently rever - revers rever - reverse revers - reversion revers - reverted revert - review review - reviewest reviewest - revil revil - revile revil - revisits revisit - reviv reviv - revive reviv - revives reviv - reviving reviv - revok revok - revoke revok - revokement revok - revolt revolt - revolted revolt - revolting revolt - revolts revolt - revolution revolut - revolutions revolut - revolve revolv - revolving revolv - reward reward - rewarded reward - rewarder reward - rewarding reward - rewards reward - reword reword - reworded reword - rex rex - rey rei - reynaldo reynaldo - rford rford - rful rful - rfull rfull - rhapsody rhapsodi - rheims rheim - rhenish rhenish - rhesus rhesu - rhetoric rhetor - rheum rheum - rheumatic rheumat - rheums rheum - rheumy rheumi - rhinoceros rhinocero - rhodes rhode - rhodope rhodop - rhubarb rhubarb - rhym rhym - rhyme rhyme - rhymers rhymer - rhymes rhyme - rhyming rhyme - rialto rialto - rib rib - ribald ribald - riband riband - ribands riband - ribaudred ribaudr - ribb ribb - ribbed rib - ribbon ribbon - ribbons ribbon - ribs rib - rice rice - rich rich - richard richard - richer richer - riches rich - richest richest - richly richli - richmond richmond - richmonds richmond - rid rid - riddance riddanc - ridden ridden - riddle riddl - riddles riddl - riddling riddl - ride ride - rider rider - riders rider - rides ride - ridest ridest - rideth rideth - ridge ridg - ridges ridg - ridiculous ridicul - riding ride - rids rid - rien rien - ries ri - rifle rifl - rift rift - rifted rift - rig rig - rigg rigg - riggish riggish - right right - righteous righteou - righteously righteous - rightful right - rightfully rightfulli - rightly rightli - rights right - rigol rigol - rigorous rigor - rigorously rigor - rigour rigour - ril ril - rim rim - rin rin - rinaldo rinaldo - rind rind - ring ring - ringing ring - ringleader ringlead - ringlets ringlet - rings ring - ringwood ringwood - riot riot - rioter rioter - rioting riot - riotous riotou - riots riot - rip rip - ripe ripe - ripely ripe - ripen ripen - ripened ripen - ripeness ripe - ripening ripen - ripens ripen - riper riper - ripest ripest - riping ripe - ripp ripp - ripping rip - rise rise - risen risen - rises rise - riseth riseth - rish rish - rising rise - rite rite - rites rite - rivage rivag - rival rival - rivality rival - rivall rival - rivals rival - rive rive - rived rive - rivelled rivel - river river - rivers river - rivet rivet - riveted rivet - rivets rivet - rivo rivo - rj rj - rless rless - road road - roads road - roam roam - roaming roam - roan roan - roar roar - roared roar - roarers roarer - roaring roar - roars roar - roast roast - roasted roast - rob rob - roba roba - robas roba - robb robb - robbed rob - robber robber - robbers robber - robbery robberi - robbing rob - robe robe - robed robe - robert robert - robes robe - robin robin - robs rob - robustious robusti - rochester rochest - rochford rochford - rock rock - rocks rock - rocky rocki - rod rod - rode rode - roderigo roderigo - rods rod - roe roe - roes roe - roger roger - rogero rogero - rogue rogu - roguery rogueri - rogues rogu - roguish roguish - roi roi - roisting roist - roll roll - rolled roll - rolling roll - rolls roll - rom rom - romage romag - roman roman - romano romano - romanos romano - romans roman - rome rome - romeo romeo - romish romish - rondure rondur - ronyon ronyon - rood rood - roof roof - roofs roof - rook rook - rooks rook - rooky rooki - room room - rooms room - root root - rooted root - rootedly rootedli - rooteth rooteth - rooting root - roots root - rope rope - ropery roperi - ropes rope - roping rope - ros ro - rosalind rosalind - rosalinda rosalinda - rosalinde rosalind - rosaline rosalin - roscius rosciu - rose rose - rosed rose - rosemary rosemari - rosencrantz rosencrantz - roses rose - ross ross - rosy rosi - rot rot - rote rote - roted rote - rother rother - rotherham rotherham - rots rot - rotted rot - rotten rotten - rottenness rotten - rotting rot - rotundity rotund - rouen rouen - rough rough - rougher rougher - roughest roughest - roughly roughli - roughness rough - round round - rounded round - roundel roundel - rounder rounder - roundest roundest - rounding round - roundly roundli - rounds round - roundure roundur - rous rou - rouse rous - roused rous - rousillon rousillon - rously rousli - roussi roussi - rout rout - routed rout - routs rout - rove rove - rover rover - row row - rowel rowel - rowland rowland - rowlands rowland - roy roi - royal royal - royalize royal - royally royal - royalties royalti - royalty royalti - roynish roynish - rs rs - rt rt - rub rub - rubb rubb - rubbing rub - rubbish rubbish - rubies rubi - rubious rubiou - rubs rub - ruby rubi - rud rud - rudand rudand - rudder rudder - ruddiness ruddi - ruddock ruddock - ruddy ruddi - rude rude - rudely rude - rudeness rude - ruder ruder - rudesby rudesbi - rudest rudest - rudiments rudiment - rue rue - rued ru - ruff ruff - ruffian ruffian - ruffians ruffian - ruffle ruffl - ruffling ruffl - ruffs ruff - rug rug - rugby rugbi - rugemount rugemount - rugged rug - ruin ruin - ruinate ruinat - ruined ruin - ruining ruin - ruinous ruinou - ruins ruin - rul rul - rule rule - ruled rule - ruler ruler - rulers ruler - rules rule - ruling rule - rumble rumbl - ruminaies ruminai - ruminat ruminat - ruminate rumin - ruminated rumin - ruminates rumin - rumination rumin - rumor rumor - rumour rumour - rumourer rumour - rumours rumour - rump rump - run run - runagate runag - runagates runag - runaway runawai - runaways runawai - rung rung - runn runn - runner runner - runners runner - running run - runs run - rupture ruptur - ruptures ruptur - rural rural - rush rush - rushes rush - rushing rush - rushling rushl - rushy rushi - russet russet - russia russia - russian russian - russians russian - rust rust - rusted rust - rustic rustic - rustically rustic - rustics rustic - rustle rustl - rustling rustl - rusts rust - rusty rusti - rut rut - ruth ruth - ruthful ruth - ruthless ruthless - rutland rutland - ruttish ruttish - ry ry - rye rye - rything ryth - s s - sa sa - saba saba - sabbath sabbath - sable sabl - sables sabl - sack sack - sackbuts sackbut - sackcloth sackcloth - sacked sack - sackerson sackerson - sacks sack - sacrament sacrament - sacred sacr - sacrific sacrif - sacrifice sacrific - sacrificers sacrific - sacrifices sacrific - sacrificial sacrifici - sacrificing sacrif - sacrilegious sacrilegi - sacring sacr - sad sad - sadder sadder - saddest saddest - saddle saddl - saddler saddler - saddles saddl - sadly sadli - sadness sad - saf saf - safe safe - safeguard safeguard - safely safe - safer safer - safest safest - safeties safeti - safety safeti - saffron saffron - sag sag - sage sage - sagittary sagittari - said said - saidst saidst - sail sail - sailing sail - sailmaker sailmak - sailor sailor - sailors sailor - sails sail - sain sain - saint saint - sainted saint - saintlike saintlik - saints saint - saith saith - sake sake - sakes sake - sala sala - salad salad - salamander salamand - salary salari - sale sale - salerio salerio - salicam salicam - salique saliqu - salisbury salisburi - sall sall - sallet sallet - sallets sallet - sallies salli - sallow sallow - sally salli - salmon salmon - salmons salmon - salt salt - salter salter - saltiers saltier - saltness salt - saltpetre saltpetr - salutation salut - salutations salut - salute salut - saluted salut - salutes salut - saluteth saluteth - salv salv - salvation salvat - salve salv - salving salv - same same - samingo samingo - samp samp - sampire sampir - sample sampl - sampler sampler - sampson sampson - samson samson - samsons samson - sancta sancta - sanctified sanctifi - sanctifies sanctifi - sanctify sanctifi - sanctimonies sanctimoni - sanctimonious sanctimoni - sanctimony sanctimoni - sanctities sanctiti - sanctity sanctiti - sanctuarize sanctuar - sanctuary sanctuari - sand sand - sandal sandal - sandbag sandbag - sanded sand - sands sand - sandy sandi - sandys sandi - sang sang - sanguine sanguin - sanguis sangui - sanity saniti - sans san - santrailles santrail - sap sap - sapient sapient - sapit sapit - sapless sapless - sapling sapl - sapphire sapphir - sapphires sapphir - saracens saracen - sarcenet sarcenet - sard sard - sardians sardian - sardinia sardinia - sardis sardi - sarum sarum - sat sat - satan satan - satchel satchel - sate sate - sated sate - satiate satiat - satiety satieti - satin satin - satire satir - satirical satir - satis sati - satisfaction satisfact - satisfied satisfi - satisfies satisfi - satisfy satisfi - satisfying satisfi - saturday saturdai - saturdays saturdai - saturn saturn - saturnine saturnin - saturninus saturninu - satyr satyr - satyrs satyr - sauc sauc - sauce sauc - sauced sauc - saucers saucer - sauces sauc - saucily saucili - sauciness sauci - saucy sauci - sauf sauf - saunder saunder - sav sav - savage savag - savagely savag - savageness savag - savagery savageri - savages savag - save save - saved save - saves save - saving save - saviour saviour - savory savori - savour savour - savouring savour - savours savour - savoury savouri - savoy savoi - saw saw - sawed saw - sawest sawest - sawn sawn - sawpit sawpit - saws saw - sawyer sawyer - saxons saxon - saxony saxoni - saxton saxton - say sai - sayest sayest - saying sai - sayings sai - says sai - sayst sayst - sblood sblood - sc sc - scab scab - scabbard scabbard - scabs scab - scaffold scaffold - scaffoldage scaffoldag - scal scal - scald scald - scalded scald - scalding scald - scale scale - scaled scale - scales scale - scaling scale - scall scall - scalp scalp - scalps scalp - scaly scali - scamble scambl - scambling scambl - scamels scamel - scan scan - scandal scandal - scandaliz scandaliz - scandalous scandal - scandy scandi - scann scann - scant scant - scanted scant - scanter scanter - scanting scant - scantling scantl - scants scant - scap scap - scape scape - scaped scape - scapes scape - scapeth scapeth - scar scar - scarce scarc - scarcely scarc - scarcity scarciti - scare scare - scarecrow scarecrow - scarecrows scarecrow - scarf scarf - scarfed scarf - scarfs scarf - scaring scare - scarlet scarlet - scarr scarr - scarre scarr - scars scar - scarus scaru - scath scath - scathe scath - scathful scath - scatt scatt - scatter scatter - scattered scatter - scattering scatter - scatters scatter - scelera scelera - scelerisque scelerisqu - scene scene - scenes scene - scent scent - scented scent - scept scept - scepter scepter - sceptre sceptr - sceptred sceptr - sceptres sceptr - schedule schedul - schedules schedul - scholar scholar - scholarly scholarli - scholars scholar - school school - schoolboy schoolboi - schoolboys schoolboi - schoolfellows schoolfellow - schooling school - schoolmaster schoolmast - schoolmasters schoolmast - schools school - sciatica sciatica - sciaticas sciatica - science scienc - sciences scienc - scimitar scimitar - scion scion - scions scion - scissors scissor - scoff scoff - scoffer scoffer - scoffing scof - scoffs scoff - scoggin scoggin - scold scold - scolding scold - scolds scold - sconce sconc - scone scone - scope scope - scopes scope - scorch scorch - scorched scorch - score score - scored score - scores score - scoring score - scorn scorn - scorned scorn - scornful scorn - scornfully scornfulli - scorning scorn - scorns scorn - scorpion scorpion - scorpions scorpion - scot scot - scotch scotch - scotches scotch - scotland scotland - scots scot - scottish scottish - scoundrels scoundrel - scour scour - scoured scour - scourg scourg - scourge scourg - scouring scour - scout scout - scouts scout - scowl scowl - scrap scrap - scrape scrape - scraping scrape - scraps scrap - scratch scratch - scratches scratch - scratching scratch - scream scream - screams scream - screech screech - screeching screech - screen screen - screens screen - screw screw - screws screw - scribbl scribbl - scribbled scribbl - scribe scribe - scribes scribe - scrimers scrimer - scrip scrip - scrippage scrippag - scripture scriptur - scriptures scriptur - scrivener scriven - scroll scroll - scrolls scroll - scroop scroop - scrowl scrowl - scroyles scroyl - scrubbed scrub - scruple scrupl - scruples scrupl - scrupulous scrupul - scuffles scuffl - scuffling scuffl - scullion scullion - sculls scull - scum scum - scurril scurril - scurrility scurril - scurrilous scurril - scurvy scurvi - scuse scuse - scut scut - scutcheon scutcheon - scutcheons scutcheon - scylla scylla - scythe scyth - scythed scyth - scythia scythia - scythian scythian - sdeath sdeath - se se - sea sea - seacoal seacoal - seafaring seafar - seal seal - sealed seal - sealing seal - seals seal - seam seam - seamen seamen - seamy seami - seaport seaport - sear sear - searce searc - search search - searchers searcher - searches search - searcheth searcheth - searching search - seared sear - seas sea - seasick seasick - seaside seasid - season season - seasoned season - seasons season - seat seat - seated seat - seats seat - sebastian sebastian - second second - secondarily secondarili - secondary secondari - seconded second - seconds second - secrecy secreci - secret secret - secretaries secretari - secretary secretari - secretly secretli - secrets secret - sect sect - sectary sectari - sects sect - secundo secundo - secure secur - securely secur - securing secur - security secur - sedg sedg - sedge sedg - sedges sedg - sedgy sedgi - sedition sedit - seditious sediti - seduc seduc - seduce seduc - seduced seduc - seducer seduc - seducing seduc - see see - seed seed - seeded seed - seedness seed - seeds seed - seedsman seedsman - seein seein - seeing see - seek seek - seeking seek - seeks seek - seel seel - seeling seel - seely seeli - seem seem - seemed seem - seemers seemer - seemest seemest - seemeth seemeth - seeming seem - seemingly seemingli - seemly seemli - seems seem - seen seen - seer seer - sees see - seese sees - seest seest - seethe seeth - seethes seeth - seething seeth - seeting seet - segregation segreg - seigneur seigneur - seigneurs seigneur - seiz seiz - seize seiz - seized seiz - seizes seiz - seizeth seizeth - seizing seiz - seizure seizur - seld seld - seldom seldom - select select - seleucus seleucu - self self - selfsame selfsam - sell sell - seller seller - selling sell - sells sell - selves selv - semblable semblabl - semblably semblabl - semblance semblanc - semblances semblanc - semblative sembl - semi semi - semicircle semicircl - semiramis semirami - semper semper - sempronius semproniu - senate senat - senator senat - senators senat - send send - sender sender - sendeth sendeth - sending send - sends send - seneca seneca - senior senior - seniory seniori - senis seni - sennet sennet - senoys senoi - sense sens - senseless senseless - senses sens - sensible sensibl - sensibly sensibl - sensual sensual - sensuality sensual - sent sent - sentenc sentenc - sentence sentenc - sentences sentenc - sententious sententi - sentinel sentinel - sentinels sentinel - separable separ - separate separ - separated separ - separates separ - separation separ - septentrion septentrion - sepulchre sepulchr - sepulchres sepulchr - sepulchring sepulchr - sequel sequel - sequence sequenc - sequent sequent - sequest sequest - sequester sequest - sequestration sequestr - sere sere - serenis sereni - serge serg - sergeant sergeant - serious seriou - seriously serious - sermon sermon - sermons sermon - serpent serpent - serpentine serpentin - serpents serpent - serpigo serpigo - serv serv - servant servant - servanted servant - servants servant - serve serv - served serv - server server - serves serv - serveth serveth - service servic - serviceable servic - services servic - servile servil - servility servil - servilius serviliu - serving serv - servingman servingman - servingmen servingmen - serviteur serviteur - servitor servitor - servitors servitor - servitude servitud - sessa sessa - session session - sessions session - sestos sesto - set set - setebos setebo - sets set - setter setter - setting set - settle settl - settled settl - settlest settlest - settling settl - sev sev - seven seven - sevenfold sevenfold - sevennight sevennight - seventeen seventeen - seventh seventh - seventy seventi - sever sever - several sever - severally sever - severals sever - severe sever - severed sever - severely sever - severest severest - severing sever - severity sever - severn severn - severs sever - sew sew - seward seward - sewer sewer - sewing sew - sex sex - sexes sex - sexton sexton - sextus sextu - seymour seymour - seyton seyton - sfoot sfoot - sh sh - shackle shackl - shackles shackl - shade shade - shades shade - shadow shadow - shadowed shadow - shadowing shadow - shadows shadow - shadowy shadowi - shady shadi - shafalus shafalu - shaft shaft - shafts shaft - shag shag - shak shak - shake shake - shaked shake - shaken shaken - shakes shake - shaking shake - shales shale - shall shall - shallenge shalleng - shallow shallow - shallowest shallowest - shallowly shallowli - shallows shallow - shalt shalt - sham sham - shambles shambl - shame shame - shamed shame - shameful shame - shamefully shamefulli - shameless shameless - shames shame - shamest shamest - shaming shame - shank shank - shanks shank - shap shap - shape shape - shaped shape - shapeless shapeless - shapen shapen - shapes shape - shaping shape - shar shar - shard shard - sharded shard - shards shard - share share - shared share - sharers sharer - shares share - sharing share - shark shark - sharp sharp - sharpen sharpen - sharpened sharpen - sharpens sharpen - sharper sharper - sharpest sharpest - sharply sharpli - sharpness sharp - sharps sharp - shatter shatter - shav shav - shave shave - shaven shaven - shaw shaw - she she - sheaf sheaf - sheal sheal - shear shear - shearers shearer - shearing shear - shearman shearman - shears shear - sheath sheath - sheathe sheath - sheathed sheath - sheathes sheath - sheathing sheath - sheaved sheav - sheaves sheav - shed shed - shedding shed - sheds shed - sheen sheen - sheep sheep - sheepcote sheepcot - sheepcotes sheepcot - sheeps sheep - sheepskins sheepskin - sheer sheer - sheet sheet - sheeted sheet - sheets sheet - sheffield sheffield - shelf shelf - shell shell - shells shell - shelt shelt - shelter shelter - shelters shelter - shelves shelv - shelving shelv - shelvy shelvi - shent shent - shepherd shepherd - shepherdes shepherd - shepherdess shepherdess - shepherdesses shepherdess - shepherds shepherd - sher sher - sheriff sheriff - sherris sherri - shes she - sheweth sheweth - shield shield - shielded shield - shields shield - shift shift - shifted shift - shifting shift - shifts shift - shilling shill - shillings shill - shin shin - shine shine - shines shine - shineth shineth - shining shine - shins shin - shiny shini - ship ship - shipboard shipboard - shipman shipman - shipmaster shipmast - shipmen shipmen - shipp shipp - shipped ship - shipping ship - ships ship - shipt shipt - shipwreck shipwreck - shipwrecking shipwreck - shipwright shipwright - shipwrights shipwright - shire shire - shirley shirlei - shirt shirt - shirts shirt - shive shive - shiver shiver - shivering shiver - shivers shiver - shoal shoal - shoals shoal - shock shock - shocks shock - shod shod - shoe shoe - shoeing shoe - shoemaker shoemak - shoes shoe - shog shog - shone shone - shook shook - shoon shoon - shoot shoot - shooter shooter - shootie shooti - shooting shoot - shoots shoot - shop shop - shops shop - shore shore - shores shore - shorn shorn - short short - shortcake shortcak - shorten shorten - shortened shorten - shortens shorten - shorter shorter - shortly shortli - shortness short - shot shot - shotten shotten - shoughs shough - should should - shoulder shoulder - shouldering shoulder - shoulders shoulder - shouldst shouldst - shout shout - shouted shout - shouting shout - shouts shout - shov shov - shove shove - shovel shovel - shovels shovel - show show - showed show - shower shower - showers shower - showest showest - showing show - shown shown - shows show - shreds shred - shrew shrew - shrewd shrewd - shrewdly shrewdli - shrewdness shrewd - shrewish shrewish - shrewishly shrewishli - shrewishness shrewish - shrews shrew - shrewsbury shrewsburi - shriek shriek - shrieking shriek - shrieks shriek - shrieve shriev - shrift shrift - shrill shrill - shriller shriller - shrills shrill - shrilly shrilli - shrimp shrimp - shrine shrine - shrink shrink - shrinking shrink - shrinks shrink - shriv shriv - shrive shrive - shriver shriver - shrives shrive - shriving shrive - shroud shroud - shrouded shroud - shrouding shroud - shrouds shroud - shrove shrove - shrow shrow - shrows shrow - shrub shrub - shrubs shrub - shrug shrug - shrugs shrug - shrunk shrunk - shudd shudd - shudders shudder - shuffl shuffl - shuffle shuffl - shuffled shuffl - shuffling shuffl - shun shun - shunless shunless - shunn shunn - shunned shun - shunning shun - shuns shun - shut shut - shuts shut - shuttle shuttl - shy shy - shylock shylock - si si - sibyl sibyl - sibylla sibylla - sibyls sibyl - sicil sicil - sicilia sicilia - sicilian sicilian - sicilius siciliu - sicils sicil - sicily sicili - sicinius siciniu - sick sick - sicken sicken - sickens sicken - sicker sicker - sickle sickl - sicklemen sicklemen - sicklied sickli - sickliness sickli - sickly sickli - sickness sick - sicles sicl - sicyon sicyon - side side - sided side - sides side - siege sieg - sieges sieg - sienna sienna - sies si - sieve siev - sift sift - sifted sift - sigeia sigeia - sigh sigh - sighed sigh - sighing sigh - sighs sigh - sight sight - sighted sight - sightless sightless - sightly sightli - sights sight - sign sign - signal signal - signet signet - signieur signieur - significant signific - significants signific - signified signifi - signifies signifi - signify signifi - signifying signifi - signior signior - signiories signiori - signiors signior - signiory signiori - signor signor - signories signori - signs sign - signum signum - silenc silenc - silence silenc - silenced silenc - silencing silenc - silent silent - silently silent - silius siliu - silk silk - silken silken - silkman silkman - silks silk - silliest silliest - silliness silli - silling sill - silly silli - silva silva - silver silver - silvered silver - silverly silverli - silvia silvia - silvius silviu - sima sima - simile simil - similes simil - simois simoi - simon simon - simony simoni - simp simp - simpcox simpcox - simple simpl - simpleness simpl - simpler simpler - simples simpl - simplicity simplic - simply simpli - simular simular - simulation simul - sin sin - since sinc - sincere sincer - sincerely sincer - sincerity sincer - sinel sinel - sinew sinew - sinewed sinew - sinews sinew - sinewy sinewi - sinful sin - sinfully sinfulli - sing sing - singe sing - singeing sing - singer singer - singes sing - singeth singeth - singing sing - single singl - singled singl - singleness singl - singly singli - sings sing - singular singular - singulariter singularit - singularities singular - singularity singular - singuled singul - sinister sinist - sink sink - sinking sink - sinks sink - sinn sinn - sinner sinner - sinners sinner - sinning sin - sinon sinon - sins sin - sip sip - sipping sip - sir sir - sire sire - siren siren - sirrah sirrah - sirs sir - sist sist - sister sister - sisterhood sisterhood - sisterly sisterli - sisters sister - sit sit - sith sith - sithence sithenc - sits sit - sitting sit - situate situat - situation situat - situations situat - siward siward - six six - sixpence sixpenc - sixpences sixpenc - sixpenny sixpenni - sixteen sixteen - sixth sixth - sixty sixti - siz siz - size size - sizes size - sizzle sizzl - skains skain - skamble skambl - skein skein - skelter skelter - skies ski - skilful skil - skilfully skilfulli - skill skill - skilless skilless - skillet skillet - skillful skill - skills skill - skim skim - skimble skimbl - skin skin - skinker skinker - skinny skinni - skins skin - skip skip - skipp skipp - skipper skipper - skipping skip - skirmish skirmish - skirmishes skirmish - skirr skirr - skirted skirt - skirts skirt - skittish skittish - skulking skulk - skull skull - skulls skull - sky sky - skyey skyei - skyish skyish - slab slab - slack slack - slackly slackli - slackness slack - slain slain - slake slake - sland sland - slander slander - slandered slander - slanderer slander - slanderers slander - slandering slander - slanderous slander - slanders slander - slash slash - slaught slaught - slaughter slaughter - slaughtered slaughter - slaughterer slaughter - slaughterman slaughterman - slaughtermen slaughtermen - slaughterous slaughter - slaughters slaughter - slave slave - slaver slaver - slavery slaveri - slaves slave - slavish slavish - slay slai - slayeth slayeth - slaying slai - slays slai - sleave sleav - sledded sled - sleek sleek - sleekly sleekli - sleep sleep - sleeper sleeper - sleepers sleeper - sleepest sleepest - sleeping sleep - sleeps sleep - sleepy sleepi - sleeve sleev - sleeves sleev - sleid sleid - sleided sleid - sleight sleight - sleights sleight - slender slender - slenderer slender - slenderly slenderli - slept slept - slew slew - slewest slewest - slice slice - slid slid - slide slide - slides slide - sliding slide - slight slight - slighted slight - slightest slightest - slightly slightli - slightness slight - slights slight - slily slili - slime slime - slimy slimi - slings sling - slink slink - slip slip - slipp slipp - slipper slipper - slippers slipper - slippery slipperi - slips slip - slish slish - slit slit - sliver sliver - slobb slobb - slomber slomber - slop slop - slope slope - slops slop - sloth sloth - slothful sloth - slough slough - slovenly slovenli - slovenry slovenri - slow slow - slower slower - slowly slowli - slowness slow - slubber slubber - slug slug - sluggard sluggard - sluggardiz sluggardiz - sluggish sluggish - sluic sluic - slumb slumb - slumber slumber - slumbers slumber - slumbery slumberi - slunk slunk - slut slut - sluts slut - sluttery slutteri - sluttish sluttish - sluttishness sluttish - sly sly - slys sly - smack smack - smacking smack - smacks smack - small small - smaller smaller - smallest smallest - smallness small - smalus smalu - smart smart - smarting smart - smartly smartli - smatch smatch - smatter smatter - smear smear - smell smell - smelling smell - smells smell - smelt smelt - smil smil - smile smile - smiled smile - smiles smile - smilest smilest - smilets smilet - smiling smile - smilingly smilingli - smirch smirch - smirched smirch - smit smit - smite smite - smites smite - smith smith - smithfield smithfield - smock smock - smocks smock - smok smok - smoke smoke - smoked smoke - smokes smoke - smoking smoke - smoky smoki - smooth smooth - smoothed smooth - smoothing smooth - smoothly smoothli - smoothness smooth - smooths smooth - smote smote - smoth smoth - smother smother - smothered smother - smothering smother - smug smug - smulkin smulkin - smutch smutch - snaffle snaffl - snail snail - snails snail - snake snake - snakes snake - snaky snaki - snap snap - snapp snapp - snapper snapper - snar snar - snare snare - snares snare - snarl snarl - snarleth snarleth - snarling snarl - snatch snatch - snatchers snatcher - snatches snatch - snatching snatch - sneak sneak - sneaking sneak - sneap sneap - sneaping sneap - sneck sneck - snip snip - snipe snipe - snipt snipt - snore snore - snores snore - snoring snore - snorting snort - snout snout - snow snow - snowballs snowbal - snowed snow - snowy snowi - snuff snuff - snuffs snuff - snug snug - so so - soak soak - soaking soak - soaks soak - soar soar - soaring soar - soars soar - sob sob - sobbing sob - sober sober - soberly soberli - sobriety sobrieti - sobs sob - sociable sociabl - societies societi - society societi - socks sock - socrates socrat - sod sod - sodden sodden - soe soe - soever soever - soft soft - soften soften - softens soften - softer softer - softest softest - softly softli - softness soft - soil soil - soiled soil - soilure soilur - soit soit - sojourn sojourn - sol sol - sola sola - solace solac - solanio solanio - sold sold - soldat soldat - solder solder - soldest soldest - soldier soldier - soldiers soldier - soldiership soldiership - sole sole - solely sole - solem solem - solemn solemn - solemness solem - solemnities solemn - solemnity solemn - solemniz solemniz - solemnize solemn - solemnized solemn - solemnly solemnli - soles sole - solicit solicit - solicitation solicit - solicited solicit - soliciting solicit - solicitings solicit - solicitor solicitor - solicits solicit - solid solid - solidares solidar - solidity solid - solinus solinu - solitary solitari - solomon solomon - solon solon - solum solum - solus solu - solyman solyman - some some - somebody somebodi - someone someon - somerset somerset - somerville somervil - something someth - sometime sometim - sometimes sometim - somever somev - somewhat somewhat - somewhere somewher - somewhither somewhith - somme somm - son son - sonance sonanc - song song - songs song - sonnet sonnet - sonneting sonnet - sonnets sonnet - sons son - sont sont - sonties sonti - soon soon - sooner sooner - soonest soonest - sooth sooth - soothe sooth - soothers soother - soothing sooth - soothsay soothsai - soothsayer soothsay - sooty sooti - sop sop - sophister sophist - sophisticated sophist - sophy sophi - sops sop - sorcerer sorcer - sorcerers sorcer - sorceress sorceress - sorceries sorceri - sorcery sorceri - sore sore - sorel sorel - sorely sore - sorer sorer - sores sore - sorrier sorrier - sorriest sorriest - sorrow sorrow - sorrowed sorrow - sorrowest sorrowest - sorrowful sorrow - sorrowing sorrow - sorrows sorrow - sorry sorri - sort sort - sortance sortanc - sorted sort - sorting sort - sorts sort - sossius sossiu - sot sot - soto soto - sots sot - sottish sottish - soud soud - sought sought - soul soul - sould sould - soulless soulless - souls soul - sound sound - sounded sound - sounder sounder - soundest soundest - sounding sound - soundless soundless - soundly soundli - soundness sound - soundpost soundpost - sounds sound - sour sour - source sourc - sources sourc - sourest sourest - sourly sourli - sours sour - sous sou - souse sous - south south - southam southam - southampton southampton - southerly southerli - southern southern - southward southward - southwark southwark - southwell southwel - souviendrai souviendrai - sov sov - sovereign sovereign - sovereignest sovereignest - sovereignly sovereignli - sovereignty sovereignti - sovereignvours sovereignvour - sow sow - sowing sow - sowl sowl - sowter sowter - space space - spaces space - spacious spaciou - spade spade - spades spade - spain spain - spak spak - spake spake - spakest spakest - span span - spangle spangl - spangled spangl - spaniard spaniard - spaniel spaniel - spaniels spaniel - spanish spanish - spann spann - spans span - spar spar - spare spare - spares spare - sparing spare - sparingly sparingli - spark spark - sparkle sparkl - sparkles sparkl - sparkling sparkl - sparks spark - sparrow sparrow - sparrows sparrow - sparta sparta - spartan spartan - spavin spavin - spavins spavin - spawn spawn - speak speak - speaker speaker - speakers speaker - speakest speakest - speaketh speaketh - speaking speak - speaks speak - spear spear - speargrass speargrass - spears spear - special special - specialities special - specially special - specialties specialti - specialty specialti - specify specifi - speciously specious - spectacle spectacl - spectacled spectacl - spectacles spectacl - spectators spectat - spectatorship spectatorship - speculation specul - speculations specul - speculative specul - sped sped - speech speech - speeches speech - speechless speechless - speed speed - speeded speed - speedier speedier - speediest speediest - speedily speedili - speediness speedi - speeding speed - speeds speed - speedy speedi - speens speen - spell spell - spelling spell - spells spell - spelt spelt - spencer spencer - spend spend - spendest spendest - spending spend - spends spend - spendthrift spendthrift - spent spent - sperato sperato - sperm sperm - spero spero - sperr sperr - spher spher - sphere sphere - sphered sphere - spheres sphere - spherical spheric - sphery spheri - sphinx sphinx - spice spice - spiced spice - spicery spiceri - spices spice - spider spider - spiders spider - spied spi - spies spi - spieth spieth - spightfully spightfulli - spigot spigot - spill spill - spilling spill - spills spill - spilt spilt - spilth spilth - spin spin - spinii spinii - spinners spinner - spinster spinster - spinsters spinster - spire spire - spirit spirit - spirited spirit - spiritless spiritless - spirits spirit - spiritual spiritu - spiritualty spiritualti - spirt spirt - spit spit - spital spital - spite spite - spited spite - spiteful spite - spites spite - spits spit - spitted spit - spitting spit - splay splai - spleen spleen - spleenful spleen - spleens spleen - spleeny spleeni - splendour splendour - splenitive splenit - splinter splinter - splinters splinter - split split - splits split - splitted split - splitting split - spoil spoil - spoils spoil - spok spok - spoke spoke - spoken spoken - spokes spoke - spokesman spokesman - sponge spong - spongy spongi - spoon spoon - spoons spoon - sport sport - sportful sport - sporting sport - sportive sportiv - sports sport - spot spot - spotless spotless - spots spot - spotted spot - spousal spousal - spouse spous - spout spout - spouting spout - spouts spout - sprag sprag - sprang sprang - sprat sprat - sprawl sprawl - spray sprai - sprays sprai - spread spread - spreading spread - spreads spread - sprighted spright - sprightful spright - sprightly sprightli - sprigs sprig - spring spring - springe spring - springes spring - springeth springeth - springhalt springhalt - springing spring - springs spring - springtime springtim - sprinkle sprinkl - sprinkles sprinkl - sprite sprite - sprited sprite - spritely sprite - sprites sprite - spriting sprite - sprout sprout - spruce spruce - sprung sprung - spun spun - spur spur - spurio spurio - spurn spurn - spurns spurn - spurr spurr - spurrer spurrer - spurring spur - spurs spur - spy spy - spying spy - squabble squabbl - squadron squadron - squadrons squadron - squand squand - squar squar - square squar - squarer squarer - squares squar - squash squash - squeak squeak - squeaking squeak - squeal squeal - squealing squeal - squeezes squeez - squeezing squeez - squele squel - squier squier - squints squint - squiny squini - squire squir - squires squir - squirrel squirrel - st st - stab stab - stabb stabb - stabbed stab - stabbing stab - stable stabl - stableness stabl - stables stabl - stablish stablish - stablishment stablish - stabs stab - stacks stack - staff staff - stafford stafford - staffords stafford - staffordshire staffordshir - stag stag - stage stage - stages stage - stagger stagger - staggering stagger - staggers stagger - stags stag - staid staid - staider staider - stain stain - stained stain - staines stain - staineth staineth - staining stain - stainless stainless - stains stain - stair stair - stairs stair - stake stake - stakes stake - stale stale - staled stale - stalk stalk - stalking stalk - stalks stalk - stall stall - stalling stall - stalls stall - stamford stamford - stammer stammer - stamp stamp - stamped stamp - stamps stamp - stanch stanch - stanchless stanchless - stand stand - standard standard - standards standard - stander stander - standers stander - standest standest - standeth standeth - standing stand - stands stand - staniel staniel - stanley stanlei - stanze stanz - stanzo stanzo - stanzos stanzo - staple stapl - staples stapl - star star - stare stare - stared stare - stares stare - staring stare - starings stare - stark stark - starkly starkli - starlight starlight - starling starl - starr starr - starry starri - stars star - start start - started start - starting start - startingly startingli - startle startl - startles startl - starts start - starv starv - starve starv - starved starv - starvelackey starvelackei - starveling starvel - starveth starveth - starving starv - state state - statelier stateli - stately state - states state - statesman statesman - statesmen statesmen - statilius statiliu - station station - statist statist - statists statist - statue statu - statues statu - stature statur - statures statur - statute statut - statutes statut - stave stave - staves stave - stay stai - stayed stai - stayest stayest - staying stai - stays stai - stead stead - steaded stead - steadfast steadfast - steadier steadier - steads stead - steal steal - stealer stealer - stealers stealer - stealing steal - steals steal - stealth stealth - stealthy stealthi - steed steed - steeds steed - steel steel - steeled steel - steely steeli - steep steep - steeped steep - steeple steepl - steeples steepl - steeps steep - steepy steepi - steer steer - steerage steerag - steering steer - steers steer - stelled stell - stem stem - stemming stem - stench stench - step step - stepdame stepdam - stephano stephano - stephen stephen - stepmothers stepmoth - stepp stepp - stepping step - steps step - sterile steril - sterility steril - sterling sterl - stern stern - sternage sternag - sterner sterner - sternest sternest - sternness stern - steterat steterat - stew stew - steward steward - stewards steward - stewardship stewardship - stewed stew - stews stew - stick stick - sticking stick - stickler stickler - sticks stick - stiff stiff - stiffen stiffen - stiffly stiffli - stifle stifl - stifled stifl - stifles stifl - stigmatic stigmat - stigmatical stigmat - stile stile - still still - stiller stiller - stillest stillest - stillness still - stilly stilli - sting sting - stinging sting - stingless stingless - stings sting - stink stink - stinking stink - stinkingly stinkingli - stinks stink - stint stint - stinted stint - stints stint - stir stir - stirr stirr - stirred stir - stirrer stirrer - stirrers stirrer - stirreth stirreth - stirring stir - stirrup stirrup - stirrups stirrup - stirs stir - stitchery stitcheri - stitches stitch - stithied stithi - stithy stithi - stoccadoes stoccado - stoccata stoccata - stock stock - stockfish stockfish - stocking stock - stockings stock - stockish stockish - stocks stock - stog stog - stogs stog - stoics stoic - stokesly stokesli - stol stol - stole stole - stolen stolen - stolest stolest - stomach stomach - stomachers stomach - stomaching stomach - stomachs stomach - ston ston - stone stone - stonecutter stonecutt - stones stone - stonish stonish - stony stoni - stood stood - stool stool - stools stool - stoop stoop - stooping stoop - stoops stoop - stop stop - stope stope - stopp stopp - stopped stop - stopping stop - stops stop - stor stor - store store - storehouse storehous - storehouses storehous - stores store - stories stori - storm storm - stormed storm - storming storm - storms storm - stormy stormi - story stori - stoup stoup - stoups stoup - stout stout - stouter stouter - stoutly stoutli - stoutness stout - stover stover - stow stow - stowage stowag - stowed stow - strachy strachi - stragglers straggler - straggling straggl - straight straight - straightest straightest - straightway straightwai - strain strain - strained strain - straining strain - strains strain - strait strait - straited strait - straiter straiter - straitly straitli - straitness strait - straits strait - strand strand - strange strang - strangely strang - strangeness strang - stranger stranger - strangers stranger - strangest strangest - strangle strangl - strangled strangl - strangler strangler - strangles strangl - strangling strangl - strappado strappado - straps strap - stratagem stratagem - stratagems stratagem - stratford stratford - strato strato - straw straw - strawberries strawberri - strawberry strawberri - straws straw - strawy strawi - stray strai - straying strai - strays strai - streak streak - streaks streak - stream stream - streamers streamer - streaming stream - streams stream - streching strech - street street - streets street - strength strength - strengthen strengthen - strengthened strengthen - strengthless strengthless - strengths strength - stretch stretch - stretched stretch - stretches stretch - stretching stretch - strew strew - strewing strew - strewings strew - strewments strewment - stricken stricken - strict strict - stricter stricter - strictest strictest - strictly strictli - stricture strictur - stride stride - strides stride - striding stride - strife strife - strifes strife - strik strik - strike strike - strikers striker - strikes strike - strikest strikest - striking strike - string string - stringless stringless - strings string - strip strip - stripes stripe - stripling stripl - striplings stripl - stripp stripp - stripping strip - striv striv - strive strive - strives strive - striving strive - strok strok - stroke stroke - strokes stroke - strond strond - stronds strond - strong strong - stronger stronger - strongest strongest - strongly strongli - strooke strook - strossers strosser - strove strove - strown strown - stroy stroi - struck struck - strucken strucken - struggle struggl - struggles struggl - struggling struggl - strumpet strumpet - strumpeted strumpet - strumpets strumpet - strung strung - strut strut - struts strut - strutted strut - strutting strut - stubble stubbl - stubborn stubborn - stubbornest stubbornest - stubbornly stubbornli - stubbornness stubborn - stuck stuck - studded stud - student student - students student - studied studi - studies studi - studious studiou - studiously studious - studs stud - study studi - studying studi - stuff stuff - stuffing stuf - stuffs stuff - stumble stumbl - stumbled stumbl - stumblest stumblest - stumbling stumbl - stump stump - stumps stump - stung stung - stupefy stupefi - stupid stupid - stupified stupifi - stuprum stuprum - sturdy sturdi - sty sty - styga styga - stygian stygian - styl styl - style style - styx styx - su su - sub sub - subcontracted subcontract - subdu subdu - subdue subdu - subdued subdu - subduements subduement - subdues subdu - subduing subdu - subject subject - subjected subject - subjection subject - subjects subject - submerg submerg - submission submiss - submissive submiss - submit submit - submits submit - submitting submit - suborn suborn - subornation suborn - suborned suborn - subscrib subscrib - subscribe subscrib - subscribed subscrib - subscribes subscrib - subscription subscript - subsequent subsequ - subsidies subsidi - subsidy subsidi - subsist subsist - subsisting subsist - substance substanc - substances substanc - substantial substanti - substitute substitut - substituted substitut - substitutes substitut - substitution substitut - subtile subtil - subtilly subtilli - subtle subtl - subtleties subtleti - subtlety subtleti - subtly subtli - subtractors subtractor - suburbs suburb - subversion subvers - subverts subvert - succedant succed - succeed succe - succeeded succeed - succeeders succeed - succeeding succeed - succeeds succe - success success - successantly successantli - successes success - successful success - successfully successfulli - succession success - successive success - successively success - successor successor - successors successor - succour succour - succours succour - such such - suck suck - sucker sucker - suckers sucker - sucking suck - suckle suckl - sucks suck - sudden sudden - suddenly suddenli - sue sue - sued su - suerly suerli - sues sue - sueth sueth - suff suff - suffer suffer - sufferance suffer - sufferances suffer - suffered suffer - suffering suffer - suffers suffer - suffic suffic - suffice suffic - sufficed suffic - suffices suffic - sufficeth sufficeth - sufficiency suffici - sufficient suffici - sufficiently suffici - sufficing suffic - sufficit sufficit - suffigance suffig - suffocate suffoc - suffocating suffoc - suffocation suffoc - suffolk suffolk - suffrage suffrag - suffrages suffrag - sug sug - sugar sugar - sugarsop sugarsop - suggest suggest - suggested suggest - suggesting suggest - suggestion suggest - suggestions suggest - suggests suggest - suis sui - suit suit - suitable suitabl - suited suit - suiting suit - suitor suitor - suitors suitor - suits suit - suivez suivez - sullen sullen - sullens sullen - sullied sulli - sullies sulli - sully sulli - sulph sulph - sulpherous sulpher - sulphur sulphur - sulphurous sulphur - sultan sultan - sultry sultri - sum sum - sumless sumless - summ summ - summa summa - summary summari - summer summer - summers summer - summit summit - summon summon - summoners summon - summons summon - sumpter sumpter - sumptuous sumptuou - sumptuously sumptuous - sums sum - sun sun - sunbeams sunbeam - sunburning sunburn - sunburnt sunburnt - sund sund - sunday sundai - sundays sundai - sunder sunder - sunders sunder - sundry sundri - sung sung - sunk sunk - sunken sunken - sunny sunni - sunrising sunris - suns sun - sunset sunset - sunshine sunshin - sup sup - super super - superficial superfici - superficially superfici - superfluity superflu - superfluous superflu - superfluously superflu - superflux superflux - superior superior - supernal supern - supernatural supernatur - superpraise superprais - superscript superscript - superscription superscript - superserviceable superservic - superstition superstit - superstitious superstiti - superstitiously superstiti - supersubtle supersubtl - supervise supervis - supervisor supervisor - supp supp - supper supper - suppers supper - suppertime suppertim - supping sup - supplant supplant - supple suppl - suppler suppler - suppliance supplianc - suppliant suppliant - suppliants suppliant - supplicant supplic - supplication supplic - supplications supplic - supplie suppli - supplied suppli - supplies suppli - suppliest suppliest - supply suppli - supplyant supplyant - supplying suppli - supplyment supplyment - support support - supportable support - supportance support - supported support - supporter support - supporters support - supporting support - supportor supportor - suppos suppo - supposal suppos - suppose suppos - supposed suppos - supposes suppos - supposest supposest - supposing suppos - supposition supposit - suppress suppress - suppressed suppress - suppresseth suppresseth - supremacy supremaci - supreme suprem - sups sup - sur sur - surance suranc - surcease surceas - surd surd - sure sure - surecard surecard - surely sure - surer surer - surest surest - sureties sureti - surety sureti - surfeit surfeit - surfeited surfeit - surfeiter surfeit - surfeiting surfeit - surfeits surfeit - surge surg - surgeon surgeon - surgeons surgeon - surgere surger - surgery surgeri - surges surg - surly surli - surmis surmi - surmise surmis - surmised surmis - surmises surmis - surmount surmount - surmounted surmount - surmounts surmount - surnam surnam - surname surnam - surnamed surnam - surpasseth surpasseth - surpassing surpass - surplice surplic - surplus surplu - surpris surpri - surprise surpris - surprised surpris - surrender surrend - surrey surrei - surreys surrei - survey survei - surveyest surveyest - surveying survei - surveyor surveyor - surveyors surveyor - surveys survei - survive surviv - survives surviv - survivor survivor - susan susan - suspect suspect - suspected suspect - suspecting suspect - suspects suspect - suspend suspend - suspense suspens - suspicion suspicion - suspicions suspicion - suspicious suspici - suspiration suspir - suspire suspir - sust sust - sustain sustain - sustaining sustain - sutler sutler - sutton sutton - suum suum - swabber swabber - swaddling swaddl - swag swag - swagg swagg - swagger swagger - swaggerer swagger - swaggerers swagger - swaggering swagger - swain swain - swains swain - swallow swallow - swallowed swallow - swallowing swallow - swallows swallow - swam swam - swan swan - swans swan - sward sward - sware sware - swarm swarm - swarming swarm - swart swart - swarth swarth - swarths swarth - swarthy swarthi - swashers swasher - swashing swash - swath swath - swathing swath - swathling swathl - sway swai - swaying swai - sways swai - swear swear - swearer swearer - swearers swearer - swearest swearest - swearing swear - swearings swear - swears swear - sweat sweat - sweaten sweaten - sweating sweat - sweats sweat - sweaty sweati - sweep sweep - sweepers sweeper - sweeps sweep - sweet sweet - sweeten sweeten - sweetens sweeten - sweeter sweeter - sweetest sweetest - sweetheart sweetheart - sweeting sweet - sweetly sweetli - sweetmeats sweetmeat - sweetness sweet - sweets sweet - swell swell - swelling swell - swellings swell - swells swell - swelter swelter - sweno sweno - swept swept - swerve swerv - swerver swerver - swerving swerv - swift swift - swifter swifter - swiftest swiftest - swiftly swiftli - swiftness swift - swill swill - swills swill - swim swim - swimmer swimmer - swimmers swimmer - swimming swim - swims swim - swine swine - swineherds swineherd - swing swing - swinge swing - swinish swinish - swinstead swinstead - switches switch - swits swit - switzers switzer - swol swol - swoll swoll - swoln swoln - swoon swoon - swooned swoon - swooning swoon - swoons swoon - swoop swoop - swoopstake swoopstak - swor swor - sword sword - sworder sworder - swords sword - swore swore - sworn sworn - swounded swound - swounds swound - swum swum - swung swung - sy sy - sycamore sycamor - sycorax sycorax - sylla sylla - syllable syllabl - syllables syllabl - syllogism syllog - symbols symbol - sympathise sympathis - sympathiz sympathiz - sympathize sympath - sympathized sympath - sympathy sympathi - synagogue synagogu - synod synod - synods synod - syracuse syracus - syracusian syracusian - syracusians syracusian - syria syria - syrups syrup - t t - ta ta - taber taber - table tabl - tabled tabl - tables tabl - tablet tablet - tabor tabor - taborer tabor - tabors tabor - tabourines tabourin - taciturnity taciturn - tack tack - tackle tackl - tackled tackl - tackles tackl - tackling tackl - tacklings tackl - taddle taddl - tadpole tadpol - taffeta taffeta - taffety taffeti - tag tag - tagrag tagrag - tah tah - tail tail - tailor tailor - tailors tailor - tails tail - taint taint - tainted taint - tainting taint - taints taint - tainture taintur - tak tak - take take - taken taken - taker taker - takes take - takest takest - taketh taketh - taking take - tal tal - talbot talbot - talbotites talbotit - talbots talbot - tale tale - talent talent - talents talent - taleporter taleport - tales tale - talk talk - talked talk - talker talker - talkers talker - talkest talkest - talking talk - talks talk - tall tall - taller taller - tallest tallest - tallies talli - tallow tallow - tally talli - talons talon - tam tam - tambourines tambourin - tame tame - tamed tame - tamely tame - tameness tame - tamer tamer - tames tame - taming tame - tamora tamora - tamworth tamworth - tan tan - tang tang - tangle tangl - tangled tangl - tank tank - tanlings tanl - tann tann - tanned tan - tanner tanner - tanquam tanquam - tanta tanta - tantaene tantaen - tap tap - tape tape - taper taper - tapers taper - tapestries tapestri - tapestry tapestri - taphouse taphous - tapp tapp - tapster tapster - tapsters tapster - tar tar - tardied tardi - tardily tardili - tardiness tardi - tardy tardi - tarentum tarentum - targe targ - targes targ - target target - targets target - tarpeian tarpeian - tarquin tarquin - tarquins tarquin - tarr tarr - tarre tarr - tarriance tarrianc - tarried tarri - tarries tarri - tarry tarri - tarrying tarri - tart tart - tartar tartar - tartars tartar - tartly tartli - tartness tart - task task - tasker tasker - tasking task - tasks task - tassel tassel - taste tast - tasted tast - tastes tast - tasting tast - tatt tatt - tatter tatter - tattered tatter - tatters tatter - tattle tattl - tattling tattl - tattlings tattl - taught taught - taunt taunt - taunted taunt - taunting taunt - tauntingly tauntingli - taunts taunt - taurus tauru - tavern tavern - taverns tavern - tavy tavi - tawdry tawdri - tawny tawni - tax tax - taxation taxat - taxations taxat - taxes tax - taxing tax - tc tc - te te - teach teach - teacher teacher - teachers teacher - teaches teach - teachest teachest - teacheth teacheth - teaching teach - team team - tear tear - tearful tear - tearing tear - tears tear - tearsheet tearsheet - teat teat - tedious tediou - tediously tedious - tediousness tedious - teem teem - teeming teem - teems teem - teen teen - teeth teeth - teipsum teipsum - telamon telamon - telamonius telamoniu - tell tell - teller teller - telling tell - tells tell - tellus tellu - temp temp - temper temper - temperality temper - temperance temper - temperate temper - temperately temper - tempers temper - tempest tempest - tempests tempest - tempestuous tempestu - temple templ - temples templ - temporal tempor - temporary temporari - temporiz temporiz - temporize tempor - temporizer tempor - temps temp - tempt tempt - temptation temptat - temptations temptat - tempted tempt - tempter tempter - tempters tempter - tempteth tempteth - tempting tempt - tempts tempt - ten ten - tenable tenabl - tenant tenant - tenantius tenantiu - tenantless tenantless - tenants tenant - tench tench - tend tend - tendance tendanc - tended tend - tender tender - tendered tender - tenderly tenderli - tenderness tender - tenders tender - tending tend - tends tend - tenedos tenedo - tenement tenement - tenements tenement - tenfold tenfold - tennis tenni - tenour tenour - tenours tenour - tens ten - tent tent - tented tent - tenth tenth - tenths tenth - tents tent - tenure tenur - tenures tenur - tercel tercel - tereus tereu - term term - termagant termag - termed term - terminations termin - termless termless - terms term - terra terra - terrace terrac - terram terram - terras terra - terre terr - terrene terren - terrestrial terrestri - terrible terribl - terribly terribl - territories territori - territory territori - terror terror - terrors terror - tertian tertian - tertio tertio - test test - testament testament - tested test - tester tester - testern testern - testify testifi - testimonied testimoni - testimonies testimoni - testimony testimoni - testiness testi - testril testril - testy testi - tetchy tetchi - tether tether - tetter tetter - tevil tevil - tewksbury tewksburi - text text - tgv tgv - th th - thaes thae - thames thame - than than - thane thane - thanes thane - thank thank - thanked thank - thankful thank - thankfully thankfulli - thankfulness thank - thanking thank - thankings thank - thankless thankless - thanks thank - thanksgiving thanksgiv - thasos thaso - that that - thatch thatch - thaw thaw - thawing thaw - thaws thaw - the the - theatre theatr - theban theban - thebes thebe - thee thee - theft theft - thefts theft - thein thein - their their - theirs their - theise theis - them them - theme theme - themes theme - themselves themselv - then then - thence thenc - thenceforth thenceforth - theoric theoric - there there - thereabout thereabout - thereabouts thereabout - thereafter thereaft - thereat thereat - thereby therebi - therefore therefor - therein therein - thereof thereof - thereon thereon - thereto thereto - thereunto thereunto - thereupon thereupon - therewith therewith - therewithal therewith - thersites thersit - these these - theseus theseu - thessalian thessalian - thessaly thessali - thetis theti - thews thew - they thei - thick thick - thicken thicken - thickens thicken - thicker thicker - thickest thickest - thicket thicket - thickskin thickskin - thief thief - thievery thieveri - thieves thiev - thievish thievish - thigh thigh - thighs thigh - thimble thimbl - thimbles thimbl - thin thin - thine thine - thing thing - things thing - think think - thinkest thinkest - thinking think - thinkings think - thinks think - thinkst thinkst - thinly thinli - third third - thirdly thirdli - thirds third - thirst thirst - thirsting thirst - thirsts thirst - thirsty thirsti - thirteen thirteen - thirties thirti - thirtieth thirtieth - thirty thirti - this thi - thisby thisbi - thisne thisn - thistle thistl - thistles thistl - thither thither - thitherward thitherward - thoas thoa - thomas thoma - thorn thorn - thorns thorn - thorny thorni - thorough thorough - thoroughly thoroughli - those those - thou thou - though though - thought thought - thoughtful thought - thoughts thought - thousand thousand - thousands thousand - thracian thracian - thraldom thraldom - thrall thrall - thralled thrall - thralls thrall - thrash thrash - thrasonical thrason - thread thread - threadbare threadbar - threaden threaden - threading thread - threat threat - threaten threaten - threatening threaten - threatens threaten - threatest threatest - threats threat - three three - threefold threefold - threepence threepenc - threepile threepil - threes three - threescore threescor - thresher thresher - threshold threshold - threw threw - thrice thrice - thrift thrift - thriftless thriftless - thrifts thrift - thrifty thrifti - thrill thrill - thrilling thrill - thrills thrill - thrive thrive - thrived thrive - thrivers thriver - thrives thrive - thriving thrive - throat throat - throats throat - throbbing throb - throbs throb - throca throca - throe throe - throes throe - thromuldo thromuldo - thron thron - throne throne - throned throne - thrones throne - throng throng - thronging throng - throngs throng - throstle throstl - throttle throttl - through through - throughfare throughfar - throughfares throughfar - throughly throughli - throughout throughout - throw throw - thrower thrower - throwest throwest - throwing throw - thrown thrown - throws throw - thrum thrum - thrumm thrumm - thrush thrush - thrust thrust - thrusteth thrusteth - thrusting thrust - thrusts thrust - thumb thumb - thumbs thumb - thump thump - thund thund - thunder thunder - thunderbolt thunderbolt - thunderbolts thunderbolt - thunderer thunder - thunders thunder - thunderstone thunderston - thunderstroke thunderstrok - thurio thurio - thursday thursdai - thus thu - thwack thwack - thwart thwart - thwarted thwart - thwarting thwart - thwartings thwart - thy thy - thyme thyme - thymus thymu - thyreus thyreu - thyself thyself - ti ti - tib tib - tiber tiber - tiberio tiberio - tibey tibei - ticed tice - tick tick - tickl tickl - tickle tickl - tickled tickl - tickles tickl - tickling tickl - ticklish ticklish - tiddle tiddl - tide tide - tides tide - tidings tide - tidy tidi - tie tie - tied ti - ties ti - tiff tiff - tiger tiger - tigers tiger - tight tight - tightly tightli - tike tike - til til - tile tile - till till - tillage tillag - tilly tilli - tilt tilt - tilter tilter - tilth tilth - tilting tilt - tilts tilt - tiltyard tiltyard - tim tim - timandra timandra - timber timber - time time - timeless timeless - timelier timeli - timely time - times time - timon timon - timor timor - timorous timor - timorously timor - tinct tinct - tincture tinctur - tinctures tinctur - tinder tinder - tingling tingl - tinker tinker - tinkers tinker - tinsel tinsel - tiny tini - tip tip - tipp tipp - tippling tippl - tips tip - tipsy tipsi - tiptoe tipto - tir tir - tire tire - tired tire - tires tire - tirest tirest - tiring tire - tirra tirra - tirrits tirrit - tis ti - tish tish - tisick tisick - tissue tissu - titan titan - titania titania - tithe tith - tithed tith - tithing tith - titinius titiniu - title titl - titled titl - titleless titleless - titles titl - tittle tittl - tittles tittl - titular titular - titus titu - tn tn - to to - toad toad - toads toad - toadstool toadstool - toast toast - toasted toast - toasting toast - toasts toast - toaze toaz - toby tobi - tock tock - tod tod - today todai - todpole todpol - tods tod - toe toe - toes toe - tofore tofor - toge toge - toged toge - together togeth - toil toil - toiled toil - toiling toil - toils toil - token token - tokens token - told told - toledo toledo - tolerable toler - toll toll - tolling toll - tom tom - tomb tomb - tombe tomb - tombed tomb - tombless tombless - tomboys tomboi - tombs tomb - tomorrow tomorrow - tomyris tomyri - ton ton - tongs tong - tongu tongu - tongue tongu - tongued tongu - tongueless tongueless - tongues tongu - tonight tonight - too too - took took - tool tool - tools tool - tooth tooth - toothache toothach - toothpick toothpick - toothpicker toothpick - top top - topas topa - topful top - topgallant topgal - topless topless - topmast topmast - topp topp - topping top - topple toppl - topples toppl - tops top - topsail topsail - topsy topsi - torch torch - torchbearer torchbear - torchbearers torchbear - torcher torcher - torches torch - torchlight torchlight - tore tore - torment torment - tormenta tormenta - tormente torment - tormented torment - tormenting torment - tormentors tormentor - torments torment - torn torn - torrent torrent - tortive tortiv - tortoise tortois - tortur tortur - torture tortur - tortured tortur - torturer tortur - torturers tortur - tortures tortur - torturest torturest - torturing tortur - toryne toryn - toss toss - tossed toss - tosseth tosseth - tossing toss - tot tot - total total - totally total - tott tott - tottered totter - totters totter - tou tou - touch touch - touched touch - touches touch - toucheth toucheth - touching touch - touchstone touchston - tough tough - tougher tougher - toughness tough - touraine tourain - tournaments tournament - tours tour - tous tou - tout tout - touze touz - tow tow - toward toward - towardly towardli - towards toward - tower tower - towering tower - towers tower - town town - towns town - township township - townsman townsman - townsmen townsmen - towton towton - toy toi - toys toi - trace trace - traces trace - track track - tract tract - tractable tractabl - trade trade - traded trade - traders trader - trades trade - tradesman tradesman - tradesmen tradesmen - trading trade - tradition tradit - traditional tradit - traduc traduc - traduced traduc - traducement traduc - traffic traffic - traffickers traffick - traffics traffic - tragedian tragedian - tragedians tragedian - tragedies tragedi - tragedy tragedi - tragic tragic - tragical tragic - trail trail - train train - trained train - training train - trains train - trait trait - traitor traitor - traitorly traitorli - traitorous traitor - traitorously traitor - traitors traitor - traitress traitress - traject traject - trammel trammel - trample trampl - trampled trampl - trampling trampl - tranc tranc - trance tranc - tranio tranio - tranquil tranquil - tranquillity tranquil - transcendence transcend - transcends transcend - transferred transfer - transfigur transfigur - transfix transfix - transform transform - transformation transform - transformations transform - transformed transform - transgress transgress - transgresses transgress - transgressing transgress - transgression transgress - translate translat - translated translat - translates translat - translation translat - transmigrates transmigr - transmutation transmut - transparent transpar - transport transport - transportance transport - transported transport - transporting transport - transports transport - transpose transpos - transshape transshap - trap trap - trapp trapp - trappings trap - traps trap - trash trash - travail travail - travails travail - travel travel - traveler travel - traveling travel - travell travel - travelled travel - traveller travel - travellers travel - travellest travellest - travelling travel - travels travel - travers traver - traverse travers - tray trai - treacherous treacher - treacherously treacher - treachers treacher - treachery treacheri - tread tread - treading tread - treads tread - treason treason - treasonable treason - treasonous treason - treasons treason - treasure treasur - treasurer treasur - treasures treasur - treasuries treasuri - treasury treasuri - treat treat - treaties treati - treatise treatis - treats treat - treaty treati - treble trebl - trebled trebl - trebles trebl - trebonius treboniu - tree tree - trees tree - tremble trembl - trembled trembl - trembles trembl - tremblest tremblest - trembling trembl - tremblingly tremblingli - tremor tremor - trempling trempl - trench trench - trenchant trenchant - trenched trench - trencher trencher - trenchering trencher - trencherman trencherman - trenchers trencher - trenches trench - trenching trench - trent trent - tres tre - trespass trespass - trespasses trespass - tressel tressel - tresses tress - treys trei - trial trial - trials trial - trib trib - tribe tribe - tribes tribe - tribulation tribul - tribunal tribun - tribune tribun - tribunes tribun - tributaries tributari - tributary tributari - tribute tribut - tributes tribut - trice trice - trick trick - tricking trick - trickling trickl - tricks trick - tricksy tricksi - trident trident - tried tri - trier trier - trifle trifl - trifled trifl - trifler trifler - trifles trifl - trifling trifl - trigon trigon - trill trill - trim trim - trimly trimli - trimm trimm - trimmed trim - trimming trim - trims trim - trinculo trinculo - trinculos trinculo - trinkets trinket - trip trip - tripartite tripartit - tripe tripe - triple tripl - triplex triplex - tripoli tripoli - tripolis tripoli - tripp tripp - tripping trip - trippingly trippingli - trips trip - tristful trist - triton triton - triumph triumph - triumphant triumphant - triumphantly triumphantli - triumpher triumpher - triumphers triumpher - triumphing triumph - triumphs triumph - triumvir triumvir - triumvirate triumvir - triumvirs triumvir - triumviry triumviri - trivial trivial - troat troat - trod trod - trodden trodden - troiant troiant - troien troien - troilus troilu - troiluses troilus - trojan trojan - trojans trojan - troll troll - tromperies tromperi - trompet trompet - troop troop - trooping troop - troops troop - trop trop - trophies trophi - trophy trophi - tropically tropic - trot trot - troth troth - trothed troth - troths troth - trots trot - trotting trot - trouble troubl - troubled troubl - troubler troubler - troubles troubl - troublesome troublesom - troublest troublest - troublous troublou - trough trough - trout trout - trouts trout - trovato trovato - trow trow - trowel trowel - trowest trowest - troy troi - troyan troyan - troyans troyan - truant truant - truce truce - truckle truckl - trudge trudg - true true - trueborn trueborn - truepenny truepenni - truer truer - truest truest - truie truie - trull trull - trulls trull - truly truli - trump trump - trumpery trumperi - trumpet trumpet - trumpeter trumpet - trumpeters trumpet - trumpets trumpet - truncheon truncheon - truncheoners truncheon - trundle trundl - trunk trunk - trunks trunk - trust trust - trusted trust - truster truster - trusters truster - trusting trust - trusts trust - trusty trusti - truth truth - truths truth - try try - ts ts - tu tu - tuae tuae - tub tub - tubal tubal - tubs tub - tuck tuck - tucket tucket - tuesday tuesdai - tuft tuft - tufts tuft - tug tug - tugg tugg - tugging tug - tuition tuition - tullus tullu - tully tulli - tumble tumbl - tumbled tumbl - tumbler tumbler - tumbling tumbl - tumult tumult - tumultuous tumultu - tun tun - tune tune - tuneable tuneabl - tuned tune - tuners tuner - tunes tune - tunis tuni - tuns tun - tupping tup - turban turban - turbans turban - turbulence turbul - turbulent turbul - turd turd - turf turf - turfy turfi - turk turk - turkey turkei - turkeys turkei - turkish turkish - turks turk - turlygod turlygod - turmoil turmoil - turmoiled turmoil - turn turn - turnbull turnbul - turncoat turncoat - turncoats turncoat - turned turn - turneth turneth - turning turn - turnips turnip - turns turn - turph turph - turpitude turpitud - turquoise turquois - turret turret - turrets turret - turtle turtl - turtles turtl - turvy turvi - tuscan tuscan - tush tush - tut tut - tutor tutor - tutored tutor - tutors tutor - tutto tutto - twain twain - twang twang - twangling twangl - twas twa - tway twai - tweaks tweak - tween tween - twelfth twelfth - twelve twelv - twelvemonth twelvemonth - twentieth twentieth - twenty twenti - twere twere - twice twice - twig twig - twiggen twiggen - twigs twig - twilight twilight - twill twill - twilled twill - twin twin - twine twine - twink twink - twinkle twinkl - twinkled twinkl - twinkling twinkl - twinn twinn - twins twin - twire twire - twist twist - twisted twist - twit twit - twits twit - twitting twit - twixt twixt - two two - twofold twofold - twopence twopenc - twopences twopenc - twos two - twould twould - tyb tyb - tybalt tybalt - tybalts tybalt - tyburn tyburn - tying ty - tyke tyke - tymbria tymbria - type type - types type - typhon typhon - tyrannical tyrann - tyrannically tyrann - tyrannize tyrann - tyrannous tyrann - tyranny tyranni - tyrant tyrant - tyrants tyrant - tyrian tyrian - tyrrel tyrrel - u u - ubique ubiqu - udders udder - udge udg - uds ud - uglier uglier - ugliest ugliest - ugly ugli - ulcer ulcer - ulcerous ulcer - ulysses ulyss - um um - umber umber - umbra umbra - umbrage umbrag - umfrevile umfrevil - umpire umpir - umpires umpir - un un - unable unabl - unaccommodated unaccommod - unaccompanied unaccompani - unaccustom unaccustom - unaching unach - unacquainted unacquaint - unactive unact - unadvis unadvi - unadvised unadvis - unadvisedly unadvisedli - unagreeable unagre - unanel unanel - unanswer unansw - unappeas unappea - unapproved unapprov - unapt unapt - unaptness unapt - unarm unarm - unarmed unarm - unarms unarm - unassail unassail - unassailable unassail - unattainted unattaint - unattempted unattempt - unattended unattend - unauspicious unauspici - unauthorized unauthor - unavoided unavoid - unawares unawar - unback unback - unbak unbak - unbanded unband - unbar unbar - unbarb unbarb - unbashful unbash - unbated unbat - unbatter unbatt - unbecoming unbecom - unbefitting unbefit - unbegot unbegot - unbegotten unbegotten - unbelieved unbeliev - unbend unbend - unbent unbent - unbewail unbewail - unbid unbid - unbidden unbidden - unbind unbind - unbinds unbind - unbitted unbit - unbless unbless - unblest unblest - unbloodied unbloodi - unblown unblown - unbodied unbodi - unbolt unbolt - unbolted unbolt - unbonneted unbonnet - unbookish unbookish - unborn unborn - unbosom unbosom - unbound unbound - unbounded unbound - unbow unbow - unbowed unbow - unbrac unbrac - unbraced unbrac - unbraided unbraid - unbreathed unbreath - unbred unbr - unbreech unbreech - unbridled unbridl - unbroke unbrok - unbruis unbrui - unbruised unbruis - unbuckle unbuckl - unbuckles unbuckl - unbuckling unbuckl - unbuild unbuild - unburden unburden - unburdens unburden - unburied unburi - unburnt unburnt - unburthen unburthen - unbutton unbutton - unbuttoning unbutton - uncapable uncap - uncape uncap - uncase uncas - uncasing uncas - uncaught uncaught - uncertain uncertain - uncertainty uncertainti - unchain unchain - unchanging unchang - uncharge uncharg - uncharged uncharg - uncharitably uncharit - unchary unchari - unchaste unchast - uncheck uncheck - unchilded unchild - uncivil uncivil - unclaim unclaim - unclasp unclasp - uncle uncl - unclean unclean - uncleanliness uncleanli - uncleanly uncleanli - uncleanness unclean - uncles uncl - unclew unclew - unclog unclog - uncoined uncoin - uncolted uncolt - uncomeliness uncomeli - uncomfortable uncomfort - uncompassionate uncompassion - uncomprehensive uncomprehens - unconfinable unconfin - unconfirm unconfirm - unconfirmed unconfirm - unconquer unconqu - unconquered unconqu - unconsidered unconsid - unconstant unconst - unconstrain unconstrain - unconstrained unconstrain - uncontemn uncontemn - uncontroll uncontrol - uncorrected uncorrect - uncounted uncount - uncouple uncoupl - uncourteous uncourt - uncouth uncouth - uncover uncov - uncovered uncov - uncropped uncrop - uncross uncross - uncrown uncrown - unction unction - unctuous unctuou - uncuckolded uncuckold - uncurable uncur - uncurbable uncurb - uncurbed uncurb - uncurls uncurl - uncurrent uncurr - uncurse uncurs - undaunted undaunt - undeaf undeaf - undeck undeck - undeeded undeed - under under - underbearing underbear - underborne underborn - undercrest undercrest - underfoot underfoot - undergo undergo - undergoes undergo - undergoing undergo - undergone undergon - underground underground - underhand underhand - underlings underl - undermine undermin - underminers undermin - underneath underneath - underprizing underpr - underprop underprop - understand understand - understandeth understandeth - understanding understand - understandings understand - understands understand - understood understood - underta underta - undertake undertak - undertakeing undertak - undertaker undertak - undertakes undertak - undertaking undertak - undertakings undertak - undertook undertook - undervalu undervalu - undervalued undervalu - underwent underw - underwrit underwrit - underwrite underwrit - undescried undescri - undeserved undeserv - undeserver undeserv - undeservers undeserv - undeserving undeserv - undetermin undetermin - undid undid - undinted undint - undiscernible undiscern - undiscover undiscov - undishonoured undishonour - undispos undispo - undistinguishable undistinguish - undistinguished undistinguish - undividable undivid - undivided undivid - undivulged undivulg - undo undo - undoes undo - undoing undo - undone undon - undoubted undoubt - undoubtedly undoubtedli - undream undream - undress undress - undressed undress - undrown undrown - unduteous undut - undutiful unduti - une un - uneared unear - unearned unearn - unearthly unearthli - uneasines uneasin - uneasy uneasi - uneath uneath - uneducated uneduc - uneffectual uneffectu - unelected unelect - unequal unequ - uneven uneven - unexamin unexamin - unexecuted unexecut - unexpected unexpect - unexperienc unexperienc - unexperient unexperi - unexpressive unexpress - unfair unfair - unfaithful unfaith - unfallible unfal - unfam unfam - unfashionable unfashion - unfasten unfasten - unfather unfath - unfathered unfath - unfed unf - unfeed unfe - unfeeling unfeel - unfeigned unfeign - unfeignedly unfeignedli - unfellowed unfellow - unfelt unfelt - unfenced unfenc - unfilial unfili - unfill unfil - unfinish unfinish - unfirm unfirm - unfit unfit - unfitness unfit - unfix unfix - unfledg unfledg - unfold unfold - unfolded unfold - unfoldeth unfoldeth - unfolding unfold - unfolds unfold - unfool unfool - unforc unforc - unforced unforc - unforfeited unforfeit - unfortified unfortifi - unfortunate unfortun - unfought unfought - unfrequented unfrequ - unfriended unfriend - unfurnish unfurnish - ungain ungain - ungalled ungal - ungart ungart - ungarter ungart - ungenitur ungenitur - ungentle ungentl - ungentleness ungentl - ungently ungent - ungird ungird - ungodly ungodli - ungor ungor - ungot ungot - ungotten ungotten - ungovern ungovern - ungracious ungraci - ungrateful ungrat - ungravely ungrav - ungrown ungrown - unguarded unguard - unguem unguem - unguided unguid - unhack unhack - unhair unhair - unhallow unhallow - unhallowed unhallow - unhand unhand - unhandled unhandl - unhandsome unhandsom - unhang unhang - unhappied unhappi - unhappily unhappili - unhappiness unhappi - unhappy unhappi - unhardened unharden - unharm unharm - unhatch unhatch - unheard unheard - unhearts unheart - unheedful unheed - unheedfully unheedfulli - unheedy unheedi - unhelpful unhelp - unhidden unhidden - unholy unholi - unhop unhop - unhopefullest unhopefullest - unhorse unhors - unhospitable unhospit - unhous unhou - unhoused unhous - unhurtful unhurt - unicorn unicorn - unicorns unicorn - unimproved unimprov - uninhabitable uninhabit - uninhabited uninhabit - unintelligent unintellig - union union - unions union - unite unit - united unit - unity uniti - universal univers - universe univers - universities univers - university univers - unjointed unjoint - unjust unjust - unjustice unjustic - unjustly unjustli - unkennel unkennel - unkept unkept - unkind unkind - unkindest unkindest - unkindly unkindli - unkindness unkind - unking unk - unkinglike unkinglik - unkiss unkiss - unknit unknit - unknowing unknow - unknown unknown - unlace unlac - unlaid unlaid - unlawful unlaw - unlawfully unlawfulli - unlearn unlearn - unlearned unlearn - unless unless - unlesson unlesson - unletter unlett - unlettered unlett - unlick unlick - unlike unlik - unlikely unlik - unlimited unlimit - unlineal unlin - unlink unlink - unload unload - unloaded unload - unloading unload - unloads unload - unlock unlock - unlocks unlock - unlook unlook - unlooked unlook - unloos unloo - unloose unloos - unlov unlov - unloving unlov - unluckily unluckili - unlucky unlucki - unmade unmad - unmake unmak - unmanly unmanli - unmann unmann - unmanner unmann - unmannerd unmannerd - unmannerly unmannerli - unmarried unmarri - unmask unmask - unmasked unmask - unmasking unmask - unmasks unmask - unmast unmast - unmatch unmatch - unmatchable unmatch - unmatched unmatch - unmeasurable unmeasur - unmeet unmeet - unmellowed unmellow - unmerciful unmerci - unmeritable unmerit - unmeriting unmerit - unminded unmind - unmindfull unmindful - unmingled unmingl - unmitigable unmitig - unmitigated unmitig - unmix unmix - unmoan unmoan - unmov unmov - unmoved unmov - unmoving unmov - unmuffles unmuffl - unmuffling unmuffl - unmusical unmus - unmuzzle unmuzzl - unmuzzled unmuzzl - unnatural unnatur - unnaturally unnatur - unnaturalness unnatur - unnecessarily unnecessarili - unnecessary unnecessari - unneighbourly unneighbourli - unnerved unnerv - unnoble unnobl - unnoted unnot - unnumb unnumb - unnumber unnumb - unowed unow - unpack unpack - unpaid unpaid - unparagon unparagon - unparallel unparallel - unpartial unparti - unpath unpath - unpaved unpav - unpay unpai - unpeaceable unpeac - unpeg unpeg - unpeople unpeopl - unpeopled unpeopl - unperfect unperfect - unperfectness unperfect - unpick unpick - unpin unpin - unpink unpink - unpitied unpiti - unpitifully unpitifulli - unplagu unplagu - unplausive unplaus - unpleas unplea - unpleasant unpleas - unpleasing unpleas - unpolicied unpolici - unpolish unpolish - unpolished unpolish - unpolluted unpollut - unpossess unpossess - unpossessing unpossess - unpossible unposs - unpractis unpracti - unpregnant unpregn - unpremeditated unpremedit - unprepar unprepar - unprepared unprepar - unpress unpress - unprevailing unprevail - unprevented unprev - unpriz unpriz - unprizable unpriz - unprofitable unprofit - unprofited unprofit - unproper unprop - unproperly unproperli - unproportion unproport - unprovide unprovid - unprovided unprovid - unprovident unprovid - unprovokes unprovok - unprun unprun - unpruned unprun - unpublish unpublish - unpurged unpurg - unpurpos unpurpo - unqualitied unqual - unqueen unqueen - unquestion unquest - unquestionable unquestion - unquiet unquiet - unquietly unquietli - unquietness unquiet - unraised unrais - unrak unrak - unread unread - unready unreadi - unreal unreal - unreasonable unreason - unreasonably unreason - unreclaimed unreclaim - unreconciled unreconcil - unreconciliable unreconcili - unrecounted unrecount - unrecuring unrecur - unregarded unregard - unregist unregist - unrelenting unrel - unremovable unremov - unremovably unremov - unreprievable unrepriev - unresolv unresolv - unrespected unrespect - unrespective unrespect - unrest unrest - unrestor unrestor - unrestrained unrestrain - unreveng unreveng - unreverend unreverend - unreverent unrever - unrevers unrev - unrewarded unreward - unrighteous unright - unrightful unright - unripe unrip - unripp unripp - unrivall unrival - unroll unrol - unroof unroof - unroosted unroost - unroot unroot - unrough unrough - unruly unruli - unsafe unsaf - unsaluted unsalut - unsanctified unsanctifi - unsatisfied unsatisfi - unsavoury unsavouri - unsay unsai - unscalable unscal - unscann unscann - unscarr unscarr - unschool unschool - unscorch unscorch - unscour unscour - unscratch unscratch - unseal unseal - unseam unseam - unsearch unsearch - unseason unseason - unseasonable unseason - unseasonably unseason - unseasoned unseason - unseconded unsecond - unsecret unsecret - unseduc unseduc - unseeing unse - unseeming unseem - unseemly unseemli - unseen unseen - unseminar unseminar - unseparable unsepar - unserviceable unservic - unset unset - unsettle unsettl - unsettled unsettl - unsever unsev - unsex unsex - unshak unshak - unshaked unshak - unshaken unshaken - unshaped unshap - unshapes unshap - unsheath unsheath - unsheathe unsheath - unshorn unshorn - unshout unshout - unshown unshown - unshrinking unshrink - unshrubb unshrubb - unshunn unshunn - unshunnable unshunn - unsifted unsift - unsightly unsightli - unsinew unsinew - unsisting unsist - unskilful unskil - unskilfully unskilfulli - unskillful unskil - unslipping unslip - unsmirched unsmirch - unsoil unsoil - unsolicited unsolicit - unsorted unsort - unsought unsought - unsound unsound - unsounded unsound - unspeak unspeak - unspeakable unspeak - unspeaking unspeak - unsphere unspher - unspoke unspok - unspoken unspoken - unspotted unspot - unsquar unsquar - unstable unstabl - unstaid unstaid - unstain unstain - unstained unstain - unstanched unstanch - unstate unstat - unsteadfast unsteadfast - unstooping unstoop - unstringed unstring - unstuff unstuff - unsubstantial unsubstanti - unsuitable unsuit - unsuiting unsuit - unsullied unsulli - unsunn unsunn - unsur unsur - unsure unsur - unsuspected unsuspect - unsway unswai - unswayable unsway - unswayed unswai - unswear unswear - unswept unswept - unsworn unsworn - untainted untaint - untalk untalk - untangle untangl - untangled untangl - untasted untast - untaught untaught - untempering untemp - untender untend - untent untent - untented untent - unthankful unthank - unthankfulness unthank - unthink unthink - unthought unthought - unthread unthread - unthrift unthrift - unthrifts unthrift - unthrifty unthrifti - untie unti - untied unti - until until - untimber untimb - untimely untim - untir untir - untirable untir - untired untir - untitled untitl - unto unto - untold untold - untouch untouch - untoward untoward - untowardly untowardli - untraded untrad - untrain untrain - untrained untrain - untread untread - untreasur untreasur - untried untri - untrimmed untrim - untrod untrod - untrodden untrodden - untroubled untroubl - untrue untru - untrussing untruss - untruth untruth - untruths untruth - untucked untuck - untun untun - untune untun - untuneable untun - untutor untutor - untutored untutor - untwine untwin - unurg unurg - unus unu - unused unus - unusual unusu - unvalued unvalu - unvanquish unvanquish - unvarnish unvarnish - unveil unveil - unveiling unveil - unvenerable unvener - unvex unvex - unviolated unviol - unvirtuous unvirtu - unvisited unvisit - unvulnerable unvulner - unwares unwar - unwarily unwarili - unwash unwash - unwatch unwatch - unwearied unweari - unwed unw - unwedgeable unwedg - unweeded unweed - unweighed unweigh - unweighing unweigh - unwelcome unwelcom - unwept unwept - unwhipp unwhipp - unwholesome unwholesom - unwieldy unwieldi - unwilling unwil - unwillingly unwillingli - unwillingness unwilling - unwind unwind - unwiped unwip - unwise unwis - unwisely unwis - unwish unwish - unwished unwish - unwitted unwit - unwittingly unwittingli - unwonted unwont - unwooed unwoo - unworthier unworthi - unworthiest unworthiest - unworthily unworthili - unworthiness unworthi - unworthy unworthi - unwrung unwrung - unyok unyok - unyoke unyok - up up - upbraid upbraid - upbraided upbraid - upbraidings upbraid - upbraids upbraid - uphoarded uphoard - uphold uphold - upholdeth upholdeth - upholding uphold - upholds uphold - uplift uplift - uplifted uplift - upmost upmost - upon upon - upper upper - uprear uprear - upreared uprear - upright upright - uprighteously upright - uprightness upright - uprise upris - uprising upris - uproar uproar - uproars uproar - uprous uprou - upshoot upshoot - upshot upshot - upside upsid - upspring upspr - upstairs upstair - upstart upstart - upturned upturn - upward upward - upwards upward - urchin urchin - urchinfield urchinfield - urchins urchin - urg urg - urge urg - urged urg - urgent urgent - urges urg - urgest urgest - urging urg - urinal urin - urinals urin - urine urin - urn urn - urns urn - urs ur - ursa ursa - ursley urslei - ursula ursula - urswick urswick - us us - usage usag - usance usanc - usances usanc - use us - used us - useful us - useless useless - user user - uses us - usest usest - useth useth - usher usher - ushered usher - ushering usher - ushers usher - using us - usual usual - usually usual - usurer usur - usurers usur - usuries usuri - usuring usur - usurp usurp - usurpation usurp - usurped usurp - usurper usurp - usurpers usurp - usurping usurp - usurpingly usurpingli - usurps usurp - usury usuri - ut ut - utensil utensil - utensils utensil - utility util - utmost utmost - utt utt - utter utter - utterance utter - uttered utter - uttereth uttereth - uttering utter - utterly utterli - uttermost uttermost - utters utter - uy uy - v v - va va - vacancy vacanc - vacant vacant - vacation vacat - vade vade - vagabond vagabond - vagabonds vagabond - vagram vagram - vagrom vagrom - vail vail - vailed vail - vailing vail - vaillant vaillant - vain vain - vainer vainer - vainglory vainglori - vainly vainli - vainness vain - vais vai - valanc valanc - valance valanc - vale vale - valence valenc - valentine valentin - valentinus valentinu - valentio valentio - valeria valeria - valerius valeriu - vales vale - valiant valiant - valiantly valiantli - valiantness valiant - validity valid - vallant vallant - valley vallei - valleys vallei - vally valli - valor valor - valorous valor - valorously valor - valour valour - valu valu - valuation valuat - value valu - valued valu - valueless valueless - values valu - valuing valu - vane vane - vanish vanish - vanished vanish - vanishes vanish - vanishest vanishest - vanishing vanish - vanities vaniti - vanity vaniti - vanquish vanquish - vanquished vanquish - vanquisher vanquish - vanquishest vanquishest - vanquisheth vanquisheth - vant vant - vantage vantag - vantages vantag - vantbrace vantbrac - vapians vapian - vapor vapor - vaporous vapor - vapour vapour - vapours vapour - vara vara - variable variabl - variance varianc - variation variat - variations variat - varied vari - variest variest - variety varieti - varld varld - varlet varlet - varletry varletri - varlets varlet - varletto varletto - varnish varnish - varrius varriu - varro varro - vary vari - varying vari - vassal vassal - vassalage vassalag - vassals vassal - vast vast - vastidity vastid - vasty vasti - vat vat - vater vater - vaudemont vaudemont - vaughan vaughan - vault vault - vaultages vaultag - vaulted vault - vaulting vault - vaults vault - vaulty vaulti - vaumond vaumond - vaunt vaunt - vaunted vaunt - vaunter vaunter - vaunting vaunt - vauntingly vauntingli - vaunts vaunt - vauvado vauvado - vaux vaux - vaward vaward - ve ve - veal veal - vede vede - vehemence vehem - vehemency vehem - vehement vehement - vehor vehor - veil veil - veiled veil - veiling veil - vein vein - veins vein - vell vell - velure velur - velutus velutu - velvet velvet - vendible vendibl - venerable vener - venereal vener - venetia venetia - venetian venetian - venetians venetian - veneys venei - venge veng - vengeance vengeanc - vengeances vengeanc - vengeful veng - veni veni - venial venial - venice venic - venison venison - venit venit - venom venom - venomous venom - venomously venom - vent vent - ventages ventag - vented vent - ventidius ventidiu - ventricle ventricl - vents vent - ventur ventur - venture ventur - ventured ventur - ventures ventur - venturing ventur - venturous ventur - venue venu - venus venu - venuto venuto - ver ver - verb verb - verba verba - verbal verbal - verbatim verbatim - verbosity verbos - verdict verdict - verdun verdun - verdure verdur - vere vere - verefore verefor - verg verg - verge verg - vergers verger - verges verg - verier verier - veriest veriest - verified verifi - verify verifi - verily verili - veritable verit - verite verit - verities veriti - verity veriti - vermilion vermilion - vermin vermin - vernon vernon - verona verona - veronesa veronesa - versal versal - verse vers - verses vers - versing vers - vert vert - very veri - vesper vesper - vessel vessel - vessels vessel - vestal vestal - vestments vestment - vesture vestur - vetch vetch - vetches vetch - veux veux - vex vex - vexation vexat - vexations vexat - vexed vex - vexes vex - vexest vexest - vexeth vexeth - vexing vex - vi vi - via via - vial vial - vials vial - viand viand - viands viand - vic vic - vicar vicar - vice vice - vicegerent viceger - vicentio vicentio - viceroy viceroi - viceroys viceroi - vices vice - vici vici - vicious viciou - viciousness vicious - vict vict - victims victim - victor victor - victoress victoress - victories victori - victorious victori - victors victor - victory victori - victual victual - victuall victual - victuals victual - videlicet videlicet - video video - vides vide - videsne videsn - vidi vidi - vie vie - vied vi - vienna vienna - view view - viewest viewest - vieweth vieweth - viewing view - viewless viewless - views view - vigil vigil - vigilance vigil - vigilant vigil - vigitant vigit - vigour vigour - vii vii - viii viii - vile vile - vilely vile - vileness vile - viler viler - vilest vilest - vill vill - village villag - villager villag - villagery villageri - villages villag - villain villain - villainies villaini - villainous villain - villainously villain - villains villain - villainy villaini - villanies villani - villanous villan - villany villani - villiago villiago - villian villian - villianda villianda - villians villian - vinaigre vinaigr - vincentio vincentio - vincere vincer - vindicative vindic - vine vine - vinegar vinegar - vines vine - vineyard vineyard - vineyards vineyard - vint vint - vintner vintner - viol viol - viola viola - violate violat - violated violat - violates violat - violation violat - violator violat - violence violenc - violent violent - violenta violenta - violenteth violenteth - violently violent - violet violet - violets violet - viper viper - viperous viper - vipers viper - vir vir - virgilia virgilia - virgin virgin - virginal virgin - virginalling virginal - virginity virgin - virginius virginiu - virgins virgin - virgo virgo - virtue virtu - virtues virtu - virtuous virtuou - virtuously virtuous - visag visag - visage visag - visages visag - visard visard - viscount viscount - visible visibl - visibly visibl - vision vision - visions vision - visit visit - visitation visit - visitations visit - visited visit - visiting visit - visitings visit - visitor visitor - visitors visitor - visits visit - visor visor - vita vita - vitae vita - vital vital - vitement vitement - vitruvio vitruvio - vitx vitx - viva viva - vivant vivant - vive vive - vixen vixen - viz viz - vizaments vizament - vizard vizard - vizarded vizard - vizards vizard - vizor vizor - vlouting vlout - vocation vocat - vocativo vocativo - vocatur vocatur - voce voce - voic voic - voice voic - voices voic - void void - voided void - voiding void - voke voke - volable volabl - volant volant - volivorco volivorco - volley vollei - volquessen volquessen - volsce volsc - volsces volsc - volscian volscian - volscians volscian - volt volt - voltemand voltemand - volubility volubl - voluble volubl - volume volum - volumes volum - volumnia volumnia - volumnius volumniu - voluntaries voluntari - voluntary voluntari - voluptuously voluptu - voluptuousness voluptu - vomissement vomiss - vomit vomit - vomits vomit - vor vor - vore vore - vortnight vortnight - vot vot - votaries votari - votarist votarist - votarists votarist - votary votari - votre votr - vouch vouch - voucher voucher - vouchers voucher - vouches vouch - vouching vouch - vouchsaf vouchsaf - vouchsafe vouchsaf - vouchsafed vouchsaf - vouchsafes vouchsaf - vouchsafing vouchsaf - voudrais voudrai - vour vour - vous vou - voutsafe voutsaf - vow vow - vowed vow - vowel vowel - vowels vowel - vowing vow - vows vow - vox vox - voyage voyag - voyages voyag - vraiment vraiment - vulcan vulcan - vulgar vulgar - vulgarly vulgarli - vulgars vulgar - vulgo vulgo - vulnerable vulner - vulture vultur - vultures vultur - vurther vurther - w w - wad wad - waddled waddl - wade wade - waded wade - wafer wafer - waft waft - waftage waftag - wafting waft - wafts waft - wag wag - wage wage - wager wager - wagers wager - wages wage - wagging wag - waggish waggish - waggling waggl - waggon waggon - waggoner waggon - wagon wagon - wagoner wagon - wags wag - wagtail wagtail - wail wail - wailful wail - wailing wail - wails wail - wain wain - wainropes wainrop - wainscot wainscot - waist waist - wait wait - waited wait - waiter waiter - waiteth waiteth - waiting wait - waits wait - wak wak - wake wake - waked wake - wakefield wakefield - waken waken - wakened waken - wakes wake - wakest wakest - waking wake - wales wale - walk walk - walked walk - walking walk - walks walk - wall wall - walled wall - wallet wallet - wallets wallet - wallon wallon - walloon walloon - wallow wallow - walls wall - walnut walnut - walter walter - wan wan - wand wand - wander wander - wanderer wander - wanderers wander - wandering wander - wanders wander - wands wand - wane wane - waned wane - wanes wane - waning wane - wann wann - want want - wanted want - wanteth wanteth - wanting want - wanton wanton - wantonly wantonli - wantonness wanton - wantons wanton - wants want - wappen wappen - war war - warble warbl - warbling warbl - ward ward - warded ward - warden warden - warder warder - warders warder - wardrobe wardrob - wardrop wardrop - wards ward - ware ware - wares ware - warily warili - warkworth warkworth - warlike warlik - warm warm - warmed warm - warmer warmer - warming warm - warms warm - warmth warmth - warn warn - warned warn - warning warn - warnings warn - warns warn - warp warp - warped warp - warr warr - warrant warrant - warranted warrant - warranteth warranteth - warrantise warrantis - warrantize warrant - warrants warrant - warranty warranti - warren warren - warrener warren - warring war - warrior warrior - warriors warrior - wars war - wart wart - warwick warwick - warwickshire warwickshir - wary wari - was wa - wash wash - washed wash - washer washer - washes wash - washford washford - washing wash - wasp wasp - waspish waspish - wasps wasp - wassail wassail - wassails wassail - wast wast - waste wast - wasted wast - wasteful wast - wasters waster - wastes wast - wasting wast - wat wat - watch watch - watched watch - watchers watcher - watches watch - watchful watch - watching watch - watchings watch - watchman watchman - watchmen watchmen - watchword watchword - water water - waterdrops waterdrop - watered water - waterfly waterfli - waterford waterford - watering water - waterish waterish - waterpots waterpot - waterrugs waterrug - waters water - waterton waterton - watery wateri - wav wav - wave wave - waved wave - waver waver - waverer waver - wavering waver - waves wave - waving wave - waw waw - wawl wawl - wax wax - waxed wax - waxen waxen - waxes wax - waxing wax - way wai - waylaid waylaid - waylay waylai - ways wai - wayward wayward - waywarder wayward - waywardness wayward - we we - weak weak - weaken weaken - weakens weaken - weaker weaker - weakest weakest - weakling weakl - weakly weakli - weakness weak - weal weal - wealsmen wealsmen - wealth wealth - wealthiest wealthiest - wealthily wealthili - wealthy wealthi - wealtlly wealtlli - wean wean - weapon weapon - weapons weapon - wear wear - wearer wearer - wearers wearer - wearied weari - wearies weari - weariest weariest - wearily wearili - weariness weari - wearing wear - wearisome wearisom - wears wear - weary weari - weasel weasel - weather weather - weathercock weathercock - weathers weather - weav weav - weave weav - weaver weaver - weavers weaver - weaves weav - weaving weav - web web - wed wed - wedded wed - wedding wed - wedg wedg - wedged wedg - wedges wedg - wedlock wedlock - wednesday wednesdai - weed weed - weeded weed - weeder weeder - weeding weed - weeds weed - weedy weedi - week week - weeke week - weekly weekli - weeks week - ween ween - weening ween - weep weep - weeper weeper - weeping weep - weepingly weepingli - weepings weep - weeps weep - weet weet - weigh weigh - weighed weigh - weighing weigh - weighs weigh - weight weight - weightier weightier - weightless weightless - weights weight - weighty weighti - weird weird - welcom welcom - welcome welcom - welcomer welcom - welcomes welcom - welcomest welcomest - welfare welfar - welkin welkin - well well - wells well - welsh welsh - welshman welshman - welshmen welshmen - welshwomen welshwomen - wench wench - wenches wench - wenching wench - wend wend - went went - wept wept - weraday weradai - were were - wert wert - west west - western western - westminster westminst - westmoreland westmoreland - westward westward - wet wet - wether wether - wetting wet - wezand wezand - whale whale - whales whale - wharf wharf - wharfs wharf - what what - whate whate - whatever whatev - whatsoe whatso - whatsoever whatsoev - whatsome whatsom - whe whe - wheat wheat - wheaten wheaten - wheel wheel - wheeling wheel - wheels wheel - wheer wheer - wheeson wheeson - wheezing wheez - whelk whelk - whelks whelk - whelm whelm - whelp whelp - whelped whelp - whelps whelp - when when - whenas whena - whence whenc - whencesoever whencesoev - whene whene - whenever whenev - whensoever whensoev - where where - whereabout whereabout - whereas wherea - whereat whereat - whereby wherebi - wherefore wherefor - wherein wherein - whereinto whereinto - whereof whereof - whereon whereon - whereout whereout - whereso whereso - wheresoe whereso - wheresoever wheresoev - wheresome wheresom - whereto whereto - whereuntil whereuntil - whereunto whereunto - whereupon whereupon - wherever wherev - wherewith wherewith - wherewithal wherewith - whet whet - whether whether - whetstone whetston - whetted whet - whew whew - whey whei - which which - whiff whiff - whiffler whiffler - while while - whiles while - whilst whilst - whin whin - whine whine - whined whine - whinid whinid - whining whine - whip whip - whipp whipp - whippers whipper - whipping whip - whips whip - whipster whipster - whipstock whipstock - whipt whipt - whirl whirl - whirled whirl - whirligig whirligig - whirling whirl - whirlpool whirlpool - whirls whirl - whirlwind whirlwind - whirlwinds whirlwind - whisp whisp - whisper whisper - whispering whisper - whisperings whisper - whispers whisper - whist whist - whistle whistl - whistles whistl - whistling whistl - whit whit - white white - whitehall whitehal - whitely white - whiteness white - whiter whiter - whites white - whitest whitest - whither whither - whiting white - whitmore whitmor - whitsters whitster - whitsun whitsun - whittle whittl - whizzing whizz - who who - whoa whoa - whoe whoe - whoever whoever - whole whole - wholesom wholesom - wholesome wholesom - wholly wholli - whom whom - whoobub whoobub - whoop whoop - whooping whoop - whor whor - whore whore - whoremaster whoremast - whoremasterly whoremasterli - whoremonger whoremong - whores whore - whoreson whoreson - whoresons whoreson - whoring whore - whorish whorish - whose whose - whoso whoso - whosoe whoso - whosoever whosoev - why why - wi wi - wick wick - wicked wick - wickednes wickedn - wickedness wicked - wicket wicket - wicky wicki - wid wid - wide wide - widens widen - wider wider - widow widow - widowed widow - widower widow - widowhood widowhood - widows widow - wield wield - wife wife - wight wight - wights wight - wild wild - wildcats wildcat - wilder wilder - wilderness wilder - wildest wildest - wildfire wildfir - wildly wildli - wildness wild - wilds wild - wiles wile - wilful wil - wilfull wilful - wilfully wilfulli - wilfulnes wilfuln - wilfulness wil - will will - willed will - willers willer - willeth willeth - william william - williams william - willing will - willingly willingli - willingness willing - willoughby willoughbi - willow willow - wills will - wilt wilt - wiltshire wiltshir - wimpled wimpl - win win - wince winc - winch winch - winchester winchest - wincot wincot - wind wind - winded wind - windgalls windgal - winding wind - windlasses windlass - windmill windmil - window window - windows window - windpipe windpip - winds wind - windsor windsor - windy windi - wine wine - wing wing - winged wing - wingfield wingfield - wingham wingham - wings wing - wink wink - winking wink - winks wink - winner winner - winners winner - winning win - winnow winnow - winnowed winnow - winnows winnow - wins win - winter winter - winterly winterli - winters winter - wip wip - wipe wipe - wiped wipe - wipes wipe - wiping wipe - wire wire - wires wire - wiry wiri - wisdom wisdom - wisdoms wisdom - wise wise - wiselier wiseli - wisely wise - wiser wiser - wisest wisest - wish wish - wished wish - wisher wisher - wishers wisher - wishes wish - wishest wishest - wisheth wisheth - wishful wish - wishing wish - wishtly wishtli - wisp wisp - wist wist - wit wit - witb witb - witch witch - witchcraft witchcraft - witches witch - witching witch - with with - withal withal - withdraw withdraw - withdrawing withdraw - withdrawn withdrawn - withdrew withdrew - wither wither - withered wither - withering wither - withers wither - withheld withheld - withhold withhold - withholds withhold - within within - withold withold - without without - withstand withstand - withstanding withstand - withstood withstood - witless witless - witness wit - witnesses wit - witnesseth witnesseth - witnessing wit - wits wit - witted wit - wittenberg wittenberg - wittiest wittiest - wittily wittili - witting wit - wittingly wittingli - wittol wittol - wittolly wittolli - witty witti - wiv wiv - wive wive - wived wive - wives wive - wiving wive - wizard wizard - wizards wizard - wo wo - woe woe - woeful woeful - woefull woeful - woefullest woefullest - woes woe - woful woful - wolf wolf - wolfish wolfish - wolsey wolsei - wolves wolv - wolvish wolvish - woman woman - womanhood womanhood - womanish womanish - womankind womankind - womanly womanli - womb womb - wombs womb - womby wombi - women women - won won - woncot woncot - wond wond - wonder wonder - wondered wonder - wonderful wonder - wonderfully wonderfulli - wondering wonder - wonders wonder - wondrous wondrou - wondrously wondrous - wont wont - wonted wont - woo woo - wood wood - woodbine woodbin - woodcock woodcock - woodcocks woodcock - wooden wooden - woodland woodland - woodman woodman - woodmonger woodmong - woods wood - woodstock woodstock - woodville woodvil - wooed woo - wooer wooer - wooers wooer - wooes wooe - woof woof - wooing woo - wooingly wooingli - wool wool - woollen woollen - woolly woolli - woolsack woolsack - woolsey woolsei - woolward woolward - woos woo - wor wor - worcester worcest - word word - words word - wore wore - worins worin - work work - workers worker - working work - workings work - workman workman - workmanly workmanli - workmanship workmanship - workmen workmen - works work - worky worki - world world - worldlings worldl - worldly worldli - worlds world - worm worm - worms worm - wormwood wormwood - wormy wormi - worn worn - worried worri - worries worri - worry worri - worrying worri - worse wors - worser worser - worship worship - worshipful worship - worshipfully worshipfulli - worshipp worshipp - worshipper worshipp - worshippers worshipp - worshippest worshippest - worships worship - worst worst - worsted worst - wort wort - worth worth - worthied worthi - worthier worthier - worthies worthi - worthiest worthiest - worthily worthili - worthiness worthi - worthless worthless - worths worth - worthy worthi - worts wort - wot wot - wots wot - wotting wot - wouid wouid - would would - wouldest wouldest - wouldst wouldst - wound wound - wounded wound - wounding wound - woundings wound - woundless woundless - wounds wound - wouns woun - woven woven - wow wow - wrack wrack - wrackful wrack - wrangle wrangl - wrangler wrangler - wranglers wrangler - wrangling wrangl - wrap wrap - wrapp wrapp - wraps wrap - wrapt wrapt - wrath wrath - wrathful wrath - wrathfully wrathfulli - wraths wrath - wreak wreak - wreakful wreak - wreaks wreak - wreath wreath - wreathed wreath - wreathen wreathen - wreaths wreath - wreck wreck - wrecked wreck - wrecks wreck - wren wren - wrench wrench - wrenching wrench - wrens wren - wrest wrest - wrested wrest - wresting wrest - wrestle wrestl - wrestled wrestl - wrestler wrestler - wrestling wrestl - wretch wretch - wretchcd wretchcd - wretched wretch - wretchedness wretched - wretches wretch - wring wring - wringer wringer - wringing wring - wrings wring - wrinkle wrinkl - wrinkled wrinkl - wrinkles wrinkl - wrist wrist - wrists wrist - writ writ - write write - writer writer - writers writer - writes write - writhled writhl - writing write - writings write - writs writ - written written - wrong wrong - wronged wrong - wronger wronger - wrongful wrong - wrongfully wrongfulli - wronging wrong - wrongly wrongli - wrongs wrong - wronk wronk - wrote wrote - wroth wroth - wrought wrought - wrung wrung - wry wry - wrying wry - wt wt - wul wul - wye wye - x x - xanthippe xanthipp - xi xi - xii xii - xiii xiii - xiv xiv - xv xv - y y - yard yard - yards yard - yare yare - yarely yare - yarn yarn - yaughan yaughan - yaw yaw - yawn yawn - yawning yawn - ycleped yclepe - ycliped yclipe - ye ye - yea yea - yead yead - year year - yearly yearli - yearn yearn - yearns yearn - years year - yeas yea - yeast yeast - yedward yedward - yell yell - yellow yellow - yellowed yellow - yellowing yellow - yellowness yellow - yellows yellow - yells yell - yelping yelp - yeoman yeoman - yeomen yeomen - yerk yerk - yes ye - yesterday yesterdai - yesterdays yesterdai - yesternight yesternight - yesty yesti - yet yet - yew yew - yicld yicld - yield yield - yielded yield - yielder yielder - yielders yielder - yielding yield - yields yield - yok yok - yoke yoke - yoked yoke - yokefellow yokefellow - yokes yoke - yoketh yoketh - yon yon - yond yond - yonder yonder - yongrey yongrei - yore yore - yorick yorick - york york - yorkists yorkist - yorks york - yorkshire yorkshir - you you - young young - younger younger - youngest youngest - youngling youngl - younglings youngl - youngly youngli - younker younker - your your - yours your - yourself yourself - yourselves yourselv - youth youth - youthful youth - youths youth - youtli youtli - zanies zani - zany zani - zeal zeal - zealous zealou - zeals zeal - zed zed - zenelophon zenelophon - zenith zenith - zephyrs zephyr - zir zir - zo zo - zodiac zodiac - zodiacs zodiac - zone zone - zounds zound - zwagger zwagger -} - -# Create a full-text index to use for testing the stemmer. -# -db close -sqlite3 db :memory: -db eval { - CREATE VIRTUAL TABLE t1 USING fts1(word, tokenize Porter); -} - -foreach {pfrom pto} $porter_test_data { - do_test fts1porter-$pfrom { - execsql { - DELETE FROM t1_term; - DELETE FROM t1_content; - INSERT INTO t1(word) VALUES($pfrom); - SELECT term FROM t1_term; - } - } $pto -} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2a.test sqlite3-3.44.0-0/test/fts2a.test --- sqlite3-3.42.0/test/fts2a.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2a.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,202 +0,0 @@ -# 2006 September 9 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing the FTS2 module. -# -# $Id: fts2a.test,v 1.2 2007/05/21 21:59:18 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Construct a full-text search table containing five keywords: -# one, two, three, four, and five, in various combinations. The -# rowid for each will be a bitmask for the elements it contains. -# -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(content); - INSERT INTO t1(content) VALUES('one'); - INSERT INTO t1(content) VALUES('two'); - INSERT INTO t1(content) VALUES('one two'); - INSERT INTO t1(content) VALUES('three'); - INSERT INTO t1(content) VALUES('one three'); - INSERT INTO t1(content) VALUES('two three'); - INSERT INTO t1(content) VALUES('one two three'); - INSERT INTO t1(content) VALUES('four'); - INSERT INTO t1(content) VALUES('one four'); - INSERT INTO t1(content) VALUES('two four'); - INSERT INTO t1(content) VALUES('one two four'); - INSERT INTO t1(content) VALUES('three four'); - INSERT INTO t1(content) VALUES('one three four'); - INSERT INTO t1(content) VALUES('two three four'); - INSERT INTO t1(content) VALUES('one two three four'); - INSERT INTO t1(content) VALUES('five'); - INSERT INTO t1(content) VALUES('one five'); - INSERT INTO t1(content) VALUES('two five'); - INSERT INTO t1(content) VALUES('one two five'); - INSERT INTO t1(content) VALUES('three five'); - INSERT INTO t1(content) VALUES('one three five'); - INSERT INTO t1(content) VALUES('two three five'); - INSERT INTO t1(content) VALUES('one two three five'); - INSERT INTO t1(content) VALUES('four five'); - INSERT INTO t1(content) VALUES('one four five'); - INSERT INTO t1(content) VALUES('two four five'); - INSERT INTO t1(content) VALUES('one two four five'); - INSERT INTO t1(content) VALUES('three four five'); - INSERT INTO t1(content) VALUES('one three four five'); - INSERT INTO t1(content) VALUES('two three four five'); - INSERT INTO t1(content) VALUES('one two three four five'); -} - -do_test fts2a-1.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'} -} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31} -do_test fts2a-1.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two'} -} {3 7 11 15 19 23 27 31} -do_test fts2a-1.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two one'} -} {3 7 11 15 19 23 27 31} -do_test fts2a-1.4 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two three'} -} {7 15 23 31} -do_test fts2a-1.5 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one three two'} -} {7 15 23 31} -do_test fts2a-1.6 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two three one'} -} {7 15 23 31} -do_test fts2a-1.7 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two one three'} -} {7 15 23 31} -do_test fts2a-1.8 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three one two'} -} {7 15 23 31} -do_test fts2a-1.9 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three two one'} -} {7 15 23 31} -do_test fts2a-1.10 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two THREE'} -} {7 15 23 31} -do_test fts2a-1.11 { - execsql {SELECT rowid FROM t1 WHERE content MATCH ' ONE Two three '} -} {7 15 23 31} - -do_test fts2a-2.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one"'} -} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31} -do_test fts2a-2.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two"'} -} {3 7 11 15 19 23 27 31} -do_test fts2a-2.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"two one"'} -} {} -do_test fts2a-2.4 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two three"'} -} {7 15 23 31} -do_test fts2a-2.5 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three two"'} -} {} -do_test fts2a-2.6 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two three four"'} -} {15 31} -do_test fts2a-2.7 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three two four"'} -} {} -do_test fts2a-2.8 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three five"'} -} {21} -do_test fts2a-2.9 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three" five'} -} {21 29} -do_test fts2a-2.10 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'five "one three"'} -} {21 29} -do_test fts2a-2.11 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'five "one three" four'} -} {29} -do_test fts2a-2.12 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'five four "one three"'} -} {29} -do_test fts2a-2.13 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one three" four five'} -} {29} - -do_test fts2a-3.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'} -} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31} -do_test fts2a-3.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one -two'} -} {1 5 9 13 17 21 25 29} -do_test fts2a-3.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '-two one'} -} {1 5 9 13 17 21 25 29} - -do_test fts2a-4.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one OR two'} -} {1 2 3 5 6 7 9 10 11 13 14 15 17 18 19 21 22 23 25 26 27 29 30 31} -do_test fts2a-4.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH '"one two" OR three'} -} {3 4 5 6 7 11 12 13 14 15 19 20 21 22 23 27 28 29 30 31} -do_test fts2a-4.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three OR "one two"'} -} {3 4 5 6 7 11 12 13 14 15 19 20 21 22 23 27 28 29 30 31} -do_test fts2a-4.4 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two OR three'} -} {3 5 7 11 13 15 19 21 23 27 29 31} -do_test fts2a-4.5 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three OR two one'} -} {3 5 7 11 13 15 19 21 23 27 29 31} -do_test fts2a-4.6 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one two OR three OR four'} -} {3 5 7 9 11 13 15 19 21 23 25 27 29 31} -do_test fts2a-4.7 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two OR three OR four one'} -} {3 5 7 9 11 13 15 19 21 23 25 27 29 31} - -# Test the ability to handle NULL content -# -do_test fts2a-5.1 { - execsql {INSERT INTO t1(content) VALUES(NULL)} -} {} -do_test fts2a-5.2 { - set rowid [db last_insert_rowid] - execsql {SELECT content FROM t1 WHERE rowid=$rowid} -} {{}} -do_test fts2a-5.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH NULL} -} {} - -# Test the ability to handle non-positive rowids -# -do_test fts2a-6.0 { - execsql {INSERT INTO t1(rowid, content) VALUES(0, 'four five')} -} {} -do_test fts2a-6.1 { - execsql {SELECT content FROM t1 WHERE rowid = 0} -} {{four five}} -do_test fts2a-6.2 { - execsql {INSERT INTO t1(rowid, content) VALUES(-1, 'three four')} -} {} -do_test fts2a-6.3 { - execsql {SELECT content FROM t1 WHERE rowid = -1} -} {{three four}} -do_test fts2a-6.4 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'four'} -} {-1 0 8 9 10 11 12 13 14 15 24 25 26 27 28 29 30 31} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2b.test sqlite3-3.44.0-0/test/fts2b.test --- sqlite3-3.42.0/test/fts2b.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2b.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,147 +0,0 @@ -# 2006 September 13 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing the FTS2 module. -# -# $Id: fts2b.test,v 1.1 2006/10/19 23:36:26 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Fill the full-text index "t1" with phrases in english, spanish, -# and german. For the i-th row, fill in the names for the bits -# that are set in the value of i. The least significant bit is -# 1. For example, the value 5 is 101 in binary which will be -# converted to "one three" in english. -# -proc fill_multilanguage_fulltext_t1 {} { - set english {one two three four five} - set spanish {un dos tres cuatro cinco} - set german {eine zwei drei vier funf} - - for {set i 1} {$i<=31} {incr i} { - set cmd "INSERT INTO t1 VALUES" - set vset {} - foreach lang {english spanish german} { - set words {} - for {set j 0; set k 1} {$j<5} {incr j; incr k $k} { - if {$k&$i} {lappend words [lindex [set $lang] $j]} - } - lappend vset "'$words'" - } - set sql "INSERT INTO t1(english,spanish,german) VALUES([join $vset ,])" - # puts $sql - db eval $sql - } -} - -# Construct a full-text search table containing five keywords: -# one, two, three, four, and five, in various combinations. The -# rowid for each will be a bitmask for the elements it contains. -# -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(english,spanish,german); -} -fill_multilanguage_fulltext_t1 - -do_test fts2b-1.1 { - execsql {SELECT rowid FROM t1 WHERE english MATCH 'one'} -} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31} -do_test fts2b-1.2 { - execsql {SELECT rowid FROM t1 WHERE spanish MATCH 'one'} -} {} -do_test fts2b-1.3 { - execsql {SELECT rowid FROM t1 WHERE german MATCH 'one'} -} {} -do_test fts2b-1.4 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one'} -} {1 3 5 7 9 11 13 15 17 19 21 23 25 27 29 31} -do_test fts2b-1.5 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'one dos drei'} -} {7 15 23 31} -do_test fts2b-1.6 { - execsql {SELECT english, spanish, german FROM t1 WHERE rowid=1} -} {one un eine} -do_test fts2b-1.7 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"one un"'} -} {} - -do_test fts2b-2.1 { - execsql { - CREATE VIRTUAL TABLE t2 USING fts2(from,to); - INSERT INTO t2([from],[to]) VALUES ('one two three', 'four five six'); - SELECT [from], [to] FROM t2 - } -} {{one two three} {four five six}} - - -# Compute an SQL string that contains the words one, two, three,... to -# describe bits set in the value $i. Only the lower 5 bits are examined. -# -proc wordset {i} { - set x {} - for {set j 0; set k 1} {$j<5} {incr j; incr k $k} { - if {$k&$i} {lappend x [lindex {one two three four five} $j]} - } - return '$x' -} - -# Create a new FTS table with three columns: -# -# norm: words for the bits of rowid -# plusone: words for the bits of rowid+1 -# invert: words for the bits of ~rowid -# -db eval { - CREATE VIRTUAL TABLE t4 USING fts2([norm],'plusone',"invert"); -} -for {set i 1} {$i<=15} {incr i} { - set vset [list [wordset $i] [wordset [expr {$i+1}]] [wordset [expr {~$i}]]] - db eval "INSERT INTO t4(norm,plusone,invert) VALUES([join $vset ,]);" -} - -do_test fts2b-4.1 { - execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one'} -} {1 3 5 7 9 11 13 15} -do_test fts2b-4.2 { - execsql {SELECT rowid FROM t4 WHERE norm MATCH 'one'} -} {1 3 5 7 9 11 13 15} -do_test fts2b-4.3 { - execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'one'} -} {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15} -do_test fts2b-4.4 { - execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:one'} -} {2 4 6 8 10 12 14} -do_test fts2b-4.5 { - execsql {SELECT rowid FROM t4 WHERE plusone MATCH 'one'} -} {2 4 6 8 10 12 14} -do_test fts2b-4.6 { - execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one plusone:two'} -} {1 5 9 13} -do_test fts2b-4.7 { - execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'norm:one two'} -} {1 3 5 7 9 11 13 15} -do_test fts2b-4.8 { - execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'plusone:two norm:one'} -} {1 5 9 13} -do_test fts2b-4.9 { - execsql {SELECT rowid FROM t4 WHERE t4 MATCH 'two norm:one'} -} {1 3 5 7 9 11 13 15} - - -finish_test diff -Nru sqlite3-3.42.0/test/fts2c.test sqlite3-3.44.0-0/test/fts2c.test --- sqlite3-3.42.0/test/fts2c.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2c.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,1213 +0,0 @@ -# 2006 September 14 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing the FTS2 module. -# -# $Id: fts2c.test,v 1.1 2006/10/19 23:36:26 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Create a table of sample email data. The data comes from email -# archives of Enron executives that was published as part of the -# litigation against that company. -# -do_test fts2c-1.1 { - db eval { - CREATE VIRTUAL TABLE email USING fts2([from],[to],subject,body); - BEGIN TRANSACTION; -INSERT INTO email([from],[to],subject,body) VALUES('savita.puthigai@enron.com', 'traders.eol@enron.com, traders.eol@enron.com', 'EnronOnline- Change to Autohedge', 'Effective Monday, October 22, 2001 the following changes will be made to the Autohedge functionality on EnronOnline. - -The volume on the hedge will now respect the minimum volume and volume increment settings on the parent product. See rules below: - -? If the transaction volume on the child is less than half of the parent''s minimum volume no hedge will occur. -? If the transaction volume on the child is more than half the parent''s minimum volume but less than half the volume increment on the parent, the hedge will volume will be the parent''s minimum volume. -? For all other volumes, the same rounding rules will apply based on the volume increment on the parent product. - -Please see example below: - -Parent''s Settings: -Minimum: 5000 -Increment: 1000 - -Volume on Autohedge transaction Volume Hedged -1 - 2499 0 -2500 - 5499 5000 -5500 - 6499 6000'); -INSERT INTO email([from],[to],subject,body) VALUES('dana.davis@enron.com', 'laynie.east@enron.com, lisa.king@enron.com, lisa.best@enron.com,', 'Leaving Early', 'FYI: -If it''s ok with everyone''s needs, I would like to leave @4pm. If you think -you will need my assistance past the 4 o''clock hour just let me know; I''ll -be more than willing to stay.'); -INSERT INTO email([from],[to],subject,body) VALUES('enron_update@concureworkplace.com', 'louise.kitchen@enron.com', '<> - CC02.06.02', 'The following expense report is ready for approval: - -Employee Name: Christopher F. Calger -Status last changed by: Mollie E. Gustafson Ms -Expense Report Name: CC02.06.02 -Report Total: $3,972.93 -Amount Due Employee: $3,972.93 - - -To approve this expense report, click on the following link for Concur Expense. -http://expensexms.enron.com'); -INSERT INTO email([from],[to],subject,body) VALUES('jeff.duff@enron.com', 'julie.johnson@enron.com', 'Work request', 'Julie, - -Could you print off the current work request report by 1:30 today? - -Gentlemen, - -I''d like to review this today at 1:30 in our office. Also, could you provide -me with your activity reports so I can have Julie enter this information. - -JD'); -INSERT INTO email([from],[to],subject,body) VALUES('v.weldon@enron.com', 'gary.l.carrier@usa.dupont.com, scott.joyce@bankofamerica.com', 'Enron News', 'This could turn into something big.... -http://biz.yahoo.com/rf/010129/n29305829.html'); -INSERT INTO email([from],[to],subject,body) VALUES('mark.haedicke@enron.com', 'paul.simons@enron.com', 'Re: First Polish Deal!', 'Congrats! Things seem to be building rapidly now on the Continent. Mark'); -INSERT INTO email([from],[to],subject,body) VALUES('e..carter@enron.com', 't..robinson@enron.com', 'FW: Producers Newsletter 9-24-2001', ' -The producer lumber pricing sheet. - -----Original Message----- -From: Johnson, Jay -Sent: Tuesday, October 16, 2001 3:42 PM -To: Carter, Karen E. -Subject: FW: Producers Newsletter 9-24-2001 - - - - -----Original Message----- -From: Daigre, Sergai -Sent: Friday, September 21, 2001 8:33 PM -Subject: Producers Newsletter 9-24-2001 - - '); -INSERT INTO email([from],[to],subject,body) VALUES('david.delainey@enron.com', 'kenneth.lay@enron.com', 'Greater Houston Partnership', 'Ken, in response to the letter from Mr Miguel San Juan, my suggestion would -be to offer up the Falcon for their use; however, given the tight time frame -and your recent visit with Mr. Fox that it would be difficult for either you -or me to participate. - -I spoke to Max and he agrees with this approach. - -I hope this meets with your approval. - -Regards -Delainey'); -INSERT INTO email([from],[to],subject,body) VALUES('lachandra.fenceroy@enron.com', 'lindy.donoho@enron.com', 'FW: Bus Applications Meeting Follow Up', 'Lindy, - -Here is the original memo we discussed earlier. Please provide any information that you may have. - -Your cooperation is greatly appreciated. - -Thanks, - -lachandra.fenceroy@enron.com -713.853.3884 -877.498.3401 Pager - - -----Original Message----- -From: Bisbee, Joanne -Sent: Wednesday, September 26, 2001 7:50 AM -To: Fenceroy, LaChandra -Subject: FW: Bus Applications Meeting Follow Up - -Lachandra, Please get with David Duff today and see what this is about. Who are our TW accounting business users? - - -----Original Message----- -From: Koh, Wendy -Sent: Tuesday, September 25, 2001 2:41 PM -To: Bisbee, Joanne -Subject: Bus Applications Meeting Follow Up - -Lisa brought up a TW change effective Nov 1. It involves eliminating a turnback surcharge. I have no other information, but you might check with the business folks for any system changes required. - -Wendy'); -INSERT INTO email([from],[to],subject,body) VALUES('danny.mccarty@enron.com', 'fran.fagan@enron.com', 'RE: worksheets', 'Fran, - If Julie''s merit needs to be lump sum, just move it over to that column. Also, send me Eric Gadd''s sheets as well. Thanks. -Dan - - -----Original Message----- -From: Fagan, Fran -Sent: Thursday, December 20, 2001 11:10 AM -To: McCarty, Danny -Subject: worksheets - -As discussed, attached are your sheets for bonus and merit. - -Thanks, - -Fran Fagan -Sr. HR Rep -713.853.5219 - - - << File: McCartyMerit.xls >> << File: mccartyBonusCommercial_UnP.xls >> - -'); -INSERT INTO email([from],[to],subject,body) VALUES('bert.meyers@enron.com', 'shift.dl-portland@enron.com', 'OCTOBER SCHEDULE', 'TEAM, - -PLEASE SEND ME ANY REQUESTS THAT YOU HAVE FOR OCTOBER. SO FAR I HAVE THEM FOR LEAF. I WOULD LIKE TO HAVE IT DONE BY THE 15TH OF THE MONTH. ANY QUESTIONS PLEASE GIVE ME A CALL. - -BERT'); -INSERT INTO email([from],[to],subject,body) VALUES('errol.mclaughlin@enron.com', 'john.arnold@enron.com, bilal.bajwa@enron.com, john.griffith@enron.com,', 'TRV Notification: (NG - PROPT P/L - 09/27/2001)', 'The report named: NG - PROPT P/L , published as of 09/27/2001 is now available for viewing on the website.'); -INSERT INTO email([from],[to],subject,body) VALUES('patrice.mims@enron.com', 'calvin.eakins@enron.com', 'Re: Small business supply assistance', 'Hi Calvin - - -I spoke with Rickey (boy, is he long-winded!!). Gave him the name of our -credit guy, Russell Diamond. - -Thank for your help!'); -INSERT INTO email([from],[to],subject,body) VALUES('legal <.hall@enron.com>', 'stephanie.panus@enron.com', 'Termination update', 'City of Vernon and Salt River Project terminated their contracts. I will fax these notices to you.'); -INSERT INTO email([from],[to],subject,body) VALUES('d..steffes@enron.com', 'richard.shapiro@enron.com', 'EES / ENA Government Affairs Staffing & Outside Services', 'Rick -- - -Here is the information on staffing and outside services. Call if you need anything else. - -Jim - - '); -INSERT INTO email([from],[to],subject,body) VALUES('gelliott@industrialinfo.com', 'pcopello@industrialinfo.com', 'ECAAR (Gavin), WSCC (Diablo Canyon), & NPCC (Seabrook)', 'Dear Power Outage Database Customer, -Attached you will find an excel document. The outages contained within are forced or rescheduled outages. Your daily delivery will still contain these outages. -In addition to the two excel documents, there is a dbf file that is formatted like your daily deliveries you receive nightly. This will enable you to load the data into your regular database. Any questions please let me know. Thanks. -Greg Elliott -IIR, Inc. -713-783-5147 x 3481 -outages@industrialinfo.com -THE INFORMATION CONTAINED IN THIS E-MAIL IS LEGALLY PRIVILEGED AND CONFIDENTIAL INFORMATION INTENDED ONLY FOR THE USE OF THE INDIVIDUAL OR ENTITY NAMED ABOVE. YOU ARE HEREBY NOTIFIED THAT ANY DISSEMINATION, DISTRIBUTION, OR COPY OF THIS E-MAIL TO UNAUTHORIZED ENTITIES IS STRICTLY PROHIBITED. IF YOU HAVE RECEIVED THIS -E-MAIL IN ERROR, PLEASE DELETE IT. - - OUTAGE.dbf - - 111201R.xls - - 111201.xls '); -INSERT INTO email([from],[to],subject,body) VALUES('enron.announcements@enron.com', 'all_ena_egm_eim@enron.com', 'EWS Brown Bag', 'MARK YOUR LUNCH CALENDARS NOW ! - -You are invited to attend the EWS Brown Bag Lunch Series - -Featuring: RAY BOWEN, COO - -Topic: Enron Industrial Markets - -Thursday, March 15, 2001 -11:30 am - 12:30 pm -EB 5 C2 - - -You bring your lunch, Limited Seating -We provide drinks and dessert. RSVP x 3-9610'); -INSERT INTO email([from],[to],subject,body) VALUES('chris.germany@enron.com', 'ingrid.immer@williams.com', 'Re: About St Pauls', 'Sounds good to me. I bet this is next to the Warick?? Hotel. - - - - -"Immer, Ingrid" on 12/21/2000 11:48:47 AM -To: "''chris.germany@enron.com''" -cc: -Subject: About St Pauls - - - - - <> -? -?http://www.stpaulshouston.org/about.html - -Chris, - -I like the looks of this place.? What do you think about going here Christmas -eve?? They have an 11:00 a.m. service and a candlelight service at 5:00 p.m., -among others. - -Let me know.?? ii - - - About St Pauls.url - -'); -INSERT INTO email([from],[to],subject,body) VALUES('nas@cpuc.ca.gov', 'skatz@sempratrading.com, kmccrea@sablaw.com, thompson@wrightlaw.com,', 'Reply Brief filed July 31, 2000', ' - CPUC01-#76371-v1-Revised_Reply_Brief__Due_today_7_31_.doc'); -INSERT INTO email([from],[to],subject,body) VALUES('gascontrol@aglresources.com', 'dscott4@enron.com, lcampbel@enron.com', 'Alert Posted 10:00 AM November 20,2000: E-GAS Request Reminder', 'Alert Posted 10:00 AM November 20,2000: E-GAS Request Reminder -As discussed in the Winter Operations Meeting on Sept.29,2000, -E-Gas(Emergency Gas) will not be offered this winter as a service from AGLC. -Marketers and Poolers can receive gas via Peaking and IBSS nominations(daisy -chain) from other marketers up to the 6 p.m. Same Day 2 nomination cycle. -'); -INSERT INTO email([from],[to],subject,body) VALUES('dutch.quigley@enron.com', 'rwolkwitz@powermerchants.com', '', ' - -Here is a goody for you'); -INSERT INTO email([from],[to],subject,body) VALUES('ryan.o''rourke@enron.com', 'k..allen@enron.com, randy.bhatia@enron.com, frank.ermis@enron.com,', 'TRV Notification: (West VaR - 11/07/2001)', 'The report named: West VaR , published as of 11/07/2001 is now available for viewing on the website.'); -INSERT INTO email([from],[to],subject,body) VALUES('mjones7@txu.com', 'cstone1@txu.com, ggreen2@txu.com, timpowell@txu.com,', 'Enron / HPL Actuals for July 10, 2000', 'Teco Tap 10.000 / Enron ; 110.000 / HPL IFERC - -LS HPL LSK IC 30.000 / Enron -'); -INSERT INTO email([from],[to],subject,body) VALUES('susan.pereira@enron.com', 'kkw816@aol.com', 'soccer practice', 'Kathy- - -Is it safe to assume that practice is cancelled for tonight?? - -Susan Pereira'); -INSERT INTO email([from],[to],subject,body) VALUES('mark.whitt@enron.com', 'barry.tycholiz@enron.com', 'Huber Internal Memo', 'Please look at this. I didn''t know how deep to go with the desk. Do you think this works. - - '); -INSERT INTO email([from],[to],subject,body) VALUES('m..forney@enron.com', 'george.phillips@enron.com', '', 'George, -Give me a call and we will further discuss opportunities on the 13st floor. - -Thanks, -JMForney -3-7160'); -INSERT INTO email([from],[to],subject,body) VALUES('brad.mckay@enron.com', 'angusmcka@aol.com', 'Re: (no subject)', 'not yet'); -INSERT INTO email([from],[to],subject,body) VALUES('adam.bayer@enron.com', 'jonathan.mckay@enron.com', 'FW: Curve Fetch File', 'Here is the curve fetch file sent to me. It has plenty of points in it. If you give me a list of which ones you need we may be able to construct a secondary worksheet to vlookup the values. - -adam -35227 - - - -----Original Message----- -From: Royed, Jeff -Sent: Tuesday, September 25, 2001 11:37 AM -To: Bayer, Adam -Subject: Curve Fetch File - -Let me know if it works. It may be required to have a certain version of Oracle for it to work properly. - - - -Jeff Royed -Enron -Energy Operations -Phone: 713-853-5295'); -INSERT INTO email([from],[to],subject,body) VALUES('matt.smith@enron.com', 'yan.wang@enron.com', 'Report Formats', 'Yan, - -The merged reports look great. I believe the only orientation changes are to -"unmerge" the following six reports: - -31 Keystone Receipts -15 Questar Pipeline -40 Rockies Production -22 West_2 -23 West_3 -25 CIG_WIC - -The orientation of the individual reports should be correct. Thanks. - -Mat - -PS. Just a reminder to add the "*" by the title of calculated points.'); -INSERT INTO email([from],[to],subject,body) VALUES('michelle.lokay@enron.com', 'jimboman@bigfoot.com', 'Egyptian Festival', '---------------------- Forwarded by Michelle Lokay/ET&S/Enron on 09/07/2000 -10:08 AM --------------------------- - - -"Karkour, Randa" on 09/07/2000 09:01:04 AM -To: "''Agheb (E-mail)" , "Leila Mankarious (E-mail)" -, "''Marymankarious (E-mail)" -, "Michelle lokay (E-mail)" , "Ramy -Mankarious (E-mail)" -cc: - -Subject: Egyptian Festival - - - <> - - http://www.egyptianfestival.com/ - - - Egyptian Festival.url -'); -INSERT INTO email([from],[to],subject,body) VALUES('errol.mclaughlin@enron.com', 'sherry.dawson@enron.com', 'Urgent!!! --- New EAST books', 'This has to be done.................................. - -Thanks ----------------------- Forwarded by Errol McLaughlin/Corp/Enron on 12/20/2000 -08:39 AM --------------------------- - - - - From: William Kelly @ ECT 12/20/2000 08:31 AM - - -To: Kam Keiser/HOU/ECT@ECT, Darron C Giron/HOU/ECT@ECT, David -Baumbach/HOU/ECT@ECT, Errol McLaughlin/Corp/Enron@ENRON -cc: Kimat Singla/HOU/ECT@ECT, Kulvinder Fowler/NA/Enron@ENRON, Kyle R -Lilly/HOU/ECT@ECT, Jeff Royed/Corp/Enron@ENRON, Alejandra -Chavez/NA/Enron@ENRON, Crystal Hyde/HOU/ECT@ECT - -Subject: New EAST books - -We have new book names in TAGG for our intramonth portfolios and it is -extremely important that any deal booked to the East is communicated quickly -to someone on my team. I know it will take some time for the new names to -sink in and I do not want us to miss any positions or P&L. - -Thanks for your help on this. - -New: -Scott Neal : East Northeast -Dick Jenkins: East Marketeast - -WK -'); -INSERT INTO email([from],[to],subject,body) VALUES('david.forster@enron.com', 'eol.wide@enron.com', 'Change to Stack Manager', 'Effective immediately, there is a change to the Stack Manager which will -affect any Inactive Child. - -An inactive Child with links to Parent products will not have their -calculated prices updated until the Child product is Activated. - -When the Child Product is activated, the price will be recalculated and -updated BEFORE it is displayed on the web. - -This means that if you are inputting a basis price on a Child product, you -will not see the final, calculated price until you Activate the product, at -which time the customer will also see it. - -If you have any questions, please contact the Help Desk on: - -Americas: 713 853 4357 -Europe: + 44 (0) 20 7783 7783 -Asia/Australia: +61 2 9229 2300 - -Dave'); -INSERT INTO email([from],[to],subject,body) VALUES('vince.kaminski@enron.com', 'jhh1@email.msn.com', 'Re: Light reading - see pieces beginning on page 7', 'John, - -I saw it. Very interesting. - -Vince - - - - - -"John H Herbert" on 07/28/2000 08:38:08 AM -To: "Vince J Kaminski" -cc: -Subject: Light reading - see pieces beginning on page 7 - - -Cheers and have a nice weekend, - - -JHHerbert - - - - - - gd000728.pdf - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('matthew.lenhart@enron.com', 'mmmarcantel@equiva.com', 'RE:', 'i will try to line up a pig for you '); -INSERT INTO email([from],[to],subject,body) VALUES('jae.black@enron.com', 'claudette.harvey@enron.com, chaun.roberts@enron.com, judy.martinez@enron.com,', 'Disaster Recovery Equipment', 'As a reminder...there are several pieces of equipment that are set up on the 30th Floor, as well as on our floor, for the Disaster Recovery Team. PLEASE DO NOT TAKE, BORROW OR USE this equipment. Should you need to use another computer system, other than yours, or make conference calls please work with your Assistant to help find or set up equipment for you to use. - -Thanks for your understanding in this matter. - -T.Jae Black -East Power Trading -Assistant to Kevin Presto -off. 713-853-5800 -fax 713-646-8272 -cell 713-539-4760'); -INSERT INTO email([from],[to],subject,body) VALUES('eric.bass@enron.com', 'dale.neuner@enron.com', '5 X 24', 'Dale, - -Have you heard anything more on the 5 X 24s? We would like to get this -product out ASAP. - - -Thanks, - -Eric'); -INSERT INTO email([from],[to],subject,body) VALUES('messenger@smartreminders.com', 'm..tholt@enron.com', '10% Coupon - PrintPal Printer Cartridges - 100% Guaranteed', '[IMAGE] -[IMAGE][IMAGE][IMAGE] -Dear SmartReminders Member, - [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] [IMAGE] - - - - - - - - - - - - - - - - - - - - - -We respect your privacy and are a Certified Participant of the BBBOnLine - Privacy Program. To be removed from future offers,click here. -SmartReminders.com is a permission based service. To unsubscribe click here . '); -INSERT INTO email([from],[to],subject,body) VALUES('benjamin.rogers@enron.com', 'mark.bernstein@enron.com', '', 'The guy you are talking about left CIN under a "cloud of suspicion" sort of -speak. He was the one who got into several bad deals and PPA''s in California -for CIN, thus he left on a bad note. Let me know if you need more detail -than that, I felt this was the type of info you were looking for. Thanks! -Ben'); -INSERT INTO email([from],[to],subject,body) VALUES('enron_update@concureworkplace.com', 'michelle.cash@enron.com', 'Expense Report Receipts Not Received', 'Employee Name: Michelle Cash -Report Name: Houston Cellular 8-11-01 -Report Date: 12/13/01 -Report ID: 594D37C9ED2111D5B452 -Submitted On: 12/13/01 - -You are only allowed 2 reports with receipts outstanding. Your expense reports will not be paid until you meet this requirement.'); -INSERT INTO email([from],[to],subject,body) VALUES('susan.mara@enron.com', 'ray.alvarez@enron.com, mark.palmer@enron.com, karen.denne@enron.com,', 'CAISO Emergency Motion -- to discontinue market-based rates for', 'FYI. the latest broadside against the generators. - -Sue Mara -Enron Corp. -Tel: (415) 782-7802 -Fax:(415) 782-7854 ------ Forwarded by Susan J Mara/NA/Enron on 06/08/2001 12:24 PM ----- - - - "Milner, Marcie" 06/08/2001 11:13 AM To: "''smara@enron.com''" cc: Subject: CAISO Emergency Motion - - -Sue, did you see this emergency motion the CAISO filed today? Apparently -they are requesting that FERC discontinue market-based rates immediately and -grant refunds plus interest on the difference between cost-based rates and -market revenues received back to May 2000. They are requesting the -commission act within 14 days. Have you heard anything about what they are -doing? - -Marcie - -http://www.caiso.com/docs/2001/06/08/200106081005526469.pdf -'); -INSERT INTO email([from],[to],subject,body) VALUES('fletcher.sturm@enron.com', 'eloy.escobar@enron.com', 'Re: General Brinks Position Meeting', 'Eloy, - -Who is General Brinks? - -Fletch'); -INSERT INTO email([from],[to],subject,body) VALUES('nailia.dindarova@enron.com', 'richard.shapiro@enron.com', 'Documents for Mark Frevert (on EU developments and lessons from', 'Rick, - -Here are the documents that Peter has prepared for Mark Frevert. - -Nailia ----------------------- Forwarded by Nailia Dindarova/LON/ECT on 25/06/2001 -16:36 --------------------------- - - -Nailia Dindarova -25/06/2001 15:36 -To: Michael Brown/Enron@EUEnronXGate -cc: Ross Sankey/Enron@EUEnronXGate, Eric Shaw/ENRON@EUEnronXGate, Peter -Styles/LON/ECT@ECT - -Subject: Documents for Mark Frevert (on EU developments and lessons from -California) - -Michael, - - -These are the documents that Peter promised to give to you for Mark Frevert. -He has now handed them to him in person but asked me to transmit them -electronically to you, as well as Eric and Ross. - -Nailia - - - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('peggy.a.kostial@accenture.com', 'dave.samuels@enron.com', 'EOL-Accenture Deal Sheet', 'Dave - - -Attached are our comments and suggested changes. Please call to review. - -On the time line for completion, we have four critical steps to complete: - Finalize market analysis to refine business case, specifically - projected revenue stream - Complete counterparty surveying, including targeting 3 CPs for letters - of intent - Review Enron asset base for potential reuse/ licensing - Contract negotiations - -Joe will come back to us with an updated time line, but it is my -expectation that we are still on the same schedule (we just begun week -three) with possibly a week or so slippage.....contract negotiations will -probably be the critical path. - -We will send our cut at the actual time line here shortly. Thanks, - -Peggy - -(See attached file: accenture-dealpoints v2.doc) - - accenture-dealpoints v2.doc '); -INSERT INTO email([from],[to],subject,body) VALUES('thomas.martin@enron.com', 'thomas.martin@enron.com', 'Re: Guadalupe Power Partners LP', '---------------------- Forwarded by Thomas A Martin/HOU/ECT on 03/20/2001 -03:49 PM --------------------------- - - -Thomas A Martin -10/11/2000 03:55 PM -To: Patrick Wade/HOU/ECT@ECT -cc: -Subject: Re: Guadalupe Power Partners LP - -The deal is physically served at Oasis Waha or Oasis Katy and is priced at -either HSC, Waha or Katytailgate GD at buyers option three days prior to -NYMEX close. - -'); -INSERT INTO email([from],[to],subject,body) VALUES('judy.townsend@enron.com', 'dan.junek@enron.com, chris.germany@enron.com', 'Columbia Distribution''s Capacity Available for Release - Sum', '---------------------- Forwarded by Judy Townsend/HOU/ECT on 03/09/2001 11:04 -AM --------------------------- - - -agoddard@nisource.com on 03/08/2001 09:16:57 AM -To: " - *Koch, Kent" , " - -*Millar, Debra" , " - *Burke, Lynn" - -cc: " - *Heckathorn, Tom" -Subject: Columbia Distribution''s Capacity Available for Release - Sum - - -Attached is Columbia Distribution''s notice of capacity available for release -for -the summer of 2001 (Apr. 2001 through Oct. 2001). - -Please note that the deadline for bids is 3:00pm EST on March 20, 2001. - -If you have any questions, feel free to contact any of the representatives -listed -at the bottom of the attachment. - -Aaron Goddard - - - - - - 2001Summer.doc -'); -INSERT INTO email([from],[to],subject,body) VALUES('rhonda.denton@enron.com', 'tim.belden@enron.com, dana.davis@enron.com, genia.fitzgerald@enron.com,', 'Split Rock Energy LLC', 'We have received the executed EEI contract from this CP dated 12/12/2000. -Copies will be distributed to Legal and Credit.'); -INSERT INTO email([from],[to],subject,body) VALUES('kerrymcelroy@dwt.com', 'jack.speer@alcoa.com, crow@millernash.com, michaelearly@earthlink.net,', 'Oral Argument Request', ' - Oral Argument Request.doc'); -INSERT INTO email([from],[to],subject,body) VALUES('mike.carson@enron.com', 'rlmichaelis@hormel.com', '', 'Did you come in town this wk end..... My new number at our house is : -713-668-3712...... my cell # is 281-381-7332 - -the kid'); -INSERT INTO email([from],[to],subject,body) VALUES('cooper.richey@enron.com', 'trycooper@hotmail.com', 'FW: Contact Info', ' - ------Original Message----- -From: Punja, Karim -Sent: Thursday, December 13, 2001 2:35 PM -To: Richey, Cooper -Subject: Contact Info - - -Cooper, - -Its been a real pleasure working with you (even though it was for only a small amount of time) -I hope we can stay in touch. - -Home# 234-0249 -email: kpunja@hotmail.com - -Take Care, - -Karim. - '); -INSERT INTO email([from],[to],subject,body) VALUES('bjm30@earthlink.net', 'mcguinn.k@enron.com, mcguinn.ian@enron.com, mcguinn.stephen@enron.com,', 'email address change', 'Hello all. - -I haven''t talked to many of you via email recently but I do want to give you -my new address for your email file: - - bjm30@earthlink.net - -I hope all is well. - -Brian McGuinn'); -INSERT INTO email([from],[to],subject,body) VALUES('shelley.corman@enron.com', 'steve.hotte@enron.com', 'Flat Panels', 'Can you please advise what is going on with the flat panels that we had planned to distribute to our gas logistics team. It was in the budget and we had the okay, but now I''m hearing there is some hold-up & the units are stored on 44. - -Shelley'); -INSERT INTO email([from],[to],subject,body) VALUES('sara.davidson@enron.com', 'john.schwartzenburg@enron.com, scott.dieball@enron.com, recipients@enron.com,', '2001 Enron Law Conference (Distribution List 2)', ' Enron Law Conference - -San Antonio, Texas May 2-4, 2001 Westin Riverwalk - - See attached memo for more details!! - - -? Registration for the law conference this year will be handled through an -Online RSVP Form on the Enron Law Conference Website at -http://lawconference.corp.enron.com. The website is still under construction -and will not be available until Thursday, March 15, 2001. - -? We will send you another e-mail to confirm when the Law Conference Website -is operational. - -? Please complete the Online RSVP Form as soon as it is available and submit -it no later than Friday, March 30th. - - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('tori.kuykendall@enron.com', 'heath.b.taylor@accenture.com', 'Re:', 'hey - thats funny about john - he definitely remembers him - i''ll call pat -and let him know - we are coming on saturday - i just havent had a chance to -call you guys back -- looking forward to it -- i probably need the -directions again though'); -INSERT INTO email([from],[to],subject,body) VALUES('darron.giron@enron.com', 'bryce.baxter@enron.com', 'Re: Feedback for Audrey Cook', 'Bryce, - -I''ll get it done today. - -DG 3-9573 - - - - - - From: Bryce Baxter 06/12/2000 07:15 PM - - -To: Darron C Giron/HOU/ECT@ECT -cc: -Subject: Feedback for Audrey Cook - -You were identified as a reviewer for Audrey Cook. If possible, could you -complete her feedback by end of business Wednesday? It will really help me -in the PRC process to have your input. Thanks. - -'); -INSERT INTO email([from],[to],subject,body) VALUES('casey.evans@enron.com', 'stephanie.sever@enron.com', 'Gas EOL ID', 'Stephanie, - -In conjunction with the recent movement of several power traders, they are changing the names of their gas books as well. The names of the new gas books and traders are as follows: - -PWR-NG-LT-SPP: Mike Carson -PWR-NG-LT-SERC: Jeff King - -If you need to know their power desk to map their ID to their gas books, those desks are as follows: - -EPMI-LT-SPP: Mike Carson -EPMI-LT-SERC: Jeff King - -I will be in training this afternoon, but will be back when class is over. Let me know if you have any questions. - -Thanks for your help! -Casey'); -INSERT INTO email([from],[to],subject,body) VALUES('darrell.schoolcraft@enron.com', 'david.roensch@enron.com, kimberly.watson@enron.com, michelle.lokay@enron.com,', 'Postings', 'Please see the attached. - - -ds - - - - - '); -INSERT INTO email([from],[to],subject,body) VALUES('mcominsky@aol.com', 'cpatman@bracepatt.com, james_derrick@enron.com', 'Jurisprudence Luncheon', 'Carrin & Jim -- - -It was an honor and a pleasure to meet both of you yesterday. I know we will -have fun working together on this very special event. - -Jeff left the jurisprudence luncheon lists for me before he left on vacation. - I wasn''t sure whether he transmitted them to you as well. Would you please -advise me if you would like them sent to you? I can email the MS Excel files -or I can fax the hard copies to you. Please advise what is most convenient. - -I plan to be in town through the holidays and can be reached by phone, email, -or cell phone at any time. My cell phone number is 713/705-4829. - -Thanks again for your interest in the ADL''s work. Martin. - -Martin B. Cominsky -Director, Southwest Region -Anti-Defamation League -713/627-3490, ext. 122 -713/627-2011 (fax) -MCominsky@aol.com'); -INSERT INTO email([from],[to],subject,body) VALUES('phillip.love@enron.com', 'todagost@utmb.edu, gbsonnta@utmb.edu', 'New President', 'I had a little bird put a word in my ear. Is there any possibility for Ben -Raimer to be Bush''s secretary of HHS? Just curious about that infamous UTMB -rumor mill. Hope things are well, happy holidays. -PL'); -INSERT INTO email([from],[to],subject,body) VALUES('marie.heard@enron.com', 'ehamilton@fna.com', 'ISDA Master Agreement', 'Erin: - -Pursuant to your request, attached are the Schedule to the ISDA Master Agreement, together with Paragraph 13 to the ISDA Credit Support Annex. Please let me know if you need anything else. We look forward to hearing your comments. - -Marie - -Marie Heard -Senior Legal Specialist -Enron North America Corp. -Phone: (713) 853-3907 -Fax: (713) 646-3490 -marie.heard@enron.com - - '); -INSERT INTO email([from],[to],subject,body) VALUES('andrea.ring@enron.com', 'beverly.beaty@enron.com', 'Re: Tennessee Buy - Louis Dreyfus', 'Beverly - once again thanks so much for your help on this. - - - - '); -INSERT INTO email([from],[to],subject,body) VALUES('karolyn.criado@enron.com', 'j..bonin@enron.com, felicia.case@enron.com, b..clapp@enron.com,', 'Price List week of Oct. 8-9, 2001', ' -Please contact me if you have any questions regarding last weeks prices. - -Thank you, -Karolyn Criado -3-9441 - - - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('kevin.presto@enron.com', 'edward.baughman@enron.com, billy.braddock@enron.com', 'Associated', 'Please begin working on filling our Associated short position in 02. I would like to take this risk off the books. - -In addition, please find out what a buy-out of VEPCO would cost us. With Rogers transitioning to run our retail risk management, I would like to clean up our customer positions. - -We also need to continue to explore a JEA buy-out. - -Thanks.'); -INSERT INTO email([from],[to],subject,body) VALUES('stacy.dickson@enron.com', 'gregg.penman@enron.com', 'RE: Constellation TC 5-7-01', 'Gregg, - -I am at home with a sick baby. (Lots of fun!) I will call you about this -tomorrow. - -Stacy'); -INSERT INTO email([from],[to],subject,body) VALUES('joe.quenet@enron.com', 'dfincher@utilicorp.com', '', 'hey big guy.....check this out..... - - w ww.gorelieberman-2000.com/'); -INSERT INTO email([from],[to],subject,body) VALUES('k..allen@enron.com', 'jacqestc@aol.com', '', 'Jacques, - -I sent you a fax of Kevin Kolb''s comments on the release. The payoff on the note would be $36,248 ($36090(principal) + $158 (accrued interest)). -This is assuming we wrap this up on Tuesday. - -Please email to confirm that their changes are ok so I can set up a meeting on Tuesday to reach closure. - -Phillip'); -INSERT INTO email([from],[to],subject,body) VALUES('kourtney.nelson@enron.com', 'mike.swerzbin@enron.com', 'Adjusted L/R Balance', 'Mike, - -I placed the adjusted L/R Balance on the Enronwest site. It is under the "Staff/Kourtney Nelson". There are two links: - -1) "Adj L_R" is the same data/format from the weekly strategy meeting. -2) "New Gen 2001_2002" link has all of the supply side info that is used to calculate the L/R balance - -Please note the Data Flag column, a value of "3" indicates the project was cancelled, on hold, etc and is not included in the calc. - -Both of these sheets are interactive Excel spreadsheets and thus you can play around with the data as you please. Also, James Bruce is working to get his gen report on the web. That will help with your access to information on new gen. - -Please let me know if you have any questions or feedback, - -Kourtney - - - -Kourtney Nelson -Fundamental Analysis -Enron North America -(503) 464-8280 -kourtney.nelson@enron.com'); -INSERT INTO email([from],[to],subject,body) VALUES('d..thomas@enron.com', 'naveed.ahmed@enron.com', 'FW: Current Enron TCC Portfolio', ' - ------Original Message----- -From: Grace, Rebecca M. -Sent: Monday, December 17, 2001 9:44 AM -To: Thomas, Paul D. -Cc: Cashion, Jim; Allen, Thresa A.; May, Tom -Subject: RE: Current Enron TCC Portfolio - - -Paul, - -I reviewed NY''s list. I agree with all of their contracts numbers and mw amounts. - -Call if you have any more questions. - -Rebecca - - - - -----Original Message----- -From: Thomas, Paul D. -Sent: Monday, December 17, 2001 9:08 AM -To: Grace, Rebecca M. -Subject: FW: Current Enron TCC Portfolio - - << File: enrontccs.xls >> -Rebecca, -Let me know if you see any differences. - -Paul -X 3-0403 ------Original Message----- -From: Thomas, Paul D. -Sent: Monday, December 17, 2001 9:04 AM -To: Ahmed, Naveed -Subject: FW: Current Enron TCC Portfolio - - - - ------Original Message----- -From: Thomas, Paul D. -Sent: Thursday, December 13, 2001 10:01 AM -To: Baughman, Edward D. -Subject: Current Enron TCC Portfolio - - -'); -INSERT INTO email([from],[to],subject,body) VALUES('stephanie.panus@enron.com', 'william.bradford@enron.com, debbie.brackett@enron.com,', 'Coastal Merchant Energy/El Paso Merchant Energy', 'Coastal Merchant Energy, L.P. merged with and into El Paso Merchant Energy, -L.P., effective February 1, 2001, with the surviving entity being El Paso -Merchant Energy, L.P. We currently have ISDA Master Agreements with both -counterparties. Please see the attached memo regarding the existing Masters -and let us know which agreement should be terminated. - -Thanks, -Stephanie -'); -INSERT INTO email([from],[to],subject,body) VALUES('kam.keiser@enron.com', 'c..kenne@enron.com', 'RE: What about this too???', ' - - -----Original Message----- -From: Kenne, Dawn C. -Sent: Wednesday, February 06, 2002 11:50 AM -To: Keiser, Kam -Subject: What about this too??? - - - << File: Netco Trader Matrix.xls >> - '); -INSERT INTO email([from],[to],subject,body) VALUES('chris.meyer@enron.com', 'joe.parks@enron.com', 'Centana', 'Talked to Chip. We do need Cash Committe approval given the netting feature of your deal, which means Batch Funding Request. Please update per my previous e-mail and forward. - -Thanks - -chris -x31666'); -INSERT INTO email([from],[to],subject,body) VALUES('debra.perlingiere@enron.com', 'jworman@academyofhealth.com', '', 'Have a great weekend! Happy Fathers Day! - - -Debra Perlingiere -Enron North America Corp. -1400 Smith Street, EB 3885 -Houston, Texas 77002 -dperlin@enron.com -Phone 713-853-7658 -Fax 713-646-3490'); -INSERT INTO email([from],[to],subject,body) VALUES('outlook.team@enron.com', '', 'Demo by Martha Janousek of Dashboard & Pipeline Profile / Julia &', 'CALENDAR ENTRY: APPOINTMENT - -Description: - Demo by Martha Janousek of Dashboard & Pipeline Profile / Julia & Dir Rpts. - 4102 - -Date: 1/5/2001 -Time: 9:00 AM - 10:00 AM (Central Standard Time) - -Chairperson: Outlook Migration Team - -Detailed Description:'); -INSERT INTO email([from],[to],subject,body) VALUES('diana.seifert@enron.com', 'mark.taylor@enron.com', 'Guest access Chile', 'Hello Mark, - -Justin Boyd told me that your can help me with questions regarding Chile. -We got a request for guest access through MG. -The company is called Escondida and is a subsidiary of BHP Australia. - -Please advise if I can set up a guest account or not. -F.Y.I.: MG is planning to put a "in w/h Chile" contract for Copper on-line as -soon as Enron has done the due diligence for this country. -Thanks ! - - -Best regards - -Diana Seifert -EOL PCG'); -INSERT INTO email([from],[to],subject,body) VALUES('enron_update@concureworkplace.com', 'mark.whitt@enron.com', '<> - 121001', 'The Approval status has changed on the following report: - -Status last changed by: Barry L. Tycholiz -Expense Report Name: 121001 -Report Total: $198.98 -Amount Due Employee: $198.98 -Amount Approved: $198.98 -Amount Paid: $0.00 -Approval Status: Approved -Payment Status: Pending - - -To review this expense report, click on the following link for Concur Expense. -http://expensexms.enron.com'); -INSERT INTO email([from],[to],subject,body) VALUES('kevin.hyatt@enron.com', '', 'Technical Support', 'Outside the U.S., please refer to the list below: - -Australia: -1800 678-515 -support@palm-au.com - -Canada: -1905 305-6530 -support@palm.com - -New Zealand: -0800 446-398 -support@palm-nz.com - -U.K.: -0171 867 0108 -eurosupport@palm.3com.com - -Please refer to the Worldwide Customer Support card for a complete technical support contact list.'); -INSERT INTO email([from],[to],subject,body) VALUES('geoff.storey@enron.com', 'dutch.quigley@enron.com', 'RE:', 'duke contact? - - -----Original Message----- -From: Quigley, Dutch -Sent: Wednesday, October 31, 2001 10:14 AM -To: Storey, Geoff -Subject: RE: - -bp corp Albert LaMore 281-366-4962 - -running the reports now - - - -----Original Message----- -From: Storey, Geoff -Sent: Wednesday, October 31, 2001 10:10 AM -To: Quigley, Dutch -Subject: RE: - -give me a contact over there too -BP - - - -----Original Message----- -From: Quigley, Dutch -Sent: Wednesday, October 31, 2001 9:42 AM -To: Storey, Geoff -Subject: - -Coral Jeff Whitnah 713-767-5374 -Relaint Steve McGinn 713-207-4000'); -INSERT INTO email([from],[to],subject,body) VALUES('pete.davis@enron.com', 'pete.davis@enron.com', 'Start Date: 4/22/01; HourAhead hour: 3; ', 'Start Date: 4/22/01; HourAhead hour: 3; No ancillary schedules awarded. -Variances detected. -Variances detected in Load schedule. - - LOG MESSAGES: - -PARSING FILE -->> O:\Portland\WestDesk\California Scheduling\ISO Final -Schedules\2001042203.txt - ----- Load Schedule ---- -$$$ Variance found in table tblLoads. - Details: (Hour: 3 / Preferred: 1.92 / Final: 1.89) - TRANS_TYPE: FINAL - LOAD_ID: PGE4 - MKT_TYPE: 2 - TRANS_DATE: 4/22/01 - SC_ID: EPMI - -'); -INSERT INTO email([from],[to],subject,body) VALUES('john.postlethwaite@enron.com', 'john.zufferli@enron.com', 'Reference', 'John, hope things are going well up there for you. The big day is almost here for you and Jessica. I was wondering if I could use your name as a job reference if need be. I am just trying to get everything in order just in case something happens. - -John'); -INSERT INTO email([from],[to],subject,body) VALUES('jeffrey.shankman@enron.com', 'lschiffm@jonesday.com', 'Re:', 'I saw you called on the cell this a.m. Sorry I missed you. (I was in the -shower). I have had a shitty week--I suspect my silence (not only to you, -but others) after our phone call is a result of the week. I''m seeing Glen at -11:15....talk to you'); -INSERT INTO email([from],[to],subject,body) VALUES('litebytz@enron.com', '', 'Lite Bytz RSVP', ' -This week''s Lite Bytz presentation will feature the following TOOLZ speaker: - -Richard McDougall -Solaris 8 -Thursday, June 7, 2001 - -If you have not already signed up, please RSVP via email to litebytz@enron.com by the end of the day Tuesday, June 5, 2001. - -*Remember: this is now a Brown Bag Event--so bring your lunch and we will provide cookies and drinks. - -Click below for more details. - -http://home.enron.com:84/messaging/litebytztoolzprint.jpg'); - COMMIT; - } -} {} - -############################################################################### -# Everything above just builds an interesting test database. The actual -# tests come after this comment. -############################################################################### - -do_test fts2c-1.2 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark' - } -} {6 17 25 38 40 42 73 74} -do_test fts2c-1.3 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'susan' - } -} {24 40} -do_test fts2c-1.4 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark susan' - } -} {40} -do_test fts2c-1.5 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'susan mark' - } -} {40} -do_test fts2c-1.6 { - execsql { - SELECT rowid FROM email WHERE email MATCH '"mark susan"' - } -} {} -do_test fts2c-1.7 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark -susan' - } -} {6 17 25 38 42 73 74} -do_test fts2c-1.8 { - execsql { - SELECT rowid FROM email WHERE email MATCH '-mark susan' - } -} {24} -do_test fts2c-1.9 { - execsql { - SELECT rowid FROM email WHERE email MATCH 'mark OR susan' - } -} {6 17 24 25 38 40 42 73 74} - -# Some simple tests of the automatic "offsets(email)" column. In the sample -# data set above, only one message, number 20, contains the words -# "gas" and "reminder" in both body and subject. -# -do_test fts2c-2.1 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE email MATCH 'gas reminder' - } -} {20 {2 0 42 3 2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}} -do_test fts2c-2.2 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE email MATCH 'subject:gas reminder' - } -} {20 {2 0 42 3 2 1 54 8 3 1 54 8}} -do_test fts2c-2.3 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE email MATCH 'body:gas reminder' - } -} {20 {2 1 54 8 3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}} -do_test fts2c-2.4 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE subject MATCH 'gas reminder' - } -} {20 {2 0 42 3 2 1 54 8}} -do_test fts2c-2.5 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE body MATCH 'gas reminder' - } -} {20 {3 0 42 3 3 1 54 8 3 0 129 3 3 0 143 3 3 0 240 3}} - -# Document 32 contains 5 instances of the world "child". But only -# 3 of them are paired with "product". Make sure only those instances -# that match the phrase appear in the offsets(email) list. -# -do_test fts2c-3.1 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE body MATCH 'child product' AND +rowid=32 - } -} {32 {3 0 94 5 3 0 114 5 3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7 3 1 493 7}} -do_test fts2c-3.2 { - execsql { - SELECT rowid, offsets(email) FROM email - WHERE body MATCH '"child product"' - } -} {32 {3 0 207 5 3 1 213 7 3 0 245 5 3 1 251 7 3 0 409 5 3 1 415 7}} - -# Snippet generator tests -# -do_test fts2c-4.1 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'subject:gas reminder' - } -} {{Alert Posted 10:00 AM November 20,2000: E-GAS Request Reminder}} -do_test fts2c-4.2 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'christmas candlelight' - } -} {{... place.? What do you think about going here Christmas -eve?? They have an 11:00 a.m. service and a candlelight service at 5:00 p.m., -among others. ...}} - -do_test fts2c-4.3 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'deal sheet potential reuse' - } -} {{EOL-Accenture Deal Sheet ... intent - Review Enron asset base for potential reuse/ licensing - Contract negotiations ...}} -do_test fts2c-4.4 { - execsql { - SELECT snippet(email,'<<<','>>>',' ') FROM email - WHERE email MATCH 'deal sheet potential reuse' - } -} {{EOL-Accenture <<>> <<>> intent - Review Enron asset base for <<>> <<>>/ licensing - Contract negotiations }} -do_test fts2c-4.5 { - execsql { - SELECT snippet(email,'<<<','>>>',' ') FROM email - WHERE email MATCH 'first things' - } -} {{Re: <<>> Polish Deal! Congrats! <<>> seem to be building rapidly now on the }} -do_test fts2c-4.6 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'chris is here' - } -} {{chris.germany@enron.com ... Sounds good to me. I bet this is next to the Warick?? Hotel. ... place.? What do you think about going here Christmas -eve?? They have an 11:00 a.m. ...}} -do_test fts2c-4.7 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH '"pursuant to"' - } -} {{Erin: - -Pursuant to your request, attached are the Schedule to ...}} -do_test fts2c-4.8 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'ancillary load davis' - } -} {{pete.davis@enron.com ... Start Date: 4/22/01; HourAhead hour: 3; No ancillary schedules awarded. -Variances detected. -Variances detected in Load schedule. - - LOG MESSAGES: - -PARSING ...}} - -# Combinations of AND and OR operators: -# -do_test fts2c-5.1 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'questar enron OR com' - } -} {{matt.smith@enron.com ... six reports: - -31 Keystone Receipts -15 Questar Pipeline -40 Rockies Production -22 West_2 ...}} -do_test fts2c-5.2 { - execsql { - SELECT snippet(email) FROM email - WHERE email MATCH 'enron OR com questar' - } -} {{matt.smith@enron.com ... six reports: - -31 Keystone Receipts -15 Questar Pipeline -40 Rockies Production -22 West_2 ...}} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2d.test sqlite3-3.44.0-0/test/fts2d.test --- sqlite3-3.42.0/test/fts2d.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2d.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -# 2006 October 1 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing the FTS2 module, and in particular -# the Porter stemmer. -# -# $Id: fts2d.test,v 1.1 2006/10/19 23:36:26 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -do_test fts2d-1.1 { - execsql { - CREATE VIRTUAL TABLE t1 USING fts2(content, tokenize porter); - INSERT INTO t1(rowid, content) VALUES(1, 'running and jumping'); - SELECT rowid FROM t1 WHERE content MATCH 'run jump'; - } -} {1} -do_test fts2d-1.2 { - execsql { - SELECT snippet(t1) FROM t1 WHERE t1 MATCH 'run jump'; - } -} {{running and jumping}} -do_test fts2d-1.3 { - execsql { - INSERT INTO t1(rowid, content) - VALUES(2, 'abcdefghijklmnopqrstuvwyxz'); - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijqrstuvwyxz' - } -} {2 abcdefghijklmnopqrstuvwyxz} -do_test fts2d-1.4 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH 'abcdefghijXXXXqrstuvwyxz' - } -} {2 abcdefghijklmnopqrstuvwyxz} -do_test fts2d-1.5 { - execsql { - INSERT INTO t1(rowid, content) - VALUES(3, 'The value is 123456789'); - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123789' - } -} {3 {The value is 123456789}} -do_test fts2d-1.6 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE t1 MATCH '123000000789' - } -} {3 {The value is 123456789}} - - -finish_test diff -Nru sqlite3-3.42.0/test/fts2e.test sqlite3-3.44.0-0/test/fts2e.test --- sqlite3-3.42.0/test/fts2e.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2e.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,85 +0,0 @@ -# 2006 October 19 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing deletions in the FTS2 module. -# -# $Id: fts2e.test,v 1.1 2006/10/19 23:36:26 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Construct a full-text search table containing keywords which are the -# ordinal numbers of the bit positions set for a sequence of integers, -# which are used for the rowid. There are a total of 30 INSERT and -# DELETE statements, so that we'll test both the segmentMerge() merge -# (over the first 16) and the termSelect() merge (over the level-1 -# segment and 14 level-0 segments). -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(content); - INSERT INTO t1 (rowid, content) VALUES(1, 'one'); - INSERT INTO t1 (rowid, content) VALUES(2, 'two'); - INSERT INTO t1 (rowid, content) VALUES(3, 'one two'); - INSERT INTO t1 (rowid, content) VALUES(4, 'three'); - DELETE FROM t1 WHERE rowid = 1; - INSERT INTO t1 (rowid, content) VALUES(5, 'one three'); - INSERT INTO t1 (rowid, content) VALUES(6, 'two three'); - INSERT INTO t1 (rowid, content) VALUES(7, 'one two three'); - DELETE FROM t1 WHERE rowid = 4; - INSERT INTO t1 (rowid, content) VALUES(8, 'four'); - INSERT INTO t1 (rowid, content) VALUES(9, 'one four'); - INSERT INTO t1 (rowid, content) VALUES(10, 'two four'); - DELETE FROM t1 WHERE rowid = 7; - INSERT INTO t1 (rowid, content) VALUES(11, 'one two four'); - INSERT INTO t1 (rowid, content) VALUES(12, 'three four'); - INSERT INTO t1 (rowid, content) VALUES(13, 'one three four'); - DELETE FROM t1 WHERE rowid = 10; - INSERT INTO t1 (rowid, content) VALUES(14, 'two three four'); - INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four'); - INSERT INTO t1 (rowid, content) VALUES(16, 'five'); - DELETE FROM t1 WHERE rowid = 13; - INSERT INTO t1 (rowid, content) VALUES(17, 'one five'); - INSERT INTO t1 (rowid, content) VALUES(18, 'two five'); - INSERT INTO t1 (rowid, content) VALUES(19, 'one two five'); - DELETE FROM t1 WHERE rowid = 16; - INSERT INTO t1 (rowid, content) VALUES(20, 'three five'); - INSERT INTO t1 (rowid, content) VALUES(21, 'one three five'); - INSERT INTO t1 (rowid, content) VALUES(22, 'two three five'); - DELETE FROM t1 WHERE rowid = 19; - DELETE FROM t1 WHERE rowid = 22; -} - -do_test fts2f-1.1 { - execsql {SELECT COUNT(*) FROM t1} -} {14} - -do_test fts2e-2.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'} -} {3 5 9 11 15 17 21} - -do_test fts2e-2.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'} -} {2 3 6 11 14 15 18} - -do_test fts2e-2.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'} -} {5 6 12 14 15 20 21} - -do_test fts2e-2.4 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'} -} {8 9 11 12 14 15} - -do_test fts2e-2.5 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'} -} {17 18 20 21} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2f.test sqlite3-3.44.0-0/test/fts2f.test --- sqlite3-3.42.0/test/fts2f.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2f.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,90 +0,0 @@ -# 2006 October 19 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing updates in the FTS2 module. -# -# $Id: fts2f.test,v 1.2 2007/02/23 00:14:06 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Construct a full-text search table containing keywords which are the -# ordinal numbers of the bit positions set for a sequence of integers, -# which are used for the rowid. There are a total of 31 INSERT, -# UPDATE, and DELETE statements, so that we'll test both the -# segmentMerge() merge (over the first 16) and the termSelect() merge -# (over the level-1 segment and 15 level-0 segments). -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(content); - INSERT INTO t1 (rowid, content) VALUES(1, 'one'); - INSERT INTO t1 (rowid, content) VALUES(2, 'two'); - INSERT INTO t1 (rowid, content) VALUES(3, 'one two'); - INSERT INTO t1 (rowid, content) VALUES(4, 'three'); - INSERT INTO t1 (rowid, content) VALUES(5, 'one three'); - INSERT INTO t1 (rowid, content) VALUES(6, 'two three'); - INSERT INTO t1 (rowid, content) VALUES(7, 'one two three'); - DELETE FROM t1 WHERE rowid = 4; - INSERT INTO t1 (rowid, content) VALUES(8, 'four'); - UPDATE t1 SET content = 'update one three' WHERE rowid = 1; - INSERT INTO t1 (rowid, content) VALUES(9, 'one four'); - INSERT INTO t1 (rowid, content) VALUES(10, 'two four'); - DELETE FROM t1 WHERE rowid = 7; - INSERT INTO t1 (rowid, content) VALUES(11, 'one two four'); - INSERT INTO t1 (rowid, content) VALUES(12, 'three four'); - INSERT INTO t1 (rowid, content) VALUES(13, 'one three four'); - DELETE FROM t1 WHERE rowid = 10; - INSERT INTO t1 (rowid, content) VALUES(14, 'two three four'); - INSERT INTO t1 (rowid, content) VALUES(15, 'one two three four'); - UPDATE t1 SET content = 'update two five' WHERE rowid = 8; - INSERT INTO t1 (rowid, content) VALUES(16, 'five'); - DELETE FROM t1 WHERE rowid = 13; - INSERT INTO t1 (rowid, content) VALUES(17, 'one five'); - INSERT INTO t1 (rowid, content) VALUES(18, 'two five'); - INSERT INTO t1 (rowid, content) VALUES(19, 'one two five'); - DELETE FROM t1 WHERE rowid = 16; - INSERT INTO t1 (rowid, content) VALUES(20, 'three five'); - INSERT INTO t1 (rowid, content) VALUES(21, 'one three five'); - INSERT INTO t1 (rowid, content) VALUES(22, 'two three five'); - DELETE FROM t1 WHERE rowid = 19; - UPDATE t1 SET content = 'update' WHERE rowid = 15; -} - -do_test fts2f-1.1 { - execsql {SELECT COUNT(*) FROM t1} -} {16} - -do_test fts2f-2.0 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'update'} -} {1 8 15} - -do_test fts2f-2.1 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'one'} -} {1 3 5 9 11 17 21} - -do_test fts2f-2.2 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'two'} -} {2 3 6 8 11 14 18 22} - -do_test fts2f-2.3 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'three'} -} {1 5 6 12 14 20 21 22} - -do_test fts2f-2.4 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'four'} -} {9 11 12 14} - -do_test fts2f-2.5 { - execsql {SELECT rowid FROM t1 WHERE content MATCH 'five'} -} {8 17 18 20 21 22} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2g.test sqlite3-3.44.0-0/test/fts2g.test --- sqlite3-3.42.0/test/fts2g.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2g.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,93 +0,0 @@ -# 2006 October 19 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing handling of edge cases for various doclist -# merging functions in the FTS2 module query logic. -# -# $Id: fts2g.test,v 1.3 2007/11/16 00:23:08 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(content); - INSERT INTO t1 (rowid, content) VALUES(1, 'this is a test'); - INSERT INTO t1 (rowid, content) VALUES(2, 'also a test'); -} - -# No hits at all. Returns empty doclists from termSelect(). -do_test fts2g-1.1 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something'} -} {} - -# Empty left in docListExceptMerge(). -do_test fts2g-1.2 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH '-this something'} -} {} - -# Empty right in docListExceptMerge(). -do_test fts2g-1.3 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this -something'} -} {1} - -# Empty left in docListPhraseMerge(). -do_test fts2g-1.4 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"this something"'} -} {} - -# Empty right in docListPhraseMerge(). -do_test fts2g-1.5 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH '"something is"'} -} {} - -# Empty left in docListOrMerge(). -do_test fts2g-1.6 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something OR this'} -} {1} - -# Empty right in docListOrMerge(). -do_test fts2g-1.7 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this OR something'} -} {1} - -# Empty left in docListAndMerge(). -do_test fts2g-1.8 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something this'} -} {} - -# Empty right in docListAndMerge(). -do_test fts2g-1.9 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this something'} -} {} - -# No support for all-except queries. -do_test fts2g-1.10 { - catchsql {SELECT rowid FROM t1 WHERE t1 MATCH '-this -something'} -} {1 {SQL logic error}} - -# Test that docListOrMerge() correctly handles reaching the end of one -# doclist before it reaches the end of the other. -do_test fts2g-1.11 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'this OR also'} -} {1 2} -do_test fts2g-1.12 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'also OR this'} -} {1 2} - -# Empty left and right in docListOrMerge(). Each term matches neither -# row, and when combined there was an assertion failure. -do_test fts2g-1.13 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something OR nothing'} -} {} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2h.test sqlite3-3.44.0-0/test/fts2h.test --- sqlite3-3.42.0/test/fts2h.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2h.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,76 +0,0 @@ -# 2006 October 31 (scaaarey) -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# here is testing correct handling of excessively long terms. -# -# $Id: fts2h.test,v 1.1 2006/11/29 21:03:01 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Generate a term of len copies of char. -proc bigterm {char len} { - for {set term ""} {$len>0} {incr len -1} { - append term $char - } - return $term -} - -# Generate a document of bigterms based on characters from the list -# chars. -proc bigtermdoc {chars len} { - set doc "" - foreach char $chars { - append doc " " [bigterm $char $len] - } - return $doc -} - -set len 5000 -set doc1 [bigtermdoc {a b c d} $len] -set doc2 [bigtermdoc {b d e f} $len] -set doc3 [bigtermdoc {a c e} $len] - -set aterm [bigterm a $len] -set bterm [bigterm b $len] -set xterm [bigterm x $len] - -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(content); - INSERT INTO t1 (rowid, content) VALUES(1, $doc1); - INSERT INTO t1 (rowid, content) VALUES(2, $doc2); - INSERT INTO t1 (rowid, content) VALUES(3, $doc3); -} - -# No hits at all. Returns empty doclists from termSelect(). -do_test fts2h-1.1 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH 'something'} -} {} - -do_test fts2h-1.2 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH $aterm} -} {1 3} - -do_test fts2h-1.2 { - execsql {SELECT rowid FROM t1 WHERE t1 MATCH $xterm} -} {} - -do_test fts2h-1.3 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH '$aterm -$xterm'" -} {1 3} - -do_test fts2h-1.4 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"$aterm $bterm\"'" -} {1} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2i.test sqlite3-3.44.0-0/test/fts2i.test --- sqlite3-3.42.0/test/fts2i.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2i.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,87 +0,0 @@ -# 2007 January 17 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite fts2 library. The -# focus here is testing handling of UPDATE when using UTF-16-encoded -# databases. -# -# $Id: fts2i.test,v 1.2 2007/01/24 03:46:35 drh Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Return the UTF-16 representation of the supplied UTF-8 string $str. -# If $nt is true, append two 0x00 bytes as a nul terminator. -# NOTE(shess) Copied from capi3.test. -proc utf16 {str {nt 1}} { - set r [encoding convertto unicode $str] - if {$nt} { - append r "\x00\x00" - } - return $r -} - -db eval { - PRAGMA encoding = "UTF-16le"; - CREATE VIRTUAL TABLE t1 USING fts2(content); -} - -do_test fts2i-1.0 { - execsql {PRAGMA encoding} -} {UTF-16le} - -do_test fts2i-1.1 { - execsql {INSERT INTO t1 (rowid, content) VALUES(1, 'one')} - execsql {SELECT content FROM t1 WHERE rowid = 1} -} {one} - -do_test fts2i-1.2 { - set sql "INSERT INTO t1 (rowid, content) VALUES(2, 'two')" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 2} -} {two} - -do_test fts2i-1.3 { - set sql "INSERT INTO t1 (rowid, content) VALUES(3, 'three')" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - set sql "UPDATE t1 SET content = 'trois' WHERE rowid = 3" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 3} -} {trois} - -do_test fts2i-1.4 { - set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(4, 'four')}] - set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 4} -} {four} - -do_test fts2i-1.5 { - set sql16 [utf16 {INSERT INTO t1 (rowid, content) VALUES(5, 'five')}] - set STMT [sqlite3_prepare16 $DB $sql16 -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - set sql "UPDATE t1 SET content = 'cinq' WHERE rowid = 5" - set STMT [sqlite3_prepare $DB $sql -1 TAIL] - sqlite3_step $STMT - sqlite3_finalize $STMT - execsql {SELECT content FROM t1 WHERE rowid = 5} -} {cinq} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2j.test sqlite3-3.44.0-0/test/fts2j.test --- sqlite3-3.42.0/test/fts2j.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2j.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,89 +0,0 @@ -# 2007 February 6 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. This -# tests creating fts2 tables in an attached database. -# -# $Id: fts2j.test,v 1.1 2007/02/07 01:01:18 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Clean up anything left over from a previous pass. -forcedelete test2.db -forcedelete test2.db-journal -sqlite3 db2 test2.db - -db eval { - CREATE VIRTUAL TABLE t3 USING fts2(content); - INSERT INTO t3 (rowid, content) VALUES(1, "hello world"); -} - -db2 eval { - CREATE VIRTUAL TABLE t1 USING fts2(content); - INSERT INTO t1 (rowid, content) VALUES(1, "hello world"); - INSERT INTO t1 (rowid, content) VALUES(2, "hello there"); - INSERT INTO t1 (rowid, content) VALUES(3, "cruel world"); -} - -# This has always worked because the t1_* tables used by fts2 will be -# the defaults. -do_test fts2j-1.1 { - execsql { - ATTACH DATABASE 'test2.db' AS two; - SELECT rowid FROM t1 WHERE t1 MATCH 'hello'; - DETACH DATABASE two; - } -} {1 2} -# Make certain we're detached if there was an error. -catch {db eval {DETACH DATABASE two}} - -# In older code, this appears to work fine, but the t2_* tables used -# by fts2 will be created in database 'main' instead of database -# 'two'. It appears to work fine because the tables end up being the -# defaults, but obviously is badly broken if you hope to use things -# other than in the exact same ATTACH setup. -do_test fts2j-1.2 { - execsql { - ATTACH DATABASE 'test2.db' AS two; - CREATE VIRTUAL TABLE two.t2 USING fts2(content); - INSERT INTO t2 (rowid, content) VALUES(1, "hello world"); - INSERT INTO t2 (rowid, content) VALUES(2, "hello there"); - INSERT INTO t2 (rowid, content) VALUES(3, "cruel world"); - SELECT rowid FROM t2 WHERE t2 MATCH 'hello'; - DETACH DATABASE two; - } -} {1 2} -catch {db eval {DETACH DATABASE two}} - -# In older code, this broke because the fts2 code attempted to create -# t3_* tables in database 'main', but they already existed. Normally -# this wouldn't happen without t3 itself existing, in which case the -# fts2 code would never be called in the first place. -do_test fts2j-1.3 { - execsql { - ATTACH DATABASE 'test2.db' AS two; - - CREATE VIRTUAL TABLE two.t3 USING fts2(content); - INSERT INTO two.t3 (rowid, content) VALUES(2, "hello there"); - INSERT INTO two.t3 (rowid, content) VALUES(3, "cruel world"); - SELECT rowid FROM two.t3 WHERE t3 MATCH 'hello'; - - DETACH DATABASE two; - } db2 -} {2} -catch {db eval {DETACH DATABASE two}} - -catch {db2 close} -forcedelete test2.db - -finish_test diff -Nru sqlite3-3.42.0/test/fts2k.test sqlite3-3.44.0-0/test/fts2k.test --- sqlite3-3.42.0/test/fts2k.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2k.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,105 +0,0 @@ -# 2007 March 9 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. These -# make sure that fts2 insertion buffering is fully transparent when -# using transactions. -# -# $Id: fts2k.test,v 1.2 2007/08/10 23:47:04 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(content); - INSERT INTO t1 (rowid, content) VALUES(1, "hello world"); - INSERT INTO t1 (rowid, content) VALUES(2, "hello there"); - INSERT INTO t1 (rowid, content) VALUES(3, "cruel world"); -} - -# Test that possibly-buffered inserts went through after commit. -do_test fts2k-1.1 { - execsql { - BEGIN TRANSACTION; - INSERT INTO t1 (rowid, content) VALUES(4, "false world"); - INSERT INTO t1 (rowid, content) VALUES(5, "false door"); - COMMIT TRANSACTION; - SELECT rowid FROM t1 WHERE t1 MATCH 'world'; - } -} {1 3 4} - -# Test that buffered inserts are seen by selects in the same -# transaction. -do_test fts2k-1.2 { - execsql { - BEGIN TRANSACTION; - INSERT INTO t1 (rowid, content) VALUES(6, "another world"); - INSERT INTO t1 (rowid, content) VALUES(7, "another test"); - SELECT rowid FROM t1 WHERE t1 MATCH 'world'; - COMMIT TRANSACTION; - } -} {1 3 4 6} - -# Test that buffered inserts are seen within a transaction. This is -# really the same test as 1.2. -do_test fts2k-1.3 { - execsql { - BEGIN TRANSACTION; - INSERT INTO t1 (rowid, content) VALUES(8, "second world"); - INSERT INTO t1 (rowid, content) VALUES(9, "second sight"); - SELECT rowid FROM t1 WHERE t1 MATCH 'world'; - ROLLBACK TRANSACTION; - } -} {1 3 4 6 8} - -# Double-check that the previous result doesn't persist past the -# rollback! -do_test fts2k-1.4 { - execsql { - SELECT rowid FROM t1 WHERE t1 MATCH 'world'; - } -} {1 3 4 6} - -# Test it all together. -do_test fts2k-1.5 { - execsql { - BEGIN TRANSACTION; - INSERT INTO t1 (rowid, content) VALUES(10, "second world"); - INSERT INTO t1 (rowid, content) VALUES(11, "second sight"); - ROLLBACK TRANSACTION; - SELECT rowid FROM t1 WHERE t1 MATCH 'world'; - } -} {1 3 4 6} - -# Test that the obvious case works. -do_test fts2k-1.6 { - execsql { - BEGIN; - INSERT INTO t1 (rowid, content) VALUES(12, "third world"); - COMMIT; - SELECT rowid FROM t1 WHERE t1 MATCH 'third'; - } -} {12} - -# This is exactly the same as the previous test, except that older -# code loses the INSERT due to an SQLITE_SCHEMA error. -do_test fts2k-1.7 { - execsql { - BEGIN; - INSERT INTO t1 (rowid, content) VALUES(13, "third dimension"); - CREATE TABLE x (c); - COMMIT; - SELECT rowid FROM t1 WHERE t1 MATCH 'dimension'; - } -} {13} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2l.test sqlite3-3.44.0-0/test/fts2l.test --- sqlite3-3.42.0/test/fts2l.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2l.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,69 +0,0 @@ -# 2007 March 28 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing isspace/isalnum/tolower problems with the -# FTS2 module. Unfortunately, this code isn't a really principled set -# of tests, because it is impossible to know where new uses of these -# functions might appear. -# -# $Id: fts2l.test,v 1.2 2007/12/13 21:54:11 drh Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# Tests that startsWith() (calls isspace, tolower, isalnum) can handle -# hi-bit chars. parseSpec() also calls isalnum here. -do_test fts2l-1.1 { - execsql "CREATE VIRTUAL TABLE t1 USING fts2(content, \x80)" -} {} - -# Additionally tests isspace() call in getToken(), and isalnum() call -# in tokenListToIdList(). -do_test fts2l-1.2 { - catch { - execsql "CREATE VIRTUAL TABLE t2 USING fts2(content, tokenize \x80)" - } - sqlite3_errmsg $DB -} "unknown tokenizer: \x80" - -# Additionally test final isalnum() in startsWith(). -do_test fts2l-1.3 { - execsql "CREATE VIRTUAL TABLE t3 USING fts2(content, tokenize\x80)" -} {} - -# The snippet-generation code has calls to isspace() which are sort of -# hard to get to. It finds convenient breakpoints by starting ~40 -# chars before and after the matched term, and scanning ~10 chars -# around that position for isspace() characters. The long word with -# embedded hi-bit chars causes one of these isspace() calls to be -# exercised. The version with a couple extra spaces should cause the -# other isspace() call to be exercised. [Both cases have been tested -# in the debugger, but I'm hoping to continue to catch it if simple -# constant changes change things slightly. -# -# The trailing and leading hi-bit chars help with code which tests for -# isspace() to coalesce multiple spaces. - -set word "\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80xxxxx\x80" -set phrase1 "$word $word $word target $word $word $word" -set phrase2 "$word $word $word target $word $word $word" - -db eval {CREATE VIRTUAL TABLE t4 USING fts2(content)} -db eval "INSERT INTO t4 (content) VALUES ('$phrase1')" -db eval "INSERT INTO t4 (content) VALUES ('$phrase2')" - -do_test fts2l-1.4 { - execsql {SELECT rowid, length(snippet(t4)) FROM t4 WHERE t4 MATCH 'target'} -} {1 111 2 117} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2m.test sqlite3-3.44.0-0/test/fts2m.test --- sqlite3-3.42.0/test/fts2m.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2m.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,65 +0,0 @@ -# 2007 April 9 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements regression tests for SQLite library. fts2 -# DELETE handling assumed all fields were non-null. This was not -# the intention at all. -# -# $Id: fts2m.test,v 1.1 2007/04/09 20:45:42 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(col_a, col_b); - - INSERT INTO t1(rowid, col_a, col_b) VALUES(1, 'testing', 'testing'); - INSERT INTO t1(rowid, col_a, col_b) VALUES(2, 'only a', null); - INSERT INTO t1(rowid, col_a, col_b) VALUES(3, null, 'only b'); - INSERT INTO t1(rowid, col_a, col_b) VALUES(4, null, null); -} - -do_test fts2m-1.0 { - execsql { - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {2 2 4} - -do_test fts2m-1.1 { - execsql { - DELETE FROM t1 WHERE rowid = 1; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {1 1 3} - -do_test fts2m-1.2 { - execsql { - DELETE FROM t1 WHERE rowid = 2; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {0 1 2} - -do_test fts2m-1.3 { - execsql { - DELETE FROM t1 WHERE rowid = 3; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {0 0 1} - -do_test fts2m-1.4 { - execsql { - DELETE FROM t1 WHERE rowid = 4; - SELECT COUNT(col_a), COUNT(col_b), COUNT(*) FROM t1; - } -} {0 0 0} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2n.test sqlite3-3.44.0-0/test/fts2n.test --- sqlite3-3.42.0/test/fts2n.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2n.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,196 +0,0 @@ -# 2007 April 26 -# -# The author disclaims copyright to this source code. -# -#************************************************************************* -# This file implements tests for prefix-searching in the fts2 -# component of the SQLite library. -# -# $Id: fts2n.test,v 1.2 2007/12/13 21:54:11 drh Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -# A large string to prime the pump with. -set text { - Lorem ipsum dolor sit amet, consectetuer adipiscing elit. Maecenas - iaculis mollis ipsum. Praesent rhoncus placerat justo. Duis non quam - sed turpis posuere placerat. Curabitur et lorem in lorem porttitor - aliquet. Pellentesque bibendum tincidunt diam. Vestibulum blandit - ante nec elit. In sapien diam, facilisis eget, dictum sed, viverra - at, felis. Vestibulum magna. Sed magna dolor, vestibulum rhoncus, - ornare vel, vulputate sit amet, felis. Integer malesuada, tellus at - luctus gravida, diam nunc porta nibh, nec imperdiet massa metus eu - lectus. Aliquam nisi. Nunc fringilla nulla at lectus. Suspendisse - potenti. Cum sociis natoque penatibus et magnis dis parturient - montes, nascetur ridiculus mus. Pellentesque odio nulla, feugiat eu, - suscipit nec, consequat quis, risus. -} - -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(c); - - INSERT INTO t1(rowid, c) VALUES(1, $text); - INSERT INTO t1(rowid, c) VALUES(2, 'Another lovely row'); -} - -# Exact match -do_test fts2n-1.1 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lorem'" -} {1} - -# And a prefix -do_test fts2n-1.2 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lore*'" -} {1} - -# Prefix includes exact match -do_test fts2n-1.3 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lorem*'" -} {1} - -# Make certain everything isn't considered a prefix! -do_test fts2n-1.4 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lore'" -} {} - -# Prefix across multiple rows. -do_test fts2n-1.5 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lo*'" -} {1 2} - -# Likewise, with multiple hits in one document. -do_test fts2n-1.6 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'l*'" -} {1 2} - -# Prefix which should only hit one document. -do_test fts2n-1.7 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lov*'" -} {2} - -# * not at end is dropped. -do_test fts2n-1.8 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH 'lo *'" -} {} - -# Stand-alone * is dropped. -do_test fts2n-1.9 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH '*'" -} {} - -# Phrase-query prefix. -do_test fts2n-1.10 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"lovely r*\"'" -} {2} -do_test fts2n-1.11 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"lovely r\"'" -} {} - -# Phrase query with multiple prefix matches. -do_test fts2n-1.12 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"a* l*\"'" -} {1 2} - -# Phrase query with multiple prefix matches. -do_test fts2n-1.13 { - execsql "SELECT rowid FROM t1 WHERE t1 MATCH '\"a* l* row\"'" -} {2} - - - - -# Test across updates (and, by implication, deletes). - -# Version of text without "lorem". -regsub -all {[Ll]orem} $text '' ntext - -db eval { - CREATE VIRTUAL TABLE t2 USING fts2(c); - - INSERT INTO t2(rowid, c) VALUES(1, $text); - INSERT INTO t2(rowid, c) VALUES(2, 'Another lovely row'); - UPDATE t2 SET c = $ntext WHERE rowid = 1; -} - -# Can't see lorem as an exact match. -do_test fts2n-2.1 { - execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lorem'" -} {} - -# Can't see a prefix of lorem, either. -do_test fts2n-2.2 { - execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lore*'" -} {} - -# Can see lovely in the other document. -do_test fts2n-2.3 { - execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lo*'" -} {2} - -# Can still see other hits. -do_test fts2n-2.4 { - execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'l*'" -} {1 2} - -# Prefix which should only hit one document. -do_test fts2n-2.5 { - execsql "SELECT rowid FROM t2 WHERE t2 MATCH 'lov*'" -} {2} - - - -# Test with a segment which will have multiple levels in the tree. - -# Build a big document with lots of unique terms. -set bigtext $text -foreach c {a b c d e} { - regsub -all {[A-Za-z]+} $bigtext "&$c" t - append bigtext $t -} - -# Populate a table with many copies of the big document, so that we -# can test the number of hits found. Populate $ret with the expected -# hit counts for each row. offsets() returns 4 elements for every -# hit. We'll have 6 hits for row 1, 1 for row 2, and 6*(2^5)==192 for -# $bigtext. -set ret {6 1} -db eval { - BEGIN; - CREATE VIRTUAL TABLE t3 USING fts2(c); - - INSERT INTO t3(rowid, c) VALUES(1, $text); - INSERT INTO t3(rowid, c) VALUES(2, 'Another lovely row'); -} -for {set i 0} {$i<100} {incr i} { - db eval {INSERT INTO t3(rowid, c) VALUES(3+$i, $bigtext)} - lappend ret 192 -} -db eval {COMMIT;} - -# Test that we get the expected number of hits. -do_test fts2n-3.1 { - set t {} - db eval {SELECT offsets(t3) as o FROM t3 WHERE t3 MATCH 'l*'} { - set l [llength $o] - lappend t [expr {$l/4}] - } - set t -} $ret - -# TODO(shess) It would be useful to test a couple edge cases, but I -# don't know if we have the precision to manage it from here at this -# time. Prefix hits can cross leaves, which the code above _should_ -# hit by virtue of size. There are two variations on this. If the -# tree is 2 levels high, the code will find the leaf-node extent -# directly, but if its higher, the code will have to follow two -# separate interior branches down the tree. Both should be tested. - -finish_test diff -Nru sqlite3-3.42.0/test/fts2o.test sqlite3-3.44.0-0/test/fts2o.test --- sqlite3-3.42.0/test/fts2o.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2o.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,169 +0,0 @@ -# 2007 June 20 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The -# focus of this script is testing the FTS2 module. -# -# $Id: fts2o.test,v 1.4 2007/07/02 10:16:50 danielk1977 Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is not defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -#--------------------------------------------------------------------- -# These tests, fts2o-1.*, test that ticket #2429 is fixed. -# -db eval { - CREATE VIRTUAL TABLE t1 USING fts2(a, b, c); - INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one four two'); -} -do_test fts2o-1.1 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE c MATCH 'four'; - } -} {1 {one four two}} -do_test fts2o-1.2 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE b MATCH 'four'; - } -} {1 {one four}} -do_test fts2o-1.3 { - execsql { - SELECT rowid, snippet(t1) FROM t1 WHERE a MATCH 'four'; - } -} {1 {one three four}} - -#--------------------------------------------------------------------- -# Test that it is possible to rename an fts2 table. -# -do_test fts2o-2.1 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {t1 t1_content t1_segments t1_segdir} -do_test fts2o-2.2 { - execsql { ALTER TABLE t1 RENAME to fts_t1; } -} {} -do_test fts2o-2.3 { - execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } -} {1 {one three four}} -do_test fts2o-2.4 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir} - -# See what happens when renaming the fts2 table fails. -# -do_test fts2o-2.5 { - catchsql { - CREATE TABLE t1_segdir(a, b, c); - ALTER TABLE fts_t1 RENAME to t1; - } -} {1 {SQL logic error}} -do_test fts2o-2.6 { - execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } -} {1 {one three four}} -do_test fts2o-2.7 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir t1_segdir} - -# See what happens when renaming the fts2 table fails inside a transaction. -# -do_test fts2o-2.8 { - execsql { - BEGIN; - INSERT INTO fts_t1(a, b, c) VALUES('one two three', 'one four', 'one two'); - } -} {} -do_test fts2o-2.9 { - catchsql { - ALTER TABLE fts_t1 RENAME to t1; - } -} {1 {SQL logic error}} -do_test fts2o-2.10 { - execsql { SELECT rowid, snippet(fts_t1) FROM fts_t1 WHERE a MATCH 'four'; } -} {1 {one three four}} -do_test fts2o-2.11 { - execsql { SELECT tbl_name FROM sqlite_master WHERE type = 'table'} -} {fts_t1 fts_t1_content fts_t1_segments fts_t1_segdir t1_segdir} -do_test fts2o-2.12 { - execsql COMMIT - execsql {SELECT a FROM fts_t1} -} {{one three four} {one two three}} -do_test fts2o-2.12 { - execsql { SELECT a, b, c FROM fts_t1 WHERE c MATCH 'four'; } -} {{one three four} {one four} {one four two}} - -#------------------------------------------------------------------- -# Close, delete and reopen the database. The following test should -# be run on an initially empty db. -# -db close -forcedelete test.db test.db-journal -sqlite3 db test.db - -do_test fts2o-3.1 { - execsql { - CREATE VIRTUAL TABLE t1 USING fts2(a, b, c); - INSERT INTO t1(a, b, c) VALUES('one three four', 'one four', 'one two'); - SELECT a, b, c FROM t1 WHERE c MATCH 'two'; - } -} {{one three four} {one four} {one two}} - -# This test was crashing at one point. -# -do_test fts2o-3.2 { - execsql { - SELECT a, b, c FROM t1 WHERE c MATCH 'two'; - CREATE TABLE t3(a, b, c); - SELECT a, b, c FROM t1 WHERE c MATCH 'two'; - } -} {{one three four} {one four} {one two} {one three four} {one four} {one two}} - -#--------------------------------------------------------------------- -# Test that it is possible to rename an fts2 table in an attached -# database. -# -forcedelete test2.db test2.db-journal - -do_test fts2o-3.1 { - execsql { - ATTACH 'test2.db' AS aux; - CREATE VIRTUAL TABLE aux.t1 USING fts2(a, b, c); - INSERT INTO aux.t1(a, b, c) VALUES( - 'neung song sahm', 'neung see', 'neung see song' - ); - } -} {} - -do_test fts2o-3.2 { - execsql { SELECT a, b, c FROM aux.t1 WHERE a MATCH 'song'; } -} {{neung song sahm} {neung see} {neung see song}} - -do_test fts2o-3.3 { - execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; } -} {{one three four} {one four} {one two}} - -do_test fts2o-3.4 { - execsql { ALTER TABLE aux.t1 RENAME TO t2 } -} {} - -do_test fts2o-3.2 { - execsql { SELECT a, b, c FROM t2 WHERE a MATCH 'song'; } -} {{neung song sahm} {neung see} {neung see song}} - -do_test fts2o-3.3 { - execsql { SELECT a, b, c FROM t1 WHERE c MATCH 'two'; } -} {{one three four} {one four} {one two}} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2p.test sqlite3-3.44.0-0/test/fts2p.test --- sqlite3-3.42.0/test/fts2p.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2p.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,357 +0,0 @@ -# 2008 June 26 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file exercises some new testing functions in the FTS2 module, -# and then uses them to do some basic tests that FTS2 is internally -# working as expected. -# -# $Id: fts2p.test,v 1.1 2008/07/22 23:32:28 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is not defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -#************************************************************************* -# Probe to see if support for these functions is compiled in. -# TODO(shess): Change main.mk to do the right thing and remove this test. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'x'); -} - -set s {SELECT dump_terms(t1, 1) FROM t1 LIMIT 1} -set r {1 {unable to use function dump_terms in the requested context}} -if {[catchsql $s]==$r} { - finish_test - return -} - -#************************************************************************* -# Test that the new functions give appropriate errors. -do_test fts2p-0.0 { - catchsql { - SELECT dump_terms(t1, 1) FROM t1 LIMIT 1; - } -} {1 {dump_terms: incorrect arguments}} - -do_test fts2p-0.1 { - catchsql { - SELECT dump_terms(t1, 0, 0, 0) FROM t1 LIMIT 1; - } -} {1 {dump_terms: incorrect arguments}} - -do_test fts2p-0.2 { - catchsql { - SELECT dump_terms(1, t1) FROM t1 LIMIT 1; - } -} {1 {unable to use function dump_terms in the requested context}} - -do_test fts2p-0.3 { - catchsql { - SELECT dump_terms(t1, 16, 16) FROM t1 LIMIT 1; - } -} {1 {dump_terms: segment not found}} - -do_test fts2p-0.4 { - catchsql { - SELECT dump_doclist(t1) FROM t1 LIMIT 1; - } -} {1 {dump_doclist: incorrect arguments}} - -do_test fts2p-0.5 { - catchsql { - SELECT dump_doclist(t1, NULL) FROM t1 LIMIT 1; - } -} {1 {dump_doclist: empty second argument}} - -do_test fts2p-0.6 { - catchsql { - SELECT dump_doclist(t1, '') FROM t1 LIMIT 1; - } -} {1 {dump_doclist: empty second argument}} - -do_test fts2p-0.7 { - catchsql { - SELECT dump_doclist(t1, 'a', 0) FROM t1 LIMIT 1; - } -} {1 {dump_doclist: incorrect arguments}} - -do_test fts2p-0.8 { - catchsql { - SELECT dump_doclist(t1, 'a', 0, 0, 0) FROM t1 LIMIT 1; - } -} {1 {dump_doclist: incorrect arguments}} - -do_test fts2p-0.9 { - catchsql { - SELECT dump_doclist(t1, 'a', 16, 16) FROM t1 LIMIT 1; - } -} {1 {dump_doclist: segment not found}} - -#************************************************************************* -# Utility function to check for the expected terms in the segment -# level/index. _all version does same but for entire index. -proc check_terms {test level index terms} { - # TODO(shess): Figure out why uplevel in do_test can't catch - # $level and $index directly. - set ::level $level - set ::index $index - do_test $test.terms { - execsql { - SELECT dump_terms(t1, $::level, $::index) FROM t1 LIMIT 1; - } - } [list $terms] -} -proc check_terms_all {test terms} { - do_test $test.terms { - execsql { - SELECT dump_terms(t1) FROM t1 LIMIT 1; - } - } [list $terms] -} - -# Utility function to check for the expected doclist for the term in -# segment level/index. _all version does same for entire index. -proc check_doclist {test level index term doclist} { - # TODO(shess): Again, why can't the non-:: versions work? - set ::term $term - set ::level $level - set ::index $index - do_test $test { - execsql { - SELECT dump_doclist(t1, $::term, $::level, $::index) FROM t1 LIMIT 1; - } - } [list $doclist] -} -proc check_doclist_all {test term doclist} { - set ::term $term - do_test $test { - execsql { - SELECT dump_doclist(t1, $::term) FROM t1 LIMIT 1; - } - } [list $doclist] -} - -#************************************************************************* -# Test the segments resulting from straight-forward inserts. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); -} - -# Check for expected segments and expected matches. -do_test fts2p-1.0.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0 0 1 0 2} -do_test fts2p-1.0.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \ - {0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \ - {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}] - -# Check the specifics of the segments constructed. -# Logical view of entire index. -check_terms_all fts2p-1.0.1 {a is test that this was} -check_doclist_all fts2p-1.0.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]} -check_doclist_all fts2p-1.0.1.2 is {[1 0[1]] [3 0[1]]} -check_doclist_all fts2p-1.0.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]} -check_doclist_all fts2p-1.0.1.4 that {[2 0[0]]} -check_doclist_all fts2p-1.0.1.5 this {[1 0[0]] [3 0[0]]} -check_doclist_all fts2p-1.0.1.6 was {[2 0[1]]} - -# Segment 0,0 -check_terms fts2p-1.0.2 0 0 {a is test this} -check_doclist fts2p-1.0.2.1 0 0 a {[1 0[2]]} -check_doclist fts2p-1.0.2.2 0 0 is {[1 0[1]]} -check_doclist fts2p-1.0.2.3 0 0 test {[1 0[3]]} -check_doclist fts2p-1.0.2.4 0 0 this {[1 0[0]]} - -# Segment 0,1 -check_terms fts2p-1.0.3 0 1 {a test that was} -check_doclist fts2p-1.0.3.1 0 1 a {[2 0[2]]} -check_doclist fts2p-1.0.3.2 0 1 test {[2 0[3]]} -check_doclist fts2p-1.0.3.3 0 1 that {[2 0[0]]} -check_doclist fts2p-1.0.3.4 0 1 was {[2 0[1]]} - -# Segment 0,2 -check_terms fts2p-1.0.4 0 2 {a is test this} -check_doclist fts2p-1.0.4.1 0 2 a {[3 0[2]]} -check_doclist fts2p-1.0.4.2 0 2 is {[3 0[1]]} -check_doclist fts2p-1.0.4.3 0 2 test {[3 0[3]]} -check_doclist fts2p-1.0.4.4 0 2 this {[3 0[0]]} - -#************************************************************************* -# Test the segments resulting from inserts followed by a delete. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); - DELETE FROM t1 WHERE rowid = 1; -} - -do_test fts2p-1.1.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0 0 1 0 2 0 3} -do_test fts2p-1.1.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}} - -check_terms_all fts2p-1.1.1 {a is test that this was} -check_doclist_all fts2p-1.1.1.1 a {[2 0[2]] [3 0[2]]} -check_doclist_all fts2p-1.1.1.2 is {[3 0[1]]} -check_doclist_all fts2p-1.1.1.3 test {[2 0[3]] [3 0[3]]} -check_doclist_all fts2p-1.1.1.4 that {[2 0[0]]} -check_doclist_all fts2p-1.1.1.5 this {[3 0[0]]} -check_doclist_all fts2p-1.1.1.6 was {[2 0[1]]} - -check_terms fts2p-1.1.2 0 0 {a is test this} -check_doclist fts2p-1.1.2.1 0 0 a {[1 0[2]]} -check_doclist fts2p-1.1.2.2 0 0 is {[1 0[1]]} -check_doclist fts2p-1.1.2.3 0 0 test {[1 0[3]]} -check_doclist fts2p-1.1.2.4 0 0 this {[1 0[0]]} - -check_terms fts2p-1.1.3 0 1 {a test that was} -check_doclist fts2p-1.1.3.1 0 1 a {[2 0[2]]} -check_doclist fts2p-1.1.3.2 0 1 test {[2 0[3]]} -check_doclist fts2p-1.1.3.3 0 1 that {[2 0[0]]} -check_doclist fts2p-1.1.3.4 0 1 was {[2 0[1]]} - -check_terms fts2p-1.1.4 0 2 {a is test this} -check_doclist fts2p-1.1.4.1 0 2 a {[3 0[2]]} -check_doclist fts2p-1.1.4.2 0 2 is {[3 0[1]]} -check_doclist fts2p-1.1.4.3 0 2 test {[3 0[3]]} -check_doclist fts2p-1.1.4.4 0 2 this {[3 0[0]]} - -check_terms fts2p-1.1.5 0 3 {a is test this} -check_doclist fts2p-1.1.5.1 0 3 a {[1]} -check_doclist fts2p-1.1.5.2 0 3 is {[1]} -check_doclist fts2p-1.1.5.3 0 3 test {[1]} -check_doclist fts2p-1.1.5.4 0 3 this {[1]} - -#************************************************************************* -# Test results when all references to certain tokens are deleted. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); - DELETE FROM t1 WHERE rowid IN (1,3); -} - -# Still 4 segments because 0,3 will contain deletes for rowid 1 and 3. -do_test fts2p-1.2.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0 0 1 0 2 0 3} -do_test fts2p-1.2.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} - -check_terms_all fts2p-1.2.1 {a is test that this was} -check_doclist_all fts2p-1.2.1.1 a {[2 0[2]]} -check_doclist_all fts2p-1.2.1.2 is {} -check_doclist_all fts2p-1.2.1.3 test {[2 0[3]]} -check_doclist_all fts2p-1.2.1.4 that {[2 0[0]]} -check_doclist_all fts2p-1.2.1.5 this {} -check_doclist_all fts2p-1.2.1.6 was {[2 0[1]]} - -check_terms fts2p-1.2.2 0 0 {a is test this} -check_doclist fts2p-1.2.2.1 0 0 a {[1 0[2]]} -check_doclist fts2p-1.2.2.2 0 0 is {[1 0[1]]} -check_doclist fts2p-1.2.2.3 0 0 test {[1 0[3]]} -check_doclist fts2p-1.2.2.4 0 0 this {[1 0[0]]} - -check_terms fts2p-1.2.3 0 1 {a test that was} -check_doclist fts2p-1.2.3.1 0 1 a {[2 0[2]]} -check_doclist fts2p-1.2.3.2 0 1 test {[2 0[3]]} -check_doclist fts2p-1.2.3.3 0 1 that {[2 0[0]]} -check_doclist fts2p-1.2.3.4 0 1 was {[2 0[1]]} - -check_terms fts2p-1.2.4 0 2 {a is test this} -check_doclist fts2p-1.2.4.1 0 2 a {[3 0[2]]} -check_doclist fts2p-1.2.4.2 0 2 is {[3 0[1]]} -check_doclist fts2p-1.2.4.3 0 2 test {[3 0[3]]} -check_doclist fts2p-1.2.4.4 0 2 this {[3 0[0]]} - -check_terms fts2p-1.2.5 0 3 {a is test this} -check_doclist fts2p-1.2.5.1 0 3 a {[1] [3]} -check_doclist fts2p-1.2.5.2 0 3 is {[1] [3]} -check_doclist fts2p-1.2.5.3 0 3 test {[1] [3]} -check_doclist fts2p-1.2.5.4 0 3 this {[1] [3]} - -#************************************************************************* -# Test results when everything is optimized manually. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); - DELETE FROM t1 WHERE rowid IN (1,3); - DROP TABLE IF EXISTS t1old; - ALTER TABLE t1 RENAME TO t1old; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) SELECT rowid, c FROM t1old; - DROP TABLE t1old; -} - -# Should be a single optimal segment with the same logical results. -do_test fts2p-1.3.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0} -do_test fts2p-1.3.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} - -check_terms_all fts2p-1.3.1 {a test that was} -check_doclist_all fts2p-1.3.1.1 a {[2 0[2]]} -check_doclist_all fts2p-1.3.1.2 test {[2 0[3]]} -check_doclist_all fts2p-1.3.1.3 that {[2 0[0]]} -check_doclist_all fts2p-1.3.1.4 was {[2 0[1]]} - -check_terms fts2p-1.3.2 0 0 {a test that was} -check_doclist fts2p-1.3.2.1 0 0 a {[2 0[2]]} -check_doclist fts2p-1.3.2.2 0 0 test {[2 0[3]]} -check_doclist fts2p-1.3.2.3 0 0 that {[2 0[0]]} -check_doclist fts2p-1.3.2.4 0 0 was {[2 0[1]]} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2q.test sqlite3-3.44.0-0/test/fts2q.test --- sqlite3-3.42.0/test/fts2q.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2q.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,346 +0,0 @@ -# 2008 June 26 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing the FTS2 module's optimize() function. -# -# $Id: fts2q.test,v 1.2 2008/07/22 23:49:44 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is not defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -#************************************************************************* -# Probe to see if support for the FTS2 dump_* functions is compiled in. -# TODO(shess): Change main.mk to do the right thing and remove this test. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'x'); -} - -set s {SELECT dump_terms(t1, 1) FROM t1 LIMIT 1} -set r {1 {unable to use function dump_terms in the requested context}} -if {[catchsql $s]==$r} { - finish_test - return -} - -#************************************************************************* -# Utility function to check for the expected terms in the segment -# level/index. _all version does same but for entire index. -proc check_terms {test level index terms} { - # TODO(shess): Figure out why uplevel in do_test can't catch - # $level and $index directly. - set ::level $level - set ::index $index - do_test $test.terms { - execsql { - SELECT dump_terms(t1, $::level, $::index) FROM t1 LIMIT 1; - } - } [list $terms] -} -proc check_terms_all {test terms} { - do_test $test.terms { - execsql { - SELECT dump_terms(t1) FROM t1 LIMIT 1; - } - } [list $terms] -} - -# Utility function to check for the expected doclist for the term in -# segment level/index. _all version does same for entire index. -proc check_doclist {test level index term doclist} { - # TODO(shess): Again, why can't the non-:: versions work? - set ::term $term - set ::level $level - set ::index $index - do_test $test { - execsql { - SELECT dump_doclist(t1, $::term, $::level, $::index) FROM t1 LIMIT 1; - } - } [list $doclist] -} -proc check_doclist_all {test term doclist} { - set ::term $term - do_test $test { - execsql { - SELECT dump_doclist(t1, $::term) FROM t1 LIMIT 1; - } - } [list $doclist] -} - -#************************************************************************* -# Test results when all rows are deleted and one is added back. -# Previously older segments would continue to exist, but now the index -# should be dropped when the table is empty. The results should look -# exactly like we never added the earlier rows in the first place. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); - DELETE FROM t1 WHERE 1=1; -- Delete each row rather than dropping table. - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); -} - -# Should be a single initial segment. -do_test fts2q-1.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0} -do_test fts2q-1.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} {{0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}} - -check_terms_all fts2q-1.1 {a is test this} -check_doclist_all fts2q-1.1.1 a {[1 0[2]]} -check_doclist_all fts2q-1.1.2 is {[1 0[1]]} -check_doclist_all fts2q-1.1.3 test {[1 0[3]]} -check_doclist_all fts2q-1.1.4 this {[1 0[0]]} - -check_terms fts2q-1.2 0 0 {a is test this} -check_doclist fts2q-1.2.1 0 0 a {[1 0[2]]} -check_doclist fts2q-1.2.2 0 0 is {[1 0[1]]} -check_doclist fts2q-1.2.3 0 0 test {[1 0[3]]} -check_doclist fts2q-1.2.4 0 0 this {[1 0[0]]} - -#************************************************************************* -# Test results when everything is optimized manually. -# NOTE(shess): This is a copy of fts2c-1.3. I've pulled a copy here -# because fts2q-2 and fts2q-3 should have identical results. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); - DELETE FROM t1 WHERE rowid IN (1,3); - DROP TABLE IF EXISTS t1old; - ALTER TABLE t1 RENAME TO t1old; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) SELECT rowid, c FROM t1old; - DROP TABLE t1old; -} - -# Should be a single optimal segment with the same logical results. -do_test fts2q-2.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0} -do_test fts2q-2.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} - -check_terms_all fts2q-2.1 {a test that was} -check_doclist_all fts2q-2.1.1 a {[2 0[2]]} -check_doclist_all fts2q-2.1.2 test {[2 0[3]]} -check_doclist_all fts2q-2.1.3 that {[2 0[0]]} -check_doclist_all fts2q-2.1.4 was {[2 0[1]]} - -check_terms fts2q-2.2 0 0 {a test that was} -check_doclist fts2q-2.2.1 0 0 a {[2 0[2]]} -check_doclist fts2q-2.2.2 0 0 test {[2 0[3]]} -check_doclist fts2q-2.2.3 0 0 that {[2 0[0]]} -check_doclist fts2q-2.2.4 0 0 was {[2 0[1]]} - -#************************************************************************* -# Test results when everything is optimized via optimize(). -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); - DELETE FROM t1 WHERE rowid IN (1,3); - SELECT OPTIMIZE(t1) FROM t1 LIMIT 1; -} - -# Should be a single optimal segment with the same logical results. -do_test fts2q-3.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0} -do_test fts2q-3.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} {{0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4}} - -check_terms_all fts2q-3.1 {a test that was} -check_doclist_all fts2q-3.1.1 a {[2 0[2]]} -check_doclist_all fts2q-3.1.2 test {[2 0[3]]} -check_doclist_all fts2q-3.1.3 that {[2 0[0]]} -check_doclist_all fts2q-3.1.4 was {[2 0[1]]} - -check_terms fts2q-3.2 0 0 {a test that was} -check_doclist fts2q-3.2.1 0 0 a {[2 0[2]]} -check_doclist fts2q-3.2.2 0 0 test {[2 0[3]]} -check_doclist fts2q-3.2.3 0 0 that {[2 0[0]]} -check_doclist fts2q-3.2.4 0 0 was {[2 0[1]]} - -#************************************************************************* -# Test optimize() against a table involving segment merges. -# NOTE(shess): Since there's no transaction, each of the INSERT/UPDATE -# statements generates a segment. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); - - UPDATE t1 SET c = 'This is a test one' WHERE rowid = 1; - UPDATE t1 SET c = 'That was a test one' WHERE rowid = 2; - UPDATE t1 SET c = 'This is a test one' WHERE rowid = 3; - - UPDATE t1 SET c = 'This is a test two' WHERE rowid = 1; - UPDATE t1 SET c = 'That was a test two' WHERE rowid = 2; - UPDATE t1 SET c = 'This is a test two' WHERE rowid = 3; - - UPDATE t1 SET c = 'This is a test three' WHERE rowid = 1; - UPDATE t1 SET c = 'That was a test three' WHERE rowid = 2; - UPDATE t1 SET c = 'This is a test three' WHERE rowid = 3; - - UPDATE t1 SET c = 'This is a test four' WHERE rowid = 1; - UPDATE t1 SET c = 'That was a test four' WHERE rowid = 2; - UPDATE t1 SET c = 'This is a test four' WHERE rowid = 3; - - UPDATE t1 SET c = 'This is a test' WHERE rowid = 1; - UPDATE t1 SET c = 'That was a test' WHERE rowid = 2; - UPDATE t1 SET c = 'This is a test' WHERE rowid = 3; -} - -# 2 segments in level 0, 1 in level 1 (18 segments created, 16 -# merged). -do_test fts2q-4.segments { - execsql { - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {0 0 0 1 1 0} - -do_test fts2q-4.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \ - {0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \ - {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}] - -check_terms_all fts2q-4.1 {a four is one test that this three two was} -check_doclist_all fts2q-4.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]} -check_doclist_all fts2q-4.1.2 four {} -check_doclist_all fts2q-4.1.3 is {[1 0[1]] [3 0[1]]} -check_doclist_all fts2q-4.1.4 one {} -check_doclist_all fts2q-4.1.5 test {[1 0[3]] [2 0[3]] [3 0[3]]} -check_doclist_all fts2q-4.1.6 that {[2 0[0]]} -check_doclist_all fts2q-4.1.7 this {[1 0[0]] [3 0[0]]} -check_doclist_all fts2q-4.1.8 three {} -check_doclist_all fts2q-4.1.9 two {} -check_doclist_all fts2q-4.1.10 was {[2 0[1]]} - -check_terms fts2q-4.2 0 0 {a four test that was} -check_doclist fts2q-4.2.1 0 0 a {[2 0[2]]} -check_doclist fts2q-4.2.2 0 0 four {[2]} -check_doclist fts2q-4.2.3 0 0 test {[2 0[3]]} -check_doclist fts2q-4.2.4 0 0 that {[2 0[0]]} -check_doclist fts2q-4.2.5 0 0 was {[2 0[1]]} - -check_terms fts2q-4.3 0 1 {a four is test this} -check_doclist fts2q-4.3.1 0 1 a {[3 0[2]]} -check_doclist fts2q-4.3.2 0 1 four {[3]} -check_doclist fts2q-4.3.3 0 1 is {[3 0[1]]} -check_doclist fts2q-4.3.4 0 1 test {[3 0[3]]} -check_doclist fts2q-4.3.5 0 1 this {[3 0[0]]} - -check_terms fts2q-4.4 1 0 {a four is one test that this three two was} -check_doclist fts2q-4.4.1 1 0 a {[1 0[2]] [2 0[2]] [3 0[2]]} -check_doclist fts2q-4.4.2 1 0 four {[1] [2 0[4]] [3 0[4]]} -check_doclist fts2q-4.4.3 1 0 is {[1 0[1]] [3 0[1]]} -check_doclist fts2q-4.4.4 1 0 one {[1] [2] [3]} -check_doclist fts2q-4.4.5 1 0 test {[1 0[3]] [2 0[3]] [3 0[3]]} -check_doclist fts2q-4.4.6 1 0 that {[2 0[0]]} -check_doclist fts2q-4.4.7 1 0 this {[1 0[0]] [3 0[0]]} -check_doclist fts2q-4.4.8 1 0 three {[1] [2] [3]} -check_doclist fts2q-4.4.9 1 0 two {[1] [2] [3]} -check_doclist fts2q-4.4.10 1 0 was {[2 0[1]]} - -# Optimize should leave the result in the level of the highest-level -# prior segment. -do_test fts2q-4.5 { - execsql { - SELECT OPTIMIZE(t1) FROM t1 LIMIT 1; - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {{Index optimized} 1 0} - -# Identical to fts2q-4.matches. -do_test fts2q-4.5.matches { - execsql { - SELECT OFFSETS(t1) FROM t1 - WHERE t1 MATCH 'this OR that OR was OR a OR is OR test' ORDER BY rowid; - } -} [list {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4} \ - {0 1 0 4 0 2 5 3 0 3 9 1 0 5 11 4} \ - {0 0 0 4 0 4 5 2 0 3 8 1 0 5 10 4}] - -check_terms_all fts2q-4.5.1 {a is test that this was} -check_doclist_all fts2q-4.5.1.1 a {[1 0[2]] [2 0[2]] [3 0[2]]} -check_doclist_all fts2q-4.5.1.2 is {[1 0[1]] [3 0[1]]} -check_doclist_all fts2q-4.5.1.3 test {[1 0[3]] [2 0[3]] [3 0[3]]} -check_doclist_all fts2q-4.5.1.4 that {[2 0[0]]} -check_doclist_all fts2q-4.5.1.5 this {[1 0[0]] [3 0[0]]} -check_doclist_all fts2q-4.5.1.6 was {[2 0[1]]} - -check_terms fts2q-4.5.2 1 0 {a is test that this was} -check_doclist fts2q-4.5.2.1 1 0 a {[1 0[2]] [2 0[2]] [3 0[2]]} -check_doclist fts2q-4.5.2.2 1 0 is {[1 0[1]] [3 0[1]]} -check_doclist fts2q-4.5.2.3 1 0 test {[1 0[3]] [2 0[3]] [3 0[3]]} -check_doclist fts2q-4.5.2.4 1 0 that {[2 0[0]]} -check_doclist fts2q-4.5.2.5 1 0 this {[1 0[0]] [3 0[0]]} -check_doclist fts2q-4.5.2.6 1 0 was {[2 0[1]]} - -# Re-optimizing does nothing. -do_test fts2q-5.0 { - execsql { - SELECT OPTIMIZE(t1) FROM t1 LIMIT 1; - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {{Index already optimal} 1 0} - -# Even if we move things around, still does nothing. -do_test fts2q-5.1 { - execsql { - UPDATE t1_segdir SET level = 2 WHERE level = 1 AND idx = 0; - SELECT OPTIMIZE(t1) FROM t1 LIMIT 1; - SELECT level, idx FROM t1_segdir ORDER BY level, idx; - } -} {{Index already optimal} 2 0} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2r.test sqlite3-3.44.0-0/test/fts2r.test --- sqlite3-3.42.0/test/fts2r.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2r.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,121 +0,0 @@ -# 2008 July 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. -# -#************************************************************************* -# These tests exercise the various types of fts2 cursors. -# -# $Id: fts2r.test,v 1.1 2008/07/29 20:38:18 shess Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is not defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -#************************************************************************* -# Test table scan (QUERY_GENERIC). This kind of query happens for -# queries with no WHERE clause, or for WHERE clauses which cannot be -# satisfied by an index. -db eval { - DROP TABLE IF EXISTS t1; - CREATE VIRTUAL TABLE t1 USING fts2(c); - INSERT INTO t1 (rowid, c) VALUES (1, 'This is a test'); - INSERT INTO t1 (rowid, c) VALUES (2, 'That was a test'); - INSERT INTO t1 (rowid, c) VALUES (3, 'This is a test'); -} - -do_test fts2e-1.1 { - execsql { - SELECT rowid FROM t1 ORDER BY rowid; - } -} {1 2 3} - -do_test fts2e-1.2 { - execsql { - SELECT rowid FROM t1 WHERE c LIKE '%test' ORDER BY rowid; - } -} {1 2 3} - -do_test fts2e-1.3 { - execsql { - SELECT rowid FROM t1 WHERE c LIKE 'That%' ORDER BY rowid; - } -} {2} - -#************************************************************************* -# Test lookup by rowid (QUERY_ROWID). This kind of query happens for -# queries which select by the rowid implicit index. -db eval { - DROP TABLE IF EXISTS t1; - DROP TABLE IF EXISTS t2; - CREATE VIRTUAL TABLE t1 USING fts2(c); - CREATE TABLE t2(id INTEGER PRIMARY KEY AUTOINCREMENT, weight INTEGER UNIQUE); - INSERT INTO t2 VALUES (null, 10); - INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test'); - INSERT INTO t2 VALUES (null, 5); - INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'That was a test'); - INSERT INTO t2 VALUES (null, 20); - INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test'); -} - -# TODO(shess): This actually is doing QUERY_GENERIC? I'd have -# expected QUERY_ROWID in this case, as for a very large table the -# full scan is less efficient. -do_test fts2e-2.1 { - execsql { - SELECT rowid FROM t1 WHERE rowid in (1, 2, 10); - } -} {1 2} - -do_test fts2e-2.2 { - execsql { - SELECT t1.rowid, weight FROM t1, t2 WHERE t2.id = t1.rowid ORDER BY weight; - } -} {2 5 1 10 3 20} - -do_test fts2e-2.3 { - execsql { - SELECT t1.rowid, weight FROM t1, t2 - WHERE t2.weight>5 AND t2.id = t1.rowid ORDER BY weight; - } -} {1 10 3 20} - -#************************************************************************* -# Test lookup by MATCH (QUERY_FULLTEXT). This is the fulltext index. -db eval { - DROP TABLE IF EXISTS t1; - DROP TABLE IF EXISTS t2; - CREATE VIRTUAL TABLE t1 USING fts2(c); - CREATE TABLE t2(id INTEGER PRIMARY KEY AUTOINCREMENT, weight INTEGER UNIQUE); - INSERT INTO t2 VALUES (null, 10); - INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test'); - INSERT INTO t2 VALUES (null, 5); - INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'That was a test'); - INSERT INTO t2 VALUES (null, 20); - INSERT INTO t1 (rowid, c) VALUES (last_insert_rowid(), 'This is a test'); -} - -do_test fts2e-3.1 { - execsql { - SELECT rowid FROM t1 WHERE t1 MATCH 'this' ORDER BY rowid; - } -} {1 3} - -do_test fts2e-3.2 { - execsql { - SELECT t1.rowid, weight FROM t1, t2 - WHERE t1 MATCH 'this' AND t1.rowid = t2.id ORDER BY weight; - } -} {1 10 3 20} - -finish_test diff -Nru sqlite3-3.42.0/test/fts2.test sqlite3-3.44.0-0/test/fts2.test --- sqlite3-3.42.0/test/fts2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,67 +0,0 @@ -# 2008 July 22 -# -# 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 runs all tests. -# -# $Id: fts2.test,v 1.2 2008/07/23 18:17:32 drh Exp $ - -proc lshift {lvar} { - upvar $lvar l - set ret [lindex $l 0] - set l [lrange $l 1 end] - return $ret -} -while {[set arg [lshift argv]] != ""} { - switch -- $arg { - -sharedpagercache { - sqlite3_enable_shared_cache 1 - } - -soak { - set G(issoak) 1 - } - default { - set argv [linsert $argv 0 $arg] - break - } - } -} - -set testdir [file dirname $argv0] -source $testdir/tester.tcl -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - return -} -rename finish_test really_finish_test -proc finish_test {} {} -set G(isquick) 1 - -set EXCLUDE { - fts2.test -} - -# Files to include in the test. If this list is empty then everything -# that is not in the EXCLUDE list is run. -# -set INCLUDE { -} - -foreach testfile [lsort -dictionary [glob $testdir/fts2*.test]] { - set tail [file tail $testfile] - if {[lsearch -exact $EXCLUDE $tail]>=0} continue - if {[llength $INCLUDE]>0 && [lsearch -exact $INCLUDE $tail]<0} continue - source $testfile - catch {db close} - if {$sqlite_open_file_count>0} { - puts "$tail did not close all files: $sqlite_open_file_count" - fail_test $tail - set sqlite_open_file_count 0 - } -} - -set sqlite_open_file_count 0 -really_finish_test diff -Nru sqlite3-3.42.0/test/fts2token.test sqlite3-3.44.0-0/test/fts2token.test --- sqlite3-3.42.0/test/fts2token.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts2token.test 1970-01-01 00:00:00.000000000 +0000 @@ -1,174 +0,0 @@ -# 2007 June 21 -# -# The author disclaims copyright to this source code. In place of -# a legal notice, here is a blessing: -# -# May you do good and not evil. -# May you find forgiveness for yourself and forgive others. -# May you share freely, never taking more than you give. -# -#************************************************************************* -# This file implements regression tests for SQLite library. The focus -# of this script is testing the pluggable tokeniser feature of the -# FTS2 module. -# -# $Id: fts2token.test,v 1.3 2007/06/25 12:05:40 danielk1977 Exp $ -# - -set testdir [file dirname $argv0] -source $testdir/tester.tcl - -# If SQLITE_ENABLE_FTS2 is defined, omit this file. -ifcapable !fts2 { - finish_test - return -} - -proc escape_string {str} { - set out "" - foreach char [split $str ""] { - scan $char %c i - if {$i<=127} { - append out $char - } else { - append out [format {\x%.4x} $i] - } - } - set out -} - -#-------------------------------------------------------------------------- -# Test cases fts2token-1.* are the warm-body test for the SQL scalar -# function fts2_tokenizer(). The procedure is as follows: -# -# 1: Verify that there is no such fts2 tokenizer as 'blah'. -# -# 2: Query for the built-in tokenizer 'simple'. Insert a copy of the -# retrieved value as tokenizer 'blah'. -# -# 3: Test that the value returned for tokenizer 'blah' is now the -# same as that retrieved for 'simple'. -# -# 4: Test that it is now possible to create an fts2 table using -# tokenizer 'blah' (it was not possible in step 1). -# -# 5: Test that the table created to use tokenizer 'blah' is usable. -# -do_test fts2token-1.1 { - catchsql { - CREATE VIRTUAL TABLE t1 USING fts2(content, tokenize blah); - } -} {1 {unknown tokenizer: blah}} -do_test fts2token-1.2 { - execsql { - SELECT fts2_tokenizer('blah', fts2_tokenizer('simple')) IS NULL; - } -} {0} -do_test fts2token-1.3 { - execsql { - SELECT fts2_tokenizer('blah') == fts2_tokenizer('simple'); - } -} {1} -do_test fts2token-1.4 { - catchsql { - CREATE VIRTUAL TABLE t1 USING fts2(content, tokenize blah); - } -} {0 {}} -do_test fts2token-1.5 { - execsql { - INSERT INTO t1(content) VALUES('There was movement at the station'); - INSERT INTO t1(content) VALUES('For the word has passed around'); - INSERT INTO t1(content) VALUES('That the colt from ol regret had got away'); - SELECT content FROM t1 WHERE content MATCH 'movement' - } -} {{There was movement at the station}} - -#-------------------------------------------------------------------------- -# Test cases fts2token-2.* test error cases in the scalar function based -# API for getting and setting tokenizers. -# -do_test fts2token-2.1 { - catchsql { - SELECT fts2_tokenizer('nosuchtokenizer'); - } -} {1 {unknown tokenizer: nosuchtokenizer}} - -#-------------------------------------------------------------------------- -# Test cases fts2token-3.* test the three built-in tokenizers with a -# simple input string via the built-in test function. This is as much -# to test the test function as the tokenizer implementations. -# -do_test fts2token-3.1 { - execsql { - SELECT fts2_tokenizer_test('simple', 'I don''t see how'); - } -} {{0 i I 1 don don 2 t t 3 see see 4 how how}} -do_test fts2token-3.2 { - execsql { - SELECT fts2_tokenizer_test('porter', 'I don''t see how'); - } -} {{0 i I 1 don don 2 t t 3 see see 4 how how}} -ifcapable icu { - do_test fts2token-3.3 { - execsql { - SELECT fts2_tokenizer_test('icu', 'I don''t see how'); - } - } {{0 i I 1 don't don't 2 see see 3 how how}} -} - -#-------------------------------------------------------------------------- -# Test cases fts2token-4.* test the ICU tokenizer. In practice, this -# tokenizer only has two modes - "thai" and "everybody else". Some other -# Asian languages (Lao, Khmer etc.) require the same special treatment as -# Thai, but ICU doesn't support them yet. -# -ifcapable icu { - - proc do_icu_test {name locale input output} { - set ::out [db eval { SELECT fts2_tokenizer_test('icu', $locale, $input) }] - do_test $name { - lindex $::out 0 - } $output - } - - do_icu_test fts2token-4.1 en_US {} {} - do_icu_test fts2token-4.2 en_US {Test cases fts2} [list \ - 0 test Test 1 cases cases 2 fts2 fts2 - ] - - # The following test shows that ICU is smart enough to recognise - # Thai chararacters, even when the locale is set to English/United - # States. - # - set input "\u0e2d\u0e30\u0e44\u0e23\u0e19\u0e30\u0e04\u0e23\u0e31\u0e1a" - set output "0 \u0e2d\u0e30\u0e44\u0e23 \u0e2d\u0e30\u0e44\u0e23 " - append output "1 \u0e19\u0e30 \u0e19\u0e30 " - append output "2 \u0e04\u0e23\u0e31\u0e1a \u0e04\u0e23\u0e31\u0e1a" - - do_icu_test fts2token-4.3 th_TH $input $output - do_icu_test fts2token-4.4 en_US $input $output - - # ICU handles an unknown locale by falling back to the default. - # So this is not an error. - do_icu_test fts2token-4.5 MiddleOfTheOcean $input $output - - set longtoken "AReallyReallyLongTokenOneThatWillSurelyRequire" - append longtoken "AReallocInTheIcuTokenizerCode" - - set input "short tokens then " - append input $longtoken - set output "0 short short " - append output "1 tokens tokens " - append output "2 then then " - append output "3 [string tolower $longtoken] $longtoken" - - do_icu_test fts2token-4.6 MiddleOfTheOcean $input $output - do_icu_test fts2token-4.7 th_TH $input $output - do_icu_test fts2token-4.8 en_US $input $output -} - -do_test fts2token-internal { - execsql { SELECT fts2_tokenizer_internal_test() } -} {ok} - -finish_test diff -Nru sqlite3-3.42.0/test/fts3conf.test sqlite3-3.44.0-0/test/fts3conf.test --- sqlite3-3.42.0/test/fts3conf.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts3conf.test 2023-11-04 14:23:58.000000000 +0000 @@ -198,7 +198,8 @@ do_execsql_test 4.1.3 { SELECT * FROM t0 WHERE t0 MATCH 'abc'; INSERT INTO t0(t0) VALUES('integrity-check'); -} {} + PRAGMA integrity_check; +} {ok} do_execsql_test 4.2.1 { CREATE VIRTUAL TABLE t01 USING fts4; @@ -211,7 +212,8 @@ do_execsql_test 4.2.2 { SELECT * FROM t01 WHERE t01 MATCH 'b'; INSERT INTO t01(t01) VALUES('integrity-check'); -} {} + PRAGMA integrity_check; +} {ok} do_execsql_test 4.3.1 { CREATE VIRTUAL TABLE t02 USING fts4; diff -Nru sqlite3-3.42.0/test/fts3corrupt4.test sqlite3-3.44.0-0/test/fts3corrupt4.test --- sqlite3-3.42.0/test/fts3corrupt4.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts3corrupt4.test 2023-11-04 14:23:58.000000000 +0000 @@ -2595,17 +2595,13 @@ UPDATE t1 SET b=quote(zeroblob(200)) WHERE a MATCH 'thread*'; } -do_catchsql_test 17.2 { - DROP TABLE IF EXISTS t1; -} {1 {SQL logic error}} - -do_execsql_test 17.3 { +do_execsql_test 17.2 { INSERT INTO t1(t1) VALUES('optimize'); } -do_catchsql_test 17.4 { +do_catchsql_test 17.3 { DROP TABLE IF EXISTS t1; -} {1 {SQL logic error}} +} {0 {}} #------------------------------------------------------------------------- reset_db @@ -5812,6 +5808,9 @@ do_catchsql_test 35.1 { INSERT INTO f(f) VALUES ('integrity-check'); } {1 {database disk image is malformed}} +do_execsql_test 35.2 { + PRAGMA integrity_check; +} {{malformed inverted index for FTS3 table main.f}} reset_db do_catchsql_test 36.0 { diff -Nru sqlite3-3.42.0/test/fts3fault3.test sqlite3-3.44.0-0/test/fts3fault3.test --- sqlite3-3.42.0/test/fts3fault3.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts3fault3.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,54 @@ +# 2023 October 23 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +set ::testprefix fts3fault + +# If SQLITE_ENABLE_FTS3 is not defined, omit this file. +ifcapable !fts3 { finish_test ; return } + +set ::TMPDBERROR [list 1 \ + {unable to open a temporary database file for storing temporary tables} +] + + +# Test error handling in an "ALTER TABLE ... RENAME TO" statement on an +# FTS3 table. Specifically, test renaming the table within a transaction +# after it has been written to. +# +do_execsql_test 1.0 { + CREATE VIRTUAL TABLE t1 USING fts3(a); + INSERT INTO t1 VALUES('test renaming the table'); + INSERT INTO t1 VALUES(' after it has been written'); + INSERT INTO t1 VALUES(' actually other stuff instead'); +} +faultsim_save_and_close +do_faultsim_test 1 -faults oom* -prep { + faultsim_restore_and_reopen + execsql { + BEGIN; + DELETE FROM t1 WHERE rowid=2; + } +} -body { + execsql { + DELETE FROM t1; + } +} -test { + catchsql { COMMIT } + faultsim_integrity_check + faultsim_test_result {0 {}} +} + + +finish_test diff -Nru sqlite3-3.42.0/test/fts3fuzz001.test sqlite3-3.44.0-0/test/fts3fuzz001.test --- sqlite3-3.42.0/test/fts3fuzz001.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts3fuzz001.test 2023-11-04 14:23:58.000000000 +0000 @@ -13,6 +13,7 @@ set testdir [file dirname $argv0] source $testdir/tester.tcl +set testprefix fts3fuzz001 ifcapable !deserialize||!fts3 { finish_test @@ -110,5 +111,31 @@ } } {1 {database disk image is malformed}} +#------------------------------------------------------------------------- +reset_db +do_execsql_test 200 { + CREATE VIRTUAL TABLE x1 USING fts3(x); + + INSERT INTO x1 VALUES('braes brag bragged bragger bragging'); + INSERT INTO x1 VALUES('brags braid braided braiding braids'); + INSERT INTO x1 VALUES('brain brainchild brained braining brains'); + INSERT INTO x1 VALUES('brainstem brainstems brainstorm brainstorms'); + INSERT INTO x1(x1) VALUES('nodesize=24'); +} + +do_execsql_test 210 { + PRAGMA integrity_check; +} {ok} + +do_execsql_test 220 { + INSERT INTO x1(x1) VALUES('merge=10,2') +} + +do_execsql_test 220 { + PRAGMA integrity_check; +} {ok} + + + finish_test diff -Nru sqlite3-3.42.0/test/fts4check.test sqlite3-3.44.0-0/test/fts4check.test --- sqlite3-3.42.0/test/fts4check.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts4check.test 2023-11-04 14:23:58.000000000 +0000 @@ -71,7 +71,10 @@ do_catchsql_test 1.2.2.$tn { INSERT INTO t1 (t1) VALUES('integrity-check') } {1 {database disk image is malformed}} - do_execsql_test 1.2.3.$tn "ROLLBACK" + do_execsql_test 1.2.3.$tn { + PRAGMA integrity_check; + } {{malformed inverted index for FTS4 table main.t1}} + do_execsql_test 1.2.4.$tn "ROLLBACK" } do_test 1.3 { fts_integrity db t1 } {ok} @@ -106,7 +109,10 @@ do_catchsql_test 2.2.2.$tn { INSERT INTO t2 (t2) VALUES('integrity-check') } {1 {database disk image is malformed}} - do_execsql_test 2.2.3.$tn "ROLLBACK" + do_test 2.2.3.$tn { + db eval {PRAGMA integrity_check(t2);} + } {{malformed inverted index for FTS4 table main.t2}} + do_execsql_test 2.2.4.$tn "ROLLBACK" } diff -Nru sqlite3-3.42.0/test/fts4intck1.test sqlite3-3.44.0-0/test/fts4intck1.test --- sqlite3-3.42.0/test/fts4intck1.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts4intck1.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,58 @@ +# 2023-10-23 +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# +# Test PRAGMA integrity_check against and FTS3/FTS4 table. +# + + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +ifcapable !fts3 { finish_test ; return } + +set ::testprefix fts4intck1 + +proc slang {in} { + return [string map {th d e eh} $in] +} + +db function slang -deterministic -innocuous slang +do_execsql_test 1.0 { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT, c TEXT AS (slang(b))); + INSERT INTO t1(b) VALUES('the quick fox jumps over the lazy brown dog'); + SELECT c FROM t1; +} {{deh quick fox jumps ovehr deh lazy brown dog}} + +do_execsql_test 1.1 { + CREATE VIRTUAL TABLE t2 USING fts4(content="t1", c); + INSERT INTO t2(t2) VALUES('rebuild'); + SELECT docid FROM t2 WHERE t2 MATCH 'deh'; +} {1} + +do_execsql_test 1.2 { + PRAGMA integrity_check(t2); +} {ok} + +db close +sqlite3 db test.db +do_execsql_test 2.1 { + PRAGMA integrity_check(t2); +} {{unable to validate the inverted index for FTS4 table main.t2: SQL logic error}} + +db function slang -deterministic -innocuous slang +do_execsql_test 2.2 { + PRAGMA integrity_check(t2); +} {ok} + +proc slang {in} {return $in} +do_execsql_test 2.3 { + PRAGMA integrity_check(t2); +} {{malformed inverted index for FTS4 table main.t2}} + + +finish_test diff -Nru sqlite3-3.42.0/test/fts4langid.test sqlite3-3.44.0-0/test/fts4langid.test --- sqlite3-3.42.0/test/fts4langid.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts4langid.test 2023-11-04 14:23:58.000000000 +0000 @@ -499,7 +499,8 @@ } do_execsql_test 6.1 { INSERT INTO vt0(vt0) VALUES('integrity-check'); -} + PRAGMA integrity_check; +} {ok} do_execsql_test 6.2 { COMMIT; INSERT INTO vt0(vt0) VALUES('integrity-check'); diff -Nru sqlite3-3.42.0/test/fts4merge.test sqlite3-3.44.0-0/test/fts4merge.test --- sqlite3-3.42.0/test/fts4merge.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fts4merge.test 2023-11-04 14:23:58.000000000 +0000 @@ -37,7 +37,7 @@ do_test 1.0 { fts3_build_db_1 -module $mod 1004 } {} do_test 1.1 { fts3_integrity_check t1 } {ok} do_execsql_test 1.1 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level } { 0 {0 1 2 3 4 5 6 7 8 9 10 11} 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13} @@ -67,7 +67,7 @@ } do_execsql_test 1.5 { - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level } { 3 0 } @@ -103,7 +103,7 @@ do_test 3.1 { fts3_integrity_check t2 } {ok} do_execsql_test 3.2 { - SELECT level, group_concat(idx, ' ') FROM t2_segdir GROUP BY level + SELECT level, string_agg(idx, ' ') FROM t2_segdir GROUP BY level } { 0 {0 1 2 3 4 5 6} 1 {0 1 2 3 4} @@ -132,7 +132,7 @@ foreach x {a c b d e f g h i j k l m n o p} { execsql "INSERT INTO t4 VALUES('[string repeat $x 600]')" } - execsql {SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level} + execsql {SELECT level, string_agg(idx, ' ') FROM t4_segdir GROUP BY level} } {0 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15}} foreach {tn expect} { @@ -160,7 +160,7 @@ do_execsql_test 4.4.2 { DELETE FROM t4_stat WHERE rowid=1; INSERT INTO t4(t4) VALUES('merge=1,12'); - SELECT level, group_concat(idx, ' ') FROM t4_segdir GROUP BY level; + SELECT level, string_agg(idx, ' ') FROM t4_segdir GROUP BY level; } "0 {0 1 2 3 4 5} 1 0" @@ -194,7 +194,7 @@ do_execsql_test 5.3 { INSERT INTO t1(t1) VALUES('merge=1,5'); INSERT INTO t1(t1) VALUES('merge=1,5'); - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level; } { 1 {0 1 2 3 4 5 6 7 8 9 10 11 12 13 14} 2 {0 1 2 3} @@ -249,7 +249,7 @@ do_execsql_test 5.11 { INSERT INTO t1(t1) VALUES('merge=1,6'); - SELECT level, group_concat(idx, ' ') FROM t1_segdir GROUP BY level; + SELECT level, string_agg(idx, ' ') FROM t1_segdir GROUP BY level; SELECT quote(value) from t1_stat WHERE rowid=1; } { 1 {0 1} 2 0 3 0 X'010E' diff -Nru sqlite3-3.42.0/test/func9.test sqlite3-3.44.0-0/test/func9.test --- sqlite3-3.42.0/test/func9.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/func9.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,40 @@ +# 2023-08-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. +# +#************************************************************************* +# +# Test cases for SQL newer functions +# +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +do_execsql_test func9-100 { + SELECT concat('abc',123,null,'xyz'); +} {abc123xyz} +do_execsql_test func9-110 { + SELECT typeof(concat(null)); +} {text} +do_catchsql_test func9-120 { + SELECT concat(); +} {1 {wrong number of arguments to function concat()}} +do_execsql_test func9-130 { + SELECT concat_ws(',',1,2,3,4,5,6,7,8,NULL,9,10,11,12); +} {1,2,3,4,5,6,7,8,9,10,11,12} +do_execsql_test func9-140 { + SELECT concat_ws(NULL,1,2,3,4,5,6,7,8,NULL,9,10,11,12); +} {{}} +do_catchsql_test func9-150 { + SELECT concat_ws(); +} {1 {wrong number of arguments to function concat_ws()}} +do_catchsql_test func9-160 { + SELECT concat_ws(','); +} {1 {wrong number of arguments to function concat_ws()}} + + +finish_test diff -Nru sqlite3-3.42.0/test/func.test sqlite3-3.44.0-0/test/func.test --- sqlite3-3.42.0/test/func.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/func.test 2023-11-04 14:23:58.000000000 +0000 @@ -42,6 +42,10 @@ do_test func-1.0 { execsql {SELECT length(t1) FROM tbl1 ORDER BY t1} } {4 2 7 8 4} +set isutf16 [regexp 16 [db one {PRAGMA encoding}]] +do_execsql_test func-1.0b { + SELECT octet_length(t1) FROM tbl1 ORDER BY t1; +} [expr {$isutf16?"8 4 14 16 8":"4 2 7 8 4"}] do_test func-1.1 { set r [catch {execsql {SELECT length(*) FROM tbl1 ORDER BY t1}} msg] lappend r $msg @@ -57,9 +61,29 @@ do_test func-1.4 { execsql {SELECT coalesce(length(a),-1) FROM t2} } {1 -1 3 -1 5} +do_execsql_test func-1.5 { + SELECT octet_length(12345); +} [expr {(1+($isutf16!=0))*5}] +db null NULL +do_execsql_test func-1.6 { + SELECT octet_length(NULL); +} {NULL} +do_execsql_test func-1.7 { + SELECT octet_length(7.5); +} [expr {(1+($isutf16!=0))*3}] +do_execsql_test func-1.8 { + SELECT octet_length(x'30313233'); +} {4} +do_execsql_test func-1.9 { + WITH c(x) AS (VALUES(char(350,351,352,353,354))) + SELECT length(x), octet_length(x) FROM c; +} {5 10} + + # Check out the substr() function # +db null {} do_test func-2.0 { execsql {SELECT substr(t1,1,2) FROM tbl1 ORDER BY t1} } {fr is pr so th} @@ -839,30 +863,13 @@ } } integer ifcapable floatingpoint { - do_test func-18.12 { - catchsql { - INSERT INTO t6 VALUES(1<<62); - SELECT sum(x) - ((1<<62)*2.0+1) from t6; - } - } {1 {integer overflow}} - do_test func-18.13 { - execsql { - SELECT total(x) - ((1<<62)*2.0+1) FROM t6 - } - } 0.0 -} -ifcapable !floatingpoint { - do_test func-18.12 { - catchsql { - INSERT INTO t6 VALUES(1<<62); - SELECT sum(x) - ((1<<62)*2+1) from t6; - } + do_catchsql_test func-18.12 { + INSERT INTO t6 VALUES(1<<62); + SELECT sum(x) - ((1<<62)*2.0+1) from t6; } {1 {integer overflow}} - do_test func-18.13 { - execsql { - SELECT total(x) - ((1<<62)*2+1) FROM t6 - } - } 0.0 + do_catchsql_test func-18.13 { + SELECT total(x) - ((1<<62)*2.0+1) FROM t6 + } {0 0.0} } if {[working_64bit_int]} { do_test func-18.14 { @@ -1129,18 +1136,18 @@ } {3} } -# The group_concat() function. +# The group_concat() and string_agg() functions. # do_test func-24.1 { execsql { - SELECT group_concat(t1) FROM tbl1 + SELECT group_concat(t1), string_agg(t1,',') FROM tbl1 } -} {this,program,is,free,software} +} {this,program,is,free,software this,program,is,free,software} do_test func-24.2 { execsql { - SELECT group_concat(t1,' ') FROM tbl1 + SELECT group_concat(t1,' '), string_agg(t1,' ') FROM tbl1 } -} {{this program is free software}} +} {{this program is free software} {this program is free software}} do_test func-24.3 { execsql { SELECT group_concat(t1,' ' || rowid || ' ') FROM tbl1 @@ -1153,9 +1160,9 @@ } {{}} do_test func-24.5 { execsql { - SELECT group_concat(t1,NULL) FROM tbl1 + SELECT group_concat(t1,NULL), string_agg(t1,NULL) FROM tbl1 } -} {thisprogramisfreesoftware} +} {thisprogramisfreesoftware thisprogramisfreesoftware} do_test func-24.6 { execsql { SELECT 'BEGIN-'||group_concat(t1) FROM tbl1 @@ -1520,6 +1527,30 @@ SELECT 123 ->> 456 } {123->>456} +# 2023-06-26 +# Enhanced precision of SUM(). +# +reset_db +do_catchsql_test func-37.100 { + WITH c(x) AS (VALUES(9223372036854775807),(9223372036854775807), + (123),(-9223372036854775807),(-9223372036854775807)) + SELECT sum(x) FROM c; +} {1 {integer overflow}} +do_catchsql_test func-37.110 { + WITH c(x) AS (VALUES(9223372036854775807),(1)) + SELECT sum(x) FROM c; +} {1 {integer overflow}} +do_catchsql_test func-37.120 { + WITH c(x) AS (VALUES(9223372036854775807),(10000),(-10010)) + SELECT sum(x) FROM c; +} {1 {integer overflow}} +# 2023-08-28 forum post https://sqlite.org/forum/forumpost/1c06ddcacc86032a +# Incorrect handling of infinity by SUM(). +# +do_execsql_test func-38.100 { + WITH t1(x) AS (VALUES(9e+999)) SELECT sum(x), avg(x), total(x) FROM t1; + WITH t1(x) AS (VALUES(-9e+999)) SELECT sum(x), avg(x), total(x) FROM t1; +} {Inf Inf Inf -Inf -Inf -Inf} finish_test diff -Nru sqlite3-3.42.0/test/fuzzcheck.c sqlite3-3.44.0-0/test/fuzzcheck.c --- sqlite3-3.42.0/test/fuzzcheck.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/fuzzcheck.c 2023-11-04 14:23:58.000000000 +0000 @@ -1130,6 +1130,44 @@ return sqlite3_finalize(pStmt); } +/* Mappings into dbconfig settings for bits taken from bytes 72..75 of +** the input database. +** +** This should be the same as in dbsqlfuzz.c. Make sure those codes stay +** in sync. +*/ +static const struct { + unsigned int mask; + int iSetting; + char *zName; +} aDbConfigSettings[] = { + { 0x0001, SQLITE_DBCONFIG_ENABLE_FKEY, "enable_fkey" }, + { 0x0002, SQLITE_DBCONFIG_ENABLE_TRIGGER, "enable_trigger" }, + { 0x0004, SQLITE_DBCONFIG_ENABLE_VIEW, "enable_view" }, + { 0x0008, SQLITE_DBCONFIG_ENABLE_QPSG, "enable_qpsg" }, + { 0x0010, SQLITE_DBCONFIG_TRIGGER_EQP, "trigger_eqp" }, + { 0x0020, SQLITE_DBCONFIG_DEFENSIVE, "defensive" }, + { 0x0040, SQLITE_DBCONFIG_WRITABLE_SCHEMA, "writable_schema" }, + { 0x0080, SQLITE_DBCONFIG_LEGACY_ALTER_TABLE, "legacy_alter_table" }, + { 0x0100, SQLITE_DBCONFIG_STMT_SCANSTATUS, "stmt_scanstatus" }, + { 0x0200, SQLITE_DBCONFIG_REVERSE_SCANORDER, "reverse_scanorder" }, +#ifdef SQLITE_DBCONFIG_STRICT_AGGREGATE + { 0x0400, SQLITE_DBCONFIG_STRICT_AGGREGATE, "strict_aggregate" }, +#endif + { 0x0800, SQLITE_DBCONFIG_DQS_DML, "dqs_dml" }, + { 0x1000, SQLITE_DBCONFIG_DQS_DDL, "dqs_ddl" }, + { 0x2000, SQLITE_DBCONFIG_TRUSTED_SCHEMA, "trusted_schema" }, +}; + +/* Toggle a dbconfig setting +*/ +static void toggleDbConfig(sqlite3 *db, int iSetting){ + int v = 0; + sqlite3_db_config(db, iSetting, -1, &v); + v = !v; + sqlite3_db_config(db, iSetting, v, 0); +} + /* Invoke this routine to run a single test case */ int runCombinedDbSqlInput( const uint8_t *aData, /* Combined DB+SQL content */ @@ -1148,6 +1186,9 @@ int nSql; /* Bytes of SQL text */ FuzzCtx cx; /* Fuzzing context */ unsigned int btsFlags = 0; /* Parsing flags */ + unsigned int dbFlags = 0; /* Flag values from db offset 72..75 */ + unsigned int dbOpt = 0; /* Flag values from db offset 76..79 */ + if( nByte<10 ) return 0; if( sqlite3_initialize() ) return 0; @@ -1163,6 +1204,14 @@ memset(&cx, 0, sizeof(cx)); iSql = decodeDatabase((unsigned char*)aData, (int)nByte, &aDb, &nDb); if( iSql<0 ) return 0; + if( nDb>=75 ){ + dbFlags = ((unsigned int)aDb[72]<<24) + ((unsigned int)aDb[73]<<16) + + ((unsigned int)aDb[74]<<8) + (unsigned int)aDb[75]; + } + if( nDb>=79 ){ + dbOpt = ((unsigned int)aDb[76]<<24) + ((unsigned int)aDb[77]<<16) + + ((unsigned int)aDb[78]<<8) + (unsigned int)aDb[79]; + } nSql = (int)(nByte - iSql); if( bScript ){ char zName[100]; @@ -1183,7 +1232,12 @@ sqlite3_free(aDb); return 1; } - sqlite3_db_config(cx.db, SQLITE_DBCONFIG_STMT_SCANSTATUS, 1, 0); + sqlite3_test_control(SQLITE_TESTCTRL_OPTIMIZATIONS, cx.db, dbOpt); + for(i=0; i>$label FROM data1 WHERE x->>$label IS NOT NULL; + +CREATE TEMP TABLE t2(x JSON TEXT); +WITH RECURSIVE + c(x) AS (VALUES(1) UNION ALL SELECT x+1 FROM c WHERE x<25000), + array1(y) AS ( + SELECT json_group_array( + json_object('x',x,'y',random(),'z',hex(randomblob(50))) + ) + FROM c + ), + c2(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c2 WHERE n<5) +INSERT INTO t2(x) + SELECT json_object('a',n,'b',n*2,'c',y,'d',3,'e',5,'f',6) FROM array1, c2; +CREATE INDEX t2x1 ON t2(x->>'a'); +CREATE INDEX t2x2 ON t2(x->>'b'); +CREATE INDEX t2x3 ON t2(x->>'e'); +CREATE INDEX t2x4 ON t2(x->>'f'); +UPDATE t2 SET x=json_replace(x,'$.f',(x->>'f')+1); +UPDATE t2 SET x=json_set(x,'$.e',(x->>'f')-1); +UPDATE t2 SET x=json_remove(x,'$.d'); diff -Nru sqlite3-3.42.0/test/json/README.md sqlite3-3.44.0-0/test/json/README.md --- sqlite3-3.42.0/test/json/README.md 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/json/README.md 2023-11-04 14:23:58.000000000 +0000 @@ -1,5 +1,6 @@ The files in this subdirectory are used to help measure the performance -of the SQLite JSON parser. +of the SQLite JSON functions, especially in relation to handling large +JSON inputs. # 1.0 Prerequisites @@ -7,6 +8,8 @@ 2. Fossil + 3. tclsh + # 2.0 Setup 1. Run: "`tclsh json-generator.tcl | sqlite3 json100mb.db`" to create @@ -14,14 +17,27 @@ file lands in the directory from which you will run tests, not in the test/json subdirectory of the source tree. - 2. Build the baseline sqlite3.c file. ("`make sqlite3.c`") + 2. Build the baseline sqlite3.c file with sqlite3.h and shell.c. + ("`CFLAGS='-Os -g' make -e clean sqlite3.c`") - 3. Run "`sh json-speed-check-1.sh trunk`". This creates the baseline + 3. Run "`sh json-speed-check.sh trunk`". This creates the baseline profile in "jout-trunk.txt". # 3.0 Testing - 1. Build the sqlite3.c to be tested. + 1. Build the sqlite3.c (with sqlite3.h and shell.c) to be tested. - 2. Run "`sh json-speed-check-1.sh x1`". The profile output will appear + 2. Run "`sh json-speed-check.sh x1`". The profile output will appear in jout-x1.txt. Substitute any label you want in place of "x1". + + 3. Run the script shown below in the CLI. + Divide 2500 by the real elapse time from this test + to get an estimate for number of MB/s that the JSON parser is + able to process. + +> ~~~~ +.open json100mb.db +.timer on +WITH RECURSIVE c(n) AS (VALUES(1) UNION ALL SELECT n+1 FROM c WHERE n<25) +SELECT sum(json_valid(x)) FROM c, data1; +~~~~ diff -Nru sqlite3-3.42.0/test/json101.test sqlite3-3.44.0-0/test/json101.test --- sqlite3-3.42.0/test/json101.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/json101.test 2023-11-04 14:23:58.000000000 +0000 @@ -119,17 +119,20 @@ do_execsql_test json101-4.8 { SELECT x FROM j1 WHERE json_insert(x)<>x; } {} +do_execsql_test json101-4.9 { + SELECT json_insert('{"a":1}','$.b',CAST(x'0000' AS text)); +} {{{"a":1,"b":"\u0000\u0000"}}} # json_extract(JSON,'$') will return objects and arrays without change. # -do_execsql_test json-4.10 { +do_execsql_test json101-4.10 { SELECT count(*) FROM j1 WHERE json_type(x) IN ('object','array'); SELECT x FROM j1 WHERE json_extract(x,'$')<>x AND json_type(x) IN ('object','array'); } {4} -do_execsql_test json-5.1 { +do_execsql_test json101-5.1 { CREATE TABLE j2(id INTEGER PRIMARY KEY, json, src); INSERT INTO j2(id,json,src) VALUES(1,'{ @@ -257,7 +260,7 @@ SELECT count(*) FROM j2; } {3} -do_execsql_test json-5.2 { +do_execsql_test json101-5.2 { SELECT id, json_valid(json), json_type(json), '|' FROM j2 ORDER BY id; } {1 1 object | 2 1 object | 3 1 array |} @@ -268,13 +271,13 @@ # fullkey is always the same as path+key (with appropriate formatting) # -do_execsql_test json-5.3 { +do_execsql_test json101-5.3 { SELECT j2.rowid, jx.rowid, fullkey, path, key FROM j2, json_tree(j2.json) AS jx WHERE fullkey!=(path || CASE WHEN typeof(key)=='integer' THEN '['||key||']' ELSE '.'||key END); } {} -do_execsql_test json-5.4 { +do_execsql_test json101-5.4 { SELECT j2.rowid, jx.rowid, fullkey, path, key FROM j2, json_each(j2.json) AS jx WHERE fullkey!=(path || CASE WHEN typeof(key)=='integer' THEN '['||key||']' @@ -285,58 +288,58 @@ # Verify that the json_each.json and json_tree.json output is always the # same as input. # -do_execsql_test json-5.5 { +do_execsql_test json101-5.5 { SELECT j2.rowid, jx.rowid, fullkey, path, key FROM j2, json_each(j2.json) AS jx WHERE jx.json<>j2.json; } {} -do_execsql_test json-5.6 { +do_execsql_test json101-5.6 { SELECT j2.rowid, jx.rowid, fullkey, path, key FROM j2, json_tree(j2.json) AS jx WHERE jx.json<>j2.json; } {} -do_execsql_test json-5.7 { +do_execsql_test json101-5.7 { SELECT j2.rowid, jx.rowid, fullkey, path, key FROM j2, json_each(j2.json) AS jx WHERE jx.value<>jx.atom AND type NOT IN ('array','object'); } {} -do_execsql_test json-5.8 { +do_execsql_test json101-5.8 { SELECT j2.rowid, jx.rowid, fullkey, path, key FROM j2, json_tree(j2.json) AS jx WHERE jx.value<>jx.atom AND type NOT IN ('array','object'); } {} -do_execsql_test json-6.1 { +do_execsql_test json101-6.1 { SELECT json_valid('{"a":55,"b":72,}'); } {0} -do_execsql_test json-6.2 { +do_execsql_test json101-6.2 { SELECT json_error_position('{"a":55,"b":72,}'); } {0} -do_execsql_test json-6.3 { +do_execsql_test json101-6.3 { SELECT json_valid(json('{"a":55,"b":72,}')); } {1} -do_execsql_test json-6.4 { +do_execsql_test json101-6.4 { SELECT json_valid('{"a":55,"b":72 , }'); } {0} -do_execsql_test json-6.5 { +do_execsql_test json101-6.5 { SELECT json_error_position('{"a":55,"b":72 , }'); } {0} -do_execsql_test json-6.6 { +do_execsql_test json101-6.6 { SELECT json_error_position('{"a":55,"b":72,,}'); } {16} -do_execsql_test json-6.7 { +do_execsql_test json101-6.7 { SELECT json_valid('{"a":55,"b":72}'); } {1} -do_execsql_test json-6.8 { +do_execsql_test json101-6.8 { SELECT json_error_position('["a",55,"b",72,]'); } {0} -do_execsql_test json-6.9 { +do_execsql_test json101-6.9 { SELECT json_error_position('["a",55,"b",72 , ]'); } {0} -do_execsql_test json-6.10 { +do_execsql_test json101-6.10 { SELECT json_error_position('["a",55,"b",72,,]'); } {16} -do_execsql_test json-6.11 { +do_execsql_test json101-6.11 { SELECT json_valid('["a",55,"b",72]'); } {1} @@ -352,7 +355,7 @@ 7.6 1 char(0x20,0x09,0x0a,0x0d,0x20) 7.7 0 char(0x20,0x09,0x0a,0x0c,0x0d,0x20) } { - do_execsql_test json-$tn.1 \ + do_execsql_test json101-$tn.1 \ "SELECT json_valid(printf('%s{%s\"x\"%s:%s9%s}%s', $::ws,$::ws,$::ws,$::ws,$::ws,$::ws));" \ $isvalid @@ -361,23 +364,23 @@ # Ticket https://www.sqlite.org/src/info/ad2559db380abf8e # Control characters must be escaped in JSON strings. # -do_execsql_test json-8.1 { +do_execsql_test json101-8.1 { DROP TABLE IF EXISTS t8; CREATE TABLE t8(a,b); INSERT INTO t8(a) VALUES('abc' || char(1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31,32,33,34,35) || 'xyz'); UPDATE t8 SET b=json_array(a); SELECT b FROM t8; } {{["abc\u0001\u0002\u0003\u0004\u0005\u0006\u0007\b\t\n\u000b\f\r\u000e\u000f\u0010\u0011\u0012\u0013\u0014\u0015\u0016\u0017\u0018\u0019\u001a\u001b\u001c\u001d\u001e\u001f !\"#xyz"]}} -do_execsql_test json-8.2 { +do_execsql_test json101-8.2 { SELECT a=json_extract(b,'$[0]') FROM t8; } {1} # 2017-04-12. Regression reported on the mailing list by Rolf Ade # -do_execsql_test json-8.3 { +do_execsql_test json101-8.3 { SELECT json_valid(char(0x22,0xe4,0x22)); } {1} -do_execsql_test json-8.4 { +do_execsql_test json101-8.4 { SELECT unicode(json_extract(char(0x22,228,0x22),'$')); } {228} @@ -385,331 +388,331 @@ # String values are quoted and interior quotes are escaped. NULL values # are rendered as the unquoted string "null". # -do_execsql_test json-9.1 { +do_execsql_test json101-9.1 { SELECT json_quote('abc"xyz'); } {{"abc\"xyz"}} -do_execsql_test json-9.2 { +do_execsql_test json101-9.2 { SELECT json_quote(3.14159); } {3.14159} -do_execsql_test json-9.3 { +do_execsql_test json101-9.3 { SELECT json_quote(12345); } {12345} -do_execsql_test json-9.4 { +do_execsql_test json101-9.4 { SELECT json_quote(null); } {"null"} -do_catchsql_test json-9.5 { +do_catchsql_test json101-9.5 { SELECT json_quote(x'30313233'); } {1 {JSON cannot hold BLOB values}} -do_catchsql_test json-9.6 { +do_catchsql_test json101-9.6 { SELECT json_quote(123,456) } {1 {wrong number of arguments to function json_quote()}} -do_catchsql_test json-9.7 { +do_catchsql_test json101-9.7 { SELECT json_quote() } {1 {wrong number of arguments to function json_quote()}} # Make sure only valid backslash-escapes are accepted. # -do_execsql_test json-10.1 { +do_execsql_test json101-10.1 { SELECT json_valid('" \ "'); } {0} -do_execsql_test json-10.2 { +do_execsql_test json101-10.2 { SELECT json_valid('" \! "'); } {0} -do_execsql_test json-10.3 { +do_execsql_test json101-10.3 { SELECT json_valid('" \" "'); } {1} -do_execsql_test json-10.4 { +do_execsql_test json101-10.4 { SELECT json_valid('" \# "'); } {0} -do_execsql_test json-10.5 { +do_execsql_test json101-10.5 { SELECT json_valid('" \$ "'); } {0} -do_execsql_test json-10.6 { +do_execsql_test json101-10.6 { SELECT json_valid('" \% "'); } {0} -do_execsql_test json-10.7 { +do_execsql_test json101-10.7 { SELECT json_valid('" \& "'); } {0} -do_execsql_test json-10.8 { +do_execsql_test json101-10.8 { SELECT json_valid('" \'' "'); } {0} -do_execsql_test json-10.9 { +do_execsql_test json101-10.9 { SELECT json_valid('" \( "'); } {0} -do_execsql_test json-10.10 { +do_execsql_test json101-10.10 { SELECT json_valid('" \) "'); } {0} -do_execsql_test json-10.11 { +do_execsql_test json101-10.11 { SELECT json_valid('" \* "'); } {0} -do_execsql_test json-10.12 { +do_execsql_test json101-10.12 { SELECT json_valid('" \+ "'); } {0} -do_execsql_test json-10.13 { +do_execsql_test json101-10.13 { SELECT json_valid('" \, "'); } {0} -do_execsql_test json-10.14 { +do_execsql_test json101-10.14 { SELECT json_valid('" \- "'); } {0} -do_execsql_test json-10.15 { +do_execsql_test json101-10.15 { SELECT json_valid('" \. "'); } {0} -do_execsql_test json-10.16 { +do_execsql_test json101-10.16 { SELECT json_valid('" \/ "'); } {1} -do_execsql_test json-10.17 { +do_execsql_test json101-10.17 { SELECT json_valid('" \0 "'); } {0} -do_execsql_test json-10.18 { +do_execsql_test json101-10.18 { SELECT json_valid('" \1 "'); } {0} -do_execsql_test json-10.19 { +do_execsql_test json101-10.19 { SELECT json_valid('" \2 "'); } {0} -do_execsql_test json-10.20 { +do_execsql_test json101-10.20 { SELECT json_valid('" \3 "'); } {0} -do_execsql_test json-10.21 { +do_execsql_test json101-10.21 { SELECT json_valid('" \4 "'); } {0} -do_execsql_test json-10.22 { +do_execsql_test json101-10.22 { SELECT json_valid('" \5 "'); } {0} -do_execsql_test json-10.23 { +do_execsql_test json101-10.23 { SELECT json_valid('" \6 "'); } {0} -do_execsql_test json-10.24 { +do_execsql_test json101-10.24 { SELECT json_valid('" \7 "'); } {0} -do_execsql_test json-10.25 { +do_execsql_test json101-10.25 { SELECT json_valid('" \8 "'); } {0} -do_execsql_test json-10.26 { +do_execsql_test json101-10.26 { SELECT json_valid('" \9 "'); } {0} -do_execsql_test json-10.27 { +do_execsql_test json101-10.27 { SELECT json_valid('" \: "'); } {0} -do_execsql_test json-10.28 { +do_execsql_test json101-10.28 { SELECT json_valid('" \; "'); } {0} -do_execsql_test json-10.29 { +do_execsql_test json101-10.29 { SELECT json_valid('" \< "'); } {0} -do_execsql_test json-10.30 { +do_execsql_test json101-10.30 { SELECT json_valid('" \= "'); } {0} -do_execsql_test json-10.31 { +do_execsql_test json101-10.31 { SELECT json_valid('" \> "'); } {0} -do_execsql_test json-10.32 { +do_execsql_test json101-10.32 { SELECT json_valid('" \? "'); } {0} -do_execsql_test json-10.33 { +do_execsql_test json101-10.33 { SELECT json_valid('" \@ "'); } {0} -do_execsql_test json-10.34 { +do_execsql_test json101-10.34 { SELECT json_valid('" \A "'); } {0} -do_execsql_test json-10.35 { +do_execsql_test json101-10.35 { SELECT json_valid('" \B "'); } {0} -do_execsql_test json-10.36 { +do_execsql_test json101-10.36 { SELECT json_valid('" \C "'); } {0} -do_execsql_test json-10.37 { +do_execsql_test json101-10.37 { SELECT json_valid('" \D "'); } {0} -do_execsql_test json-10.38 { +do_execsql_test json101-10.38 { SELECT json_valid('" \E "'); } {0} -do_execsql_test json-10.39 { +do_execsql_test json101-10.39 { SELECT json_valid('" \F "'); } {0} -do_execsql_test json-10.40 { +do_execsql_test json101-10.40 { SELECT json_valid('" \G "'); } {0} -do_execsql_test json-10.41 { +do_execsql_test json101-10.41 { SELECT json_valid('" \H "'); } {0} -do_execsql_test json-10.42 { +do_execsql_test json101-10.42 { SELECT json_valid('" \I "'); } {0} -do_execsql_test json-10.43 { +do_execsql_test json101-10.43 { SELECT json_valid('" \J "'); } {0} -do_execsql_test json-10.44 { +do_execsql_test json101-10.44 { SELECT json_valid('" \K "'); } {0} -do_execsql_test json-10.45 { +do_execsql_test json101-10.45 { SELECT json_valid('" \L "'); } {0} -do_execsql_test json-10.46 { +do_execsql_test json101-10.46 { SELECT json_valid('" \M "'); } {0} -do_execsql_test json-10.47 { +do_execsql_test json101-10.47 { SELECT json_valid('" \N "'); } {0} -do_execsql_test json-10.48 { +do_execsql_test json101-10.48 { SELECT json_valid('" \O "'); } {0} -do_execsql_test json-10.49 { +do_execsql_test json101-10.49 { SELECT json_valid('" \P "'); } {0} -do_execsql_test json-10.50 { +do_execsql_test json101-10.50 { SELECT json_valid('" \Q "'); } {0} -do_execsql_test json-10.51 { +do_execsql_test json101-10.51 { SELECT json_valid('" \R "'); } {0} -do_execsql_test json-10.52 { +do_execsql_test json101-10.52 { SELECT json_valid('" \S "'); } {0} -do_execsql_test json-10.53 { +do_execsql_test json101-10.53 { SELECT json_valid('" \T "'); } {0} -do_execsql_test json-10.54 { +do_execsql_test json101-10.54 { SELECT json_valid('" \U "'); } {0} -do_execsql_test json-10.55 { +do_execsql_test json101-10.55 { SELECT json_valid('" \V "'); } {0} -do_execsql_test json-10.56 { +do_execsql_test json101-10.56 { SELECT json_valid('" \W "'); } {0} -do_execsql_test json-10.57 { +do_execsql_test json101-10.57 { SELECT json_valid('" \X "'); } {0} -do_execsql_test json-10.58 { +do_execsql_test json101-10.58 { SELECT json_valid('" \Y "'); } {0} -do_execsql_test json-10.59 { +do_execsql_test json101-10.59 { SELECT json_valid('" \Z "'); } {0} -do_execsql_test json-10.60 { +do_execsql_test json101-10.60 { SELECT json_valid('" \[ "'); } {0} -do_execsql_test json-10.61 { +do_execsql_test json101-10.61 { SELECT json_valid('" \\ "'); } {1} -do_execsql_test json-10.62 { +do_execsql_test json101-10.62 { SELECT json_valid('" \] "'); } {0} -do_execsql_test json-10.63 { +do_execsql_test json101-10.63 { SELECT json_valid('" \^ "'); } {0} -do_execsql_test json-10.64 { +do_execsql_test json101-10.64 { SELECT json_valid('" \_ "'); } {0} -do_execsql_test json-10.65 { +do_execsql_test json101-10.65 { SELECT json_valid('" \` "'); } {0} -do_execsql_test json-10.66 { +do_execsql_test json101-10.66 { SELECT json_valid('" \a "'); } {0} -do_execsql_test json-10.67 { +do_execsql_test json101-10.67 { SELECT json_valid('" \b "'); } {1} -do_execsql_test json-10.68 { +do_execsql_test json101-10.68 { SELECT json_valid('" \c "'); } {0} -do_execsql_test json-10.69 { +do_execsql_test json101-10.69 { SELECT json_valid('" \d "'); } {0} -do_execsql_test json-10.70 { +do_execsql_test json101-10.70 { SELECT json_valid('" \e "'); } {0} -do_execsql_test json-10.71 { +do_execsql_test json101-10.71 { SELECT json_valid('" \f "'); } {1} -do_execsql_test json-10.72 { +do_execsql_test json101-10.72 { SELECT json_valid('" \g "'); } {0} -do_execsql_test json-10.73 { +do_execsql_test json101-10.73 { SELECT json_valid('" \h "'); } {0} -do_execsql_test json-10.74 { +do_execsql_test json101-10.74 { SELECT json_valid('" \i "'); } {0} -do_execsql_test json-10.75 { +do_execsql_test json101-10.75 { SELECT json_valid('" \j "'); } {0} -do_execsql_test json-10.76 { +do_execsql_test json101-10.76 { SELECT json_valid('" \k "'); } {0} -do_execsql_test json-10.77 { +do_execsql_test json101-10.77 { SELECT json_valid('" \l "'); } {0} -do_execsql_test json-10.78 { +do_execsql_test json101-10.78 { SELECT json_valid('" \m "'); } {0} -do_execsql_test json-10.79 { +do_execsql_test json101-10.79 { SELECT json_valid('" \n "'); } {1} -do_execsql_test json-10.80 { +do_execsql_test json101-10.80 { SELECT json_valid('" \o "'); } {0} -do_execsql_test json-10.81 { +do_execsql_test json101-10.81 { SELECT json_valid('" \p "'); } {0} -do_execsql_test json-10.82 { +do_execsql_test json101-10.82 { SELECT json_valid('" \q "'); } {0} -do_execsql_test json-10.83 { +do_execsql_test json101-10.83 { SELECT json_valid('" \r "'); } {1} -do_execsql_test json-10.84 { +do_execsql_test json101-10.84 { SELECT json_valid('" \s "'); } {0} -do_execsql_test json-10.85 { +do_execsql_test json101-10.85 { SELECT json_valid('" \t "'); } {1} -do_execsql_test json-10.86.0 { +do_execsql_test json101-10.86.0 { SELECT json_valid('" \u "'); } {0} -do_execsql_test json-10.86.1 { +do_execsql_test json101-10.86.1 { SELECT json_valid('" \ua "'); } {0} -do_execsql_test json-10.86.2 { +do_execsql_test json101-10.86.2 { SELECT json_valid('" \uab "'); } {0} -do_execsql_test json-10.86.3 { +do_execsql_test json101-10.86.3 { SELECT json_valid('" \uabc "'); } {0} -do_execsql_test json-10.86.4 { +do_execsql_test json101-10.86.4 { SELECT json_valid('" \uabcd "'); } {1} -do_execsql_test json-10.86.5 { +do_execsql_test json101-10.86.5 { SELECT json_valid('" \uFEDC "'); } {1} -do_execsql_test json-10.86.6 { +do_execsql_test json101-10.86.6 { SELECT json_valid('" \u1234 "'); } {1} -do_execsql_test json-10.87 { +do_execsql_test json101-10.87 { SELECT json_valid('" \v "'); } {0} -do_execsql_test json-10.88 { +do_execsql_test json101-10.88 { SELECT json_valid('" \w "'); } {0} -do_execsql_test json-10.89 { +do_execsql_test json101-10.89 { SELECT json_valid('" \x "'); } {0} -do_execsql_test json-10.90 { +do_execsql_test json101-10.90 { SELECT json_valid('" \y "'); } {0} -do_execsql_test json-10.91 { +do_execsql_test json101-10.91 { SELECT json_valid('" \z "'); } {0} -do_execsql_test json-10.92 { +do_execsql_test json101-10.92 { SELECT json_valid('" \{ "'); } {0} -do_execsql_test json-10.93 { +do_execsql_test json101-10.93 { SELECT json_valid('" \| "'); } {0} -do_execsql_test json-10.94 { +do_execsql_test json101-10.94 { SELECT json_valid('" \} "'); } {0} -do_execsql_test json-10.95 { +do_execsql_test json101-10.95 { SELECT json_valid('" \~ "'); } {0} @@ -719,20 +722,20 @@ # # The following tests confirm that deeply nested JSON is considered invalid. # -do_execsql_test json-11.0 { +do_execsql_test json101-11.0 { /* Shallow enough to be parsed */ SELECT json_valid(printf('%.1000c0%.1000c','[',']')); } {1} -do_execsql_test json-11.1 { +do_execsql_test json101-11.1 { /* Too deep by one */ SELECT json_valid(printf('%.1001c0%.1001c','[',']')); } {0} -do_execsql_test json-11.2 { +do_execsql_test json101-11.2 { /* Shallow enough to be parsed { */ SELECT json_valid(replace(printf('%.1000c0%.1000c','[','}'),'[','{"a":')); /* } */ } {1} -do_execsql_test json-11.3 { +do_execsql_test json101-11.3 { /* Too deep by one { */ SELECT json_valid(replace(printf('%.1001c0%.1001c','[','}'),'[','{"a":')); /* } */ @@ -742,7 +745,7 @@ # a json structure even though the element name constains a "." # character, by quoting the element name in the path. # -do_execsql_test json-12.100 { +do_execsql_test json101-12.100 { CREATE TABLE t12(x); INSERT INTO t12(x) VALUES( '{"settings": @@ -766,11 +769,11 @@ } }'); } {} -do_execsql_test json-12.110 { +do_execsql_test json101-12.110 { SELECT json_remove(x, '$.settings.layer2."dis.legomenon".forceDisplay') FROM t12; } {{{"settings":{"layer2":{"hapax.legomenon":{"forceDisplay":true,"transliterate":true,"add.footnote":true,"summary.report":true},"dis.legomenon":{"transliterate":false,"add.footnote":false,"summary.report":true},"tris.legomenon":{"forceDisplay":true,"transliterate":false,"add.footnote":false,"summary.report":false}}}}}} -do_execsql_test json-12.120 { +do_execsql_test json101-12.120 { SELECT json_extract(x, '$.settings.layer2."tris.legomenon"."summary.report"') FROM t12; } {0} @@ -779,7 +782,7 @@ # ticket https://www.sqlite.org/src/tktview/80177f0c226ff54f6ddd41 # Make sure the query planner knows about the arguments to table-valued functions. # -do_execsql_test json-13.100 { +do_execsql_test json101-13.100 { DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; CREATE TABLE t1(id, json); @@ -794,7 +797,7 @@ WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z WHERE Z.value==t2.id); } {1 {{"items":[3,5]}} 3 {{"value":3}} 1 {{"items":[3,5]}} 5 {{"value":5}}} -do_execsql_test json-13.110 { +do_execsql_test json101-13.110 { SELECT * FROM t2 CROSS JOIN t1 WHERE EXISTS(SELECT 1 FROM json_each(t1.json,'$.items') AS Z WHERE Z.value==t2.id); @@ -804,28 +807,28 @@ # Incorrect fullkey output from json_each() # when the input JSON is not an array or object. # -do_execsql_test json-14.100 { +do_execsql_test json101-14.100 { SELECT fullkey FROM json_each('123'); } {$} -do_execsql_test json-14.110 { +do_execsql_test json101-14.110 { SELECT fullkey FROM json_each('123.56'); } {$} -do_execsql_test json-14.120 { +do_execsql_test json101-14.120 { SELECT fullkey FROM json_each('"hello"'); } {$} -do_execsql_test json-14.130 { +do_execsql_test json101-14.130 { SELECT fullkey FROM json_each('null'); } {$} -do_execsql_test json-14.140 { +do_execsql_test json101-14.140 { SELECT fullkey FROM json_tree('123'); } {$} -do_execsql_test json-14.150 { +do_execsql_test json101-14.150 { SELECT fullkey FROM json_tree('123.56'); } {$} -do_execsql_test json-14.160 { +do_execsql_test json101-14.160 { SELECT fullkey FROM json_tree('"hello"'); } {$} -do_execsql_test json-14.170 { +do_execsql_test json101-14.170 { SELECT fullkey FROM json_tree('null'); } {$} @@ -835,16 +838,16 @@ # # Bug reported via private email. See TH3 for more information. # -do_execsql_test json-15.100 { +do_execsql_test json101-15.100 { SELECT * FROM JSON_EACH('{"a":1, "b":2}'); } {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}} -do_execsql_test json-15.110 { +do_execsql_test json101-15.110 { SELECT xyz.* FROM JSON_EACH('{"a":1, "b":2}') AS xyz; } {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}} -do_execsql_test json-15.120 { +do_execsql_test json101-15.120 { SELECT * FROM (JSON_EACH('{"a":1, "b":2}')); } {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}} -do_execsql_test json-15.130 { +do_execsql_test json101-15.130 { SELECT xyz.* FROM (JSON_EACH('{"a":1, "b":2}')) AS xyz; } {a 1 integer 1 2 {} {$.a} {$} b 2 integer 2 4 {} {$.b} {$}} @@ -852,18 +855,18 @@ # Mailing list bug report on the handling of surrogate pairs # in JSON. # -do_execsql_test json-16.10 { +do_execsql_test json101-16.10 { SELECT length(json_extract('"abc\uD834\uDD1Exyz"','$')); } {7} -do_execsql_test json-16.20 { +do_execsql_test json101-16.20 { SELECT length(json_extract('"\uD834\uDD1E"','$')); } {1} -do_execsql_test json-16.30 { +do_execsql_test json101-16.30 { SELECT unicode(json_extract('"\uD834\uDD1E"','$')); } {119070} # 2022-01-30 dbsqlfuzz 4678cf825d27f87c9b8343720121e12cf944b71a -do_execsql_test json-17.1 { +do_execsql_test json101-17.1 { DROP TABLE IF EXISTS t1; DROP TABLE IF EXISTS t2; CREATE TABLE t1(a,b,c); @@ -872,19 +875,19 @@ } {} # 2022-04-04 forum post https://sqlite.org/forum/forumpost/c082aeab43 -do_execsql_test json-18.1 { +do_execsql_test json101-18.1 { SELECT json_valid('{"":5}'); } {1} -do_execsql_test json-18.2 { +do_execsql_test json101-18.2 { SELECT json_extract('{"":5}', '$.""'); } {5} -do_execsql_test json-18.3 { +do_execsql_test json101-18.3 { SELECT json_extract('[3,{"a":4,"":[5,{"hi":6},7]},8]', '$[1].""[1].hi'); } {6} -do_execsql_test json-18.4 { +do_execsql_test json101-18.4 { SELECT json_extract('[3,{"a":4,"":[5,{"hi":6},7]},8]', '$[1].""[1]."hi"'); } {6} -do_catchsql_test json-18.5 { +do_catchsql_test json101-18.5 { SELECT json_extract('{"":8}', '$.'); } {1 {JSON path error near ''}} @@ -893,28 +896,28 @@ # a problem with transaction control. But the json() function makes # the problem more easily accessible, so it is tested here. # -do_execsql_test json-19.1 { +do_execsql_test json101-19.1 { DROP TABLE IF EXISTS t1; CREATE TABLE t1(x); } {} -do_catchsql_test json-19.2 { +do_catchsql_test json101-19.2 { BEGIN; INSERT INTO t1 VALUES(0), (json('not-valid-json')); } {1 {malformed JSON}} -do_execsql_test json-19.3 { +do_execsql_test json101-19.3 { COMMIT; SELECT * FROM t1; } {} # 2023-03-17 positive and negative infinities # -do_execsql_test json-20.1 { +do_execsql_test json101-20.1 { SELECT json_object('a',2e370,'b',-3e380); } {{{"a":9.0e+999,"b":-9.0e+999}}} -do_execsql_test json-20.2 { +do_execsql_test json101-20.2 { SELECT json_object('a',2e370,'b',-3e380)->>'a'; } Inf -do_execsql_test json-20.3 { +do_execsql_test json101-20.3 { SELECT json_object('a',2e370,'b',-3e380)->>'b'; } {-Inf} @@ -923,91 +926,133 @@ # a NULL value as the JSON input. # db null NULL -do_execsql_test json-21.1 { - SELECT json_valid(NULL); -} NULL -do_execsql_test json-21.2 { +if {[db exists {SELECT * FROM pragma_compile_options WHERE compile_options LIKE '%legacy_json_valid%'}]} { + do_execsql_test json101-21.1-legacy { + SELECT json_valid(NULL); + } 0 +} else { + do_execsql_test json101-21.1-correct { + SELECT json_valid(NULL); + } NULL +} +do_execsql_test json101-21.2 { SELECT json_error_position(NULL); } NULL -do_execsql_test json-21.3 { +do_execsql_test json101-21.3 { SELECT json(NULL); } NULL -do_execsql_test json-21.4 { +do_execsql_test json101-21.4 { SELECT json_array(NULL); } {[null]} -do_execsql_test json-21.5 { +do_execsql_test json101-21.5 { SELECT json_extract(NULL); } NULL -do_execsql_test json-21.6 { +do_execsql_test json101-21.6 { SELECT json_insert(NULL,'$',123); } NULL -do_execsql_test json-21.7 { +do_execsql_test json101-21.7 { SELECT NULL->0; } NULL -do_execsql_test json-21.8 { +do_execsql_test json101-21.8 { SELECT NULL->>0; } NULL -do_execsql_test json-21.9 { +do_execsql_test json101-21.9 { SELECT '{a:5}'->NULL; } NULL -do_execsql_test json-21.10 { +do_execsql_test json101-21.10 { SELECT '{a:5}'->>NULL; } NULL -do_catchsql_test json-21.11 { +do_catchsql_test json101-21.11 { SELECT json_object(NULL,5); } {1 {json_object() labels must be TEXT}} -do_execsql_test json-21.12 { +do_execsql_test json101-21.12 { SELECT json_patch(NULL,'{a:5}'); } NULL -do_execsql_test json-21.13 { +do_execsql_test json101-21.13 { SELECT json_patch('{a:5}',NULL); } NULL -do_execsql_test json-21.14 { +do_execsql_test json101-21.14 { SELECT json_patch(NULL,NULL); } NULL -do_execsql_test json-21.15 { +do_execsql_test json101-21.15 { SELECT json_remove(NULL,'$'); } NULL -do_execsql_test json-21.16 { +do_execsql_test json101-21.16 { SELECT json_remove('{a:5,b:7}',NULL); } NULL -do_execsql_test json-21.17 { +do_execsql_test json101-21.17 { SELECT json_replace(NULL,'$.a',123); } NULL -do_execsql_test json-21.18 { +do_execsql_test json101-21.18 { SELECT json_replace('{a:5,b:7}',NULL,NULL); } {{{"a":5,"b":7}}} -do_execsql_test json-21.19 { +do_execsql_test json101-21.19 { SELECT json_set(NULL,'$.a',123); } NULL -do_execsql_test json-21.20 { +do_execsql_test json101-21.20 { SELECT json_set('{a:5,b:7}',NULL,NULL); } {{{"a":5,"b":7}}} -do_execsql_test json-21.21 { +do_execsql_test json101-21.21 { SELECT json_type(NULL); } NULL -do_execsql_test json-21.22 { +do_execsql_test json101-21.22 { SELECT json_type('{a:5,b:7}',NULL); } NULL -do_execsql_test json-21.23 { +do_execsql_test json101-21.23 { SELECT json_quote(NULL); } null -do_execsql_test json-21.24 { +do_execsql_test json101-21.24 { SELECT count(*) FROM json_each(NULL); } 0 -do_execsql_test json-21.25 { +do_execsql_test json101-21.25 { SELECT count(*) FROM json_tree(NULL); } 0 -do_execsql_test json-21.26 { +do_execsql_test json101-21.26 { WITH c(x) AS (VALUES(1),(2.0),(NULL),('three')) SELECT json_group_array(x) FROM c; } {[1,2.0,null,"three"]} -do_execsql_test json-21.27 { +do_execsql_test json101-21.27 { WITH c(x,y) AS (VALUES('a',1),('b',2.0),('c',NULL),(NULL,'three'),('e','four')) SELECT json_group_object(x,y) FROM c; } {{{"a":1,"b":2.0,"c":null,:"three","e":"four"}}} - +# 2023-10-09 https://sqlite.org/forum/forumpost/b25edc1d46 +# UAF due to JSON cache overflow +# +do_execsql_test json101-22.1 { + SELECT json_set( + '{}', + '$.a', json('1'), + '$.a', json('2'), + '$.b', json('3'), + '$.b', json('4'), + '$.c', json('5'), + '$.c', json('6') + ); +} {{{"a":2,"b":4,"c":6}}} +do_execsql_test json101-22.2 { + SELECT json_replace( + '{"a":7,"b":8,"c":9}', + '$.a', json('1'), + '$.a', json('2'), + '$.b', json('3'), + '$.b', json('4'), + '$.c', json('5'), + '$.c', json('6') + ); +} {{{"a":2,"b":4,"c":6}}} + +# 2023-10-17 https://sqlite.org/forum/forumpost/fc0e3f1e2a +# Incorrect accesss to '$[0]' in parsed + edited JSON. +# +do_execsql_test json101-23.1 { + SELECT j, j->>0, j->>1 + FROM (SELECT json_set(json_set('[]','$[#]',0), '$[#]',1) AS j); +} {{[0,1]} 0 1} +do_execsql_test json101-23.2 { + SELECT j, j->>0, j->>1 + FROM (SELECT json_set('[]','$[#]',0,'$[#]',1) AS j); +} {{[0,1]} 0 1} diff -Nru sqlite3-3.42.0/test/json102.test sqlite3-3.44.0-0/test/json102.test --- sqlite3-3.42.0/test/json102.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/json102.test 2023-11-04 14:23:58.000000000 +0000 @@ -48,6 +48,9 @@ do_execsql_test json102-190 { SELECT json_array_length('[1,2,3,4]'); } {{4}} +do_execsql_test json102-191 { + SELECT json_array_length( json_remove('[1,2,3,4]','$[2]') ); +} {{3}} do_execsql_test json102-200 { SELECT json_array_length('[1,2,3,4]', '$'); } {{4}} @@ -397,4 +400,22 @@ 6 {} null {} null {} null ] +reset_db +do_execsql_test json102-1700 { + CREATE TABLE t1(a1 DATE, a2 INTEGER PRIMARY KEY, a3 INTEGER, memo TEXT); + CREATE INDEX t1x1 ON t1(a3, a1, memo->>'y'); + INSERT INTO t1(a2,a1,a3,memo) VALUES (876, '2023-08-03', 5, '{"x":77,"y":4}'); +} +do_execsql_test json102-1710 { + UPDATE t1 SET memo = JSON_REMOVE(memo, '$.y'); + PRAGMA integrity_check; + SELECT * FROM t1; +} {ok 2023-08-03 876 5 {{"x":77}}} +do_execsql_test json102-1720 { + UPDATE t1 SET memo = JSON_SET(memo, '$.y', 6) + WHERE a2 IN (876) AND JSON_TYPE(memo, '$.y') IS NULL; + PRAGMA integrity_check; + SELECT * FROM t1; +} {ok 2023-08-03 876 5 {{"x":77,"y":6}}} + finish_test diff -Nru sqlite3-3.42.0/test/kvtest.c sqlite3-3.44.0-0/test/kvtest.c --- sqlite3-3.42.0/test/kvtest.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/kvtest.c 2023-11-04 14:23:58.000000000 +0000 @@ -161,7 +161,7 @@ #endif /* -** Show thqe help text and quit. +** Show the help text and quit. */ static void showHelp(void){ fprintf(stdout, "%s", zHelp); diff -Nru sqlite3-3.42.0/test/like.test sqlite3-3.44.0-0/test/like.test --- sqlite3-3.42.0/test/like.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/like.test 2023-11-04 14:23:58.000000000 +0000 @@ -1140,4 +1140,24 @@ } {1} +# 2023-08-15 https://sqlite.org/forum/forumpost/925dc9f67804c540 +# +reset_db +sqlite3_db_config db DEFENSIVE 1 +db eval {PRAGMA trusted_schema=OFF} +do_execsql_test 18.0 { + CREATE TABLE t1(x INT, y TEXT); + INSERT INTO t1 VALUES(1,'abc'),(2,'ABC'),(3,'Abc'); + CREATE VIEW t2 AS SELECT * FROM t1 WHERE y LIKE 'a%'; + SELECT * FROM t2; +} {1 abc 2 ABC 3 Abc} +do_execsql_test 18.1 { + PRAGMA case_sensitive_like=OFF; + SELECT * FROM t2; +} {1 abc 2 ABC 3 Abc} +do_execsql_test 18.2 { + PRAGMA case_sensitive_like=ON; + SELECT * FROM t2; +} {1 abc} + finish_test diff -Nru sqlite3-3.42.0/test/memdb2.test sqlite3-3.44.0-0/test/memdb2.test --- sqlite3-3.42.0/test/memdb2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/memdb2.test 2023-11-04 14:23:58.000000000 +0000 @@ -74,4 +74,3 @@ } finish_test - diff -Nru sqlite3-3.42.0/test/memjournal2.test sqlite3-3.44.0-0/test/memjournal2.test --- sqlite3-3.42.0/test/memjournal2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/memjournal2.test 2023-11-04 14:23:58.000000000 +0000 @@ -59,5 +59,3 @@ finish_test - - diff -Nru sqlite3-3.42.0/test/mutex1.test sqlite3-3.44.0-0/test/mutex1.test --- sqlite3-3.42.0/test/mutex1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/mutex1.test 2023-11-04 14:23:58.000000000 +0000 @@ -115,6 +115,14 @@ } } { + # For journal_mode=memory, the static_prng mutex is not required. This + # is because the header of an in-memory journal does not contain + # any random bytes, and so no call to sqlite3_randomness() is made. + if {[permutation]=="inmemory_journal"} { + set idx [lsearch $mutexes static_prng] + if {$idx>=0} { set mutexes [lreplace $mutexes $idx $idx] } + } + do_test mutex1.2.$mode.1 { catch {db close} sqlite3_shutdown diff -Nru sqlite3-3.42.0/test/pendingrace.test sqlite3-3.44.0-0/test/pendingrace.test --- sqlite3-3.42.0/test/pendingrace.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/pendingrace.test 2023-11-04 14:23:58.000000000 +0000 @@ -121,6 +121,3 @@ tvfs2 delete finish_test - - - diff -Nru sqlite3-3.42.0/test/permutations.test sqlite3-3.44.0-0/test/permutations.test --- sqlite3-3.42.0/test/permutations.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/permutations.test 2023-11-04 14:23:58.000000000 +0000 @@ -10,9 +10,11 @@ #*********************************************************************** # -set testdir [file dirname $argv0] -source $testdir/tester.tcl -db close +if {[info vars ::trd::tcltest]==""} { + set testdir [file dirname $argv0] + source $testdir/tester.tcl + db close +} #------------------------------------------------------------------------- # test_suite NAME OPTIONS @@ -813,117 +815,111 @@ recoverpgsz.test }] -ifcapable mem3 { - test_suite "memsys3" -description { - Run tests using the allocator in mem3.c. - } -files [test_set $::allquicktests -exclude { - autovacuum.test delete3.test manydb.test - bigrow.test incrblob2.test memdb.test - bitvec.test index2.test memsubsys1.test - capi3c.test ioerr.test memsubsys2.test - capi3.test join3.test pagesize.test - collate5.test limit.test backup_ioerr.test - backup_malloc.test - }] -initialize { - catch {db close} - sqlite3_reset_auto_extension - sqlite3_shutdown - sqlite3_config_heap 25000000 0 - sqlite3_config_lookaside 0 0 - ifcapable mem5 { - # If both memsys3 and memsys5 are enabled in the build, the call to - # [sqlite3_config_heap] will initialize the system to use memsys5. - # The following overrides this preference and installs the memsys3 - # allocator. - sqlite3_install_memsys3 - } - install_malloc_faultsim 1 - sqlite3_initialize - autoinstall_test_functions - } -shutdown { - catch {db close} - sqlite3_shutdown - sqlite3_config_heap 0 0 - sqlite3_config_lookaside 100 500 - install_malloc_faultsim 1 - sqlite3_initialize - autoinstall_test_functions +test_suite "memsys3" -description { + Run tests using the allocator in mem3.c. +} -files [test_set $::allquicktests -exclude { + autovacuum.test delete3.test manydb.test + bigrow.test incrblob2.test memdb.test + bitvec.test index2.test memsubsys1.test + capi3c.test ioerr.test memsubsys2.test + capi3.test join3.test pagesize.test + collate5.test limit.test backup_ioerr.test + backup_malloc.test +}] -initialize { + catch {db close} + sqlite3_reset_auto_extension + sqlite3_shutdown + sqlite3_config_heap 25000000 0 + sqlite3_config_lookaside 0 0 + ifcapable mem5 { + # If both memsys3 and memsys5 are enabled in the build, the call to + # [sqlite3_config_heap] will initialize the system to use memsys5. + # The following overrides this preference and installs the memsys3 + # allocator. + sqlite3_install_memsys3 } + install_malloc_faultsim 1 + sqlite3_initialize + autoinstall_test_functions +} -shutdown { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 0 0 + sqlite3_config_lookaside 100 500 + install_malloc_faultsim 1 + sqlite3_initialize + autoinstall_test_functions } -ifcapable mem5 { - test_suite "memsys5" -description { - Run tests using the allocator in mem5.c. - } -files [test_set $::allquicktests -exclude { - autovacuum.test delete3.test manydb.test - bigrow.test incrblob2.test memdb.test - bitvec.test index2.test memsubsys1.test - capi3c.test ioerr.test memsubsys2.test - capi3.test join3.test pagesize.test - collate5.test limit.test zeroblob.test - }] -initialize { - catch {db close} - sqlite3_shutdown - sqlite3_config_heap 25000000 64 - sqlite3_config_lookaside 0 0 - install_malloc_faultsim 1 - sqlite3_initialize - autoinstall_test_functions - } -shutdown { - catch {db close} - sqlite3_shutdown - sqlite3_config_heap 0 0 - sqlite3_config_lookaside 100 500 - install_malloc_faultsim 1 - sqlite3_initialize - autoinstall_test_functions - } +test_suite "memsys5" -description { + Run tests using the allocator in mem5.c. +} -files [test_set $::allquicktests -exclude { + autovacuum.test delete3.test manydb.test + bigrow.test incrblob2.test memdb.test + bitvec.test index2.test memsubsys1.test + capi3c.test ioerr.test memsubsys2.test + capi3.test join3.test pagesize.test + collate5.test limit.test zeroblob.test +}] -initialize { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 25000000 64 + sqlite3_config_lookaside 0 0 + install_malloc_faultsim 1 + sqlite3_initialize + autoinstall_test_functions +} -shutdown { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 0 0 + sqlite3_config_lookaside 100 500 + install_malloc_faultsim 1 + sqlite3_initialize + autoinstall_test_functions +} - test_suite "memsys5-2" -description { - Run tests using the allocator in mem5.c in a different configuration. - } -files { - select1.test - } -initialize { - catch {db close} - sqlite3_shutdown - sqlite3_config_memstatus 0 - sqlite3_config_heap 40000000 16 - sqlite3_config_lookaside 0 0 - install_malloc_faultsim 1 - sqlite3_initialize - autoinstall_test_functions - } -shutdown { - catch {db close} - sqlite3_shutdown - sqlite3_config_heap 0 0 - sqlite3_config_lookaside 100 500 - install_malloc_faultsim 1 - sqlite3_initialize - autoinstall_test_functions - } +test_suite "memsys5-2" -description { + Run tests using the allocator in mem5.c in a different configuration. +} -files { + select1.test +} -initialize { + catch {db close} + sqlite3_shutdown + sqlite3_config_memstatus 0 + sqlite3_config_heap 40000000 16 + sqlite3_config_lookaside 0 0 + install_malloc_faultsim 1 + sqlite3_initialize + autoinstall_test_functions +} -shutdown { + catch {db close} + sqlite3_shutdown + sqlite3_config_heap 0 0 + sqlite3_config_lookaside 100 500 + install_malloc_faultsim 1 + sqlite3_initialize + autoinstall_test_functions } -ifcapable threadsafe { - test_suite "no_mutex_try" -description { - The sqlite3_mutex_try() interface always fails - } -files [ - test_set $::allquicktests -exclude mutex1.test mutex2.test - ] -initialize { - catch {db close} - sqlite3_shutdown - install_mutex_counters 1 - set ::disable_mutex_try 1 - sqlite3_initialize - autoinstall_test_functions - } -shutdown { - catch {db close} - catch {db2 close} - catch {db3 close} - sqlite3_shutdown - install_mutex_counters 0 - sqlite3_initialize - autoinstall_test_functions - } +test_suite "no_mutex_try" -description { + The sqlite3_mutex_try() interface always fails +} -files [ + test_set $::allquicktests -exclude mutex1.test mutex2.test +] -initialize { + catch {db close} + sqlite3_shutdown + install_mutex_counters 1 + set ::disable_mutex_try 1 + sqlite3_initialize + autoinstall_test_functions +} -shutdown { + catch {db close} + catch {db2 close} + catch {db3 close} + sqlite3_shutdown + install_mutex_counters 0 + sqlite3_initialize + autoinstall_test_functions } # run_tests "crash_safe_append" -description { diff -Nru sqlite3-3.42.0/test/quickcheck.test sqlite3-3.44.0-0/test/quickcheck.test --- sqlite3-3.42.0/test/quickcheck.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/quickcheck.test 2023-11-04 14:23:58.000000000 +0000 @@ -31,4 +31,3 @@ } finish_test - diff -Nru sqlite3-3.42.0/test/releasetest_data.tcl sqlite3-3.44.0-0/test/releasetest_data.tcl --- sqlite3-3.42.0/test/releasetest_data.tcl 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/releasetest_data.tcl 2023-11-04 14:23:58.000000000 +0000 @@ -53,6 +53,12 @@ --enable-session -DSQLITE_ENABLE_RBU } + "All-Debug" { + --enable-debug --enable-all + } + "All-O0" { + -O0 --enable-all + } "Sanitize" { CC=clang -fsanitize=address,undefined -DSQLITE_ENABLE_STAT4 @@ -257,6 +263,7 @@ -DSQLITE_ENABLE_FTS4 -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_HIDDEN_COLUMNS + -DLONGDOUBLE_TYPE=double -DCONFIG_SLOWDOWN_FACTOR=8.0 } @@ -671,6 +678,12 @@ lappend opts -DSQLITE_ENABLE_PREUPDATE_HOOK lappend opts -DSQLITE_ENABLE_SESSION } + --enable-all { + } + --enable-debug { + # lappend makeOpts OPTIMIZATIONS=0 + lappend opts -DSQLITE_DEBUG + } default { error "Cannot translate $param for MSVC" } @@ -716,7 +729,12 @@ puts " \$SRCDIR/configure --with-tcl=\$TCL $configOpts" puts {fi} puts {} - puts {OPTS=" -DSQLITE_NO_SYNC=1"} + if {[info exists ::env(OPTS)]} { + puts "# From environment variable:" + puts "OPTS=$::env(OPTS)" + puts "" + } + puts {OPTS="$OPTS -DSQLITE_NO_SYNC=1"} foreach o $opts { puts "OPTS=\"\$OPTS $o\"" } diff -Nru sqlite3-3.42.0/test/round1.test sqlite3-3.44.0-0/test/round1.test --- sqlite3-3.42.0/test/round1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/round1.test 2023-11-04 14:23:58.000000000 +0000 @@ -34,8 +34,8 @@ set r2 $x1.$x4 set ans [string trimright $r2 0] if {[string match *. $ans]} {set ans ${ans}0} - do_test $iTest/$n/${r}5=>$ans { - set x [db one "SELECT round(${r}5,$n)"] + do_test $iTest/$n/${r}6=>$ans { + set x [db one "SELECT round(${r}6,$n)"] } $ans } diff -Nru sqlite3-3.42.0/test/rowvalue9.test sqlite3-3.44.0-0/test/rowvalue9.test --- sqlite3-3.42.0/test/rowvalue9.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/rowvalue9.test 2023-11-04 14:23:58.000000000 +0000 @@ -350,5 +350,3 @@ finish_test - - diff -Nru sqlite3-3.42.0/test/rowvalueA.test sqlite3-3.44.0-0/test/rowvalueA.test --- sqlite3-3.42.0/test/rowvalueA.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/rowvalueA.test 2023-11-04 14:23:58.000000000 +0000 @@ -74,4 +74,3 @@ } {1 {row value misused}} finish_test - diff -Nru sqlite3-3.42.0/test/scanstatus2.test sqlite3-3.44.0-0/test/scanstatus2.test --- sqlite3-3.42.0/test/scanstatus2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/scanstatus2.test 2023-11-04 14:23:58.000000000 +0000 @@ -55,11 +55,12 @@ dict get $r nCycle } -proc foreach_scan {varname stmt body} { +proc foreach_scan {varname stmt body {debug 0}} { upvar $varname var - for {set ii 0} {1} {incr ii} { - set r [sqlite3_stmt_scanstatus -flags complex $stmt $ii] + set f "complex" + if {$debug} { set f "complex debug" } + set r [sqlite3_stmt_scanstatus -flags $f $stmt $ii] if {[llength $r]==0} break array set var $r uplevel $body @@ -102,6 +103,15 @@ puts [string trim [get_graph $stmt]] } +proc puts_debug_info {sql} { + db eval $sql + set stmt [db version -last-stmt-ptr] + foreach_scan X $stmt { + puts -nonewline "$X(debug_explain) $X(zExplain): " + puts -nonewline "loop=$X(debug_loop) visit=$X(debug_visit) " + puts "csr=$X(debug_csr) range=$X(debug_range)" + } 1 +} do_zexplain_test 0 1.1 { SELECT (SELECT a FROM t1 WHERE b=x) FROM t2 WHERE y=2 @@ -135,8 +145,8 @@ QUERY (nCycle=nnn) --MATERIALIZE v2 (nCycle=nnn) ----SCAN t2 (nCycle=nnn) ---SCAN v2 (nCycle=nnn) --SCAN t1 (nCycle=nnn) +--SCAN v2 (nCycle=nnn) --USE TEMP B-TREE FOR ORDER BY (nCycle=nnn) } @@ -235,7 +245,7 @@ QUERY (nCycle=nnn) --CO-ROUTINE v1 ----SCAN rt2 (nCycle=nnn) -----USE TEMP B-TREE FOR GROUP BY +----USE TEMP B-TREE FOR GROUP BY (nCycle=nnn) --SCAN rt1 (nCycle=nnn) --CREATE AUTOMATIC INDEX ON v1(x1, cnt) (nCycle=nnn) --BLOOM FILTER ON v1 (x1=?) @@ -270,6 +280,55 @@ } {{SCAN t1} {SCAN t1} {SCAN t1}} } -finish_test +#------------------------------------------------------------------------- +reset_db +sqlite3_db_config db STMT_SCANSTATUS 1 + +do_execsql_test 6.0 { + CREATE TABLE t1(a, b); + INSERT INTO t1 VALUES(1, 'one'); + INSERT INTO t1 VALUES(2, 'two'); + INSERT INTO t1 VALUES(3, 'three'); + INSERT INTO t1 VALUES(4, 'four'); + INSERT INTO t1 VALUES(5, 'five'); + INSERT INTO t1 VALUES(6, 'six'); + INSERT INTO t1 VALUES(7, 'seven'); + INSERT INTO t1 VALUES(8, 'eight'); +} + +do_graph_test 6.1 { + SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1 +} { +QUERY (nCycle=nnn) +--SCAN t1 (nCycle=nnn) +--USE TEMP B-TREE FOR GROUP BY (nCycle=nnn) +} + +set sql { + WITH xy(x, y) AS ( SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1) + SELECT * FROM xy WHERE x=1 +} +do_graph_test 6.2 $sql { +QUERY (nCycle=nnn) +--CO-ROUTINE xy +----SCAN t1 (nCycle=nnn) +----USE TEMP B-TREE FOR GROUP BY (nCycle=nnn) +--SCAN xy (nCycle=nnn) +} +do_graph_test 6.3 { + WITH xy(x, y) AS ( SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1) + SELECT * FROM xy, xy AS xy2 +} { +QUERY (nCycle=nnn) +--MATERIALIZE xy (nCycle=nnn) +----SCAN t1 (nCycle=nnn) +----USE TEMP B-TREE FOR GROUP BY (nCycle=nnn) +--SCAN xy (nCycle=nnn) +--SCAN xy2 (nCycle=nnn) +} + +#explain_i { SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1 } +#puts_debug_info { SELECT (a % 2), group_concat(b) FROM t1 GROUP BY 1 } +finish_test diff -Nru sqlite3-3.42.0/test/select3.test sqlite3-3.44.0-0/test/select3.test --- sqlite3-3.42.0/test/select3.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/select3.test 2023-11-04 14:23:58.000000000 +0000 @@ -434,4 +434,3 @@ } finish_test - diff -Nru sqlite3-3.42.0/test/selectH.test sqlite3-3.44.0-0/test/selectH.test --- sqlite3-3.42.0/test/selectH.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/selectH.test 2023-11-04 14:23:58.000000000 +0000 @@ -113,6 +113,33 @@ CREATE TABLE t1(a INTEGER PRIMARY KEY, b TEXT); SELECT 1 FROM (SELECT DISTINCT name COLLATE rtrim FROM sqlite_schema UNION ALL SELECT a FROM t1); -} 1 +} {1 1} + +do_execsql_test 4.2 { + SELECT DISTINCT name COLLATE rtrim FROM sqlite_schema + UNION ALL + SELECT a FROM t1 +} {v1 t1} + +#------------------------------------------------------------------------- +# forum post https://sqlite.org/forum/forumpost/b83c7b2168 +# +reset_db +do_execsql_test 5.0 { + CREATE TABLE t1 (val1); + INSERT INTO t1 VALUES(4); + INSERT INTO t1 VALUES(5); + CREATE TABLE t2 (val2); +} +do_execsql_test 5.1 { + SELECT DISTINCT val1 FROM t1 UNION ALL SELECT val2 FROM t2; +} { + 4 5 +} +do_execsql_test 5.2 { + SELECT count(1234) FROM ( + SELECT DISTINCT val1 FROM t1 UNION ALL SELECT val2 FROM t2 + ) +} {2} finish_test diff -Nru sqlite3-3.42.0/test/sessionfuzz.c sqlite3-3.44.0-0/test/sessionfuzz.c --- sqlite3-3.42.0/test/sessionfuzz.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/sessionfuzz.c 2023-11-04 14:23:58.000000000 +0000 @@ -66,14 +66,6 @@ #define SQLITE_ENABLE_DESERIALIZE 1 #include "sqlite3.c" -/* Create a test database. This will be an in-memory database */ -static const char zInitSql[] = - "CREATE TABLE t1(a INTEGER PRIMARY KEY,b,c,d);\n" - "CREATE TABLE t2(e TEXT PRIMARY KEY NOT NULL,f,g);\n" - "CREATE TABLE t3(w REAL PRIMARY KEY NOT NULL,x,y);\n" - "CREATE TABLE t4(z PRIMARY KEY) WITHOUT ROWID;\n" -; - /* Code to populate the database */ static const char zFillSql[] = "INSERT INTO t1(a,b,c,d) VALUES\n" diff -Nru sqlite3-3.42.0/test/shell1.test sqlite3-3.44.0-0/test/shell1.test --- sqlite3-3.42.0/test/shell1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/shell1.test 2023-11-04 14:23:58.000000000 +0000 @@ -1081,10 +1081,10 @@ # set escapes [list \ \t \\t \n \\n \v \\v \f \\f \ - " " "\" \"" \" \\\" ' \"'\" \\ \\\\] + " " "\" \"" \" \\\" \\ \\\\] } set char [string map $escapes $char] - set x [catchcmdex test.db ".print $char\n"] + set x [catchcmdex test.db ".print \"$char\"\n"] set code [lindex $x 0] set res [lindex $x 1] if {$code ne "0"} { @@ -1165,21 +1165,21 @@ } {0 {CREATE TABLE Z (x TEXT PRIMARY KEY); CREATE TABLE _ (x TEXT PRIMARY KEY);}} do_test shell1-7.1.3 { - catchcmd "test.db" ".schema \\\\_" + catchcmd "test.db" ".schema \"\\\\_\"" } {0 {CREATE TABLE _ (x TEXT PRIMARY KEY);}} do_test shell1-7.1.4 { catchcmd "test.db" ".schema __" } {0 {CREATE TABLE YY (x TEXT PRIMARY KEY); CREATE TABLE __ (x TEXT PRIMARY KEY);}} do_test shell1-7.1.5 { - catchcmd "test.db" ".schema \\\\_\\\\_" + catchcmd "test.db" ".schema \"\\\\_\\\\_\"" } {0 {CREATE TABLE __ (x TEXT PRIMARY KEY);}} do_test shell1-7.1.6 { catchcmd "test.db" ".schema ___" } {0 {CREATE TABLE WWW (x TEXT PRIMARY KEY); CREATE TABLE ___ (x TEXT PRIMARY KEY);}} do_test shell1-7.1.7 { - catchcmd "test.db" ".schema \\\\_\\\\_\\\\_" + catchcmd "test.db" ".schema \"\\\\_\\\\_\\\\_\"" } {0 {CREATE TABLE ___ (x TEXT PRIMARY KEY);}} } diff -Nru sqlite3-3.42.0/test/shell2.test sqlite3-3.44.0-0/test/shell2.test --- sqlite3-3.42.0/test/shell2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/shell2.test 2023-11-04 14:23:58.000000000 +0000 @@ -262,5 +262,14 @@ SELECT count(*) FROM t;}]] } {0 1} +# Bug from forum post 7cbe081746dd3803 +# Keywords as column names were producing an error message. +do_test shell2-1.4.12 { + set res [catchcmd :memory: [string trim { + CREATE TABLE "group"("order" text); + INSERT INTO "group" VALUES ('ABC'); +.sha3sum}]] +} {0 ca08bc02b7e95c7df431a3a4b1cc0f8d8743914793473f55b5558e03} + finish_test diff -Nru sqlite3-3.42.0/test/snapshot_fault.test sqlite3-3.44.0-0/test/snapshot_fault.test --- sqlite3-3.42.0/test/snapshot_fault.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/snapshot_fault.test 2023-11-04 14:23:58.000000000 +0000 @@ -23,6 +23,7 @@ # checkpointing the db. # do_faultsim_test 1.0 -prep { + catch { db2 close } faultsim_delete_and_reopen sqlite3 db2 test.db db2 eval { diff -Nru sqlite3-3.42.0/test/sort2.test sqlite3-3.44.0-0/test/sort2.test --- sqlite3-3.42.0/test/sort2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/sort2.test 2023-11-04 14:23:58.000000000 +0000 @@ -69,7 +69,7 @@ # Because it uses so much data, this test can take 12-13 seconds even on # a modern workstation. So it is omitted from "veryquick" and other # permutations.test tests. - if {[isquick]==0} { + if {[isquick]==0 && [clang_sanitize_address]==0} { do_execsql_test $tn.3 { PRAGMA cache_size = 5; WITH r(x,y) AS ( diff -Nru sqlite3-3.42.0/test/speedtest1.c sqlite3-3.44.0-0/test/speedtest1.c --- sqlite3-3.42.0/test/speedtest1.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/speedtest1.c 2023-11-04 14:23:58.000000000 +0000 @@ -21,6 +21,7 @@ " --memdb Use an in-memory database\n" " --mmap SZ MMAP the first SZ bytes of the database file\n" " --multithread Set multithreaded mode\n" + " --nolongdouble Disable the use of long double\n" " --nomemstat Disable memory statistics\n" " --nomutex Open db with SQLITE_OPEN_NOMUTEX\n" " --nosync Set PRAGMA synchronous=OFF\n" @@ -2307,6 +2308,10 @@ ARGC_VALUE_CHECK(1); mmapSize = integerValue(argv[++i]); #endif + }else if( strcmp(z,"nolongdouble")==0 ){ +#ifdef SQLITE_TESTCTRL_USELONGDOUBLE + sqlite3_test_control(SQLITE_TESTCTRL_USELONGDOUBLE, 0); +#endif }else if( strcmp(z,"nomutex")==0 ){ openFlags |= SQLITE_OPEN_NOMUTEX; }else if( strcmp(z,"nosync")==0 ){ diff -Nru sqlite3-3.42.0/test/sqldiff1.test sqlite3-3.44.0-0/test/sqldiff1.test --- sqlite3-3.42.0/test/sqldiff1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/sqldiff1.test 2023-11-04 14:23:58.000000000 +0000 @@ -63,4 +63,26 @@ INSERT INTO t3(rowid,a,b,c) VALUES(1,111,222,333); DROP TABLE t4;} +db close +forcedelete test.db test2.db +sqlite3 db test.db + +do_test sqldiff-2.0 { + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY); + } + db close + sqlite3 db test2.db + db eval { + CREATE TABLE t1(a INTEGER PRIMARY KEY, b); + } + db close + set line "exec $PROG test.db test2.db" + unset -nocomplain ::MSG + catch {eval $line} ::MSG +} {0} +do_test sqldiff-2.1 { + set ::MSG +} {ALTER TABLE t1 ADD COLUMN b;} + finish_test diff -Nru sqlite3-3.42.0/test/statfault.test sqlite3-3.44.0-0/test/statfault.test --- sqlite3-3.42.0/test/statfault.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/statfault.test 2023-11-04 14:23:58.000000000 +0000 @@ -52,4 +52,3 @@ } finish_test - diff -Nru sqlite3-3.42.0/test/subquery.test sqlite3-3.44.0-0/test/subquery.test --- sqlite3-3.42.0/test/subquery.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/subquery.test 2023-11-04 14:23:58.000000000 +0000 @@ -11,8 +11,6 @@ # This file implements regression tests for SQLite library. The # focus of this script is testing correlated subqueries # -# $Id: subquery.test,v 1.17 2009/01/09 01:12:28 drh Exp $ -# set testdir [file dirname $argv0] source $testdir/tester.tcl @@ -613,4 +611,45 @@ SELECT (SELECT DISTINCT x FROM t1 ORDER BY +x LIMIT 1 OFFSET 2) FROM t1; } {{} {} {} {}} +# 2023-09-15 +# Query planner performance regression reported by private email +# on 2023-09-14, caused by VIEWSCAN optimization of check-in 609fbb94b8f01d67 +# from 2022-09-01. +# +reset_db +do_execsql_test subquery-10.1 { + CREATE TABLE t1(aa TEXT, bb INT, cc TEXT); + CREATE INDEX x11 on t1(bb); + CREATE INDEX x12 on t1(aa); + CREATE TABLE t2(aa TEXT, xx INT); + ANALYZE sqlite_master; + INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES('t1', 'x11', '156789 28'); + INSERT INTO sqlite_stat1(tbl, idx, stat) VALUES('t1', 'x12', '156789 1'); + ANALYZE sqlite_master; +} +do_eqp_test subquery-10.2 { + WITH v1(aa,cc,bb) AS (SELECT aa, cc, bb FROM t1 WHERE bb=12345), + v2(aa,mx) AS (SELECT aa, max(xx) FROM t2 GROUP BY aa) + SELECT * FROM v1 JOIN v2 ON v1.aa=v2.aa; +} { + QUERY PLAN + |--CO-ROUTINE v2 + | |--SCAN t2 + | `--USE TEMP B-TREE FOR GROUP BY + |--SEARCH t1 USING INDEX x11 (bb=?) + `--SEARCH v2 USING AUTOMATIC COVERING INDEX (aa=?) +} +# ^^^^^^^^^^^^^ +# Prior to the fix the incorrect (slow) plan caused by the +# VIEWSCAN optimization was: +# +# QUERY PLAN +# |--CO-ROUTINE v2 +# | |--SCAN t2 +# | `--USE TEMP B-TREE FOR GROUP BY +# |--SCAN v2 +# `--SEARCH t1 USING INDEX x12 (aa=?) +# + + finish_test diff -Nru sqlite3-3.42.0/test/table.test sqlite3-3.44.0-0/test/table.test --- sqlite3-3.42.0/test/table.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/table.test 2023-11-04 14:23:58.000000000 +0000 @@ -784,13 +784,13 @@ } {1 {unknown function: count()}} do_catchsql_test table-16.6 { DROP TABLE t16; - CREATE TABLE t16(x DEFAULT(group_concat('x',','))); + CREATE TABLE t16(x DEFAULT(string_agg('x',','))); INSERT INTO t16(rowid) VALUES(123); SELECT rowid, x FROM t16; -} {1 {unknown function: group_concat()}} +} {1 {unknown function: string_agg()}} do_catchsql_test table-16.7 { INSERT INTO t16 DEFAULT VALUES; -} {1 {unknown function: group_concat()}} +} {1 {unknown function: string_agg()}} # Ticket [https://www.sqlite.org/src/info/094d39a4c95ee4abbc417f04214617675ba15c63] # describes a assertion fault that occurs on a CREATE TABLE .. AS SELECT statement. diff -Nru sqlite3-3.42.0/test/testrunner_data.tcl sqlite3-3.44.0-0/test/testrunner_data.tcl --- sqlite3-3.42.0/test/testrunner_data.tcl 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/testrunner_data.tcl 2023-11-04 14:23:58.000000000 +0000 @@ -5,6 +5,7 @@ variable tcltest variable extra variable all_configs + variable build # Tcl tests to run for various builds. @@ -35,6 +36,7 @@ set tcltest(win.Have-Not) veryquick set tcltest(win.Windows-Memdebug) veryquick set tcltest(win.Windows-Win32Heap) veryquick + set tcltest(win.Windows-Sanitize) veryquick set tcltest(win.Default) full # Extra [make xyz] tests that should be run for various builds. @@ -63,6 +65,7 @@ set extra(win.Stdcall) {fuzztest sourcetest} set extra(win.Windows-Memdebug) {fuzztest sourcetest} set extra(win.Windows-Win32Heap) {fuzztest sourcetest} + set extra(win.Windows-Sanitize) fuzztest set extra(win.Have-Not) {fuzztest sourcetest} # The following mirrors the set of test suites invoked by "all.test". @@ -75,6 +78,251 @@ inmemory_journal pcache0 pcache10 pcache50 pcache90 pcache100 prepare mmap } + + #----------------------------------------------------------------------- + # Start of build() definitions. + # + set build(Default) { + -O2 + --disable-amalgamation --disable-shared + --enable-session + -DSQLITE_ENABLE_RBU + } + + # These two are used by [testrunner.tcl mdevtest] (All-O0) and + # [testrunner.tcl sdevtest] (All-Sanitize). + # + set build(All-Debug) { + --enable-debug --enable-all + } + set build(All-O0) { + -O0 --enable-all + } + set build(All-Sanitize) { + -DSQLITE_OMIT_LOOKASIDE=1 + --enable-all -fsanitize=address,undefined + } + + set build(Sanitize) { + CC=clang -fsanitize=address,undefined + -DSQLITE_ENABLE_STAT4 + -DSQLITE_OMIT_LOOKASIDE=1 + -DCONFIG_SLOWDOWN_FACTOR=5.0 + --enable-debug + --enable-all + } + set build(Stdcall) { + -DUSE_STDCALL=1 + -O2 + } + + # The "Have-Not" configuration sets all possible -UHAVE_feature options + # in order to verify that the code works even on platforms that lack + # these support services. + set build(Have-Not) { + -DHAVE_FDATASYNC=0 + -DHAVE_GMTIME_R=0 + -DHAVE_ISNAN=0 + -DHAVE_LOCALTIME_R=0 + -DHAVE_LOCALTIME_S=0 + -DHAVE_MALLOC_USABLE_SIZE=0 + -DHAVE_STRCHRNUL=0 + -DHAVE_USLEEP=0 + -DHAVE_UTIME=0 + } + set build(Unlock-Notify) { + -O2 + -DSQLITE_ENABLE_UNLOCK_NOTIFY + -DSQLITE_THREADSAFE + -DSQLITE_TCL_DEFAULT_FULLMUTEX=1 + } + set build(User-Auth) { + -O2 + -DSQLITE_USER_AUTHENTICATION=1 + } + set build(Secure-Delete) { + -O2 + -DSQLITE_SECURE_DELETE=1 + -DSQLITE_SOUNDEX=1 + } + set build(Update-Delete-Limit) { + -O2 + -DSQLITE_DEFAULT_FILE_FORMAT=4 + -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 + -DSQLITE_ENABLE_STMT_SCANSTATUS + -DSQLITE_LIKE_DOESNT_MATCH_BLOBS + -DSQLITE_ENABLE_CURSOR_HINTS + } + set build(Check-Symbols) { + -DSQLITE_MEMDEBUG=1 + -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 + -DSQLITE_ENABLE_FTS3=1 + -DSQLITE_ENABLE_RTREE=1 + -DSQLITE_ENABLE_MEMSYS5=1 + -DSQLITE_ENABLE_MEMSYS3=1 + -DSQLITE_ENABLE_COLUMN_METADATA=1 + -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 + -DSQLITE_SECURE_DELETE=1 + -DSQLITE_SOUNDEX=1 + -DSQLITE_ENABLE_ATOMIC_WRITE=1 + -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 + -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1 + -DSQLITE_ENABLE_STAT4 + -DSQLITE_ENABLE_STMT_SCANSTATUS + --enable-fts5 --enable-session + } + set build(Debug-One) { + --disable-shared + -O2 -funsigned-char + -DSQLITE_DEBUG=1 + -DSQLITE_MEMDEBUG=1 + -DSQLITE_MUTEX_NOOP=1 + -DSQLITE_TCL_DEFAULT_FULLMUTEX=1 + -DSQLITE_ENABLE_FTS3=1 + -DSQLITE_ENABLE_RTREE=1 + -DSQLITE_ENABLE_MEMSYS5=1 + -DSQLITE_ENABLE_COLUMN_METADATA=1 + -DSQLITE_ENABLE_STAT4 + -DSQLITE_ENABLE_HIDDEN_COLUMNS + -DSQLITE_MAX_ATTACHED=125 + -DSQLITE_MUTATION_TEST + --enable-fts5 + } + set build(Debug-Two) { + -DSQLITE_DEFAULT_MEMSTATUS=0 + -DSQLITE_MAX_EXPR_DEPTH=0 + --enable-debug + } + set build(Fast-One) { + -O6 + -DSQLITE_ENABLE_FTS4=1 + -DSQLITE_ENABLE_RTREE=1 + -DSQLITE_ENABLE_STAT4 + -DSQLITE_ENABLE_RBU + -DSQLITE_MAX_ATTACHED=125 + -DSQLITE_MAX_MMAP_SIZE=12884901888 + -DSQLITE_ENABLE_SORTER_MMAP=1 + -DLONGDOUBLE_TYPE=double + --enable-session + } + set build(Device-One) { + -O2 + -DSQLITE_DEBUG=1 + -DSQLITE_DEFAULT_AUTOVACUUM=1 + -DSQLITE_DEFAULT_CACHE_SIZE=64 + -DSQLITE_DEFAULT_PAGE_SIZE=1024 + -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=32 + -DSQLITE_DISABLE_LFS=1 + -DSQLITE_ENABLE_ATOMIC_WRITE=1 + -DSQLITE_ENABLE_IOTRACE=1 + -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 + -DSQLITE_MAX_PAGE_SIZE=4096 + -DSQLITE_OMIT_LOAD_EXTENSION=1 + -DSQLITE_OMIT_PROGRESS_CALLBACK=1 + -DSQLITE_OMIT_VIRTUALTABLE=1 + -DSQLITE_ENABLE_HIDDEN_COLUMNS + -DSQLITE_TEMP_STORE=3 + } + set build(Device-Two) { + -DSQLITE_4_BYTE_ALIGNED_MALLOC=1 + -DSQLITE_DEFAULT_AUTOVACUUM=1 + -DSQLITE_DEFAULT_CACHE_SIZE=1000 + -DSQLITE_DEFAULT_LOCKING_MODE=0 + -DSQLITE_DEFAULT_PAGE_SIZE=1024 + -DSQLITE_DEFAULT_TEMP_CACHE_SIZE=1000 + -DSQLITE_DISABLE_LFS=1 + -DSQLITE_ENABLE_FTS3=1 + -DSQLITE_ENABLE_MEMORY_MANAGEMENT=1 + -DSQLITE_ENABLE_RTREE=1 + -DSQLITE_MAX_COMPOUND_SELECT=50 + -DSQLITE_MAX_PAGE_SIZE=32768 + -DSQLITE_OMIT_TRACE=1 + -DSQLITE_TEMP_STORE=3 + -DSQLITE_THREADSAFE=2 + --enable-fts5 --enable-session + } + set build(Locking-Style) { + -O2 + -DSQLITE_ENABLE_LOCKING_STYLE=1 + } + set build(Apple) { + -Os + -DHAVE_GMTIME_R=1 + -DHAVE_ISNAN=1 + -DHAVE_LOCALTIME_R=1 + -DHAVE_PREAD=1 + -DHAVE_PWRITE=1 + -DHAVE_UTIME=1 + -DSQLITE_DEFAULT_CACHE_SIZE=1000 + -DSQLITE_DEFAULT_CKPTFULLFSYNC=1 + -DSQLITE_DEFAULT_MEMSTATUS=1 + -DSQLITE_DEFAULT_PAGE_SIZE=1024 + -DSQLITE_DISABLE_PAGECACHE_OVERFLOW_STATS=1 + -DSQLITE_ENABLE_API_ARMOR=1 + -DSQLITE_ENABLE_AUTO_PROFILE=1 + -DSQLITE_ENABLE_FLOCKTIMEOUT=1 + -DSQLITE_ENABLE_FTS3=1 + -DSQLITE_ENABLE_FTS3_PARENTHESIS=1 + -DSQLITE_ENABLE_FTS3_TOKENIZER=1 + -DSQLITE_ENABLE_PERSIST_WAL=1 + -DSQLITE_ENABLE_PURGEABLE_PCACHE=1 + -DSQLITE_ENABLE_RTREE=1 + -DSQLITE_ENABLE_SNAPSHOT=1 + -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT=1 + -DSQLITE_MAX_LENGTH=2147483645 + -DSQLITE_MAX_VARIABLE_NUMBER=500000 + -DSQLITE_NO_SYNC=1 + -DSQLITE_OMIT_AUTORESET=1 + -DSQLITE_OMIT_LOAD_EXTENSION=1 + -DSQLITE_PREFER_PROXY_LOCKING=1 + -DSQLITE_SERIES_CONSTRAINT_VERIFY=1 + -DSQLITE_THREADSAFE=2 + -DSQLITE_USE_URI=1 + -DSQLITE_WRITE_WALFRAME_PREBUFFERED=1 + -DUSE_GUARDED_FD=1 + -DUSE_PREAD=1 + --enable-fts5 + } + set build(Extra-Robustness) { + -DSQLITE_ENABLE_OVERSIZE_CELL_CHECK=1 + -DSQLITE_MAX_ATTACHED=62 + } + set build(Devkit) { + -DSQLITE_DEFAULT_FILE_FORMAT=4 + -DSQLITE_MAX_ATTACHED=30 + -DSQLITE_ENABLE_COLUMN_METADATA + -DSQLITE_ENABLE_FTS4 + -DSQLITE_ENABLE_FTS5 + -DSQLITE_ENABLE_FTS4_PARENTHESIS + -DSQLITE_DISABLE_FTS4_DEFERRED + -DSQLITE_ENABLE_RTREE + --enable-fts5 + } + set build(No-lookaside) { + -DSQLITE_TEST_REALLOC_STRESS=1 + -DSQLITE_OMIT_LOOKASIDE=1 + } + set build(Valgrind) { + -DSQLITE_ENABLE_STAT4 + -DSQLITE_ENABLE_FTS4 + -DSQLITE_ENABLE_RTREE + -DSQLITE_ENABLE_HIDDEN_COLUMNS + -DLONGDOUBLE_TYPE=double + -DCONFIG_SLOWDOWN_FACTOR=8.0 + } + + set build(Windows-Memdebug) { + MEMDEBUG=1 + DEBUG=3 + } + set build(Windows-Win32Heap) { + WIN32HEAP=1 + DEBUG=4 + } + set build(Windows-Sanitize) { + ASAN=1 + } + } @@ -84,6 +332,7 @@ variable ::trd::tcltest variable ::trd::extra variable ::trd::all_configs + variable ::trd::build } } @@ -106,13 +355,13 @@ set ret } -proc trd_configs {platform build} { +proc trd_configs {platform bld} { trd_import set clist [list] - if {[info exists tcltest($platform.$build)]} { - set clist $tcltest($platform.$build) + if {[info exists tcltest($platform.$bld)]} { + set clist $tcltest($platform.$bld) if {$clist=="all"} { set clist $all_configs } elseif {$clist=="all_plus_autovacuum_crash"} { @@ -123,21 +372,265 @@ set clist } -proc trd_extras {platform build} { +proc trd_extras {platform bld} { trd_import + if {[info exists extra($platform.$bld)]==0} { return [list] } + return $extra($platform.$bld) +} + +# Usage: +# +# trd_fuzztest_data +# +# This returns data used by testrunner.tcl to run commands equivalent +# to [make fuzztest]. The returned value is a list, which should be +# interpreted as a sequence of pairs. The first element of each pair +# is an interpreter name. The second element is a list of files. +# testrunner.tcl automatically creates one job to build each interpreter, +# and one to run each of the files with it once it has been built. +# +# In practice, the returned value looks like this: +# +# { +# {fuzzcheck {$testdir/fuzzdata1.db $testdir/fuzzdata2.db ...}} +# {{sessionfuzz run} $testdir/sessionfuzz-data1.db} +# } +# +# where $testdir is replaced by the full-path to the test-directory (the +# directory containing this file). "fuzzcheck" and "sessionfuzz" have .exe +# extensions on windows. +# +proc trd_fuzztest_data {} { + set EXE "" + set lFuzzDb [glob [file join $::testdir fuzzdata*.db]] + set lSessionDb [glob [file join $::testdir sessionfuzz-data*.db]] - set elist [list] - if {[info exists extra($platform.$build)]} { - set elist $extra($platform.$build) + if {$::tcl_platform(platform)=="windows"} { + return [list fuzzcheck.exe $lFuzzDb] } - set elist + return [list fuzzcheck $lFuzzDb {sessionfuzz run} $lSessionDb] } + proc trd_all_configs {} { trd_import set all_configs } +proc trimscript {text} { + set text [string map {"\n " "\n"} [string trim $text]] +} + +proc make_sh_script {srcdir opts cflags makeOpts configOpts} { + + set tcldir [::tcl::pkgconfig get libdir,install] + set myopts "" + if {[info exists ::env(OPTS)]} { + append myopts "# From environment variable:\n" + append myopts "OPTS=$::env(OPTS)\n\n" + } + foreach o [lsort $opts] { + append myopts "OPTS=\"\$OPTS $o\"\n" + } + + return [trimscript [subst -nocommands { + set -e + if [ "\$#" -ne 1 ] ; then + echo "Usage: \$0 " + exit -1 + fi + + SRCDIR="$srcdir" + TCLDIR="$tcldir" + + if [ ! -f Makefile ] ; then + \$SRCDIR/configure --with-tcl=\$TCL $configOpts + fi + + $myopts + CFLAGS="$cflags" + + make \$1 "CFLAGS=\$CFLAGS" "OPTS=\$OPTS" $makeOpts + }]] +} + +# Generate the text of a *.bat script. +# +proc make_bat_file {srcdir opts cflags makeOpts} { + set srcdir [file nativename [file normalize $srcdir]] + + return [trimscript [subst -nocommands { + set TARGET=%1 + set TMP=%CD% + nmake /f $srcdir\\Makefile.msc TOP="$srcdir" %TARGET% "CCOPTS=$cflags" "OPTS=$opts" $makeOpts + }]] +} + + +# Generate the text of a shell script. +# +proc make_script {cfg srcdir bMsvc} { + set opts [list] ;# OPTS value + set cflags [expr {$bMsvc ? "-Zi" : "-g"}] ;# CFLAGS value + set makeOpts [list] ;# Extra args for [make] + set configOpts [list] ;# Extra args for [configure] + + # Define either SQLITE_OS_WIN or SQLITE_OS_UNIX, as appropriate. + if {$::tcl_platform(platform)=="windows"} { + lappend opts -DSQLITE_OS_WIN=1 + } else { + lappend opts -DSQLITE_OS_UNIX=1 + } + + # Unless the configuration specifies -DHAVE_USLEEP=0, set -DHAVE_USLEEP=1. + # + if {[lsearch $cfg "-DHAVE_USLEEP=0"]<0} { + lappend cfg -DHAVE_USLEEP=1 + } + # Loop through the parameters of the nominated configuration, updating + # $opts, $cflags, $makeOpts and $configOpts along the way. Rules are as + # follows: + # + # 1. If the parameter begins with "-D", add it to $opts. + # + # 2. If the parameter begins with "--" add it to $configOpts. Unless + # this command is preparing a script for MSVC - then add an + # equivalent to $makeOpts or $opts. + # + # 3. If the parameter begins with "-" add it to $cflags. If in MSVC + # mode and the parameter is an -O option, instead add + # an OPTIMIZATIONS= switch to $makeOpts. + # + # 4. If none of the above apply, add the parameter to $makeOpts + # + foreach param $cfg { + + if {[string range $param 0 1]=="-D"} { + lappend opts $param + continue + } + + if {[string range $param 0 1]=="--"} { + if {$bMsvc==0} { + lappend configOpts $param + } else { + + switch -- $param { + --disable-amalgamation { + lappend makeOpts USE_AMALGAMATION=0 + } + --disable-shared { + lappend makeOpts USE_CRT_DLL=0 DYNAMIC_SHELL=0 + } + --enable-fts5 { + lappend opts -DSQLITE_ENABLE_FTS5 + } + --enable-shared { + lappend makeOpts USE_CRT_DLL=1 DYNAMIC_SHELL=1 + } + --enable-session { + lappend opts -DSQLITE_ENABLE_PREUPDATE_HOOK + lappend opts -DSQLITE_ENABLE_SESSION + } + --enable-all { + } + --enable-debug { + # lappend makeOpts OPTIMIZATIONS=0 + lappend opts -DSQLITE_DEBUG + } + default { + error "Cannot translate $param for MSVC" + } + } + } + + continue + } + + if {[string range $param 0 0]=="-"} { + + if {$bMsvc} { + if {[regexp -- {^-O(\d+)$} $param -> level]} { + lappend makeOpts OPTIMIZATIONS=$level + continue + } + if {$param eq "-fsanitize=address,undefined"} { + lappend makeOpts ASAN=1 + continue + } + } + + lappend cflags $param + continue + } + + lappend makeOpts $param + } + + if {$bMsvc==0} { + set zRet [make_sh_script $srcdir $opts $cflags $makeOpts $configOpts] + } else { + set zRet [make_bat_file $srcdir $opts $cflags $makeOpts] + } +} + +# Usage: +# +# trd_buildscript CONFIG SRCDIR MSVC +# +# This command returns the full text of a script (either a shell script or +# an ms-dos bat file) that may be used to build SQLite source code according +# to a nominated configuration. +# +# Parameter CONFIG must be a configuration defined above in the ::trd::build +# array. SRCDIR is the root directory of an SQLite source tree (the parent +# directory of that containing this script). MSVC is a boolean - true to +# use the MSVC compiler, false otherwise. +# +proc trd_buildscript {config srcdir bMsvc} { + trd_import + + # Ensure that the named configuration exists. + if {![info exists build($config)]} { + error "No such build config: $config" + } + + # Generate and return the script. + return [make_script $build($config) $srcdir $bMsvc] +} + +# Usage: +# +# trd_test_script_properties PATH +# +# The argument must be a path to a Tcl test script. This function scans the +# first 100 lines of the script for lines that look like: +# +# TESTRUNNER: +# +# where is a list of identifiers, each of which defines a +# property of the test script. Example properties are "slow" or "superslow". +# +proc trd_test_script_properties {path} { + # Use this global array as a cache: + global trd_test_script_properties_cache + + if {![info exists trd_test_script_properties_cache($path)]} { + set fd [open $path] + set ret [list] + for {set line 0} {$line < 100 && ![eof $fd]} {incr line} { + set text [gets $fd] + if {[string match -nocase *testrunner:* $text]} { + regexp -nocase {.*testrunner:(.*)} $text -> properties + lappend ret {*}$properties + } + } + set trd_test_script_properties_cache($path) $ret + close $fd + } + + set trd_test_script_properties_cache($path) +} diff -Nru sqlite3-3.42.0/test/testrunner.tcl sqlite3-3.44.0-0/test/testrunner.tcl --- sqlite3-3.42.0/test/testrunner.tcl 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/testrunner.tcl 2023-11-04 14:23:58.000000000 +0000 @@ -1,6 +1,6 @@ set dir [pwd] -set testdir [file dirname $argv0] +set testdir [file normalize [file dirname $argv0]] set saved $argv set argv [list] source [file join $testdir testrunner_data.tcl] @@ -8,6 +8,42 @@ set argv $saved cd $dir +# This script requires an interpreter that supports [package require sqlite3] +# to run. If this is not such an intepreter, see if there is a [testfixture] +# in the current directory. If so, run the command using it. If not, +# recommend that the user build one. +# +proc find_interpreter {} { + set interpreter [file tail [info nameofexec]] + set rc [catch { package require sqlite3 }] + if {$rc} { + if { [string match -nocase testfixture* $interpreter]==0 + && [file executable ./testfixture] + } { + puts "Failed to find tcl package sqlite3. Restarting with ./testfixture.." + set status [catch { + exec ./testfixture [info script] {*}$::argv >@ stdout + } msg] + exit $status + } + } + if {$rc} { + puts stderr "Failed to find tcl package sqlite3" + puts stderr "Run \"make testfixture\" and then try again..." + exit 1 + } +} +find_interpreter + +# Usually this script is run by [testfixture]. But it can also be run +# by a regular [tclsh]. For these cases, emulate the [clock_milliseconds] +# command. +if {[info commands clock_milliseconds]==""} { + proc clock_milliseconds {} { + clock milliseconds + } +} + #------------------------------------------------------------------------- # Usage: # @@ -23,7 +59,6 @@ where SWITCHES are: --jobs NUMBER-OF-JOBS - --fuzztest --zipvfs ZIPVFS-SOURCE-DIR Interesting values for PERMUTATION are: @@ -47,11 +82,6 @@ instead of a list of patterns, then that single Tcl test script is run with the specified permutation. -The --fuzztest option is ignored if the PERMUTATION is "release". Otherwise, -if it is present, then "make -C fuzztest" is run as part of the tests, -where is the directory containing the testfixture binary used to -run the script. - The "status" and "njob" commands are designed to be run from the same directory as a running testrunner.tcl script that is running tests. The "status" command prints a report describing the current state and progress @@ -74,16 +104,20 @@ if {[catch {number_of_cores} ret]} { set ret 4 - if {$::tcl_platform(os)=="Darwin"} { - set cmd "sysctl -n hw.logicalcpu" + if {$::tcl_platform(platform)=="windows"} { + catch { set ret $::env(NUMBER_OF_PROCESSORS) } } else { - set cmd "nproc" - } - catch { - set fd [open "|$cmd" r] - set ret [gets $fd] - close $fd - set ret [expr $ret] + if {$::tcl_platform(os)=="Darwin"} { + set cmd "sysctl -n hw.logicalcpu" + } else { + set cmd "nproc" + } + catch { + set fd [open "|$cmd" r] + set ret [gets $fd] + close $fd + set ret [expr $ret] + } } } return $ret @@ -117,19 +151,28 @@ switch -nocase -glob -- $tcl_platform(os) { *darwin* { - set TRG(platform) osx - set TRG(make) make.sh - set TRG(makecmd) "bash make.sh" + set TRG(platform) osx + set TRG(make) make.sh + set TRG(makecmd) "bash make.sh" + set TRG(testfixture) testfixture + set TRG(run) run.sh + set TRG(runcmd) "bash run.sh" } *linux* { - set TRG(platform) linux - set TRG(make) make.sh - set TRG(makecmd) "bash make.sh" + set TRG(platform) linux + set TRG(make) make.sh + set TRG(makecmd) "bash make.sh" + set TRG(testfixture) testfixture + set TRG(run) run.sh + set TRG(runcmd) "bash run.sh" } *win* { - set TRG(platform) win - set TRG(make) make.bat - set TRG(makecmd) make.bat + set TRG(platform) win + set TRG(make) make.bat + set TRG(makecmd) make.bat + set TRG(testfixture) testfixture.exe + set TRG(run) run.bat + set TRG(runcmd) "run.bat" } default { error "cannot determine platform!" @@ -141,22 +184,59 @@ # The database schema used by the testrunner.db database. # set TRG(schema) { - DROP TABLE IF EXISTS script; + DROP TABLE IF EXISTS jobs; DROP TABLE IF EXISTS config; - CREATE TABLE script( - build TEXT DEFAULT '', - config TEXT, - filename TEXT, -- full path to test script - slow BOOLEAN, -- true if script is "slow" + /* + ** This table contains one row for each job that testrunner.tcl must run + ** before the entire test run is finished. + ** + ** jobid: + ** Unique identifier for each job. Must be a +ve non-zero number. + ** + ** displaytype: + ** 3 or 4 letter mnemonic for the class of tests this belongs to e.g. + ** "fuzz", "tcl", "make" etc. + ** + ** displayname: + ** Name/description of job. For display purposes. + ** + ** build: + ** If the job requires a make.bat/make.sh make wrapper (i.e. to build + ** something), the name of the build configuration it uses. See + ** testrunner_data.tcl for a list of build configs. e.g. "Win32-MemDebug". + ** + ** dirname: + ** If the job should use a well-known directory name for its + ** sub-directory instead of an anonymous "testdir[1234...]" sub-dir + ** that is deleted after the job is finished. + ** + ** cmd: + ** Bash or batch script to run the job. + ** + ** depid: + ** The jobid value of a job that this job depends on. This job may not + ** be run before its depid job has finished successfully. + ** + ** priority: + ** Higher values run first. Sometimes. + */ + CREATE TABLE jobs( + /* Fields populated when db is initialized */ + jobid INTEGER PRIMARY KEY, -- id to identify job + displaytype TEXT NOT NULL, -- Type of test (for one line report) + displayname TEXT NOT NULL, -- Human readable job name + build TEXT NOT NULL DEFAULT '', -- make.sh/make.bat file request, if any + dirname TEXT NOT NULL DEFAULT '', -- directory name, if required + cmd TEXT NOT NULL, -- shell command to run + depid INTEGER, -- identifier of dependency (or '') + priority INTEGER NOT NULL, -- higher priority jobs may run earlier + + /* Fields updated as jobs run */ + starttime INTEGER, + endtime INTEGER, state TEXT CHECK( state IN ('', 'ready', 'running', 'done', 'failed') ), - time INTEGER, -- Time in ms - output TEXT, -- full output of test script - priority AS ((config='make') + ((config='build')*2) + (slow*4)), - jobtype AS ( - CASE WHEN config IN ('build', 'make') THEN config ELSE 'script' END - ), - PRIMARY KEY(build, config, filename) + output TEXT ); CREATE TABLE config( @@ -164,8 +244,8 @@ value ) WITHOUT ROWID; - CREATE INDEX i1 ON script(state, jobtype); - CREATE INDEX i2 ON script(state, priority); + CREATE INDEX i1 ON jobs(state, priority); + CREATE INDEX i2 ON jobs(depid); } #------------------------------------------------------------------------- @@ -181,10 +261,11 @@ set script [file normalize [lindex $argv 1]] set ::argv [list] + set testdir [file dirname $argv0] + source $::testdir/tester.tcl + if {$permutation=="full"} { - set testdir [file dirname $argv0] - source $::testdir/tester.tcl unset -nocomplain ::G(isquick) reset_db @@ -242,45 +323,36 @@ #-------------------------------------------------------------------------- #-------------------------------------------------------------------------- +# Check if this is the "script" command: +# +if {[string compare -nocase script [lindex $argv 0]]==0} { + if {[llength $argv]!=2 && !([llength $argv]==3&&[lindex $argv 1]=="-msvc")} { + usage + } + + set bMsvc [expr ([llength $argv]==3)] + set config [lindex $argv [expr [llength $argv]-1]] + + puts [trd_buildscript $config [file dirname $testdir] $bMsvc] + exit +} + + +#-------------------------------------------------------------------------- # Check if this is the "status" command: # if {[llength $argv]==1 && [string compare -nocase status [lindex $argv 0]]==0 } { - proc display_job {build config filename {tm ""}} { - if {$config=="build"} { - set fname "build: $filename" - set config "" - } elseif {$config=="make"} { - set fname "make: $filename" - set config "" - } else { - set fname [file normalize $filename] - if {[string first $::srcdir $fname]==0} { - set fname [string range $fname [string length $::srcdir]+1 end] - } - } - set dfname [format %-33s $fname] + proc display_job {jobdict {tm ""}} { + array set job $jobdict + + set dfname [format %-60s $job(displayname)] - set dbuild "" - set dconfig "" - set dparams "" set dtm "" - if {$build!=""} { set dbuild $build } - if {$config!="" && $config!="full"} { set dconfig $config } - if {$dbuild!="" || $dconfig!=""} { - append dparams "(" - if {$dbuild!=""} {append dparams "build=$dbuild"} - if {$dbuild!="" && $dconfig!=""} {append dparams " "} - if {$dconfig!=""} {append dparams "config=$dconfig"} - append dparams ")" - set dparams [format %-33s $dparams] - } - if {$tm!=""} { - set dtm "\[${tm}ms\]" - } - puts " $dfname $dparams $dtm" + if {$tm!=""} { set dtm "\[[expr {$tm-$job(starttime)}]ms\]" } + puts " $dfname $dtm" } sqlite3 mydb $TRG(dbname) @@ -289,14 +361,18 @@ set cmdline [mydb one { SELECT value FROM config WHERE name='cmdline' }] set nJob [mydb one { SELECT value FROM config WHERE name='njob' }] - set tm [expr [clock_milliseconds] - [mydb one { - SELECT value FROM config WHERE name='start' - }]] + + set now [clock_milliseconds] + set tm [mydb one { + SELECT + COALESCE((SELECT value FROM config WHERE name='end'), $now) - + (SELECT value FROM config WHERE name='start') + }] set total 0 foreach s {"" ready running done failed} { set S($s) 0 } mydb eval { - SELECT state, count(*) AS cnt FROM script GROUP BY 1 + SELECT state, count(*) AS cnt FROM jobs GROUP BY 1 } { incr S($state) $cnt incr total $cnt @@ -315,21 +391,18 @@ set srcdir [file dirname [file dirname $TRG(info_script)]] if {$S(running)>0} { puts "Running: " - set now [clock_milliseconds] mydb eval { - SELECT build, config, filename, time FROM script WHERE state='running' - ORDER BY time - } { - display_job $build $config $filename [expr $now-$time] + SELECT * FROM jobs WHERE state='running' ORDER BY starttime + } job { + display_job [array get job] $now } } if {$S(failed)>0} { puts "Failures: " mydb eval { - SELECT build, config, filename FROM script WHERE state='failed' - ORDER BY 3 - } { - display_job $build $config $filename + SELECT * FROM jobs WHERE state='failed' ORDER BY starttime + } job { + display_job [array get job] } } @@ -350,8 +423,6 @@ incr ii set TRG(nJob) [lindex $argv $ii] if {$isLast} { usage } - } elseif {($n>2 && [string match "$a*" --fuzztest]) || $a=="-f"} { - set TRG(fuzztest) 1 } elseif {($n>2 && [string match "$a*" --zipvfs]) || $a=="-z"} { incr ii set TRG(zipvfs) [lindex $argv $ii] @@ -411,8 +482,6 @@ return $iRet } -set testdir [file dirname $argv0] - # Check that directory $dir exists. If it does not, create it. If # it does, delete its contents. # @@ -424,89 +493,141 @@ } } -proc copy_dir {from to} { - foreach f [glob -nocomplain [file join $from *]] { - catch { file copy -force $f $to } - } -} - proc build_to_dirname {bname} { set fold [string tolower [string map {- _} $bname]] return "testrunner_build_$fold" } #------------------------------------------------------------------------- -# Return a list of tests to run. Each element of the list is itself a -# list of two elements - the name of a permuations.test configuration -# followed by the full path to a test script. i.e.: + +proc r_write_db {tcl} { + trdb eval { BEGIN EXCLUSIVE } + uplevel $tcl + trdb eval { COMMIT } +} + +# Obtain a new job to be run by worker $iJob (an integer). A job is +# returned as a three element list: # -# {BUILD CONFIG FILENAME} {BUILD CONFIG FILENAME} ... +# {$build $config $file} # -proc testset_patternlist {patternlist} { - global TRG +proc r_get_next_job {iJob} { + global T - set testset [list] ;# return value + if {($iJob%2)} { + set orderby "ORDER BY priority ASC" + } else { + set orderby "ORDER BY priority DESC" + } - set first [lindex $patternlist 0] + set ret [list] - if {$first=="release"} { - set platform $::TRG(platform) + r_write_db { + set query " + SELECT * FROM jobs AS j WHERE state='ready' $orderby LIMIT 1 + " + trdb eval $query job { + set tm [clock_milliseconds] + set T($iJob) $tm + set jobid $job(jobid) - set patternlist [lrange $patternlist 1 end] - foreach b [trd_builds $platform] { - foreach c [trd_configs $platform $b] { - testset_append testset $b $c $patternlist + trdb eval { + UPDATE jobs SET starttime=$tm, state='running' WHERE jobid=$jobid } - if {[llength $patternlist]==0 || $b=="User-Auth"} { - set target testfixture - } else { - set target coretestprogs - } - lappend testset [list $b build $target] + set ret [array get job] } + } - if {[llength $patternlist]==0} { - foreach b [trd_builds $platform] { - foreach e [trd_extras $platform $b] { - lappend testset [list $b make $e] - } - } - } + return $ret +} - set TRG(fuzztest) 0 ;# ignore --fuzztest option in this case +#rename r_get_next_job r_get_next_job_r +#proc r_get_next_job {iJob} { + #puts [time { set res [r_get_next_job_r $iJob] }] + #set res +#} - } elseif {$first=="all"} { +# Usage: +# +# add_job OPTION ARG OPTION ARG... +# +# where available OPTIONS are: +# +# -displaytype +# -displayname +# -build +# -dirname +# -cmd +# -depid +# -priority +# +# Returns the jobid value for the new job. +# +proc add_job {args} { - set clist [trd_all_configs] - set patternlist [lrange $patternlist 1 end] - foreach c $clist { - testset_append testset "" $c $patternlist - } + set options { + -displaytype -displayname -build -dirname + -cmd -depid -priority + } - } elseif {[info exists ::testspec($first)]} { - set clist $first - testset_append testset "" $first [lrange $patternlist 1 end] - } elseif { [llength $patternlist]==0 } { - testset_append testset "" veryquick $patternlist - } else { - testset_append testset "" full $patternlist + # Set default values of options. + set A(-dirname) "" + set A(-depid) "" + set A(-priority) 0 + set A(-build) "" + + array set A $args + + # Check all required options are present. And that no extras are present. + foreach o $options { + if {[info exists A($o)]==0} { error "missing required option $o" } } - if {$TRG(fuzztest)} { - if {$TRG(platform)=="win"} { error "todo" } - lappend testset [list "" make fuzztest] + foreach o [array names A] { + if {[lsearch -exact $options $o]<0} { error "unrecognized option: $o" } } - set testset + set state "" + if {$A(-depid)==""} { set state ready } + + trdb eval { + INSERT INTO jobs( + displaytype, displayname, build, dirname, cmd, depid, priority, + state + ) VALUES ( + $A(-displaytype), + $A(-displayname), + $A(-build), + $A(-dirname), + $A(-cmd), + $A(-depid), + $A(-priority), + $state + ) + } + + trdb last_insert_rowid } -proc testset_append {listvar build config patternlist} { - upvar $listvar lvar +proc add_tcl_jobs {build config patternlist} { + global TRG - catch { array unset O } - array set O $::testspec($config) + set topdir [file dirname $::testdir] + set testrunner_tcl [file normalize [info script]] + + if {$build==""} { + set testfixture [info nameofexec] + } else { + set testfixture [file join [lindex $build 1] $TRG(testfixture)] + } + if {[lindex $build 2]=="Valgrind"} { + set setvar "export OMIT_MISUSE=1\n" + set testfixture "${setvar}valgrind -v --error-exitcode=1 $testfixture" + } + + # The ::testspec array is populated by permutations.test + foreach f [dict get $::testspec($config) -files] { - foreach f $O(-files) { if {[llength $patternlist]>0} { set bMatch 0 foreach p $patternlist { @@ -518,160 +639,242 @@ if {$bMatch==0} continue } - if {[file pathtype $f]!="absolute"} { - set f [file join $::testdir $f] + if {[file pathtype $f]!="absolute"} { set f [file join $::testdir $f] } + set f [file normalize $f] + + set displayname [string map [list $topdir/ {}] $f] + if {$config=="full" || $config=="veryquick"} { + set cmd "$testfixture $f" + } else { + set cmd "$testfixture $testrunner_tcl $config $f" + set displayname "config=$config $displayname" + } + if {$build!=""} { + set displayname "[lindex $build 2] $displayname" } - lappend lvar [list $build $config $f] + + set lProp [trd_test_script_properties $f] + set priority 0 + if {[lsearch $lProp slow]>=0} { set priority 2 } + if {[lsearch $lProp superslow]>=0} { set priority 4 } + + add_job \ + -displaytype tcl \ + -displayname $displayname \ + -cmd $cmd \ + -depid [lindex $build 0] \ + -priority $priority + } } -#-------------------------------------------------------------------------- +proc add_build_job {buildname target} { + global TRG + set dirname "[string tolower [string map {- _} $buildname]]_$target" + set dirname "testrunner_bld_$dirname" -proc r_write_db {tcl} { - trdb eval { BEGIN EXCLUSIVE } - uplevel $tcl - trdb eval { COMMIT } + set id [add_job \ + -displaytype bld \ + -displayname "Build $buildname ($target)" \ + -dirname $dirname \ + -build $buildname \ + -cmd "$TRG(makecmd) $target" \ + -priority 3 + ] + + list $id [file normalize $dirname] $buildname } -# Obtain a new job to be run by worker $iJob (an integer). A job is -# returned as a three element list: -# -# {$build $config $file} -# -proc r_get_next_job {iJob} { - global T +proc add_make_job {bld target} { + global TRG - if {($iJob%2)} { - set orderby "ORDER BY priority ASC" + if {$TRG(platform)=="win"} { + set path [string map {/ \\} [lindex $bld 1]] + set cmd "xcopy /S $path\\* ." } else { - set orderby "ORDER BY priority DESC" + set cmd "cp -r [lindex $bld 1]/* ." } + append cmd "\n$TRG(makecmd) $target" - r_write_db { - set f "" - set c "" - trdb eval " - SELECT build, config, filename - FROM script - WHERE state='ready' - $orderby LIMIT 1 - " { - set b $build - set c $config - set f $filename - } - if {$f!=""} { - set tm [clock_milliseconds] - set T($iJob) $tm - trdb eval { - UPDATE script SET state='running', time=$tm - WHERE (build, config, filename) = ($b, $c, $f) + add_job \ + -displaytype make \ + -displayname "[lindex $bld 2] make $target" \ + -cmd $cmd \ + -depid [lindex $bld 0] \ + -priority 1 +} + +proc add_fuzztest_jobs {buildname} { + + foreach {interpreter scripts} [trd_fuzztest_data] { + set subcmd [lrange $interpreter 1 end] + set interpreter [lindex $interpreter 0] + + set bld [add_build_job $buildname $interpreter] + foreach {depid dirname displayname} $bld {} + + foreach s $scripts { + + # Fuzz data files fuzzdata1.db and fuzzdata2.db are larger than + # the others. So ensure that these are run as a higher priority. + set tail [file tail $s] + if {$tail=="fuzzdata1.db" || $tail=="fuzzdata2.db"} { + set priority 5 + } else { + set priority 1 } + + add_job \ + -displaytype fuzz \ + -displayname "$buildname $interpreter $tail" \ + -depid $depid \ + -cmd "[file join $dirname $interpreter] $subcmd $s" \ + -priority $priority } } - - if {$f==""} { return "" } - list $b $c $f } -#rename r_get_next_job r_get_next_job_r -#proc r_get_next_job {iJob} { -# puts [time { set res [r_get_next_job_r $iJob] }] -# set res -#} - -proc make_new_testset {} { +proc add_zipvfs_jobs {} { global TRG + source [file join $TRG(zipvfs) test zipvfs_testrunner.tcl] + + set bld [add_build_job Zipvfs $TRG(testfixture)] + foreach s [zipvfs_testrunner_files] { + set cmd "[file join [lindex $bld 1] $TRG(testfixture)] $s" + add_job \ + -displaytype tcl \ + -displayname "Zipvfs [file tail $s]" \ + -cmd $cmd \ + -depid [lindex $bld 0] + } - set tests [testset_patternlist $TRG(patternlist)] + set ::env(SQLITE_TEST_DIR) $::testdir +} + +proc add_jobs_from_cmdline {patternlist} { + global TRG if {$TRG(zipvfs)!=""} { - source [file join $TRG(zipvfs) test zipvfs_testrunner.tcl] - set tests [concat $tests [zipvfs_testrunner_testset]] + add_zipvfs_jobs + if {[llength $patternlist]==0} return } - r_write_db { - - trdb eval $TRG(schema) - set nJob $TRG(nJob) - set cmdline $TRG(cmdline) - set tm [clock_milliseconds] - trdb eval { REPLACE INTO config VALUES('njob', $nJob ); } - trdb eval { REPLACE INTO config VALUES('cmdline', $cmdline ); } - trdb eval { REPLACE INTO config VALUES('start', $tm ); } + if {[llength $patternlist]==0} { + set patternlist [list veryquick] + } - foreach t $tests { - foreach {b c s} $t {} - set slow 0 - - if {$c!="make" && $c!="build"} { - set fd [open $s] - for {set ii 0} {$ii<100 && ![eof $fd]} {incr ii} { - set line [gets $fd] - if {[string match -nocase *testrunner:* $line]} { - regexp -nocase {.*testrunner:(.*)} $line -> properties - foreach p $properties { - if {$p=="slow"} { set slow 1 } - if {$p=="superslow"} { set slow 2 } - } - } - } - close $fd + set first [lindex $patternlist 0] + switch -- $first { + all { + set patternlist [lrange $patternlist 1 end] + set clist [trd_all_configs] + foreach c $clist { + add_tcl_jobs "" $c $patternlist } + } - if {$c=="make" && $b==""} { - # --fuzztest option - set slow 1 + mdevtest { + foreach b [list All-O0 All-Debug] { + set bld [add_build_job $b $TRG(testfixture)] + add_tcl_jobs $bld veryquick "" + add_fuzztest_jobs $b } + } - if {$c=="veryquick"} { - set c "" + sdevtest { + foreach b [list All-Sanitize All-Debug] { + set bld [add_build_job $b $TRG(testfixture)] + add_tcl_jobs $bld veryquick "" + add_fuzztest_jobs $b } + } + + release { + foreach b [trd_builds $TRG(platform)] { + set bld [add_build_job $b $TRG(testfixture)] + foreach c [trd_configs $TRG(platform) $b] { + add_tcl_jobs $bld $c "" + } - set state ready - if {$b!="" && $c!="build"} { - set state "" + foreach e [trd_extras $TRG(platform) $b] { + if {$e=="fuzztest"} { + add_fuzztest_jobs $b + } else { + add_make_job $bld $e + } + } } + } - trdb eval { - INSERT INTO script(build, config, filename, slow, state) - VALUES ($b, $c, $s, $slow, $state) + default { + if {[info exists ::testspec($first)]} { + add_tcl_jobs "" $first [lrange $patternlist 1 end] + } else { + add_tcl_jobs "" full $patternlist } } } } -proc script_input_ready {fd iJob b c f} { +proc make_new_testset {} { + global TRG + + r_write_db { + trdb eval $TRG(schema) + set nJob $TRG(nJob) + set cmdline $TRG(cmdline) + set tm [clock_milliseconds] + trdb eval { REPLACE INTO config VALUES('njob', $nJob ); } + trdb eval { REPLACE INTO config VALUES('cmdline', $cmdline ); } + trdb eval { REPLACE INTO config VALUES('start', $tm ); } + + add_jobs_from_cmdline $TRG(patternlist) + } + +} + +proc script_input_ready {fd iJob jobid} { global TRG global O global T if {[eof $fd]} { + trdb eval { SELECT * FROM jobs WHERE jobid=$jobid } job {} + + # If this job specified a directory name, then delete the run.sh/run.bat + # file from it before continuing. This is because the contents of this + # directory might be copied by some other job, and we don't want to copy + # the run.sh file in this case. + if {$job(dirname)!=""} { + file delete -force [file join $job(dirname) $TRG(run)] + } + set ::done 1 fconfigure $fd -blocking 1 set state "done" set rc [catch { close $fd } msg] if {$rc} { - puts "FAILED: $b $c $f" + if {[info exists TRG(reportlength)]} { + puts -nonewline "[string repeat " " $TRG(reportlength)]\r" + } + puts "FAILED: $job(displayname) ($iJob)" set state "failed" } - set tm [expr [clock_milliseconds] - $T($iJob)] + set tm [clock_milliseconds] + set jobtm [expr {$tm - $job(starttime)}] - puts $TRG(log) "### $b ### $c ### $f ${tm}ms ($state)" + puts $TRG(log) "### $job(displayname) ${jobtm}ms ($state)" puts $TRG(log) [string trim $O($iJob)] r_write_db { set output $O($iJob) trdb eval { - UPDATE script SET output = $output, state=$state, time=$tm - WHERE (build, config, filename) = ($b, $c, $f) - } - if {$state=="done" && $c=="build"} { - trdb eval { - UPDATE script SET state = 'ready' WHERE (build, state)==($b, '') - } + UPDATE jobs + SET output=$output, state=$state, endtime=$tm + WHERE jobid=$jobid; + UPDATE jobs SET state='ready' WHERE depid=$jobid; } } @@ -702,84 +905,39 @@ set testfixture [info nameofexec] set script $TRG(info_script) - set dir [dirname $iJob] - create_or_clear_dir $dir - set O($iJob) "" - set job [r_get_next_job $iJob] - if {$job==""} { return 0 } - - foreach {b c f} $job {} + set jobdict [r_get_next_job $iJob] + if {$jobdict==""} { return 0 } + array set job $jobdict - if {$c=="build"} { - set testdir [file dirname $TRG(info_script)] - set srcdir [file dirname $testdir] - set builddir [build_to_dirname $b] - create_or_clear_dir $builddir + set dir $job(dirname) + if {$dir==""} { set dir [dirname $iJob] } + create_or_clear_dir $dir - if {$b=="Zipvfs"} { + if {$job(build)!=""} { + set srcdir [file dirname $::testdir] + if {$job(build)=="Zipvfs"} { set script [zipvfs_testrunner_script] } else { - set cmd [info nameofexec] - lappend cmd [file join $testdir releasetest_data.tcl] - lappend cmd trscript - if {$TRG(platform)=="win"} { lappend cmd -msvc } - lappend cmd $b $srcdir - set script [exec {*}$cmd] + set bWin [expr {$TRG(platform)=="win"}] + set script [trd_buildscript $job(build) $srcdir $bWin] } - - set fd [open [file join $builddir $TRG(make)] w] + set fd [open [file join $dir $TRG(make)] w] puts $fd $script close $fd - - puts "Launching build \"$b\" in directory $builddir..." - set target coretestprogs - if {$b=="User-Auth"} { set target testfixture } - - set cmd "$TRG(makecmd) $target" - set dir $builddir - - } elseif {$c=="make"} { - if {$b==""} { - if {$f!="fuzztest"} { error "corruption in testrunner.db!" } - # Special case - run [make fuzztest] - set makedir [file dirname $testfixture] - if {$TRG(platform)=="win"} { - error "how?" - } else { - set cmd [list make -C $makedir fuzztest] - } - } else { - set builddir [build_to_dirname $b] - copy_dir $builddir $dir - set cmd "$TRG(makecmd) $f" - } - } else { - if {$b==""} { - set testfixture [info nameofexec] - } else { - set tail testfixture - if {$TRG(platform)=="win"} { set tail testfixture.exe } - set testfixture [file normalize [file join [build_to_dirname $b] $tail]] - } - - if {$c=="valgrind"} { - set testfixture "valgrind -v --error-exitcode=1 $testfixture" - set ::env(OMIT_MISUSE) 1 - } - set cmd [concat $testfixture [list $script $c $f]] } set pwd [pwd] cd $dir - set fd [open "|$cmd 2>@1" r] + set fd [open $TRG(run) w] + puts $fd $job(cmd) + close $fd + set fd [open "|$TRG(runcmd) 2>@1" r] cd $pwd - set pid [pid $fd] fconfigure $fd -blocking false - fileevent $fd readable [list script_input_ready $fd $iJob $b $c $f] - unset -nocomplain ::env(OMIT_MISUSE) + fileevent $fd readable [list script_input_ready $fd $iJob $job(jobid)] return 1 } @@ -790,39 +948,36 @@ set tm [expr [clock_milliseconds] - $TRG(starttime)] set tm [format "%d" [expr int($tm/1000.0 + 0.5)]] - foreach s {ready running done failed} { - set v($s,build) 0 - set v($s,make) 0 - set v($s,script) 0 - } - r_write_db { - trdb eval { - SELECT state, jobtype, count(*) AS cnt - FROM script - GROUP BY state, jobtype + trdb eval { + SELECT displaytype, state, count(*) AS cnt + FROM jobs + GROUP BY 1, 2 } { - set v($state,$jobtype) $cnt - if {[info exists t($jobtype)]} { - incr t($jobtype) $cnt - } else { - set t($jobtype) $cnt - } + set v($state,$displaytype) $cnt + incr t($displaytype) $cnt } } set text "" - foreach j [array names t] { + foreach j [lsort [array names t]] { + foreach k {done failed running} { incr v($k,$j) 0 } set fin [expr $v(done,$j) + $v(failed,$j)] - lappend text "$j ($fin/$t($j)) f=$v(failed,$j) r=$v(running,$j)" + lappend text "${j}($fin/$t($j))" + if {$v(failed,$j)>0} { + lappend text "f$v(failed,$j)" + } + if {$v(running,$j)>0} { + lappend text "r$v(running,$j)" + } } if {[info exists TRG(reportlength)]} { puts -nonewline "[string repeat " " $TRG(reportlength)]\r" } - set report "${tm}s: [join $text { }]" + set report "${tm} [join $text { }]" set TRG(reportlength) [string length $report] - if {[string length $report]<80} { + if {[string length $report]<100} { puts -nonewline "$report\r" flush stdout } else { @@ -834,9 +989,8 @@ proc launch_some_jobs {} { global TRG - r_write_db { - set nJob [trdb one { SELECT value FROM config WHERE name='njob' }] - } + set nJob [trdb one { SELECT value FROM config WHERE name='njob' }] + while {[dirs_nHelper]<$nJob} { set iDir [dirs_allocDir] if {0==[launch_another_job $iDir]} { @@ -854,7 +1008,6 @@ set TRG(log) [open $TRG(logname) w] launch_some_jobs - # launch_another_job $ii one_line_report while {[dirs_nHelper]>0} { @@ -865,13 +1018,15 @@ one_line_report r_write_db { - set nErr [trdb one {SELECT count(*) FROM script WHERE state='failed'}] + set tm [clock_milliseconds] + trdb eval { REPLACE INTO config VALUES('end', $tm ); } + set nErr [trdb one {SELECT count(*) FROM jobs WHERE state='failed'}] if {$nErr>0} { puts "$nErr failures:" trdb eval { - SELECT build, config, filename FROM script WHERE state='failed' + SELECT displayname FROM jobs WHERE state='failed' } { - puts "FAILED: $build $config $filename" + puts "FAILED: $displayname" } } } @@ -885,7 +1040,7 @@ trdb timeout $TRG(timeout) set tm [lindex [time { make_new_testset }] 0] if {$TRG(nJob)>1} { - puts "splitting work across $TRG(nJob) cores" + puts "splitting work across $TRG(nJob) jobs" } puts "built testset in [expr $tm/1000]ms.." run_testset diff -Nru sqlite3-3.42.0/test/thread3.test sqlite3-3.44.0-0/test/thread3.test --- sqlite3-3.42.0/test/thread3.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/thread3.test 2023-11-04 14:23:58.000000000 +0000 @@ -75,4 +75,3 @@ } $nAttempt finish_test - diff -Nru sqlite3-3.42.0/test/timediff1.test sqlite3-3.44.0-0/test/timediff1.test --- sqlite3-3.42.0/test/timediff1.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/timediff1.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,222 @@ +# 2023-05-30 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# This file implements regression tests for SQLite library. The +# focus of this file is testing date and time functions. +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl + +# Skip this whole file if date and time functions are omitted +# at compile-time +# +ifcapable {!datetime} { + finish_test + return +} + +proc datetest {tnum expr result} { + do_test timediff-$tnum [subst { + execsql "SELECT coalesce($expr,'NULL')" + }] [list $result] +} +set tcl_precision 15 + + +# February overflow on a leap year +datetest 1.1 {datetime('2000-01-31','+1 month')} {2000-03-02 00:00:00} +datetest 1.2 {datetime('2004-01-29','+1 month')} {2004-02-29 00:00:00} +datetest 1.3 {datetime('2000-03-01','-1 day')} {2000-02-29 00:00:00} +datetest 1.4 {datetime('2000-03-31','-1 month')} {2000-03-02 00:00:00} +datetest 1.5 {datetime('2000-03-30','-1 month')} {2000-03-01 00:00:00} +datetest 1.6 {datetime('2000-03-29','-1 month')} {2000-02-29 00:00:00} +datetest 1.7 {datetime('2000-03-28','-1 month')} {2000-02-28 00:00:00} +datetest 1.8 {datetime('2000-02-29','+1 year')} {2001-03-01 00:00:00} +datetest 1.9 {datetime('2000-02-29','+4 years')} {2004-02-29 00:00:00} + +datetest 1.10 {datetime('1998-11-10','+0001-03-19 12:34:56')} \ + {2000-02-29 12:34:56} +datetest 1.11 {datetime('2000-01-31','+0004-01-00 12:34:56')} \ + {2004-03-02 12:34:56} +datetest 1.12 {datetime('2000-01-29','+0008-01-00 12:34:56')} \ + {2008-02-29 12:34:56} +datetest 1.13 {datetime('2001-03-31','-0001-01-00 06:10')} \ + {2000-03-01 17:50:00} + + +# February overflow on a non-leap year +datetest 2.1 {datetime('2001-01-31','+1 month')} {2001-03-03 00:00:00} +datetest 2.2 {datetime('2005-01-29','+1 month')} {2005-03-01 00:00:00} +datetest 2.3 {datetime('2001-03-01','-1 day')} {2001-02-28 00:00:00} +datetest 2.4 {datetime('2001-03-31','-1 month')} {2001-03-03 00:00:00} +datetest 2.5 {datetime('2001-03-30','-1 month')} {2001-03-02 00:00:00} +datetest 2.6 {datetime('2001-03-29','-1 month')} {2001-03-01 00:00:00} +datetest 2.7 {datetime('2001-03-28','-1 month')} {2001-02-28 00:00:00} + +datetest 2.10 {datetime('1999-11-10','+0001-03-19 12:34:56')} \ + {2001-03-01 12:34:56} +datetest 2.11 {datetime('2000-01-31','+0005-01-00 12:34:56')} \ + {2005-03-03 12:34:56} +datetest 2.12 {datetime('2000-01-29','+0009-01-00 12:34:56')} \ + {2009-03-01 12:34:56} +datetest 2.13 {datetime('2002-03-31','-0001-01-00 06:10')} \ + {2001-03-02 17:50:00} + +# timediff +datetest 3.1 {timediff('2000-03-02','2000-01-31')} {+0000-01-00 00:00:00.000} +datetest 3.2 {timediff('2000-01-31','2000-03-02')} {-0000-01-02 00:00:00.000} +datetest 3.3 {timediff('2000-03-02','1999-01-31')} {+0001-01-00 00:00:00.000} +datetest 3.4 {timediff('1999-01-31','2000-03-02')} {-0001-01-02 00:00:00.000} + +unset -nocomplain p1 +unset -nocomplain p2 +set p1 { + 0 {-4713-11-24 12:00:00} + 1 {-2000-04-30 05:19:26} + 2 {0000-01-01 12:34:56} + 3 {1776-07-04 13:00:00} + 4 {1969-07-20 20:17} + 5 {2440587.5} + 6 {2000-05-29 14:26} + 7 {2023-05-29 18:11} + 8 {2050-05-29 14:26} + 9 {4796-02-29 11:23:55.46} +} +set p2 { + A {1066-10-14} + B {1900-02-28 11:00} + C {1900-03-01 12:00} + D {1904-02-29 11:25} + E {2000-02-29 13:00} + E {2000-03-01 14:00} + F {2001-03-31 15:15} + G {2002-04-01 16:59} + H {2003-04-30 17:00} + I {2004-05-01 23:59:59} + J {2005-06-01} + K {2006-06-30 01:23:45} + L {2007-12-31 02:00} + M {2008-01-01 01:59} + N {3152-07-04 12:00} + P {9999-12-31 23:59:59} +} + +foreach {x1 d1} $p1 { + foreach {x2 d2} $p2 { + set r1 [db one {SELECT datetime($d1)}] + do_execsql_test timediff-4-$x1$x2 { + SELECT datetime($d2, timediff($d1,$d2)); + } [list $r1] + set r2 [db one {SELECT datetime($d2)}] + do_execsql_test timediff-4-$x2$x1 { + SELECT datetime($d1, timediff($d2,$d1)); + } [list $r2] + } +} + +# Partial time-diffs as modifiers +# +datetest 5-1 {datetime('2000-01-01','+0001-02-03')} {2001-03-04 00:00:00} +datetest 5-2 {datetime('2000-01-01','+0001-02-03x')} {NULL} +datetest 5-3 {datetime('2000-01-01','+0001-11-03')} {2001-12-04 00:00:00} +datetest 5-4 {datetime('2000-01-01','+0001-12-03')} {NULL} +datetest 5-5 {datetime('2000-01-01','+0001-02-30')} {2001-03-31 00:00:00} +datetest 5-6 {datetime('2000-01-01','+0001-02-31')} {NULL} +datetest 5-7 {datetime('2000-01-01','+0001-02-03 0')} {NULL} +datetest 5-8 {datetime('2000-01-01','+0001-02-03 01')} {NULL} +datetest 5-9 {datetime('2000-01-01','+0001-02-03 01:')} {NULL} +datetest 5-10 {datetime('2000-01-01','+0001-02-03 01:0')} {NULL} +datetest 5-11 {datetime('2000-01-01','+0001-02-03 01:02')} {2001-03-04 01:02:00} +datetest 5-12 {datetime('2000-01-01','+0001-02-03 01:02:')} {NULL} +datetest 5-13 {datetime('2000-01-01','+0001-02-03 01:02:0')} {NULL} +datetest 5-14 {datetime('2000-01-01','+0001-02-03 01:02:03')} \ + {2001-03-04 01:02:03} +datetest 5-15 {datetime('2000-01-01','+0001-02-03 01:02:03.')} NULL +datetest 5-16 {datetime('2000-01-01','+0001-02-03 01:02:03.5')} \ + {2001-03-04 01:02:03} +datetest 5-17 {datetime('2000-01-01','+0001-02-03 01:02:03.50')} \ + {2001-03-04 01:02:03} +datetest 5-18 {datetime('2000-01-01','+0001-02-03 01:02:03.500')} \ + {2001-03-04 01:02:03} +datetest 5-19 {datetime('2000-01-01','+0001-02-03 01:02:03.500x')} {NULL} +datetest 5-20 {datetime('2000-01-01','+0001-02-03 01:02:03.500 x')} {NULL} + +unset -nocomplain p1 +unset -nocomplain p2 +set p1 { + a {2000-01-01 00:00:00} + b {2000-01-31 23:59:59} + c {2000-02-01 00:00:00} + d {2000-02-29 23:59:59} + e {2000-03-01 00:00:00} + f {2000-03-31 23:59:59} + g {2000-04-01 00:00:00} + h {2000-04-30 23:59:59} + i {2000-05-01 00:00:00} + j {2000-05-31 23:59:59} + k {2000-06-01 00:00:00} + l {2000-06-30 23:59:59} + m {2000-07-01 00:00:00} + n {2000-07-31 23:59:59} + o {2000-08-01 00:00:00} + p {2000-08-31 23:59:59} + q {2000-09-01 00:00:00} + r {2000-09-30 23:59:59} + s {2000-10-01 00:00:00} + t {2000-10-31 23:59:59} + u {2000-11-01 00:00:00} + v {2000-11-30 23:59:59} + w {2000-12-01 00:00:00} + x {2000-12-31 23:59:59} +} +set p2 { + A {2001-01-01 00:00:00} + B {2001-01-31 23:59:59} + C {2001-02-01 00:00:00} + D {2001-02-28 23:59:59} + E {2001-03-01 00:00:00} + F {2001-03-31 23:59:59} + G {2001-04-01 00:00:00} + H {2001-04-30 23:59:59} + I {2001-05-01 00:00:00} + J {2001-05-31 23:59:59} + K {2001-06-01 00:00:00} + L {2001-06-30 23:59:59} + M {2001-07-01 00:00:00} + N {2001-07-31 23:59:59} + O {2001-08-01 00:00:00} + P {2001-08-31 23:59:59} + Q {2001-09-01 00:00:00} + R {2001-09-30 23:59:59} + S {2001-10-01 00:00:00} + T {2001-10-31 23:59:59} + U {2001-11-01 00:00:00} + V {2001-11-30 23:59:59} + W {2001-12-01 00:00:00} + X {2001-12-31 23:59:59} +} + +foreach {x1 d1} $p1 { + foreach {x2 d2} $p2 { + set r1 [db one {SELECT datetime($d1)}] + do_execsql_test timediff-6-$x1$x2 { + SELECT datetime($d2, timediff($d1,$d2)); + } [list $r1] + set r2 [db one {SELECT datetime($d2)}] + do_execsql_test timediff-6-$x2$x1 { + SELECT datetime($d1, timediff($d2,$d1)); + } [list $r2] + } +} + + + +finish_test diff -Nru sqlite3-3.42.0/test/tkt-cbd054fa6b.test sqlite3-3.44.0-0/test/tkt-cbd054fa6b.test --- sqlite3-3.42.0/test/tkt-cbd054fa6b.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/tkt-cbd054fa6b.test 2023-11-04 14:23:58.000000000 +0000 @@ -65,7 +65,7 @@ } {} do_test tkt-cbd05-1.3 { execsql { - SELECT tbl,idx,group_concat(s(sample),' ') + SELECT tbl,idx,string_agg(s(sample),' ') FROM vvv WHERE idx = 't1_x' GROUP BY tbl,idx diff -Nru sqlite3-3.42.0/test/trigger2.test sqlite3-3.44.0-0/test/trigger2.test --- sqlite3-3.42.0/test/trigger2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/trigger2.test 2023-11-04 14:23:58.000000000 +0000 @@ -790,4 +790,3 @@ finish_test - diff -Nru sqlite3-3.42.0/test/unhex.test sqlite3-3.44.0-0/test/unhex.test --- sqlite3-3.42.0/test/unhex.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/unhex.test 2023-11-04 14:23:58.000000000 +0000 @@ -55,6 +55,8 @@ #-------------------------------------------------------------------------- # Test the 2-argument version. # +# Zap global x array set in some previous test. +if {[array exists x]} {array unset x} foreach {tn hex} { 1 "FFFF ABCD" 2 "FFFF ABCD" @@ -98,5 +100,3 @@ finish_test - - diff -Nru sqlite3-3.42.0/test/update.test sqlite3-3.44.0-0/test/update.test --- sqlite3-3.42.0/test/update.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/update.test 2023-11-04 14:23:58.000000000 +0000 @@ -764,5 +764,27 @@ SELECT * FROM t1 ORDER BY vkey, c5; ROLLBACK; } {6 -54 100 NULL} +# Follow-up on 2023-07-31 (forum post https://sqlite.org/forum/forumpost/8ab195fd44e75ed0): +# Only disable one-pass if the subquery is in the WHERE clause. The SET expressions +# do not count. +do_execsql_test update-21.11 { + DROP TABLE t1; + CREATE TABLE t1(a INTEGER PRIMARY KEY, b INT); + CREATE TABLE t2(d INT); +} +do_eqp_test update-21.12 { + WITH t3(x,y) AS (SELECT d, row_number()OVER() FROM t2) + UPDATE t1 SET b=(SELECT y FROM t3 WHERE t1.a=t3.x); +} { + QUERY PLAN + |--SCAN t1 + `--CORRELATED SCALAR SUBQUERY xxxxxx + |--CO-ROUTINE t3 + | |--CO-ROUTINE (subquery-xxxxxx) + | | `--SCAN t2 + | `--SCAN (subquery-xxxxxx) + |--BLOOM FILTER ON t3 (x=?) + `--SEARCH t3 USING AUTOMATIC COVERING INDEX (x=?) +} finish_test diff -Nru sqlite3-3.42.0/test/upfrom4.test sqlite3-3.44.0-0/test/upfrom4.test --- sqlite3-3.42.0/test/upfrom4.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/upfrom4.test 2023-11-04 14:23:58.000000000 +0000 @@ -127,4 +127,30 @@ 1000 - - - } +# Forum post https://sqlite.org/forum/forumpost/36ff78b2a3 +# +ifcapable update_delete_limit { + reset_db + do_execsql_test 500 { + CREATE TABLE t1(abc INT, def INT); + INSERT INTO t1 VALUES(0,0); + INSERT INTO t1 VALUES(0,0); + INSERT INTO t1 VALUES(0,0); + CREATE TABLE dual(dummy TEXT); + INSERT INTO dual(dummy) VALUES('X'); + } {} + + do_execsql_test 510 { + UPDATE t1 + SET (abc, def)=(SELECT x, 123) + FROM dual LEFT JOIN (SELECT 789 AS 'x' FROM dual) AS d2 + LIMIT 2 + } + + do_execsql_test 520 { + SELECT * FROM t1 + } {789 123 789 123 0 0} +} + + finish_test diff -Nru sqlite3-3.42.0/test/upsert1.test sqlite3-3.44.0-0/test/upsert1.test --- sqlite3-3.42.0/test/upsert1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/upsert1.test 2023-11-04 14:23:58.000000000 +0000 @@ -255,4 +255,17 @@ SELECT * FROM t1; } {1 22} +# 2023-08-17 dbsqlfuzz 9983e2c77634a8ccf33b5c91fa9982599de5f9e9 +# Bound parameters in the ON CONFLICT clause of an UPSERT. +# +reset_db +do_execsql_test upsert1-1200 { + CREATE TABLE t1(a INT, b INT); + CREATE UNIQUE INDEX t1x ON t1(b+3); +} +sqlite3_db_config db ENABLE_QPSG 1 +do_catchsql_test upsert1-1210 { + INSERT INTO t1(a,b) VALUES(1,2) ON CONFLICT(b+?1) DO NOTHING; +} {1 {ON CONFLICT clause does not match any PRIMARY KEY or UNIQUE constraint}} + finish_test diff -Nru sqlite3-3.42.0/test/vacuum-into.test sqlite3-3.44.0-0/test/vacuum-into.test --- sqlite3-3.42.0/test/vacuum-into.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/vacuum-into.test 2023-11-04 14:23:58.000000000 +0000 @@ -185,6 +185,3 @@ finish_test - - - diff -Nru sqlite3-3.42.0/test/vt02.c sqlite3-3.44.0-0/test/vt02.c --- sqlite3-3.42.0/test/vt02.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/vt02.c 2023-11-04 14:23:58.000000000 +0000 @@ -580,8 +580,11 @@ sqlite3_finalize(pStmt); } sqlite3RunSql(db,pVTab, - "INSERT INTO temp.\"%w\"(bi,vn,ix) VALUES(%d,'nConstraint',%d)", - zLogTab, iBI, pInfo->nConstraint + "INSERT INTO temp.\"%w\"(bi,vn,ix) VALUES(%d,'nConstraint',%d)" + "RETURNING iif(bi=%d,'ok',RAISE(ABORT,'wrong trigger'))", + /* The RETURNING clause checks to see that the returning trigger fired + ** for the correct INSERT in the case of nested INSERT RETURNINGs. */ + zLogTab, iBI, pInfo->nConstraint, iBI ); for(i=0; inConstraint; i++){ sqlite3_value *pVal; @@ -983,7 +986,9 @@ /* xRename */ 0, /* xSavepoint */ 0, /* xRelease */ 0, - /* xRollbackTo */ 0 + /* xRollbackTo */ 0, + /* xShadowName */ 0, + /* xIntegrity */ 0 }; static void vt02CoreInit(sqlite3 *db){ diff -Nru sqlite3-3.42.0/test/walseh1.test sqlite3-3.44.0-0/test/walseh1.test --- sqlite3-3.42.0/test/walseh1.test 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/test/walseh1.test 2023-11-04 14:23:58.000000000 +0000 @@ -0,0 +1,148 @@ +# 2021 August 16 +# +# The author disclaims copyright to this source code. In place of +# a legal notice, here is a blessing: +# +# May you do good and not evil. +# May you find forgiveness for yourself and forgive others. +# May you share freely, never taking more than you give. +# +#*********************************************************************** +# + +set testdir [file dirname $argv0] +source $testdir/tester.tcl +source $testdir/malloc_common.tcl +set testprefix walseh1 + +set ::seh_countdown 0 +set ::seh_errno 10 +proc seh_faultsim_callback {iFault} { + if {$iFault==650} { + incr ::seh_countdown -1 + if {$::seh_countdown==0} { return $::seh_errno } + } + return 0 +} + +proc seh_injectinstall {} { + sqlite3_test_control_fault_install seh_faultsim_callback +} +proc seh_injectuninstall {} { + sqlite3_test_control_fault_install +} +proc seh_injectstart {iFail} { + set ::seh_errno [expr 2+$iFail*10] + set ::seh_countdown $iFail +} +proc seh_injectstop {} { + set res [expr $::seh_countdown<=0] + set ::seh_countdown 0 + set res +} + +set FAULTSIM(seh) [list \ + -injectinstall seh_injectinstall \ + -injectstart seh_injectstart \ + -injectstop seh_injectstop \ + -injecterrlist {{1 {disk I/O error}}} \ + -injectuninstall seh_injectuninstall \ +] + +proc test_system_errno {db expect} { + set serrno [sqlite3_system_errno $db] + if {$serrno!=$expect} { + error "surprising system_errno. Expected $expect, got $serrno" + } +} + +do_execsql_test 1.0 { + PRAGMA journal_mode = wal; + CREATE TABLE t1(x, y); + INSERT INTO t1 VALUES(1, 2); + INSERT INTO t1 VALUES(3, 4); +} {wal} +faultsim_save_and_close + +do_faultsim_test 1 -faults seh -prep { + catch { db2 close } + faultsim_restore_and_reopen + execsql { SELECT * FROM sqlite_schema } + sqlite3 db2 test.db +} -body { + execsql { SELECT * FROM t1 } db2 +} -test { + faultsim_test_result {0 {1 2 3 4}} + if {$testrc} { test_system_errno db2 $::seh_errno } +} +catch { db2 close } + +faultsim_save_and_close + +do_faultsim_test 2 -faults seh -prep { + catch { db close } + faultsim_restore_and_reopen +} -body { + execsql { SELECT * FROM t1 } +} -test { + faultsim_test_result {0 {1 2 3 4}} + if {$testrc} { test_system_errno db $::seh_errno } +} + +do_faultsim_test 3 -faults seh -prep { + catch { db close } + faultsim_restore_and_reopen +} -body { + execsql { INSERT INTO t1 VALUES(5, 6) } + execsql { SELECT * FROM t1 } +} -test { + faultsim_test_result {0 {1 2 3 4 5 6}} + if {$testrc} { test_system_errno db $::seh_errno } +} + +do_faultsim_test 4 -faults seh -prep { + catch { db close } + faultsim_restore_and_reopen +} -body { + execsql { PRAGMA wal_checkpoint } + execsql { INSERT INTO t1 VALUES(7, 8) } + execsql { SELECT * FROM t1 } +} -test { + faultsim_test_result {0 {1 2 3 4 7 8}} + if {$testrc} { test_system_errno db $::seh_errno } +} +catch { db close } + +do_faultsim_test 5 -faults seh -prep { + catch { db close } + faultsim_restore_and_reopen + execsql { + PRAGMA cache_size = 5; + BEGIN; + WITH s(i) AS ( + SELECT 1 UNION ALL SELECT i+1 FROM s WHERE i<50 + ) + INSERT INTO t1 SELECT randomblob(500), randomblob(500) FROM s; + } +} -body { + execsql ROLLBACK +} -test { + faultsim_test_result {0 {}} + if {$testrc} { test_system_errno db $::seh_errno } +} +catch { db close } + +do_faultsim_test 6 -faults seh -prep { + catch { db close } + faultsim_restore_and_reopen +} -body { + execsql { PRAGMA wal_checkpoint = TRUNCATE } + execsql { INSERT INTO t1 VALUES(7, 8) } + execsql { SELECT * FROM t1 } +} -test { + faultsim_test_result {0 {1 2 3 4 7 8}} + if {$testrc} { test_system_errno db $::seh_errno } +} +catch { db close } + +finish_test diff -Nru sqlite3-3.42.0/test/where7.test sqlite3-3.44.0-0/test/where7.test --- sqlite3-3.42.0/test/where7.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/where7.test 2023-11-04 14:23:58.000000000 +0000 @@ -47,18 +47,33 @@ SELECT * FROM t1; } } {1 2 3 4 2 3 4 5 3 4 6 8 4 5 10 15 5 10 100 1000} -do_execsql_test where7-1.1.1 { - CREATE TABLE t(a); - CREATE INDEX ta ON t(a); - INSERT INTO t(a) VALUES(1),(2); - SELECT * FROM t ORDER BY a; - SELECT * FROM t WHERE a<2 OR a<3 ORDER BY a; - PRAGMA count_changes=ON; - DELETE FROM t WHERE a<2 OR a<3; - SELECT * FROM t; - PRAGMA count_changes=OFF; - DROP TABLE t; -} {1 2 1 2 2} +if {[permutation] != "no_optimization"} { + do_execsql_test where7-1.1.1 { + CREATE TABLE t(a); + CREATE INDEX ta ON t(a); + INSERT INTO t(a) VALUES(1),(2); + SELECT * FROM t ORDER BY a; + SELECT * FROM t WHERE a<2 OR a<3 ORDER BY a; + PRAGMA count_changes=ON; + DELETE FROM t WHERE a<2 OR a<3; + SELECT * FROM t; + PRAGMA count_changes=OFF; + DROP TABLE t; + } {1 2 1 2 2} +} else { + do_execsql_test where7-1.1.1-noopt { + CREATE TABLE t(a); + CREATE INDEX ta ON t(a); + INSERT INTO t(a) VALUES(1),(2); + SELECT * FROM t ORDER BY a; + SELECT * FROM t WHERE a<2 OR a<3 ORDER BY a; + PRAGMA count_changes=ON; + DELETE FROM t WHERE a<2 OR a<3; + SELECT * FROM t; + PRAGMA count_changes=OFF; + DROP TABLE t; + } {1 2 1 2 3} +} do_test where7-1.2 { count_steps { SELECT a FROM t1 WHERE b=3 OR c=6 ORDER BY a diff -Nru sqlite3-3.42.0/test/wherelimit2.test sqlite3-3.44.0-0/test/wherelimit2.test --- sqlite3-3.42.0/test/wherelimit2.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/wherelimit2.test 2023-11-04 14:23:58.000000000 +0000 @@ -299,5 +299,35 @@ set ::log } {ax a bx b cx c dx d ex a} +#----------------------------------------------------------------------- +reset_db +do_execsql_test 6.0 { + CREATE TABLE t2(x); + INSERT INTO t2(x) VALUES(1),(2),(3),(5),(8),(13); +} {} + +do_execsql_test 6.1 { + WITH t2 AS MATERIALIZED (VALUES(5)) + DELETE FROM t2 ORDER BY rank()OVER() LIMIT 2; +} + +do_execsql_test 6.2 { + SELECT * FROM t2; +} {3 5 8 13} + +#------------------------------------------------------------------------- + +do_execsql_test 7.0 { + CREATE TABLE t1(a INT); INSERT INTO t1(a) VALUES(0); +} {} + +do_execsql_test 7.1 { + WITH t1(b) AS (SELECT * FROM (SELECT * FROM (VALUES(2)))) + UPDATE t1 SET a=3 LIMIT 1; +} + +do_execsql_test 7.2 { + SELECT * FROM t1; +} {3} finish_test diff -Nru sqlite3-3.42.0/test/window1.test sqlite3-3.44.0-0/test/window1.test --- sqlite3-3.42.0/test/window1.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/window1.test 2023-11-04 14:23:58.000000000 +0000 @@ -158,7 +158,7 @@ do_execsql_test 4.10.1 { SELECT a, count() OVER (ORDER BY a DESC), - group_concat(a, '.') OVER (ORDER BY a DESC) + string_agg(a, '.') OVER (ORDER BY a DESC) FROM t2 ORDER BY a DESC } { 6 1 6 @@ -825,7 +825,7 @@ } do_execsql_test 18.3.1 { - SELECT group_concat(c, '.') OVER (PARTITION BY b ORDER BY c) + SELECT string_agg(c, '.') OVER (PARTITION BY b ORDER BY c) FROM t1 } {four four.six four.six.two five five.one five.one.three} @@ -836,7 +836,7 @@ } {four four.six four.six.two five five.one five.one.three} do_execsql_test 18.3.3 { - SELECT group_concat(c, '.') OVER win2 + SELECT string_agg(c, '.') OVER win2 FROM t1 WINDOW win1 AS (PARTITION BY b), win2 AS (win1 ORDER BY c) @@ -850,7 +850,7 @@ } {four four.six four.six.two five five.one five.one.three} do_execsql_test 18.3.5 { - SELECT group_concat(c, '.') OVER win5 + SELECT string_agg(c, '.') OVER win5 FROM t1 WINDOW win1 AS (PARTITION BY b), win2 AS (win1), @@ -1127,7 +1127,7 @@ } do_execsql_test 28.1.2 { - SELECT group_concat(b,'') OVER w1 FROM t1 + SELECT string_agg(b,'') OVER w1 FROM t1 WINDOW w1 AS (ORDER BY a RANGE BETWEEN 3 PRECEDING AND 1 PRECEDING) } { {} {} @@ -2363,4 +2363,17 @@ SELECT (SELECT max(y)+sum(0) OVER ()) FROM t3 LEFT JOIN t4 ON x=y GROUP BY x; } {100 {} 400} +# 2023-05-23 https://sqlite.org/forum/forumpost/fbfe330a20 +# +reset_db +do_execsql_test 77.1 { + CREATE TABLE t1(x INT); + CREATE INDEX t1x ON t1(likely(x)); + INSERT INTO t1 VALUES(1),(2),(4),(8); +} +do_execsql_test 77.2 { + SELECT max(~likely(x)) FILTER (WHERE true) FROM t1 INDEXED BY t1x GROUP BY x; +} {-2 -3 -5 -9} + + finish_test diff -Nru sqlite3-3.42.0/test/window3.test sqlite3-3.44.0-0/test/window3.test --- sqlite3-3.42.0/test/window3.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/window3.test 2023-11-04 14:23:59.000000000 +0000 @@ -1181,7 +1181,7 @@ {} {} {} {} {} {} {} {} {} {} {}} do_execsql_test 1.1.14.1 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 + SELECT string_agg(CAST(b AS TEXT), '.') OVER (ORDER BY a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 } {89 89.81 89.81.96 89.81.96.59 89.81.96.59.38 89.81.96.59.38.68 89.81.96.59.38.68.39 89.81.96.59.38.68.39.62 89.81.96.59.38.68.39.62.91 89.81.96.59.38.68.39.62.91.46 89.81.96.59.38.68.39.62.91.46.6 @@ -1471,7 +1471,7 @@ 89.59.39.99.29.59.89.89.29.9.79.49.59.29.59.19.39.9.9.99.69.39} do_execsql_test 1.1.14.3 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 + SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 } {1 1.1 1.1.2 1.1.2.2 1.1.2.2.3 1.1.2.2.3.3 1.1.2.2.3.3.4 1.1.2.2.3.3.4.5 1.1.2.2.3.3.4.5.6 1.1.2.2.3.3.4.5.6.7 1.1.2.2.3.3.4.5.6.7.7 1.1.2.2.3.3.4.5.6.7.7.7 1.1.2.2.3.3.4.5.6.7.7.7.8 @@ -1758,7 +1758,7 @@ 9.9.9.19.29.29.29.39.39.39.49.59.59.59.59.69.79.89.89.89.99.99} do_execsql_test 1.1.14.5 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 + SELECT string_agg(CAST(b AS TEXT), '.') OVER ( ORDER BY b%10,a RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW ) FROM t2 } {90 90.40 90.40.30 90.40.30.80 90.40.30.80.20 90.40.30.80.20.90 90.40.30.80.20.90.60 90.40.30.80.20.90.60.70 90.40.30.80.20.90.60.70.80 90.40.30.80.20.90.60.70.80.90 90.40.30.80.20.90.60.70.80.90.30 @@ -1960,7 +1960,7 @@ 83 27 17 7} do_execsql_test 1.1.14.7 { - SELECT group_concat(CAST(b AS TEXT), '.') OVER (win1 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) + SELECT string_agg(CAST(b AS TEXT), '.') OVER (win1 ORDER BY b%10 RANGE BETWEEN UNBOUNDED PRECEDING AND CURRENT ROW) FROM t2 WINDOW win1 AS (PARTITION BY b%2,a) ORDER BY 1 diff -Nru sqlite3-3.42.0/test/with3.test sqlite3-3.44.0-0/test/with3.test --- sqlite3-3.42.0/test/with3.test 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/test/with3.test 2023-11-04 14:23:59.000000000 +0000 @@ -132,8 +132,8 @@ | | `--SCALAR SUBQUERY xxxxxx | | `--SCAN w2 | `--RECURSIVE STEP - | |--SCAN c - | `--SCAN w1 + | |--SCAN w1 + | `--SCAN c |--SCAN c |--SEARCH w2 USING INTEGER PRIMARY KEY (rowid=?) `--SEARCH w1 USING INTEGER PRIMARY KEY (rowid=?) diff -Nru sqlite3-3.42.0/tool/build-shell.sh sqlite3-3.44.0-0/tool/build-shell.sh --- sqlite3-3.42.0/tool/build-shell.sh 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/build-shell.sh 2023-11-04 14:23:59.000000000 +0000 @@ -16,7 +16,6 @@ -DSQLITE_ENABLE_FTS4 \ -DSQLITE_ENABLE_RTREE \ -DHAVE_READLINE \ - -DHAVE_USLEEP=1 \ ../sqlite/src/shell.c \ ../sqlite/src/test_vfstrace.c \ sqlite3.c -ldl -lreadline -lncurses diff -Nru sqlite3-3.42.0/tool/cktclsh.sh sqlite3-3.44.0-0/tool/cktclsh.sh --- sqlite3-3.42.0/tool/cktclsh.sh 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/tool/cktclsh.sh 2023-11-04 14:23:59.000000000 +0000 @@ -0,0 +1,11 @@ +# Fail with an error if the TCLSH named in $2 is not tclsh version $1 or later. +# +echo "set vers $1" >cktclsh$1.tcl +echo 'if {$tcl_version<$vers} {exit 1}' >>cktclsh$1.tcl +if ! $2 cktclsh$1.tcl +then + echo "ERROR: This makefile target requires tclsh $1 or later." + rm cktclsh$1.tcl + exit 1 +fi +rm cktclsh$1.tcl diff -Nru sqlite3-3.42.0/tool/custom.txt sqlite3-3.44.0-0/tool/custom.txt --- sqlite3-3.42.0/tool/custom.txt 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/tool/custom.txt 2023-11-04 14:23:59.000000000 +0000 @@ -0,0 +1,1246 @@ +aa +aaa +abc +abcdefg +abd +abf +Abortable +acc +accessor +accum +acd +activecpu +Adaptor +Additionallly +addop +addoptrace +addr +adjustements +af +aff +afp +afterward +Agg +agg +agginfo +alikes +Alloc +alloc +alloca +allocator +allocators +alphabetics +alphanumerics +alternateform +altertab +altform +amalgamator +amongst +analyse +antipenultimate +ap +api +appdef +appendall +appendchar +appendf +ar +arg +argc +argcount +arglist +argn +args +argv +arrayname +ascii +asm +async +atoi +atomics +auth +authorizer +autocheckpoint +autocommit +autoconf +autoext +autoextension +autoinc +autoincrement +autoincremented +autoindex +autoinstall +autovac +autovacuum +autovacuumed +autovacuuming +auxdata +awk +Ax +backend +backends +backfill +backfilled +backfilling +backtrace +backtraces +backtracing +bb +bba +bcb +bcc +beginthreadex +behavior +behavioral +behaviors +benigncnt +bg +bigblob +bitcount +bitfield +bitmask +bitmasks +bitset +bitvec +bitvecs +bitwise +blobwrite +blockquote +Bloomfilter +bom +boolean +booleans +Borland +br +breadthfirstsearch +breakpoint +bt +btree +btrees +buf +bufpt +butoindex +bytearray +bytecode +bytecodevtab +byteorder +cacheflush +cachegrind +Cachesize +calc'ing +callgrind +cardinalities +cardinality +carray +cb +cd +cdbaa +ce +ceil +cellpadding +cellspacing +center +chacha +changecounter +changeset +characgter +characterset +checkpointed +Checkpointer +checkpointer +checkpointers +checkpointing +checksummed +checksums +chmod +chng +chown +chroot +chsize +chunksize +cid +cis +ckalloc'd +ckpt +cksum +cksumvfs +clientdata +closedir +clownshoe +cmd +cmp +cmpaff +Cmpr +cnt +codec +codepage +collseq +colname +compileoption +concat +config +confstr +connetion +consective +considertion +const +coredump +coroutine +coroutines +cov +crashparams +csr +csv +Cte +ctime +Ctrl +ctrl +ctx +ctype +cume +Cx +cx +Cygwin +cygwin +dan +darkstar +databasename +databse +datasource +datatypes +datetime +dbfuzz +dbinfo +dbname +dbpage +dbpagevfs +dbs +dbsize +dbsqlfuzz +dbstat +dbtotxt +De +de +deadman +deallocate +deallocated +deallocates +deallocating +deallocation +decltype +decrementing +defense +defenses +defn +defragment +defragmentation +defragmented +deinitialization +Deinitialize +deinitialize +demovfs +dependences +dequote +dequoted +dequoting +dereferenced +dereferences +desc +deserialization +deserialize +deserialized +deserializes +deserializing +dest +destructor +destructors +deterministically +dev +devsim +devsym +df +Dfdatasync +dflt +dir +directonly +dirent +dirs +disjunct +disjunction +disjuncts +diskfull +divy +dl +dll +dlopen +dlsym +docid +docids +dont +dontcache +dotfile +dotlock +doublearray +drh +dryrun +dstr +dt +Duint +dup +Durian +dword +Dx +dylib +Dyn +Ec +ec +ecel +editability +ef +efc +eg +Ei +elif +emcc +emscripten +encodings +endeavor +endfor +endian +endianness +endif +endthreadex +enum +eof +eph +Ephem +eq +eqp +equaling +equalities +errcode +errmsg +errno +errorcode +erroroffset +errstr +esc +esign +et +etfs +etilqs +eval +exe +expander +explainer +expmask +expr +exprlist +extern +fakeheap +fallocate +fanout +faultsim +favor +favors +fb +fc +fchmod +fchown +fclose +fcntl +fd +fdatasync +feb +fef +Feijoa +ferror +ffff +ffffeff +ffffffe +fffffff +ffffffff +fffffffffffffff +fflush +fg +fgets +fi +fibonacci +fid +Fifo +filecount +filectrl +filemapping +filesize +filesystem +filesystems +finalised +finalizer +findfirst +findnext +fixup +fk +fkctr +fkey +flattener +fmt +fopen +foreach +formatter +fprintf +fputs +fread +fred +fred's +freeblock +freeblocks +freelist +freepage +freespace +frombind +fs +fsanitize +fsctl +fsdir +fseek +fstat +fstree +fsync +fsynced +fsyncs +ftell +ftruncate +fts +fullfsync +fullname +fullschema +fullshm +fullsync +fullsyncs +func +funcs +fuzzer +fuzzers +fwrite +Fx +gcc +gcov +gdb +getcwd +getenv +gethostuuid +getpagesize +getpid +getrusage +getsubtype +getter +getters +gibabyte +gid +glibc +globbing +gmtime +Gosub +Goto +goto +groupbyparent +Groupid +growable +grp +hdl +hdr +hexdb +hexdouble +hexio +highwater +hijklmno +honor +honored +honoring +hostid +href +html +htsize +hw +Hwtime +icecube +ideographical +idx +idxaff +idxnum +idxstr +idx'th +ieee +ifdef +iff +ifndef +imm +impl +incr +incrblob +incrementing +indexable +indexname +infop +ing +init +initfail +initializer +initializers +initiallly +inlined +inlines +inlining +ino +inode +inodes +inopertune +installable +intarray +inteface +interoperate +interp +interpretable +intkey +intptr +intreal +intrinsics +invalidations +invariants +io +ioerr +iotrace +ipk +iplan +isalnum +isalpha +isatty +isdigit +isempty +isexplain +ismemdb +isnan +isspace +isxdigit +i'th +iversion +jfd +jj +jointype +jointypes +journaled +journaling +journalled +journalling +journalmode +jrnl +jsl +json +jt +julian +julianday +keyinfo +keywordhash +kibibytes +kvstorage +kvvfs +lappend +lasterrno +lbl +ldl +le +leafdata +leftjustify +len +leveling +lexeme +lexemes +lhs +li +libm +libversion +lifecycle +lindex +lineno +Linenoise +linux +lised +lld +llvm +lm +ln +lncurses +loadext +localhost +localtime +lockd +lockdata +lockingcontext +lockless +lockproxy +locktype +logmsg +longvalue +longwords +lookahead +Lookaside +lookaside +lookups +losslessly +lpthread +lrc +lreadline +lru +lseek +lt +lvalue +lwr +makefile +makefiles +malloc +malloc'd +malloced +mallocs +manditory +manpage +matchinfo +materializations +mathfuncs +maxsize +mbcs +Mcafee +md +Meeus +mem +memcmp +memcpy +memdb +memdebug +memget +memmove +mempool +memset +memstatus +memsys +memvfs +mergeable +mergepatch +middleware +millisec +mincore +mingw +mis +miscoded +mj +mkctimec +mkdir +mkkeywordhash +mkopcodec +mkopcodeh +mkpragmatab +mmap +mmapped +mno +modeof +Movepage +mprintf +msd +msdos +msec +msg +msgs +msize +msvc +mtime +mult +multibyte +multiplex'ed +multiplexor +multithreaded +multiwrite +mutex +mutexes +mutexing +mx +mxpathname +myprefix +nal +namecontext +namespace +natively +nbr +nbsp +ncell +ncol +ncycle +nd +ndlt +neighbors +neq +nestable +newrowid +nfs +nlt +nnn +nocase +nochange +nochng +nofollow +nolock +nomem +nomutex +nonblocking +nonroot +noop +noshm +notational +notheld +notnull +nowrap +nr +ntile +nul +nullable +nullif +nullvalue +Num +objproc +oc +offsetof +ofst +ogham +oid +Ok +ok +ol +onecolumn +onepass +onoff +onwards +oom +opcodesnever +openable +opendir +optimizers +optimizible +orconf +orderby +orderbylist +os +Oswrite +overread +overreads +overrideable +oversize +overwriteable +ovewrite +ovfl +pagecache +pagecaches +pagecount +pagelist +pageno +pagesize +pagetype +Param +params +passwd +patchset +pathname +pathnames +pc +pcache +pclose +pcx +pgno +pgoffset +pgsize +pgsz +pid +pluggable +pmasz +pn +popen +pos +posix +Postgres +Powersafe +powersafe +pq +pqr +pqrstuvw +pragma +pragmaed +pragma's +pragmas +pre +pread +preallocate +preallocated +precisions +precompiled +precomputed +prefetch +prefetched +preformated +preformatted +prepend +prepended +prepending +prepends +prepopulate +preprocess +preprocessed +preprocessing +preprocessor +prereq +prereqs +preupdate +primarykey +printf +printfs +prng +proc +procs +profiler +proleptic +proxying +proxys +pseudocode +pseudotable +psow +psz +pthread +pthreads +ptr +ptrmap +ptrs +purgeable +putsnl +pwrite +pz +qbox +Qcircle +quotaed +quotefix +radix +randomblob +randstr +rarr +rc +rcauth +Rcvr +rds +readdir +readline +readlock +readonly +Readr +realloc +reallocs +realvalue +rebalance +rebalanced +recoverability +redefinable +redux +reenabled +reentrant +refcount +refcounts +regs +reindexed +reinitializer +reinitializes +rekey +rekeyed +relevancies +relink +relink +relock +renormalize +reoptimize +reparse +reparse +reparsed +reparsing +reportable +reprepare +reprepare +reprepared +reprepares +representable +repurpose +Req'd +requeries +requote +reregister +reseek +reservebytes +resumable +retarget +retargeted +retrys +returntype +rfc +rhs +Ri +Rivest +ro +rootpage +rowid +rowids +Rowkey +rownumber +rowset +runtime +rw +rwc +samplelib +sampleno +sandboxed +sandboxing +savepoint +savepoints +scanf +scanstats +scanstatus +schemas +sectorsize +selecttrace +selftest +setrlimit +setsubtype +settitle +sharable +shm +shmlock +sibs +sig +signaling +significand +sizehint +Sizeof +sizeof +snprintf +Solaris +sorterref +soundex +sourceid +speedtest +sprintf +sql +sqlar +sqlite +sqliteplocks +sqliterc +sqllog +sqllogglobal +sqlthread +sqr +sqrt +src +srcck +statfs +stderr +stdin +stdout +stmt +stmts +str +strace +strcasecmp +strcmp +strdup +strerror +strftime +strglob +stricmp +stringify +strlen +strlike +strncmp +strncpy +strnicmp +stronly +strstr +struct +structs +subbitmap +subcases +subclassed +subclauses +subcomponents +subdirectory +subelement +subexpression +subexpressions +subfunction +subfunctions +subitem +subjournals +sublevels +subnode +suboptimal +subpages +subprocedures +subprog +subprogs +subq +subqueries +subquery +Subrtn +subsec +subsecond +subsequence +substr +substring +substrings +subsubstructure +subsubterms +Subtask +subtasks +subterm +subterms +subtransaction +subtransactions +subtree +subtrees +subtype +subtypes +sumint +superclass +superlock +superset +superunlock +symlinks +synching +sys +syscall +sz +szosfile +tablename +tailval +tailvar +tbl +tblname +Tcl +tcl +Tclcmd +tclcmd +tclsh +tclsqlite +tclvar +td +tempfilename +testcase +testctrl +testfixture +testtag +testvfs +textarray +th +threadid +threadsafe +threadsafety +throughs +tht +timediff +tkt +tm +tmp +tmpdir +tmpfs +tnum +Todo +tokenize +tokenizer +tokenizing +tolower +toobig +toupper +treetrace +treeview +trimleft +trimright +truesize +trys +Tsd +Ts'o +tunable +tvfs +txn +txt +Typecheck +typedef +typedefed +typedefs +typename +typenames +typeof +tz +uber +uid +uint +ul +umask +Un +un +unallocated +unanalyzed +unary +unbuffered +unclosed +uncompiled +uncomputed +undefining +underfull +unexpanded +unfinalized +unfreed +unhex +unicode +unindexed +uninit +uninitialize +unintuitive +unioned +unissued +unix +unixepoch +unlink +unlinked +unlinking +unlinks +unmap +unmapped +unmapping +unoptimized +unparsed +unreduced +unref +unreferenced +unrefs +unregister +unregistering +unregisters +unresolvable +unsynced +unterminated +untracked +untrusted +Upfrom +uppercasing +upr +Upsert +upsert +upto +uptr +uri +userauth +userdata +Userid +usleep +utc +Utf +utf +util +uuu +uuuuu +uuzzzz +va +valgrind +vanishingly +vappendf +vararg +varargs +varint +varints +varname +vcolumn +vdbe +vdbeapi +vdbe's +vdbes +vdbesort +ve +verifications +vfs +vfslog +vfsname +vfs's +vfstrace +vm +vmprintf +vmstep +vsnprintf +vt +vtab +vtabs +Vugt +vvv +vvvv +vvvvv +vvvvvv +vwait +vxworks +wal +wasm +wherecode +whereexpr +wheretrace +whitespace +Willmann +withoutrowid +wr +wrapup +writeable +writecrash +writefile +wsd +ww +wwww +wwzzzzyy +wxyz +xa +xac +xb +xbf +xc +xd +xdg +xe +xf +xfe +xfer +xff +xfff +xfffd +xfffe +xffffffff +x'hhhhhh +xinfo +xlc +xtype +xxxx +xxxxx +xxxxxx +xxxxxxx +xxxxxxxx +xyz +xyzzy +yy +yyxxxxxx +yyy +yyyyy +yyyyyy +zeroblob +Zeroblobs +zerodata +zeropad +zipfile +zipvfs +zplan +zulu +zzzz +zzzzyyyy diff -Nru sqlite3-3.42.0/tool/fuzzershell.c sqlite3-3.44.0-0/tool/fuzzershell.c --- sqlite3-3.42.0/tool/fuzzershell.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/fuzzershell.c 2023-11-04 14:23:59.000000000 +0000 @@ -680,6 +680,11 @@ 0, /* xRollback */ 0, /* xFindMethod */ 0, /* xRename */ + 0, /* xSavepoint */ + 0, /* xRelease */ + 0, /* xRollbackTo */ + 0, /* xShadowName */ + 0 /* xIntegrity */ }; /* END the generate_series(START,END,STEP) implementation *********************************************************************************/ diff -Nru sqlite3-3.42.0/tool/lemon.c sqlite3-3.44.0-0/tool/lemon.c --- sqlite3-3.42.0/tool/lemon.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/lemon.c 2023-11-04 14:23:59.000000000 +0000 @@ -426,7 +426,8 @@ int printPreprocessed; /* Show preprocessor output on stdout */ int has_fallback; /* True if any %fallback is seen in the grammar */ int nolinenosflag; /* True if #line statements should not be printed */ - char *argv0; /* Name of the program */ + int argc; /* Number of command-line arguments */ + char **argv; /* Command-line arguments */ }; #define MemoryCheck(X) if((X)==0){ \ @@ -1516,8 +1517,10 @@ exit(1); } -static int nDefine = 0; /* Number of -D options on the command line */ -static char **azDefine = 0; /* Name of the -D macros */ +static int nDefine = 0; /* Number of -D options on the command line */ +static int nDefineUsed = 0; /* Number of -D options actually used */ +static char **azDefine = 0; /* Name of the -D macros */ +static char *bDefineUsed = 0; /* True for every -D macro actually used */ /* This routine is called with the argument to each -D command-line option. ** Add the macro defined to the azDefine array. @@ -1530,6 +1533,12 @@ fprintf(stderr,"out of memory\n"); exit(1); } + bDefineUsed = (char*)realloc(bDefineUsed, nDefine); + if( bDefineUsed==0 ){ + fprintf(stderr,"out of memory\n"); + exit(1); + } + bDefineUsed[nDefine-1] = 0; paz = &azDefine[nDefine-1]; *paz = (char *) malloc( lemonStrlen(z)+1 ); if( *paz==0 ){ @@ -1666,7 +1675,6 @@ struct lemon lem; struct rule *rp; - (void)argc; OptInit(argv,options,stderr); if( version ){ printf("Lemon version 1.0\n"); @@ -1683,7 +1691,8 @@ Strsafe_init(); Symbol_init(); State_init(); - lem.argv0 = argv[0]; + lem.argv = argv; + lem.argc = argc; lem.filename = OptArg(0); lem.basisflag = basisflag; lem.nolinenosflag = nolinenosflag; @@ -2856,6 +2865,10 @@ res = 0; for(j=0; jargv0,templatename,0); + toFree = tpltname = pathsearch(lemp->argv[0],templatename,0); } if( tpltname==0 ){ fprintf(stderr,"Can't find the parser driver template file \"%s\".\n", @@ -4396,7 +4409,17 @@ fprintf(out, "/* This file is automatically generated by Lemon from input grammar\n" - "** source file \"%s\". */\n", lemp->filename); lineno += 2; + "** source file \"%s\"", lemp->filename); lineno++; + if( nDefineUsed==0 ){ + fprintf(out, ".\n*/\n"); lineno += 2; + }else{ + fprintf(out, " with these options:\n**\n"); lineno += 2; + for(i=0; i=2 ){\n"); - printf(" i = ((charMap(z[0])*%d) %c", HASH_C0, HASH_CC); + printf(" assert( n>=2 );\n"); + printf(" i = ((charMap(z[0])*%d) %c", HASH_C0, HASH_CC); printf(" (charMap(z[n-1])*%d) %c", HASH_C1, HASH_CC); printf(" n*%d) %% %d;\n", HASH_C2, bestSize); - printf(" for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){\n"); - printf(" if( aKWLen[i]!=n ) continue;\n"); - printf(" zKW = &zKWText[aKWOffset[i]];\n"); + printf(" for(i=(int)aKWHash[i]; i>0; i=aKWNext[i]){\n"); + printf(" if( aKWLen[i]!=n ) continue;\n"); + printf(" zKW = &zKWText[aKWOffset[i]];\n"); printf("#ifdef SQLITE_ASCII\n"); - printf(" if( (z[0]&~0x20)!=zKW[0] ) continue;\n"); - printf(" if( (z[1]&~0x20)!=zKW[1] ) continue;\n"); - printf(" j = 2;\n"); - printf(" while( j=2 ) keywordCode((char*)z, n, &id);\n"); printf(" return id;\n"); printf("}\n"); printf("#define SQLITE_N_KEYWORD %d\n", nKeyword); diff -Nru sqlite3-3.42.0/tool/mksqlite3c.tcl sqlite3-3.44.0-0/tool/mksqlite3c.tcl --- sqlite3-3.42.0/tool/mksqlite3c.tcl 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/mksqlite3c.tcl 2023-11-04 14:23:59.000000000 +0000 @@ -106,7 +106,30 @@ ** if you want a wrapper to interface SQLite with your choice of programming ** language. The code for the "sqlite3" command-line shell is also in a ** separate file. This file contains only code for the core SQLite library. -*/ +**}] +set srcroot [file dirname [file dirname [info script]]] +if {$tcl_platform(platform)=="windows"} { + set vsrcprog src-verify.exe +} else { + set vsrcprog ./src-verify +} +if {[file executable $vsrcprog] && [file readable $srcroot/manifest]} { + set res [string trim [split [exec $vsrcprog -x $srcroot]] \n] + puts $out "** The content in this amalgamation comes from Fossil check-in" + puts -nonewline $out "** [string range [lindex $res 0] 0 35]" + if {[llength $res]==1} { + puts $out "." + } else { + puts $out " with changes in files:\n**" + foreach f [lrange $res 1 end] { + puts $out "** $f" + } + } +} else { + puts $out "** The origin of the sources used to build this amalgamation" + puts $out "** is unknown." +} +puts $out [subst {*/ #define SQLITE_CORE 1 #define SQLITE_AMALGAMATION 1}] if {$addstatic} { diff -Nru sqlite3-3.42.0/tool/mktoolzip.tcl sqlite3-3.44.0-0/tool/mktoolzip.tcl --- sqlite3-3.42.0/tool/mktoolzip.tcl 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/tool/mktoolzip.tcl 2023-11-04 14:23:59.000000000 +0000 @@ -0,0 +1,69 @@ +#!/usr/bin/tclsh +# +# Run this script in order to generate a ZIP archive containing various +# command-line tools. +# +# The makefile that invokes this script must first build the following +# binaries: +# +# testfixture -- used to run this script +# sqlite3 -- the SQLite CLI +# sqldiff -- Program to diff two databases +# sqlite3_analyzer -- Space analyzer +# +switch $tcl_platform(os) { + {Windows NT} { + set OS win32 + set EXE .exe + } + Linux { + set OS linux + set EXE {} + } + Darwin { + set OS osx + set EXE {} + } + default { + set OS unknown + set EXE {} + } +} +switch $tcl_platform(machine) { + arm64 { + set ARCH arm64 + } + x86_64 { + set ARCH x64 + } + amd64 - + intel { + if {$tcl_platform(pointerSize)==4} { + set ARCH x86 + } else { + set ARCH x64 + } + } + default { + set ARCH unk + } +} +set in [open [file join [file dirname [file dirname [info script]]] VERSION]] +set vers [read $in] +close $in +scan $vers %d.%d.%d v1 v2 v3 +set v2 [format 3%02d%02d00 $v2 $v3] +set name sqlite-tools-$OS-$ARCH-$v2.zip + +if {$OS=="win32"} { + # The win32 tar.exe supports the -a ("auto-compress") option. This causes + # tar to create an archive type based on the extension of the output file. + # In this case, a zip file. + puts "tar -a -cf $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE" + puts [exec tar -a -cf $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE] + puts "$name: [file size $name] bytes" +} else { + puts "zip $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE" + puts [exec zip $name sqlite3$EXE sqldiff$EXE sqlite3_analyzer$EXE] + puts [exec ls -l $name] +} diff -Nru sqlite3-3.42.0/tool/showdb.c sqlite3-3.44.0-0/tool/showdb.c --- sqlite3-3.42.0/tool/showdb.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/showdb.c 2023-11-04 14:23:59.000000000 +0000 @@ -959,6 +959,10 @@ a = fileRead((pgno-1)*g.pagesize, g.pagesize); iNext = decodeInt32(a); n = decodeInt32(a+4); + if( n>(g.pagesize - 8)/4 ){ + printf("ERROR: page %d too many freelist entries (%d)\n", pgno, n); + n = (g.pagesize - 8)/4; + } for(i=0; i65536 ){ + printf("\"%s\": invalid page size.\n", argv[1]); + return 1; + } mxFrame = (sbuf.st_size - 32)/(pagesize + 24); printf("Available pages: 1..%d\n", mxFrame); if( argc==2 ){ diff -Nru sqlite3-3.42.0/tool/spaceanal.tcl sqlite3-3.44.0-0/tool/spaceanal.tcl --- sqlite3-3.42.0/tool/spaceanal.tcl 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/spaceanal.tcl 2023-11-04 14:23:59.000000000 +0000 @@ -581,6 +581,7 @@ set inuse_percent [percent $inuse_pgcnt $file_pgcnt] set free_pgcnt [expr {$file_pgcnt-$inuse_pgcnt-$av_pgcnt}] +if {$file_bytes>1073741824 && $free_pgcnt>0} {incr free_pgcnt -1} set free_percent [percent $free_pgcnt $file_pgcnt] set free_pgcnt2 [db one {PRAGMA freelist_count}] set free_percent2 [percent $free_pgcnt2 $file_pgcnt] diff -Nru sqlite3-3.42.0/tool/speed-check.sh sqlite3-3.44.0-0/tool/speed-check.sh --- sqlite3-3.42.0/tool/speed-check.sh 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/speed-check.sh 2023-11-04 14:23:59.000000000 +0000 @@ -99,6 +99,9 @@ --stmtcache) shift; SPEEDTEST_OPTS="$SPEEDTEST_OPTS --stmtcache $1" ;; + --nolongdouble) + SPEEDTEST_OPTS="$SPEEDTEST_OPTS --nolongdouble" + ;; --checkpoint) SPEEDTEST_OPTS="$SPEEDTEST_OPTS --checkpoint" ;; diff -Nru sqlite3-3.42.0/tool/spellsift.tcl sqlite3-3.44.0-0/tool/spellsift.tcl --- sqlite3-3.42.0/tool/spellsift.tcl 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/tool/spellsift.tcl 2023-11-04 14:23:59.000000000 +0000 @@ -0,0 +1,74 @@ +#!/usr/bin/tclsh + +set usage { + Usage: spellsift.tcl + The named .c and .h source files comment blocks are spell-checked. +} + +if {[llength $argv] == 0} { + puts stderr $usage + exit 0 +} + +# Want a Tcl version with 3-argument close. +package require Tcl 8.6 + +set ::spellchk "aspell --extra-dicts ./custom.rws list" + +# Run text through aspell with custom dictionary, return finds. +proc misspelled {text} { + set spellerr [open "|$::spellchk" r+] + puts $spellerr $text + flush $spellerr + close $spellerr write + set huhq [regsub {\s*$} [read $spellerr] {}] + close $spellerr read + return [split $huhq "\n"] +} + +# Eliminate some common patterns that need not be well spelled. +proc decruft {text} { + set nopp [regsub -all "\n *#\[^\n\]*\n" $text "\n\n" ] + set noticket [regsub -all {Ticket \[?[0-9a-f]+\]?} $nopp "" ] + return $noticket +} + +# Sift out common variable spellings not in normal dictionaries. +proc varsift {words} { + set rv [list] + foreach w $words { + set n [string length $w] + set cr [string range $w 1 end] + if {[string tolower $cr] ne $cr} continue + lappend rv $w; + } + return $rv +} + +foreach fname $argv { + set ich [open $fname r] + set dtext [decruft [read $ich]] + close $ich + set cbounds [regexp -indices -inline -all {(/\*)|(\*/)} $dtext] + set ccb -1 + set cblocks [list] + foreach {ap cb ce} $cbounds { + set cib [lindex $cb 1] + set cie [lindex $ce 0] + if {$cie != -1} { + if {$ccb != -1} { + set cce [expr $cie - 1] + set destar [string map [list * " "] [string range $dtext $ccb $cce]] + lappend cblocks $destar + set ccb -1 + } else continue + } elseif {$cib != -1} { + set ccb [expr $cib + 1] + } + } + set oddspells [varsift [misspelled [join $cblocks "\n"]]] + if {[llength $oddspells] > 0} { + puts "!? Misspellings from $fname:" + puts [join [lsort -nocase -unique $oddspells] "\n"] + } +} diff -Nru sqlite3-3.42.0/tool/sqldiff.c sqlite3-3.44.0-0/tool/sqldiff.c --- sqlite3-3.42.0/tool/sqldiff.c 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/sqldiff.c 2023-11-04 14:23:59.000000000 +0000 @@ -596,7 +596,9 @@ /* Build the comparison query */ for(n2=n; az2[n2]; n2++){ - fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, safeId(az2[n2])); + char *zNTab = safeId(az2[n2]); + fprintf(out, "ALTER TABLE %s ADD COLUMN %s;\n", zId, zNTab); + sqlite3_free(zNTab); } nQ = nPk2+1+2*(n2-nPk2); if( n2>nPk2 ){ @@ -605,18 +607,18 @@ strPrintf(&sql, "%sB.%s", zSep, az[i]); zSep = ", "; } - strPrintf(&sql, ", 1%s -- changed row\n", nPk==n ? "" : ","); + strPrintf(&sql, ", 1 /* changed row */"); while( az[i] ){ - strPrintf(&sql, " A.%s IS NOT B.%s, B.%s%s\n", - az[i], az2[i], az2[i], az2[i+1]==0 ? "" : ","); + strPrintf(&sql, ", A.%s IS NOT B.%s, B.%s", + az[i], az2[i], az2[i]); i++; } while( az2[i] ){ - strPrintf(&sql, " B.%s IS NOT NULL, B.%s%s\n", - az2[i], az2[i], az2[i+1]==0 ? "" : ","); + strPrintf(&sql, ", B.%s IS NOT NULL, B.%s", + az2[i], az2[i]); i++; } - strPrintf(&sql, " FROM main.%s A, aux.%s B\n", zId, zId); + strPrintf(&sql, "\n FROM main.%s A, aux.%s B\n", zId, zId); zSep = " WHERE"; for(i=0; i +#include +#include +#if !defined(_WIN32) +# include +#else +# include +# ifndef R_OK +# define R_OK 04 +# endif +# ifndef access +# define access(f,m) _access((f),(m)) +# endif +#endif +typedef unsigned long long int u64; + +/* +** The SHA1 implementation below is adapted from: +** +** $NetBSD: sha1.c,v 1.6 2009/11/06 20:31:18 joerg Exp $ +** $OpenBSD: sha1.c,v 1.9 1997/07/23 21:12:32 kstailey Exp $ +** +** SHA-1 in C +** By Steve Reid +** 100% Public Domain +*/ +typedef struct SHA1Context SHA1Context; +struct SHA1Context { + unsigned int state[5]; + unsigned int count[2]; + unsigned char buffer[64]; +}; + +/* + * blk0() and blk() perform the initial expand. + * I got the idea of expanding during the round function from SSLeay + * + * blk0le() for little-endian and blk0be() for big-endian. + */ +#define SHA_ROT(x,l,r) ((x) << (l) | (x) >> (r)) +#define rol(x,k) SHA_ROT(x,k,32-(k)) +#define ror(x,k) SHA_ROT(x,32-(k),k) +#define blk0le(i) (block[i] = (ror(block[i],8)&0xFF00FF00) \ + |(rol(block[i],8)&0x00FF00FF)) +#define blk0be(i) block[i] +#define blk(i) (block[i&15] = rol(block[(i+13)&15]^block[(i+8)&15] \ + ^block[(i+2)&15]^block[i&15],1)) + +/* + * (R0+R1), R2, R3, R4 are the different operations (rounds) used in SHA1 + * + * Rl0() for little-endian and Rb0() for big-endian. Endianness is + * determined at run-time. + */ +#define Rl0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0le(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define Rb0(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk0be(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R1(v,w,x,y,z,i) \ + z+=((w&(x^y))^y)+blk(i)+0x5A827999+rol(v,5);w=ror(w,2); +#define R2(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0x6ED9EBA1+rol(v,5);w=ror(w,2); +#define R3(v,w,x,y,z,i) \ + z+=(((w|x)&y)|(w&x))+blk(i)+0x8F1BBCDC+rol(v,5);w=ror(w,2); +#define R4(v,w,x,y,z,i) \ + z+=(w^x^y)+blk(i)+0xCA62C1D6+rol(v,5);w=ror(w,2); + +/* + * Hash a single 512-bit block. This is the core of the algorithm. + */ +#define a qq[0] +#define b qq[1] +#define c qq[2] +#define d qq[3] +#define e qq[4] + +void SHA1Transform(unsigned int state[5], const unsigned char buffer[64]) +{ + unsigned int qq[5]; /* a, b, c, d, e; */ + static int one = 1; + unsigned int block[16]; + memcpy(block, buffer, 64); + memcpy(qq,state,5*sizeof(unsigned int)); + + /* Copy context->state[] to working vars */ + /* + a = state[0]; + b = state[1]; + c = state[2]; + d = state[3]; + e = state[4]; + */ + + /* 4 rounds of 20 operations each. Loop unrolled. */ + if( 1 == *(unsigned char*)&one ){ + Rl0(a,b,c,d,e, 0); Rl0(e,a,b,c,d, 1); Rl0(d,e,a,b,c, 2); Rl0(c,d,e,a,b, 3); + Rl0(b,c,d,e,a, 4); Rl0(a,b,c,d,e, 5); Rl0(e,a,b,c,d, 6); Rl0(d,e,a,b,c, 7); + Rl0(c,d,e,a,b, 8); Rl0(b,c,d,e,a, 9); Rl0(a,b,c,d,e,10); Rl0(e,a,b,c,d,11); + Rl0(d,e,a,b,c,12); Rl0(c,d,e,a,b,13); Rl0(b,c,d,e,a,14); Rl0(a,b,c,d,e,15); + }else{ + Rb0(a,b,c,d,e, 0); Rb0(e,a,b,c,d, 1); Rb0(d,e,a,b,c, 2); Rb0(c,d,e,a,b, 3); + Rb0(b,c,d,e,a, 4); Rb0(a,b,c,d,e, 5); Rb0(e,a,b,c,d, 6); Rb0(d,e,a,b,c, 7); + Rb0(c,d,e,a,b, 8); Rb0(b,c,d,e,a, 9); Rb0(a,b,c,d,e,10); Rb0(e,a,b,c,d,11); + Rb0(d,e,a,b,c,12); Rb0(c,d,e,a,b,13); Rb0(b,c,d,e,a,14); Rb0(a,b,c,d,e,15); + } + R1(e,a,b,c,d,16); R1(d,e,a,b,c,17); R1(c,d,e,a,b,18); R1(b,c,d,e,a,19); + R2(a,b,c,d,e,20); R2(e,a,b,c,d,21); R2(d,e,a,b,c,22); R2(c,d,e,a,b,23); + R2(b,c,d,e,a,24); R2(a,b,c,d,e,25); R2(e,a,b,c,d,26); R2(d,e,a,b,c,27); + R2(c,d,e,a,b,28); R2(b,c,d,e,a,29); R2(a,b,c,d,e,30); R2(e,a,b,c,d,31); + R2(d,e,a,b,c,32); R2(c,d,e,a,b,33); R2(b,c,d,e,a,34); R2(a,b,c,d,e,35); + R2(e,a,b,c,d,36); R2(d,e,a,b,c,37); R2(c,d,e,a,b,38); R2(b,c,d,e,a,39); + R3(a,b,c,d,e,40); R3(e,a,b,c,d,41); R3(d,e,a,b,c,42); R3(c,d,e,a,b,43); + R3(b,c,d,e,a,44); R3(a,b,c,d,e,45); R3(e,a,b,c,d,46); R3(d,e,a,b,c,47); + R3(c,d,e,a,b,48); R3(b,c,d,e,a,49); R3(a,b,c,d,e,50); R3(e,a,b,c,d,51); + R3(d,e,a,b,c,52); R3(c,d,e,a,b,53); R3(b,c,d,e,a,54); R3(a,b,c,d,e,55); + R3(e,a,b,c,d,56); R3(d,e,a,b,c,57); R3(c,d,e,a,b,58); R3(b,c,d,e,a,59); + R4(a,b,c,d,e,60); R4(e,a,b,c,d,61); R4(d,e,a,b,c,62); R4(c,d,e,a,b,63); + R4(b,c,d,e,a,64); R4(a,b,c,d,e,65); R4(e,a,b,c,d,66); R4(d,e,a,b,c,67); + R4(c,d,e,a,b,68); R4(b,c,d,e,a,69); R4(a,b,c,d,e,70); R4(e,a,b,c,d,71); + R4(d,e,a,b,c,72); R4(c,d,e,a,b,73); R4(b,c,d,e,a,74); R4(a,b,c,d,e,75); + R4(e,a,b,c,d,76); R4(d,e,a,b,c,77); R4(c,d,e,a,b,78); R4(b,c,d,e,a,79); + + /* Add the working vars back into context.state[] */ + state[0] += a; + state[1] += b; + state[2] += c; + state[3] += d; + state[4] += e; +} + +/* + * SHA1Init - Initialize new context + */ +static void SHA1Init(SHA1Context *context){ + /* SHA1 initialization constants */ + context->state[0] = 0x67452301; + context->state[1] = 0xEFCDAB89; + context->state[2] = 0x98BADCFE; + context->state[3] = 0x10325476; + context->state[4] = 0xC3D2E1F0; + context->count[0] = context->count[1] = 0; +} + + +/* + * Run your data through this. + */ +static void SHA1Update( + SHA1Context *context, + const unsigned char *data, + unsigned int len +){ + unsigned int i, j; + + j = context->count[0]; + if ((context->count[0] += len << 3) < j) + context->count[1] += (len>>29)+1; + j = (j >> 3) & 63; + if ((j + len) > 63) { + (void)memcpy(&context->buffer[j], data, (i = 64-j)); + SHA1Transform(context->state, context->buffer); + for ( ; i + 63 < len; i += 64) + SHA1Transform(context->state, &data[i]); + j = 0; + } else { + i = 0; + } + (void)memcpy(&context->buffer[j], &data[i], len - i); +} + + +/* + * Add padding and return the message digest. + */ +static void SHA1Final(unsigned char *digest, SHA1Context *context){ + unsigned int i; + unsigned char finalcount[8]; + + for (i = 0; i < 8; i++) { + finalcount[i] = (unsigned char)((context->count[(i >= 4 ? 0 : 1)] + >> ((3-(i & 3)) * 8) ) & 255); /* Endian independent */ + } + SHA1Update(context, (const unsigned char *)"\200", 1); + while ((context->count[0] & 504) != 448) + SHA1Update(context, (const unsigned char *)"\0", 1); + SHA1Update(context, finalcount, 8); /* Should cause a SHA1Transform() */ + + if (digest) { + for (i = 0; i < 20; i++) + digest[i] = (unsigned char) + ((context->state[i>>2] >> ((3-(i & 3)) * 8) ) & 255); + } +} + + +/* +** Macros to determine whether the machine is big or little endian, +** and whether or not that determination is run-time or compile-time. +** +** For best performance, an attempt is made to guess at the byte-order +** using C-preprocessor macros. If that is unsuccessful, or if +** -DSHA3_BYTEORDER=0 is set, then byte-order is determined +** at run-time. +*/ +#ifndef SHA3_BYTEORDER +# if defined(i386) || defined(__i386__) || defined(_M_IX86) || \ + defined(__x86_64) || defined(__x86_64__) || defined(_M_X64) || \ + defined(_M_AMD64) || defined(_M_ARM) || defined(__x86) || \ + defined(__arm__) +# define SHA3_BYTEORDER 1234 +# elif defined(sparc) || defined(__ppc__) +# define SHA3_BYTEORDER 4321 +# else +# define SHA3_BYTEORDER 0 +# endif +#endif + + +/* +** State structure for a SHA3 hash in progress +*/ +typedef struct SHA3Context SHA3Context; +struct SHA3Context { + union { + u64 s[25]; /* Keccak state. 5x5 lines of 64 bits each */ + unsigned char x[1600]; /* ... or 1600 bytes */ + } u; + unsigned nRate; /* Bytes of input accepted per Keccak iteration */ + unsigned nLoaded; /* Input bytes loaded into u.x[] so far this cycle */ + unsigned ixMask; /* Insert next input into u.x[nLoaded^ixMask]. */ +}; + +/* +** A single step of the Keccak mixing function for a 1600-bit state +*/ +static void KeccakF1600Step(SHA3Context *p){ + int i; + u64 B0, B1, B2, B3, B4; + u64 C0, C1, C2, C3, C4; + u64 D0, D1, D2, D3, D4; + static const u64 RC[] = { + 0x0000000000000001ULL, 0x0000000000008082ULL, + 0x800000000000808aULL, 0x8000000080008000ULL, + 0x000000000000808bULL, 0x0000000080000001ULL, + 0x8000000080008081ULL, 0x8000000000008009ULL, + 0x000000000000008aULL, 0x0000000000000088ULL, + 0x0000000080008009ULL, 0x000000008000000aULL, + 0x000000008000808bULL, 0x800000000000008bULL, + 0x8000000000008089ULL, 0x8000000000008003ULL, + 0x8000000000008002ULL, 0x8000000000000080ULL, + 0x000000000000800aULL, 0x800000008000000aULL, + 0x8000000080008081ULL, 0x8000000000008080ULL, + 0x0000000080000001ULL, 0x8000000080008008ULL + }; +# define A00 (p->u.s[0]) +# define A01 (p->u.s[1]) +# define A02 (p->u.s[2]) +# define A03 (p->u.s[3]) +# define A04 (p->u.s[4]) +# define A10 (p->u.s[5]) +# define A11 (p->u.s[6]) +# define A12 (p->u.s[7]) +# define A13 (p->u.s[8]) +# define A14 (p->u.s[9]) +# define A20 (p->u.s[10]) +# define A21 (p->u.s[11]) +# define A22 (p->u.s[12]) +# define A23 (p->u.s[13]) +# define A24 (p->u.s[14]) +# define A30 (p->u.s[15]) +# define A31 (p->u.s[16]) +# define A32 (p->u.s[17]) +# define A33 (p->u.s[18]) +# define A34 (p->u.s[19]) +# define A40 (p->u.s[20]) +# define A41 (p->u.s[21]) +# define A42 (p->u.s[22]) +# define A43 (p->u.s[23]) +# define A44 (p->u.s[24]) +# define ROL64(a,x) ((a<>(64-x))) + + for(i=0; i<24; i+=4){ + C0 = A00^A10^A20^A30^A40; + C1 = A01^A11^A21^A31^A41; + C2 = A02^A12^A22^A32^A42; + C3 = A03^A13^A23^A33^A43; + C4 = A04^A14^A24^A34^A44; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A11^D1), 44); + B2 = ROL64((A22^D2), 43); + B3 = ROL64((A33^D3), 21); + B4 = ROL64((A44^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i]; + A11 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A20^D0), 3); + B3 = ROL64((A31^D1), 45); + B4 = ROL64((A42^D2), 61); + B0 = ROL64((A03^D3), 28); + B1 = ROL64((A14^D4), 20); + A20 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A40^D0), 18); + B0 = ROL64((A01^D1), 1); + B1 = ROL64((A12^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A34^D4), 8); + A40 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A10^D0), 36); + B2 = ROL64((A21^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A43^D3), 56); + B0 = ROL64((A04^D4), 27); + A10 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A30^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A02^D2), 62); + B1 = ROL64((A13^D3), 55); + B2 = ROL64((A24^D4), 39); + A30 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + C0 = A00^A20^A40^A10^A30; + C1 = A11^A31^A01^A21^A41; + C2 = A22^A42^A12^A32^A02; + C3 = A33^A03^A23^A43^A13; + C4 = A44^A14^A34^A04^A24; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A31^D1), 44); + B2 = ROL64((A12^D2), 43); + B3 = ROL64((A43^D3), 21); + B4 = ROL64((A24^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+1]; + A31 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A40^D0), 3); + B3 = ROL64((A21^D1), 45); + B4 = ROL64((A02^D2), 61); + B0 = ROL64((A33^D3), 28); + B1 = ROL64((A14^D4), 20); + A40 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A30^D0), 18); + B0 = ROL64((A11^D1), 1); + B1 = ROL64((A42^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A04^D4), 8); + A30 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A20^D0), 36); + B2 = ROL64((A01^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A13^D3), 56); + B0 = ROL64((A44^D4), 27); + A20 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A10^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A22^D2), 62); + B1 = ROL64((A03^D3), 55); + B2 = ROL64((A34^D4), 39); + A10 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + C0 = A00^A40^A30^A20^A10; + C1 = A31^A21^A11^A01^A41; + C2 = A12^A02^A42^A32^A22; + C3 = A43^A33^A23^A13^A03; + C4 = A24^A14^A04^A44^A34; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A21^D1), 44); + B2 = ROL64((A42^D2), 43); + B3 = ROL64((A13^D3), 21); + B4 = ROL64((A34^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+2]; + A21 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A30^D0), 3); + B3 = ROL64((A01^D1), 45); + B4 = ROL64((A22^D2), 61); + B0 = ROL64((A43^D3), 28); + B1 = ROL64((A14^D4), 20); + A30 = B0 ^((~B1)& B2 ); + A01 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A10^D0), 18); + B0 = ROL64((A31^D1), 1); + B1 = ROL64((A02^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A44^D4), 8); + A10 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A40^D0), 36); + B2 = ROL64((A11^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A03^D3), 56); + B0 = ROL64((A24^D4), 27); + A40 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A20^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A12^D2), 62); + B1 = ROL64((A33^D3), 55); + B2 = ROL64((A04^D4), 39); + A20 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + C0 = A00^A30^A10^A40^A20; + C1 = A21^A01^A31^A11^A41; + C2 = A42^A22^A02^A32^A12; + C3 = A13^A43^A23^A03^A33; + C4 = A34^A14^A44^A24^A04; + D0 = C4^ROL64(C1, 1); + D1 = C0^ROL64(C2, 1); + D2 = C1^ROL64(C3, 1); + D3 = C2^ROL64(C4, 1); + D4 = C3^ROL64(C0, 1); + + B0 = (A00^D0); + B1 = ROL64((A01^D1), 44); + B2 = ROL64((A02^D2), 43); + B3 = ROL64((A03^D3), 21); + B4 = ROL64((A04^D4), 14); + A00 = B0 ^((~B1)& B2 ); + A00 ^= RC[i+3]; + A01 = B1 ^((~B2)& B3 ); + A02 = B2 ^((~B3)& B4 ); + A03 = B3 ^((~B4)& B0 ); + A04 = B4 ^((~B0)& B1 ); + + B2 = ROL64((A10^D0), 3); + B3 = ROL64((A11^D1), 45); + B4 = ROL64((A12^D2), 61); + B0 = ROL64((A13^D3), 28); + B1 = ROL64((A14^D4), 20); + A10 = B0 ^((~B1)& B2 ); + A11 = B1 ^((~B2)& B3 ); + A12 = B2 ^((~B3)& B4 ); + A13 = B3 ^((~B4)& B0 ); + A14 = B4 ^((~B0)& B1 ); + + B4 = ROL64((A20^D0), 18); + B0 = ROL64((A21^D1), 1); + B1 = ROL64((A22^D2), 6); + B2 = ROL64((A23^D3), 25); + B3 = ROL64((A24^D4), 8); + A20 = B0 ^((~B1)& B2 ); + A21 = B1 ^((~B2)& B3 ); + A22 = B2 ^((~B3)& B4 ); + A23 = B3 ^((~B4)& B0 ); + A24 = B4 ^((~B0)& B1 ); + + B1 = ROL64((A30^D0), 36); + B2 = ROL64((A31^D1), 10); + B3 = ROL64((A32^D2), 15); + B4 = ROL64((A33^D3), 56); + B0 = ROL64((A34^D4), 27); + A30 = B0 ^((~B1)& B2 ); + A31 = B1 ^((~B2)& B3 ); + A32 = B2 ^((~B3)& B4 ); + A33 = B3 ^((~B4)& B0 ); + A34 = B4 ^((~B0)& B1 ); + + B3 = ROL64((A40^D0), 41); + B4 = ROL64((A41^D1), 2); + B0 = ROL64((A42^D2), 62); + B1 = ROL64((A43^D3), 55); + B2 = ROL64((A44^D4), 39); + A40 = B0 ^((~B1)& B2 ); + A41 = B1 ^((~B2)& B3 ); + A42 = B2 ^((~B3)& B4 ); + A43 = B3 ^((~B4)& B0 ); + A44 = B4 ^((~B0)& B1 ); + } +} + +/* +** Initialize a new hash. iSize determines the size of the hash +** in bits and should be one of 224, 256, 384, or 512. Or iSize +** can be zero to use the default hash size of 256 bits. +*/ +static void SHA3Init(SHA3Context *p, int iSize){ + memset(p, 0, sizeof(*p)); + if( iSize>=128 && iSize<=512 ){ + p->nRate = (1600 - ((iSize + 31)&~31)*2)/8; + }else{ + p->nRate = (1600 - 2*256)/8; + } +#if SHA3_BYTEORDER==1234 + /* Known to be little-endian at compile-time. No-op */ +#elif SHA3_BYTEORDER==4321 + p->ixMask = 7; /* Big-endian */ +#else + { + static unsigned int one = 1; + if( 1==*(unsigned char*)&one ){ + /* Little endian. No byte swapping. */ + p->ixMask = 0; + }else{ + /* Big endian. Byte swap. */ + p->ixMask = 7; + } + } +#endif +} + +/* +** Make consecutive calls to the SHA3Update function to add new content +** to the hash +*/ +static void SHA3Update( + SHA3Context *p, + const unsigned char *aData, + unsigned int nData +){ + unsigned int i = 0; +#if SHA3_BYTEORDER==1234 + if( (p->nLoaded % 8)==0 && ((aData - (const unsigned char*)0)&7)==0 ){ + for(; i+7u.s[p->nLoaded/8] ^= *(u64*)&aData[i]; + p->nLoaded += 8; + if( p->nLoaded>=p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } + } +#endif + for(; iu.x[p->nLoaded] ^= aData[i]; +#elif SHA3_BYTEORDER==4321 + p->u.x[p->nLoaded^0x07] ^= aData[i]; +#else + p->u.x[p->nLoaded^p->ixMask] ^= aData[i]; +#endif + p->nLoaded++; + if( p->nLoaded==p->nRate ){ + KeccakF1600Step(p); + p->nLoaded = 0; + } + } +} + +/* +** After all content has been added, invoke SHA3Final() to compute +** the final hash. The function returns a pointer to the binary +** hash value. +*/ +static unsigned char *SHA3Final(SHA3Context *p){ + unsigned int i; + if( p->nLoaded==p->nRate-1 ){ + const unsigned char c1 = 0x86; + SHA3Update(p, &c1, 1); + }else{ + const unsigned char c2 = 0x06; + const unsigned char c3 = 0x80; + SHA3Update(p, &c2, 1); + p->nLoaded = p->nRate - 1; + SHA3Update(p, &c3, 1); + } + for(i=0; inRate; i++){ + p->u.x[i+p->nRate] = p->u.x[i^p->ixMask]; + } + return &p->u.x[p->nRate]; +} + +/* +** Convert a digest into base-16. +*/ +static void DigestToBase16(unsigned char *digest, char *zBuf, int nByte){ + static const char zEncode[] = "0123456789abcdef"; + int ix; + + for(ix=0; ix>4)&0xf]; + *zBuf++ = zEncode[*digest++ & 0xf]; + } + *zBuf = '\0'; +} + +/* +** Compute the SHA3-256 checksum of a file on disk. Store the resulting +** checksum in the zCksum. +** +** Return the number of errors. +*/ +void sha3sum_file(const char *zFilename, char *zCksum){ + FILE *in; + SHA3Context ctx; + char zBuf[10240]; + + in = fopen(zFilename,"rb"); + if( in==0 ){ + zCksum[0] = 0; + return; + } + SHA3Init(&ctx, 256); + for(;;){ + size_t n; + n = fread(zBuf, 1, sizeof(zBuf), in); + if( n<=0 ) break; + SHA3Update(&ctx, (unsigned char*)zBuf, (unsigned)n); + } + fclose(in); + DigestToBase16(SHA3Final(&ctx), zCksum, 32); +} + +/* +** Compute the SHA1 checksum of a file on disk. Store the resulting +** checksum in the zCksum. +** +** Return the number of errors. +*/ +void sha1sum_file(const char *zFilename, char *zCksum){ + FILE *in; + SHA1Context ctx; + unsigned char zResult[20]; + char zBuf[10240]; + + in = fopen(zFilename,"rb"); + if( in==0 ){ + zCksum[0] = 0; + return; + } + SHA1Init(&ctx); + for(;;){ + size_t n; + n = fread(zBuf, 1, sizeof(zBuf), in); + if( n<=0 ) break; + SHA1Update(&ctx, (unsigned char*)zBuf, (unsigned)n); + } + fclose(in); + SHA1Final(zResult, &ctx); + DigestToBase16(zResult, zCksum, 20); +} + +/* +** Decode a fossilized string in-place. +*/ +void defossilize(char *z){ + int i, j, cc; + char *zSlash = strchr(z, '\\'); + if( zSlash==0 ) return; + i = zSlash - z; + for(j=i; (cc=z[i])!=0; i++){ + if( cc=='\\' && z[i+1] ){ + i++; + switch( z[i] ){ + case 'n': cc = '\n'; break; + case 's': cc = ' '; break; + case 't': cc = '\t'; break; + case 'r': cc = '\r'; break; + case 'v': cc = '\v'; break; + case 'f': cc = '\f'; break; + case '0': cc = 0; break; + case '\\': cc = '\\'; break; + default: cc = z[i]; break; + } + } + z[j++] = cc; + } + if( z[j] ) z[j] = 0; +} + +/* +** Report that a single file is incorrect. +*/ +static void errorMsg(int *pnErr, const char *zVers, const char *zFile){ + if( *pnErr==0 ){ + printf("Derived from %.25s with changes to:\n", zVers); + } + printf(" %s\n", zFile); + (*pnErr)++; +} +static void errorMsgNH(int *pnErr, const char *zVers, const char *zFile){ + if( *pnErr==0 ){ + printf("%s\n", zVers); + } + printf("%s\n", zFile); + (*pnErr)++; +} + +int main(int argc, char **argv){ + int i, j; + int nDir; + FILE *in; + int bDebug = 0; + int bNonHuman = 0; + int bSeenManifestErr = 0; + int nErr = 0; + SHA3Context ctx3; + const char *zDir = 0; + void (*xErr)(int*,const char*,const char*); + char zHash[100]; + char zCk[100]; + char zVers[100]; + char zLine[40000]; + char zFile[40000]; + xErr = errorMsg; + for(i=1; i1000 ){ + fprintf(stderr, "Directory argument too big: [%s]\n", zDir); + return 1; + } + nDir = (int)strlen(zDir); + if( nDir<0 ){ + fprintf(stderr, "Directory argument too short.\n"); + return 1; + } + memcpy(zFile, zDir, nDir); + if( zFile[nDir-1]!='/' ){ + zFile[nDir++] = '/'; + } + memcpy(&zFile[nDir], "manifest", 9); + if( bDebug ){ + printf("manifest file: [%s]\n", zFile); + } + in = fopen(zFile, "rb"); + if( in==0 ){ + fprintf(stderr, "missing manifest: \"%s\"\n", zFile); + return 1; + } + SHA3Init(&ctx3, 256); + while( fgets(zLine, sizeof(zLine), in) ){ + if( zLine[0]=='#' ) break; + SHA3Update(&ctx3, (unsigned char*)zLine, (int)strlen(zLine)); + } + DigestToBase16(SHA3Final(&ctx3), zVers, 32); + + rewind(in); + while( fgets(zLine, sizeof(zLine), in) ){ + if( zLine[0]!='F' ) continue; + if( zLine[1]!=' ' ) continue; + for(i=2, j=nDir; zLine[i]!=0 && zLine[i]!=' '; i++, j++){ + if( j='0' && zLine[i]<='f'; i++, j++){ + if( j +#include +static void usage(const char *zAppName){ + puts("Emits version info about the sqlite3 it is built against."); + printf("Usage: %s [--quote] --INFO-FLAG:\n\n", zAppName); + puts(" --version Emit SQLITE_VERSION (3.X.Y)"); + puts(" --version-number Emit SQLITE_VERSION_NUMBER (30XXYYZZ)"); + puts(" --download-version Emit /download.html version number (3XXYYZZ)"); + puts(" --source-id Emit SQLITE_SOURCE_ID"); + puts(" --json Emit all info in JSON form"); + puts("\nThe non-JSON formats may be modified by:\n"); + puts(" --quote Add double quotes around output."); +} + +int main(int argc, char const * const * argv){ + int fJson = 0; + int fVersion = 0; + int fVersionNumber = 0; + int fDlVersion = 0; + int dlVersion = 0; + int fSourceInfo = 0; + int fQuote = 0; + int nFlags = 0; + int i; + + for( i = 1; i < argc; ++i ){ + const char * zArg = argv[i]; + while('-'==*zArg) ++zArg; + if( 0==strcmp("version", zArg) ){ + fVersion = 1; + }else if( 0==strcmp("version-number", zArg) ){ + fVersionNumber = 1; + }else if( 0==strcmp("download-version", zArg) ){ + fDlVersion = 1; + }else if( 0==strcmp("source-id", zArg) ){ + fSourceInfo = 1; + }else if( 0==strcmp("json", zArg) ){ + fJson = 1; + }else if( 0==strcmp("quote", zArg) ){ + fQuote = 1; + --nFlags; + }else{ + printf("Unhandled flag: %s\n", argv[i]); + usage(argv[0]); + return 1; + } + ++nFlags; + } + + if( 0==nFlags ) fJson = 1; + + { + const int v = SQLITE_VERSION_NUMBER; + int ver[4] = {0,0,0,0}; + ver[0] = (v / 1000000) * 1000000; + ver[1] = v % 1000000 / 100 * 1000; + ver[2] = v % 100 * 100; + dlVersion = ver[0] + ver[1] + ver[2] + ver[3]; + } + if( fJson ){ + printf("{\"libVersion\": \"%s\", " + "\"libVersionNumber\": %d, " + "\"sourceId\": \"%s\"," + "\"downloadVersion\": %d}"/*missing newline is intentional*/, + SQLITE_VERSION, + SQLITE_VERSION_NUMBER, + SQLITE_SOURCE_ID, + dlVersion); + }else{ + if(fQuote) printf("%c", '"'); + if( fVersion ){ + printf("%s", SQLITE_VERSION); + }else if( fVersionNumber ){ + printf("%d", SQLITE_VERSION_NUMBER); + }else if( fSourceInfo ){ + printf("%s", SQLITE_SOURCE_ID); + }else if( fDlVersion ){ + printf("%d", dlVersion); + } + if(fQuote) printf("%c", '"'); + puts(""); + } + return 0; +} diff -Nru sqlite3-3.42.0/tool/warnings.sh sqlite3-3.44.0-0/tool/warnings.sh --- sqlite3-3.42.0/tool/warnings.sh 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/tool/warnings.sh 2023-11-04 14:23:59.000000000 +0000 @@ -32,7 +32,6 @@ echo '********** Android configuration ******************************' echo '********** ' Options: $WARNING_ANDROID_OPTS gcc -c \ - -DHAVE_USLEEP=1 \ -DSQLITE_HAVE_ISNAN \ -DSQLITE_DEFAULT_JOURNAL_SIZE_LIMIT=1048576 \ -DSQLITE_THREADSAFE=2 \ diff -Nru sqlite3-3.42.0/VERSION sqlite3-3.44.0-0/VERSION --- sqlite3-3.42.0/VERSION 2023-05-16 13:45:19.000000000 +0000 +++ sqlite3-3.44.0-0/VERSION 2023-11-04 14:23:58.000000000 +0000 @@ -1 +1 @@ -3.42.0 +3.44.1 diff -Nru sqlite3-3.42.0/www/34to35.html sqlite3-3.44.0-0/www/34to35.html --- sqlite3-3.42.0/www/34to35.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/34to35.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
  • Moving From SQLite 3.4.2 to 3.5.0

    @@ -941,5 +917,4 @@ tolerant of highly threaded designs.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/35to36.html sqlite3-3.44.0-0/www/35to36.html --- sqlite3-3.42.0/www/35to36.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/35to36.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Moving From SQLite 3.5.9 to 3.6.0

    SQLite version 3.6.0 (2008-07-16) @@ -351,5 +327,4 @@

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/about.html sqlite3-3.44.0-0/www/about.html --- sqlite3-3.42.0/www/about.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/about.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    About SQLite

    @@ -170,7 +146,7 @@ as a replacement for fopen()

    SQLite is a compact library. -With all features enabled, the library size can be less than 750KiB, +With all features enabled, the library size can be less than 600KiB, depending on the target platform and compiler optimization settings. (64-bit code is larger. And some compiler optimizations such as aggressive function inlining and loop unrolling can cause the @@ -224,5 +200,4 @@ are fast, reliable, and simple to use. Seek forgiveness for yourself as you forgive others. And just as you have received SQLite for free, so also freely give, paying the debt forward.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/affcase1.html sqlite3-3.44.0-0/www/affcase1.html --- sqlite3-3.42.0/www/affcase1.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/affcase1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -682,5 +658,4 @@ predates SQLite. Rather, the point of this article is to use OpenDocument as a concrete example of how SQLite can be used to build better application file formats for future projects. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/aff_short.html sqlite3-3.44.0-0/www/aff_short.html --- sqlite3-3.42.0/www/aff_short.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/aff_short.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -211,5 +187,4 @@ file(1) can determine that the file is associated with your application and is not just a generic SQL database.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/amalgamation.html sqlite3-3.44.0-0/www/amalgamation.html --- sqlite3-3.42.0/www/amalgamation.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/amalgamation.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -129,47 +105,48 @@

    1. Executive Summary

    Over 100 separate source files are concatenated into a -single large file of C-code named "sqlite3.c" and -referred to as "the amalgamation". The amalgamation +single large files of C-code named "sqlite3.c" and +called "the amalgamation". The amalgamation contains everything an application needs to embed SQLite. +The amalgamation file is more than 220,000 lines long and over 7.5 +megabytes in size (as of 2018-11-24).

    Combining all the code for SQLite into one big file makes SQLite -easier to deploy — there is just one file to keep track of. +easier to deploy — there is just one file to keep track of. And because all code is in -a single translation unit, compilers can do -better inter-procedure and inlining optimization -resulting in machine code that is between 5% and 10% faster. +a single translation unit, compilers can do better inter-procedure +optimization resulting in machine code that is between 5% and 10% faster.

    2. The SQLite Amalgamation

    -

    The SQLite library consists of 111 files of C code -(as of Version 3.37.0 - 2021-11-27) -in the core with 22 additional files that -implement certain commonly used extensions. - -Of the 133 +

    The SQLite library consists of 102 files of C code +(as of Version 3.9.0 - 2015-10-14) +in the core with 32 additional files that +implement the FTS3, FTS5, RTREE, DBSTAT, JSON1, and +RBU extensions. +Of the 102 main source files, about 75% are C code and about 25% are C header files. -Most of these are "source" files in the sense that they are stored +Most of these are "source" files in the sense that they are stored in the SQLite version control system and are edited manually in an ordinary text editor. But some of the C-language files are generated using scripts or auxiliary programs. For example, the parse.y -file contains an LALR(1) grammar of the SQL language which is compiled, -by the Lemon parser generator, to produce a parser contained in the file -"parse.c" accompanied by token identifiers in "parse.h". +file contains an LALR(1) grammar of the SQL language which is compiled +down into are parser in files "parse.c" and "parse.h" by the +Lemon parser generator.

    The makefiles for SQLite have an "sqlite3.c" target for building the -amalgamation, to contain all C code for the core SQLite library and the -FTS3, FTS5, RTREE, DBSTAT, JSON1, -RBU and SESSION -extensions. -This file contains about 238K lines of code -(or 145K if you omit blank lines and comments) and is over 8.4 megabytes -in size (as of 2021-12-29). - -

    Though the various extensions are included in the +file we call "the amalgamation". +The amalgamation is a single C code file, named "sqlite3.c", +that contains all C code +for the core SQLite library and the FTS3, FTS5, RTREE, +DBSTAT, JSON1, and RBU extensions. +This file contains about 184K lines of code +(113K if you omit blank lines and comments) and is over 6.4 megabytes +in size. +Though the various extensions are included in the "sqlite3.c" amalgamation file, they are disabled using #ifdef statements. Activate the extensions using compile-time options like: @@ -178,31 +155,31 @@

  • -DSQLITE_ENABLE_FTS5
  • -DSQLITE_ENABLE_RTREE
  • -DSQLITE_ENABLE_DBSTAT_VTAB +
  • -DSQLITE_ENABLE_JSON1
  • -DSQLITE_ENABLE_RBU -
  • -DSQLITE_ENABLE_SESSION
  • -

    The amalgamation contains everything you need to integrate SQLite -into a larger project. Just copy the amalgamation into your source +

    The amalgamation contains everything you need to integrate SQLite +into a larger project. Just copy the amalgamation into your source directory and compile it along with the other C code files in your project. (A more detailed discussion of the compilation process is available.) -You may also want to make use of the "sqlite3.h" header file that -defines the programming API for SQLite. -The sqlite3.h header file is available separately. +You may also want to make use of the "sqlite3.h" header file that +defines the programming API for SQLite. +The sqlite3.h header file is available separately. The sqlite3.h file is also contained within the amalgamation, in -the first few thousand lines. So if you have a copy of -sqlite3.c but cannot seem to locate sqlite3.h, you can always +the first few thousand lines. So if you have a copy of +sqlite3.c but cannot seem to locate sqlite3.h, you can always regenerate the sqlite3.h by copying and pasting from the amalgamation.

    In addition to making SQLite easier to incorporate into other projects, the amalgamation also makes it run faster. Many -compilers are able to do additional optimizations on code when -it is contained with in a single translation unit such as it +compilers are able to do additional optimizations on code when +it is contained with in a single translation unit such as it is in the amalgamation. We have measured performance improvements -of between 5 and 10% when we use the amalgamation to compile +of between 5 and 10% when we use the amalgamation to compile SQLite rather than individual source files. The downside of this -is that the additional optimizations often take the form of +is that the additional optimizations often take the form of function inlining which tends to make the size of the resulting binary image larger.

    @@ -211,7 +188,7 @@

    3. The Split Amalgamation

    Developers sometimes experience trouble debugging the -quarter-million line amalgamation source file because some debuggers +185,000-line-long amalgamation source file because some debuggers are only able to handle source code line numbers less than 32,768. The amalgamation source code runs fine. One just cannot single-step through it in a debugger. @@ -243,7 +220,7 @@

    The amalgamation and the sqlite3.h header file are available on -the download page as a file +the download page as a file named sqlite-amalgamation-X.zip where the X is replaced by the appropriate version number.

    @@ -273,7 +250,7 @@

    5.1. Dependencies

    -

    The build process makes extensive use of the +

    The build process makes extensive use of the Tcl scripting language. You will need to have a copy of TCL installed in order for the make targets above to work. Easy-to-use installers can be obtained from http://www.tcl-lang.org/. @@ -283,5 +260,4 @@

    Additional notes on compiling SQLite can be found on the How To Compile SQLite page. -

    This page last modified on 2023-03-12 14:42:53 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/appfileformat.html sqlite3-3.44.0-0/www/appfileformat.html --- sqlite3-3.42.0/www/appfileformat.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/appfileformat.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -553,5 +529,4 @@ extensible, performant, accessible, concurrent file format. It deserves your consideration as the standard file format on your next application design. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/appfunc.html sqlite3-3.44.0-0/www/appfunc.html --- sqlite3-3.42.0/www/appfunc.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/appfunc.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -523,8 +499,8 @@ where an attacker might be able to surreptiously invoke them by modifying a database schema:

      -
    • In VIEWs. -
    • In TRIGGERSs. +
    • In in VIEWs. +
    • In in TRIGGERSs.
    • In CHECK constraints of a table definition.
    • In DEFAULT constraints of a table definition.
    • In the definitions of generated columns. @@ -562,5 +538,4 @@ and are certain that it can do no harm even if it falls under the control of an attacker.

    • -

      This page last modified on 2023-02-27 02:07:35 UTC

      diff -Nru sqlite3-3.42.0/www/arch.html sqlite3-3.44.0-0/www/arch.html --- sqlite3-3.42.0/www/arch.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/arch.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -314,7 +290,7 @@ vdbe.h header file defines an interface between the virtual machine and the rest of the SQLite library and vdbeInt.h which defines structures and interfaces that -are private to the virtual machine itself. +are private the virtual machine itself. Various other vdbe*.c files are helpers to the virtual machine. The vdbeaux.c file contains utilities used by the virtual machine and interface modules used by the rest of the library to @@ -373,10 +349,10 @@

    OS Interface

    -In order to provide portability across operating systems, -SQLite uses an abstract object called the VFS. Each VFS provides methods -for opening, reading, writing, and closing files on disk, and for other -OS-specific tasks such as finding the current time, or obtaining randomness +In order to provide portability between across operating systems, +SQLite uses abstract object called the VFS. Each VFS provides methods +for opening, read, writing, and closing files on disk, and for other +OS-specific task such as finding the current time, or obtaining randomness to initialize the built-in pseudo-random number generator. SQLite currently provides VFSes for unix (in the os_unix.c file) and Windows (in the os_win.c file). @@ -405,5 +381,4 @@ build of the library.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/assert.html sqlite3-3.44.0-0/www/assert.html --- sqlite3-3.42.0/www/assert.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/assert.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -366,5 +342,4 @@ cases of an inequality comparison are checked. For example, at https://sqlite.org/src/artifact/18a53540aa3?ln=5766. These kind of checks help to prevent off-by-one errors. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/asyncvfs.html sqlite3-3.44.0-0/www/asyncvfs.html --- sqlite3-3.42.0/www/asyncvfs.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/asyncvfs.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    An Asynchronous I/O Module For SQLite

    @@ -293,5 +269,4 @@

    The functionality required of each of the above functions is described in comments in sqlite3async.c. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/atomiccommit.html sqlite3-3.44.0-0/www/atomiccommit.html --- sqlite3-3.42.0/www/atomiccommit.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/atomiccommit.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    +
    @@ -266,5 +242,4 @@ table column other than INTEGER PRIMARY KEY. Any attempt to use AUTOINCREMENT on a WITHOUT ROWID table or on a column other than the INTEGER PRIMARY KEY column results in an error.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/backup.html sqlite3-3.44.0-0/www/backup.html --- sqlite3-3.42.0/www/backup.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/backup.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -165,17 +141,13 @@

    The Online Backup API was created to address these concerns. The online backup API allows the contents of - one database to be copied into another database file, replacing any + one database to be copied into another database, overwriting the original contents of the target database. The copy operation may be done incrementally, in which case the source database does not need to be locked for the duration of the copy, only for the brief periods of time when it is actually being read from. This allows other database - users to continue without excessive delays while a backup of an online - database is made. -

    - The effect of completing the backup call sequence is to make the - destination a bit-wise identical copy of the source database as it - was when the copying commenced. (The destination becomes a "snapshot.") + users to continue uninterrupted while a backup of an online database is + made.

    The online backup API is documented here. @@ -487,5 +459,4 @@

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/bindptr.html sqlite3-3.44.0-0/www/bindptr.html --- sqlite3-3.42.0/www/bindptr.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/bindptr.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -547,6 +523,13 @@ of a pointer value destroys the pointer and transforms the value into an ordinary SQL NULL. +

    +Both the pointer and the pointer type parameter to the +sqlite3_bind_pointer() and sqlite3_result_pointer() interfaces +are "owned" by the caller. In other words, the caller is responsible +for ensuring that both values remain valid until after the last access +via sqlite3_value_pointer(). +

    5. Summary

    Key take-aways from this essay: @@ -592,5 +575,4 @@ string literal that appears directly in the API call. The pointer type should not be a parameter passed in from a higher-level function.

    -

    This page last modified on 2022-10-07 10:23:26 UTC

    diff -Nru sqlite3-3.42.0/www/books.html sqlite3-3.44.0-0/www/books.html --- sqlite3-3.42.0/www/books.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/books.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -127,7 +103,7 @@

    Author: Paul Sanderson
    -Publisher: Amazon +Publisher: Amazon

    This text by noted digital forensics expert, Paul Sanderson, provides @@ -147,7 +123,7 @@ from the data alone. The book covers basic SQL queries and how they can be used to create a custom report that includes data from different tables, and shows how one can use SQL queries to test hypotheses about -the relationships of data in different tables. +the relationships of data in different tables.

    This book is aimed mainly at forensic practitioners, and it is assumed that the reader has some basic @@ -163,14 +139,14 @@

    Learning SQLite for iOS (2016)

    -Author: Gene Da Rocha
    +Author: Gene Da Rocha
    Publisher: Packt Publishing

    This book starts with the architecture of SQLite database and introduces you to concepts in SQL. You will find yourself equipped to design your own database system, administer it, and maintain it. Further, you will -learn how to operate your SQLite databases smoothly using SQL commands. +learn how to operate your SQLite databases smoothly using SQL commands.

    You will be able to extend the functionality of SQLite by using its vast @@ -194,9 +170,9 @@ Publisher: https://books.google.com/

    -This book provides a comprehensive description of SQLite database system. +This book provides a comprehensive description of SQLite database system. It describes design principles, engineering trade-offs, implementation issues, -and operations of SQLite. +and operations of SQLite.


    @@ -231,7 +207,7 @@

    Author: Sribatsa Das
    Publisher: Amazon
    -Amazon +Amazon

    SQLite for Mobile Apps Simplified is devoted to presenting approach @@ -241,7 +217,7 @@ In addition, it presents ADB Shell and SQLite command-line shell from ADB Shell to access the SQLite Database created by the Android apps. For BlackBerry and iOS application, the book presents ways to access -the data using the command line shell. +the data using the command line shell.


    @@ -255,23 +231,23 @@ Amazon

    -Outside of the world of enterprise computing, there is one database -that enables a huge range of software and hardware to flex relational -database capabilities, without the baggage and cost of traditional +Outside of the world of enterprise computing, there is one database +that enables a huge range of software and hardware to flex relational +database capabilities, without the baggage and cost of traditional database management systems. That database is SQLite - an embeddable -database with an amazingly small footprint, yet able to handle databases -of enormous size. SQLite comes equipped with an array of powerful -features available through a host of programming and development +database with an amazingly small footprint, yet able to handle databases +of enormous size. SQLite comes equipped with an array of powerful +features available through a host of programming and development environments. It is supported by languages such as C, Java, Perl, PHP, Python, Ruby, TCL, and more.

    -

    The Definitive Guide to SQLite, Second Edition -is devoted to complete coverage of the latest version of this powerful -database. It offers a thorough overview of SQLite's capabilities +

    The Definitive Guide to SQLite, Second Edition +is devoted to complete coverage of the latest version of this powerful +database. It offers a thorough overview of SQLite's capabilities and APIs. The book also uses SQLite as the basis for helping newcomers -make their first foray into database development. In only a short time -you can be writing programs as diverse as a server-side browser plug-in -or the next great iPhone or Android application! +make their first foray into database development. In only a short time +you can be writing programs as diverse as a server-side browser plug-in +or the next great iPhone or Android application!

    @@ -288,17 +264,17 @@

    Developers, take note: databases aren't just for the IS group any more. You can build database-backed applications for the desktop, Web, embedded systems, or operating systems without linking to heavy-duty -client-server databases such as Oracle and MySQL. -This book shows how you to use SQLite, a small and lightweight +client-server databases such as Oracle and MySQL. +This book shows how you to use SQLite, a small and lightweight database that you can build right into your application during development. Applications that handle data have an enormous advantage today, and with SQLite, you'll discover how to develop a database-backed application that remains manageable in size and complexity. This book guides -you every step of the way. You'll get a crash course in data modeling, -become familiar with SQLite's dialect of the SQL database language, -and learn how you to work with SQLite using either a scripting -language or a C-based language, such as C# or Objective C.Now, -even relatively small and nimble applications can be a part of +you every step of the way. You'll get a crash course in data modeling, +become familiar with SQLite's dialect of the SQL database language, +and learn how you to work with SQLite using either a scripting +language or a C-based language, such as C# or Objective C.Now, +even relatively small and nimble applications can be a part of the data revolution. Using SQLite shows you how.

    @@ -309,23 +285,23 @@

    SQLite 3 - Einstieg in die Datenbankwelt (2010)

    -Author: Kay Droessler
    +Author: Key Droessler
    Publisher: Lulu.com
    -Amazon

    +Amazon

    Die Datenbanksprache SQL ( Structured Query Language ) wird in Datenbanken -zur Definition, Manipulation, Sicherung, aber hauptsaechlich zur Abfrage -von Daten aus der Datenbank eingesetzt. Unabhaengig vom Betriebssystem oder -aufwendigen, benutzerfreundlichen, graphischen Oberflaechen bleibt die -Logik aber immer gleich.SQLite ist eine freie Desktop-Datenbank, -sie kostet nichts, ist fuer viele Betriebssysteme verfuegbar, -schnell heruntergeladen und installiert und auf das Notwendigste -reduziert. Fuer den Einsteiger sind das die besten Voraussetzungen, -ohne viel Aufwand schnell in die Welt der Datenbanken und Datenbanksprache +zur Definition, Manipulation, Sicherung, aber hauptsaechlich zur Abfrage +von Daten aus der Datenbank eingesetzt. Unabhaengig vom Betriebssystem oder +aufwendigen, benutzerfreundlichen, graphischen Oberflaechen bleibt die +Logik aber immer gleich.SQLite ist eine freie Desktop-Datenbank, +sie kostet nichts, ist fuer viele Betriebssysteme verfuegbar, +schnell heruntergeladen und installiert und auf das Notwendigste +reduziert. Fuer den Einsteiger sind das die besten Voraussetzungen, +ohne viel Aufwand schnell in die Welt der Datenbanken und Datenbanksprache reinzuschnuppern.Wer nach den Uebungen aber auf den Geschmack gekommen ist, -hat schon den groessten Teil an Datenbanken und SQL gelernt, denn alles -Besprochene ist Wissen, welches auch auf jedes andere der vielen -Datenbanken grundlegend anwendbar ist. Nun koennen Sie auf die richtig +hat schon den groessten Teil an Datenbanken und SQL gelernt, denn alles +Besprochene ist Wissen, welches auch auf jedes andere der vielen +Datenbanken grundlegend anwendbar ist. Nun koennen Sie auf die richtig Grossen zugehen, vom grossen Fachbuch bis zum riesigen Datenbanksystem.

    @@ -344,14 +320,14 @@ which is based on SQLite. The authors (both members of the Symbian engineering team responsible for the implementation of the code) show you how to design code -and ease migration from an internal and external point of view, -plus they reveal the dos and don'ts of writing high-performance -database applications. Packed with resources and sample code, -this timely book reveals how to design and tune applications +and ease migration from an internal and external point of view, +plus they reveal the dos and don'ts of writing high-performance +database applications. Packed with resources and sample code, +this timely book reveals how to design and tune applications that use the Symbian SQL framework to ultimately improve performance.

    -

    With its sample code and insider expertise, this text has everything -you need to keep you ahead of the curve. +

    With its sample code and insider expertise, this text has everything +you need to keep you ahead of the curve.

    @@ -362,15 +338,15 @@

    Author: Rick F. van der Lans
    Publisher: Lulu.com
    -Amazon

    +Amazon

    SQLite is a small, fast, embeddable, SQL-based database server. It is easy to install, needs no management, and is open source. This book describes SQLite in detail. With hundreds of examples, plus a proven approach and structure, the book teaches you how to use SQLite -efficiently and effectively. It contains a complete description of the -SQL dialect as implemented in SQLite version 3.6. The book can be seen -as a tutorial and a reference book. Source code for the numerous SQL +efficiently and effectively. It contains a complete description of the +SQL dialect as implemented in SQLite version 3.6. The book can be seen +as a tutorial and a reference book. Source code for the numerous SQL examples and exercises included in this book can be downloaded from www.r20.nl.

    @@ -382,11 +358,11 @@

    Author: Naoki Nishizawa
    Publisher: Shoeisha
    -Amazon.jp

    +Amazon.jp

    This text is written in fluent Japanese specifically for a Japanese audience. This is the second edition of the book - the first edition -was published in 2005. +was published in 2005.

    @@ -400,18 +376,18 @@ Publisher: O'Reilly Media
    O'Reilly

    -

    SQLite is a small, zero-configuration, custom-tailored, embeddable, +

    SQLite is a small, zero-configuration, custom-tailored, embeddable, thread-safe, easily maintainable, transaction-oriented, SQL-based, -relational database management system. There is no separate install or -setup procedure to initialize SQLite before using it. -There is no configuration file. -SQLite is open source, and is available in the public domain -(for more information on open source, visit http://opensource.org). -You can download SQLite source code from its homepage http://www.sqlite.org, +relational database management system. There is no separate install or +setup procedure to initialize SQLite before using it. +There is no configuration file. +SQLite is open source, and is available in the public domain +(for more information on open source, visit http://opensource.org). +You can download SQLite source code from its homepage http://www.sqlite.org, compile it using your favorite C compiler, and start using the compiled -library. SQLite runs on Linux, Windows, Mac OS X, and a few other operating systems. It has been widely used in low-to-medium tier database applications. -This Short Cut discusses design principles, engineering trade-offs, -implementation issues, and operations of SQLite. It presents a +library. SQLite runs on Linux, Windows, Mac OS X, and a few other operating systems. It has been widely used in low-to-medium tier database applications. +This Short Cut discusses design principles, engineering trade-offs, +implementation issues, and operations of SQLite. It presents a comprehensive description of all important components of the SQLite engine.

    @@ -423,20 +399,19 @@

    Author: Chris Newman
    Publisher: Sams
    -Amazon

    +Amazon

    -SQLite is a small, fast, embeddable database. What makes it popular is -the combination of the database engine and interface into a single library +SQLite is a small, fast, embeddable database. What makes it popular is +the combination of the database engine and interface into a single library as well as the ability to store all the data in a single file. -Its functionality lies between MySQL and PostgreSQL, however it is faster +Its functionality lies between MySQL and PostgreSQL, however it is faster than both databases.

    -

    In SQLite, -author Chris Newman provides a thorough, practical guide to -using, administering and programming this up-and-coming database. -If you want to learn about SQLite or about its use in conjunction with +

    In SQLite, +author Chris Newman provides a thorough, practical guide to +using, administering and programming this up-and-coming database. +If you want to learn about SQLite or about its use in conjunction with PHP this is the book for you.

    -

    This page last modified on 2023-02-27 02:07:35 UTC

    diff -Nru sqlite3-3.42.0/www/bytecodevtab.html sqlite3-3.44.0-0/www/bytecodevtab.html --- sqlite3-3.42.0/www/bytecodevtab.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/bytecodevtab.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -228,5 +204,4 @@ accessed. NULL means the main body of the prepared statement. Otherwise this field is the name of a trigger or "(FK)" for a foreign key action.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/c3ref/aggregate_context.html sqlite3-3.44.0-0/www/c3ref/aggregate_context.html --- sqlite3-3.42.0/www/c3ref/aggregate_context.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/aggregate_context.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Obtain Aggregate Function Context

    @@ -142,7 +118,7 @@
     
     

    The sqlite3_aggregate_context(C,N) routine returns a NULL pointer when first called if N is less than or equal to zero or if a memory -allocation error occurs.

    +allocate error occurs.

    The amount of space allocated by sqlite3_aggregate_context(C,N) is determined by the N parameter on first successful call. Changing the @@ -163,7 +139,6 @@

    This routine must be called from the same thread in which the aggregate SQL function is running.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/aggregate_count.html sqlite3-3.44.0-0/www/c3ref/aggregate_count.html --- sqlite3-3.42.0/www/c3ref/aggregate_count.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/aggregate_count.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Deprecated Functions

    @@ -138,7 +114,6 @@
     the use of these functions.  To encourage programmers to avoid
     these functions, we will not explain what they do.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/api_routines.html sqlite3-3.44.0-0/www/c3ref/api_routines.html --- sqlite3-3.42.0/www/c3ref/api_routines.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/api_routines.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Loadable Extension Thunk

    @@ -129,7 +105,6 @@
     structure must be typedefed in order to work around compiler warnings
     on some platforms.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/auto_extension.html sqlite3-3.44.0-0/www/c3ref/auto_extension.html --- sqlite3-3.42.0/www/c3ref/auto_extension.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/auto_extension.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Automatically Load Statically Linked Extensions

    @@ -157,7 +133,6 @@
     

    See also: sqlite3_reset_auto_extension() and sqlite3_cancel_auto_extension()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/autovacuum_pages.html sqlite3-3.44.0-0/www/c3ref/autovacuum_pages.html --- sqlite3-3.42.0/www/c3ref/autovacuum_pages.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/autovacuum_pages.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,189 +0,0 @@ - - - - - -Autovacuum Compaction Amount Callback - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Autovacuum Compaction Amount Callback

    -
    -
    -int sqlite3_autovacuum_pages(
    -  sqlite3 *db,
    -  unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
    -  void*,
    -  void(*)(void*)
    -);
    -
    -

    -The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback -function C that is invoked prior to each autovacuum of the database -file. The callback is passed a copy of the generic data pointer (P), -the schema-name of the attached database that is being autovacuumed, -the size of the database file in pages, the number of free pages, -and the number of bytes per page, respectively. The callback should -return the number of free pages that should be removed by the -autovacuum. If the callback returns zero, then no autovacuum happens. -If the value returned is greater than or equal to the number of -free pages, then a complete autovacuum happens.

    - -

    If there are multiple ATTACH-ed database files that are being -modified as part of a transaction commit, then the autovacuum pages -callback is invoked separately for each file.

    - -

    The callback is not reentrant. The callback function should -not attempt to invoke any other SQLite interface. If it does, bad -things may happen, including segmentation faults and corrupt database -files. The callback function should be a simple function that -does some arithmetic on its input parameters and returns a result.

    - -

    The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional -destructor for the P parameter. If X is not NULL, then X(P) is -invoked whenever the database connection closes or when the callback -is overwritten by another invocation of sqlite3_autovacuum_pages().

    - -

    There is only one autovacuum pages callback per database connection. -Each call to the sqlite3_autovacuum_pages() interface overrides all -previous invocations for that database connection. If the callback -argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, -then the autovacuum steps callback is cancelled. The return value -from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might -be some other error code if something goes wrong. The current -implementation will only return SQLITE_OK or SQLITE_MISUSE, but other -return codes might be added in future releases.

    - -

    If no autovacuum pages callback is specified (the usual case) or -a NULL pointer is provided for the callback, -then the default behavior is to vacuum all free pages. So, in other -words, the default behavior is the same as if the callback function -were something like this:

    - -

    -    unsigned int demonstration_autovac_pages_callback(
    -      void *pClientData,
    -      const char *zSchema,
    -      unsigned int nDbPage,
    -      unsigned int nFreePage,
    -      unsigned int nBytePerPage
    -    ){
    -      return nFreePage;
    -    }
    -
    -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/backup_finish.html sqlite3-3.44.0-0/www/c3ref/backup_finish.html --- sqlite3-3.42.0/www/c3ref/backup_finish.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/backup_finish.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Online Backup API.

    @@ -305,7 +281,7 @@
     if the application incorrectly accesses the destination database connection
     and so no error code is reported, but the operations may malfunction
     nevertheless.  Use of the destination database connection while a
    -backup is in progress might also cause a mutex deadlock.

    +backup is in progress might also also cause a mutex deadlock.

    If running in shared cache mode, the application must guarantee that the shared cache used by the destination database @@ -321,7 +297,6 @@ same time as another thread is invoking sqlite3_backup_step() it is possible that they return invalid values.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/backup.html sqlite3-3.44.0-0/www/c3ref/backup.html --- sqlite3-3.42.0/www/c3ref/backup.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/backup.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Online Backup Object

    @@ -131,7 +107,6 @@
     
     

    See Also: Using the SQLite Online Backup API

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/bind_blob.html sqlite3-3.44.0-0/www/c3ref/bind_blob.html --- sqlite3-3.42.0/www/c3ref/bind_blob.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/bind_blob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Binding Values To Prepared Statements

    @@ -273,7 +249,6 @@
     

    See also: sqlite3_bind_parameter_count(), sqlite3_bind_parameter_name(), and sqlite3_bind_parameter_index().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/bind_parameter_count.html sqlite3-3.44.0-0/www/c3ref/bind_parameter_count.html --- sqlite3-3.42.0/www/c3ref/bind_parameter_count.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/bind_parameter_count.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Number Of SQL Parameters

    @@ -139,7 +115,6 @@
     sqlite3_bind_parameter_name(), and
     sqlite3_bind_parameter_index().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/bind_parameter_index.html sqlite3-3.44.0-0/www/c3ref/bind_parameter_index.html --- sqlite3-3.42.0/www/c3ref/bind_parameter_index.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/bind_parameter_index.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Index Of A Parameter With A Given Name

    @@ -136,7 +112,6 @@
     sqlite3_bind_parameter_count(), and
     sqlite3_bind_parameter_name().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/bind_parameter_name.html sqlite3-3.44.0-0/www/c3ref/bind_parameter_name.html --- sqlite3-3.42.0/www/c3ref/bind_parameter_name.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/bind_parameter_name.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Name Of A Host Parameter

    @@ -146,7 +122,6 @@
     sqlite3_bind_parameter_count(), and
     sqlite3_bind_parameter_index().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/blob_bytes.html sqlite3-3.44.0-0/www/c3ref/blob_bytes.html --- sqlite3-3.42.0/www/c3ref/blob_bytes.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/blob_bytes.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Return The Size Of An Open BLOB

    @@ -134,7 +110,6 @@
     been closed by sqlite3_blob_close().  Passing any other pointer in
     to this routine results in undefined and probably undesirable behavior.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/blob_close.html sqlite3-3.44.0-0/www/c3ref/blob_close.html --- sqlite3-3.42.0/www/c3ref/blob_close.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/blob_close.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Close A BLOB Handle

    @@ -141,7 +117,6 @@
     is passed a valid open blob handle, the values returned by the
     sqlite3_errcode() and sqlite3_errmsg() functions are set before returning.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/blob.html sqlite3-3.44.0-0/www/c3ref/blob.html --- sqlite3-3.42.0/www/c3ref/blob.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/blob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    A Handle To An Open BLOB

    @@ -131,15 +107,14 @@
     The sqlite3_blob_read() and sqlite3_blob_write() interfaces
     can be used to read or write small subsections of the BLOB.
     The sqlite3_blob_bytes() interface returns the size of the BLOB in bytes.
    -

    1 Constructor using this object: sqlite3_blob_open()

    -

    1 Destructor using this object: sqlite3_blob_close()

    -

    4 Methods using this object: +

    1 Constructor: sqlite3_blob_open()

    +

    1 Destructor: sqlite3_blob_close()

    +

    4 Methods: sqlite3_blob_bytes(), sqlite3_blob_read(), sqlite3_blob_reopen(), sqlite3_blob_write()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/blob_open.html sqlite3-3.44.0-0/www/c3ref/blob_open.html --- sqlite3-3.42.0/www/c3ref/blob_open.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/blob_open.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Open A BLOB For Incremental I/O

    @@ -210,7 +186,6 @@
     sqlite3_blob_reopen(), sqlite3_blob_read(),
     sqlite3_blob_bytes(), sqlite3_blob_write().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/blob_read.html sqlite3-3.44.0-0/www/c3ref/blob_read.html --- sqlite3-3.42.0/www/c3ref/blob_read.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/blob_read.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Read Data From A BLOB Incrementally

    @@ -147,7 +123,6 @@
     
     

    See also: sqlite3_blob_write().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/blob_reopen.html sqlite3-3.44.0-0/www/c3ref/blob_reopen.html --- sqlite3-3.42.0/www/c3ref/blob_reopen.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/blob_reopen.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Move a BLOB Handle to a New Row

    @@ -143,7 +119,6 @@
     
     

    This function sets the database handle error code and message.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/blob_write.html sqlite3-3.44.0-0/www/c3ref/blob_write.html --- sqlite3-3.42.0/www/c3ref/blob_write.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/blob_write.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Write Data Into A BLOB Incrementally

    @@ -160,7 +136,6 @@
     
     

    See also: sqlite3_blob_read().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/busy_handler.html sqlite3-3.44.0-0/www/c3ref/busy_handler.html --- sqlite3-3.42.0/www/c3ref/busy_handler.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/busy_handler.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Register A Callback To Handle SQLITE_BUSY Errors

    @@ -178,7 +154,6 @@
     

    A busy handler must not close the database connection or prepared statement that invoked the busy handler.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/busy_timeout.html sqlite3-3.44.0-0/www/c3ref/busy_timeout.html --- sqlite3-3.42.0/www/c3ref/busy_timeout.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/busy_timeout.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Set A Busy Timeout

    @@ -141,7 +117,6 @@
     
     

    See also: PRAGMA busy_timeout

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_abort.html sqlite3-3.44.0-0/www/c3ref/c_abort.html --- sqlite3-3.42.0/www/c3ref/c_abort.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_abort.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -163,7 +139,6 @@
     
     

    See also: extended result code definitions

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_abort_rollback.html sqlite3-3.44.0-0/www/c3ref/c_abort_rollback.html --- sqlite3-3.42.0/www/c3ref/c_abort_rollback.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_abort_rollback.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Extended Result Codes

    @@ -189,14 +165,12 @@
     #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
     #define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
     #define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))
    -#define SQLITE_CONSTRAINT_DATATYPE     (SQLITE_CONSTRAINT |(12<<8))
     #define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
     #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
    -#define SQLITE_NOTICE_RBU              (SQLITE_NOTICE | (3<<8))
     #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
     #define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
     #define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
    -#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8)) /* internal use only */
    +#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8))
     

    In its default configuration, SQLite API routines return one of 30 integer @@ -212,7 +186,6 @@ the most recent error can be obtained using sqlite3_extended_errcode().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_access_exists.html sqlite3-3.44.0-0/www/c3ref/c_access_exists.html --- sqlite3-3.42.0/www/c3ref/c_access_exists.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_access_exists.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Flags for the xAccess VFS method

    @@ -143,7 +119,6 @@
     currently unused, though it might be used in a future release of
     SQLite.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_alter_table.html sqlite3-3.44.0-0/www/c3ref/c_alter_table.html --- sqlite3-3.42.0/www/c3ref/c_alter_table.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_alter_table.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Authorizer Action Codes

    @@ -174,7 +150,6 @@
     the access attempt or NULL if this access attempt is directly from
     top-level SQL code.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/cancel_auto_extension.html sqlite3-3.44.0-0/www/c3ref/cancel_auto_extension.html --- sqlite3-3.42.0/www/c3ref/cancel_auto_extension.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/cancel_auto_extension.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Cancel Automatic Extension Loading

    @@ -131,7 +107,6 @@
     unregistered and it returns 0 if X was not on the list of initialization
     routines.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_any.html sqlite3-3.44.0-0/www/c3ref/c_any.html --- sqlite3-3.42.0/www/c3ref/c_any.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_any.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -132,7 +108,6 @@
     These constant define integer codes that represent the various
     text encodings supported by SQLite.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_blob.html sqlite3-3.44.0-0/www/c3ref/c_blob.html --- sqlite3-3.42.0/www/c3ref/c_blob.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_blob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Fundamental Datatypes

    @@ -150,7 +126,6 @@
     SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
     SQLITE_TEXT.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_checkpoint_full.html sqlite3-3.44.0-0/www/c3ref/c_checkpoint_full.html --- sqlite3-3.42.0/www/c3ref/c_checkpoint_full.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_checkpoint_full.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,41 +89,17 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Checkpoint Mode Values

     #define SQLITE_CHECKPOINT_PASSIVE  0  /* Do as much as possible w/o blocking */
     #define SQLITE_CHECKPOINT_FULL     1  /* Wait for writers, then checkpoint */
    -#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for readers */
    +#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for for readers */
     #define SQLITE_CHECKPOINT_TRUNCATE 3  /* Like RESTART but also truncate WAL */
     

    @@ -132,7 +108,6 @@ See the sqlite3_wal_checkpoint_v2() documentation for details on the meaning of each of these checkpoint modes.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_config_covering_index_scan.html sqlite3-3.44.0-0/www/c3ref/c_config_covering_index_scan.html --- sqlite3-3.42.0/www/c3ref/c_config_covering_index_scan.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_config_covering_index_scan.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,60 +89,36 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Configuration Options

    -#define SQLITE_CONFIG_SINGLETHREAD         1  /* nil */
    -#define SQLITE_CONFIG_MULTITHREAD          2  /* nil */
    -#define SQLITE_CONFIG_SERIALIZED           3  /* nil */
    -#define SQLITE_CONFIG_MALLOC               4  /* sqlite3_mem_methods* */
    -#define SQLITE_CONFIG_GETMALLOC            5  /* sqlite3_mem_methods* */
    -#define SQLITE_CONFIG_SCRATCH              6  /* No longer used */
    -#define SQLITE_CONFIG_PAGECACHE            7  /* void*, int sz, int N */
    -#define SQLITE_CONFIG_HEAP                 8  /* void*, int nByte, int min */
    -#define SQLITE_CONFIG_MEMSTATUS            9  /* boolean */
    -#define SQLITE_CONFIG_MUTEX               10  /* sqlite3_mutex_methods* */
    -#define SQLITE_CONFIG_GETMUTEX            11  /* sqlite3_mutex_methods* */
    -/* previously SQLITE_CONFIG_CHUNKALLOC    12 which is now unused. */
    -#define SQLITE_CONFIG_LOOKASIDE           13  /* int int */
    -#define SQLITE_CONFIG_PCACHE              14  /* no-op */
    -#define SQLITE_CONFIG_GETPCACHE           15  /* no-op */
    -#define SQLITE_CONFIG_LOG                 16  /* xFunc, void* */
    -#define SQLITE_CONFIG_URI                 17  /* int */
    -#define SQLITE_CONFIG_PCACHE2             18  /* sqlite3_pcache_methods2* */
    -#define SQLITE_CONFIG_GETPCACHE2          19  /* sqlite3_pcache_methods2* */
    +#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
    +#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
    +#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
    +#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
    +#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
    +#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
    +#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
    +#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
    +#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
    +#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
    +#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
    +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
    +#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
    +#define SQLITE_CONFIG_PCACHE       14  /* no-op */
    +#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
    +#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
    +#define SQLITE_CONFIG_URI          17  /* int */
    +#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
    +#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
     #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
    -#define SQLITE_CONFIG_SQLLOG              21  /* xSqllog, void* */
    -#define SQLITE_CONFIG_MMAP_SIZE           22  /* sqlite3_int64, sqlite3_int64 */
    +#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
    +#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
     #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
     #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
     #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
    @@ -155,23 +131,6 @@
     These constants are the available integer configuration options that
     can be passed as the first argument to the sqlite3_config() interface.

    -

    Most of the configuration options for sqlite3_config() -will only work if invoked prior to sqlite3_initialize() or after -sqlite3_shutdown(). The few exceptions to this rule are called -"anytime configuration options". -Calling sqlite3_config() with a first argument that is not an -anytime configuration option in between calls to sqlite3_initialize() and -sqlite3_shutdown() is a no-op that returns SQLITE_MISUSE.

    - -

    The set of anytime configuration options can change (by insertions -and/or deletions) from one release of SQLite to the next. -As of SQLite version 3.42.0, the complete set of anytime configuration -options is: -

      -
    • SQLITE_CONFIG_LOG -
    • SQLITE_CONFIG_PCACHE_HDRSZ -

    -

    New configuration options may be added in future releases of SQLite. Existing configuration options might be discontinued. Applications should check the return code from sqlite3_config() to make sure that @@ -546,7 +505,6 @@ compile-time option is not set, then the default maximum is 1073741824.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_dbconfig_defensive.html sqlite3-3.44.0-0/www/c3ref/c_dbconfig_defensive.html --- sqlite3-3.42.0/www/c3ref/c_dbconfig_defensive.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_dbconfig_defensive.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Database Connection Configuration Options

    @@ -139,9 +115,7 @@
     #define SQLITE_DBCONFIG_ENABLE_VIEW           1015 /* int int* */
     #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT    1016 /* int int* */
     #define SQLITE_DBCONFIG_TRUSTED_SCHEMA        1017 /* int int* */
    -#define SQLITE_DBCONFIG_STMT_SCANSTATUS       1018 /* int int* */
    -#define SQLITE_DBCONFIG_REVERSE_SCANORDER     1019 /* int int* */
    -#define SQLITE_DBCONFIG_MAX                   1019 /* Largest DBCONFIG */
    +#define SQLITE_DBCONFIG_MAX                   1017 /* Largest DBCONFIG */
     

    These constants are the available integer configuration options that @@ -174,7 +148,7 @@ configuration for a database connection can only be changed when that connection is not currently using lookaside memory, or in other words when the "current value" returned by -sqlite3_db_status(D,SQLITE_DBSTATUS_LOOKASIDE_USED,...) is zero. +sqlite3_db_status(D,SQLITE_CONFIG_LOOKASIDE,...) is zero. Any attempt to change the lookaside memory configuration when lookaside memory is in use leaves the configuration unchanged and returns SQLITE_BUSY.

    @@ -334,12 +308,8 @@
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); Because resetting a database is destructive and irreversible, the -process requires the use of this obscure API and multiple steps to -help ensure that it does not happen by accident. Because this -feature must be capable of resetting corrupt databases, and -shutting down virtual tables may require access to that corrupt -storage, the library must abandon any installed virtual tables -without calling their xDestroy() methods.

    +process requires the use of this obscure API and multiple steps to help +ensure that it does not happen by accident.

    SQLITE_DBCONFIG_DEFENSIVE
    @@ -351,7 +321,6 @@ @@ -382,7 +351,7 @@

    -

    SQLITE_DBCONFIG_DQS_DML
    +
    SQLITE_DBCONFIG_DQS_DML
    The SQLITE_DBCONFIG_DQS_DML option activates or deactivates the legacy double-quoted string literal misfeature for DML statements only, that is DELETE, INSERT, SELECT, and UPDATE statements. The @@ -392,7 +361,7 @@

    -

    SQLITE_DBCONFIG_DQS_DDL
    +
    SQLITE_DBCONFIG_DQS_DDL
    The SQLITE_DBCONFIG_DQS option activates or deactivates the legacy double-quoted string literal misfeature for DDL statements, such as CREATE TABLE and CREATE INDEX. The @@ -402,7 +371,7 @@

    -

    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    +
    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to assume that database schemas are untainted by malicious content. When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite @@ -423,7 +392,7 @@

    -

    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    +
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates the legacy file format flag. When activated, this flag causes all newly created database file to have a schema format version number (the 4-byte @@ -432,7 +401,7 @@ any SQLite version back to 3.0.0 (2004-06-18). Without this setting, newly created databases are generally not understandable by SQLite versions prior to 3.3.0 (2006-01-11). As these words are written, there -is now scarcely any need to generate database files that are compatible +is now scarcely any need to generated database files that are compatible all the way back to version 3.0.0, and so this setting is of little practical use, but is provided so that SQLite can continue to claim the ability to generate new database files that are compatible with version @@ -442,44 +411,9 @@ process a table with generated columns and a descending index. This is not considered a bug since SQLite versions 3.3.0 and earlier do not support either generated columns or decending indexes. -

    - -

    - -

    SQLITE_DBCONFIG_STMT_SCANSTATUS
    -
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in -SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears -a flag that enables collection of the sqlite3_stmt_scanstatus_v2() -statistics. For statistics to be collected, the flag must be set on -the database handle both when the SQL statement is prepared and when it -is stepped. The flag is set (collection of statistics is enabled) -by default. This option takes two arguments: an integer and a pointer to -an integer.. The first argument is 1, 0, or -1 to enable, disable, or -leave unchanged the statement scanstatus option. If the second argument -is not NULL, then the value of the statement scanstatus setting after -processing the first argument is written into the integer that the second -argument points to. -

    - -

    - -

    SQLITE_DBCONFIG_REVERSE_SCANORDER
    -
    The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order -in which tables and indexes are scanned so that the scans start at the end -and work toward the beginning rather than starting at the beginning and -working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the -same as setting PRAGMA reverse_unordered_selects. This option takes -two arguments which are an integer and a pointer to an integer. The first -argument is 1, 0, or -1 to enable, disable, or leave unchanged the -reverse scan order flag, respectively. If the second argument is not NULL, -then 0 or 1 is written into the integer that the second argument points to -depending on if the reverse scan order flag is set after processing the -first argument. -

    - -

    + +

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_dbstatus_options.html sqlite3-3.44.0-0/www/c3ref/c_dbstatus_options.html --- sqlite3-3.42.0/www/c3ref/c_dbstatus_options.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_dbstatus_options.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Status Parameters for database connections

    @@ -257,7 +233,6 @@
     
     
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_deny.html sqlite3-3.44.0-0/www/c3ref/c_deny.html --- sqlite3-3.42.0/www/c3ref/c_deny.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_deny.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Authorizer Return Codes

    @@ -134,7 +110,6 @@
     

    Note that SQLITE_IGNORE is also used as a conflict resolution mode returned from the sqlite3_vtab_on_conflict() interface.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_deserialize_freeonclose.html sqlite3-3.44.0-0/www/c3ref/c_deserialize_freeonclose.html --- sqlite3-3.42.0/www/c3ref/c_deserialize_freeonclose.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_deserialize_freeonclose.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Flags for sqlite3_deserialize()

    @@ -144,7 +120,6 @@
     

    The SQLITE_DESERIALIZE_READONLY flag means that the deserialized database should be treated as read-only.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_deterministic.html sqlite3-3.44.0-0/www/c3ref/c_deterministic.html --- sqlite3-3.42.0/www/c3ref/c_deterministic.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_deterministic.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -151,21 +127,10 @@
     from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in
     schema structures such as CHECK constraints, DEFAULT clauses,
     expression indexes, partial indexes, or generated columns.
    -

    -The SQLITE_DIRECTONLY flag is recommended for any -application-defined SQL function -that has side-effects or that could potentially leak sensitive information. -This will prevent attacks in which an application is tricked -into using a database file that has had its schema surreptiously -modified to invoke the application-defined function in ways that are -harmful. -

    -Some people say it is good practice to set SQLITE_DIRECTONLY on all -application-defined SQL functions, regardless of whether or not they -are security sensitive, as doing so prevents those functions from being used -inside of the database schema, and thus ensures that the database -can be inspected and modified using generic tools (such as the CLI) -that do not have access to the application-defined functions. +The SQLITE_DIRECTONLY flags is a security feature which is recommended +for all application-defined SQL functions, and especially for functions +that have side-effects or that could potentially leak sensitive +information.

    @@ -204,7 +169,6 @@

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_fail.html sqlite3-3.44.0-0/www/c3ref/c_fail.html --- sqlite3-3.42.0/www/c3ref/c_fail.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_fail.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Conflict resolution modes

    @@ -136,7 +112,6 @@
     return value from the sqlite3_set_authorizer() callback and that
     SQLITE_ABORT is also a result code.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_fcntl_begin_atomic_write.html sqlite3-3.44.0-0/www/c3ref/c_fcntl_begin_atomic_write.html --- sqlite3-3.42.0/www/c3ref/c_fcntl_begin_atomic_write.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_fcntl_begin_atomic_write.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Standard File Control Opcodes

    @@ -161,7 +137,6 @@
     #define SQLITE_FCNTL_CKPT_START             39
     #define SQLITE_FCNTL_EXTERNAL_READER        40
     #define SQLITE_FCNTL_CKSM_FILE              41
    -#define SQLITE_FCNTL_RESET_CACHE            42
     

    These integer constants are opcodes for the xFileControl method @@ -175,8 +150,9 @@ opcode causes the xFileControl method to write the current state of the lock (one of SQLITE_LOCK_NONE, SQLITE_LOCK_SHARED, SQLITE_LOCK_RESERVED, SQLITE_LOCK_PENDING, or SQLITE_LOCK_EXCLUSIVE) -into an integer that the pArg argument points to. -This capability is only available if SQLite is compiled with SQLITE_DEBUG.

    +into an integer that the pArg argument points to. This capability +is used during testing and is only available when the SQLITE_TEST +compile-time option is used.

  • @@ -511,7 +487,8 @@ The SQLITE_FCNTL_CKPT_DONE opcode is invoked from within a checkpoint in wal mode after the client has finished copying pages from the wal file to the database file, but before the *-shm file is updated to -record the fact that the pages have been checkpointed.

    +record the fact that the pages have been checkpointed. +

  • @@ -524,22 +501,14 @@ currently has an SQL transaction open on the database. It is set to 0 if the database is not a wal-mode db, or if there is no such connection in any other process. This opcode cannot be used to detect transactions opened -by clients within the current process, only within other processes.

    +by clients within the current process, only within other processes. +

  • -The SQLITE_FCNTL_CKSM_FILE opcode is for use interally by the -checksum VFS shim only.

    - -

  • - -If there is currently no transaction open on the database, and the -database is not a temp db, then the SQLITE_FCNTL_RESET_CACHE file-control -purges the contents of the in-memory page cache. If there is an open -transaction, or if the db is a temp-db, this opcode is a no-op, not an error. +Used by the cksmvfs VFS module only.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/changes.html sqlite3-3.44.0-0/www/c3ref/changes.html --- sqlite3-3.42.0/www/c3ref/changes.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/changes.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,50 +89,22 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Count The Number Of Rows Modified

     int sqlite3_changes(sqlite3*);
    -sqlite3_int64 sqlite3_changes64(sqlite3*);
     

    -These functions return the number of rows modified, inserted or +This function returns the number of rows modified, inserted or deleted by the most recently completed INSERT, UPDATE or DELETE statement on the database connection specified by the only parameter. -The two functions are identical except for the type of the return value -and that if the number of rows modified by the most recent INSERT, UPDATE -or DELETE is greater than the maximum value supported by type "int", then -the return value of sqlite3_changes() is undefined. Executing any other -type of SQL statement does not modify the value returned by these functions.

    +Executing any other type of SQL statement does not modify the value +returned by this function.

    Only changes made directly by the INSERT, UPDATE or DELETE statement are considered - auxiliary changes caused by triggers, @@ -180,7 +152,6 @@

  • the data_version pragma

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_index_constraint_eq.html sqlite3-3.44.0-0/www/c3ref/c_index_constraint_eq.html --- sqlite3-3.42.0/www/c3ref/c_index_constraint_eq.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_index_constraint_eq.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,93 +89,36 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Constraint Operator Codes

    -#define SQLITE_INDEX_CONSTRAINT_EQ          2
    -#define SQLITE_INDEX_CONSTRAINT_GT          4
    -#define SQLITE_INDEX_CONSTRAINT_LE          8
    -#define SQLITE_INDEX_CONSTRAINT_LT         16
    -#define SQLITE_INDEX_CONSTRAINT_GE         32
    -#define SQLITE_INDEX_CONSTRAINT_MATCH      64
    -#define SQLITE_INDEX_CONSTRAINT_LIKE       65
    -#define SQLITE_INDEX_CONSTRAINT_GLOB       66
    -#define SQLITE_INDEX_CONSTRAINT_REGEXP     67
    -#define SQLITE_INDEX_CONSTRAINT_NE         68
    -#define SQLITE_INDEX_CONSTRAINT_ISNOT      69
    -#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL  70
    -#define SQLITE_INDEX_CONSTRAINT_ISNULL     71
    -#define SQLITE_INDEX_CONSTRAINT_IS         72
    -#define SQLITE_INDEX_CONSTRAINT_LIMIT      73
    -#define SQLITE_INDEX_CONSTRAINT_OFFSET     74
    -#define SQLITE_INDEX_CONSTRAINT_FUNCTION  150
    +#define SQLITE_INDEX_CONSTRAINT_EQ         2
    +#define SQLITE_INDEX_CONSTRAINT_GT         4
    +#define SQLITE_INDEX_CONSTRAINT_LE         8
    +#define SQLITE_INDEX_CONSTRAINT_LT        16
    +#define SQLITE_INDEX_CONSTRAINT_GE        32
    +#define SQLITE_INDEX_CONSTRAINT_MATCH     64
    +#define SQLITE_INDEX_CONSTRAINT_LIKE      65
    +#define SQLITE_INDEX_CONSTRAINT_GLOB      66
    +#define SQLITE_INDEX_CONSTRAINT_REGEXP    67
    +#define SQLITE_INDEX_CONSTRAINT_NE        68
    +#define SQLITE_INDEX_CONSTRAINT_ISNOT     69
    +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
    +#define SQLITE_INDEX_CONSTRAINT_ISNULL    71
    +#define SQLITE_INDEX_CONSTRAINT_IS        72
    +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
     

    These macros define the allowed values for the sqlite3_index_info.aConstraint[].op field. Each value represents -an operator that is part of a constraint term in the WHERE clause of -a query that uses a virtual table.

    - -

    The left-hand operand of the operator is given by the corresponding -aConstraint[].iColumn field. An iColumn of -1 indicates the left-hand -operand is the rowid. -The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET -operators have no left-hand operand, and so for those operators the -corresponding aConstraint[].iColumn is meaningless and should not be -used.

    - -

    All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through -value 255 are reserved to represent functions that are overloaded -by the xFindFunction method of the virtual table -implementation.

    - -

    The right-hand operands for each constraint might be accessible using -the sqlite3_vtab_rhs_value() interface. Usually the right-hand -operand is only available if it appears as a single constant literal -in the input SQL. If the right-hand operand is another column or an -expression (even a constant expression) or a parameter, then the -sqlite3_vtab_rhs_value() probably will not be able to extract it. -The SQLITE_INDEX_CONSTRAINT_ISNULL and -SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand -and hence calls to sqlite3_vtab_rhs_value() for those operators will -always return SQLITE_NOTFOUND.

    - -

    The collating sequence to be used for comparison can be found using -the sqlite3_vtab_collation() interface. For most real-world virtual -tables, the collating sequence of constraints does not matter (for example -because the constraints are numeric) and so the sqlite3_vtab_collation() -interface is not commonly needed. +an operator that is part of a constraint term in the wHERE clause of +a query that uses a virtual table.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_index_scan_unique.html sqlite3-3.44.0-0/www/c3ref/c_index_scan_unique.html --- sqlite3-3.42.0/www/c3ref/c_index_scan_unique.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_index_scan_unique.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Scan Flags

    @@ -128,7 +104,6 @@
     sqlite3_index_info.idxFlags field to some combination of
     these bits.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_iocap_atomic.html sqlite3-3.44.0-0/www/c3ref/c_iocap_atomic.html --- sqlite3-3.42.0/www/c3ref/c_iocap_atomic.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_iocap_atomic.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Device Characteristics

    @@ -168,7 +144,6 @@
     write operations are bracketed by SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and
     SQLITE_FCNTL_COMMIT_ATOMIC_WRITE.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/clear_bindings.html sqlite3-3.44.0-0/www/c3ref/clear_bindings.html --- sqlite3-3.42.0/www/c3ref/clear_bindings.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/clear_bindings.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Reset All Bindings On A Prepared Statement

    @@ -128,7 +104,6 @@
     the bindings on a prepared statement.
     Use this routine to reset all host parameters to NULL.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_limit_attached.html sqlite3-3.44.0-0/www/c3ref/c_limit_attached.html --- sqlite3-3.42.0/www/c3ref/c_limit_attached.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_limit_attached.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Run-Time Limit Categories

    @@ -199,7 +175,6 @@
     prepared statement may start.
     
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_lock_exclusive.html sqlite3-3.44.0-0/www/c3ref/c_lock_exclusive.html --- sqlite3-3.42.0/www/c3ref/c_lock_exclusive.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_lock_exclusive.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,54 +89,25 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    File Locking Levels

    -#define SQLITE_LOCK_NONE          0       /* xUnlock() only */
    -#define SQLITE_LOCK_SHARED        1       /* xLock() or xUnlock() */
    -#define SQLITE_LOCK_RESERVED      2       /* xLock() only */
    -#define SQLITE_LOCK_PENDING       3       /* xLock() only */
    -#define SQLITE_LOCK_EXCLUSIVE     4       /* xLock() only */
    +#define SQLITE_LOCK_NONE          0
    +#define SQLITE_LOCK_SHARED        1
    +#define SQLITE_LOCK_RESERVED      2
    +#define SQLITE_LOCK_PENDING       3
    +#define SQLITE_LOCK_EXCLUSIVE     4
     

    SQLite uses one of these integer values as the second argument to calls it makes to the xLock() and xUnlock() methods -of an sqlite3_io_methods object. These values are ordered from -lest restrictive to most restrictive.

    - -

    The argument to xLock() is always SHARED or higher. The argument to -xUnlock is either SHARED or NONE. +of an sqlite3_io_methods object.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/close.html sqlite3-3.44.0-0/www/c3ref/close.html --- sqlite3-3.42.0/www/c3ref/close.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/close.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Closing A Database Connection

    @@ -159,7 +135,6 @@
     Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer
     argument is a harmless no-op.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_mutex_fast.html sqlite3-3.44.0-0/www/c3ref/c_mutex_fast.html --- sqlite3-3.42.0/www/c3ref/c_mutex_fast.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_mutex_fast.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -146,7 +122,6 @@
     next.  Applications that override the built-in mutex logic must be
     prepared to accommodate additional static mutexes.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/collation_needed.html sqlite3-3.44.0-0/www/c3ref/collation_needed.html --- sqlite3-3.42.0/www/c3ref/collation_needed.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/collation_needed.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Collation Needed Callbacks

    @@ -156,7 +132,6 @@
     sqlite3_create_collation(), sqlite3_create_collation16(), or
     sqlite3_create_collation_v2().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/column_blob.html sqlite3-3.44.0-0/www/c3ref/column_blob.html --- sqlite3-3.42.0/www/c3ref/column_blob.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/column_blob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Result Values From A Query

    @@ -227,10 +203,6 @@
     even empty strings, are always zero-terminated.  The return
     value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.

    -

    Strings returned by sqlite3_column_text16() always have the endianness -which is native to the platform, regardless of the text encoding set -for the database.

    -

    Warning: The object returned by sqlite3_column_value() is an unprotected sqlite3_value object. In a multithreaded environment, an unprotected sqlite3_value object may only be used safely with @@ -244,7 +216,7 @@ application-defined SQL functions or virtual tables, not within top-level application code.

    -

    These routines may attempt to convert the datatype of the result. +

    The these routines may attempt to convert the datatype of the result. For example, if the internal representation is FLOAT and a text result is requested, sqlite3_snprintf() is used internally to perform the conversion automatically. The following table details the conversions @@ -269,7 +241,7 @@ TEXT BLOB No change BLOB INTEGER CAST to INTEGER BLOB FLOAT CAST to REAL - BLOB TEXT CAST to TEXT, ensure zero terminator + BLOB TEXT Add a zero terminator if needed

    @@ -341,7 +313,6 @@ return value is obtained and before any other SQLite interface is called on the same database connection.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/column_count.html sqlite3-3.44.0-0/www/c3ref/column_count.html --- sqlite3-3.42.0/www/c3ref/column_count.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/column_count.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Number Of Columns In A Result Set

    @@ -134,7 +110,6 @@
     
     

    See also: sqlite3_data_count()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/column_database_name.html sqlite3-3.44.0-0/www/c3ref/column_database_name.html --- sqlite3-3.42.0/www/c3ref/column_database_name.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/column_database_name.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Source Of Data In A Query Result

    @@ -167,7 +143,6 @@
     for the same prepared statement and result column
     at the same time then the results are undefined.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/column_decltype.html sqlite3-3.44.0-0/www/c3ref/column_decltype.html --- sqlite3-3.42.0/www/c3ref/column_decltype.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/column_decltype.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Declared Datatype Of A Query Result

    @@ -151,7 +127,6 @@
     is associated with individual values, not with the containers
     used to hold those values.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/column_name.html sqlite3-3.44.0-0/www/c3ref/column_name.html --- sqlite3-3.42.0/www/c3ref/column_name.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/column_name.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Column Names In A Result Set

    @@ -148,7 +124,6 @@
     then the name of the column is unspecified and may change from
     one release of SQLite to the next.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/commit_hook.html sqlite3-3.44.0-0/www/c3ref/commit_hook.html --- sqlite3-3.42.0/www/c3ref/commit_hook.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/commit_hook.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Commit And Rollback Notification Callbacks

    @@ -168,7 +144,6 @@
     
     

    See also the sqlite3_update_hook() interface.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/compileoption_get.html sqlite3-3.44.0-0/www/c3ref/compileoption_get.html --- sqlite3-3.42.0/www/c3ref/compileoption_get.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/compileoption_get.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Run-Time Library Compilation Options Diagnostics

    @@ -149,7 +125,6 @@
     

    See also: SQL functions sqlite_compileoption_used() and sqlite_compileoption_get() and the compile_options pragma.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/complete.html sqlite3-3.44.0-0/www/c3ref/complete.html --- sqlite3-3.42.0/www/c3ref/complete.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/complete.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine If An SQL Statement Is Complete

    @@ -155,7 +131,6 @@
     

    The input to sqlite3_complete16() must be a zero-terminated UTF-16 string in native byte order.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/config.html sqlite3-3.44.0-0/www/c3ref/config.html --- sqlite3-3.42.0/www/c3ref/config.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/config.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Configuring The SQLite Library

    @@ -134,28 +110,24 @@
     must ensure that no other SQLite interfaces are invoked by other
     threads while sqlite3_config() is running.

    -

    The first argument to sqlite3_config() is an integer -configuration option that determines -what property of SQLite is to be configured. Subsequent arguments -vary depending on the configuration option -in the first argument.

    - -

    For most configuration options, the sqlite3_config() interface +

    The sqlite3_config() interface may only be invoked prior to library initialization using sqlite3_initialize() or after shutdown by sqlite3_shutdown(). -The exceptional configuration options that may be invoked at any time -are called "anytime configuration options". If sqlite3_config() is called after sqlite3_initialize() and before -sqlite3_shutdown() with a first argument that is not an anytime -configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. +sqlite3_shutdown() then it will return SQLITE_MISUSE. Note, however, that sqlite3_config() can be called as part of the implementation of an application-defined sqlite3_os_init().

    +

    The first argument to sqlite3_config() is an integer +configuration option that determines +what property of SQLite is to be configured. Subsequent arguments +vary depending on the configuration option +in the first argument.

    +

    When a configuration option is set, sqlite3_config() returns SQLITE_OK. If the option is unknown or SQLite is unable to set the option then this routine returns a non-zero error code.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/constlist.html sqlite3-3.44.0-0/www/c3ref/constlist.html --- sqlite3-3.42.0/www/c3ref/constlist.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/constlist.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite C Interface

    + +

    SQLite C Interface

    List Of Constants:

    Also available: list of error codes

    @@ -131,7 +107,7 @@
  • SQLITE_ANY
  • SQLITE_ATTACH
  • SQLITE_AUTH
  • -
  • SQLITE_AUTH_USER
  • +
  • SQLITE_AUTH_USER
  • SQLITE_BLOB
  • SQLITE_BUSY
  • SQLITE_BUSY_RECOVERY
  • @@ -179,7 +155,6 @@
  • SQLITE_CONSTRAINT
  • SQLITE_CONSTRAINT_CHECK
  • SQLITE_CONSTRAINT_COMMITHOOK
  • -
  • SQLITE_CONSTRAINT_DATATYPE
  • SQLITE_CONSTRAINT_FOREIGNKEY
  • SQLITE_CONSTRAINT_FUNCTION
  • SQLITE_CONSTRAINT_NOTNULL
  • @@ -219,8 +194,6 @@
  • SQLITE_DBCONFIG_MAX
  • SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
  • SQLITE_DBCONFIG_RESET_DATABASE
  • -
  • SQLITE_DBCONFIG_REVERSE_SCANORDER
  • -
  • SQLITE_DBCONFIG_STMT_SCANSTATUS
  • SQLITE_DBCONFIG_TRIGGER_EQP
  • SQLITE_DBCONFIG_TRUSTED_SCHEMA
  • SQLITE_DBCONFIG_WRITABLE_SCHEMA
  • @@ -287,7 +260,6 @@
  • SQLITE_FCNTL_PRAGMA
  • SQLITE_FCNTL_RBU
  • SQLITE_FCNTL_RESERVE_BYTES
  • -
  • SQLITE_FCNTL_RESET_CACHE
  • SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE
  • SQLITE_FCNTL_SET_LOCKPROXYFILE
  • SQLITE_FCNTL_SIZE_HINT
  • @@ -319,11 +291,9 @@
  • SQLITE_INDEX_CONSTRAINT_ISNULL
  • SQLITE_INDEX_CONSTRAINT_LE
  • SQLITE_INDEX_CONSTRAINT_LIKE
  • -
  • SQLITE_INDEX_CONSTRAINT_LIMIT
  • SQLITE_INDEX_CONSTRAINT_LT
  • SQLITE_INDEX_CONSTRAINT_MATCH
  • SQLITE_INDEX_CONSTRAINT_NE
  • -
  • SQLITE_INDEX_CONSTRAINT_OFFSET
  • SQLITE_INDEX_CONSTRAINT_REGEXP
  • SQLITE_INDEX_SCAN_UNIQUE
  • SQLITE_INNOCUOUS
  • @@ -355,7 +325,7 @@
  • SQLITE_IOERR_CLOSE
  • SQLITE_IOERR_COMMIT_ATOMIC
  • SQLITE_IOERR_CONVPATH
  • -
  • SQLITE_IOERR_CORRUPTFS
  • +
  • SQLITE_IOERR_CORRUPTFS
  • SQLITE_IOERR_DATA
  • SQLITE_IOERR_DELETE
  • SQLITE_IOERR_DELETE_NOENT
  • @@ -423,7 +393,6 @@
  • SQLITE_NOTADB
  • SQLITE_NOTFOUND
  • SQLITE_NOTICE
  • -
  • SQLITE_NOTICE_RBU
  • SQLITE_NOTICE_RECOVER_ROLLBACK
  • SQLITE_NOTICE_RECOVER_WAL
  • SQLITE_NULL
  • @@ -434,7 +403,6 @@
  • SQLITE_OPEN_CREATE
  • SQLITE_OPEN_DELETEONCLOSE
  • SQLITE_OPEN_EXCLUSIVE
  • -
  • SQLITE_OPEN_EXRESCODE
  • SQLITE_OPEN_FULLMUTEX
  • SQLITE_OPEN_MAIN_DB
  • SQLITE_OPEN_MAIN_JOURNAL
  • @@ -473,14 +441,11 @@
  • SQLITE_ROLLBACK
  • SQLITE_ROW
  • SQLITE_SAVEPOINT
  • -
  • SQLITE_SCANSTAT_COMPLEX
  • SQLITE_SCANSTAT_EST
  • SQLITE_SCANSTAT_EXPLAIN
  • SQLITE_SCANSTAT_NAME
  • -
  • SQLITE_SCANSTAT_NCYCLE
  • SQLITE_SCANSTAT_NLOOP
  • SQLITE_SCANSTAT_NVISIT
  • -
  • SQLITE_SCANSTAT_PARENTID
  • SQLITE_SCANSTAT_SELECTID
  • SQLITE_SCHEMA
  • SQLITE_SELECT
  • @@ -503,8 +468,6 @@
  • SQLITE_STATUS_SCRATCH_SIZE
  • SQLITE_STATUS_SCRATCH_USED
  • SQLITE_STMTSTATUS_AUTOINDEX
  • -
  • SQLITE_STMTSTATUS_FILTER_HIT
  • -
  • SQLITE_STMTSTATUS_FILTER_MISS
  • SQLITE_STMTSTATUS_FULLSCAN_STEP
  • SQLITE_STMTSTATUS_MEMUSED
  • SQLITE_STMTSTATUS_REPREPARE
  • @@ -530,7 +493,6 @@
  • SQLITE_TESTCTRL_ISKEYWORD
  • SQLITE_TESTCTRL_LAST
  • SQLITE_TESTCTRL_LOCALTIME_FAULT
  • -
  • SQLITE_TESTCTRL_LOGEST
  • SQLITE_TESTCTRL_NEVER_CORRUPT
  • SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD
  • SQLITE_TESTCTRL_OPTIMIZATIONS
  • @@ -571,7 +533,6 @@
  • SQLITE_VTAB_CONSTRAINT_SUPPORT
  • SQLITE_VTAB_DIRECTONLY
  • SQLITE_VTAB_INNOCUOUS
  • -
  • SQLITE_VTAB_USES_ALL_SCHEMAS
  • SQLITE_WARNING
  • SQLITE_WARNING_AUTOINDEX
  • SQLITE_WIN32_DATA_DIRECTORY_TYPE
  • @@ -579,8 +540,7 @@

    Other lists: -Objects and -Functions and +Objects and +Functions and Result Codes.

    - diff -Nru sqlite3-3.42.0/www/c3ref/context_db_handle.html sqlite3-3.44.0-0/www/c3ref/context_db_handle.html --- sqlite3-3.42.0/www/c3ref/context_db_handle.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/context_db_handle.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Database Connection For Functions

    @@ -130,7 +106,6 @@
     and sqlite3_create_function16() routines that originally
     registered the application defined function.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/context.html sqlite3-3.44.0-0/www/c3ref/context.html --- sqlite3-3.42.0/www/c3ref/context.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/context.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    SQL Function Context Object

    @@ -132,7 +108,7 @@
     sqlite3_aggregate_context(), sqlite3_user_data(),
     sqlite3_context_db_handle(), sqlite3_get_auxdata(),
     and/or sqlite3_set_auxdata().
    -

    26 Methods using this object: +

    26 Methods:

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_open_autoproxy.html sqlite3-3.44.0-0/www/c3ref/c_open_autoproxy.html --- sqlite3-3.42.0/www/c3ref/c_open_autoproxy.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_open_autoproxy.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Flags For File Open Operations

    @@ -142,27 +118,12 @@
     #define SQLITE_OPEN_PRIVATECACHE     0x00040000  /* Ok for sqlite3_open_v2() */
     #define SQLITE_OPEN_WAL              0x00080000  /* VFS only */
     #define SQLITE_OPEN_NOFOLLOW         0x01000000  /* Ok for sqlite3_open_v2() */
    -#define SQLITE_OPEN_EXRESCODE        0x02000000  /* Extended result codes */
     

    These bit values are intended for use in the 3rd parameter to the sqlite3_open_v2() interface and -in the 4th parameter to the sqlite3_vfs.xOpen method.

    - -

    Only those flags marked as "Ok for sqlite3_open_v2()" may be -used as the third argument to the sqlite3_open_v2() interface. -The other flags have historically been ignored by sqlite3_open_v2(), -though future versions of SQLite might change so that an error is -raised if any of the disallowed bits are passed into sqlite3_open_v2(). -Applications should not depend on the historical behavior.

    - -

    Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into -sqlite3_open_v2() does *not* cause the underlying database file -to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into -sqlite3_open_v2() has historically be a no-op and might become an -error in future versions of SQLite. +in the 4th parameter to the sqlite3_vfs.xOpen method.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_prepare_normalize.html sqlite3-3.44.0-0/www/c3ref/c_prepare_normalize.html --- sqlite3-3.42.0/www/c3ref/c_prepare_normalize.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_prepare_normalize.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -161,7 +137,6 @@
     any virtual tables.
     
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/create_collation.html sqlite3-3.44.0-0/www/c3ref/create_collation.html --- sqlite3-3.42.0/www/c3ref/create_collation.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/create_collation.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Define New Collating Sequences

    @@ -222,7 +198,6 @@
     
     

    See also: sqlite3_collation_needed() and sqlite3_collation_needed16().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/create_filename.html sqlite3-3.44.0-0/www/c3ref/create_filename.html --- sqlite3-3.42.0/www/c3ref/create_filename.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/create_filename.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,46 +89,22 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Create and Destroy VFS Filenames

    -sqlite3_filename sqlite3_create_filename(
    +char *sqlite3_create_filename(
       const char *zDatabase,
       const char *zJournal,
       const char *zWal,
       int nParam,
       const char **azParam
     );
    -void sqlite3_free_filename(sqlite3_filename);
    +void sqlite3_free_filename(char*);
     

    These interfces are provided for use by VFS shim implementations and @@ -173,7 +149,6 @@ then the corresponding [sqlite3_module.xClose() method should also be invoked prior to calling sqlite3_free_filename(Y).

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/create_function.html sqlite3-3.44.0-0/www/c3ref/create_function.html --- sqlite3-3.42.0/www/c3ref/create_function.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/create_function.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Create Or Redefine SQL Functions

    @@ -284,7 +260,6 @@
     close the database connection nor finalize or reset the prepared
     statement in which the function is running.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/create_module.html sqlite3-3.44.0-0/www/c3ref/create_module.html --- sqlite3-3.42.0/www/c3ref/create_module.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/create_module.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Register A Virtual Table Implementation

    @@ -159,12 +135,11 @@
     destructor.

    If the third parameter (the pointer to the sqlite3_module object) is -NULL then no new module is created and any existing modules with the +NULL then no new module is create and any existing modules with the same name are dropped.

    See also: sqlite3_drop_modules()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_scanstat_complex.html sqlite3-3.44.0-0/www/c3ref/c_scanstat_complex.html --- sqlite3-3.42.0/www/c3ref/c_scanstat_complex.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_scanstat_complex.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,130 +0,0 @@ - - - - - -Prepared Statement Scan Status - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Prepared Statement Scan Status

    -
    -
    -#define SQLITE_SCANSTAT_COMPLEX 0x0001
    -
    -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/c_scanstat_est.html sqlite3-3.44.0-0/www/c3ref/c_scanstat_est.html --- sqlite3-3.42.0/www/c3ref/c_scanstat_est.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_scanstat_est.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Prepared Statement Scan Status Opcodes

    @@ -127,8 +103,6 @@
     #define SQLITE_SCANSTAT_NAME     3
     #define SQLITE_SCANSTAT_EXPLAIN  4
     #define SQLITE_SCANSTAT_SELECTID 5
    -#define SQLITE_SCANSTAT_PARENTID 6
    -#define SQLITE_SCANSTAT_NCYCLE   7
     

    The following constants can be used for the T parameter to the @@ -139,10 +113,6 @@ managed by the prepared statement S and will be automatically freed when S is finalized.

    -

    Not all values are available for all query elements. When a value is -not available, the output variable is set to -1 if the value is numeric, -or to NULL if it is a string (SQLITE_SCANSTAT_NAME).

    -

    SQLITE_SCANSTAT_NLOOP
    @@ -176,29 +146,14 @@ description for the X-th loop.

    -

    SQLITE_SCANSTAT_SELECTID
    -
    The "int" variable pointed to by the V parameter will be set to the -id for the X-th query plan element. The id value is unique within the -statement. The select-id is the same value as is output in the first -column of an EXPLAIN QUERY PLAN query.

    - -

    -

    SQLITE_SCANSTAT_PARENTID
    +
    SQLITE_SCANSTAT_SELECT
    The "int" variable pointed to by the V parameter will be set to the -the id of the parent of the current query element, if applicable, or -to zero if the query element has no parent. This is the same value as -returned in the second column of an EXPLAIN QUERY PLAN query.

    - -

    -

    SQLITE_SCANSTAT_NCYCLE
    -
    The sqlite3_int64 output value is set to the number of cycles, -according to the processor time-stamp counter, that elapsed while the -query element was being processed. This value is not available for -all query elements - if it is unavailable the output variable is -set to -1. +"select-id" for the X-th loop. The select-id identifies which query or +subquery the loop is part of. The main query has a select-id of zero. +The select-id is the same value as is output in the first column +of an EXPLAIN QUERY PLAN query.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_serialize_nocopy.html sqlite3-3.44.0-0/www/c3ref/c_serialize_nocopy.html --- sqlite3-3.42.0/www/c3ref/c_serialize_nocopy.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_serialize_nocopy.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Flags for sqlite3_serialize

    @@ -135,7 +111,6 @@
     using a contiguous in-memory database if it has been initialized by a
     prior call to sqlite3_deserialize().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_shm_exclusive.html sqlite3-3.44.0-0/www/c3ref/c_shm_exclusive.html --- sqlite3-3.42.0/www/c3ref/c_shm_exclusive.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_shm_exclusive.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Flags for the xShmLock VFS method

    @@ -146,7 +122,6 @@
     between unlocked and EXCLUSIVE.  It cannot transition between SHARED
     and EXCLUSIVE.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_shm_nlock.html sqlite3-3.44.0-0/www/c3ref/c_shm_nlock.html --- sqlite3-3.42.0/www/c3ref/c_shm_nlock.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_shm_nlock.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Maximum xShmLock index

    @@ -129,7 +105,6 @@
     The SQLite core will never attempt to acquire or release a
     lock outside of this range
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_source_id.html sqlite3-3.44.0-0/www/c3ref/c_source_id.html --- sqlite3-3.42.0/www/c3ref/c_source_id.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_source_id.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,41 +89,17 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Compile-Time Library Version Numbers

    -#define SQLITE_VERSION        "3.42.0"
    -#define SQLITE_VERSION_NUMBER 3042000
    -#define SQLITE_SOURCE_ID      "2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0"
    +#define SQLITE_VERSION        "3.36.0"
    +#define SQLITE_VERSION_NUMBER 3036000
    +#define SQLITE_SOURCE_ID      "2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5"
     

    The SQLITE_VERSION C preprocessor macro in the sqlite3.h header @@ -153,7 +129,6 @@ sqlite3_libversion_number(), sqlite3_sourceid(), sqlite_version() and sqlite_source_id().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_static.html sqlite3-3.44.0-0/www/c3ref/c_static.html --- sqlite3-3.42.0/www/c3ref/c_static.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_static.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Constants Defining Special Destructor Behavior

    @@ -137,7 +113,6 @@
     

    The typedef is necessary to work around problems in certain C++ compilers.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_status_malloc_count.html sqlite3-3.44.0-0/www/c3ref/c_status_malloc_count.html --- sqlite3-3.42.0/www/c3ref/c_status_malloc_count.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_status_malloc_count.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -206,7 +182,6 @@
     
     

    New status parameters may be added from time to time.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_stmtstatus_counter.html sqlite3-3.44.0-0/www/c3ref/c_stmtstatus_counter.html --- sqlite3-3.42.0/www/c3ref/c_stmtstatus_counter.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_stmtstatus_counter.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Status Parameters for prepared statements

    @@ -127,8 +103,6 @@
     #define SQLITE_STMTSTATUS_VM_STEP           4
     #define SQLITE_STMTSTATUS_REPREPARE         5
     #define SQLITE_STMTSTATUS_RUN               6
    -#define SQLITE_STMTSTATUS_FILTER_MISS       7
    -#define SQLITE_STMTSTATUS_FILTER_HIT        8
     #define SQLITE_STMTSTATUS_MEMUSED           99
     

    @@ -181,18 +155,6 @@ The counter is incremented on the first sqlite3_step() call of each cycle.

    -

    - - - -

    SQLITE_STMTSTATUS_FILTER_HIT
    -SQLITE_STMTSTATUS_FILTER_MISS
    -
    SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join -step was bypassed because a Bloom filter returned not-found. The -corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of -times that the Bloom filter returned a find, and thus the join step -had to be processed as normal.

    -

    SQLITE_STMTSTATUS_MEMUSED
    This is the approximate number of bytes of heap memory @@ -202,7 +164,6 @@

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_sync_dataonly.html sqlite3-3.44.0-0/www/c3ref/c_sync_dataonly.html --- sqlite3-3.42.0/www/c3ref/c_sync_dataonly.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_sync_dataonly.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Synchronization Type Flags

    @@ -149,7 +125,6 @@
     operating systems natively supported by SQLite, only Mac OSX
     cares about the difference.)
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_testctrl_always.html sqlite3-3.44.0-0/www/c3ref/c_testctrl_always.html --- sqlite3-3.42.0/www/c3ref/c_testctrl_always.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_testctrl_always.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Testing Interface Operation Codes

    @@ -152,8 +128,7 @@
     #define SQLITE_TESTCTRL_SEEK_COUNT              30
     #define SQLITE_TESTCTRL_TRACEFLAGS              31
     #define SQLITE_TESTCTRL_TUNE                    32
    -#define SQLITE_TESTCTRL_LOGEST                  33
    -#define SQLITE_TESTCTRL_LAST                    33  /* Largest TESTCTRL */
    +#define SQLITE_TESTCTRL_LAST                    32  /* Largest TESTCTRL */
     

    These constants are the valid operation code parameters used @@ -164,7 +139,6 @@ Applications should not use any of these parameters or the sqlite3_test_control() interface.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_trace.html sqlite3-3.44.0-0/www/c3ref/c_trace.html --- sqlite3-3.42.0/www/c3ref/c_trace.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_trace.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    SQL Trace Event Codes

    @@ -160,8 +136,8 @@
     
    An SQLITE_TRACE_PROFILE callback provides approximately the same information as is provided by the sqlite3_profile() callback. The P argument is a pointer to the prepared statement and the -X argument points to a 64-bit integer which is approximately -the number of nanoseconds that the prepared statement took to run. +X argument points to a 64-bit integer which is the estimated of +the number of nanosecond that the prepared statement took to run. The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.

    @@ -179,7 +155,6 @@ and the X argument is unused.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_txn_none.html sqlite3-3.44.0-0/www/c3ref/c_txn_none.html --- sqlite3-3.42.0/www/c3ref/c_txn_none.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_txn_none.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Allowed return values from [sqlite3_txn_state()]

    @@ -154,7 +130,6 @@
     but has not yet committed.  The transaction state will change to
     to SQLITE_TXN_NONE at the next ROLLBACK or COMMIT.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_vtab_constraint_support.html sqlite3-3.44.0-0/www/c3ref/c_vtab_constraint_support.html --- sqlite3-3.42.0/www/c3ref/c_vtab_constraint_support.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_vtab_constraint_support.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,42 +89,17 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Configuration Options

     #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1
     #define SQLITE_VTAB_INNOCUOUS          2
     #define SQLITE_VTAB_DIRECTONLY         3
    -#define SQLITE_VTAB_USES_ALL_SCHEMAS   4
     

    These macros define the various options to the @@ -178,26 +153,15 @@

    SQLITE_VTAB_INNOCUOUS
    Calls of the form sqlite3_vtab_config(db,SQLITE_VTAB_INNOCUOUS) from within the -the xConnect or xCreate methods of a virtual table implementation +the xConnect or xCreate methods of a virtual table implmentation identify that virtual table as being safe to use from within triggers and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the virtual table can do no serious harm even if it is controlled by a malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS flag unless absolutely necessary. -

    - -

    -

    SQLITE_VTAB_USES_ALL_SCHEMAS
    -
    Calls of the form -sqlite3_vtab_config(db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the -the xConnect or xCreate methods of a virtual table implementation -instruct the query planner to begin at least a read transaction on -all schemas ("main", "temp", and any ATTACH-ed databases) whenever the -virtual table is used.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/c_win32_data_directory_type.html sqlite3-3.44.0-0/www/c3ref/c_win32_data_directory_type.html --- sqlite3-3.42.0/www/c3ref/c_win32_data_directory_type.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/c_win32_data_directory_type.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Win32 Directory Types

    @@ -128,7 +104,6 @@
     These macros are only available on Windows.  They define the allowed values
     for the type argument to the sqlite3_win32_set_directory interface.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/database_file_object.html sqlite3-3.44.0-0/www/c3ref/database_file_object.html --- sqlite3-3.42.0/www/c3ref/database_file_object.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/database_file_object.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Database File Corresponding To A Journal

    @@ -138,7 +114,6 @@
     of this routine results in undefined and probably undesirable
     behavior.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/data_count.html sqlite3-3.44.0-0/www/c3ref/data_count.html --- sqlite3-3.42.0/www/c3ref/data_count.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/data_count.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Number of columns in a result set

    @@ -139,7 +115,6 @@
     
     

    See also: sqlite3_column_count()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/data_directory.html sqlite3-3.44.0-0/www/c3ref/data_directory.html --- sqlite3-3.42.0/www/c3ref/data_directory.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/data_directory.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Name Of The Folder Holding Database Files

    @@ -156,7 +132,6 @@
     made NULL or made to point to memory obtained from sqlite3_malloc
     or else the use of the data_store_directory pragma should be avoided.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_cacheflush.html sqlite3-3.44.0-0/www/c3ref/db_cacheflush.html --- sqlite3-3.42.0/www/c3ref/db_cacheflush.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_cacheflush.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Flush caches to disk mid-transaction

    @@ -151,7 +127,6 @@
     

    This function does not set the database handle error code or message returned by the sqlite3_errcode() and sqlite3_errmsg() functions.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_config.html sqlite3-3.44.0-0/www/c3ref/db_config.html --- sqlite3-3.42.0/www/c3ref/db_config.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_config.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Configure database connections

    @@ -137,7 +113,6 @@
     

    Calls to sqlite3_db_config() return SQLITE_OK if and only if the call is considered successful.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_filename.html sqlite3-3.44.0-0/www/c3ref/db_filename.html --- sqlite3-3.42.0/www/c3ref/db_filename.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_filename.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,39 +89,15 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Return The Filename For A Database Connection

    -sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName);
    +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
     

    The sqlite3_db_filename(D,N) interface returns a pointer to the filename @@ -150,7 +126,6 @@

  • sqlite3_filename_wal()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_handle.html sqlite3-3.44.0-0/www/c3ref/db_handle.html --- sqlite3-3.42.0/www/c3ref/db_handle.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_handle.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Find The Database Handle Of A Prepared Statement

    @@ -131,7 +107,6 @@
     to the sqlite3_prepare_v2() call (or its variants) that was used to
     create the statement in the first place.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_mutex.html sqlite3-3.44.0-0/www/c3ref/db_mutex.html --- sqlite3-3.42.0/www/c3ref/db_mutex.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_mutex.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Retrieve the mutex for a database connection

    @@ -130,7 +106,6 @@
     If the threading mode is Single-thread or Multi-thread then this
     routine returns a NULL pointer.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_name.html sqlite3-3.44.0-0/www/c3ref/db_name.html --- sqlite3-3.42.0/www/c3ref/db_name.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_name.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ - - - - - -Return The Schema Name For A Database Connection - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Return The Schema Name For A Database Connection

    -
    -
    -const char *sqlite3_db_name(sqlite3 *db, int N);
    -
    -

    -The sqlite3_db_name(D,N) interface returns a pointer to the schema name -for the N-th database on database connection D, or a NULL pointer of N is -out of range. An N value of 0 means the main database file. An N of 1 is -the "temp" schema. Larger values of N correspond to various ATTACH-ed -databases.

    - -

    Space to hold the string that is returned by sqlite3_db_name() is managed -by SQLite itself. The string might be deallocated by any operation that -changes the schema, including ATTACH or DETACH or calls to -sqlite3_serialize() or sqlite3_deserialize(), even operations that -occur on a different thread. Applications that need to -remember the string long-term should make their own copy. Applications that -are accessing the same database connection simultaneously on multiple -threads should mutex-protect calls to this API and should make their own -private copy of the result prior to releasing the mutex. -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/db_readonly.html sqlite3-3.44.0-0/www/c3ref/db_readonly.html --- sqlite3-3.42.0/www/c3ref/db_readonly.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_readonly.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine if a database is read-only

    @@ -128,7 +104,6 @@
     of connection D is read-only, 0 if it is read/write, or -1 if N is not
     the name of a database on connection D.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_release_memory.html sqlite3-3.44.0-0/www/c3ref/db_release_memory.html --- sqlite3-3.42.0/www/c3ref/db_release_memory.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_release_memory.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Free Memory Used By A Database Connection

    @@ -132,7 +108,6 @@
     
     

    See also: sqlite3_release_memory()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/db_status.html sqlite3-3.44.0-0/www/c3ref/db_status.html --- sqlite3-3.42.0/www/c3ref/db_status.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/db_status.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Database Connection Status

    @@ -143,7 +119,6 @@
     
     

    See also: sqlite3_status() and sqlite3_stmt_status().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/declare_vtab.html sqlite3-3.44.0-0/www/c3ref/declare_vtab.html --- sqlite3-3.42.0/www/c3ref/declare_vtab.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/declare_vtab.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Declare The Schema Of A Virtual Table

    @@ -129,7 +105,6 @@
     to declare the format (the names and datatypes of the columns) of
     the virtual tables they implement.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/deserialize.html sqlite3-3.44.0-0/www/c3ref/deserialize.html --- sqlite3-3.42.0/www/c3ref/deserialize.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/deserialize.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Deserialize a database

    @@ -150,10 +126,6 @@
     database is currently in a read transaction or is involved in a backup
     operation.

    -

    It is not possible to deserialized into the TEMP database. If the -S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the -function returns SQLITE_ERROR.

    -

    If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then sqlite3_free() is invoked on argument P prior to returning.

    @@ -161,7 +133,6 @@

    This interface is omitted if SQLite is compiled with the SQLITE_OMIT_DESERIALIZE option.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/drop_modules.html sqlite3-3.44.0-0/www/c3ref/drop_modules.html --- sqlite3-3.42.0/www/c3ref/drop_modules.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/drop_modules.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Remove Unnecessary Virtual Table Implementations

    @@ -135,7 +111,6 @@
     
     

    See also: sqlite3_create_module()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/enable_load_extension.html sqlite3-3.44.0-0/www/c3ref/enable_load_extension.html --- sqlite3-3.42.0/www/c3ref/enable_load_extension.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/enable_load_extension.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Enable Or Disable Extension Loading

    @@ -145,7 +121,6 @@
     remains disabled. This will prevent SQL injections from giving attackers
     access to extension loading capabilities.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/enable_shared_cache.html sqlite3-3.44.0-0/www/c3ref/enable_shared_cache.html --- sqlite3-3.42.0/www/c3ref/enable_shared_cache.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/enable_shared_cache.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Enable Or Disable Shared Pager Cache

    @@ -129,11 +105,6 @@
     to the same database. Sharing is enabled if the argument is true
     and disabled if the argument is false.

    -

    This interface is omitted if SQLite is compiled with --DSQLITE_OMIT_SHARED_CACHE. The -DSQLITE_OMIT_SHARED_CACHE -compile-time option is recommended because the -use of shared cache mode is discouraged.

    -

    Cache sharing is enabled and disabled for an entire process. This is a change as of SQLite version 3.5.0 (2007-09-04). In prior versions of SQLite, @@ -165,7 +136,6 @@

    See Also: SQLite Shared-Cache Mode

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/errcode.html sqlite3-3.44.0-0/www/c3ref/errcode.html --- sqlite3-3.42.0/www/c3ref/errcode.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/errcode.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Error Codes And Messages

    @@ -126,7 +102,6 @@
     const char *sqlite3_errmsg(sqlite3*);
     const void *sqlite3_errmsg16(sqlite3*);
     const char *sqlite3_errstr(int);
    -int sqlite3_error_offset(sqlite3 *db);
     

    If the most recent sqlite3_* API call associated with @@ -142,14 +117,13 @@ sqlite3_extended_errcode() might change with each API call. Except, there are some interfaces that are guaranteed to never change the value of the error code. The error-code preserving -interfaces include the following:

    +interfaces are:

    • sqlite3_errcode()
    • sqlite3_extended_errcode()
    • sqlite3_errmsg()
    • sqlite3_errmsg16() -
    • sqlite3_error_offset()

    The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -164,13 +138,6 @@ Memory to hold the error message string is managed internally and must not be freed by the application.

    -

    If the most recent error references a specific token in the input -SQL, the sqlite3_error_offset() interface returns the byte offset -of the start of that token. The byte offset returned by -sqlite3_error_offset() assumes that the input SQL is UTF8. -If the most recent error does not reference a specific token in the input -SQL, then the sqlite3_error_offset() function returns -1.

    -

    When the serialized threading mode is in use, it might be the case that a second error occurs on a separate thread in between the time of the first error and the call to these interfaces. @@ -185,7 +152,6 @@ was invoked incorrectly by the application. In that case, the error code and message may or may not be set.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/exec.html sqlite3-3.44.0-0/www/c3ref/exec.html --- sqlite3-3.42.0/www/c3ref/exec.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/exec.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    One-Step Query Execution Interface

    @@ -188,7 +164,6 @@
     the 2nd parameter of sqlite3_exec() while sqlite3_exec() is running.
     
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/expanded_sql.html sqlite3-3.44.0-0/www/c3ref/expanded_sql.html --- sqlite3-3.42.0/www/c3ref/expanded_sql.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/expanded_sql.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,43 +89,17 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Retrieving Statement SQL

     const char *sqlite3_sql(sqlite3_stmt *pStmt);
     char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
    -#ifdef SQLITE_ENABLE_NORMALIZE
     const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
    -#endif
     

    The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 @@ -159,13 +133,9 @@ are managed by SQLite and are automatically freed when the prepared statement is finalized. The string returned by sqlite3_expanded_sql(P), on the other hand, -is obtained from sqlite3_malloc() and must be freed by the application -by passing it to sqlite3_free().

    - -

    The sqlite3_normalized_sql() interface is only available if -the SQLITE_ENABLE_NORMALIZE compile-time option is defined. +is obtained from sqlite3_malloc() and must be free by the application +by passing it to sqlite3_free().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/experimental.html sqlite3-3.44.0-0/www/c3ref/experimental.html --- sqlite3-3.42.0/www/c3ref/experimental.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/experimental.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite C Interface

    + +

    SQLite C Interface

    Experimental And Deprecated Interfaces

    @@ -132,7 +108,7 @@ should always be able to relink against a newer version of SQLite without any changes.

    -

    Experimental interfaces are subject to change. +

    Experimental interfaces are subject to change. Applications that use experimental interfaces may need to be modified when upgrading to a newer SQLite release, though this is rare. @@ -151,7 +127,7 @@

    Key points:

      -
    • Experimental interfaces are subject to change and/or removal +
    • Experimental interfaces are subject to change and/or removal at any time.
    • Deprecated interfaces should not be used in new code and might @@ -159,4 +135,3 @@
    - diff -Nru sqlite3-3.42.0/www/c3ref/extended_result_codes.html sqlite3-3.44.0-0/www/c3ref/extended_result_codes.html --- sqlite3-3.42.0/www/c3ref/extended_result_codes.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/extended_result_codes.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Enable Or Disable Extended Result Codes

    @@ -128,7 +104,6 @@
     extended result codes feature of SQLite. The extended result
     codes are disabled by default for historical compatibility.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/file_control.html sqlite3-3.44.0-0/www/c3ref/file_control.html --- sqlite3-3.42.0/www/c3ref/file_control.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/file_control.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Low-Level Control Of Database Files

    @@ -160,7 +136,6 @@
     
     

    See also: file control opcodes

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/file.html sqlite3-3.44.0-0/www/c3ref/file.html --- sqlite3-3.42.0/www/c3ref/file.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/file.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    OS Interface Open File Handle

    @@ -135,7 +111,6 @@
     sqlite3_io_methods object that defines methods for performing
     I/O operations on the open file.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/filename_database.html sqlite3-3.44.0-0/www/c3ref/filename_database.html --- sqlite3-3.42.0/www/c3ref/filename_database.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/filename_database.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,41 +89,17 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Translate filenames

    -const char *sqlite3_filename_database(sqlite3_filename);
    -const char *sqlite3_filename_journal(sqlite3_filename);
    -const char *sqlite3_filename_wal(sqlite3_filename);
    +const char *sqlite3_filename_database(const char*);
    +const char *sqlite3_filename_journal(const char*);
    +const char *sqlite3_filename_wal(const char*);
     

    These routines are available to custom VFS implementations for @@ -150,7 +126,6 @@ return value from sqlite3_db_filename(), then the result is undefined and is likely a memory access violation.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/filename.html sqlite3-3.44.0-0/www/c3ref/filename.html --- sqlite3-3.42.0/www/c3ref/filename.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/filename.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,145 +0,0 @@ - - - - - -File Name - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    File Name

    -
    -
    -typedef const char *sqlite3_filename;
    -
    -

    -Type sqlite3_filename is used by SQLite to pass filenames to the -xOpen method of a VFS. It may be cast to (const char*) and treated -as a normal, nul-terminated, UTF-8 buffer containing the filename, but -may also be passed to special APIs such as:

    - -

      -
    • sqlite3_filename_database() -
    • sqlite3_filename_journal() -
    • sqlite3_filename_wal() -
    • sqlite3_uri_parameter() -
    • sqlite3_uri_boolean() -
    • sqlite3_uri_int64() -
    • sqlite3_uri_key() -
    -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/finalize.html sqlite3-3.44.0-0/www/c3ref/finalize.html --- sqlite3-3.42.0/www/c3ref/finalize.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/finalize.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Destroy A Prepared Statement Object

    @@ -146,7 +122,6 @@
     statement after it has been finalized can result in undefined and
     undesirable behavior such as segfaults and heap corruption.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/free.html sqlite3-3.44.0-0/www/c3ref/free.html --- sqlite3-3.42.0/www/c3ref/free.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/free.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Memory Allocation Subsystem

    @@ -201,7 +177,6 @@
     a block of memory after it has been released using
     sqlite3_free() or sqlite3_realloc().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/free_table.html sqlite3-3.44.0-0/www/c3ref/free_table.html --- sqlite3-3.42.0/www/c3ref/free_table.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/free_table.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Convenience Routines For Running Queries

    @@ -201,7 +177,6 @@
     reflected in subsequent calls to sqlite3_errcode() or
     sqlite3_errmsg().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/funclist.html sqlite3-3.44.0-0/www/c3ref/funclist.html --- sqlite3-3.42.0/www/c3ref/funclist.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/funclist.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,39 +89,15 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite C Interface

    + +

    SQLite C Interface

    List Of Functions:

    Note: Functions marked with "(exp)" are experimental and functions whose names are struck through are deprecated.

    - +
    @@ -129,7 +105,6 @@
  • sqlite3_aggregate_context
  • sqlite3_aggregate_count
  • sqlite3_auto_extension
  • -
  • sqlite3_autovacuum_pages
  • sqlite3_backup_finish
  • sqlite3_backup_init
  • sqlite3_backup_pagecount
  • @@ -161,7 +136,6 @@
  • sqlite3_busy_timeout
  • sqlite3_cancel_auto_extension
  • sqlite3_changes
  • -
  • sqlite3_changes64
  • sqlite3_clear_bindings
  • sqlite3_close
  • sqlite3_close_v2
  • @@ -212,7 +186,6 @@
  • sqlite3_db_filename
  • sqlite3_db_handle
  • sqlite3_db_mutex
  • -
  • sqlite3_db_name
  • sqlite3_db_readonly
  • sqlite3_db_release_memory
  • sqlite3_db_status
  • @@ -224,7 +197,6 @@
  • sqlite3_errcode
  • sqlite3_errmsg
  • sqlite3_errmsg16
  • -
  • sqlite3_error_offset
  • sqlite3_errstr
  • sqlite3_exec
  • sqlite3_expanded_sql
  • @@ -246,7 +218,6 @@
  • sqlite3_hard_heap_limit64
  • sqlite3_initialize
  • sqlite3_interrupt
  • -
  • sqlite3_is_interrupted
  • sqlite3_keyword_check
  • sqlite3_keyword_count
  • sqlite3_keyword_name
  • @@ -344,7 +315,6 @@
  • sqlite3_stmt_readonly
  • sqlite3_stmt_scanstatus
  • sqlite3_stmt_scanstatus_reset
  • -
  • sqlite3_stmt_scanstatus_v2
  • sqlite3_stmt_status
  • sqlite3_str_append
  • sqlite3_str_appendall
  • @@ -367,7 +337,6 @@
  • sqlite3_thread_cleanup
  • sqlite3_threadsafe
  • sqlite3_total_changes
  • -
  • sqlite3_total_changes64
  • sqlite3_trace
  • sqlite3_trace_v2
  • sqlite3_transfer_bindings
  • @@ -384,7 +353,6 @@
  • sqlite3_value_bytes16
  • sqlite3_value_double
  • sqlite3_value_dup
  • -
  • sqlite3_value_encoding
  • sqlite3_value_free
  • sqlite3_value_frombind
  • sqlite3_value_int
  • @@ -406,13 +374,8 @@
  • sqlite3_vsnprintf
  • sqlite3_vtab_collation
  • sqlite3_vtab_config
  • -
  • sqlite3_vtab_distinct
  • -
  • sqlite3_vtab_in
  • -
  • sqlite3_vtab_in_first
  • -
  • sqlite3_vtab_in_next
  • sqlite3_vtab_nochange
  • sqlite3_vtab_on_conflict
  • -
  • sqlite3_vtab_rhs_value
  • sqlite3_wal_autocheckpoint
  • sqlite3_wal_checkpoint
  • sqlite3_wal_checkpoint_v2
  • @@ -423,8 +386,7 @@

    Other lists: -Constants and -Objects and +Constants and +Objects and Result Codes

    - diff -Nru sqlite3-3.42.0/www/c3ref/get_autocommit.html sqlite3-3.44.0-0/www/c3ref/get_autocommit.html --- sqlite3-3.42.0/www/c3ref/get_autocommit.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/get_autocommit.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Test For Auto-Commit Mode

    @@ -141,7 +117,6 @@
     connection while this routine is running, then the return value
     is undefined.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/get_auxdata.html sqlite3-3.44.0-0/www/c3ref/get_auxdata.html --- sqlite3-3.42.0/www/c3ref/get_auxdata.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/get_auxdata.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Function Auxiliary Data

    @@ -178,7 +154,6 @@
     

    These routines must be called from the same thread in which the SQL function is running.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/hard_heap_limit64.html sqlite3-3.44.0-0/www/c3ref/hard_heap_limit64.html --- sqlite3-3.42.0/www/c3ref/hard_heap_limit64.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/hard_heap_limit64.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Impose A Limit On Heap Size

    @@ -157,7 +133,7 @@
     

    The soft heap limit may not be greater than the hard heap limit. If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) is invoked with a value of N that is greater than the hard heap limit, -the soft heap limit is set to the value of the hard heap limit. +the the soft heap limit is set to the value of the hard heap limit. The soft heap limit is automatically enabled whenever the hard heap limit is enabled. When sqlite3_hard_heap_limit64(N) is invoked and the soft heap limit is outside the range of 1..N, then the soft heap @@ -186,7 +162,6 @@

    The circumstances under which SQLite will enforce the heap limits may changes in future releases of SQLite.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/index_info.html sqlite3-3.44.0-0/www/c3ref/index_info.html --- sqlite3-3.42.0/www/c3ref/index_info.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/index_info.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Indexing Information

    @@ -206,10 +182,10 @@
     when the omit flag is true there is no guarantee that the constraint will
     not be checked again using byte code.

    -

    The idxNum and idxStr values are recorded and passed into the +

    The idxNum and idxPtr values are recorded and passed into the xFilter method. -sqlite3_free() is used to free idxStr if and only if -needToFreeIdxStr is true.

    +sqlite3_free() is used to free idxPtr if and only if +needToFreeIdxPtr is true.

    The orderByConsumed means that output from xFilter/xNext will occur in the correct order to satisfy the ORDER BY clause so that no separate @@ -251,12 +227,7 @@ It may therefore only be used if sqlite3_libversion_number() returns a value greater than or equal to 3009000. -

    3 Methods using this object: - sqlite3_vtab_collation(), -sqlite3_vtab_distinct(), -sqlite3_vtab_rhs_value()

    -

    See also lists of - Objects, - Constants, and - Functions.

    - +

    See also lists of + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/initialize.html sqlite3-3.44.0-0/www/c3ref/initialize.html --- sqlite3-3.42.0/www/c3ref/initialize.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/initialize.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Initialize The SQLite Library

    @@ -199,7 +175,6 @@
     must return SQLITE_OK on success and some other error code upon
     failure.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/int64.html sqlite3-3.44.0-0/www/c3ref/int64.html --- sqlite3-3.42.0/www/c3ref/int64.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/int64.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    64-Bit Integer Types

    @@ -151,7 +127,6 @@
     sqlite3_uint64 and sqlite_uint64 types can store integer values
     between 0 and +18446744073709551615 inclusive.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/interrupt.html sqlite3-3.44.0-0/www/c3ref/interrupt.html --- sqlite3-3.42.0/www/c3ref/interrupt.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/interrupt.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,40 +89,15 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Interrupt A Long-Running Query

     void sqlite3_interrupt(sqlite3*);
    -int sqlite3_is_interrupted(sqlite3*);
     

    This function causes any pending database operation to abort and @@ -154,12 +129,8 @@ not effected by the sqlite3_interrupt(). A call to sqlite3_interrupt(D) that occurs when there are no running SQL statements is a no-op and has no effect on SQL statements -that are started after the sqlite3_interrupt() call returns.

    - -

    The sqlite3_is_interrupted(D) interface can be used to determine whether -or not an interrupt is currently in effect for database connection D. +that are started after the sqlite3_interrupt() call returns.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/intro.html sqlite3-3.44.0-0/www/c3ref/intro.html --- sqlite3-3.42.0/www/c3ref/intro.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/intro.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    @@ -134,14 +110,14 @@

    The SQLite interface elements can be grouped into three categories:

      -
    1. List Of Objects. +

    2. List Of Objects. This is a list of all abstract objects and datatypes used by the SQLite library. There are couple dozen objects in total, but the two most important objects are: A database connection object sqlite3, and the prepared statement object sqlite3_stmt.

    3. -
    4. List Of Constants. +

    5. List Of Constants. This is a list of numeric constants used by SQLite and represented by #defines in the sqlite3.h header file. These constants are things such as numeric result codes from @@ -149,13 +125,12 @@ into functions to control behavior (ex: SQLITE_OPEN_READONLY).

    6. -
    7. List Of Functions. - This is a list of all functions and methods operating on the - objects and using and/or - returning constants. There +

    8. List Of Functions. + This is a list of all functions and methods operating on the + objects and using and/or + returning constants. There are many functions, but most applications only use a handful.

    - diff -Nru sqlite3-3.42.0/www/c3ref/io_methods.html sqlite3-3.44.0-0/www/c3ref/io_methods.html --- sqlite3-3.42.0/www/c3ref/io_methods.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/io_methods.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    OS Interface File Virtual Methods Object

    @@ -176,13 +152,7 @@
     
  • SQLITE_LOCK_PENDING, or
  • SQLITE_LOCK_EXCLUSIVE. -xLock() upgrades the database file lock. In other words, xLock() moves the -database file lock in the direction NONE toward EXCLUSIVE. The argument to -xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never -SQLITE_LOCK_NONE. If the database file lock is already at or above the -requested lock, then the call to xLock() is a no-op. -xUnlock() downgrades the database file lock to either SHARED or NONE. -to xUnlock() is a no-op. +xLock() increases the lock. xUnlock() decreases the lock. The xCheckReservedLock() method checks whether any database connection, either in this process or in some other process, is holding a RESERVED, PENDING, or EXCLUSIVE lock on the file. It returns true @@ -246,7 +216,6 @@ failure to zero-fill short reads will eventually lead to database corruption.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/keyword_check.html sqlite3-3.44.0-0/www/c3ref/keyword_check.html --- sqlite3-3.42.0/www/c3ref/keyword_check.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/keyword_check.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    SQL Keyword Checking

    @@ -170,7 +146,6 @@
     SQLite is compiled with the -DSQLITE_OMIT_VACUUM option.  Also,
     new keywords may be added to future releases of SQLite.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/last_insert_rowid.html sqlite3-3.44.0-0/www/c3ref/last_insert_rowid.html --- sqlite3-3.42.0/www/c3ref/last_insert_rowid.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/last_insert_rowid.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -180,7 +156,6 @@
     unpredictable and might not equal either the old or the new
     last insert rowid.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/libversion.html sqlite3-3.44.0-0/www/c3ref/libversion.html --- sqlite3-3.42.0/www/c3ref/libversion.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/libversion.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Run-Time Library Version Numbers

    @@ -155,7 +131,6 @@
     
     

    See also: sqlite_version() and sqlite_source_id().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/limit.html sqlite3-3.44.0-0/www/c3ref/limit.html --- sqlite3-3.42.0/www/c3ref/limit.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/limit.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -160,7 +136,6 @@
     
     

    New run-time limit categories may be added in future releases.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/load_extension.html sqlite3-3.44.0-0/www/c3ref/load_extension.html --- sqlite3-3.42.0/www/c3ref/load_extension.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/load_extension.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -169,7 +145,6 @@
     
     

    See also the load_extension() SQL function.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/log.html sqlite3-3.44.0-0/www/c3ref/log.html --- sqlite3-3.42.0/www/c3ref/log.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/log.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Error Logging Interface

    @@ -142,7 +118,6 @@
     a few hundred characters, it will be truncated to the length of the
     buffer.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/mem_methods.html sqlite3-3.44.0-0/www/c3ref/mem_methods.html --- sqlite3-3.42.0/www/c3ref/mem_methods.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/mem_methods.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Memory Allocation Routines

    @@ -194,7 +170,6 @@
     

    SQLite will never invoke xInit() more than once without an intervening call to xShutdown().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/memory_highwater.html sqlite3-3.44.0-0/www/c3ref/memory_highwater.html --- sqlite3-3.42.0/www/c3ref/memory_highwater.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/memory_highwater.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Memory Allocator Statistics

    @@ -145,7 +121,6 @@
     by sqlite3_memory_highwater(1) is the high-water mark
     prior to the reset.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/module.html sqlite3-3.44.0-0/www/c3ref/module.html --- sqlite3-3.42.0/www/c3ref/module.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/module.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Object

    @@ -172,7 +148,6 @@
     of this structure must not change while it is registered with
     any database connection.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/mprintf.html sqlite3-3.44.0-0/www/c3ref/mprintf.html --- sqlite3-3.42.0/www/c3ref/mprintf.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/mprintf.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Formatted String Printing Functions

    @@ -164,7 +140,6 @@
     
     

    See also: built-in printf(), printf() SQL function

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/mutex_alloc.html sqlite3-3.44.0-0/www/c3ref/mutex_alloc.html --- sqlite3-3.42.0/www/c3ref/mutex_alloc.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/mutex_alloc.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -233,13 +209,12 @@
     is undefined if the mutex is not currently entered by the
     calling thread or is not currently allocated.

    -

    If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), -sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, -then any of the four routines behaves as a no-op.

    +

    If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +sqlite3_mutex_leave() is a NULL pointer, then all three routines +behave as no-ops.

    See also: sqlite3_mutex_held() and sqlite3_mutex_notheld().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/mutex_held.html sqlite3-3.44.0-0/www/c3ref/mutex_held.html --- sqlite3-3.42.0/www/c3ref/mutex_held.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/mutex_held.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Mutex Verification Routines

    @@ -153,7 +129,6 @@
     the appropriate thing to do.  The sqlite3_mutex_notheld()
     interface should also return 1 when given a NULL pointer.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/mutex.html sqlite3-3.44.0-0/www/c3ref/mutex.html --- sqlite3-3.42.0/www/c3ref/mutex.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/mutex.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -131,7 +107,6 @@
     
     

    Mutexes are created using sqlite3_mutex_alloc().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/mutex_methods.html sqlite3-3.44.0-0/www/c3ref/mutex_methods.html --- sqlite3-3.42.0/www/c3ref/mutex_methods.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/mutex_methods.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Mutex Methods Object

    @@ -197,7 +173,6 @@
     If xMutexInit fails in any way, it is expected to clean up after itself
     prior to returning.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/next_stmt.html sqlite3-3.44.0-0/www/c3ref/next_stmt.html --- sqlite3-3.42.0/www/c3ref/next_stmt.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/next_stmt.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Find the next prepared statement

    @@ -134,7 +110,6 @@
     sqlite3_next_stmt(D,S) must refer to an open database
     connection and in particular must not be a NULL pointer.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/objlist.html sqlite3-3.44.0-0/www/c3ref/objlist.html --- sqlite3-3.42.0/www/c3ref/objlist.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/objlist.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite C Interface

    + +

    SQLite C Interface

    List Of Objects:

    Other lists: -Constants and -Functions and +Constants and +Functions and Result Codes. - diff -Nru sqlite3-3.42.0/www/c3ref/open.html sqlite3-3.44.0-0/www/c3ref/open.html --- sqlite3-3.42.0/www/c3ref/open.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/open.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    -

    SQLite C Interface

    +

    SQLite C Interface

    Opening A New Database Connection

    @@ -166,18 +142,13 @@
     
     

    SQLITE_OPEN_READONLY
    -
    The database is opened in read-only mode. If the database does -not already exist, an error is returned.

    +
    The database is opened in read-only mode. If the database does not +already exist, an error is returned.

    SQLITE_OPEN_READWRITE
    -
    The database is opened for reading and writing if possible, or -reading only if the file is write protected by the operating -system. In either case the database must already exist, otherwise -an error is returned. For historical reasons, if opening in -read-write mode fails due to OS-level permissions, an attempt is -made to open it in read-only mode. sqlite3_db_readonly() can be -used to determine whether the database is actually -read-write.

    +
    The database is opened for reading and writing if possible, or reading +only if the file is write protected by the operating system. In either +case the database must already exist, otherwise an error is returned.

    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
    The database is opened for reading and writing, and is created if @@ -214,42 +185,22 @@

    SQLITE_OPEN_SHAREDCACHE
    The database is opened shared cache enabled, overriding the default shared cache setting provided by -sqlite3_enable_shared_cache(). -The use of shared cache mode is discouraged and hence shared cache -capabilities may be omitted from many builds of SQLite. In such cases, -this option is a no-op.

    +sqlite3_enable_shared_cache().

    SQLITE_OPEN_PRIVATECACHE
    The database is opened shared cache disabled, overriding the default shared cache setting provided by sqlite3_enable_shared_cache().

    -

    -

    SQLITE_OPEN_EXRESCODE
    -
    The database connection comes up in "extended result code mode". -In other words, the database behaves has if -sqlite3_extended_result_codes(db,1) where called on the database -connection as soon as the connection is created. In addition to setting -the extended result code mode, this flag also causes sqlite3_open_v2() -to return an extended result code.

    -

    SQLITE_OPEN_NOFOLLOW
    -
    The database filename is not allowed to contain a symbolic link
    +
    The database filename is not allowed to be a symbolic link

    If the 3rd parameter to sqlite3_open_v2() is not one of the required combinations shown above optionally combined with other SQLITE_OPEN_* bits -then the behavior is undefined. Historic versions of SQLite -have silently ignored surplus bits in the flags parameter to -sqlite3_open_v2(), however that behavior might not be carried through -into future versions of SQLite and so applications should not rely -upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op -for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause -the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE -flag is intended for use by the VFS interface only, and not -by sqlite3_open_v2().

    +then the behavior is undefined.

    The fourth parameter to sqlite3_open_v2() is the name of the sqlite3_vfs object that defines the operating system interface that @@ -416,7 +367,6 @@

    See also: sqlite3_temp_directory

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/overload_function.html sqlite3-3.44.0-0/www/c3ref/overload_function.html --- sqlite3-3.42.0/www/c3ref/overload_function.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/overload_function.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Overload A Function For A Virtual Table

    @@ -137,7 +113,6 @@
     purpose is to be a placeholder function that can be overloaded
     by a virtual table.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/pcache.html sqlite3-3.44.0-0/www/c3ref/pcache.html --- sqlite3-3.42.0/www/c3ref/pcache.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/pcache.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Custom Page Cache Object

    @@ -132,7 +108,6 @@
     
     

    See sqlite3_pcache_methods2 for additional information.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/pcache_methods2.html sqlite3-3.44.0-0/www/c3ref/pcache_methods2.html --- sqlite3-3.42.0/www/c3ref/pcache_methods2.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/pcache_methods2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Application Defined Page Cache.

    @@ -305,7 +281,6 @@
     is not obligated to free any memory, but well-behaved implementations should
     do their best.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/pcache_page.html sqlite3-3.44.0-0/www/c3ref/pcache_page.html --- sqlite3-3.42.0/www/c3ref/pcache_page.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/pcache_page.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Custom Page Cache Object

    @@ -135,7 +111,6 @@
     
     

    See sqlite3_pcache_methods2 for additional information.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/prepare.html sqlite3-3.44.0-0/www/c3ref/prepare.html --- sqlite3-3.42.0/www/c3ref/prepare.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/prepare.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Compiling An SQL Statement

    @@ -261,7 +237,6 @@
     sqlite3_prepare_v2() interface works exactly the same as
     sqlite3_prepare_v3() with a zero prepFlags parameter.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/preupdate_blobwrite.html sqlite3-3.44.0-0/www/c3ref/preupdate_blobwrite.html --- sqlite3-3.42.0/www/c3ref/preupdate_blobwrite.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/preupdate_blobwrite.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    The pre-update hook.

    @@ -184,10 +160,6 @@
     function is not defined for operations on WITHOUT ROWID tables, or for
     DELETE operations on rowid tables.

    -

    The sqlite3_preupdate_hook(D,C,P) function returns the P argument from -the previous call on the same database connection D, or NULL for -the first call on D.

    -

    The sqlite3_preupdate_old(), sqlite3_preupdate_new(), sqlite3_preupdate_count(), and sqlite3_preupdate_depth() interfaces provide additional information about a preupdate event. These routines @@ -235,7 +207,6 @@

    See also: sqlite3_update_hook()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/profile.html sqlite3-3.44.0-0/www/c3ref/profile.html --- sqlite3-3.42.0/www/c3ref/profile.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/profile.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Tracing And Profiling Functions

    @@ -155,7 +131,6 @@
     either sqlite3_trace() or sqlite3_trace_v2() will cancel the
     profile callback.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/progress_handler.html sqlite3-3.44.0-0/www/c3ref/progress_handler.html --- sqlite3-3.42.0/www/c3ref/progress_handler.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/progress_handler.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Query Progress Callbacks

    @@ -126,7 +102,7 @@
     

    The sqlite3_progress_handler(D,N,X,P) interface causes the callback function X to be invoked periodically during long running calls to -sqlite3_step() and sqlite3_prepare() and similar for +sqlite3_exec(), sqlite3_step() and sqlite3_get_table() for database connection D. An example use for this interface is to keep a GUI updated during a large query.

    @@ -151,15 +127,7 @@ Note that sqlite3_prepare_v2() and sqlite3_step() both modify their database connections for the meaning of "modify" in this paragraph.

    -

    The progress handler callback would originally only be invoked from the -bytecode engine. It still might be invoked during sqlite3_prepare() -and similar because those routines might force a reparse of the schema -which involves running the bytecode engine. However, beginning with -SQLite version 3.41.0, the progress handler callback might also be -invoked directly from sqlite3_prepare() while analyzing and generating -code for complex queries. -

    See also lists of - Objects, - Constants, and - Functions.

    - +

    See also lists of + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/randomness.html sqlite3-3.44.0-0/www/c3ref/randomness.html --- sqlite3-3.42.0/www/c3ref/randomness.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/randomness.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Pseudo-Random Number Generator

    @@ -142,7 +118,6 @@
     internally and without recourse to the sqlite3_vfs xRandomness
     method.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/release_memory.html sqlite3-3.44.0-0/www/c3ref/release_memory.html --- sqlite3-3.42.0/www/c3ref/release_memory.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/release_memory.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Attempt To Free Heap Memory

    @@ -135,7 +111,6 @@
     
     

    See also: sqlite3_db_release_memory()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/reset_auto_extension.html sqlite3-3.44.0-0/www/c3ref/reset_auto_extension.html --- sqlite3-3.42.0/www/c3ref/reset_auto_extension.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/reset_auto_extension.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Reset Automatic Extension Loading

    @@ -127,7 +103,6 @@
     This interface disables all automatic extensions previously
     registered using sqlite3_auto_extension().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/reset.html sqlite3-3.44.0-0/www/c3ref/reset.html --- sqlite3-3.42.0/www/c3ref/reset.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/reset.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Reset A Prepared Statement Object

    @@ -145,7 +121,6 @@
     

    The sqlite3_reset(S) interface does not change the values of any bindings on the prepared statement S.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/result_blob.html sqlite3-3.44.0-0/www/c3ref/result_blob.html --- sqlite3-3.42.0/www/c3ref/result_blob.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/result_blob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Setting The Result Of An SQL Function

    @@ -217,10 +193,9 @@
     of SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16BE, or SQLITE_UTF16LE.
     SQLite takes the text result from the application from
     the 2nd parameter of the sqlite3_result_text* interfaces.
    -If the 3rd parameter to any of the sqlite3_result_text* interfaces
    -other than sqlite3_result_text64() is negative, then SQLite computes
    -the string length itself by searching the 2nd parameter for the first
    -zero character.
    +If the 3rd parameter to the sqlite3_result_text* interfaces
    +is negative, then SQLite takes result text from the 2nd parameter
    +through the first zero character.
     If the 3rd parameter to the sqlite3_result_text* interfaces
     is non-negative, then as many bytes (not characters) of the text
     pointed to by the 2nd parameter are taken as the application-defined
    @@ -288,7 +263,6 @@
     than the one containing the application-defined function that received
     the sqlite3_context pointer, the results are undefined.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/result_subtype.html sqlite3-3.44.0-0/www/c3ref/result_subtype.html --- sqlite3-3.42.0/www/c3ref/result_subtype.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/result_subtype.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Setting The Subtype Of An SQL Function

    @@ -132,7 +108,6 @@
     The number of subtype bytes preserved by SQLite might increase
     in future releases of SQLite.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/serialize.html sqlite3-3.44.0-0/www/c3ref/serialize.html --- sqlite3-3.42.0/www/c3ref/serialize.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/serialize.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Serialize a database

    @@ -162,7 +138,6 @@
     

    This interface is omitted if SQLite is compiled with the SQLITE_OMIT_DESERIALIZE option.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/set_authorizer.html sqlite3-3.44.0-0/www/c3ref/set_authorizer.html --- sqlite3-3.42.0/www/c3ref/set_authorizer.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/set_authorizer.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Compile-Time Authorization Callbacks

    @@ -212,7 +188,6 @@
     as stated in the previous paragraph, sqlite3_step() invokes
     sqlite3_prepare_v2() to reprepare a statement after a schema change.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/set_last_insert_rowid.html sqlite3-3.44.0-0/www/c3ref/set_last_insert_rowid.html --- sqlite3-3.42.0/www/c3ref/set_last_insert_rowid.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/set_last_insert_rowid.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Set the Last Insert Rowid value.

    @@ -128,7 +104,6 @@
     set the value returned by calling sqlite3_last_insert_rowid(D) to R
     without inserting a row into the database.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/sleep.html sqlite3-3.44.0-0/www/c3ref/sleep.html --- sqlite3-3.42.0/www/c3ref/sleep.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/sleep.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Suspend Execution For A Short Time

    @@ -136,16 +112,8 @@
     method of the default sqlite3_vfs object.  If the xSleep() method
     of the default VFS is not implemented correctly, or not implemented at
     all, then the behavior of sqlite3_sleep() may deviate from the description
    -in the previous paragraphs.

    - -

    If a negative argument is passed to sqlite3_sleep() the results vary by -VFS and operating system. Some system treat a negative argument as an -instruction to sleep forever. Others understand it to mean do not sleep -at all. In SQLite version 3.42.0 and later, a negative -argument passed into sqlite3_sleep() is changed to zero before it is relayed -down into the xSleep method of the VFS. +in the previous paragraphs.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/snapshot_cmp.html sqlite3-3.44.0-0/www/c3ref/snapshot_cmp.html --- sqlite3-3.42.0/www/c3ref/snapshot_cmp.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/snapshot_cmp.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Compare the ages of two snapshot handles.

    @@ -148,7 +124,6 @@
     

    This interface is only available if SQLite is compiled with the SQLITE_ENABLE_SNAPSHOT option.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/snapshot_free.html sqlite3-3.44.0-0/www/c3ref/snapshot_free.html --- sqlite3-3.42.0/www/c3ref/snapshot_free.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/snapshot_free.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Destroy a snapshot

    @@ -131,7 +107,6 @@
     

    The sqlite3_snapshot_free() interface is only available when the SQLITE_ENABLE_SNAPSHOT compile-time option is used.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/snapshot_get.html sqlite3-3.44.0-0/www/c3ref/snapshot_get.html --- sqlite3-3.42.0/www/c3ref/snapshot_get.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/snapshot_get.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Record A Database Snapshot

    @@ -167,7 +143,6 @@
     

    The sqlite3_snapshot_get() interface is only available when the SQLITE_ENABLE_SNAPSHOT compile-time option is used.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/snapshot.html sqlite3-3.44.0-0/www/c3ref/snapshot.html --- sqlite3-3.42.0/www/c3ref/snapshot.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/snapshot.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -141,14 +117,13 @@
     version of the database file so that it is possible to later open a new read
     transaction that sees that historical version of the database rather than
     the most recent version.
    -

    1 Constructor using this object: sqlite3_snapshot_get()

    -

    1 Destructor using this object: sqlite3_snapshot_free()

    -

    3 Methods using this object: +

    1 Constructor: sqlite3_snapshot_get()

    +

    1 Destructor: sqlite3_snapshot_free()

    +

    3 Methods: sqlite3_snapshot_cmp(), sqlite3_snapshot_open(), sqlite3_snapshot_recover()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/snapshot_open.html sqlite3-3.44.0-0/www/c3ref/snapshot_open.html --- sqlite3-3.42.0/www/c3ref/snapshot_open.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/snapshot_open.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Start a read transaction on an historical snapshot

    @@ -167,7 +143,6 @@
     

    The sqlite3_snapshot_open() interface is only available when the SQLITE_ENABLE_SNAPSHOT compile-time option is used.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/snapshot_recover.html sqlite3-3.44.0-0/www/c3ref/snapshot_recover.html --- sqlite3-3.42.0/www/c3ref/snapshot_recover.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/snapshot_recover.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Recover snapshots from a wal file

    @@ -143,7 +119,6 @@
     

    This interface is only available if SQLite is compiled with the SQLITE_ENABLE_SNAPSHOT option.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/soft_heap_limit.html sqlite3-3.44.0-0/www/c3ref/soft_heap_limit.html --- sqlite3-3.42.0/www/c3ref/soft_heap_limit.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/soft_heap_limit.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Deprecated Soft Heap Limit Interface

    @@ -129,7 +105,6 @@
     only.  All new applications should use the
     sqlite3_soft_heap_limit64() interface rather than this one.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/sqlite3.html sqlite3-3.44.0-0/www/c3ref/sqlite3.html --- sqlite3-3.42.0/www/c3ref/sqlite3.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/sqlite3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Database Connection Handle

    @@ -133,22 +109,20 @@
     sqlite3_prepare_v2(), sqlite3_create_function(), and
     sqlite3_busy_timeout() to name but three) that are methods on an
     sqlite3 object.
    -

    3 Constructors using this object: +

    3 Constructors: sqlite3_open(), sqlite3_open16(), sqlite3_open_v2()

    -

    2 Destructors using this object: +

    2 Destructors: sqlite3_close(), sqlite3_close_v2()

    -

    77 Methods using this object: +

    71 Methods:

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/status.html sqlite3-3.44.0-0/www/c3ref/status.html --- sqlite3-3.42.0/www/c3ref/status.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/status.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    SQLite Runtime Status

    @@ -153,7 +129,6 @@
     
     

    See also: sqlite3_db_status()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/step.html sqlite3-3.44.0-0/www/c3ref/step.html --- sqlite3-3.42.0/www/c3ref/step.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/step.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Evaluate An SQL Statement

    @@ -202,7 +178,6 @@
     then the more specific error codes are returned directly
     by sqlite3_step().  The use of the "vX" interfaces is recommended.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stmt_busy.html sqlite3-3.44.0-0/www/c3ref/stmt_busy.html --- sqlite3-3.42.0/www/c3ref/stmt_busy.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stmt_busy.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine If A Prepared Statement Has Been Reset

    @@ -139,7 +115,6 @@
     for example, in diagnostic routines to search for prepared
     statements that are holding a transaction open.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stmt.html sqlite3-3.44.0-0/www/c3ref/stmt.html --- sqlite3-3.42.0/www/c3ref/stmt.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stmt.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Prepared Statement Object

    @@ -143,7 +119,7 @@
     to step 2.  Do this zero or more times.
     
  • Destroy the object using sqlite3_finalize(). -

    6 Constructors using this object: +

    6 Constructors:

    -

    1 Destructor using this object: sqlite3_finalize()

    -

    52 Methods using this object: +

    1 Destructor: sqlite3_finalize()

    +

    51 Methods:

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stmt_isexplain.html sqlite3-3.44.0-0/www/c3ref/stmt_isexplain.html --- sqlite3-3.42.0/www/c3ref/stmt_isexplain.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stmt_isexplain.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Query The EXPLAIN Setting For A Prepared Statement

    @@ -130,7 +106,6 @@
     The sqlite3_stmt_isexplain(S) interface returns 0 if S is
     an ordinary statement or a NULL pointer.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stmt_readonly.html sqlite3-3.44.0-0/www/c3ref/stmt_readonly.html --- sqlite3-3.42.0/www/c3ref/stmt_readonly.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stmt_readonly.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine If An SQL Statement Writes The Database

    @@ -161,13 +137,8 @@
     makes it a no-op, but the sqlite3_stmt_readonly() result would still
     be false.  Similarly, a CREATE TABLE IF NOT EXISTS statement is a
     read-only no-op if the table already exists, but
    -sqlite3_stmt_readonly() still returns false for such a statement.

    - -

    If prepared statement X is an EXPLAIN or EXPLAIN QUERY PLAN -statement, then sqlite3_stmt_readonly(X) returns the same value as -if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. +sqlite3_stmt_readonly() still returns false for such a statement.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stmt_scanstatus.html sqlite3-3.44.0-0/www/c3ref/stmt_scanstatus.html --- sqlite3-3.42.0/www/c3ref/stmt_scanstatus.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stmt_scanstatus.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Prepared Statement Scan Status

    @@ -127,16 +103,9 @@
       int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
       void *pOut                /* Result written here */
     );
    -int sqlite3_stmt_scanstatus_v2(
    -  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
    -  int idx,                  /* Index of loop to report on */
    -  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
    -  int flags,                /* Mask of flags defined below */
    -  void *pOut                /* Result written here */
    -);
     

    -These interfaces return information about the predicted and measured +This interface returns information about the predicted and measured performance for pStmt. Advanced applications can use this interface to compare the predicted and the measured performance and issue warnings and/or rerun ANALYZE if discrepancies are found.

    @@ -147,29 +116,22 @@

    The "iScanStatusOp" parameter determines which status information to return. The "iScanStatusOp" must be one of the scanstatus options or the behavior -of this interface is undefined. The requested measurement is written into -a variable pointed to by the "pOut" parameter.

    - -

    The "flags" parameter must be passed a mask of flags. At present only -one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX -is specified, then status information is available for all elements -of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If -SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements -that correspond to query loops (the "SCAN..." and "SEARCH..." elements of -the EXPLAIN QUERY PLAN output) are available. Invoking API -sqlite3_stmt_scanstatus() is equivalent to calling -sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.

    - -

    Parameter "idx" identifies the specific query element to retrieve statistics -for. Query elements are numbered starting from zero. A value of -1 may be -to query for statistics regarding the entire query. If idx is out of range -- less than -1 or greater than or equal to the total number of query -elements used to implement the statement - a non-zero value is returned and -the variable that pOut points to is unchanged.

    +of this interface is undefined. +The requested measurement is written into a variable pointed to by +the "pOut" parameter. +Parameter "idx" identifies the specific loop to retrieve statistics for. +Loops are numbered starting from zero. If idx is out of range - less than +zero or greater than or equal to the total number of loops used to implement +the statement - a non-zero value is returned and the variable that pOut +points to is unchanged.

    + +

    Statistics might not be available for all loops in all statements. In cases +where there exist loops with no available statistics, this function behaves +as if the loop did not exist - it returns non-zero and leave the variable +that pOut points to unchanged.

    See also: sqlite3_stmt_scanstatus_reset()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stmt_scanstatus_reset.html sqlite3-3.44.0-0/www/c3ref/stmt_scanstatus_reset.html --- sqlite3-3.42.0/www/c3ref/stmt_scanstatus_reset.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stmt_scanstatus_reset.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Zero Scan-Status Counters

    @@ -129,7 +105,6 @@
     

    This API is only available if the library is built with pre-processor symbol SQLITE_ENABLE_STMT_SCANSTATUS defined.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stmt_status.html sqlite3-3.44.0-0/www/c3ref/stmt_status.html --- sqlite3-3.42.0/www/c3ref/stmt_status.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stmt_status.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Prepared Statement Status

    @@ -144,7 +120,6 @@
     
     

    See also: sqlite3_status() and sqlite3_db_status().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/str_append.html sqlite3-3.44.0-0/www/c3ref/str_append.html --- sqlite3-3.42.0/www/c3ref/str_append.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/str_append.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Add Content To A Dynamic String

    @@ -157,7 +133,6 @@
     is recorded in the sqlite3_str object and can be recovered by a
     subsequent call to sqlite3_str_errcode(X).
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/str_errcode.html sqlite3-3.44.0-0/www/c3ref/str_errcode.html --- sqlite3-3.42.0/www/c3ref/str_errcode.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/str_errcode.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Status Of A Dynamic String

    @@ -151,7 +127,6 @@
     outside the range of 0 to sqlite3_str_length(X) and do not read or
     write any byte after any subsequent sqlite3_str method call.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/str_finish.html sqlite3-3.44.0-0/www/c3ref/str_finish.html --- sqlite3-3.42.0/www/c3ref/str_finish.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/str_finish.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Finalize A Dynamic String

    @@ -133,7 +109,6 @@
     sqlite3_str_finish(X) interface will also return a NULL pointer if the
     string in sqlite3_str object X is zero bytes long.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/strglob.html sqlite3-3.44.0-0/www/c3ref/strglob.html --- sqlite3-3.42.0/www/c3ref/strglob.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/strglob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -135,7 +111,6 @@
     
     

    See also: sqlite3_strlike().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/str.html sqlite3-3.44.0-0/www/c3ref/str.html --- sqlite3-3.42.0/www/c3ref/str.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/str.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Dynamic String Object

    @@ -135,9 +111,9 @@
     
  • The sqlite3_str object is destroyed and the string it created is returned using the sqlite3_str_finish() interface. -

    1 Constructor using this object: sqlite3_str_new()

    -

    1 Destructor using this object: sqlite3_str_finish()

    -

    9 Methods using this object: +

    1 Constructor: sqlite3_str_new()

    +

    1 Destructor: sqlite3_str_finish()

    +

    9 Methods:

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/stricmp.html sqlite3-3.44.0-0/www/c3ref/stricmp.html --- sqlite3-3.42.0/www/c3ref/stricmp.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/stricmp.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -130,7 +106,6 @@
     strings in a case-independent fashion, using the same definition of "case
     independence" that SQLite uses internally when comparing identifiers.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/strlike.html sqlite3-3.44.0-0/www/c3ref/strlike.html --- sqlite3-3.42.0/www/c3ref/strlike.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/strlike.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    String LIKE Matching

    @@ -141,7 +117,6 @@
     
     

    See also: sqlite3_strglob().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/str_new.html sqlite3-3.44.0-0/www/c3ref/str_new.html --- sqlite3-3.42.0/www/c3ref/str_new.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/str_new.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Create A New Dynamic String Object

    @@ -145,7 +121,6 @@
     the value set for sqlite3_limit(D,SQLITE_LIMIT_LENGTH) instead
     of SQLITE_MAX_LENGTH.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/system_errno.html sqlite3-3.44.0-0/www/c3ref/system_errno.html --- sqlite3-3.42.0/www/c3ref/system_errno.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/system_errno.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Low-level system error code

    @@ -131,7 +107,6 @@
     called to get back the underlying "errno" that caused the problem, such
     as ENOSPC, EAUTH, EISDIR, and so forth.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/table_column_metadata.html sqlite3-3.44.0-0/www/c3ref/table_column_metadata.html --- sqlite3-3.42.0/www/c3ref/table_column_metadata.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/table_column_metadata.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Extract Metadata About A Column Of A Table

    @@ -199,7 +175,6 @@
     parsed, if that has not already been done, and returns an error if
     any errors are encountered while loading the schema.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/temp_directory.html sqlite3-3.44.0-0/www/c3ref/temp_directory.html --- sqlite3-3.42.0/www/c3ref/temp_directory.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/temp_directory.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Name Of The Folder Holding Temporary Files

    @@ -177,7 +153,6 @@
     sqlite3_temp_directory = sqlite3_mprintf("%s", zPathBuf);
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/test_control.html sqlite3-3.44.0-0/www/c3ref/test_control.html --- sqlite3-3.42.0/www/c3ref/test_control.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/test_control.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -138,7 +114,6 @@
     Unlike most of the SQLite API, this function is not guaranteed to
     operate consistently from one release to the next.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/threadsafe.html sqlite3-3.44.0-0/www/c3ref/threadsafe.html --- sqlite3-3.42.0/www/c3ref/threadsafe.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/threadsafe.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Test To See If The Library Is Threadsafe

    @@ -157,7 +133,6 @@
     
     

    See the threading mode documentation for additional information.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/total_changes.html sqlite3-3.44.0-0/www/c3ref/total_changes.html --- sqlite3-3.42.0/www/c3ref/total_changes.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/total_changes.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,51 +89,22 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); - + +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Total Number Of Rows Modified

     int sqlite3_total_changes(sqlite3*);
    -sqlite3_int64 sqlite3_total_changes64(sqlite3*);
     

    -These functions return the total number of rows inserted, modified or +This function returns the total number of rows inserted, modified or deleted by all INSERT, UPDATE or DELETE statements completed since the database connection was opened, including those executed as -part of trigger programs. The two functions are identical except for the -type of the return value and that if the number of rows modified by the -connection exceeds the maximum value supported by type "int", then -the return value of sqlite3_total_changes() is undefined. Executing -any other type of SQL statement does not affect the value returned by -sqlite3_total_changes().

    +part of trigger programs. Executing any other type of SQL statement +does not affect the value returned by sqlite3_total_changes().

    Changes made as part of foreign key actions are included in the count, but those made as part of REPLACE constraint resolution are @@ -160,7 +131,6 @@

  • the SQLITE_FCNTL_DATA_VERSION file control

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/trace_v2.html sqlite3-3.44.0-0/www/c3ref/trace_v2.html --- sqlite3-3.42.0/www/c3ref/trace_v2.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/trace_v2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -154,7 +130,6 @@
     interfaces sqlite3_trace() and sqlite3_profile(), both of which
     are deprecated.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/txn_state.html sqlite3-3.44.0-0/www/c3ref/txn_state.html --- sqlite3-3.42.0/www/c3ref/txn_state.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/txn_state.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine the transaction state of a database

    @@ -136,7 +112,6 @@
     If the S argument to sqlite3_txn_state(D,S) is not the name of
     a valid schema, then -1 is returned.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/unlock_notify.html sqlite3-3.44.0-0/www/c3ref/unlock_notify.html --- sqlite3-3.42.0/www/c3ref/unlock_notify.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/unlock_notify.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Unlock Notification

    @@ -239,7 +215,6 @@
     the special "DROP TABLE/INDEX" case, the extended error code is just
     SQLITE_LOCKED.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/update_hook.html sqlite3-3.44.0-0/www/c3ref/update_hook.html --- sqlite3-3.42.0/www/c3ref/update_hook.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/update_hook.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Data Change Notification Callbacks

    @@ -173,7 +149,6 @@
     

    See also the sqlite3_commit_hook(), sqlite3_rollback_hook(), and sqlite3_preupdate_hook() interfaces.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/uri_boolean.html sqlite3-3.44.0-0/www/c3ref/uri_boolean.html --- sqlite3-3.42.0/www/c3ref/uri_boolean.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/uri_boolean.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,42 +89,18 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Obtain Values For URI Parameters

    -const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam);
    -int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault);
    -sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64);
    -const char *sqlite3_uri_key(sqlite3_filename z, int N);
    +const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
    +int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
    +sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
    +const char *sqlite3_uri_key(const char *zFilename, int N);
     

    These are utility routines, useful to custom VFS implementations, @@ -190,7 +166,6 @@

    See the URI filename documentation for additional information.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/user_data.html sqlite3-3.44.0-0/www/c3ref/user_data.html --- sqlite3-3.42.0/www/c3ref/user_data.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/user_data.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    User Data For Functions

    @@ -133,7 +109,6 @@
     

    This routine must be called from the same thread in which the application-defined function is running.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/value_blob.html sqlite3-3.44.0-0/www/c3ref/value_blob.html --- sqlite3-3.42.0/www/c3ref/value_blob.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/value_blob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Obtaining SQL Values

    @@ -262,7 +238,6 @@
     return value is obtained and before any
     other SQLite interface is called on the same database connection.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/value_dup.html sqlite3-3.44.0-0/www/c3ref/value_dup.html --- sqlite3-3.42.0/www/c3ref/value_dup.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/value_dup.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Copy And Free SQL Values

    @@ -129,14 +105,12 @@
     object D and returns a pointer to that copy.  The sqlite3_value returned
     is a protected sqlite3_value object even if the input is not.
     The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a
    -memory allocation fails. If V is a pointer value, then the result
    -of sqlite3_value_dup(V) is a NULL value.

    +memory allocation fails.

    The sqlite3_value_free(V) interface frees an sqlite3_value object previously obtained from sqlite3_value_dup(). If V is a NULL pointer then sqlite3_value_free(V) is a harmless no-op.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/value_encoding.html sqlite3-3.44.0-0/www/c3ref/value_encoding.html --- sqlite3-3.42.0/www/c3ref/value_encoding.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/value_encoding.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,146 +0,0 @@ - - - - - -Report the internal text encoding state of an sqlite3_value object - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Report the internal text encoding state of an sqlite3_value object

    -
    -
    -int sqlite3_value_encoding(sqlite3_value*);
    -
    -

    -The sqlite3_value_encoding(X) interface returns one of SQLITE_UTF8, -SQLITE_UTF16BE, or SQLITE_UTF16LE according to the current text encoding -of the value X, assuming that X has type TEXT. If sqlite3_value_type(X) -returns something other than SQLITE_TEXT, then the return value from -sqlite3_value_encoding(X) is meaningless. Calls to -sqlite3_value_text(X), sqlite3_value_text16(X), sqlite3_value_text16be(X), -sqlite3_value_text16le(X), sqlite3_value_bytes(X), or -sqlite3_value_bytes16(X) might change the encoding of the value X and -thus change the return from subsequent calls to sqlite3_value_encoding(X).

    - -

    This routine is intended for used by applications that test and validate -the SQLite implementation. This routine is inquiring about the opaque -internal state of an sqlite3_value object. Ordinary applications should -not need to know what the internal state of an sqlite3_value object is and -hence should not need to use this interface. -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/value.html sqlite3-3.44.0-0/www/c3ref/value.html --- sqlite3-3.42.0/www/c3ref/value.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/value.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Dynamically Typed Value Object

    @@ -152,8 +128,6 @@
     
     

    The sqlite3_value objects that are passed as parameters into the implementation of application-defined SQL functions are protected. -The sqlite3_value objects returned by sqlite3_vtab_rhs_value() -are protected. The sqlite3_value object returned by sqlite3_column_value() is unprotected. Unprotected sqlite3_value objects may only be used as arguments @@ -161,7 +135,7 @@ sqlite3_value_dup(). The sqlite3_value_type() family of interfaces require protected sqlite3_value objects. -

    19 Methods using this object: +

    18 Methods:

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/value_subtype.html sqlite3-3.44.0-0/www/c3ref/value_subtype.html --- sqlite3-3.42.0/www/c3ref/value_subtype.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/value_subtype.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Finding The Subtype Of SQL Values

    @@ -130,7 +106,6 @@
     one SQL function to another.  Use the sqlite3_result_subtype()
     routine to set the subtype for the return value of an SQL function.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vfs_find.html sqlite3-3.44.0-0/www/c3ref/vfs_find.html --- sqlite3-3.42.0/www/c3ref/vfs_find.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vfs_find.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual File System Objects

    @@ -152,7 +128,6 @@
     If the default VFS is unregistered, another VFS is chosen as
     the default.  The choice for the new VFS is arbitrary.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vfs.html sqlite3-3.44.0-0/www/c3ref/vfs.html --- sqlite3-3.42.0/www/c3ref/vfs.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vfs.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    OS Interface Object

    @@ -130,7 +106,7 @@
       sqlite3_vfs *pNext;      /* Next registered VFS */
       const char *zName;       /* Name of this virtual file system */
       void *pAppData;          /* Pointer to application-specific data */
    -  int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*,
    +  int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*,
                    int flags, int *pOutFlags);
       int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir);
       int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
    @@ -331,7 +307,6 @@
     from one release to the next.  Applications must not attempt to access
     any of these methods if the iVersion of the VFS is less than 3.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vtab_collation.html sqlite3-3.44.0-0/www/c3ref/vtab_collation.html --- sqlite3-3.42.0/www/c3ref/vtab_collation.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_collation.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine The Collation For a Virtual Table Constraint

    @@ -125,35 +101,15 @@
     

    This function may only be called from within a call to the xBestIndex -method of a virtual table. This function returns a pointer to a string -that is the name of the appropriate collation sequence to use for text -comparisons on the constraint identified by its arguments.

    +method of a virtual table.

    -

    The first argument must be the pointer to the sqlite3_index_info object -that is the first parameter to the xBestIndex() method. The second argument -must be an index into the aConstraint[] array belonging to the -sqlite3_index_info structure passed to xBestIndex.

    - -

    Important: -The first parameter must be the same pointer that is passed into the -xBestMethod() method. The first parameter may not be a pointer to a -different sqlite3_index_info object, even an exact copy.

    - -

    The return value is computed as follows:

    - -

      -
    1. If the constraint comes from a WHERE clause expression that contains -a COLLATE operator, then the name of the collation specified by -that COLLATE operator is returned. -

    2. If there is no COLLATE operator, but the column that is the subject -of the constraint specifies an alternative collating sequence via -a COLLATE clause on the column definition within the CREATE TABLE -statement that was passed into sqlite3_declare_vtab(), then the -name of that alternative collating sequence is returned. -

    3. Otherwise, "BINARY" is returned. -

    +

    The first argument must be the sqlite3_index_info object that is the +first parameter to the xBestIndex() method. The second argument must be +an index into the aConstraint[] array belonging to the sqlite3_index_info +structure passed to xBestIndex. This function returns a pointer to a buffer +containing the name of the collation sequence for the corresponding +constraint.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vtab_config.html sqlite3-3.44.0-0/www/c3ref/vtab_config.html --- sqlite3-3.42.0/www/c3ref/vtab_config.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_config.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Interface Configuration

    @@ -139,7 +115,6 @@
     of parameters after C depend on which virtual table configuration option
     is used.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vtab_cursor.html sqlite3-3.44.0-0/www/c3ref/vtab_cursor.html --- sqlite3-3.42.0/www/c3ref/vtab_cursor.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_cursor.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Cursor Object

    @@ -140,7 +116,6 @@
     

    This superclass exists in order to define fields of the cursor that are common to all implementations.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vtab_distinct.html sqlite3-3.44.0-0/www/c3ref/vtab_distinct.html --- sqlite3-3.42.0/www/c3ref/vtab_distinct.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_distinct.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,197 +0,0 @@ - - - - - -Determine if a virtual table query is DISTINCT - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Determine if a virtual table query is DISTINCT

    -
    -
    -int sqlite3_vtab_distinct(sqlite3_index_info*);
    -
    -

    -This API may only be used from within an xBestIndex method -of a virtual table implementation. The result of calling this -interface from outside of xBestIndex() is undefined and probably harmful.

    - -

    The sqlite3_vtab_distinct() interface returns an integer between 0 and -3. The integer returned by sqlite3_vtab_distinct() -gives the virtual table additional information about how the query -planner wants the output to be ordered. As long as the virtual table -can meet the ordering requirements of the query planner, it may set -the "orderByConsumed" flag.

    - -

    1. -If the sqlite3_vtab_distinct() interface returns 0, that means -that the query planner needs the virtual table to return all rows in the -sort order defined by the "nOrderBy" and "aOrderBy" fields of the -sqlite3_index_info object. This is the default expectation. If the -virtual table outputs all rows in sorted order, then it is always safe for -the xBestIndex method to set the "orderByConsumed" flag, regardless of -the return value from sqlite3_vtab_distinct(). -

    2. -If the sqlite3_vtab_distinct() interface returns 1, that means -that the query planner does not need the rows to be returned in sorted order -as long as all rows with the same values in all columns identified by the -"aOrderBy" field are adjacent. This mode is used when the query planner -is doing a GROUP BY. -

    3. -If the sqlite3_vtab_distinct() interface returns 2, that means -that the query planner does not need the rows returned in any particular -order, as long as rows with the same values in all "aOrderBy" columns -are adjacent. Furthermore, only a single row for each particular -combination of values in the columns identified by the "aOrderBy" field -needs to be returned. It is always ok for two or more rows with the same -values in all "aOrderBy" columns to be returned, as long as all such rows -are adjacent. The virtual table may, if it chooses, omit extra rows -that have the same value for all columns identified by "aOrderBy". -However omitting the extra rows is optional. -This mode is used for a DISTINCT query. -

    4. -If the sqlite3_vtab_distinct() interface returns 3, that means -that the query planner needs only distinct rows but it does need the -rows to be sorted. The virtual table implementation is free to omit -rows that are identical in all aOrderBy columns, if it wants to, but -it is not required to omit any rows. This mode is used for queries -that have both DISTINCT and ORDER BY clauses. -

    - -

    For the purposes of comparing virtual table output values to see if the -values are same value for sorting purposes, two NULL values are considered -to be the same. In other words, the comparison operator is "IS" -(or "IS NOT DISTINCT FROM") and not "==".

    - -

    If a virtual table implementation is unable to meet the requirements -specified above, then it must not set the "orderByConsumed" flag in the -sqlite3_index_info object or an incorrect answer may result.

    - -

    A virtual table implementation is always free to return rows in any order -it wants, as long as the "orderByConsumed" flag is not set. When the -the "orderByConsumed" flag is unset, the query planner will add extra -bytecode to ensure that the final results returned by the SQL query are -ordered correctly. The use of the "orderByConsumed" flag and the -sqlite3_vtab_distinct() interface is merely an optimization. Careful -use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" -flag might help queries against a virtual table to run faster. Being -overly aggressive and setting the "orderByConsumed" flag when it is not -valid to do so, on the other hand, might cause SQLite to return incorrect -results. -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/vtab.html sqlite3-3.44.0-0/www/c3ref/vtab.html --- sqlite3-3.42.0/www/c3ref/vtab.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Virtual Table Instance Object

    @@ -143,7 +119,6 @@
     is delivered up to the client application, the string will be automatically
     freed by sqlite3_free() and the zErrMsg field will be zeroed.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vtab_in_first.html sqlite3-3.44.0-0/www/c3ref/vtab_in_first.html --- sqlite3-3.42.0/www/c3ref/vtab_in_first.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_in_first.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,173 +0,0 @@ - - - - - -Find all elements on the right-hand side of an IN constraint. - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Find all elements on the right-hand side of an IN constraint.

    -
    -
    -int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
    -int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
    -
    -

    -These interfaces are only useful from within the -xFilter() method of a virtual table implementation. -The result of invoking these interfaces from any other context -is undefined and probably harmful.

    - -

    The X parameter in a call to sqlite3_vtab_in_first(X,P) or -sqlite3_vtab_in_next(X,P) should be one of the parameters to the -xFilter method which invokes these routines, and specifically -a parameter that was previously selected for all-at-once IN constraint -processing use the sqlite3_vtab_in() interface in the -xBestIndex method. If the X parameter is not -an xFilter argument that was selected for all-at-once IN constraint -processing, then these routines return SQLITE_ERROR.

    - -

    Use these routines to access all values on the right-hand side -of the IN constraint using code like the following:

    - -

    -   for(rc=sqlite3_vtab_in_first(pList, &pVal);
    -       rc==SQLITE_OK && pVal;
    -       rc=sqlite3_vtab_in_next(pList, &pVal)
    -   ){
    -     // do something with pVal
    -   }
    -   if( rc!=SQLITE_OK ){
    -     // an error has occurred
    -   }
    -

    - -

    On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) -routines return SQLITE_OK and set *P to point to the first or next value -on the RHS of the IN constraint. If there are no more values on the -right hand side of the IN constraint, then *P is set to NULL and these -routines return SQLITE_DONE. The return value might be -some other value, such as SQLITE_NOMEM, in the event of a malfunction.

    - -

    The *ppOut values returned by these routines are only valid until the -next call to either of these routines or until the end of the xFilter -method from which these routines were called. If the virtual table -implementation needs to retain the *ppOut values for longer, it must make -copies. The *ppOut values are protected. -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/vtab_in.html sqlite3-3.44.0-0/www/c3ref/vtab_in.html --- sqlite3-3.42.0/www/c3ref/vtab_in.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_in.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,198 +0,0 @@ - - - - - -Identify and handle IN constraints in xBestIndex - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Identify and handle IN constraints in xBestIndex

    -
    -
    -int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
    -
    -

    -This interface may only be used from within an -xBestIndex() method of a virtual table implementation. -The result of invoking this interface from any other context is -undefined and probably harmful.

    - -

    A constraint on a virtual table of the form -"column IN (...)" is -communicated to the xBestIndex method as a -SQLITE_INDEX_CONSTRAINT_EQ constraint. If xBestIndex wants to use -this constraint, it must set the corresponding -aConstraintUsage[].argvIndex to a postive integer. Then, under -the usual mode of handling IN operators, SQLite generates bytecode -that invokes the xFilter() method once for each value -on the right-hand side of the IN operator. Thus the virtual table -only sees a single value from the right-hand side of the IN operator -at a time.

    - -

    In some cases, however, it would be advantageous for the virtual -table to see all values on the right-hand of the IN operator all at -once. The sqlite3_vtab_in() interfaces facilitates this in two ways:

    - -

      -
    1. -A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) -if and only if the P->aConstraint[N] constraint -is an IN operator that can be processed all at once. In other words, -sqlite3_vtab_in() with -1 in the third argument is a mechanism -by which the virtual table can ask SQLite if all-at-once processing -of the IN operator is even possible.

      - -

    2. -A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates -to SQLite that the virtual table does or does not want to process -the IN operator all-at-once, respectively. Thus when the third -parameter (F) is non-negative, this interface is the mechanism by -which the virtual table tells SQLite how it wants to process the -IN operator. -

    - -

    The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times -within the same xBestIndex method call. For any given P,N pair, -the return value from sqlite3_vtab_in(P,N,F) will always be the same -within the same xBestIndex call. If the interface returns true -(non-zero), that means that the constraint is an IN operator -that can be processed all-at-once. If the constraint is not an IN -operator or cannot be processed all-at-once, then the interface returns -false.

    - -

    All-at-once processing of the IN operator is selected if both of the -following conditions are met:

    - -

      -
    1. The P->aConstraintUsage[N].argvIndex value is set to a positive -integer. This is how the virtual table tells SQLite that it wants to -use the N-th constraint.

      - -

    2. The last call to sqlite3_vtab_in(P,N,F) for which F was -non-negative had F>=1. -

    - -

    If either or both of the conditions above are false, then SQLite uses -the traditional one-at-a-time processing strategy for the IN constraint. -If both conditions are true, then the argvIndex-th parameter to the -xFilter method will be an sqlite3_value that appears to be NULL, -but which can be passed to sqlite3_vtab_in_first() and -sqlite3_vtab_in_next() to find all values on the right-hand side -of the IN constraint. -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/vtab_nochange.html sqlite3-3.44.0-0/www/c3ref/vtab_nochange.html --- sqlite3-3.42.0/www/c3ref/vtab_nochange.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_nochange.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine If Virtual Table Column Access Is For UPDATE

    @@ -145,7 +121,6 @@
     current implementation, the sqlite3_vtab_nochange() interface does always
     returns false for the enhanced UPDATE FROM statement.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vtab_on_conflict.html sqlite3-3.44.0-0/www/c3ref/vtab_on_conflict.html --- sqlite3-3.42.0/www/c3ref/vtab_on_conflict.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_on_conflict.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Determine The Virtual Table Conflict Policy

    @@ -131,7 +107,6 @@
     of the SQL statement that triggered the call to the xUpdate method of the
     virtual table.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/vtab_rhs_value.html sqlite3-3.44.0-0/www/c3ref/vtab_rhs_value.html --- sqlite3-3.42.0/www/c3ref/vtab_rhs_value.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/vtab_rhs_value.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,166 +0,0 @@ - - - - - -Constraint values in xBestIndex() - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - - -
    -

    SQLite C Interface

    -

    Constraint values in xBestIndex()

    -
    -
    -int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
    -
    -

    -This API may only be used from within the xBestIndex method -of a virtual table implementation. The result of calling this interface -from outside of an xBestIndex method are undefined and probably harmful.

    - -

    When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within -the xBestIndex method of a virtual table implementation, with P being -a copy of the sqlite3_index_info object pointer passed into xBestIndex and -J being a 0-based index into P->aConstraint[], then this routine -attempts to set *V to the value of the right-hand operand of -that constraint if the right-hand operand is known. If the -right-hand operand is not known, then *V is set to a NULL pointer. -The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if -and only if *V is set to a value. The sqlite3_vtab_rhs_value(P,J,V) -inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th -constraint is not available. The sqlite3_vtab_rhs_value() interface -can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if -something goes wrong.

    - -

    The sqlite3_vtab_rhs_value() interface is usually only successful if -the right-hand operand of a constraint is a literal value in the original -SQL statement. If the right-hand operand is an expression or a reference -to some other column or a host parameter, then sqlite3_vtab_rhs_value() -will probably return SQLITE_NOTFOUND.

    - -

    Some constraints, such as SQLITE_INDEX_CONSTRAINT_ISNULL and -SQLITE_INDEX_CONSTRAINT_ISNOTNULL, have no right-hand operand. For such -constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.

    - -

    The sqlite3_value object returned in *V is a protected sqlite3_value -and remains valid for the duration of the xBestIndex method call. -When xBestIndex returns, the sqlite3_value object returned by -sqlite3_vtab_rhs_value() is automatically deallocated.

    - -

    The "_rhs_" in the name of this routine is an abbreviation for -"Right-Hand Side". -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/c3ref/wal_autocheckpoint.html sqlite3-3.44.0-0/www/c3ref/wal_autocheckpoint.html --- sqlite3-3.42.0/www/c3ref/wal_autocheckpoint.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/wal_autocheckpoint.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Configure an auto-checkpoint

    @@ -149,7 +125,6 @@
     is only necessary if the default setting is found to be suboptimal
     for a particular application.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/wal_checkpoint.html sqlite3-3.44.0-0/www/c3ref/wal_checkpoint.html --- sqlite3-3.42.0/www/c3ref/wal_checkpoint.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/wal_checkpoint.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Checkpoint a database

    @@ -140,7 +116,6 @@
     start a callback but which do not need the full power (and corresponding
     complication) of sqlite3_wal_checkpoint_v2().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/wal_checkpoint_v2.html sqlite3-3.44.0-0/www/c3ref/wal_checkpoint_v2.html --- sqlite3-3.42.0/www/c3ref/wal_checkpoint_v2.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/wal_checkpoint_v2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Checkpoint a database

    @@ -218,7 +194,6 @@
     

    The PRAGMA wal_checkpoint command can be used to invoke this interface from SQL.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/wal_hook.html sqlite3-3.44.0-0/www/c3ref/wal_hook.html --- sqlite3-3.42.0/www/c3ref/wal_hook.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/wal_hook.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Write-Ahead Log Commit Hook

    @@ -153,13 +129,11 @@
     
     

    A single database handle may have at most a single write-ahead log callback registered at one time. Calling sqlite3_wal_hook() replaces any -previously registered write-ahead log callback. The return value is -a copy of the third parameter from the previous call, if any, or 0. -Note that the sqlite3_wal_autocheckpoint() interface and the +previously registered write-ahead log callback. Note that the +sqlite3_wal_autocheckpoint() interface and the wal_autocheckpoint pragma both invoke sqlite3_wal_hook() and will overwrite any prior sqlite3_wal_hook() settings.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/c3ref/win32_set_directory.html sqlite3-3.44.0-0/www/c3ref/win32_set_directory.html --- sqlite3-3.42.0/www/c3ref/win32_set_directory.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c3ref/win32_set_directory.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -

    SQLite C Interface

    +

    SQLite C Interface

    Win32 Specific Interface

    @@ -145,7 +121,6 @@
     sqlite3_win32_set_directory interface except the string parameter must be
     UTF-8 or UTF-16, respectively.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/capi3.html sqlite3-3.44.0-0/www/capi3.html --- sqlite3-3.42.0/www/capi3.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/capi3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -628,5 +604,4 @@ is the name of the collating sequence in UTF-8. For sqlite3_collation_need16() the callback sends the collating sequence name in UTF-16 host byte order.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/capi3ref.html sqlite3-3.44.0-0/www/capi3ref.html --- sqlite3-3.42.0/www/capi3ref.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/capi3ref.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -129,8 +105,8 @@
  • SQLite In 3 Minutes Or Less and/or
  • the Introduction To The SQLite C/C++ Interface. -This same content is also available split out into -some smaller pages.

    +This same content is also available split out into +lots of small pages.


    @@ -151,7 +127,7 @@ should always be able to relink against a newer version of SQLite without any changes.

    -

    Experimental interfaces are subject to change. +

    Experimental interfaces are subject to change. Applications that use experimental interfaces may need to be modified when upgrading to a newer SQLite release, though this is rare. @@ -170,7 +146,7 @@

    Key points:

    -xLock() upgrades the database file lock. In other words, xLock() moves the -database file lock in the direction NONE toward EXCLUSIVE. The argument to -xLock() is always on of SHARED, RESERVED, PENDING, or EXCLUSIVE, never -SQLITE_LOCK_NONE. If the database file lock is already at or above the -requested lock, then the call to xLock() is a no-op. -xUnlock() downgrades the database file lock to either SHARED or NONE. -to xUnlock() is a no-op. +xLock() increases the lock. xUnlock() decreases the lock. The xCheckReservedLock() method checks whether any database connection, either in this process or in some other process, is holding a RESERVED, PENDING, or EXCLUSIVE lock on the file. It returns true @@ -1705,7 +1620,7 @@ sqlite3_vfs *pNext; /* Next registered VFS */ const char *zName; /* Name of this virtual file system */ void *pAppData; /* Pointer to application-specific data */ - int (*xOpen)(sqlite3_vfs*, sqlite3_filename zName, sqlite3_file*, + int (*xOpen)(sqlite3_vfs*, const char *zName, sqlite3_file*, int flags, int *pOutFlags); int (*xDelete)(sqlite3_vfs*, const char *zName, int syncDir); int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut); @@ -1955,7 +1870,7 @@

    The sqlite3_aggregate_context(C,N) routine returns a NULL pointer when first called if N is less than or equal to zero or if a memory -allocation error occurs.

    +allocate error occurs.

    The amount of space allocated by sqlite3_aggregate_context(C,N) is determined by the N parameter on first successful call. Changing the @@ -2014,71 +1929,6 @@

    See also: sqlite3_reset_auto_extension() and sqlite3_cancel_auto_extension() -


    -

    Autovacuum Compaction Amount Callback

    - -
    -int sqlite3_autovacuum_pages(
    -  sqlite3 *db,
    -  unsigned int(*)(void*,const char*,unsigned int,unsigned int,unsigned int),
    -  void*,
    -  void(*)(void*)
    -);
    -
    -

    -The sqlite3_autovacuum_pages(D,C,P,X) interface registers a callback -function C that is invoked prior to each autovacuum of the database -file. The callback is passed a copy of the generic data pointer (P), -the schema-name of the attached database that is being autovacuumed, -the size of the database file in pages, the number of free pages, -and the number of bytes per page, respectively. The callback should -return the number of free pages that should be removed by the -autovacuum. If the callback returns zero, then no autovacuum happens. -If the value returned is greater than or equal to the number of -free pages, then a complete autovacuum happens.

    - -

    If there are multiple ATTACH-ed database files that are being -modified as part of a transaction commit, then the autovacuum pages -callback is invoked separately for each file.

    - -

    The callback is not reentrant. The callback function should -not attempt to invoke any other SQLite interface. If it does, bad -things may happen, including segmentation faults and corrupt database -files. The callback function should be a simple function that -does some arithmetic on its input parameters and returns a result.

    - -

    The X parameter to sqlite3_autovacuum_pages(D,C,P,X) is an optional -destructor for the P parameter. If X is not NULL, then X(P) is -invoked whenever the database connection closes or when the callback -is overwritten by another invocation of sqlite3_autovacuum_pages().

    - -

    There is only one autovacuum pages callback per database connection. -Each call to the sqlite3_autovacuum_pages() interface overrides all -previous invocations for that database connection. If the callback -argument (C) to sqlite3_autovacuum_pages(D,C,P,X) is a NULL pointer, -then the autovacuum steps callback is cancelled. The return value -from sqlite3_autovacuum_pages() is normally SQLITE_OK, but might -be some other error code if something goes wrong. The current -implementation will only return SQLITE_OK or SQLITE_MISUSE, but other -return codes might be added in future releases.

    - -

    If no autovacuum pages callback is specified (the usual case) or -a NULL pointer is provided for the callback, -then the default behavior is to vacuum all free pages. So, in other -words, the default behavior is the same as if the callback function -were something like this:

    - -

    -    unsigned int demonstration_autovac_pages_callback(
    -      void *pClientData,
    -      const char *zSchema,
    -      unsigned int nDbPage,
    -      unsigned int nFreePage,
    -      unsigned int nBytePerPage
    -    ){
    -      return nFreePage;
    -    }
    -


    Number Of SQL Parameters

    @@ -2409,6 +2259,64 @@ routine returns 1 if initialization routine X was successfully unregistered and it returns 0 if X was not on the list of initialization routines. +


    +

    Count The Number Of Rows Modified

    + +
    +int sqlite3_changes(sqlite3*);
    +
    +

    +This function returns the number of rows modified, inserted or +deleted by the most recently completed INSERT, UPDATE or DELETE +statement on the database connection specified by the only parameter. +Executing any other type of SQL statement does not modify the value +returned by this function.

    + +

    Only changes made directly by the INSERT, UPDATE or DELETE statement are +considered - auxiliary changes caused by triggers, +foreign key actions or REPLACE constraint resolution are not counted.

    + +

    Changes to a view that are intercepted by +INSTEAD OF triggers are not counted. The value +returned by sqlite3_changes() immediately after an INSERT, UPDATE or +DELETE statement run on a view is always zero. Only changes made to real +tables are counted.

    + +

    Things are more complicated if the sqlite3_changes() function is +executed while a trigger program is running. This may happen if the +program uses the changes() SQL function, or if some other callback +function invokes sqlite3_changes() directly. Essentially:

    + +

      +
    • Before entering a trigger program the value returned by +sqlite3_changes() function is saved. After the trigger program +has finished, the original value is restored.

      + +

    • Within a trigger program each INSERT, UPDATE and DELETE +statement sets the value returned by sqlite3_changes() +upon completion as normal. Of course, this value will not include +any changes performed by sub-triggers, as the sqlite3_changes() +value will be saved and restored after each sub-trigger has run. +

    + +

    This means that if the changes() SQL function (or similar) is used +by the first INSERT, UPDATE or DELETE statement within a trigger, it +returns the value as set when the calling statement began executing. +If it is used by the second or subsequent such statement within a trigger +program, the value returned reflects the number of rows modified by the +previous INSERT, UPDATE or DELETE statement within the same trigger.

    + +

    If a separate thread makes changes on the same database connection +while sqlite3_changes() is running then the value returned +is unpredictable and not meaningful.

    + +

    See also: +


    Reset All Bindings On A Prepared Statement

    @@ -2452,23 +2360,20 @@ must ensure that no other SQLite interfaces are invoked by other threads while sqlite3_config() is running.

    -

    The first argument to sqlite3_config() is an integer -configuration option that determines -what property of SQLite is to be configured. Subsequent arguments -vary depending on the configuration option -in the first argument.

    - -

    For most configuration options, the sqlite3_config() interface +

    The sqlite3_config() interface may only be invoked prior to library initialization using sqlite3_initialize() or after shutdown by sqlite3_shutdown(). -The exceptional configuration options that may be invoked at any time -are called "anytime configuration options". If sqlite3_config() is called after sqlite3_initialize() and before -sqlite3_shutdown() with a first argument that is not an anytime -configuration option, then the sqlite3_config() call will return SQLITE_MISUSE. +sqlite3_shutdown() then it will return SQLITE_MISUSE. Note, however, that sqlite3_config() can be called as part of the implementation of an application-defined sqlite3_os_init().

    +

    The first argument to sqlite3_config() is an integer +configuration option that determines +what property of SQLite is to be configured. Subsequent arguments +vary depending on the configuration option +in the first argument.

    +

    When a configuration option is set, sqlite3_config() returns SQLITE_OK. If the option is unknown or SQLite is unable to set the option then this routine returns a non-zero error code. @@ -2581,7 +2486,7 @@

    Return The Filename For A Database Connection

    -sqlite3_filename sqlite3_db_filename(sqlite3 *db, const char *zDbName);
    +const char *sqlite3_db_filename(sqlite3 *db, const char *zDbName);
     

    The sqlite3_db_filename(D,N) interface returns a pointer to the filename @@ -2634,28 +2539,6 @@ when the threading mode is Serialized. If the threading mode is Single-thread or Multi-thread then this routine returns a NULL pointer. -


    -

    Return The Schema Name For A Database Connection

    - -
    -const char *sqlite3_db_name(sqlite3 *db, int N);
    -
    -

    -The sqlite3_db_name(D,N) interface returns a pointer to the schema name -for the N-th database on database connection D, or a NULL pointer of N is -out of range. An N value of 0 means the main database file. An N of 1 is -the "temp" schema. Larger values of N correspond to various ATTACH-ed -databases.

    - -

    Space to hold the string that is returned by sqlite3_db_name() is managed -by SQLite itself. The string might be deallocated by any operation that -changes the schema, including ATTACH or DETACH or calls to -sqlite3_serialize() or sqlite3_deserialize(), even operations that -occur on a different thread. Applications that need to -remember the string long-term should make their own copy. Applications that -are accessing the same database connection simultaneously on multiple -threads should mutex-protect calls to this API and should make their own -private copy of the result prior to releasing the mutex.


    Determine if a database is read-only

    @@ -2749,10 +2632,6 @@ database is currently in a read transaction or is involved in a backup operation.

    -

    It is not possible to deserialized into the TEMP database. If the -S argument to sqlite3_deserialize(D,S,P,N,M,F) is "temp" then the -function returns SQLITE_ERROR.

    -

    If sqlite3_deserialize(D,S,P,N,M,F) fails for any reason and if the SQLITE_DESERIALIZE_FREEONCLOSE bit is set in argument F, then sqlite3_free() is invoked on argument P prior to returning.

    @@ -2815,11 +2694,6 @@ to the same database. Sharing is enabled if the argument is true and disabled if the argument is false.

    -

    This interface is omitted if SQLite is compiled with --DSQLITE_OMIT_SHARED_CACHE. The -DSQLITE_OMIT_SHARED_CACHE -compile-time option is recommended because the -use of shared cache mode is discouraged.

    -

    Cache sharing is enabled and disabled for an entire process. This is a change as of SQLite version 3.5.0 (2007-09-04). In prior versions of SQLite, @@ -2958,6 +2832,43 @@ a prepared statement after it has been finalized. Any use of a prepared statement after it has been finalized can result in undefined and undesirable behavior such as segfaults and heap corruption. +


    +

    Interrupt A Long-Running Query

    + +
    +void sqlite3_interrupt(sqlite3*);
    +
    +

    +This function causes any pending database operation to abort and +return at its earliest opportunity. This routine is typically +called in response to a user action such as pressing "Cancel" +or Ctrl-C where the user wants a long query operation to halt +immediately.

    + +

    It is safe to call this routine from a thread different from the +thread that is currently running the database operation. But it +is not safe to call this routine with a database connection that +is closed or might close before sqlite3_interrupt() returns.

    + +

    If an SQL operation is very nearly finished at the time when +sqlite3_interrupt() is called, then it might not have an opportunity +to be interrupted and might continue to completion.

    + +

    An SQL operation that is interrupted will return SQLITE_INTERRUPT. +If the interrupted SQL operation is an INSERT, UPDATE, or DELETE +that is inside an explicit transaction, then the entire transaction +will be rolled back automatically.

    + +

    The sqlite3_interrupt(D) call is in effect until all currently running +SQL statements on database connection D complete. Any new SQL statements +that are started after the sqlite3_interrupt() call and before the +running statement count reaches zero are interrupted as if they had been +running prior to the sqlite3_interrupt() call. New SQL statements +that are started after the running statement count reaches zero are +not effected by the sqlite3_interrupt(). +A call to sqlite3_interrupt(D) that occurs when there are no running +SQL statements is a no-op and has no effect on SQL statements +that are started after the sqlite3_interrupt() call returns.


    Last Insert Rowid

    @@ -3181,7 +3092,7 @@

    The sqlite3_progress_handler(D,N,X,P) interface causes the callback function X to be invoked periodically during long running calls to -sqlite3_step() and sqlite3_prepare() and similar for +sqlite3_exec(), sqlite3_step() and sqlite3_get_table() for database connection D. An example use for this interface is to keep a GUI updated during a large query.

    @@ -3206,14 +3117,7 @@ Note that sqlite3_prepare_v2() and sqlite3_step() both modify their database connections for the meaning of "modify" in this paragraph.

    -

    The progress handler callback would originally only be invoked from the -bytecode engine. It still might be invoked during sqlite3_prepare() -and similar because those routines might force a reparse of the schema -which involves running the bytecode engine. However, beginning with -SQLite version 3.41.0, the progress handler callback might also be -invoked directly from sqlite3_prepare() while analyzing and generating -code for complex queries. -


    +


    Pseudo-Random Number Generator

    @@ -3377,14 +3281,7 @@
     method of the default sqlite3_vfs object.  If the xSleep() method
     of the default VFS is not implemented correctly, or not implemented at
     all, then the behavior of sqlite3_sleep() may deviate from the description
    -in the previous paragraphs.

    - -

    If a negative argument is passed to sqlite3_sleep() the results vary by -VFS and operating system. Some system treat a negative argument as an -instruction to sleep forever. Others understand it to mean do not sleep -at all. In SQLite version 3.42.0 and later, a negative -argument passed into sqlite3_sleep() is changed to zero before it is relayed -down into the xSleep method of the VFS. +in the previous paragraphs.


    Compare the ages of two snapshot handles.

    @@ -3723,11 +3620,45 @@ makes it a no-op, but the sqlite3_stmt_readonly() result would still be false. Similarly, a CREATE TABLE IF NOT EXISTS statement is a read-only no-op if the table already exists, but -sqlite3_stmt_readonly() still returns false for such a statement.

    +sqlite3_stmt_readonly() still returns false for such a statement. +


    +

    Prepared Statement Scan Status

    + +
    +int sqlite3_stmt_scanstatus(
    +  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
    +  int idx,                  /* Index of loop to report on */
    +  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
    +  void *pOut                /* Result written here */
    +);
    +
    +

    +This interface returns information about the predicted and measured +performance for pStmt. Advanced applications can use this +interface to compare the predicted and the measured performance and +issue warnings and/or rerun ANALYZE if discrepancies are found.

    + +

    Since this interface is expected to be rarely used, it is only +available if SQLite is compiled using the SQLITE_ENABLE_STMT_SCANSTATUS +compile-time option.

    -

    If prepared statement X is an EXPLAIN or EXPLAIN QUERY PLAN -statement, then sqlite3_stmt_readonly(X) returns the same value as -if the EXPLAIN or EXPLAIN QUERY PLAN prefix were omitted. +

    The "iScanStatusOp" parameter determines which status information to return. +The "iScanStatusOp" must be one of the scanstatus options or the behavior +of this interface is undefined. +The requested measurement is written into a variable pointed to by +the "pOut" parameter. +Parameter "idx" identifies the specific loop to retrieve statistics for. +Loops are numbered starting from zero. If idx is out of range - less than +zero or greater than or equal to the total number of loops used to implement +the statement - a non-zero value is returned and the variable that pOut +points to is unchanged.

    + +

    Statistics might not be available for all loops in all statements. In cases +where there exist loops with no available statistics, this function behaves +as if the loop did not exist - it returns non-zero and leave the variable +that pOut points to unchanged.

    + +

    See also: sqlite3_stmt_scanstatus_reset()


    Zero Scan-Status Counters

    @@ -4000,6 +3931,43 @@ is unchanged by calls to sqlite3_config().

    See the threading mode documentation for additional information. +


    +

    Total Number Of Rows Modified

    + +
    +int sqlite3_total_changes(sqlite3*);
    +
    +

    +This function returns the total number of rows inserted, modified or +deleted by all INSERT, UPDATE or DELETE statements completed +since the database connection was opened, including those executed as +part of trigger programs. Executing any other type of SQL statement +does not affect the value returned by sqlite3_total_changes().

    + +

    Changes made as part of foreign key actions are included in the +count, but those made as part of REPLACE constraint resolution are +not. Changes to a view that are intercepted by INSTEAD OF triggers +are not counted.

    + +

    The sqlite3_total_changes(D) interface only reports the number +of rows that changed due to SQL statement run against database +connection D. Any changes by other database connections are ignored. +To detect changes against a database file from other database +connections use the PRAGMA data_version command or the +SQLITE_FCNTL_DATA_VERSION file control.

    + +

    If a separate thread makes changes on the same database connection +while sqlite3_total_changes() is running then the value +returned is unpredictable and not meaningful.

    + +

    See also: +


    SQL Trace Hook

    @@ -4245,28 +4213,6 @@

    This routine must be called from the same thread in which the application-defined function is running. -


    -

    Report the internal text encoding state of an sqlite3_value object

    - -
    -int sqlite3_value_encoding(sqlite3_value*);
    -
    -

    -The sqlite3_value_encoding(X) interface returns one of SQLITE_UTF8, -SQLITE_UTF16BE, or SQLITE_UTF16LE according to the current text encoding -of the value X, assuming that X has type TEXT. If sqlite3_value_type(X) -returns something other than SQLITE_TEXT, then the return value from -sqlite3_value_encoding(X) is meaningless. Calls to -sqlite3_value_text(X), sqlite3_value_text16(X), sqlite3_value_text16be(X), -sqlite3_value_text16le(X), sqlite3_value_bytes(X), or -sqlite3_value_bytes16(X) might change the encoding of the value X and -thus change the return from subsequent calls to sqlite3_value_encoding(X).

    - -

    This routine is intended for used by applications that test and validate -the SQLite implementation. This routine is inquiring about the opaque -internal state of an sqlite3_value object. Ordinary applications should -not need to know what the internal state of an sqlite3_value object is and -hence should not need to use this interface.


    Finding The Subtype Of SQL Values

    @@ -4287,33 +4233,14 @@

    This function may only be called from within a call to the xBestIndex -method of a virtual table. This function returns a pointer to a string -that is the name of the appropriate collation sequence to use for text -comparisons on the constraint identified by its arguments.

    - -

    The first argument must be the pointer to the sqlite3_index_info object -that is the first parameter to the xBestIndex() method. The second argument -must be an index into the aConstraint[] array belonging to the -sqlite3_index_info structure passed to xBestIndex.

    - -

    Important: -The first parameter must be the same pointer that is passed into the -xBestMethod() method. The first parameter may not be a pointer to a -different sqlite3_index_info object, even an exact copy.

    +method of a virtual table.

    -

    The return value is computed as follows:

    - -

      -
    1. If the constraint comes from a WHERE clause expression that contains -a COLLATE operator, then the name of the collation specified by -that COLLATE operator is returned. -

    2. If there is no COLLATE operator, but the column that is the subject -of the constraint specifies an alternative collating sequence via -a COLLATE clause on the column definition within the CREATE TABLE -statement that was passed into sqlite3_declare_vtab(), then the -name of that alternative collating sequence is returned. -

    3. Otherwise, "BINARY" is returned. -

    +

    The first argument must be the sqlite3_index_info object that is the +first parameter to the xBestIndex() method. The second argument must be +an index into the aConstraint[] array belonging to the sqlite3_index_info +structure passed to xBestIndex. This function returns a pointer to a buffer +containing the name of the collation sequence for the corresponding +constraint.


    Virtual Table Interface Configuration

    @@ -4335,153 +4262,6 @@ of the virtual table configuration options. The presence and meaning of parameters after C depend on which virtual table configuration option is used. -


    -

    Determine if a virtual table query is DISTINCT

    - -
    -int sqlite3_vtab_distinct(sqlite3_index_info*);
    -
    -

    -This API may only be used from within an xBestIndex method -of a virtual table implementation. The result of calling this -interface from outside of xBestIndex() is undefined and probably harmful.

    - -

    The sqlite3_vtab_distinct() interface returns an integer between 0 and -3. The integer returned by sqlite3_vtab_distinct() -gives the virtual table additional information about how the query -planner wants the output to be ordered. As long as the virtual table -can meet the ordering requirements of the query planner, it may set -the "orderByConsumed" flag.

    - -

    1. -If the sqlite3_vtab_distinct() interface returns 0, that means -that the query planner needs the virtual table to return all rows in the -sort order defined by the "nOrderBy" and "aOrderBy" fields of the -sqlite3_index_info object. This is the default expectation. If the -virtual table outputs all rows in sorted order, then it is always safe for -the xBestIndex method to set the "orderByConsumed" flag, regardless of -the return value from sqlite3_vtab_distinct(). -

    2. -If the sqlite3_vtab_distinct() interface returns 1, that means -that the query planner does not need the rows to be returned in sorted order -as long as all rows with the same values in all columns identified by the -"aOrderBy" field are adjacent. This mode is used when the query planner -is doing a GROUP BY. -

    3. -If the sqlite3_vtab_distinct() interface returns 2, that means -that the query planner does not need the rows returned in any particular -order, as long as rows with the same values in all "aOrderBy" columns -are adjacent. Furthermore, only a single row for each particular -combination of values in the columns identified by the "aOrderBy" field -needs to be returned. It is always ok for two or more rows with the same -values in all "aOrderBy" columns to be returned, as long as all such rows -are adjacent. The virtual table may, if it chooses, omit extra rows -that have the same value for all columns identified by "aOrderBy". -However omitting the extra rows is optional. -This mode is used for a DISTINCT query. -

    4. -If the sqlite3_vtab_distinct() interface returns 3, that means -that the query planner needs only distinct rows but it does need the -rows to be sorted. The virtual table implementation is free to omit -rows that are identical in all aOrderBy columns, if it wants to, but -it is not required to omit any rows. This mode is used for queries -that have both DISTINCT and ORDER BY clauses. -

    - -

    For the purposes of comparing virtual table output values to see if the -values are same value for sorting purposes, two NULL values are considered -to be the same. In other words, the comparison operator is "IS" -(or "IS NOT DISTINCT FROM") and not "==".

    - -

    If a virtual table implementation is unable to meet the requirements -specified above, then it must not set the "orderByConsumed" flag in the -sqlite3_index_info object or an incorrect answer may result.

    - -

    A virtual table implementation is always free to return rows in any order -it wants, as long as the "orderByConsumed" flag is not set. When the -the "orderByConsumed" flag is unset, the query planner will add extra -bytecode to ensure that the final results returned by the SQL query are -ordered correctly. The use of the "orderByConsumed" flag and the -sqlite3_vtab_distinct() interface is merely an optimization. Careful -use of the sqlite3_vtab_distinct() interface and the "orderByConsumed" -flag might help queries against a virtual table to run faster. Being -overly aggressive and setting the "orderByConsumed" flag when it is not -valid to do so, on the other hand, might cause SQLite to return incorrect -results. -


    -

    Identify and handle IN constraints in xBestIndex

    - -
    -int sqlite3_vtab_in(sqlite3_index_info*, int iCons, int bHandle);
    -
    -

    -This interface may only be used from within an -xBestIndex() method of a virtual table implementation. -The result of invoking this interface from any other context is -undefined and probably harmful.

    - -

    A constraint on a virtual table of the form -"column IN (...)" is -communicated to the xBestIndex method as a -SQLITE_INDEX_CONSTRAINT_EQ constraint. If xBestIndex wants to use -this constraint, it must set the corresponding -aConstraintUsage[].argvIndex to a postive integer. Then, under -the usual mode of handling IN operators, SQLite generates bytecode -that invokes the xFilter() method once for each value -on the right-hand side of the IN operator. Thus the virtual table -only sees a single value from the right-hand side of the IN operator -at a time.

    - -

    In some cases, however, it would be advantageous for the virtual -table to see all values on the right-hand of the IN operator all at -once. The sqlite3_vtab_in() interfaces facilitates this in two ways:

    - -

      -
    1. -A call to sqlite3_vtab_in(P,N,-1) will return true (non-zero) -if and only if the P->aConstraint[N] constraint -is an IN operator that can be processed all at once. In other words, -sqlite3_vtab_in() with -1 in the third argument is a mechanism -by which the virtual table can ask SQLite if all-at-once processing -of the IN operator is even possible.

      - -

    2. -A call to sqlite3_vtab_in(P,N,F) with F==1 or F==0 indicates -to SQLite that the virtual table does or does not want to process -the IN operator all-at-once, respectively. Thus when the third -parameter (F) is non-negative, this interface is the mechanism by -which the virtual table tells SQLite how it wants to process the -IN operator. -

    - -

    The sqlite3_vtab_in(P,N,F) interface can be invoked multiple times -within the same xBestIndex method call. For any given P,N pair, -the return value from sqlite3_vtab_in(P,N,F) will always be the same -within the same xBestIndex call. If the interface returns true -(non-zero), that means that the constraint is an IN operator -that can be processed all-at-once. If the constraint is not an IN -operator or cannot be processed all-at-once, then the interface returns -false.

    - -

    All-at-once processing of the IN operator is selected if both of the -following conditions are met:

    - -

      -
    1. The P->aConstraintUsage[N].argvIndex value is set to a positive -integer. This is how the virtual table tells SQLite that it wants to -use the N-th constraint.

      - -

    2. The last call to sqlite3_vtab_in(P,N,F) for which F was -non-negative had F>=1. -

    - -

    If either or both of the conditions above are false, then SQLite uses -the traditional one-at-a-time processing strategy for the IN constraint. -If both conditions are true, then the argvIndex-th parameter to the -xFilter method will be an sqlite3_value that appears to be NULL, -but which can be passed to sqlite3_vtab_in_first() and -sqlite3_vtab_in_next() to find all values on the right-hand side -of the IN constraint.


    Determine If Virtual Table Column Access Is For UPDATE

    @@ -4522,48 +4302,6 @@ SQLITE_ABORT, or SQLITE_REPLACE, according to the ON CONFLICT mode of the SQL statement that triggered the call to the xUpdate method of the virtual table. -


    -

    Constraint values in xBestIndex()

    - -
    -int sqlite3_vtab_rhs_value(sqlite3_index_info*, int, sqlite3_value **ppVal);
    -
    -

    -This API may only be used from within the xBestIndex method -of a virtual table implementation. The result of calling this interface -from outside of an xBestIndex method are undefined and probably harmful.

    - -

    When the sqlite3_vtab_rhs_value(P,J,V) interface is invoked from within -the xBestIndex method of a virtual table implementation, with P being -a copy of the sqlite3_index_info object pointer passed into xBestIndex and -J being a 0-based index into P->aConstraint[], then this routine -attempts to set *V to the value of the right-hand operand of -that constraint if the right-hand operand is known. If the -right-hand operand is not known, then *V is set to a NULL pointer. -The sqlite3_vtab_rhs_value(P,J,V) interface returns SQLITE_OK if -and only if *V is set to a value. The sqlite3_vtab_rhs_value(P,J,V) -inteface returns SQLITE_NOTFOUND if the right-hand side of the J-th -constraint is not available. The sqlite3_vtab_rhs_value() interface -can return an result code other than SQLITE_OK or SQLITE_NOTFOUND if -something goes wrong.

    - -

    The sqlite3_vtab_rhs_value() interface is usually only successful if -the right-hand operand of a constraint is a literal value in the original -SQL statement. If the right-hand operand is an expression or a reference -to some other column or a host parameter, then sqlite3_vtab_rhs_value() -will probably return SQLITE_NOTFOUND.

    - -

    Some constraints, such as SQLITE_INDEX_CONSTRAINT_ISNULL and -SQLITE_INDEX_CONSTRAINT_ISNOTNULL, have no right-hand operand. For such -constraints, sqlite3_vtab_rhs_value() always returns SQLITE_NOTFOUND.

    - -

    The sqlite3_value object returned in *V is a protected sqlite3_value -and remains valid for the duration of the xBestIndex method call. -When xBestIndex returns, the sqlite3_value object returned by -sqlite3_vtab_rhs_value() is automatically deallocated.

    - -

    The "_rhs_" in the name of this routine is an abbreviation for -"Right-Hand Side".


    Configure an auto-checkpoint

    @@ -4753,12 +4491,41 @@

    A single database handle may have at most a single write-ahead log callback registered at one time. Calling sqlite3_wal_hook() replaces any -previously registered write-ahead log callback. The return value is -a copy of the third parameter from the previous call, if any, or 0. -Note that the sqlite3_wal_autocheckpoint() interface and the +previously registered write-ahead log callback. Note that the +sqlite3_wal_autocheckpoint() interface and the wal_autocheckpoint pragma both invoke sqlite3_wal_hook() and will overwrite any prior sqlite3_wal_hook() settings. -


    +


    +

    Database Snapshot

    + +
    +typedef struct sqlite3_snapshot {
    +  unsigned char hidden[48];
    +} sqlite3_snapshot;
    +
    +

    +An instance of the snapshot object records the state of a WAL mode +database for some specific point in history.

    + +

    In WAL mode, multiple database connections that are open on the +same database file can each be reading a different historical version +of the database file. When a database connection begins a read +transaction, that connection sees an unchanging copy of the database +as it existed for the point in time when the transaction first started. +Subsequent changes to the database from other connections are not seen +by the reader until a new read transaction is started.

    + +

    The sqlite3_snapshot object records state information about an historical +version of the database file so that it is possible to later open a new read +transaction that sees that historical version of the database rather than +the most recent version. +

    1 Constructor: sqlite3_snapshot_get()

    +

    1 Destructor: sqlite3_snapshot_free()

    +

    3 Methods: + sqlite3_snapshot_cmp(), +sqlite3_snapshot_open(), +sqlite3_snapshot_recover()

    +

    Result Codes

    @@ -4875,14 +4642,12 @@
     #define SQLITE_CONSTRAINT_VTAB         (SQLITE_CONSTRAINT | (9<<8))
     #define SQLITE_CONSTRAINT_ROWID        (SQLITE_CONSTRAINT |(10<<8))
     #define SQLITE_CONSTRAINT_PINNED       (SQLITE_CONSTRAINT |(11<<8))
    -#define SQLITE_CONSTRAINT_DATATYPE     (SQLITE_CONSTRAINT |(12<<8))
     #define SQLITE_NOTICE_RECOVER_WAL      (SQLITE_NOTICE | (1<<8))
     #define SQLITE_NOTICE_RECOVER_ROLLBACK (SQLITE_NOTICE | (2<<8))
    -#define SQLITE_NOTICE_RBU              (SQLITE_NOTICE | (3<<8))
     #define SQLITE_WARNING_AUTOINDEX       (SQLITE_WARNING | (1<<8))
     #define SQLITE_AUTH_USER               (SQLITE_AUTH | (1<<8))
     #define SQLITE_OK_LOAD_PERMANENTLY     (SQLITE_OK | (1<<8))
    -#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8)) /* internal use only */
    +#define SQLITE_OK_SYMLINK              (SQLITE_OK | (2<<8))
     

    In its default configuration, SQLite API routines return one of 30 integer @@ -5030,7 +4795,7 @@

     #define SQLITE_CHECKPOINT_PASSIVE  0  /* Do as much as possible w/o blocking */
     #define SQLITE_CHECKPOINT_FULL     1  /* Wait for writers, then checkpoint */
    -#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for readers */
    +#define SQLITE_CHECKPOINT_RESTART  2  /* Like FULL but wait for for readers */
     #define SQLITE_CHECKPOINT_TRUNCATE 3  /* Like RESTART but also truncate WAL */
     

    @@ -5042,28 +4807,28 @@

    Configuration Options

    -#define SQLITE_CONFIG_SINGLETHREAD         1  /* nil */
    -#define SQLITE_CONFIG_MULTITHREAD          2  /* nil */
    -#define SQLITE_CONFIG_SERIALIZED           3  /* nil */
    -#define SQLITE_CONFIG_MALLOC               4  /* sqlite3_mem_methods* */
    -#define SQLITE_CONFIG_GETMALLOC            5  /* sqlite3_mem_methods* */
    -#define SQLITE_CONFIG_SCRATCH              6  /* No longer used */
    -#define SQLITE_CONFIG_PAGECACHE            7  /* void*, int sz, int N */
    -#define SQLITE_CONFIG_HEAP                 8  /* void*, int nByte, int min */
    -#define SQLITE_CONFIG_MEMSTATUS            9  /* boolean */
    -#define SQLITE_CONFIG_MUTEX               10  /* sqlite3_mutex_methods* */
    -#define SQLITE_CONFIG_GETMUTEX            11  /* sqlite3_mutex_methods* */
    -/* previously SQLITE_CONFIG_CHUNKALLOC    12 which is now unused. */
    -#define SQLITE_CONFIG_LOOKASIDE           13  /* int int */
    -#define SQLITE_CONFIG_PCACHE              14  /* no-op */
    -#define SQLITE_CONFIG_GETPCACHE           15  /* no-op */
    -#define SQLITE_CONFIG_LOG                 16  /* xFunc, void* */
    -#define SQLITE_CONFIG_URI                 17  /* int */
    -#define SQLITE_CONFIG_PCACHE2             18  /* sqlite3_pcache_methods2* */
    -#define SQLITE_CONFIG_GETPCACHE2          19  /* sqlite3_pcache_methods2* */
    +#define SQLITE_CONFIG_SINGLETHREAD  1  /* nil */
    +#define SQLITE_CONFIG_MULTITHREAD   2  /* nil */
    +#define SQLITE_CONFIG_SERIALIZED    3  /* nil */
    +#define SQLITE_CONFIG_MALLOC        4  /* sqlite3_mem_methods* */
    +#define SQLITE_CONFIG_GETMALLOC     5  /* sqlite3_mem_methods* */
    +#define SQLITE_CONFIG_SCRATCH       6  /* No longer used */
    +#define SQLITE_CONFIG_PAGECACHE     7  /* void*, int sz, int N */
    +#define SQLITE_CONFIG_HEAP          8  /* void*, int nByte, int min */
    +#define SQLITE_CONFIG_MEMSTATUS     9  /* boolean */
    +#define SQLITE_CONFIG_MUTEX        10  /* sqlite3_mutex_methods* */
    +#define SQLITE_CONFIG_GETMUTEX     11  /* sqlite3_mutex_methods* */
    +/* previously SQLITE_CONFIG_CHUNKALLOC 12 which is now unused. */
    +#define SQLITE_CONFIG_LOOKASIDE    13  /* int int */
    +#define SQLITE_CONFIG_PCACHE       14  /* no-op */
    +#define SQLITE_CONFIG_GETPCACHE    15  /* no-op */
    +#define SQLITE_CONFIG_LOG          16  /* xFunc, void* */
    +#define SQLITE_CONFIG_URI          17  /* int */
    +#define SQLITE_CONFIG_PCACHE2      18  /* sqlite3_pcache_methods2* */
    +#define SQLITE_CONFIG_GETPCACHE2   19  /* sqlite3_pcache_methods2* */
     #define SQLITE_CONFIG_COVERING_INDEX_SCAN 20  /* int */
    -#define SQLITE_CONFIG_SQLLOG              21  /* xSqllog, void* */
    -#define SQLITE_CONFIG_MMAP_SIZE           22  /* sqlite3_int64, sqlite3_int64 */
    +#define SQLITE_CONFIG_SQLLOG       21  /* xSqllog, void* */
    +#define SQLITE_CONFIG_MMAP_SIZE    22  /* sqlite3_int64, sqlite3_int64 */
     #define SQLITE_CONFIG_WIN32_HEAPSIZE      23  /* int nByte */
     #define SQLITE_CONFIG_PCACHE_HDRSZ        24  /* int *psz */
     #define SQLITE_CONFIG_PMASZ               25  /* unsigned int szPma */
    @@ -5076,23 +4841,6 @@
     These constants are the available integer configuration options that
     can be passed as the first argument to the sqlite3_config() interface.

    -

    Most of the configuration options for sqlite3_config() -will only work if invoked prior to sqlite3_initialize() or after -sqlite3_shutdown(). The few exceptions to this rule are called -"anytime configuration options". -Calling sqlite3_config() with a first argument that is not an -anytime configuration option in between calls to sqlite3_initialize() and -sqlite3_shutdown() is a no-op that returns SQLITE_MISUSE.

    - -

    The set of anytime configuration options can change (by insertions -and/or deletions) from one release of SQLite to the next. -As of SQLite version 3.42.0, the complete set of anytime configuration -options is: -

      -
    • SQLITE_CONFIG_LOG -
    • SQLITE_CONFIG_PCACHE_HDRSZ -

    -

    New configuration options may be added in future releases of SQLite. Existing configuration options might be discontinued. Applications should check the return code from sqlite3_config() to make sure that @@ -5488,9 +5236,7 @@ #define SQLITE_DBCONFIG_ENABLE_VIEW 1015 /* int int* */ #define SQLITE_DBCONFIG_LEGACY_FILE_FORMAT 1016 /* int int* */ #define SQLITE_DBCONFIG_TRUSTED_SCHEMA 1017 /* int int* */ -#define SQLITE_DBCONFIG_STMT_SCANSTATUS 1018 /* int int* */ -#define SQLITE_DBCONFIG_REVERSE_SCANORDER 1019 /* int int* */ -#define SQLITE_DBCONFIG_MAX 1019 /* Largest DBCONFIG */ +#define SQLITE_DBCONFIG_MAX 1017 /* Largest DBCONFIG */

    These constants are the available integer configuration options that @@ -5523,7 +5269,7 @@ configuration for a database connection can only be changed when that connection is not currently using lookaside memory, or in other words when the "current value" returned by -sqlite3_db_status(D,SQLITE_DBSTATUS_LOOKASIDE_USED,...) is zero. +sqlite3_db_status(D,SQLITE_CONFIG_LOOKASIDE,...) is zero. Any attempt to change the lookaside memory configuration when lookaside memory is in use leaves the configuration unchanged and returns SQLITE_BUSY.

    @@ -5683,12 +5429,8 @@
  • sqlite3_db_config(db, SQLITE_DBCONFIG_RESET_DATABASE, 0, 0); Because resetting a database is destructive and irreversible, the -process requires the use of this obscure API and multiple steps to -help ensure that it does not happen by accident. Because this -feature must be capable of resetting corrupt databases, and -shutting down virtual tables may require access to that corrupt -storage, the library must abandon any installed virtual tables -without calling their xDestroy() methods.

    +process requires the use of this obscure API and multiple steps to help +ensure that it does not happen by accident.

    SQLITE_DBCONFIG_DEFENSIVE
    @@ -5700,7 +5442,6 @@ @@ -5731,7 +5472,7 @@

    -

    SQLITE_DBCONFIG_DQS_DML
    +
    SQLITE_DBCONFIG_DQS_DML
    The SQLITE_DBCONFIG_DQS_DML option activates or deactivates the legacy double-quoted string literal misfeature for DML statements only, that is DELETE, INSERT, SELECT, and UPDATE statements. The @@ -5741,7 +5482,7 @@

    -

    SQLITE_DBCONFIG_DQS_DDL
    +
    SQLITE_DBCONFIG_DQS_DDL
    The SQLITE_DBCONFIG_DQS option activates or deactivates the legacy double-quoted string literal misfeature for DDL statements, such as CREATE TABLE and CREATE INDEX. The @@ -5751,7 +5492,7 @@

    -

    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    +
    SQLITE_DBCONFIG_TRUSTED_SCHEMA
    The SQLITE_DBCONFIG_TRUSTED_SCHEMA option tells SQLite to assume that database schemas are untainted by malicious content. When the SQLITE_DBCONFIG_TRUSTED_SCHEMA option is disabled, SQLite @@ -5772,7 +5513,7 @@

    -

    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    +
    SQLITE_DBCONFIG_LEGACY_FILE_FORMAT
    The SQLITE_DBCONFIG_LEGACY_FILE_FORMAT option activates or deactivates the legacy file format flag. When activated, this flag causes all newly created database file to have a schema format version number (the 4-byte @@ -5781,7 +5522,7 @@ any SQLite version back to 3.0.0 (2004-06-18). Without this setting, newly created databases are generally not understandable by SQLite versions prior to 3.3.0 (2006-01-11). As these words are written, there -is now scarcely any need to generate database files that are compatible +is now scarcely any need to generated database files that are compatible all the way back to version 3.0.0, and so this setting is of little practical use, but is provided so that SQLite can continue to claim the ability to generate new database files that are compatible with version @@ -5791,42 +5532,8 @@ process a table with generated columns and a descending index. This is not considered a bug since SQLite versions 3.3.0 and earlier do not support either generated columns or decending indexes. -

    - -

    - -

    SQLITE_DBCONFIG_STMT_SCANSTATUS
    -
    The SQLITE_DBCONFIG_STMT_SCANSTATUS option is only useful in -SQLITE_ENABLE_STMT_SCANSTATUS builds. In this case, it sets or clears -a flag that enables collection of the sqlite3_stmt_scanstatus_v2() -statistics. For statistics to be collected, the flag must be set on -the database handle both when the SQL statement is prepared and when it -is stepped. The flag is set (collection of statistics is enabled) -by default. This option takes two arguments: an integer and a pointer to -an integer.. The first argument is 1, 0, or -1 to enable, disable, or -leave unchanged the statement scanstatus option. If the second argument -is not NULL, then the value of the statement scanstatus setting after -processing the first argument is written into the integer that the second -argument points to. -

    - -

    - -

    SQLITE_DBCONFIG_REVERSE_SCANORDER
    -
    The SQLITE_DBCONFIG_REVERSE_SCANORDER option changes the default order -in which tables and indexes are scanned so that the scans start at the end -and work toward the beginning rather than starting at the beginning and -working toward the end. Setting SQLITE_DBCONFIG_REVERSE_SCANORDER is the -same as setting PRAGMA reverse_unordered_selects. This option takes -two arguments which are an integer and a pointer to an integer. The first -argument is 1, 0, or -1 to enable, disable, or leave unchanged the -reverse scan order flag, respectively. If the second argument is not NULL, -then 0 or 1 is written into the integer that the second argument points to -depending on if the reverse scan order flag is set after processing the -first argument. -

    - -

    + +


    Authorizer Return Codes

    @@ -5903,21 +5610,10 @@ from top-level SQL, and cannot be used in VIEWs or TRIGGERs nor in schema structures such as CHECK constraints, DEFAULT clauses, expression indexes, partial indexes, or generated columns. -

    -The SQLITE_DIRECTONLY flag is recommended for any -application-defined SQL function -that has side-effects or that could potentially leak sensitive information. -This will prevent attacks in which an application is tricked -into using a database file that has had its schema surreptiously -modified to invoke the application-defined function in ways that are -harmful. -

    -Some people say it is good practice to set SQLITE_DIRECTONLY on all -application-defined SQL functions, regardless of whether or not they -are security sensitive, as doing so prevents those functions from being used -inside of the database schema, and thus ensures that the database -can be inspected and modified using generic tools (such as the CLI) -that do not have access to the application-defined functions. +The SQLITE_DIRECTONLY flags is a security feature which is recommended +for all application-defined SQL functions, and especially for functions +that have side-effects or that could potentially leak sensitive +information.

    @@ -6017,7 +5713,6 @@ #define SQLITE_FCNTL_CKPT_START 39 #define SQLITE_FCNTL_EXTERNAL_READER 40 #define SQLITE_FCNTL_CKSM_FILE 41 -#define SQLITE_FCNTL_RESET_CACHE 42

  • These integer constants are opcodes for the xFileControl method @@ -6031,8 +5726,9 @@ opcode causes the xFileControl method to write the current state of the lock (one of SQLITE_LOCK_NONE, SQLITE_LOCK_SHARED, SQLITE_LOCK_RESERVED, SQLITE_LOCK_PENDING, or SQLITE_LOCK_EXCLUSIVE) -into an integer that the pArg argument points to. -This capability is only available if SQLite is compiled with SQLITE_DEBUG.

    +into an integer that the pArg argument points to. This capability +is used during testing and is only available when the SQLITE_TEST +compile-time option is used.

  • @@ -6367,7 +6063,8 @@ The SQLITE_FCNTL_CKPT_DONE opcode is invoked from within a checkpoint in wal mode after the client has finished copying pages from the wal file to the database file, but before the *-shm file is updated to -record the fact that the pages have been checkpointed.

    +record the fact that the pages have been checkpointed. +

  • @@ -6380,77 +6077,38 @@ currently has an SQL transaction open on the database. It is set to 0 if the database is not a wal-mode db, or if there is no such connection in any other process. This opcode cannot be used to detect transactions opened -by clients within the current process, only within other processes.

    +by clients within the current process, only within other processes. +

  • -The SQLITE_FCNTL_CKSM_FILE opcode is for use interally by the -checksum VFS shim only.

    - -

  • - -If there is currently no transaction open on the database, and the -database is not a temp db, then the SQLITE_FCNTL_RESET_CACHE file-control -purges the contents of the in-memory page cache. If there is an open -transaction, or if the db is a temp-db, this opcode is a no-op, not an error. +Used by the cksmvfs VFS module only.


    Virtual Table Constraint Operator Codes

    -#define SQLITE_INDEX_CONSTRAINT_EQ          2
    -#define SQLITE_INDEX_CONSTRAINT_GT          4
    -#define SQLITE_INDEX_CONSTRAINT_LE          8
    -#define SQLITE_INDEX_CONSTRAINT_LT         16
    -#define SQLITE_INDEX_CONSTRAINT_GE         32
    -#define SQLITE_INDEX_CONSTRAINT_MATCH      64
    -#define SQLITE_INDEX_CONSTRAINT_LIKE       65
    -#define SQLITE_INDEX_CONSTRAINT_GLOB       66
    -#define SQLITE_INDEX_CONSTRAINT_REGEXP     67
    -#define SQLITE_INDEX_CONSTRAINT_NE         68
    -#define SQLITE_INDEX_CONSTRAINT_ISNOT      69
    -#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL  70
    -#define SQLITE_INDEX_CONSTRAINT_ISNULL     71
    -#define SQLITE_INDEX_CONSTRAINT_IS         72
    -#define SQLITE_INDEX_CONSTRAINT_LIMIT      73
    -#define SQLITE_INDEX_CONSTRAINT_OFFSET     74
    -#define SQLITE_INDEX_CONSTRAINT_FUNCTION  150
    +#define SQLITE_INDEX_CONSTRAINT_EQ         2
    +#define SQLITE_INDEX_CONSTRAINT_GT         4
    +#define SQLITE_INDEX_CONSTRAINT_LE         8
    +#define SQLITE_INDEX_CONSTRAINT_LT        16
    +#define SQLITE_INDEX_CONSTRAINT_GE        32
    +#define SQLITE_INDEX_CONSTRAINT_MATCH     64
    +#define SQLITE_INDEX_CONSTRAINT_LIKE      65
    +#define SQLITE_INDEX_CONSTRAINT_GLOB      66
    +#define SQLITE_INDEX_CONSTRAINT_REGEXP    67
    +#define SQLITE_INDEX_CONSTRAINT_NE        68
    +#define SQLITE_INDEX_CONSTRAINT_ISNOT     69
    +#define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70
    +#define SQLITE_INDEX_CONSTRAINT_ISNULL    71
    +#define SQLITE_INDEX_CONSTRAINT_IS        72
    +#define SQLITE_INDEX_CONSTRAINT_FUNCTION 150
     

    These macros define the allowed values for the sqlite3_index_info.aConstraint[].op field. Each value represents -an operator that is part of a constraint term in the WHERE clause of -a query that uses a virtual table.

    - -

    The left-hand operand of the operator is given by the corresponding -aConstraint[].iColumn field. An iColumn of -1 indicates the left-hand -operand is the rowid. -The SQLITE_INDEX_CONSTRAINT_LIMIT and SQLITE_INDEX_CONSTRAINT_OFFSET -operators have no left-hand operand, and so for those operators the -corresponding aConstraint[].iColumn is meaningless and should not be -used.

    - -

    All operator values from SQLITE_INDEX_CONSTRAINT_FUNCTION through -value 255 are reserved to represent functions that are overloaded -by the xFindFunction method of the virtual table -implementation.

    - -

    The right-hand operands for each constraint might be accessible using -the sqlite3_vtab_rhs_value() interface. Usually the right-hand -operand is only available if it appears as a single constant literal -in the input SQL. If the right-hand operand is another column or an -expression (even a constant expression) or a parameter, then the -sqlite3_vtab_rhs_value() probably will not be able to extract it. -The SQLITE_INDEX_CONSTRAINT_ISNULL and -SQLITE_INDEX_CONSTRAINT_ISNOTNULL operators have no right-hand operand -and hence calls to sqlite3_vtab_rhs_value() for those operators will -always return SQLITE_NOTFOUND.

    - -

    The collating sequence to be used for comparison can be found using -the sqlite3_vtab_collation() interface. For most real-world virtual -tables, the collating sequence of constraints does not matter (for example -because the constraints are numeric) and so the sqlite3_vtab_collation() -interface is not commonly needed. +an operator that is part of a constraint term in the wHERE clause of +a query that uses a virtual table.


    Device Characteristics

    @@ -6505,20 +6163,16 @@

    File Locking Levels

    -#define SQLITE_LOCK_NONE          0       /* xUnlock() only */
    -#define SQLITE_LOCK_SHARED        1       /* xLock() or xUnlock() */
    -#define SQLITE_LOCK_RESERVED      2       /* xLock() only */
    -#define SQLITE_LOCK_PENDING       3       /* xLock() only */
    -#define SQLITE_LOCK_EXCLUSIVE     4       /* xLock() only */
    +#define SQLITE_LOCK_NONE          0
    +#define SQLITE_LOCK_SHARED        1
    +#define SQLITE_LOCK_RESERVED      2
    +#define SQLITE_LOCK_PENDING       3
    +#define SQLITE_LOCK_EXCLUSIVE     4
     

    SQLite uses one of these integer values as the second argument to calls it makes to the xLock() and xUnlock() methods -of an sqlite3_io_methods object. These values are ordered from -lest restrictive to most restrictive.

    - -

    The argument to xLock() is always SHARED or higher. The argument to -xUnlock is either SHARED or NONE. +of an sqlite3_io_methods object.


    Mutex Types

    @@ -6572,25 +6226,11 @@ #define SQLITE_OPEN_PRIVATECACHE 0x00040000 /* Ok for sqlite3_open_v2() */ #define SQLITE_OPEN_WAL 0x00080000 /* VFS only */ #define SQLITE_OPEN_NOFOLLOW 0x01000000 /* Ok for sqlite3_open_v2() */ -#define SQLITE_OPEN_EXRESCODE 0x02000000 /* Extended result codes */
  • These bit values are intended for use in the 3rd parameter to the sqlite3_open_v2() interface and -in the 4th parameter to the sqlite3_vfs.xOpen method.

    - -

    Only those flags marked as "Ok for sqlite3_open_v2()" may be -used as the third argument to the sqlite3_open_v2() interface. -The other flags have historically been ignored by sqlite3_open_v2(), -though future versions of SQLite might change so that an error is -raised if any of the disallowed bits are passed into sqlite3_open_v2(). -Applications should not depend on the historical behavior.

    - -

    Note in particular that passing the SQLITE_OPEN_EXCLUSIVE flag into -sqlite3_open_v2() does *not* cause the underlying database file -to be opened using O_EXCL. Passing SQLITE_OPEN_EXCLUSIVE into -sqlite3_open_v2() has historically be a no-op and might become an -error in future versions of SQLite. +in the 4th parameter to the sqlite3_vfs.xOpen method.


    Prepare Flags

    @@ -6634,13 +6274,7 @@ to return an error (error code SQLITE_ERROR) if the statement uses any virtual tables. -


    -

    Prepared Statement Scan Status

    - -
    -#define SQLITE_SCANSTAT_COMPLEX 0x0001
    -
    -


    +


    Prepared Statement Scan Status Opcodes

    @@ -6650,8 +6284,6 @@
     #define SQLITE_SCANSTAT_NAME     3
     #define SQLITE_SCANSTAT_EXPLAIN  4
     #define SQLITE_SCANSTAT_SELECTID 5
    -#define SQLITE_SCANSTAT_PARENTID 6
    -#define SQLITE_SCANSTAT_NCYCLE   7
     

    The following constants can be used for the T parameter to the @@ -6662,10 +6294,6 @@ managed by the prepared statement S and will be automatically freed when S is finalized.

    -

    Not all values are available for all query elements. When a value is -not available, the output variable is set to -1 if the value is numeric, -or to NULL if it is a string (SQLITE_SCANSTAT_NAME).

    -

    SQLITE_SCANSTAT_NLOOP
    @@ -6699,26 +6327,12 @@ description for the X-th loop.

    -

    SQLITE_SCANSTAT_SELECTID
    -
    The "int" variable pointed to by the V parameter will be set to the -id for the X-th query plan element. The id value is unique within the -statement. The select-id is the same value as is output in the first -column of an EXPLAIN QUERY PLAN query.

    - -

    -

    SQLITE_SCANSTAT_PARENTID
    +
    SQLITE_SCANSTAT_SELECT
    The "int" variable pointed to by the V parameter will be set to the -the id of the parent of the current query element, if applicable, or -to zero if the query element has no parent. This is the same value as -returned in the second column of an EXPLAIN QUERY PLAN query.

    - -

    -

    SQLITE_SCANSTAT_NCYCLE
    -
    The sqlite3_int64 output value is set to the number of cycles, -according to the processor time-stamp counter, that elapsed while the -query element was being processed. This value is not available for -all query elements - if it is unavailable the output variable is -set to -1. +"select-id" for the X-th loop. The select-id identifies which query or +subquery the loop is part of. The main query has a select-id of zero. +The select-id is the same value as is output in the first column +of an EXPLAIN QUERY PLAN query.


    Flags for the xShmLock VFS method

    @@ -6752,9 +6366,9 @@

    Compile-Time Library Version Numbers

    -#define SQLITE_VERSION        "3.42.0"
    -#define SQLITE_VERSION_NUMBER 3042000
    -#define SQLITE_SOURCE_ID      "2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0"
    +#define SQLITE_VERSION        "3.36.0"
    +#define SQLITE_VERSION_NUMBER 3036000
    +#define SQLITE_SOURCE_ID      "2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5"
     

    The SQLITE_VERSION C preprocessor macro in the sqlite3.h header @@ -6956,8 +6570,7 @@ #define SQLITE_TESTCTRL_SEEK_COUNT 30 #define SQLITE_TESTCTRL_TRACEFLAGS 31 #define SQLITE_TESTCTRL_TUNE 32 -#define SQLITE_TESTCTRL_LOGEST 33 -#define SQLITE_TESTCTRL_LAST 33 /* Largest TESTCTRL */ +#define SQLITE_TESTCTRL_LAST 32 /* Largest TESTCTRL */

    These constants are the valid operation code parameters used @@ -7010,8 +6623,8 @@

    An SQLITE_TRACE_PROFILE callback provides approximately the same information as is provided by the sqlite3_profile() callback. The P argument is a pointer to the prepared statement and the -X argument points to a 64-bit integer which is approximately -the number of nanoseconds that the prepared statement took to run. +X argument points to a 64-bit integer which is the estimated of +the number of nanosecond that the prepared statement took to run. The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes.

    @@ -7071,7 +6684,6 @@ #define SQLITE_VTAB_CONSTRAINT_SUPPORT 1 #define SQLITE_VTAB_INNOCUOUS 2 #define SQLITE_VTAB_DIRECTONLY 3 -#define SQLITE_VTAB_USES_ALL_SCHEMAS 4

    These macros define the various options to the @@ -7125,22 +6737,12 @@

    SQLITE_VTAB_INNOCUOUS
    Calls of the form sqlite3_vtab_config(db,SQLITE_VTAB_INNOCUOUS) from within the -the xConnect or xCreate methods of a virtual table implementation +the xConnect or xCreate methods of a virtual table implmentation identify that virtual table as being safe to use from within triggers and views. Conceptually, the SQLITE_VTAB_INNOCUOUS tag means that the virtual table can do no serious harm even if it is controlled by a malicious hacker. Developers should avoid setting the SQLITE_VTAB_INNOCUOUS flag unless absolutely necessary. -

    - -

    -

    SQLITE_VTAB_USES_ALL_SCHEMAS
    -
    Calls of the form -sqlite3_vtab_config(db,SQLITE_VTAB_USES_ALL_SCHEMA) from within the -the xConnect or xCreate methods of a virtual table implementation -instruct the query planner to begin at least a read transaction on -all schemas ("main", "temp", and any ATTACH-ed databases) whenever the -virtual table is used.


    @@ -7383,8 +6985,6 @@ #define SQLITE_STMTSTATUS_VM_STEP 4 #define SQLITE_STMTSTATUS_REPREPARE 5 #define SQLITE_STMTSTATUS_RUN 6 -#define SQLITE_STMTSTATUS_FILTER_MISS 7 -#define SQLITE_STMTSTATUS_FILTER_HIT 8 #define SQLITE_STMTSTATUS_MEMUSED 99

    @@ -7437,18 +7037,6 @@ The counter is incremented on the first sqlite3_step() call of each cycle.

    -

    - - - -

    SQLITE_STMTSTATUS_FILTER_HIT
    -SQLITE_STMTSTATUS_FILTER_MISS
    -
    SQLITE_STMTSTATUS_FILTER_HIT is the number of times that a join -step was bypassed because a Bloom filter returned not-found. The -corresponding SQLITE_STMTSTATUS_FILTER_MISS value is the number of -times that the Bloom filter returned a find, and thus the join step -had to be processed as normal.

    -

    SQLITE_STMTSTATUS_MEMUSED
    This is the approximate number of bytes of heap memory @@ -7457,37 +7045,7 @@ is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED.
    -


    -

    Database Snapshot

    - -
    -typedef struct sqlite3_snapshot {
    -  unsigned char hidden[48];
    -} sqlite3_snapshot;
    -
    -

    -An instance of the snapshot object records the state of a WAL mode -database for some specific point in history.

    - -

    In WAL mode, multiple database connections that are open on the -same database file can each be reading a different historical version -of the database file. When a database connection begins a read -transaction, that connection sees an unchanging copy of the database -as it existed for the point in time when the transaction first started. -Subsequent changes to the database from other connections are not seen -by the reader until a new read transaction is started.

    - -

    The sqlite3_snapshot object records state information about an historical -version of the database file so that it is possible to later open a new read -transaction that sees that historical version of the database rather than -the most recent version. -

    1 Constructor using this object: sqlite3_snapshot_get()

    -

    1 Destructor using this object: sqlite3_snapshot_free()

    -

    3 Methods using this object: - sqlite3_snapshot_cmp(), -sqlite3_snapshot_open(), -sqlite3_snapshot_recover()

    -
    +


    64-Bit Integer Types

    @@ -7610,9 +7168,9 @@
     The sqlite3_blob_read() and sqlite3_blob_write() interfaces
     can be used to read or write small subsections of the BLOB.
     The sqlite3_blob_bytes() interface returns the size of the BLOB in bytes.
    -

    1 Constructor using this object: sqlite3_blob_open()

    -

    1 Destructor using this object: sqlite3_blob_close()

    -

    4 Methods using this object: +

    1 Constructor: sqlite3_blob_open()

    +

    1 Destructor: sqlite3_blob_close()

    +

    4 Methods: sqlite3_blob_bytes(), sqlite3_blob_read(), sqlite3_blob_reopen(), @@ -7633,22 +7191,20 @@ sqlite3_prepare_v2(), sqlite3_create_function(), and sqlite3_busy_timeout() to name but three) that are methods on an sqlite3 object. -

    3 Constructors using this object: +

    3 Constructors: sqlite3_open(), sqlite3_open16(), sqlite3_open_v2()

    -

    2 Destructors using this object: +

    2 Destructors: sqlite3_close(), sqlite3_close_v2()

    -

    77 Methods using this object: +

    71 Methods:

    -sqlite3_filename sqlite3_create_filename(
    +char *sqlite3_create_filename(
       const char *zDatabase,
       const char *zJournal,
       const char *zWal,
       int nParam,
       const char **azParam
     );
    -void sqlite3_free_filename(sqlite3_filename);
    +void sqlite3_free_filename(char*);
     

    These interfces are provided for use by VFS shim implementations and @@ -8906,7 +8392,7 @@ destructor.

    If the third parameter (the pointer to the sqlite3_module object) is -NULL then no new module is created and any existing modules with the +NULL then no new module is create and any existing modules with the same name are dropped.

    See also: sqlite3_drop_modules() @@ -8919,7 +8405,6 @@ const char *sqlite3_errmsg(sqlite3*); const void *sqlite3_errmsg16(sqlite3*); const char *sqlite3_errstr(int); -int sqlite3_error_offset(sqlite3 *db);

    If the most recent sqlite3_* API call associated with @@ -8935,14 +8420,13 @@ sqlite3_extended_errcode() might change with each API call. Except, there are some interfaces that are guaranteed to never change the value of the error code. The error-code preserving -interfaces include the following:

    +interfaces are:

    • sqlite3_errcode()
    • sqlite3_extended_errcode()
    • sqlite3_errmsg()
    • sqlite3_errmsg16() -
    • sqlite3_error_offset()

    The sqlite3_errmsg() and sqlite3_errmsg16() return English-language @@ -8957,13 +8441,6 @@ Memory to hold the error message string is managed internally and must not be freed by the application.

    -

    If the most recent error references a specific token in the input -SQL, the sqlite3_error_offset() interface returns the byte offset -of the start of that token. The byte offset returned by -sqlite3_error_offset() assumes that the input SQL is UTF8. -If the most recent error does not reference a specific token in the input -SQL, then the sqlite3_error_offset() function returns -1.

    -

    When the serialized threading mode is in use, it might be the case that a second error occurs on a separate thread in between the time of the first error and the call to these interfaces. @@ -8983,9 +8460,7 @@

     const char *sqlite3_sql(sqlite3_stmt *pStmt);
     char *sqlite3_expanded_sql(sqlite3_stmt *pStmt);
    -#ifdef SQLITE_ENABLE_NORMALIZE
     const char *sqlite3_normalized_sql(sqlite3_stmt *pStmt);
    -#endif
     

    The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 @@ -9019,18 +8494,15 @@ are managed by SQLite and are automatically freed when the prepared statement is finalized. The string returned by sqlite3_expanded_sql(P), on the other hand, -is obtained from sqlite3_malloc() and must be freed by the application -by passing it to sqlite3_free().

    - -

    The sqlite3_normalized_sql() interface is only available if -the SQLITE_ENABLE_NORMALIZE compile-time option is defined. +is obtained from sqlite3_malloc() and must be free by the application +by passing it to sqlite3_free().


    Translate filenames

    -const char *sqlite3_filename_database(sqlite3_filename);
    -const char *sqlite3_filename_journal(sqlite3_filename);
    -const char *sqlite3_filename_wal(sqlite3_filename);
    +const char *sqlite3_filename_database(const char*);
    +const char *sqlite3_filename_journal(const char*);
    +const char *sqlite3_filename_wal(const char*);
     

    These routines are available to custom VFS implementations for @@ -9322,7 +8794,7 @@

    The soft heap limit may not be greater than the hard heap limit. If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) is invoked with a value of N that is greater than the hard heap limit, -the soft heap limit is set to the value of the hard heap limit. +the the soft heap limit is set to the value of the hard heap limit. The soft heap limit is automatically enabled whenever the hard heap limit is enabled. When sqlite3_hard_heap_limit64(N) is invoked and the soft heap limit is outside the range of 1..N, then the soft heap @@ -9431,47 +8903,6 @@ implementation of sqlite3_os_init() or sqlite3_os_end() must return SQLITE_OK on success and some other error code upon failure. -


    -

    Interrupt A Long-Running Query

    - -
    -void sqlite3_interrupt(sqlite3*);
    -int sqlite3_is_interrupted(sqlite3*);
    -
    -

    -This function causes any pending database operation to abort and -return at its earliest opportunity. This routine is typically -called in response to a user action such as pressing "Cancel" -or Ctrl-C where the user wants a long query operation to halt -immediately.

    - -

    It is safe to call this routine from a thread different from the -thread that is currently running the database operation. But it -is not safe to call this routine with a database connection that -is closed or might close before sqlite3_interrupt() returns.

    - -

    If an SQL operation is very nearly finished at the time when -sqlite3_interrupt() is called, then it might not have an opportunity -to be interrupted and might continue to completion.

    - -

    An SQL operation that is interrupted will return SQLITE_INTERRUPT. -If the interrupted SQL operation is an INSERT, UPDATE, or DELETE -that is inside an explicit transaction, then the entire transaction -will be rolled back automatically.

    - -

    The sqlite3_interrupt(D) call is in effect until all currently running -SQL statements on database connection D complete. Any new SQL statements -that are started after the sqlite3_interrupt() call and before the -running statement count reaches zero are interrupted as if they had been -running prior to the sqlite3_interrupt() call. New SQL statements -that are started after the running statement count reaches zero are -not effected by the sqlite3_interrupt(). -A call to sqlite3_interrupt(D) that occurs when there are no running -SQL statements is a no-op and has no effect on SQL statements -that are started after the sqlite3_interrupt() call returns.

    - -

    The sqlite3_is_interrupted(D) interface can be used to determine whether -or not an interrupt is currently in effect for database connection D.


    SQL Keyword Checking

    @@ -9750,9 +9181,9 @@ is undefined if the mutex is not currently entered by the calling thread or is not currently allocated.

    -

    If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), -sqlite3_mutex_leave(), or sqlite3_mutex_free() is a NULL pointer, -then any of the four routines behaves as a no-op.

    +

    If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or +sqlite3_mutex_leave() is a NULL pointer, then all three routines +behave as no-ops.

    See also: sqlite3_mutex_held() and sqlite3_mutex_notheld().


    @@ -9839,18 +9270,13 @@

    SQLITE_OPEN_READONLY
    -
    The database is opened in read-only mode. If the database does -not already exist, an error is returned.

    +
    The database is opened in read-only mode. If the database does not +already exist, an error is returned.

    SQLITE_OPEN_READWRITE
    -
    The database is opened for reading and writing if possible, or -reading only if the file is write protected by the operating -system. In either case the database must already exist, otherwise -an error is returned. For historical reasons, if opening in -read-write mode fails due to OS-level permissions, an attempt is -made to open it in read-only mode. sqlite3_db_readonly() can be -used to determine whether the database is actually -read-write.

    +
    The database is opened for reading and writing if possible, or reading +only if the file is write protected by the operating system. In either +case the database must already exist, otherwise an error is returned.

    SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE
    The database is opened for reading and writing, and is created if @@ -9887,42 +9313,22 @@

    SQLITE_OPEN_SHAREDCACHE
    The database is opened shared cache enabled, overriding the default shared cache setting provided by -sqlite3_enable_shared_cache(). -The use of shared cache mode is discouraged and hence shared cache -capabilities may be omitted from many builds of SQLite. In such cases, -this option is a no-op.

    +sqlite3_enable_shared_cache().

    SQLITE_OPEN_PRIVATECACHE
    The database is opened shared cache disabled, overriding the default shared cache setting provided by sqlite3_enable_shared_cache().

    -

    -

    SQLITE_OPEN_EXRESCODE
    -
    The database connection comes up in "extended result code mode". -In other words, the database behaves has if -sqlite3_extended_result_codes(db,1) where called on the database -connection as soon as the connection is created. In addition to setting -the extended result code mode, this flag also causes sqlite3_open_v2() -to return an extended result code.

    -

    SQLITE_OPEN_NOFOLLOW
    -
    The database filename is not allowed to contain a symbolic link
    +
    The database filename is not allowed to be a symbolic link

    If the 3rd parameter to sqlite3_open_v2() is not one of the required combinations shown above optionally combined with other SQLITE_OPEN_* bits -then the behavior is undefined. Historic versions of SQLite -have silently ignored surplus bits in the flags parameter to -sqlite3_open_v2(), however that behavior might not be carried through -into future versions of SQLite and so applications should not rely -upon it. Note in particular that the SQLITE_OPEN_EXCLUSIVE flag is a no-op -for sqlite3_open_v2(). The SQLITE_OPEN_EXCLUSIVE does *not* cause -the open to fail if the database already exists. The SQLITE_OPEN_EXCLUSIVE -flag is intended for use by the VFS interface only, and not -by sqlite3_open_v2().

    +then the behavior is undefined.

    The fourth parameter to sqlite3_open_v2() is the name of the sqlite3_vfs object that defines the operating system interface that @@ -10155,10 +9561,6 @@ function is not defined for operations on WITHOUT ROWID tables, or for DELETE operations on rowid tables.

    -

    The sqlite3_preupdate_hook(D,C,P) function returns the P argument from -the previous call on the same database connection D, or NULL for -the first call on D.

    -

    The sqlite3_preupdate_old(), sqlite3_preupdate_new(), sqlite3_preupdate_count(), and sqlite3_preupdate_depth() interfaces provide additional information about a preupdate event. These routines @@ -10342,10 +9744,9 @@ of SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16BE, or SQLITE_UTF16LE. SQLite takes the text result from the application from the 2nd parameter of the sqlite3_result_text* interfaces. -If the 3rd parameter to any of the sqlite3_result_text* interfaces -other than sqlite3_result_text64() is negative, then SQLite computes -the string length itself by searching the 2nd parameter for the first -zero character. +If the 3rd parameter to the sqlite3_result_text* interfaces +is negative, then SQLite takes result text from the 2nd parameter +through the first zero character. If the 3rd parameter to the sqlite3_result_text* interfaces is non-negative, then as many bytes (not characters) of the text pointed to by the 2nd parameter are taken as the application-defined @@ -10447,57 +9848,6 @@ sqlite3_status() are undefined.

    See also: sqlite3_db_status() -


    -

    Prepared Statement Scan Status

    - -
    -int sqlite3_stmt_scanstatus(
    -  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
    -  int idx,                  /* Index of loop to report on */
    -  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
    -  void *pOut                /* Result written here */
    -);
    -int sqlite3_stmt_scanstatus_v2(
    -  sqlite3_stmt *pStmt,      /* Prepared statement for which info desired */
    -  int idx,                  /* Index of loop to report on */
    -  int iScanStatusOp,        /* Information desired.  SQLITE_SCANSTAT_* */
    -  int flags,                /* Mask of flags defined below */
    -  void *pOut                /* Result written here */
    -);
    -
    -

    -These interfaces return information about the predicted and measured -performance for pStmt. Advanced applications can use this -interface to compare the predicted and the measured performance and -issue warnings and/or rerun ANALYZE if discrepancies are found.

    - -

    Since this interface is expected to be rarely used, it is only -available if SQLite is compiled using the SQLITE_ENABLE_STMT_SCANSTATUS -compile-time option.

    - -

    The "iScanStatusOp" parameter determines which status information to return. -The "iScanStatusOp" must be one of the scanstatus options or the behavior -of this interface is undefined. The requested measurement is written into -a variable pointed to by the "pOut" parameter.

    - -

    The "flags" parameter must be passed a mask of flags. At present only -one flag is defined - SQLITE_SCANSTAT_COMPLEX. If SQLITE_SCANSTAT_COMPLEX -is specified, then status information is available for all elements -of a query plan that are reported by "EXPLAIN QUERY PLAN" output. If -SQLITE_SCANSTAT_COMPLEX is not specified, then only query plan elements -that correspond to query loops (the "SCAN..." and "SEARCH..." elements of -the EXPLAIN QUERY PLAN output) are available. Invoking API -sqlite3_stmt_scanstatus() is equivalent to calling -sqlite3_stmt_scanstatus_v2() with a zeroed flags parameter.

    - -

    Parameter "idx" identifies the specific query element to retrieve statistics -for. Query elements are numbered starting from zero. A value of -1 may be -to query for statistics regarding the entire query. If idx is out of range -- less than -1 or greater than or equal to the total number of query -elements used to implement the statement - a non-zero value is returned and -the variable that pOut points to is unchanged.

    - -

    See also: sqlite3_stmt_scanstatus_reset()


    Add Content To A Dynamic String

    @@ -10582,56 +9932,14 @@ and extensions to compare the contents of two buffers containing UTF-8 strings in a case-independent fashion, using the same definition of "case independence" that SQLite uses internally when comparing identifiers. -


    -

    Total Number Of Rows Modified

    - -
    -int sqlite3_total_changes(sqlite3*);
    -sqlite3_int64 sqlite3_total_changes64(sqlite3*);
    -
    -

    -These functions return the total number of rows inserted, modified or -deleted by all INSERT, UPDATE or DELETE statements completed -since the database connection was opened, including those executed as -part of trigger programs. The two functions are identical except for the -type of the return value and that if the number of rows modified by the -connection exceeds the maximum value supported by type "int", then -the return value of sqlite3_total_changes() is undefined. Executing -any other type of SQL statement does not affect the value returned by -sqlite3_total_changes().

    - -

    Changes made as part of foreign key actions are included in the -count, but those made as part of REPLACE constraint resolution are -not. Changes to a view that are intercepted by INSTEAD OF triggers -are not counted.

    - -

    The sqlite3_total_changes(D) interface only reports the number -of rows that changed due to SQL statement run against database -connection D. Any changes by other database connections are ignored. -To detect changes against a database file from other database -connections use the PRAGMA data_version command or the -SQLITE_FCNTL_DATA_VERSION file control.

    - -

    If a separate thread makes changes on the same database connection -while sqlite3_total_changes() is running then the value -returned is unpredictable and not meaningful.

    - -

    See also: -


    Obtain Values For URI Parameters

    -const char *sqlite3_uri_parameter(sqlite3_filename z, const char *zParam);
    -int sqlite3_uri_boolean(sqlite3_filename z, const char *zParam, int bDefault);
    -sqlite3_int64 sqlite3_uri_int64(sqlite3_filename, const char*, sqlite3_int64);
    -const char *sqlite3_uri_key(sqlite3_filename z, int N);
    +const char *sqlite3_uri_parameter(const char *zFilename, const char *zParam);
    +int sqlite3_uri_boolean(const char *zFile, const char *zParam, int bDefault);
    +sqlite3_int64 sqlite3_uri_int64(const char*, const char*, sqlite3_int64);
    +const char *sqlite3_uri_key(const char *zFilename, int N);
     

    These are utility routines, useful to custom VFS implementations, @@ -10852,8 +10160,7 @@ object D and returns a pointer to that copy. The sqlite3_value returned is a protected sqlite3_value object even if the input is not. The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a -memory allocation fails. If V is a pointer value, then the result -of sqlite3_value_dup(V) is a NULL value.

    +memory allocation fails.

    The sqlite3_value_free(V) interface frees an sqlite3_value object previously obtained from sqlite3_value_dup(). If V is a NULL pointer @@ -10892,55 +10199,6 @@

    Unregister a VFS with the sqlite3_vfs_unregister() interface. If the default VFS is unregistered, another VFS is chosen as the default. The choice for the new VFS is arbitrary. -


    -

    Find all elements on the right-hand side of an IN constraint.

    - -
    -int sqlite3_vtab_in_first(sqlite3_value *pVal, sqlite3_value **ppOut);
    -int sqlite3_vtab_in_next(sqlite3_value *pVal, sqlite3_value **ppOut);
    -
    -

    -These interfaces are only useful from within the -xFilter() method of a virtual table implementation. -The result of invoking these interfaces from any other context -is undefined and probably harmful.

    - -

    The X parameter in a call to sqlite3_vtab_in_first(X,P) or -sqlite3_vtab_in_next(X,P) should be one of the parameters to the -xFilter method which invokes these routines, and specifically -a parameter that was previously selected for all-at-once IN constraint -processing use the sqlite3_vtab_in() interface in the -xBestIndex method. If the X parameter is not -an xFilter argument that was selected for all-at-once IN constraint -processing, then these routines return SQLITE_ERROR.

    - -

    Use these routines to access all values on the right-hand side -of the IN constraint using code like the following:

    - -

    -   for(rc=sqlite3_vtab_in_first(pList, &pVal);
    -       rc==SQLITE_OK && pVal;
    -       rc=sqlite3_vtab_in_next(pList, &pVal)
    -   ){
    -     // do something with pVal
    -   }
    -   if( rc!=SQLITE_OK ){
    -     // an error has occurred
    -   }
    -

    - -

    On success, the sqlite3_vtab_in_first(X,P) and sqlite3_vtab_in_next(X,P) -routines return SQLITE_OK and set *P to point to the first or next value -on the RHS of the IN constraint. If there are no more values on the -right hand side of the IN constraint, then *P is set to NULL and these -routines return SQLITE_DONE. The return value might be -some other value, such as SQLITE_NOMEM, in the event of a malfunction.

    - -

    The *ppOut values returned by these routines are only valid until the -next call to either of these routines or until the end of the xFilter -method from which these routines were called. If the virtual table -implementation needs to retain the *ppOut values for longer, it must make -copies. The *ppOut values are protected.


    Win32 Specific Interface

    @@ -11553,10 +10811,6 @@ even empty strings, are always zero-terminated. The return value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer.

    -

    Strings returned by sqlite3_column_text16() always have the endianness -which is native to the platform, regardless of the text encoding set -for the database.

    -

    Warning: The object returned by sqlite3_column_value() is an unprotected sqlite3_value object. In a multithreaded environment, an unprotected sqlite3_value object may only be used safely with @@ -11570,7 +10824,7 @@ application-defined SQL functions or virtual tables, not within top-level application code.

    -

    These routines may attempt to convert the datatype of the result. +

    The these routines may attempt to convert the datatype of the result. For example, if the internal representation is FLOAT and a text result is requested, sqlite3_snprintf() is used internally to perform the conversion automatically. The following table details the conversions @@ -11595,7 +10849,7 @@ TEXT BLOB No change BLOB INTEGER CAST to INTEGER BLOB FLOAT CAST to REAL - BLOB TEXT CAST to TEXT, ensure zero terminator + BLOB TEXT Add a zero terminator if needed

    @@ -11876,4 +11130,3 @@ statement in which the function is running.


    - diff -Nru sqlite3-3.42.0/www/carray.html sqlite3-3.44.0-0/www/carray.html --- sqlite3-3.42.0/www/carray.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/carray.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -144,9 +120,7 @@

    The carray() function was first added to SQLite in version 3.14 (2016-08-08). The sqlite3_carray_bind() interface and the single-argument variant of carray() was added in SQLite version 3.34.0 -(2020-12-01). The ability to bind an array of struct iovec -objects that are interpreted as BLOBs was added in SQLite version 3.41.0 -(2023-02-21). +(2020-12-01).

    3. Details

    @@ -166,25 +140,13 @@
  • 'int64'
  • 'double'
  • 'char*' -
  • 'struct iovec'
  • The default datatype is 'int32'. -

    The 'struct iovec' type used for BLOB data is a standard Posix data -structure, normally declared using "#include <sys/uio.h>". -The format is: - -

    -struct iovec {
    -  void  *iov_base; /* Starting address */
    -  size_t iov_len;  /* Number of bytes to transfer */
    -};
    -
    - -

    3.1. Single-Argument CARRAY

    +

    3.1. Single-Argument CARRAY

    The single-argument form of carray() requires a special C-language interface named "sqlite3_carray_bind()" in order to attach values: @@ -207,7 +169,6 @@ #define CARRAY_INT64 1 #define CARRAY_DOUBLE 2 #define CARRAY_TEXT 3 - #define CARRAY_BLOB 4

    Higher order bits of the mFlags parameter must all be zero for now, @@ -251,5 +212,4 @@

    SELECT * FROM obj WHERE rowid IN carray($PTR, 10);
     
    -

    This page last modified on 2023-02-17 13:24:09 UTC

    diff -Nru sqlite3-3.42.0/www/changes.html sqlite3-3.44.0-0/www/changes.html --- sqlite3-3.42.0/www/changes.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/changes.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Release History

    @@ -129,538 +105,6 @@ See the chronology a succinct listing of releases.

    - -

    2023-05-16 (3.42.0)

      -
    1. Add the FTS5 secure-delete command. This option causes all forensic traces - to be removed from the FTS5 inverted index when content is deleted. -
    2. Enhance the JSON SQL functions to support JSON5 extensions. -
    3. The SQLITE_CONFIG_LOG and SQLITE_CONFIG_PCACHE_HDRSZ calls to sqlite3_config() - are now allowed to occur after sqlite3_initialize(). -
    4. New sqlite3_db_config() options: SQLITE_DBCONFIG_STMT_SCANSTATUS and - SQLITE_DBCONFIG_REVERSE_SCANORDER. -
    5. Query planner improvements: -
        -
      1. Enable the "count-of-view" optimization by default. -
      2. Avoid computing unused columns in subqueries. -
      3. Improvements to the push-down optimization. -
      -
    6. Enhancements to the CLI: -
        -
      1. Add the --unsafe-testing command-line option. Without this option, some - dot-commands (ex: ".testctrl") are now disabled because those commands - that are intended for testing only and can cause malfunctions misused. -
      2. Allow commands ".log on" and ".log off", even in --safe mode. -
      3. "--" as a command-line argument means all subsequent arguments that - start with "-" are interpreted as normal non-option argument. -
      4. Magic parameters ":inf" and ":nan" bind to floating point literals - Infinity and NaN, respectively. -
      5. The --utf8 command-line option omits all translation to or from - MBCS on the Windows console for interactive sessions, and sets - the console code page for UTF-8 I/O during such sessions. - The --utf8 option is a no-op on all other platforms. -
      -
    7. Add the ability for application-defined SQL functions to have the same name - as join keywords: CROSS, FULL, INNER, LEFT, NATURAL, OUTER, or RIGHT. -
    8. Enhancements to PRAGMA integrity_check: -
        -
      1. Detect and raise an error when a NaN value is stored in a NOT NULL column. -
      2. Improved error message output identifies the root page of a b-tree when - an error is found within a b-tree. -
      -
    9. Allow the session extension to be configured to capture changes from - tables that lack an explicit ROWID. -
    10. Added the subsecond modifier to the date and time functions. -
    11. Negative values passed into sqlite3_sleep() are henceforth interpreted as 0. -
    12. The maximum recursion depth for JSON arrays and objects is lowered from 2000 - to 1000. -
    13. Extended the built-in printf() function so the comma option now works with - floating-point conversions in addition to integer conversions. -
    14. Miscellaneous bug fixes and performance optimizations -

      Hashes: -

    15. SQLITE_SOURCE_ID: 2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0 -
    16. SHA3-256 for sqlite3.c: 6aa3fadf000000625353bbaa1e83af114c40c240a0aa5a2c1c2aabcfc28d4f92 - -

    - -

    2023-03-22 (3.41.2)

      -
    1. Multiple fixes for reads past the end of memory buffers - (NB: reads not writes) in the following circumstances: -
        -
      1. When processing a corrupt database file using the non-standard - SQLITE_ENABLE_STAT4 compile-time option. -
      2. In the CLI when the sqlite3_error_offset() routine returns an out-of-range value - (see also the fix to sqlite3_error_offset() below). -
      3. In the recovery extension. -
      4. In FTS3 when processing a corrupt database file. -
      -
    2. Fix the sqlite3_error_offset() so that it does not return out-of-range values when - reporting errors associated with generated columns. -
    3. Multiple fixes in the query optimizer for problems that cause incorrect - results for bizarre, fuzzer-generated queries. -
    4. Increase the size of the reference counter in the page cache object to 64 bits to - ensure that the counter never overflows. -
    5. Fix a performance regression caused by a bug fix in patch release 3.41.1. -
    6. Fix a few incorrect assert() statements. -

      Hashes: -

    7. SQLITE_SOURCE_ID: 2023-03-22 11:56:21 0d1fc92f94cb6b76bffe3ec34d69cffde2924203304e8ffc4155597af0c191da -
    8. SHA3-256 for sqlite3.c: c83f68b7aac1e7d3ed0fcdb9857742f024449e1300bfb3375131a6180b36cf7c - -

    - -

    2023-03-10 (3.41.1)

      -
    1. Provide compile-time options -DHAVE_LOG2=0 and -DHAVE_LOG10=0 to enable SQLite to be - compiled on systems that omit the standard library functions log2() and log10(), repectively. -
    2. Ensure that the datatype for column t1.x in - "CREATE TABLE t1 AS SELECT CAST(7 AS INT) AS x;" continues to be INT and is not NUM, - for historical compatibility. -
    3. Enhance PRAGMA integrity_check to detect when extra bytes appear at the end of an - index record. -
    4. Fix various obscure bugs reported by the user community. See the - timeline of changes - for details. - -

      Hashes: -

    5. SQLITE_SOURCE_ID: 2023-03-10 12:13:52 20399f3eda5ec249d147ba9e48da6e87f969d7966a9a896764ca437ff7e737ff -
    6. SHA3-256 for sqlite3.c: d0d9db8425570f4a57def04fb8f4ac84f5c3e4e71d3d4d10472e3639c5fdf09f - -

    - -

    2023-02-21 (3.41.0)

      -
    1. Query planner improvements: -
        -
      1. Make use of indexed expressions within an aggregate query that - includes a GROUP BY clause. -
      2. The query planner has improved awareness of when an index is - a covering index and adjusts predicted runtimes accordingly. -
      3. The query planner is more aggressive about using co-routines rather - than materializing subqueries and views. -
      4. Queries against the built-in table-valued functions json_tree() and - json_each() will now usually treat "ORDER BY rowid" as a no-op. -
      5. Enhance the ability of the query planner to use indexed expressions - even if the expression has been modified by the - constant-propagation optimization. - (See forum thread 0a539c7.) -
      -
    2. Add the built-in unhex() SQL function. -
    3. Add the base64 and base85 application-defined functions as an extension and - include that extension in the CLI. -
    4. Add the sqlite3_stmt_scanstatus_v2() interface. (This interface is only - available if SQLite is compiled using SQLITE_ENABLE_STMT_SCANSTATUS.) -
    5. In-memory databases created using sqlite3_deserialize() now report their - filename as an empty string, not as 'x'. -
    6. Changes to the CLI: -
        -
      1. Add the new base64() and base85() SQL functions -
      2. Enhanced EXPLAIN QUERY PLAN output using the new sqlite3_stmt_scanstatus_v2() - interface when compiled using SQLITE_ENABLE_STMT_SCANSTATUS. -
      3. The ".scanstats est" command provides query planner estimates in profiles. -
      4. The continuation prompt indicates if the input is currently inside of a - string literal, identifier literal, comment, trigger definition, etc. -
      5. Enhance the --safe command-line option to disallow dangerous SQL functions. -
      6. The double-quoted string misfeature is now disabled by default for CLI - builds. Legacy use cases can reenable the misfeature at run-time using - the ".dbconfig dqs_dml on" and ".dbconfig dqs_ddl on" - commands. -
      -
    7. Enhance the PRAGMA integrity_check command so that it detects when text strings in - a table are equivalent to but not byte-for-byte identical to the same strings in the index. -
    8. Enhance the carray table-valued function so that it is able to bind an array of - BLOB objects. -
    9. Added the sqlite3_is_interrupted() interface. -
    10. Long-running calls to sqlite3_prepare() and similar now invoke the - progress handler callback and react to sqlite3_interrupt(). -
    11. The sqlite3_vtab_in_first() and sqlite3_vtab_in_next() functions are enhanced so that - they reliably detect if they are invoked on a parameter that was not selected for - multi-value IN processing using sqlite3_vtab_in(). - They return SQLITE_ERROR instead of SQLITE_MISUSE in this case. -
    12. The parser now ignores excess parentheses around a subquery on the right-hand side - of an IN operator, so that SQLite now works the same as PostgreSQL in this regard. - Formerly, SQLite treated the subquery as an expression with an implied "LIMIT 1". -
    13. Added the SQLITE_FCNTL_RESET_CACHE option to the sqlite3_file_control() API. -
    14. Makefile improvements: -
        -
      1. The new makefile target "sqlite3r.c" builds an amalgamation that includes - the recovery extension. -
      2. New makefile targets "devtest" and "releasetest" for running a - quick developmental test prior to doing a check-in and for doing a full - release test, respectively. -
      -
    15. Miscellaneous performance enhancements. -

      Hashes: -

    16. SQLITE_SOURCE_ID: 2023-02-21 18:09:37 05941c2a04037fc3ed2ffae11f5d2260706f89431f463518740f72ada350866d -
    17. SHA3-256 for sqlite3.c: 02bd9e678460946810801565667fdb8f0c29c78e51240512d2e5bb3dbdee7464 - -

    - -

    2022-12-28 (3.40.1)

      -
    1. Fix the --safe command-line option to the CLI - such that it correctly disallows the - use of SQL functions like writefile() that can cause harmful side-effects. -
    2. Fix a potential infinite loop in the memsys5 alternative memory allocator. This - bug was introduced by a performance optimization in version 3.39.0. -
    3. Various other obscure fixes. -

      Hashes: -

    4. SQLITE_SOURCE_ID: 2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f38a24 -
    5. SHA3-256 for sqlite3.c: 4d6800e9032ff349376fe612e422b49ba5eb4e378fac0b3e405235d09dd366ab - -

    - -

    2022-11-16 (3.40.0)

      -
    1. Add support for compiling SQLite to WASM - and running it in web browsers. NB: The WASM build and its interfaces - are considered "beta" and are subject to minor changes if the need - arises. We anticipate finalizing the interface for the next release. -
    2. Add the recovery extension that might be able to recover some content - from a corrupt database file. -
    3. Query planner enhancements: -
        -
      1. Recognize covering indexes on tables with more than 63 columns where - columns beyond the 63rd column are used in the query and/or are - referenced by the index. -
      2. Extract the values of expressions contained within expression indexes - where practical, rather than recomputing the expression. -
      3. The NOT NULL and IS NULL operators (and their equivalents) avoid - loading the content of large strings and BLOB values from disk. -
      4. Avoid materializing a view on which a full scan is performed - exactly once. Use and discard the rows of the view as they are computed. -
      5. Allow flattening of a subquery that is the right-hand operand of - a LEFT JOIN in an aggregate query. -
      -
    4. A new typedef named sqlite3_filename is added and used to represent - the name of a database file. Various interfaces are - modified to use the new typedef instead of "char*". This interface - change should be fully backwards compatible, though it might cause - (harmless) compiler warnings when rebuilding some legacy applications. -
    5. Add the sqlite3_value_encoding() interface. -
    6. Security enhancement: SQLITE_DBCONFIG_DEFENSIVE is augmented to prohibit - changing the schema_version. The schema_version - becomes read-only in defensive mode. -
    7. Enhancements to the PRAGMA integrity_check statement: -
        -
      1. Columns in non-STRICT tables with TEXT affinity should not contain numeric values. -
      2. Columns in non-STRICT tables with NUMERIC affinity should not - contain TEXT values that could be converted into numbers. -
      3. Verify that the rows of a WITHOUT ROWID table are in the correct order. -
      -
    8. Enhance the VACUUM INTO statement so that it honors the - PRAGMA synchronous setting. -
    9. Enhance the sqlite3_strglob() and sqlite3_strlike() APIs so that they are able - to accept NULL pointers for their string parameters and still generate a sensible - result. -
    10. Provide the new SQLITE_MAX_ALLOCATION_SIZE compile-time option for limiting - the size of memory allocations. -
    11. Change the algorithm used by SQLite's built-in pseudo-random number generator (PRNG) - from RC4 to Chacha20. -
    12. Allow two or more indexes to have the same name as long as they are all in - separate schemas. -
    13. Miscellaneous performance optimizations result in about 1% fewer CPU cycles - used on typical workloads. -

      Hashes: -

    14. SQLITE_SOURCE_ID: 2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318 -
    15. SHA3-256 for sqlite3.c: ab8da6bc754642989e67d581f26683dc705b068cea671970f0a7d32cfacbad19 - -

    - -

    2022-09-29 (3.39.4)

      -
    1. Fix the build on Windows so that it works with -DSQLITE_OMIT_AUTOINIT -
    2. Fix a long-standing problem in the btree balancer that might, in rare cases, - cause database corruption if the application uses an - application-defined page cache. -
    3. Enhance SQLITE_DBCONFIG_DEFENSIVE so that it disallows CREATE TRIGGER - statements if one or more of the statements in the body of the trigger write - into shadow tables. -
    4. Fix a possible integer overflow in the size computation for a memory allocation - in FTS3. -
    5. Fix a misuse of the sqlite3_set_auxdata() interface in the - ICU Extension. -

      Hashes: -

    6. SQLITE_SOURCE_ID: 2022-09-29 15:55:41 a29f9949895322123f7c38fbe94c649a9d6e6c9cd0c3b41c96d694552f26b309 -
    7. SHA3-256 for sqlite3.c: f65082298127e2ddae6539beb94f5204b591df64ba2c7da83c7d0faffd6959d8 - -

    - -

    2022-09-05 (3.39.3)

      -
    1. Use a statement journal on DML statement affecting two or more database - rows if the statement makes use of a SQL functions that might abort. See - forum thread 9b9e4716c0d7bbd1. -
    2. Use a mutex to protect the PRAGMA temp_store_directory and - PRAGMA data_store_directory statements, even though they are deprecated and - documented as not being threadsafe. See - forum post 719a11e1314d1c70. -
    3. Other bug and warning fixes. See the - timeline - for details. -

      Hashes: -

    4. SQLITE_SOURCE_ID: 2022-09-05 11:02:23 4635f4a69c8c2a8df242b384a992aea71224e39a2ccab42d8c0b0602f1e826e8 -
    5. SHA3-256 for sqlite3.c: 2fc273cf8032b601c9e06207efa0ae80eb73d5a1d283eb91096c815fa9640257 - -

    - -

    2022-07-21 (3.39.2)

      -
    1. Fix a performance regression in the query planner associated with rearranging - the order of FROM clause terms in the presences of a LEFT JOIN. -
    2. Apply fixes for CVE-2022-35737, Chromium bugs 1343348 and 1345947, - forum post 3607259d3c, and - other minor problems discovered by internal testing. -

      Hashes: -

    3. SQLITE_SOURCE_ID: 2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603 -
    4. SHA3-256 for sqlite3.c: bffbaafa94706f0ed234f183af3eb46e6485e7e2c75983173ded76e0da805f11 - -

    - -

    2022-07-13 (3.39.1)

      -
    1. Fix an incorrect result from a query that uses a view that contains a compound - SELECT in which only one arm contains a RIGHT JOIN and where the view is not - the first FROM clause term of the query that contains the view. - forum post 174afeae5734d42d. -
    2. Fix some harmless compiler warnings. -
    3. Fix a long-standing problem with ALTER TABLE RENAME that can only arise - if the sqlite3_limit(SQLITE_LIMIT_SQL_LENGTH) is set to a very small value. -
    4. Fix a long-standing problem in FTS3 that can only arise when compiled with - the SQLITE_ENABLE_FTS3_PARENTHESIS compile-time option. -
    5. Fix the build so that is works when the SQLITE_DEBUG and - SQLITE_OMIT_WINDOWFUNC compile-time options are both provided at the - same time. -
    6. Fix the initial-prefix optimization for the REGEXP extension so that it works - correctly even if the prefix contains characters that require a 3-byte UTF8 - encoding. -
    7. Enhance the sqlite_stmt virtual table so that it buffers all of its output. -

      Hashes: -

    8. SQLITE_SOURCE_ID: 2022-07-13 19:41:41 7c16541a0efb3985578181171c9f2bb3fdc4bad6a2ec85c6e31ab96f3eff201f -
    9. SHA3-256 for sqlite3.c: 6d13fcf1c31133da541d1eb8a83552d746f39b81a0657bd4077fed0221749511 - -

    - -

    2022-06-25 (3.39.0)

      -
    1. Add (long overdue) support for RIGHT and FULL OUTER JOIN. -
    2. Add new binary comparison operators IS NOT DISTINCT FROM and IS DISTINCT FROM - that are equivalent to IS and IS NOT, respective, for compatibility with - PostgreSQL and SQL standards. -
    3. Add a new return code (value "3") from the sqlite3_vtab_distinct() - interface that indicates a query that has both DISTINCT and ORDER BY - clauses. -
    4. Added the sqlite3_db_name() interface. -
    5. The unix os interface resolves all symbolic links in database - filenames to create a canonical name for the database before the - file is opened. - If the SQLITE_OPEN_NOFOLLOW flag is used with sqlite3_open_v2() - or similar, the open will fail if any element of the path is a - symbolic link. -
    6. Defer materializing views until the materialization - is actually needed, thus avoiding unnecessary work if the materialization turns - out to never be used. -
    7. The HAVING clause of a SELECT statement is now allowed on any aggregate query, - even queries that do not have a GROUP BY clause. -
    8. Many microoptimizations collectively reduce CPU cycles by about 2.3%. -

      Hashes: -

    9. SQLITE_SOURCE_ID: 2022-06-25 14:57:57 14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918 -
    10. SHA3-256 for sqlite3.c: d9c439cacad5e4992d0d25989cfd27a4c4f59a3183c97873bc03f0ad1aa78b7a - -

    - -

    2022-05-06 (3.38.5)

      -
    1. Fix a blunder in the CLI of the 3.38.4 release. - -

      Hashes: -

    2. SQLITE_SOURCE_ID: 2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe -
    3. SHA3-256 for sqlite3.c: b05ef42ed234009b4b3dfb36c5f5ccf6d728da80f25ee560291269cf6cfe635f - -

    - -

    2022-05-04 (3.38.4)

      -
    1. Fix a byte-code problem in the Bloom filter pull-down optimization added by release - 3.38.0 in which an error in the byte code causes the byte code engine to enter an - infinite loop when the pull-down optimization encounters a NULL key. - Forum thread 2482b32700384a0f. -
    2. Other minor patches. See the - timeline for - details. - -

      Hashes: -

    3. SQLITE_SOURCE_ID: 2022-05-04 15:45:55 d402f49871152670a62f4f28cacb15d814f2c1644e9347ad7d258e562978e45e -
    4. SHA3-256 for sqlite3.c: e6a50effb021858c200e885664611ed3c5e949413ff2dca452ac7ee336b9de1d - -

    - -

    2022-04-27 (3.38.3)

      -
    1. Fix a case of the query planner be overly aggressive with optimizing automatic-index - and Bloom-filter construction, using inappropriate ON clause terms to restrict the - size of the automatic-index or Bloom filter, and resulting in missing rows in the - output. - Forum thread 0d3200f4f3bcd3a3. -
    2. Other minor patches. See the - timeline for - details. - -

      Hashes: -

    3. SQLITE_SOURCE_ID: 2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4 -
    4. SHA3-256 for sqlite3.c: d4d66feffad66ea82073fbb97ae9c84e3615887ebc5168226ccee28d82424517 - -

    - -

    2022-03-26 (3.38.2)

      -
    1. Fix a user-discovered problem with the new Bloom filter optimization - that might cause an incorrect answer when doing a LEFT JOIN with a WHERE - clause constraint that says that one of the columns on the right table of - the LEFT JOIN is NULL. See - forum thread 031e262a89b6a9d2. -
    2. Other minor patches. See the - timeline for - details. - -

      Hashes: -

    3. SQLITE_SOURCE_ID: 2022-03-26 13:51:10 d33c709cc0af66bc5b6dc6216eba9f1f0b40960b9ae83694c986fbf4c1d6f08f -
    4. SHA3-256 for sqlite3.c: 0fbac6b6999f894184899431fb77b9792324c61246b2a010d736694ccaa6d613 - -

    - -

    2022-03-12 (3.38.1)

      -
    1. Fix problems with the new Bloom filter optimization that might cause - some obscure queries to get an incorrect answer. -
    2. Fix the localtime modifier of the date and time functions so that - it preserves fractional seconds. -
    3. Fix the sqlite_offset SQL function so that it works correctly even - in corner cases such as when the argument is a virtual column or the - column of a view. -
    4. Fix row value IN operator constraints on virtual tables so that they - work correctly even if the virtual table implementation relies on bytecode - to filter rows that do not satisfy the constraint. -
    5. Other minor fixes to assert() statements, test cases, and documentation. - See the source code timeline - for details. - -

      Hashes: -

    6. SQLITE_SOURCE_ID: 2022-03-12 13:37:29 38c210fdd258658321c85ec9c01a072fda3ada94540e3239d29b34dc547a8cbc -
    7. SHA3-256 for sqlite3.c: 262ba071e960a8a0a6ce39307ae30244a2b0dc9fe1c4c09d0e1070d4353cd92c - -

    - -

    2022-02-22 (3.38.0)

      -
    1. Added the -> and ->> operators for easier processing of JSON. - The new operators are compatible with MySQL and PostgreSQL. -
    2. The JSON functions are now built-ins. It is no longer necessary - to use the -DSQLITE_ENABLE_JSON1 compile-time option to enable JSON - support. JSON is on by default. Disable the JSON interface using - the new -DSQLITE_OMIT_JSON compile-time option. -
    3. Enhancements to date and time functions: -
        -
      1. Added the unixepoch() function. -
      2. Added the auto modifier and the julianday modifier. -
      -
    4. Rename the printf() SQL function to format() for better - compatibility. The original printf() name is retained as an alias - for backwards compatibility. -
    5. Added the sqlite3_error_offset() interface, which can sometimes - help to localize an SQL error to a specific character in the input - SQL text, so that applications can provide better error messages. -
    6. Enhanced the interface to virtual tables as follows: -
        -
      1. Added the sqlite3_vtab_distinct() interface. -
      2. Added the sqlite3_vtab_rhs_value() interface. -
      3. Added new operator types SQLITE_INDEX_CONSTRAINT_LIMIT - and SQLITE_INDEX_CONSTRAINT_OFFSET. -
      4. Added the sqlite3_vtab_in() interface (and related) to enable - a virtual table to process IN operator constraints all at once, - rather than processing each value of the right-hand side of the - IN operator separately. -
      -
    7. CLI enhancements: -
        -
      1. Columnar output modes are enhanced to correctly handle tabs - and newlines embedded in text. -
      2. Added options like "--wrap N", "--wordwrap on", and "--quote" - to the columnar output modes. -
      3. Added the .mode qbox alias. -
      4. The .import command automatically disambiguates column names. -
      5. Use the new sqlite3_error_offset() interface to provide better - error messages. -
      -
    8. Query planner enhancements: -
        -
      1. Use a Bloom filter to speed up large analytic queries. -
      2. Use a balanced merge tree to evaluate UNION or UNION ALL - compound SELECT statements that have an ORDER BY clause. -
      -
    9. The ALTER TABLE statement is changed to silently ignores entries in the - sqlite_schema table that do not parse when PRAGMA writable_schema=ON. -

      Hashes: -

    10. SQLITE_SOURCE_ID: 2022-02-22 18:58:40 40fa792d359f84c3b9e9d6623743e1a59826274e221df1bde8f47086968a1bab - -
    11. SHA3-256 for sqlite3.c: a69af0a88d59271a2dd3c846a3e93cbd29e7c499864f6c0462a3b4160bee1762 - -

    - -

    2022-01-06 (3.37.2)

      -
    1. Fix a bug introduced - in version 3.35.0 (2021-03-12) that - can cause database corruption - if a SAVEPOINT is rolled back while in PRAGMA temp_store=MEMORY mode, - and other changes are made, and then the outer transaction commits. - Check-in 73c2b50211d3ae26 -
    2. Fix a long-standing problem with ON DELETE CASCADE and ON UPDATE CASCADE - in which a cache of the bytecode used to implement the cascading change - was not being reset following a local DDL change. - Check-in 5232c9777fe4fb13. -
    3. Other minor fixes that should not impact production builds. - -

      Hashes: -

    4. SQLITE_SOURCE_ID: 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5d17a0 -
    5. SHA3-256 for sqlite3.c: 1bb01c382295cba85ec4685cedc52a7477cdae71cc37f1ad0f48719a17af1e1e - -

    - -

    2021-12-30 (3.37.1)

      -
    1. Fix a bug introduced by the UPSERT enhancements of version 3.35.0 that - can cause incorrect byte-code to be generated for some obscure but valid - SQL, possibly resulting in a NULL-pointer dereference. -
    2. Fix an OOB read that can occur in FTS5 when reading corrupt database files. -
    3. Improved robustness of the --safe option in the CLI. -
    4. Other minor fixes to assert() statements and test cases. - -

      Hashes: -

    5. SQLITE_SOURCE_ID: 2021-12-30 15:30:28 378629bf2ea546f73eee84063c5358439a12f7300e433f18c9e1bddd948dea62 -
    6. SHA3-256 for sqlite3.c: 915afb3f29c2d217ea0c283326a9df7d505e6c73b40236f0b33ded91f812d174 - -

    - -

    2021-11-27 (3.37.0)

      -
    1. STRICT tables provide a prescriptive style of data type management, - for developers who prefer that kind of thing. -
    2. When adding columns that contain a - CHECK constraint or a generated column containing a NOT NULL constraint, - the ALTER TABLE ADD COLUMN now checks new constraints against - preexisting rows in the database and will only proceed if no constraints - are violated. -
    3. Added the PRAGMA table_list statement. -
    4. CLI enhancements: -
        -
      1. Add the .connection command, allowing the CLI to keep multiple database - connections open at the same time. -
      2. Add the --safe command-line option that disables - dot-commands and SQL statements that might cause side-effects that extend - beyond the single database file named on the command-line. -
      3. Performance improvements when reading SQL statements - that span many lines. -
      -
    5. Added the sqlite3_autovacuum_pages() interface. -
    6. The sqlite3_deserialize() does not and has never worked for the TEMP - database. That limitation is now noted in the documentation. -
    7. The query planner now omits ORDER BY clauses on subqueries and views - if removing those clauses does not change the semantics of the query. -
    8. The generate_series table-valued function extension is modified so that - the first parameter ("START") is now required. This is done as a way to - demonstrate how to write table-valued functions with required parameters. - The legacy behavior is available using the -DZERO_ARGUMENT_GENERATE_SERIES - compile-time option. -
    9. Added new sqlite3_changes64() and sqlite3_total_changes64() interfaces. -
    10. Added the SQLITE_OPEN_EXRESCODE flag option to sqlite3_open_v2(). -
    11. Use less memory to hold the database schema. - -

      Hashes: -

    12. SQLITE_SOURCE_ID: 2021-11-27 14:13:22 bd41822c7424d393a30e92ff6cb254d25c26769889c1499a18a0b9339f5d6c8a -
    13. SHA3-256 for sqlite3.c: a202a950ab401cda052e81259e96d6e64ad91faaaaf5690d769f64c2ab962f27 - -

    2021-06-18 (3.36.0)

    1. Improvement to the EXPLAIN QUERY PLAN output to make it easier to @@ -673,7 +117,7 @@ the legacy behavior for applications that need it.
    2. The sqlite3_deserialize() and sqlite3_serialize() interfaces are now enabled by default. The -DSQLITE_ENABLE_DESERIALIZE compile-time option is - no longer required. Instead, there is a new -DSQLITE_OMIT_DESERIALIZE + no longer required. Instead, there is is a new -DSQLITE_OMIT_DESERIALIZE compile-time option to omit those interfaces.
    3. The "memdb" VFS now allows the same in-memory database to be shared among multiple database connections in the same process as long as the @@ -686,6 +130,7 @@
    4. The REGEXP extension is now included in CLI builds. +

      Hashes:

    5. SQLITE_SOURCE_ID: 2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5
    6. SHA3-256 for sqlite3.c: 2a8e87aaa414ac2d45ace8eb74e710935423607a8de0fafcb36bbde5b952d157 @@ -704,7 +149,7 @@

    2021-04-02 (3.35.4)

      -
    1. Fix a defect in the query planner optimization identified by +
    2. Fix a defect in the query planner optimization identified by item 8b above. Ticket de7db14784a08053.
    3. Fix a defect in the new RETURNING syntax. Ticket @@ -736,7 +181,7 @@ Forum post aa5a0431c99e.
    4. Fix some incorrect assert() statements.
    5. Fix to the SELECT statement syntax diagram so that the FROM clause - syntax is shown correctly. + syntax is shown correctly. Forum post 9ed02582fe.
    6. Fix the EBCDIC character classifier so that it understands newlines as whitespace. Forum post 58540ce22dcd. @@ -752,8 +197,8 @@

    2021-03-17 (3.35.2)

      -
    1. Fix a problem in the - appendvfs.c +
    2. Fix a problem in the + appendvfs.c extension that was introduced into version 3.35.0.
    3. Ensure that date/time functions with no arguments (which generate responses that depend on the current time) are treated as @@ -808,7 +253,7 @@
    4. Query planner/optimizer improvements:
      1. Enhancements to the min/max optimization so that it works better - with the IN operator and the OP_SeekScan optimization of the + with the IN operator and the OP_SeekScan optimization of the previous release.
      2. Attempt to process EXISTS operators in the WHERE clause as if they were IN operators, in cases where this is a valid transformation @@ -891,10 +336,10 @@
      3. Query planner improvements:
        1. Improved estimates for the cost of running a DISTINCT operator. -
        2. When doing an UPDATE or DELETE using a multi-column index where - only a few of the earlier columns of the index are useful for the - index lookup, postpone doing the main table seek until after all - WHERE clause constraints have been evaluated, in case those +
        3. When doing an UPDATE or DELETE using a multi-column index where + only a few of the earlier columns of the index are useful for the + index lookup, postpone doing the main table seek until after all + WHERE clause constraints have been evaluated, in case those constraints can be covered by unused later terms of the index, thus avoiding unnecessary main table seeks.
        4. The new OP_SeekScan opcode is used to improve performance of @@ -1040,7 +485,7 @@

          2020-01-27 (3.31.1)

          1. Revert the data layout for an internal-use-only SQLite data structure. Applications that use SQLite should never reference internal SQLite - data structures, but some do anyhow, and a change to one such + data structures, but some do anyhow, and a change to one such data structure in 3.30.0 broke a popular and widely-deployed application. Reverting that change in SQLite, at least temporarily, gives developers of misbehaving applications time to fix their code. @@ -1100,7 +545,7 @@

            2019-10-10 (3.30.1)

            1. Fix a bug in the query flattener that might cause a segfault -for nested queries that use the new +for nested queries that use the new FILTER clause on aggregate functions. Ticket 1079ad19993d13fa
            2. Cherrypick fixes for other obscure problems found since the 3.30.0 @@ -1219,7 +664,7 @@ new --insert option that works like --update used to work.
          2. Added the fossildelta.c - extension that can create, apply, and deconstruct the + extension that can create, apply, and deconstruct the Fossil DVCS file delta format that is used by the RBU extension.
          3. Added the SQLITE_DBCONFIG_WRITABLE_SCHEMA verb for the sqlite3_db_config() @@ -1238,10 +683,10 @@ tokenizer method object even without the sqlite3_db_config(SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER) setting if the second argument is a bound parameter -
          +
      4. Improved robustness against corrupt database files.
      5. Miscellaneous performance enhancements -
      6. Established a Git mirror of the offical SQLite source tree. +
      7. Established a Git mirror of the offical SQLite source tree. The canonical sources for SQLite are maintained using the Fossil DVCS at https://sqlite.org/src. The Git mirror can be seen at https://github.com/sqlite/sqlite. @@ -1252,7 +697,7 @@

      2019-02-25 (3.27.2)

        -
      1. Fix a bug in the IN operator that was introduced by an +
      2. Fix a bug in the IN operator that was introduced by an attempted optimization in version 3.27.0. Ticket df46dfb631f75694
      3. Fix a bug causing a crash when a window function is misused. Ticket @@ -1278,7 +723,7 @@

        2019-02-07 (3.27.0)

        1. Added the VACUUM INTO command -
        2. Issue an SQLITE_WARNING message on the error log if a +
        3. Issue an SQLITE_WARNING message on the error log if a double-quoted string literal is used.
        4. The sqlite3_normalized_sql() interface works on any prepared statement created using sqlite3_prepare_v2() or sqlite3_prepare_v3(). It is no @@ -1304,15 +749,15 @@
        5. Enhancements to the CLI, mostly to support testing and debugging of the SQLite library itself:
            -
          1. Add support for ".open --hexdb". The - "dbtotxt" utility - program used to generate the text for the "hexdb" is added to the +
          2. Add support for ".open --hexdb". The + "dbtotxt" utility + program used to generate the text for the "hexdb" is added to the source tree.
          3. Add support for the "--maxsize N" option on ".open --deserialize".
          4. Add the "--memtrace" command-line option, to show all memory allocations and deallocations.
          5. Add the ".eqp trace" option on builds with SQLITE_DEBUG, to enable - bytecode program listing with indentation and + bytecode program listing with indentation and PRAGMA vdbe_trace all in one step.
          6. Add the ".progress" command for accessing the sqlite3_progress_handler() interface. @@ -1320,7 +765,7 @@
          7. Add options "--expanded", "--normalized", "--plain", "--profile", "--row", "--stmt", and "--close" to the ".trace" command.
          -
        6. Increased robustness against malicious SQL that is run against a +
        7. Increased robustness against malicious SQL that is run against a maliciously corrupted database.

          Bug fixes:

        8. Do not use a partial index to do a table scan on an IN operator. @@ -1342,7 +787,7 @@ NULL value into a NOT NULL column even if the NOT NULL column has a default value of NULL. Ticket e6f1f2e34dceeb1ed6 -
        9. Fix a problem with the use of window functions used within +
        10. Fix a problem with the use of window functions used within correlated subqueries. Ticket d0866b26f83e9c55e3
        11. Fix the ALTER TABLE RENAME COLUMN command so that it works for tables @@ -1365,7 +810,7 @@
        12. Allow the xBestIndex() method of virtual table implementations to return SQLITE_CONSTRAINT to indicate that the proposed query plan is unusable and should not be given further consideration. -
        13. Added the SQLITE_DBCONFIG_DEFENSIVE option which disables the ability to +
        14. Added the SQLITE_DBCONFIG_DEFENSIVE option which disables the ability to create corrupt database files using ordinary SQL.
        15. Added support for read-only shadow tables when the SQLITE_DBCONFIG_DEFENSIVE option is enabled. @@ -1401,10 +846,10 @@
      4. Enhancements to the session extension:
          -
        1. Added the SQLITE_CHANGESETAPPLY_INVERT flag +
        2. Added the SQLITE_CHANGESETAPPLY_INVERT flag
        3. Added the sqlite3changeset_start_v2() interface and the SQLITE_CHANGESETSTART_INVERT flag. -
        4. Added the +
        5. Added the changesetfuzz.c test-case generator utility.
        @@ -1457,7 +902,7 @@ updates a virtual table. The false-positive caused the ALTER TABLE to rollback, thus leaving the schema unchanged. Ticket b41031ea2b537237. -
      5. The fix in the 3.25.0 release for the endless-loop in the byte-code +
      6. The fix in the 3.25.0 release for the endless-loop in the byte-code associated with the ORDER BY LIMIT optimization did not work for some queries involving window functions. An additional correction is required. Ticket @@ -1545,7 +990,7 @@
      7. Added the SQLITE_DBCONFIG_RESET_DATABASE option to the sqlite3_db_config() API.

        CLI Enhancements: -

      8. Automatically intercepts the raw EXPLAIN QUERY PLAN +
      9. Automatically intercepts the raw EXPLAIN QUERY PLAN output and reformats it into an ASCII-art graph.
      10. Lines that begin with "#" and that are not in the middle of an SQL statement are interpreted as comments. @@ -1554,8 +999,8 @@

        Performance:

      11. UPDATE avoids unnecessary low-level disk writes when the contents of the database file do not actually change. - For example, "UPDATE t1 SET x=25 WHERE y=?" generates no extra - disk I/O if the value in column x is already 25. Similarly, + For example, "UPDATE t1 SET x=25 WHERE y=?" generates no extra + disk I/O if the value in column x is already 25. Similarly, when doing UPDATE on records that span multiple pages, only the subset of pages that actually change are written to disk. This is a low-level performance optimization only and does not @@ -1567,7 +1012,7 @@ LIMIT is small relative to the number of unrestricted output rows.
      12. The OR optimization is allowed to proceed even if the OR expression has also been converted into an IN - expression. Uses of the OR optimization are now also + expression. Uses of the OR optimization are now also more clearly shown in the EXPLAIN QUERY PLAN output.
      13. The query planner is more aggressive about using automatic indexes for views and subqueries for which it is @@ -1660,7 +1105,7 @@
      14. Fix the parser to accept valid row value syntax. Ticket 7310e2fb3d046a5
      15. Fix the query planner so that it takes into account dependencies in - the arguments to table-valued functions in subexpressions in + the arguments to table-valued functions in subexpressions in the WHERE clause. Ticket 80177f0c226ff54
      16. Fix incorrect result with complex OR-connected WHERE and STAT4. @@ -1721,7 +1166,7 @@

        2018-01-22 (3.22.0)

        1. The output of sqlite3_trace_v2() now shows each individual SQL statement run within a trigger. -
        2. Add the ability to read from WAL mode databases even if the application +
        3. Add the ability to read from WAL mode databases even if the application lacks write permission on the database and its containing directory, as long as the -shm and -wal files exist in that directory.
        4. Added the rtreecheck() scalar SQL function to the R-Tree extension. @@ -1731,7 +1176,7 @@
        5. Added support for the "^" initial token syntax in FTS5.
        6. New extensions:
            -
          1. The Zipfile virtual table can read and write a +
          2. The Zipfile virtual table can read and write a ZIP Archive.
          3. Added the fsdir(PATH) table-valued function to the fileio.c extension, @@ -1757,7 +1202,7 @@ set biases the decision toward the use of co-routines.
          4. The planner avoids query plans that use indexes with unknown collating functions. -
          5. The planner omits unused LEFT JOINs even if they are not the +
          6. The planner omits unused LEFT JOINs even if they are not the right-most joins of a query.
        7. Other performance optimizations: @@ -1779,12 +1224,12 @@
        8. Enhance the ".lint fkey-indexes" command so that it works with WITHOUT ROWID tables.
        9. If the filename argument to the shell is a ZIP archive rather than - an SQLite database, then the shell automatically opens that ZIP + an SQLite database, then the shell automatically opens that ZIP archive using the Zipfile virtual table.
        10. Added the edit() SQL function.
        11. Added the .excel command to simplify exporting database content to a spreadsheet. -
        12. Databases are opened using +
        13. Databases are opened using Append VFS when the --append flag is used on the command line or with the .open command. @@ -1821,7 +1266,7 @@

        2017-10-24 (3.21.0)

          -
        1. Take advantage of the atomic-write capabilities in the +
        2. Take advantage of the atomic-write capabilities in the F2FS filesystem when available, for greatly reduced transaction overhead. This currently requires the SQLITE_ENABLE_BATCH_ATOMIC_WRITE compile-time option. @@ -1857,7 +1302,7 @@
        3. Added the swarm virtual table to the existing union virtual table extension. -
        4. Added the +
        5. Added the sqlite_dbpage virtual table for providing direct access to pages of the database file. The source code is built into the amalgamation and @@ -1917,8 +1362,8 @@
        6. Update the text of error messages returned by sqlite3_errmsg() for some error codes.
        7. Add new pointer passing interfaces. -
        8. Backwards-incompatible changes to some extensions in order to take - advantage of the improved security offered by the new +
        9. Backwards-incompatible changes to some extensions in order to take + advantage of the improved security offered by the new pointer passing interfaces:
          1. Extending FTS5 → requires sqlite3_bind_pointer() to find @@ -1962,20 +1407,20 @@
          2. Query planner enhancements:
            1. When generating individual loops for each ORed term of an OR scan, - move any constant WHERE expressions outside of the loop, as is + move any constant WHERE expressions outside of the loop, as is done for top-level loops.
            2. The query planner examines the values of bound parameters to help determine if a partial index is usable. -
            3. When deciding between two plans with the same estimated cost, bias +
            4. When deciding between two plans with the same estimated cost, bias the selection toward the one that does not use the sorter.
            5. Evaluate WHERE clause constraints involving correlated subqueries last, in the hope that they never have be evaluated at all. -
            6. Do not use the flattening optimization for a sub-query on the RHS +
            7. Do not use the flattening optimization for a sub-query on the RHS of a LEFT JOIN if that subquery reads data from a virtual table as doing so prevents the query planner from creating automatic indexes on the results of the sub-query, which can slow down the query.
            -
          3. Add SQLITE_STMTSTATUS_REPREPARE, SQLITE_STMTSTATUS_RUN, +
          4. Add SQLITE_STMTSTATUS_REPREPARE, SQLITE_STMTSTATUS_RUN, and SQLITE_STMTSTATUS_MEMUSED options for the sqlite3_stmt_status() interface.
          5. Provide PRAGMA functions for @@ -1997,9 +1442,9 @@
          6. Fix the query planner so that it knows not to use automatic indexes on the right table of LEFT JOIN if the WHERE clause uses the IS operator. Fix for ce68383bf6aba. -
          7. Ensure that the query planner knows that any column of a - flattened LEFT JOIN can be NULL even - if that column is labeled with "NOT NULL". Fix for ticket +
          8. Ensure that the query planner knows that any column of a + flattened LEFT JOIN can be NULL even + if that column is labeled with "NOT NULL". Fix for ticket 892fc34f173e99d8.
          9. Fix rare false-positives in PRAGMA integrity_check when run on a database connection with attached databases. Ticket @@ -2124,10 +1569,10 @@ and the sqlite3_sourceid() C API and found in the SQLITE_SOURCE_ID macro is now a 64-digit SHA3-256 hash instead of a 40-digit SHA1 hash.
          10. Added the json_patch() SQL function to the JSON1 extension. -
          11. Enhance the LIKE optimization so that it works for arbitrary expressions on +
          12. Enhance the LIKE optimization so that it works for arbitrary expressions on the left-hand side as long as the LIKE pattern on the right-hand side does not begin with a digit or minus sign. -
          13. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in +
          14. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in the FTS3, FTS4, and FTS5 extensions to ensure that the sqlite3_last_insert_rowid() interface always returns reasonable values.
          15. Enhance PRAGMA integrity_check and PRAGMA quick_check so that they verify @@ -2138,7 +1583,7 @@ to put comma separators at the thousands marks for integers, if the "," format modifier is used in between the "%" and the "d" (example: "%,d").
          16. Added the -DSQLITE_MAX_MEMORY=N compile-time option. -
          17. Added the .sha3sum dot-command and the .selftest dot-command +
          18. Added the .sha3sum dot-command and the .selftest dot-command to the command-line shell
          19. Begin enforcing SQLITE_LIMIT_VDBE_OP. This can be used, for example, to prevent excessively large prepared statements in systems that accept SQL queries from @@ -2174,9 +1619,9 @@
        10. Add the SQLITE_DEFAULT_LOOKASIDE compile-time option.
        11. Increase the default lookaside - size from 512,125 to 1200,100 - as this provides better performance while only adding 56KB - of extra memory per connection. Memory-sensitive + size from 512,125 to 1200,100 + as this provides better performance while only adding 56KB + of extra memory per connection. Memory-sensitive applications can restore the old default at compile-time, start-time, or run-time.
        12. Use compiler built-ins __builtin_sub_overflow(), __builtin_add_overflow(), @@ -2202,12 +1647,12 @@ extension.
        13. In the command-line shell, enhance the ".mode" command so that it restores the default column and row separators for modes "line", - "list", "column", and "tcl". + "list", "column", and "tcl".
        14. Enhance the SQLITE_DIRECT_OVERFLOW_READ option so that it works in WAL mode as long as the pages being read are not in the WAL file. -
        15. Enhance the +
        16. Enhance the Lemon parser generator - so that it can store the parser object as a stack variable rather than + so that it can store the parser object as a stack variable rather than allocating space from the heap and make use of that enhancement in the amalgamation.
        17. Other performance improvements. Uses about 6.5% fewer CPU cycles. @@ -2230,7 +1675,7 @@

        2017-01-06 (3.16.2)

          -
        1. Fix the REPLACE statement for +
        2. Fix the REPLACE statement for WITHOUT ROWID tables that lack secondary indexes so that it works correctly with triggers and foreign keys. This was a new bug caused by performance optimizations added in version 3.16.0. @@ -2274,7 +1719,7 @@ for the full span of supported dates.
        3. Changed the default configuration of the lookaside memory allocator from 500 slots of 128 bytes each into 125 slots of 512 bytes each. -
        4. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if +
        5. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if the "x" column appears in a LIKE or GLOB operator.
        6. Enhanced sqlite3_interrupt() so that it interrupts checkpoint operations that are in process. @@ -2303,7 +1748,7 @@

          2016-11-28 (3.15.2)

          1. Multiple bug fixes to the row value logic that was introduced in version 3.15.0.
          2. Fix a NULL pointer dereference in ATTACH/DETACH following a maliciously constructed - syntax error. Ticket + syntax error. Ticket 2f1b168ab4d4844.
          3. Fix a crash that can occur following an out-of-memory condition in the built-in instr() function. @@ -2321,7 +1766,7 @@ than holding everything in memory, and possible causing an out-of-memory error for larger database files. This fixes an issue introduced by version 3.15.0. -
          4. Fix a case (present since 3.8.0 - 2013-08-26) +
          5. Fix a case (present since 3.8.0 - 2013-08-26) where OR-connected terms in the ON clause of a LEFT JOIN might cause incorrect results. Ticket 34a579141b2c5ac. @@ -2365,7 +1810,7 @@ table are initialized doing "Xfer Optimization" on "INSERT ... SELECT" statements. Fix for ticket 7b3328086a5c116c. -
          6. Make sure the ORDER BY LIMIT optimization +
          7. Make sure the ORDER BY LIMIT optimization (from check-in 559733b09e) works with IN operators on INTEGER PRIMARY KEYs. Fix for ticket 96c1454c @@ -2385,7 +1830,7 @@ that its input is not interactive.
          8. Correct affinity computations for a SELECT on the RHS of an IN operator. Fix for ticket 199df4168c. -
          9. The ORDER BY LIMIT optimization is not valid unless the inner-most IN operator +
          10. The ORDER BY LIMIT optimization is not valid unless the inner-most IN operator loop is actually used by the query plan. Fix for ticket 0c4df46116e90f92.
          11. Fix an internal code generator problem that was causing some DELETE operations @@ -2425,7 +1870,7 @@ SQLITE_OK_LOAD_PERMANENTLY return code from the extension entry point.
          12. Added the SQLITE_DBSTATUS_CACHE_USED_SHARED option to sqlite3_db_status(). -
          13. Add the +
          14. Add the vfsstat.c loadable extension - a VFS shim that measures I/O together with an eponymous virtual table that provides access to the measurements. @@ -2439,7 +1884,7 @@ eponymous virtual tables.
          15. Added the "win32-none" VFS, analogous to the "unix-none" VFS, that works like the default "win32" VFS except that it ignores all file locks. -
          16. The query planner uses a full scan of a partial index instead of a +
          17. The query planner uses a full scan of a partial index instead of a full scan of the main table, in cases where that makes sense.
          18. Allow table-valued functions to appear on the right-hand side of an IN operator.
          19. Created the dbhash.exe command-line utility. @@ -2479,7 +1924,7 @@ and EXPLAIN QUERY PLAN on each statement that is evaluated.
          20. Improved unicode filename handling in the command-line shell on Windows.
          21. Improved resistance against goofy query planner decisions caused by - incomplete or incorrect modifications to the sqlite_stat1 + incomplete or incorrect modifications to the sqlite_stat1 table by the application.
          22. Added the sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION) interface which allows the sqlite3_load_extension() C-API to be enabled while keeping the @@ -2492,7 +1937,7 @@ causing it to compute incorrect answers with a self-referential subquery in the WHERE clause. Fix for ticket dc6ebeda9396087 -
          23. Fix a possible segfault with DELETE when table is a rowid table with an +
          24. Fix a possible segfault with DELETE when table is a rowid table with an INTEGER PRIMARY KEY and the WHERE clause contains a OR and the table has one or more indexes that are able to trigger the OR optimization, but none of the indexes reference any table columns other than the INTEGER PRIMARY KEY. @@ -2527,7 +1972,7 @@
          25. Fix a boundary condition error introduced by version 3.12.0 that can result in a crash during heavy SAVEPOINT usage. Ticket 7f7f8026eda38. -
          26. Fix views so that they inherit column datatypes from the +
          27. Fix views so that they inherit column datatypes from the table that they are defined against, when possible.
          28. Fix the query planner so that IS and IS NULL operators are able to drive an index on a LEFT OUTER JOIN. @@ -2558,7 +2003,7 @@
          29. Fix a boundary condition error introduced by version 3.12.0 that can result in a crash during heavy SAVEPOINT usage. Ticket 7f7f8026eda38. -
          30. Fix views so that they inherit column datatypes from the +
          31. Fix views so that they inherit column datatypes from the table that they are defined against, when possible.
          32. Fix the query planner so that IS and IS NULL operators are able to drive an index on a LEFT OUTER JOIN. @@ -2579,8 +2024,8 @@

            2016-03-29 (3.12.0)

              Potentially Disruptive Change: -

            1. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. - The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so +
            2. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. + The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so the same amount of cache memory is used by default. See the application note on the version 3.12.0 page size change for further information. @@ -2602,7 +2047,7 @@ accesses in a 3-way or higher join where constraints on the virtual table are split across two or more other tables of the join.
            3. More efficient handling of application-defined SQL functions, especially - in cases where the application defines hundreds or thousands of + in cases where the application defines hundreds or thousands of custom functions.
            4. The query planner considers the LIMIT clause when estimating the cost of ORDER BY. @@ -2618,7 +2063,7 @@ be enabled or disabled at run-time.
            5. Added the sqlite3rbu_bp_progress() interface to the RBU extension. -
            6. The PRAGMA defer_foreign_keys=ON statement now also disables +
            7. The PRAGMA defer_foreign_keys=ON statement now also disables RESTRICT actions on foreign key.
            8. Added the sqlite3_system_errno() interface.
            9. Added the SQLITE_DEFAULT_SYNCHRONOUS and SQLITE_DEFAULT_WAL_SYNCHRONOUS @@ -2664,7 +2109,7 @@ a covering index as part of the OR optimization.
            10. Avoid recomputing NOT NULL and CHECK constraints on unchanged columns in UPDATE statement. -
            11. Many micro-optimizations, resulting in a library that is +
            12. Many micro-optimizations, resulting in a library that is faster than the previous release.

              Enhancements to the command-line shell:

            13. By default, the shell is now in "auto-explain" mode. The output of @@ -2692,7 +2137,7 @@
            14. Reenable the xCurrentTime and xGetLastError methods in the built-in unix VFSes as long as SQLITE_OMIT_DEPRECATED is not defined.

              Backwards Compatibility: -

            15. Because of continuing security concerns, the two-argument version +
            16. Because of continuing security concerns, the two-argument version of of the seldom-used and little-known fts3_tokenizer() function is disabled unless SQLite is compiled with the SQLITE_ENABLE_FTS3_TOKENIZER.

              Hashes: @@ -2705,7 +2150,7 @@

              2016-01-20 (3.10.2)

                Critical bug fix:

              1. Version 3.10.0 introduced a case-folding bug in the LIKE operator which is fixed - by this patch release. Ticket + by this patch release. Ticket 80369eddd5c94.

                Other miscellaneous bug fixes:

              2. Fix a use-after-free that can occur when SQLite is compiled with -DSQLITE_HAS_CODEC. @@ -2770,7 +2215,7 @@
              3. Fix inconsistent integer to floating-point comparison operations that could result in a corrupt index if the index is created on a table column that contains both large integers and floating point values - of similar magnitude. Ticket + of similar magnitude. Ticket 38a97a87a6.
              4. Fix an infinite-loop in the query planner that could occur on malformed common table expressions. @@ -2783,7 +2228,7 @@

              2015-11-02 (3.9.2)

                -
              1. Fix the schema parser so that it interprets certain +
              2. Fix the schema parser so that it interprets certain (obscure and ill-formed) CREATE TABLE statements the same as legacy. Fix for ticket ac661962a2aeab3c331 @@ -2833,7 +2278,7 @@
              3. The query planner is now able to use partial indexes that contain AND-connected terms in the WHERE clause.
              4. The sqlite3_analyzer.exe utility is updated to report the depth of - each btree and to show the average fanout for indexes and + each btree and to show the average fanout for indexes and WITHOUT ROWID tables.
              5. Enhanced the dbstat virtual table so that it can be used as a table-valued function where the argument is the schema to be @@ -2842,9 +2287,9 @@
              6. The sqlite3_memory_alarm() interface, which has been deprecated and undocumented for 8 years, is changed into a no-op.

                Important fixes: -

              7. Fixed a critical bug in the +
              8. Fixed a critical bug in the SQLite Encryption Extension that - could cause the database to become unreadable and unrecoverable if a VACUUM command + could cause the database to become unreadable and unrecoverable if a VACUUM command changed the size of the encryption nonce.
              9. Added a memory barrier in the implementation of sqlite3_initialize() to help ensure that it is thread-safe. @@ -2894,10 +2339,10 @@ use for the initial set page cache lines. Set the default preallocation to 100 pages. Yields about a 5% performance increase on common workloads.
              10. Miscellaneous micro-optimizations result in 22.3% more work for the same - number of CPU cycles relative to the previous release. + number of CPU cycles relative to the previous release. SQLite now runs twice as fast as version 3.8.0 and three times as fast as version 3.3.9. - (Measured using + (Measured using cachegrind on the speedtest1.c workload on Ubuntu 14.04 x64 with gcc 4.8.2 and -Os. Your performance may vary.) @@ -2925,7 +2370,7 @@

                2015-05-20 (3.8.10.2)

                1. Fix an index corruption issue introduced by version 3.8.7. An index - with a TEXT key can be corrupted by an INSERT into the corresponding + with a TEXT key can be corrupted by an INSERT into the corresponding table if the table has two nested triggers that convert the key value to INTEGER and back to TEXT again. Ticket 34cd55d68e0 @@ -2949,7 +2394,7 @@

                  2015-05-07 (3.8.10)

                  1. Added the sqldiff.exe utility program for computing the differences between two SQLite database files. -
                  2. Added the matchinfo y flag to the +
                  3. Added the matchinfo y flag to the matchinfo() function of FTS3.
                  4. Performance improvements for ORDER BY, VACUUM, CREATE INDEX, PRAGMA integrity_check, and PRAGMA quick_check. @@ -2981,7 +2426,7 @@
                  5. Correct miscounts in the sqlite3_analyzer.exe utility related to WITHOUT ROWID tables.
                  6. Added the ".dbinfo" command to the command-line shell. -
                  7. Improve the performance of fts3/4 queries that use the OR operator +
                  8. Improve the performance of fts3/4 queries that use the OR operator and at least one auxiliary fts function.
                  9. Fix a bug in the fts3 snippet() function causing it to omit leading separator characters from snippets that begin with the @@ -2996,7 +2441,7 @@ 2326c258d02ead33) that can lead to incorrect results if the qualifying constraint of a partial index appears in the ON clause of a LEFT JOIN. -
                  10. Added the ability to link against the +
                  11. Added the ability to link against the "linenoise" command-line editing library in unix builds of the command-line shell. @@ -3076,7 +2521,7 @@
                  12. Fix obscure crash bugs found by american fuzzy lop. Ticket a59ae93ee990a55. -
                  13. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the +
                  14. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the R-Tree extension to compute incorrect results when compiled with -O3.

                    Other changes:

                  15. Disable the use of the strchrnul() C-library routine unless it is @@ -3100,7 +2545,7 @@
                  16. Bug fix: Ensure the cached KeyInfo objects (an internal abstraction not visible to the application) do not go stale when operating in shared cache mode and frequently closing and reopening some database connections while leaving other database connections on the - same shared cache open continuously. Ticket + same shared cache open continuously. Ticket e4a18565a36884b00edf.
                  17. Bug fix: Recognize that any column in the right-hand table of a LEFT JOIN can be NULL even if the column has a NOT NULL constraint. Do not apply optimizations that @@ -3122,7 +2567,7 @@ Ticket 094d39a4c95ee4.
                  18. Bug fix: The %c format in sqlite3_mprintf() is able to handle precisions greater than 70.
                  19. Bug fix: Do not automatically remove the DISTINCT keyword from a SELECT that forms - the right-hand side of an IN operator since it is necessary if the SELECT also + the right-hand side of an IN operator since it is necessary if the SELECT also contains a LIMIT. Ticket db87229497. @@ -3149,9 +2594,9 @@

                    2014-10-17 (3.8.7)

                      Performance Enhancements:

                    1. Many micro-optimizations result in 20.3% more work for the same number - of CPU cycles relative to the previous release. + of CPU cycles relative to the previous release. The cumulative performance increase since version 3.8.0 is 61%. - (Measured using + (Measured using cachegrind on the speedtest1.c workload on Ubuntu 13.10 x64 with gcc 4.8.1 and -Os. Your performance may vary.) @@ -3195,7 +2640,7 @@ Ticket 369d57fb8e5ccdff06f1

                      Test, Debug, and Analysis Changes:

                    2. Show ASCII-art abstract syntax tree diagrams using the ".selecttrace" - and ".wheretrace" commands in the + and ".wheretrace" commands in the command-line shell when compiled with SQLITE_DEBUG, SQLITE_ENABLE_SELECTTRACE, and SQLITE_ENABLE_WHERETRACE. Also provide the sqlite3TreeViewExpr() and sqlite3TreeViewSelect() entry points that can be invoked from with the @@ -3308,7 +2753,7 @@
                    3. ORDER BY ignored if the query has an identical GROUP BY. Ticket b75a9ca6b0
                    4. The group_concat(x,'') SQL function returns NULL instead of an empty string - when all inputs are empty strings. + when all inputs are empty strings. Ticket 55746f9e65
                    5. Fix a bug in the VDBE code generator that caused crashes when doing an INSERT INTO ... SELECT statement where the number of columns @@ -3332,7 +2777,7 @@

                    2014-04-03 (3.8.4.3)

                      -
                    1. Add a +
                    2. Add a one-character fix for a problem that might cause incorrect query results on a query that mixes DISTINCT, GROUP BY in a subquery, and ORDER BY. @@ -3369,13 +2814,13 @@
                    3. Add support for coverage testing of VDBE programs using the SQLITE_TESTCTRL_VDBE_COVERAGE verb of sqlite3_test_control().
                    4. Update the _FILE_OFFSET_BITS macro so that builds work again on QNX. -
                    5. Change the datatype of SrcList.nSrc from type u8 to type int to work around +
                    6. Change the datatype of SrcList.nSrc from type u8 to type int to work around an issue in the C compiler on AIX.
                    7. Get extension loading working on Cygwin.
                    8. Bug fix: Fix the char() SQL function so that it returns an empty string - rather than an "out of memory" error when called with zero arguments. + rather than an "out of memory" error when called with zero arguments.
                    9. Bug fix: DISTINCT now recognizes that a zeroblob and a blob of all - 0x00 bytes are the same thing. + 0x00 bytes are the same thing. Ticket [fccbde530a]
                    10. Bug fix: Compute the correct answer for queries that contain an IS NOT NULL term in the WHERE clause and also contain an OR term in the WHERE clause and @@ -3437,7 +2882,7 @@ considers dangerous. (Ex: sprintf).
                    11. Bug fix: In the command-line shell CSV import feature, do not end a field when an escaped double-quote occurs at the end of a CRLN line. -
                    12. SQLITE_SOURCE_ID: +
                    13. SQLITE_SOURCE_ID: "2014-02-03 13:52:03 e816dd924619db5f766de6df74ea2194f3e3b538"
                    14. SHA1 for sqlite3.c: 98a07da78f71b0275e8d9c510486877adc31dbee @@ -3445,9 +2890,9 @@

                      2013-12-06 (3.8.2)

                      1. Changed the defined behavior for the CAST expression when floating point values - greater than +9223372036854775807 are cast into integers so that the + greater than +9223372036854775807 are cast into into integers so that the result is the largest possible integer, +9223372036854775807, instead of - the smallest possible integer, -9223372036854775808. After this change, + the smallest possible integer, -9223372036854775808. After this change, CAST(9223372036854775809.0 as INT) yields +9223372036854775807 instead of -9223372036854775808.  Potentially Incompatible Change! @@ -3469,7 +2914,7 @@
                      2. Enhanced the ".timer" feature of the command-line shell so that it shows wall-clock time in addition to system and user times. -
                      3. SQLITE_SOURCE_ID: +
                      4. SQLITE_SOURCE_ID: "2013-12-06 14:53:30 27392118af4c38c5203a04b8013e1afdb1cebd0d"
                      5. SHA1 for sqlite3.c: 6422c7d69866f5ea3db0968f67ee596e7114544e @@ -3487,7 +2932,7 @@
                    15. Added the soft_heap_limit pragma.
                    16. Added support for SQLITE_ENABLE_STAT4 -
                    17. Added support for "sz=NNN" parameters at the end of +
                    18. Added support for "sz=NNN" parameters at the end of sqlite_stat1.stat fields used to specify the average length in bytes for table and index rows.
                    19. Avoid running foreign-key constraint checks on an UPDATE if none of the @@ -3516,7 +2961,7 @@ there is a partial index on the table. Ticket a5c8ed66ca. -
                    20. SQLITE_SOURCE_ID: +
                    21. SQLITE_SOURCE_ID: "2013-10-17 12:57:35 c78be6d786c19073b3a6730dfe3fb1be54f5657a"
                    22. SHA1 for sqlite3.c: 0a54d76566728c2ba96292a49b138e4f69a7c391 @@ -3525,21 +2970,21 @@

                      2013-09-03 (3.8.0.2)

                      1. Fix a bug in the optimization that attempts to omit unused LEFT JOINs -
                      2. SQLITE_SOURCE_ID: +
                      3. SQLITE_SOURCE_ID: "2013-09-03 17:11:13 7dd4968f235d6e1ca9547cda9cf3bd570e1609ef"
                      4. SHA1 for sqlite3.c: 6cf0c7b46975a87a0dc3fba69c229a7de61b0c21

                      2013-08-29 (3.8.0.1)

                        -
                      1. Fix an off-by-one error that caused quoted empty string at the end of a +
                      2. Fix an off-by-one error that caused quoted empty string at the end of a CRNL-terminated line of CSV input to be misread by the command-line shell.
                      3. Fix a query planner bug involving a LEFT JOIN with a BETWEEN or LIKE/GLOB constraint and then another INNER JOIN to the right that involves an OR constraint.
                      4. Fix a query planner bug that could result in a segfault when querying tables with a UNIQUE or PRIMARY KEY constraint with more than four columns. -
                      5. SQLITE_SOURCE_ID: +
                      6. SQLITE_SOURCE_ID: "2013-08-29 17:35:01 352362bc01660edfbda08179d60f09e2038a2f49"
                      7. SHA1 for sqlite3.c: 99906bf63e6cef63d6f3d7f8526ac4a70e76559e @@ -3548,7 +2993,7 @@

                        2013-08-26 (3.8.0)

                        1. Add support for partial indexes
                        2. Cut-over to the next generation query planner for faster and better query plans. -
                        3. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of +
                        4. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of rows generated by each loop in a join.
                        5. Added the FTS4 notindexed option, allowing non-indexed columns in an FTS4 table.
                        6. Added the SQLITE_STMTSTATUS_VM_STEP option to sqlite3_stmt_status(). @@ -3568,7 +3013,7 @@
                        7. Issue an SQLITE_WARNING_AUTOINDEX warning on the SQLITE_CONFIG_LOG whenever the query planner uses an automatic index.
                        8. Added the SQLITE_FTS3_MAX_EXPR_DEPTH compile-time option. -
                        9. Added an optional 5th parameter defining the collating sequence to the +
                        10. Added an optional 5th parameter defining the collating sequence to the next_char() extension SQL function.
                        11. The SQLITE_BUSY_SNAPSHOT extended error code is returned in WAL mode when a read transaction cannot be upgraded to a write transaction because the read is @@ -3576,7 +3021,7 @@
                        12. Enhancements to the sqlite3_analyzer utility program to provide size information separately for each individual index of a table, in addition to the aggregate size. -
                        13. Allow read transactions to be freely opened and closed by SQL statements run +
                        14. Allow read transactions to be freely opened and closed by SQL statements run from within the implementation of application-defined SQL functions if the function is called by a SELECT statement that does not access any database table.
                        15. Disable the use of posix_fallocate() on all (unix) systems unless the @@ -3589,10 +3034,10 @@
                        16. Bug fix: Bare identifiers in ORDER BY clauses bind more tightly to output column names, but identifiers in expressions bind more tightly to input column names. Identifiers in GROUP BY clauses always prefer output column names, however. -
                        17. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the +
                        18. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the move to NGQP. -
                        19. SQLITE_SOURCE_ID: +
                        20. SQLITE_SOURCE_ID: "2013-08-26 04:50:08 f64cd21e2e23ed7cff48f7dafa5e76adde9321c2"
                        21. SHA1 for sqlite3.c: b7347f4b4c2a840e6ba12040093d606bd16ea21e @@ -3605,9 +3050,9 @@ Application ID for when SQLite is used as an application file-format. Added the PRAGMA application_id command to query and set the Application ID.
                        22. Report rollback recovery in the error log as SQLITE_NOTICE_RECOVER_ROLLBACK. - Change the error log code for WAL recover from + Change the error log code for WAL recover from SQLITE_OK to SQLITE_NOTICE_RECOVER_WAL. -
                        23. Report the risky uses of unlinked database files and +
                        24. Report the risky uses of unlinked database files and database filename aliasing as SQLITE_WARNING messages in the error log.
                        25. Added the SQLITE_TRACE_SIZE_LIMIT compile-time option.
                        26. Increase the default value of SQLITE_MAX_SCHEMA_RETRY to 50 and make sure @@ -3629,7 +3074,7 @@
                      8. Added many new loadable extensions to the source tree, including amatch, closure, fuzzer, ieee754, nextchar, regexp, spellfix, - and wholenumber. See header comments on each extension source file + and wholenumber. See header comments on each extension source file for further information about what that extension does.
                      9. Enhance FTS3 to avoid using excess stack space when there are a huge number of terms on the right-hand side of the MATCH operator. A side-effect @@ -3650,10 +3095,10 @@ Ticket e636a050b7
                      10. Bug fix: Only consider AS names from the result set as candidates for resolving - identifiers in the WHERE clause if there are no other matches. In the + identifiers in the WHERE clause if there are no other matches. In the ORDER BY clause, AS names take priority over any column names. Ticket 2500cdb9be05 -
                      11. Bug fix: Do not allow a virtual table to cancel the ORDER BY clause unless +
                      12. Bug fix: Do not allow a virtual table to cancel the ORDER BY clause unless all outer loops are guaranteed to return no more than one row result. Ticket ba82a4a41eac1.
                      13. Bug fix: Do not suppress the ORDER BY clause on a virtual table query if @@ -3672,13 +3117,13 @@ doing an UPDATE that changes the rowid. Ticket 0eb70d77cb05bb2272
                      14. Bug fix: Do not move WHERE clause terms inside OR expressions that are - contained within an ON clause of a LEFT JOIN. Ticket + contained within an ON clause of a LEFT JOIN. Ticket f2369304e4
                      15. Bug fix: Make sure an error is always reported when attempting to preform an operation that requires a collating sequence that is missing. Ticket 0fc59f908b -
                      16. SQLITE_SOURCE_ID: +
                      17. SQLITE_SOURCE_ID: "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
                      18. SHA1 for sqlite3.c: 246987605d0503c700a08b9ee99a6b5d67454aab @@ -3688,11 +3133,11 @@
                      19. Fix a bug (present since version 3.7.13) that could result in database corruption on windows if two or more processes try to access the same database file at the same time and immediately after third process crashed in the middle of committing - to that same file. See ticket + to that same file. See ticket 7ff3120e4f for further information. -
                      20. SQLITE_SOURCE_ID: +
                      21. SQLITE_SOURCE_ID: "2013-04-12 11:52:43 cbea02d93865ce0e06789db95fd9168ebac970c7"
                      22. SHA1 for sqlite3.c: d466b54789dff4fb0238b9232e74896deaefab94 @@ -3715,7 +3160,7 @@
                      23. The SQLITE_OMIT_MERGE_SORT option has been removed. The merge sorter is now a required component of SQLite.
                      24. Fixed lots of spelling errors in the source-code comments -
                      25. SQLITE_SOURCE_ID: +
                      26. SQLITE_SOURCE_ID: "2013-03-29 13:44:34 527231bc67285f01fb18d4451b28f61da3c4e39d"
                      27. SHA1 for sqlite3.c: 7a91ceceac9bcf47ceb8219126276e5518f7ff5a @@ -3728,7 +3173,7 @@ cannot be opened because it needs rollback recovery but is read-only.
                      28. Added SQL functions unicode(A) and char(X1,...,XN).
                      29. Performance improvements for PRAGMA incremental_vacuum, especially in - cases where the number of free pages is greater than what will fit on a + cases where the number of free pages is greater than what will fit on a single trunk page of the freelist.
                      30. Improved optimization of queries containing aggregate min() or max().
                      31. Enhance virtual tables so that they can potentially use an index when @@ -3754,11 +3199,11 @@ the two tables involved.
                      32. Remove all uses of umask() in the unix VFS.
                      33. Added the PRAGMA vdbe_addoptrace and PRAGMA vdbe_debug commands. -
                      34. Change to use strncmp() or the equivalent instead of memcmp() when +
                      35. Change to use strncmp() or the equivalent instead of memcmp() when comparing non-zero-terminated strings.
                      36. Update cygwin interfaces to omit deprecated API calls.
                      37. Enhance the spellfix1 extension so that the edit distance cost table can - be changed at runtime by inserting a string like 'edit_cost_table=TABLE' + be changed at runtime by inserting a string like 'edit_cost_table=TABLE' into the "command" field.
                      38. Bug fix: repair a long-standing problem that could cause incorrect query @@ -3772,7 +3217,7 @@
                      39. Bug fix: Make sure the schema is up-to-date prior to running pragmas table_info, index_list, index_info, and foreign_key_list. -
                      40. SQLITE_SOURCE_ID: +
                      41. SQLITE_SOURCE_ID: "2013-03-18 11:39:23 66d5f2b76750f3520eb7a495f6247206758f5b90"
                      42. SHA1 for sqlite3.c: 7308ab891ca1b2ebc596025cfe4dc36f1ee89cf6 @@ -3784,7 +3229,7 @@ required. Ticket 598f5f7596b055 -
                      43. SQLITE_SOURCE_ID: +
                      44. SQLITE_SOURCE_ID: "2013-01-09 11:53:05 c0e09560d26f0a6456be9dd3447f5311eb4f238f"
                      45. SHA1 for sqlite3.c: 5741f47d1bc38aa0a8c38f09e60a5fe0031f272d @@ -3793,10 +3238,10 @@

                        2012-12-19 (3.7.15.1)

                        1. Fix a bug, introduced in version 3.7.15, that causes a segfault if the AS name of a result column of a SELECT statement is used as a logical - term in the WHERE clause. Ticket + term in the WHERE clause. Ticket a7b7803e8d1e869. -
                        2. SQLITE_SOURCE_ID: +
                        3. SQLITE_SOURCE_ID: "2012-12-19 20:39:10 6b85b767d0ff7975146156a99ad673f2c1a23318"
                        4. SHA1 for sqlite3.c: bbbaa68061e925bd4d7d18d7e1270935c5f7e39a @@ -3841,21 +3286,21 @@
                        5. Bug fix: Avoid segfault when using the COLLATE operator inside of a CHECK constraint or view in shared cache mode. -
                        6. SQLITE_SOURCE_ID: +
                        7. SQLITE_SOURCE_ID: "2012-12-12 13:36:53 cd0b37c52658bfdf992b1e3dc467bae1835a94ae"
                        8. SHA1 for sqlite3.c: 2b413611f5e3e3b6ef5f618f2a9209cdf25cbcff"

                        2012-10-04 (3.7.14.1)

                          -
                        1. Fix a bug (ticket -[d02e1406a58ea02d]]) +
                        2. Fix a bug (ticket +[d02e1406a58ea02d]]) that causes a segfault on a LEFT JOIN that includes an OR in the ON clause.
                        3. Work around a bug in the optimizer in the VisualStudio-2012 compiler that causes invalid code to be generated when compiling SQLite on ARM.
                        4. Fix the TCL interface so that the "nullvalue" setting is honored for TCL implementations of SQL functions. -
                        5. SQLITE_SOURCE_ID: +
                        6. SQLITE_SOURCE_ID: "2012-10-04 19:37:12 091570e46d04e84b67228e0bdbcd6e1fb60c6bdb"
                        7. SHA1 for sqlite3.c: 62aaecaacab3a4bf4a8fe4aec1cfdc1571fe9a44 @@ -3868,7 +3313,7 @@ sqlite3_vfs_register() interface. The code removed in this release can serve as a baseline for the application-defined VFS.
                        8. Ensure that floating point values are preserved exactly when reconstructing - a database from the output of the ".dump" command of the + a database from the output of the ".dump" command of the command-line shell.
                        9. Added the sqlite3_close_v2() interface.
                        10. Updated the command-line shell so that it can be built using @@ -3886,7 +3331,7 @@ contained within subqueries.
                        11. Enhance the query planner so that it will try to use a covering index on queries that make use of or optimization. -
                        12. SQLITE_SOURCE_ID: +
                        13. SQLITE_SOURCE_ID: "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a"
                        14. SHA1 for sqlite3.c: 5fdf596b29bb426001f28b488ff356ae14d5a5a6 @@ -3912,19 +3357,19 @@ return SQLITE_MISUSE on any attempt to overload or replace a virtual table module. The destructor is always called in this case, in accordance with historical and current documentation. -
                        15. SQLITE_SOURCE_ID: +
                        16. SQLITE_SOURCE_ID: "2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc"
                        17. SHA1 for sqlite3.c: ff0a771d6252545740ba9685e312b0e3bb6a641b

                        2012-05-22 (3.7.12.1)

                          -
                        1. Fix a bug +
                        2. Fix a bug (ticket c2ad16f997) in the 3.7.12 release that can cause a segfault for certain obscure nested aggregate queries.
                        3. Fix various other minor test script problems. -
                        4. SQLITE_SOURCE_ID: +
                        5. SQLITE_SOURCE_ID: "2012-05-22 02:45:53 6d326d44fd1d626aae0e8456e5fa2049f1ce0789"
                        6. SHA1 for sqlite3.c: d494e8d81607f0515d4f386156fb0fd86d5ba7df @@ -3965,7 +3410,7 @@
                        7. Bug fix: Do not optimize away an ORDER BY clause that has the same terms as a UNIQUE index unless those terms are also NOT NULL. Ticket 2a5629202f. -
                        8. SQLITE_SOURCE_ID: +
                        9. SQLITE_SOURCE_ID: "2012-05-14 01:41:23 8654aa9540fe9fd210899d83d17f3f407096c004"
                        10. SHA1 for sqlite3.c: 57e2104a0f7b3f528e7f6b7a8e553e2357ccd2e1 @@ -3983,21 +3428,21 @@
                        11. Added the SQLITE_FCNTL_PRAGMA file control, giving VFS implementations the ability to add new PRAGMA statements or to override built-in PRAGMAs. -
                        12. Queries of the form: "SELECT max(x), y FROM table" returns the +
                        13. Queries of the form: "SELECT max(x), y FROM table" returns the value of y on the same row that contains the maximum x value. -
                        14. Added support for the FTS4 languageid option. +
                        15. Added support for the FTS4 languageid option.
                        16. Documented support for the FTS4 content option. This feature has actually been in the code since version 3.7.9 but is only now considered to be officially supported.
                        17. Pending statements no longer block ROLLBACK. Instead, the pending statement will return SQLITE_ABORT upon next access after the ROLLBACK.
                        18. Improvements to the handling of CSV inputs in the command-line shell -
                        19. Fix a bug introduced +
                        20. Fix a bug introduced in version 3.7.10 that might cause a LEFT JOIN to be incorrectly converted into an INNER JOIN if the WHERE clause indexable terms connected by OR. -
                        21. SQLITE_SOURCE_ID: +
                        22. SQLITE_SOURCE_ID: "2012-03-20 11:35:50 00bb9c9ce4f465e6ac321ced2a9d0062dc364669"
                        23. SHA1 for sqlite3.c: d460d7eda3a9dccd291aed2a9fda868b9b120a10 @@ -4043,7 +3488,7 @@ and rmdir() instead of locking files with open() and unlink().
                        24. Enhancements to the test_quota.c extension to support stdio-like interfaces with quotas. -
                        25. Change the unix VFS to be tolerant of read() system calls that return +
                        26. Change the unix VFS to be tolerant of read() system calls that return less then the full number of requested bytes.
                        27. Change both unix and windows VFSes to report a sector size of 4096 instead of the old default of 512. @@ -4065,7 +3510,7 @@
                        28. Bug fix: Fix problems that can result from 32-bit integer overflow. Ticket ac00f496b7e2 -
                        29. SQLITE_SOURCE_ID: +
                        30. SQLITE_SOURCE_ID: "2012-01-16 13:28:40 ebd01a8deffb5024a5d7494eef800d2366d97204"
                        31. SHA1 for sqlite3.c: 6497cbbaad47220bd41e2e4216c54706e7ae95d4 @@ -4091,7 +3536,7 @@
                        32. Enhanced the query planner so that it can factor terms in and out of OR expressions in the WHERE clause in an effort to find better indices.
                        33. Added the SQLITE_DIRECT_OVERFLOW_READ compile-time option, causing - overflow pages to be read directly from the database file, + overflow pages to be read directly from the database file, bypassing the page cache.
                        34. Remove limits on the magnitude of precision and width value in the format specifiers of the sqlite3_mprintf() family of string rendering @@ -4111,7 +3556,7 @@
                        35. Fix a bug in virtual table implementation that causes a crash if an FTS4 table is dropped inside a transaction and a SAVEPOINT occurs afterwards. -
                        36. SQLITE_SOURCE_ID: +
                        37. SQLITE_SOURCE_ID: "2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e"
                        38. SHA1 for sqlite3.c: becd16877f4f9b281b91c97e106089497d71bb47 @@ -4126,7 +3571,7 @@
                        39. Allow more system calls to be overridden in the unix VFS - to provide better support for chromium sandboxes.
                        40. Increase the default size of a lookahead cache line from 100 to 128 bytes. -
                        41. Enhancements to the test_quota.c module so that it can track +
                        42. Enhancements to the test_quota.c module so that it can track preexisting files.
                        43. Bug fix: Virtual tables now handle IS NOT NULL constraints correctly.
                        44. Bug fixes: Correctly handle nested correlated subqueries used with @@ -4138,7 +3583,7 @@

                        2011-06-28 (3.7.7.1)

                          -
                        1. Fix a bug causing +
                        2. Fix a bug causing PRAGMA case_sensitive_like statements compiled using sqlite3_prepare() to fail with an SQLITE_SCHEMA error.
                        3. SQLITE_SOURCE_ID: @@ -4241,13 +3686,13 @@ VACUUM that could (in theory) cause database corruption.
                        4. Enhance the sqlite3_trace() mechanism so that nested SQL statements such as might be generated by virtual tables are shown but are shown - in comments and without parameter expansion. This + in comments and without parameter expansion. This greatly improves tracing output when using the FTS3/4 and/or RTREE virtual tables.
                        5. Change the xFileControl() methods on all built-in VFSes to return SQLITE_NOTFOUND instead of SQLITE_ERROR for an unrecognized operation code. -
                        6. The SQLite core invokes the SQLITE_FCNTL_SYNC_OMITTED +
                        7. The SQLite core invokes the SQLITE_FCNTL_SYNC_OMITTED file control to the VFS in place of a call to xSync if the database has PRAGMA synchronous set to OFF. @@ -4266,10 +3711,11 @@
                        8. Added PRAGMA checkpoint_fullfsync.
                        9. Added the SQLITE_FCNTL_FILE_POINTER option to sqlite3_file_control(). -
                        10. Added support for FTS4 and enhancements +
                        11. Added support for FTS4 and enhancements to the FTS matchinfo() function.
                        12. Added the test_superlock.c module which provides example - code for obtaining an exclusive lock to a rollback or WAL database. + code for obtaining an exclusive lock to a rollback + or WAL database.
                        13. Added the test_multiplex.c module which provides an example VFS that provides multiplexing (sharding) of a DB, splitting it over multiple files of fixed size. @@ -4290,7 +3736,7 @@ SQLITE_ENABLE_MEMORY_MANAGEMENT is not set.
                        14. Added the sqlite3_soft_heap_limit64() interface as a replacement for sqlite3_soft_heap_limit(). -
                        15. The ANALYZE command now gathers statistics on tables even if they +
                        16. The ANALYZE command now gathers statistics on tables even if they have no indices.
                        17. Tweaks to the query planner to help it do a better job of finding the most efficient query plan for each query. @@ -4423,7 +3869,7 @@

                        2009-11-04 (3.6.20)

                          -
                        1. Optimizer enhancement: prepared statements are automatically +
                        2. Optimizer enhancement: prepared statements are automatically re-compiled when a binding on the RHS of a LIKE operator changes or when any range constraint changes under SQLITE_ENABLE_STAT2.
                        3. Various minor bug fixes and documentation enhancements. @@ -4431,7 +3877,7 @@

                        2009-10-30 (3.6.16.1)

                          -
                        1. A small patch to version 3.6.16 to fix +
                        2. A small patch to version 3.6.16 to fix the OP_If bug.

                        @@ -4453,12 +3899,12 @@
                      46. Versioning of the SQLite source code has transitioned from CVS to Fossil.
                      47. Query planner enhancements. -
                      48. The SQLITE_ENABLE_STAT2 compile-time option causes the ANALYZE +
                      49. The SQLITE_ENABLE_STAT2 compile-time option causes the ANALYZE command to collect a small histogram of each index, to help SQLite better select among competing range query indices.
                      50. Recursive triggers can be enabled using the PRAGMA recursive_triggers - statement. -
                      51. Delete triggers fire when rows are removed due to a + statement. +
                      52. Delete triggers fire when rows are removed due to a REPLACE conflict resolution. This feature is only enabled when recursive triggers are enabled.
                      53. Added the SQLITE_OPEN_SHAREDCACHE and SQLITE_OPEN_PRIVATECACHE @@ -4507,6 +3953,7 @@
                      54. Continuing improvements to the test suite and fixes to obscure bugs and inconsistencies that the test suite improvements are uncovering. +

                      @@ -4541,8 +3988,8 @@

                      2009-04-13 (3.6.13)

                      1. Fix a bug in version 3.6.12 that causes a segfault when running a count(*) on the sqlite_master table of an empty database. Ticket #3774. -
                      2. Fix a bug in version 3.6.12 that causes a segfault that when - inserting into a table using a DEFAULT value where there is a +
                      3. Fix a bug in version 3.6.12 that causes a segfault that when + inserting into a table using a DEFAULT value where there is a function as part of the DEFAULT value expression. Ticket #3791.
                      4. Fix data structure alignment issues on Sparc. Ticket #3777.
                      5. Other minor bug fixes. @@ -4591,7 +4038,7 @@

                        2009-01-12 (3.6.8)

                        1. Added support for nested transactions
                        2. Enhanced the query optimizer so that it is able to use - multiple indices to efficiently process + multiple indices to efficiently process OR-connected constraints in a WHERE clause.
                        3. Added support for parentheses in FTS3 query patterns using the @@ -4673,7 +4120,7 @@ documentation for the genfkey program for automatically generating triggers to enforce foreign key constraints.
                        4. Added the SQLITE_OMIT_TRUNCATE_OPTIMIZATION compile-time option.
                        5. -
                        6. The SQL language documentation is converted to use +
                        7. The SQL language documentation is converted to use syntax diagrams instead of BNF.
                        8. Other minor bug fixes
                        9. @@ -4729,7 +4176,7 @@ but as it has the potential to break legacy applications that depend on the older buggy behavior, we mark that as a *** Potentially incompatible change *** -
                        10. The result column names generated for compound subqueries have been +
                        11. The result column names generated for compound subqueries have been simplified to show only the name of the column of the original table and omit the table name. This makes SQLite operate more like other SQL database engines.
                        12. @@ -4847,18 +4294,18 @@ be deleted as side effects. (See ticket #2832.) The most likely result of this bug is a segmentation fault, though database corruption is a possibility. -
                        13. Bring the processing of ORDER BY into compliance with the +
                        14. Bring the processing of ORDER BY into compliance with the SQL standard for case where a result alias and a table column name are in conflict. Correct behavior is to prefer the result alias. Older versions of SQLite incorrectly picked the table column. (See ticket #2822.)
                        15. The VACUUM command preserves -the setting of the +the setting of the legacy_file_format pragma. (Ticket #2804.)
                        16. Productize and officially support the group_concat() SQL function.
                        17. Better optimization of some IN operator expressions.
                        18. -
                        19. Add the ability to change the +
                        20. Add the ability to change the auto_vacuum status of a database by setting the auto_vaccum pragma and VACUUMing the database.
                        21. Prefix search in FTS3 is much more efficient.
                        22. @@ -4938,8 +4385,8 @@ threads in the process, not just the single thread in which they are invoked. *** Potentially incompatible change *** -
                        23. Added the sqlite3_open_v2() interface. -
                        24. Reimplemented the memory allocation subsystem and made it +
                        25. Added the sqlite3_open_v2() interface. +
                        26. Reimplemented the memory allocation subsystem and made it replaceable at compile-time.
                        27. Created a new mutex subsystem and made it replicable at compile-time. @@ -4951,7 +4398,7 @@

                          2007-08-13 (3.4.2)

                          1. Fix a database corruption bug that might occur if a ROLLBACK command is executed in auto-vacuum mode -and a very small sqlite3_soft_heap_limit is set. +and a very small sqlite3_soft_heap_limit is set. Ticket #2565.
                          2. Add the ability to run a full regression test with a small @@ -4959,7 +4406,7 @@
                          3. Fix other minor problems with using small soft heap limits. -
                          4. Work-around for +
                          5. Work-around for GCC bug 32575.
                          6. Improved error detection of misused aggregate functions. @@ -4993,7 +4440,7 @@
                          7. Add the capability of "hidden" columns in virtual tables.
                          8. Use the macro SQLITE_PRIVATE (defaulting to "static") on all internal functions in the amalgamation.
                          9. -
                          10. Add pluggable tokenizers and ICU +
                          11. Add pluggable tokenizers and ICU tokenization support to FTS2
                          12. Other minor bug fixes and documentation enhancements
                          13. @@ -5006,7 +4453,7 @@
                          14. Fix a bug that can lead to database corruption if autovacuum mode is on and a malloc() failure follows a CREATE TABLE or CREATE INDEX statement which itself follows a cache overflow inside a transaction. See - ticket #2418. + ticket #2418.
                          15. Added explicit upper bounds on the sizes and quantities of things SQLite can process. This change might cause @@ -5015,14 +4462,14 @@ release is 3.4.0 instead of 3.3.18.
                          16. Added support for Incremental BLOB I/O.
                          17. Added the sqlite3_bind_zeroblob() API - and the zeroblob() SQL function.
                          18. + and the zeroblob() SQL function.
                          19. Added support for Incremental Vacuum.
                          20. Added the SQLITE_MIXED_ENDIAN_64BIT_FLOAT compile-time option to support ARM7 processors with goofy endianness.
                          21. Removed all instances of sprintf() and strcpy() from the core library.
                          22. Added support for - International Components for Unicode (ICU) + International Components for Unicode (ICU) to the full-text search extensions.
                          23. In the Windows OS driver, reacquire a SHARED lock if an attempt to acquire an EXCLUSIVE lock fails. Ticket #2354
                          24. @@ -5048,7 +4495,7 @@
                          25. Fix a bug in the handling of UTF16 codepoint 0xE000
                          26. Consider explicit collate clauses when matching WHERE constraints to indices in the query optimizer. Ticket #2391
                          27. -
                          28. Fix the query optimizer to correctly handle constant expressions in +
                          29. Fix the query optimizer to correctly handle constant expressions in the ON clause of a LEFT JOIN. Ticket #2403
                          30. Fix the query optimizer to handle rowid comparisons to NULL correctly. Ticket #2404
                          31. @@ -5095,7 +4542,7 @@

                            2007-04-02 (3.3.14)

                            1. Fix a bug (ticket #2273) that could cause a segfault when the IN operator - is used one term of a two-column index and the right-hand side of + is used one one term of a two-column index and the right-hand side of the IN operator contains a NULL.
                            2. Added a new OS interface method for determining the sector size of underlying media: sqlite3OsSectorSize().
                            3. @@ -5107,7 +4554,7 @@
                              1. Do not read the last page of an overflow chain when deleting the row - just add that page to the freelist.
                              2. -
                              3. Do not store pages being deleted in the +
                              4. Do not store pages being deleted in the rollback journal.
                              5. Do not read in the (meaningless) content of pages extracted from the freelist.
                              6. @@ -5126,7 +4573,7 @@ limitations.
                              7. Add a makefile target "sqlite3.c" that builds an amalgamation containing the core SQLite library C code in a single file.
                              8. -
                              9. Get the library working correctly when compiled +
                              10. Get the library working correctly when compiled with GCC option "-fstrict-aliasing".
                              11. Removed the vestigal SQLITE_PROTOCOL error.
                              12. Improvements to test coverage, other minor bugs fixed, @@ -5142,9 +4589,9 @@ additional testing.
                              13. Allow up to 64 tables in a join - the old limit was 32.
                              14. Added two new experimental functions: -randomblob() and -hex(). -Their intended use is to facilitate generating +randomBlob() and +hex(). +Their intended use is to facilitate generating UUIDs.
                              15. Fix a problem where @@ -5169,7 +4616,7 @@

                              2007-01-22 (3.3.11)

                                -
                              1. Fix another bug in the implementation of the new +
                              2. Fix another bug in the implementation of the new sqlite3_prepare_v2() API. We'll get it right eventually...
                              3. Fix a bug in the IS NULL optimization that was added in version 3.3.9 - @@ -5182,17 +4629,17 @@

                              2007-01-09 (3.3.10)

                                -
                              1. Fix bugs in the implementation of the new +
                              2. Fix bugs in the implementation of the new sqlite3_prepare_v2() API that can lead to segfaults.
                              3. -
                              4. Fix 1-second round-off errors in the +
                              5. Fix 1-second round-off errors in the strftime() function
                              6. Enhance the Windows OS layer to provide detailed error codes
                              7. Work around a win2k problem so that SQLite can use single-character database file names
                              8. The user_version and -schema_version pragmas +schema_version pragmas correctly set their column names in the result set
                              9. Documentation updates
                              10. @@ -5249,11 +4696,11 @@

                                2006-08-12 (3.3.7)

                                1. Added support for virtual tables (beta)
                                2. Added support for dynamically loaded extensions (beta)
                                3. -
                                4. The +
                                5. The sqlite3_interrupt() routine can be called for a different thread
                                6. Added the MATCH operator.
                                7. -
                                8. The default file format is now 1. +
                                9. The default file format is now 1.

                                @@ -5356,7 +4803,7 @@

                                2005-12-19 (3.2.8)

                                1. Fix an obscure bug that can cause database corruption under the -following unusual circumstances: A large INSERT or UPDATE statement which +following unusual circumstances: A large INSERT or UPDATE statement which is part of an even larger transaction fails due to a uniqueness constraint but the containing transaction commits.
                                2. @@ -5364,7 +4811,7 @@

                                  2005-12-19 (2.8.17)

                                  1. Fix an obscure bug that can cause database corruption under the -following unusual circumstances: A large INSERT or UPDATE statement which +following unusual circumstances: A large INSERT or UPDATE statement which is part of an even larger transaction fails due to a uniqueness contraint but the containing transaction commits.
                                  2. @@ -5500,7 +4947,7 @@ version 3.1 is turned on.
                                  3. The F_FULLSYNC ioctl (currently only supported on Mac OS X) is disabled if the synchronous pragma is set to something other than "full".
                                  4. -
                                  5. Add additional forward compatibility to the future version 3.2 database +
                                  6. Add additional forward compatibility to the future version 3.2 database file format.
                                  7. Fix a bug in WHERE clauses of the form (rowid<'2')
                                  8. New SQLITE_OMIT_... compile-time options added
                                  9. @@ -5590,7 +5037,7 @@
                                  10. New interface: sqlite3_bind_parameter_index()
                                  11. Add support for wildcard parameters of the form: "?nnn"
                                  12. Fix problems found on 64-bit systems.
                                  13. -
                                  14. Removed encode.c file (containing unused routines) from the +
                                  15. Removed encode.c file (containing unused routines) from the version 3.0 source tree.
                                  16. The sqlite3_trace() callbacks occur before each statement is executed, not when the statement is compiled.
                                  17. @@ -5672,8 +5119,8 @@

                                    2004-06-09 (2.8.14)

                                    1. Fix the min() and max() optimizer so that it works when the FROM clause consists of a subquery.
                                    2. -
                                    3. Ignore extra whitespace at the end of "." commands in the shell.
                                    4. -
                                    5. Bundle sqlite_encode_binary() and sqlite_decode_binary() with the +
                                    6. Ignore extra whitespace at the end of of "." commands in the shell.
                                    7. +
                                    8. Bundle sqlite_encode_binary() and sqlite_decode_binary() with the library.
                                    9. The TEMP_STORE and DEFAULT_TEMP_STORE pragmas now work.
                                    10. Code changes to compile cleanly using OpenWatcom.
                                    11. @@ -5725,7 +5172,7 @@

                                      2004-01-14 (2.8.10)

                                      1. Fix a potential database corruption problem on Unix caused by the fact that all POSIX advisory locks are cleared whenever you close() a file. - The work around it to embargo all close() calls while locks are + The work around it to embargo all close() calls while locks are outstanding.
                                      2. Performance enhancements on some corner cases of COUNT(*).
                                      3. Make sure the in-memory backend response sanely if malloc() fails.
                                      4. @@ -5796,7 +5243,7 @@
                                      5. Correctly handle comparisons between an INTEGER PRIMARY KEY and a floating point number.
                                      6. Fix several important bugs in the new ATTACH and DETACH commands.
                                      7. -
                                      8. Updated the NULL-handling document.
                                      9. +
                                      10. Updated the NULL-handling document.
                                      11. Allow NULL arguments in sqlite_compile() and sqlite_step().
                                      12. Many minor bug fixes
                                      13. @@ -5829,7 +5276,7 @@

                                      2003-05-17 (2.8.1)

                                        -
                                      1. Reactivated the VACUUM command that reclaims unused disk space in +
                                      2. Reactivated the VACUUM command that reclaims unused disk space in a database file.
                                      3. Added the ATTACH and DETACH commands to allow interacting with multiple database files at the same time.
                                      4. @@ -5874,7 +5321,7 @@
                                      5. The optimizer will now scan tables in the reverse if doing so will satisfy an ORDER BY ... DESC clause.
                                      6. The full pathname of the database file is now remembered even if - a relative path is passed into sqlite_open(). This allows + a relative path is passed into sqlite_open(). This allows the library to continue operating correctly after a chdir().
                                      7. Speed improvements in the VDBE.
                                      8. Lots of little bug fixes.
                                      9. @@ -6162,7 +5609,7 @@
                                      10. Added the subquery flattening optimizer.
                                      11. Modified the B-Tree and Pager modules so that disk pages that do not contain real data (free pages) are not journaled and are not - written from memory back to the disk when they change. This does not + written from memory back to the disk when they change. This does not impact database integrity, since the pages contain no real data, but it does make large INSERT operations about 2.5 times faster and large DELETEs about 5 times faster.
                                      12. @@ -6197,7 +5644,7 @@

                                        2002-02-13 (2.3.1)

                                        1. Bug fix: An assertion was failing if "PRAGMA full_column_names=ON;" was - set and you did a query that used a rowid, like this: + set and you did a query that used a rowid, like this: "SELECT rowid, * FROM ...".

                                        @@ -6211,7 +5658,7 @@ clause for details.
                                      13. Temporary files are now automatically deleted by the operating system when closed. There are no more dangling temporary files on a program - crash. (If the OS crashes, fsck will delete the file after reboot + crash. (If the OS crashes, fsck will delete the file after reboot under Unix. I do not know what happens under Windows.)
                                      14. NOT NULL constraints are honored.
                                      15. The COPY command puts NULLs in columns whose data is '\N'.
                                      16. @@ -6270,7 +5717,7 @@

                                        2001-12-22 (2.2.0)

                                        1. Columns of type INTEGER PRIMARY KEY are actually used as the primary key in underlying B-Tree representation of the table.
                                        2. -
                                        3. Several obscure, unrelated bugs were found and fixed while +
                                        4. Several obscure, unrelated bugs were found and fixed while implemented the integer primary key change of the previous bullet.
                                        5. Added the ability to specify "*" as part of a larger column list in the result section of a SELECT statement. For example: @@ -6299,7 +5746,7 @@

                                        2001-12-06 (2.1.5)

                                          -
                                        1. Fix for another problem (unrelated to the one fixed in 2.1.4) +
                                        2. Fix for another problem (unrelated to the one fixed in 2.1.4) that sometimes causes sqlite_exec() to return SQLITE_PROTOCOL unnecessarily. This time the bug was in the POSIX locking code and should not effect Windows users.
                                        3. @@ -6318,7 +5765,7 @@

                                        2001-11-24 (2.1.3)

                                          -
                                        1. Fix the behavior of comparison operators +
                                        2. Fix the behavior of comparison operators (ex: "<", "==", etc.) so that they are consistent with the order of entries in an index.
                                        3. Correct handling of integers in SQL expressions that are larger than @@ -6329,10 +5776,10 @@

                                          2001-11-23 (2.1.2)

                                          1. Changes to support 64-bit architectures.
                                          2. Fix a bug in the locking protocol.
                                          3. -
                                          4. Fix a bug that could (rarely) cause the database to become +
                                          5. Fix a bug that could (rarely) cause the database to become unreadable after a DROP TABLE due to corruption to the SQLITE_MASTER table.
                                          6. -
                                          7. Change the code so that version 2.1.1 databases that were rendered +
                                          8. Change the code so that version 2.1.1 databases that were rendered unreadable by the above bug can be read by this version of the library even though the SQLITE_MASTER table is (slightly) corrupted.
                                          9. @@ -6547,7 +5994,7 @@

                                            2001-03-14 (1.0.24)

                                            1. Fix a bug which was causing the UPDATE command to fail on systems where "malloc(0)" returns - NULL. The problem does not appear on Windows, Linux, or HPUX but does + NULL. The problem does not appear on Windows, Linux, or HPUX but does cause the library to fail on QNX.
                                            2. @@ -6630,7 +6077,7 @@

                                            2000-10-17 (1.0.12)

                                              -
                                            1. Fixed an off-by-one error that was causing a coredump in +
                                            2. Fixed an off-by-one error that was causing a coredump in the '%q' format directive of the new sqlite_..._printf() routines.
                                            3. Added the sqlite_interrupt() interface.
                                            4. @@ -6649,7 +6096,7 @@

                                              2000-10-09 (1.0.9)

                                              1. Added the sqlite_..._printf() interface routines.
                                              2. -
                                              3. Modified the sqlite shell program to use the new interface +
                                              4. Modified the sqlite shell program to use the new interface routines.
                                              5. Modified the sqlite shell program to print the schema for the built-in SQLITE_MASTER table, if explicitly requested.
                                              6. @@ -6761,7 +6208,7 @@

                                              2000-07-28

                                                -
                                              1. Added the sqlite_busy_handler() +
                                              2. Added the sqlite_busy_handler() and sqlite_busy_timeout() interface.

                                              @@ -6816,15 +6263,15 @@

                                            2000-06-02

                                              -
                                            1. All database files to be modified by an UPDATE, INSERT or DELETE are -now locked before any changes are made to any files. +
                                            2. All database files to be modified by an UPDATE, INSERT or DELETE are +now locked before any changes are made to any files. This makes it safe (I think) to access the same database simultaneously from multiple processes.
                                            3. The code appears stable so we are now calling it "beta".

                                            2000-06-01

                                              -
                                            1. Better support for file locking so that two or more processes +
                                            2. Better support for file locking so that two or more processes (or threads) can access the same database simultaneously. More work needed in this area, though.
                                            3. @@ -6838,14 +6285,14 @@

                                            2000-05-30

                                            1. Added the LIKE operator.
                                            2. -
                                            3. Added a GLOB operator: similar to LIKE -but it uses Unix shell globbing wildcards instead of the '%' +
                                            4. Added a GLOB operator: similar to LIKE +but it uses Unix shell globbing wildcards instead of the '%' and '_' wildcards of SQL.
                                            5. -
                                            6. Added the COPY command patterned after +
                                            7. Added the COPY command patterned after PostgreSQL so that SQLite can now read the output of the pg_dump database dump utility of PostgreSQL.
                                            8. -
                                            9. Added a VACUUM command that calls the +
                                            10. Added a VACUUM command that calls the gdbm_reorganize() function on the underlying database files.
                                            11. And many, many bug fixes...
                                            12. @@ -6858,4 +6305,3 @@ - diff -Nru sqlite3-3.42.0/www/chronology.html sqlite3-3.44.0-0/www/chronology.html --- sqlite3-3.42.0/www/chronology.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/chronology.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

                                              History Of SQLite Releases

                                              @@ -125,681 +101,641 @@ DateVersion -2023-05-16 -3.42.0 -2023-03-22 -3.41.2 -2023-03-10 -3.41.1 -2023-02-21 -3.41.0 -2022-12-28 -3.40.1 -2022-11-16 -3.40.0 -2022-09-29 -3.39.4 -2022-09-05 -3.39.3 -2022-07-21 -3.39.2 -2022-07-13 -3.39.1 -2022-06-25 -3.39.0 -2022-05-06 -3.38.5 -2022-05-04 -3.38.4 -2022-04-27 -3.38.3 -2022-03-26 -3.38.2 -2022-03-12 -3.38.1 -2022-02-22 -3.38.0 -2022-01-06 -3.37.2 -2021-12-30 -3.37.1 -2021-11-27 -3.37.0 -2021-06-18 +2021-06-18 3.36.0 -2021-04-19 +2021-04-19 3.35.5 -2021-04-02 +2021-04-02 3.35.4 -2021-03-26 +2021-03-26 3.35.3 -2021-03-17 +2021-03-17 3.35.2 -2021-03-15 +2021-03-15 3.35.1 -2021-03-12 +2021-03-12 3.35.0 -2021-01-20 +2021-01-20 3.34.1 -2020-12-01 +2020-12-01 3.34.0 -2020-08-14 +2020-08-14 3.33.0 -2020-06-18 +2020-06-18 3.32.3 -2020-06-04 +2020-06-04 3.32.2 -2020-05-25 +2020-05-25 3.32.1 -2020-05-22 +2020-05-22 3.32.0 -2020-01-27 +2020-01-27 3.31.1 -2020-01-22 +2020-01-22 3.31.0 -2019-10-10 +2019-10-10 3.30.1 -2019-10-04 +2019-10-04 3.30.0 -2019-07-10 +2019-07-10 3.29.0 -2019-04-16 +2019-04-16 3.28.0 -2019-02-25 +2019-02-25 3.27.2 -2019-02-08 +2019-02-08 3.27.1 -2019-02-07 +2019-02-07 3.27.0 -2018-12-01 +2018-12-01 3.26.0 -2018-11-05 +2018-11-05 3.25.3 -2018-09-25 +2018-09-25 3.25.2 -2018-09-18 +2018-09-18 3.25.1 -2018-09-15 +2018-09-15 3.25.0 -2018-06-04 +2018-06-04 3.24.0 -2018-04-10 +2018-04-10 3.23.1 -2018-04-02 +2018-04-02 3.23.0 -2018-01-22 +2018-01-22 3.22.0 -2017-10-24 +2017-10-24 3.21.0 -2017-08-24 +2017-08-24 3.20.1 -2017-08-01 +2017-08-01 3.20.0 -2017-06-17 +2017-06-17 3.18.2 -2017-06-16 +2017-06-16 3.18.1 -2017-06-08 +2017-06-08 3.19.3 -2017-05-25 +2017-05-25 3.19.2 -2017-05-24 +2017-05-24 3.19.1 -2017-05-22 +2017-05-22 3.19.0 -2017-03-28 +2017-03-28 3.18.0 -2017-02-13 +2017-02-13 3.17.0 -2017-01-06 +2017-01-06 3.16.2 -2017-01-03 +2017-01-03 3.16.1 -2017-01-02 +2017-01-02 3.16.0 -2016-11-28 +2016-11-28 3.15.2 -2016-11-04 +2016-11-04 3.15.1 -2016-10-14 +2016-10-14 3.15.0 -2016-09-12 +2016-09-12 3.14.2 -2016-08-11 +2016-08-11 3.14.1 -2016-08-08 +2016-08-08 3.14 -2016-05-18 +2016-05-18 3.13.0 -2016-04-18 +2016-04-18 3.12.2 -2016-04-08 +2016-04-08 3.12.1 -2016-03-31 +2016-03-31 3.9.3 -2016-03-29 +2016-03-29 3.12.0 -2016-03-03 +2016-03-03 3.11.1 -2016-02-15 +2016-02-15 3.11.0 -2016-01-20 +2016-01-20 3.10.2 -2016-01-14 +2016-01-14 3.10.1 -2016-01-06 +2016-01-06 3.10.0 -2015-11-02 +2015-11-02 3.9.2 -2015-10-16 +2015-10-16 3.9.1 -2015-10-14 +2015-10-14 3.9.0 -2015-07-29 +2015-07-29 3.8.11.1 -2015-07-27 +2015-07-27 3.8.11 -2015-05-20 +2015-05-20 3.8.10.2 -2015-05-09 +2015-05-09 3.8.10.1 -2015-05-07 +2015-05-07 3.8.10 -2015-04-08 +2015-04-08 3.8.9 -2015-02-25 +2015-02-25 3.8.8.3 -2015-01-30 +2015-01-30 3.8.8.2 -2015-01-20 +2015-01-20 3.8.8.1 -2015-01-16 +2015-01-16 3.8.8 -2014-12-09 +2014-12-09 3.8.7.4 -2014-12-05 +2014-12-05 3.8.7.3 -2014-11-18 +2014-11-18 3.8.7.2 -2014-10-29 +2014-10-29 3.8.7.1 -2014-10-22 +2014-10-22 3.8.6.1 -2014-10-17 +2014-10-17 3.8.7 -2014-08-15 +2014-08-15 3.8.6 -2014-06-04 +2014-06-04 3.8.5 -2014-04-03 +2014-04-03 3.8.4.3 -2014-03-26 +2014-03-26 3.8.4.2 -2014-03-11 +2014-03-11 3.8.4.1 -2014-03-10 +2014-03-10 3.8.4 -2014-02-11 +2014-02-11 3.8.3.1 -2014-02-03 +2014-02-03 3.8.3 -2013-12-06 +2013-12-06 3.8.2 -2013-10-17 +2013-10-17 3.8.1 -2013-09-03 +2013-09-03 3.8.0.2 -2013-08-29 +2013-08-29 3.8.0.1 -2013-08-26 +2013-08-26 3.8.0 -2013-05-20 +2013-05-20 3.7.17 -2013-04-12 +2013-04-12 3.7.16.2 -2013-03-29 +2013-03-29 3.7.16.1 -2013-03-18 +2013-03-18 3.7.16 -2013-01-09 +2013-01-09 3.7.15.2 -2012-12-19 +2012-12-19 3.7.15.1 -2012-12-12 +2012-12-12 3.7.15 -2012-10-04 +2012-10-04 3.7.14.1 -2012-09-03 +2012-09-03 3.7.14 -2012-06-11 +2012-06-11 3.7.13 -2012-05-22 +2012-05-22 3.7.12.1 -2012-05-14 +2012-05-14 3.7.12 -2012-05-14 +2012-05-14 3.7.12 -2012-05-14 +2012-05-14 3.7.12 -2012-03-20 +2012-03-20 3.7.11 -2012-01-16 +2012-01-16 3.7.10 -2011-11-01 +2011-11-01 3.7.9 -2011-09-19 +2011-09-19 3.7.8 -2011-06-28 +2011-06-28 3.7.7.1 -2011-06-23 +2011-06-23 3.7.7 -2011-05-19 +2011-05-19 3.7.6.3 -2011-04-17 +2011-04-17 3.7.6.2 -2011-04-13 +2011-04-13 3.7.6.1 -2011-04-12 +2011-04-12 3.7.6 -2011-02-01 +2011-02-01 3.7.5 -2010-12-07 +2010-12-07 3.7.4 -2010-10-08 +2010-10-08 3.7.3 -2010-08-24 +2010-08-24 3.7.2 -2010-08-23 +2010-08-23 3.7.1 -2010-08-04 +2010-08-04 3.7.0.1 -2010-07-21 +2010-07-21 3.7.0 -2010-03-26 +2010-03-26 3.6.23.1 -2010-03-09 +2010-03-09 3.6.23 -2010-01-06 +2010-01-06 3.6.22 -2009-12-07 +2009-12-07 3.6.21 -2009-11-04 +2009-11-04 3.6.20 -2009-10-30 +2009-10-30 3.6.16.1 -2009-10-14 +2009-10-14 3.6.19 -2009-09-11 +2009-09-11 3.6.18 -2009-08-10 +2009-08-10 3.6.17 -2009-06-27 +2009-06-27 3.6.16 -2009-06-15 +2009-06-15 3.6.15 -2009-05-25 +2009-05-25 3.6.14.2 -2009-05-19 +2009-05-19 3.6.14.1 -2009-05-07 +2009-05-07 3.6.14 -2009-04-13 +2009-04-13 3.6.13 -2009-03-31 +2009-03-31 3.6.12 -2009-02-18 +2009-02-18 3.6.11 -2009-01-15 +2009-01-15 3.6.10 -2009-01-14 +2009-01-14 3.6.9 -2009-01-12 +2009-01-12 3.6.8 -2008-12-16 +2008-12-16 3.6.7 -2008-11-26 +2008-11-26 3.6.6.2 -2008-11-22 +2008-11-22 3.6.6.1 -2008-11-19 +2008-11-19 3.6.6 -2008-11-12 +2008-11-12 3.6.5 -2008-10-15 +2008-10-15 3.6.4 -2008-09-22 +2008-09-22 3.6.3 -2008-08-30 +2008-08-30 3.6.2 -2008-08-06 +2008-08-06 3.6.1 -2008-07-16 +2008-07-16 3.6.0 -2008-05-14 +2008-05-14 3.5.9 -2008-04-16 +2008-04-16 3.5.8 -2008-03-17 +2008-03-17 3.5.7 -2008-02-06 +2008-02-06 3.5.6 -2008-01-31 +2008-01-31 3.5.5 -2007-12-14 +2007-12-14 3.5.4 -2007-11-27 +2007-11-27 3.5.3 -2007-11-05 +2007-11-05 3.5.2 -2007-10-04 +2007-10-04 3.5.1 -2007-09-04 +2007-09-04 3.5.0 -2007-08-13 +2007-08-13 3.4.2 -2007-07-20 +2007-07-20 3.4.1 -2007-06-18 +2007-06-18 3.4.0 -2007-04-25 +2007-04-25 3.3.17 -2007-04-18 +2007-04-18 3.3.16 -2007-04-09 +2007-04-09 3.3.15 -2007-04-02 +2007-04-02 3.3.14 -2007-02-13 +2007-02-13 3.3.13 -2007-01-27 +2007-01-27 3.3.12 -2007-01-22 +2007-01-22 3.3.11 -2007-01-10 +2007-01-10 3.3.10 -2007-01-04 +2007-01-04 3.3.9 -2006-10-09 +2006-10-09 3.3.8 -2006-08-12 +2006-08-12 3.3.7 -2006-06-06 +2006-06-06 3.3.6 -2006-04-05 +2006-04-05 3.3.5 -2006-02-11 +2006-02-11 3.3.4 -2006-01-31 +2006-01-31 3.3.3 -2006-01-24 +2006-01-24 3.3.2 -2006-01-16 +2006-01-16 3.3.1 -2006-01-11 +2006-01-11 3.3.0 -2005-12-19 +2005-12-19 2.8.17 -2005-12-19 +2005-12-19 3.2.8 -2005-09-24 +2005-09-24 3.2.7 -2005-09-17 +2005-09-17 3.2.6 -2005-08-27 +2005-08-27 3.2.5 -2005-08-24 +2005-08-24 3.2.4 -2005-08-21 +2005-08-21 3.2.3 -2005-06-12 +2005-06-12 3.2.2 -2005-03-29 +2005-03-29 3.2.1 -2005-03-21 +2005-03-21 3.2.0 -2005-03-17 +2005-03-17 3.1.6 -2005-03-11 +2005-03-11 3.1.5 -2005-03-11 +2005-03-11 3.1.4 -2005-02-28 +2005-02-28 3.1.3.1 -2005-02-20 +2005-02-20 3.1.3 -2005-02-15 +2005-02-15 3.1.2 -2005-02-15 +2005-02-15 2.8.16 -2005-02-01 +2005-02-01 3.1.1 -2005-01-21 +2005-01-21 3.1.0 -2004-10-12 +2004-10-12 3.0.8 -2004-09-18 +2004-09-18 3.0.7 -2004-09-02 +2004-09-02 3.0.6 -2004-08-29 +2004-08-29 3.0.5 -2004-08-09 +2004-08-09 3.0.4 -2004-07-22 +2004-07-22 3.0.3 -2004-07-22 +2004-07-22 2.8.15 -2004-06-30 +2004-06-30 3.0.2 -2004-06-22 +2004-06-22 3.0.1 -2004-06-18 +2004-06-18 3.0.0 -2004-06-09 +2004-06-09 2.8.14 -2004-03-08 +2004-03-08 2.8.13 -2004-02-08 +2004-02-08 2.8.12 -2004-01-14 +2004-01-14 2.8.11 -2004-01-14 +2004-01-14 2.8.10 -2004-01-06 +2004-01-06 2.8.9 -2003-12-18 +2003-12-18 2.8.8 -2003-12-04 +2003-12-04 2.8.7 -2003-08-22 +2003-08-22 2.8.6 -2003-07-22 +2003-07-22 2.8.5 -2003-06-29 +2003-06-29 2.8.4 -2003-06-04 +2003-06-04 2.8.3 -2003-05-17 +2003-05-17 2.8.2 -2003-05-17 +2003-05-17 2.8.1 -2003-02-16 +2003-02-16 2.8.0 -2003-01-25 +2003-01-25 2.7.6 -2002-12-28 +2002-12-28 2.7.5 -2002-12-17 +2002-12-17 2.7.4 -2002-10-31 +2002-10-31 2.7.3 -2002-09-25 +2002-09-25 2.7.2 -2002-08-31 +2002-08-31 2.7.1 -2002-08-25 +2002-08-25 2.7.0 -2002-08-13 +2002-08-13 2.6.3 -2002-07-31 +2002-07-31 2.6.2 -2002-07-19 +2002-07-19 2.6.1 -2002-07-18 +2002-07-18 2.6.0 -2002-07-07 +2002-07-07 2.5.6 -2002-07-06 +2002-07-06 2.5.5 -2002-07-01 +2002-07-01 2.5.4 -2002-06-25 +2002-06-25 2.5.3 -2002-06-25 +2002-06-25 2.5.2 -2002-06-19 +2002-06-19 2.5.1 -2002-06-17 +2002-06-17 2.5.0 -2002-05-10 +2002-05-10 2.4.12 -2002-05-08 +2002-05-08 2.4.11 -2002-05-03 +2002-05-03 2.4.10 -2002-04-22 +2002-04-22 2.4.9 -2002-04-20 +2002-04-20 2.4.8 -2002-04-12 +2002-04-12 2.4.7 -2002-04-02 +2002-04-02 2.4.6 -2002-04-02 +2002-04-02 2.4.5 -2002-03-30 +2002-03-30 2.4.4 -2002-03-23 +2002-03-23 2.4.3 -2002-03-20 +2002-03-20 2.4.2 -2002-03-13 +2002-03-13 2.4.1 -2002-03-13 +2002-03-13 2.4.1 -2002-03-11 +2002-03-11 2.4.0 -2002-02-19 +2002-02-19 2.3.3 -2002-02-14 +2002-02-14 2.3.2 -2002-02-13 +2002-02-13 2.3.1 -2002-02-03 +2002-02-03 2.3.0 -2002-01-28 +2002-01-28 2.2.5 -2002-01-22 +2002-01-22 2.2.4 -2002-01-16 +2002-01-16 2.2.3 -2002-01-14 +2002-01-14 2.2.2 -2002-01-09 +2002-01-09 2.2.1 -2001-12-22 +2001-12-22 2.2.0 -2001-12-15 +2001-12-15 2.1.7 -2001-12-14 +2001-12-14 2.1.6 -2001-12-06 +2001-12-06 2.1.5 -2001-12-05 +2001-12-05 2.1.4 -2001-11-24 +2001-11-24 2.1.3 -2001-11-23 +2001-11-23 2.1.2 -2001-11-13 +2001-11-13 2.1.1 -2001-11-12 +2001-11-12 2.1.0 -2001-11-04 +2001-11-04 2.0.8 -2001-10-22 +2001-10-22 2.0.7 -2001-10-19 +2001-10-19 2.0.6 -2001-10-15 +2001-10-15 2.0.5 -2001-10-13 +2001-10-13 2.0.4 -2001-10-13 +2001-10-13 2.0.3 -2001-10-09 +2001-10-09 2.0.2 -2001-10-02 +2001-10-02 2.0.1 -2001-09-28 +2001-09-28 2.0.0 -2001-07-23 +2001-07-23 1.0.32 -2001-04-15 +2001-04-15 1.0.31 -2001-04-06 +2001-04-06 1.0.30 -2001-04-05 +2001-04-05 1.0.29 -2001-04-04 +2001-04-04 1.0.28 -2001-03-20 +2001-03-20 1.0.27 -2001-03-20 +2001-03-20 1.0.26 -2001-03-15 +2001-03-15 1.0.25 -2001-03-14 +2001-03-14 1.0.24 -2001-02-20 +2001-02-20 1.0.23 -2001-02-19 +2001-02-19 1.0.22 -2001-02-19 +2001-02-19 1.0.21 -2001-02-11 +2001-02-11 1.0.20 -2001-02-06 +2001-02-06 1.0.19 -2001-01-04 +2001-01-04 1.0.18 -2000-12-10 +2000-12-10 1.0.17 -2000-11-28 +2000-11-28 1.0.16 -2000-10-23 +2000-10-23 1.0.15 -2000-10-19 +2000-10-19 1.0.14 -2000-10-19 +2000-10-19 1.0.13 -2000-10-17 +2000-10-17 1.0.12 -2000-10-11 +2000-10-11 1.0.10 -2000-10-09 +2000-10-09 1.0.9 -2000-09-30 +2000-09-30 1.0.8 -2000-09-14 +2000-09-14 1.0.5 -2000-08-28 +2000-08-28 1.0.4 -2000-08-22 +2000-08-22 1.0.3 -2000-08-18 +2000-08-18 1.0.1 -2000-08-17 +2000-08-17 1.0 @@ -877,9 +813,8 @@ if (isNaN(aa)) aa = 0; bb = parseFloat(b.cells[i].textContent); if (isNaN(bb)) bb = 0; - if(aabb) return +1; - return a.rowIndex-b.rowIndex; + if(aa==bb) return a.rowIndex-b.rowIndex; + return aa-bb; } this.sortKey = function(a,b) { var i = thisObject.sortIndex; @@ -921,12 +856,11 @@ } this.setHdrIcons() } -var t = new SortableTable(document.getElementById("chrontab"),"nK",1); +var t = new SortableTable(document.getElementById("chrontab"),"TK",1);

                                              -338 releases -over 22.7 years. +318 releases +over 20.8 years. -

                                              This page last modified on 2023-03-03 01:19:02 UTC

                                              diff -Nru sqlite3-3.42.0/www/c_interface.html sqlite3-3.44.0-0/www/c_interface.html --- sqlite3-3.42.0/www/c_interface.html 2023-05-16 13:43:10.000000000 +0000 +++ sqlite3-3.44.0-0/www/c_interface.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

                                              @@ -259,7 +235,7 @@

                                              The names of the columns are contained in first argc entries of the fourth argument. -If the SHOW_DATATYPES pragma +If the SHOW_DATATYPES pragma is on (it is off by default) then the second argc entries in the 4th argument are the datatypes for the corresponding columns. @@ -569,7 +545,7 @@ the sqlite_exec interface. Except, with sqlite_step the column datatype information is always included in the in the 4th parameter regardless of whether or not the -SHOW_DATATYPES pragma +SHOW_DATATYPES pragma is on or off.

                                              @@ -1237,5 +1213,4 @@ See also the sources to the Tcl interface for SQLite in the source file src/tclsqlite.c.

                                              -

                                              This page last modified on 2023-01-06 00:45:39 UTC

                                              diff -Nru sqlite3-3.42.0/www/cintro.html sqlite3-3.44.0-0/www/cintro.html --- sqlite3-3.42.0/www/cintro.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/cintro.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                              @@ -177,7 +153,7 @@

                                            13. sqlite3_prepare() → Compile SQL text into -byte-code that will do the work of querying or updating the database. +byte-code that will do the work of querying or updating the database. The constructor for sqlite3_stmt.

                                            14. sqlite3_bind() → @@ -218,7 +194,7 @@ provides detailed specifications for all C/C++ APIs for SQLite. Once the reader - understands the basic principles of operation for SQLite, + understands the basic principles of operation for SQLite, that document should be used as a reference guide. This article is intended as introduction only and is neither a complete nor authoritative reference for the SQLite API. @@ -269,7 +245,7 @@ The list mentions sqlite3_column() when in fact no such routine exists. The "sqlite3_column()" shown in the list is a placeholder for - an entire family of routines that extract column + an entire family of routines that extra column data in various datatypes.

                                              @@ -281,7 +257,7 @@
                                            15. sqlite3_open()

                                              - This routine + This routine opens a connection to an SQLite database file and returns a database connection object. This is often the first SQLite API call that an application makes and is a prerequisite for most other @@ -326,13 +302,13 @@ set for a prepared statement that is being evaluated by sqlite3_step(). Each time sqlite3_step() stops with a new result set row, this routine can be called multiple times to find the values of all columns in that row. - +

                                              As noted above, there really is no such thing as a "sqlite3_column()" function in the SQLite API. Instead, what we here call "sqlite3_column()" is a place-holder for an entire family of functions that return a value from the result set in various data types. There are also routines in this family that return the size of the result (if it is a string or - BLOB) and the number of columns in the result set. + BLOB) and the number of columns in the result set.

                                              • sqlite3_column_blob()
                                              • @@ -398,7 +374,7 @@
                                              • Create a prepared statement using sqlite3_prepare().
                                              • Evaluate the prepared statement by calling sqlite3_step() one or more times.
                                              • -
                                              • For queries, extract results by calling +
                                              • For queries, extract results by calling sqlite3_column() in between two calls to sqlite3_step().
                                              • Destroy the prepared statement using sqlite3_finalize().
                                              • @@ -472,11 +448,9 @@

                                                - SQLite allows a parameter wherever a string literal, - blob literal, numeric constant, or NULL is allowed - in queries or data modification statements. (DQL or DML) - (Parameters may not be used for column or table names, - or as values for constraints or default values. (DDL)) + SQLite allows a parameter wherever + a string literal, numeric constant, or NULL is allowed. + (Parameters may not be used for column or table names.) A parameter takes one of the following forms:

                                                @@ -530,9 +504,9 @@
                                              • Set up a process-wide error log.
                                              • Specify an application-defined page cache.
                                              • Adjust the use of mutexes so that they are appropriate for various - threading models, or substitute an + threading models, or substitute an application-defined mutex system. -
                                              +
                                            16. After process-wide configuration is complete and database connections have been created, individual database connections can be configured using @@ -561,7 +535,7 @@

                                              - The sqlite3_create_function() interface creates new SQL functions - + The sqlite3_create_function() interface creates new SQL functions - either scalar or aggregate. The new function implementation typically makes use of the following additional interfaces:

                                              @@ -576,7 +550,7 @@

                                              All of the built-in SQL functions of SQLite are created using exactly these same interfaces. Refer to the SQLite source code, and in particular - the + the date.c and func.c source files for examples. @@ -591,12 +565,11 @@ This article only mentions the most important and most commonly used SQLite interfaces. The SQLite library includes many other APIs implementing useful - features that are not described here. + features that are not described here. A complete list of functions that form the SQLite application programming interface is found at the C/C++ Interface Specification. Refer to that document for complete and authoritative information about all SQLite interfaces.

                                              -

                                              This page last modified on 2022-12-31 21:51:03 UTC

                                              diff -Nru sqlite3-3.42.0/www/cksumvfs.html sqlite3-3.44.0-0/www/cksumvfs.html --- sqlite3-3.42.0/www/cksumvfs.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/cksumvfs.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                              @@ -310,5 +286,4 @@ the database file does not have a reserve bytes value of 8. The pragma will return no rows at all if the cksumvfs extension is not loaded. -

                                              This page last modified on 2022-01-08 05:02:57 UTC

                                              - +

                                              diff -Nru sqlite3-3.42.0/www/cli.html sqlite3-3.44.0-0/www/cli.html --- sqlite3-3.42.0/www/cli.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/cli.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                              @@ -128,51 +104,38 @@
                                              - - - - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
                                              +
                                              @@ -136,5 +112,4 @@ this document is available in the SQLite Documentation source repository: https://www.sqlite.org/docsrc/finfo/pages/codeofconduct.in -

                                              This page last modified on 2022-01-08 05:02:57 UTC

                                              diff -Nru sqlite3-3.42.0/www/codeofethics.html sqlite3-3.44.0-0/www/codeofethics.html --- sqlite3-3.42.0/www/codeofethics.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/codeofethics.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                              @@ -332,5 +308,4 @@
                                            17. Never despair of God's mercy.
                                            -

                                            This page last modified on 2022-01-08 05:02:57 UTC

                                            diff -Nru sqlite3-3.42.0/www/compile.html sqlite3-3.44.0-0/www/compile.html --- sqlite3-3.42.0/www/compile.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/compile.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                            +
                                            @@ -183,5 +159,4 @@ will try to return new completions taken from function and pragma names and other sources, as well as consider more context. The completion table should be considered a work-in-progress. -

                                            This page last modified on 2022-01-08 05:02:57 UTC

                                            - +

                                            diff -Nru sqlite3-3.42.0/www/conflict.html sqlite3-3.44.0-0/www/conflict.html --- sqlite3-3.42.0/www/conflict.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/conflict.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

                                            Constraint Conflict Resolution in SQLite

                                            @@ -175,5 +151,4 @@ or updating the current row. Thus the insert or update always occurs. The command continues executing normally. No error is returned.

                                            -

                                            This page last modified on 2022-01-08 05:02:57 UTC

                                            diff -Nru sqlite3-3.42.0/www/consortium_agreement-20071201.html sqlite3-3.44.0-0/www/consortium_agreement-20071201.html --- sqlite3-3.42.0/www/consortium_agreement-20071201.html 2023-05-16 13:43:06.000000000 +0000 +++ sqlite3-3.44.0-0/www/consortium_agreement-20071201.html 2023-11-04 14:24:19.000000000 +0000 @@ -212,7 +212,7 @@

                                            2.3.6 Disaster Planning

                                            Hwaci shall maintain backup copies of all SQLite source files and documentation, current and historical, -at least two separate locations separated from each +at at least two separate locations separated from each other and from the primary on-line SQLite repository by at least 400 kilometers.

                                            diff -Nru sqlite3-3.42.0/www/consortium.html sqlite3-3.44.0-0/www/consortium.html --- sqlite3-3.42.0/www/consortium.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/consortium.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                            @@ -247,5 +223,4 @@ -

                                            This page last modified on 2022-01-08 05:02:57 UTC

                                            diff -Nru sqlite3-3.42.0/www/copyright.html sqlite3-3.44.0-0/www/copyright.html --- sqlite3-3.42.0/www/copyright.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/copyright.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                            @@ -136,7 +112,7 @@ have signed affidavits dedicating their contributions to the public domain and originals of those signed affidavits are stored in a firesafe at the main offices -of Hwaci. All contributors are citizens +of Hwaci. All contibutors are citizens of countries that allow creative works to be dedicated into the public domain. Anyone is free to copy, modify, publish, use, compile, sell, or distribute @@ -235,5 +211,4 @@ change and you include a patch as a proof-of-concept, that would be great. However, please do not be offended if we rewrite your patch from scratch. -

                                            This page last modified on 2022-04-18 02:55:50 UTC

                                            diff -Nru sqlite3-3.42.0/www/cpu.html sqlite3-3.44.0-0/www/cpu.html --- sqlite3-3.42.0/www/cpu.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/cpu.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                            @@ -373,5 +349,4 @@ Time spent doing I/O is not reflected in the CPU cycle counts, and I/O time predominates in many SQLite usage scenarios.

                                            -

                                            This page last modified on 2022-01-08 05:02:57 UTC

                                            diff -Nru sqlite3-3.42.0/www/crew.html sqlite3-3.44.0-0/www/crew.html --- sqlite3-3.42.0/www/crew.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/crew.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                            @@ -164,5 +140,4 @@ software industry since 1994.
                                            -

                                            This page last modified on 2022-01-08 05:02:57 UTC

                                            - +

                                            diff -Nru sqlite3-3.42.0/www/csv.html sqlite3-3.44.0-0/www/csv.html --- sqlite3-3.42.0/www/csv.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/csv.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                            @@ -236,5 +212,4 @@ the values found in the first line of the CSV file become the column names. If the schema= argument is omitted and header is false, then the columns are named "c0", "c1", "c2", and so forth. -

                                            This page last modified on 2022-01-08 05:02:57 UTC

                                            - +

                                            diff -Nru sqlite3-3.42.0/www/custombuild.html sqlite3-3.44.0-0/www/custombuild.html --- sqlite3-3.42.0/www/custombuild.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/custombuild.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
                                            @@ -131,7 +107,7 @@ SQLite is to use the amalgamation code file, sqlite3.c, and its corresponding header file sqlite3.h. The sqlite3.c code file should compile and -run on any Unix, Windows system without any changes +run on any unix, Windows system without any changes or special compiler options. Most applications can simply include the sqlite3.c file together with the other C code files that make up the application, compile them all together, and have working @@ -255,7 +231,7 @@

    There are two separate configuration changes here which can -be used either together or separately. The +be used either togethr or separately. The SQLITE_CONFIG_MULTITHREAD setting disables the mutexes that serialize access to database connection objects and prepared statement objects. With this setting, the application @@ -399,5 +375,4 @@ official SQLite API and is not otherwise provided when compiled with -DSQLITE_OS_OTHER=1, so the auxiliary C code file should probably provide it for completeness.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/cves.html sqlite3-3.44.0-0/www/cves.html --- sqlite3-3.42.0/www/cves.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/cves.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -223,7 +199,7 @@ SQLite contains authoritative information. CVEs often contain inaccuracies. The SQLite developers have attempted to add clarifications and -corrections to CVEs about SQLite. +corrections to CVEs about SQLite, but without success.

  • @@ -396,117 +372,15 @@ -CVE-2022-46908 - -Bug not in the SQLite library -This is a bug in the --safe command-line option of the command-line shell - program that is available for accessing SQLite database files. The bug does - not exist in the SQLite library. Nor is it an issue for the CLI as long as - the user does not depend on the --safe option. It is not serious. It is - debatable whether or not this is a security issue. - - - -CVE-2022-38627 - -Not a bug -This is not a bug in SQLite. This is an - SQL injection bug in a specific - PHP application. In other words, the bug is in the PHP application code, not - in SQLite. Even though this CVE is not about SQLite, "SQLite" is - mentioned in the publicity about the bug and so we list it here. - - - -CVE-2022-35737 - -3.39.2
    (2022-07-21) -This bug is an array-bounds overflow. The bug is only accessible when using some - of the C-language APIs provided by SQLite. The bug cannot be reached using SQL - nor can it be reached by providing SQLite with a corrupt database file. - The bug only comes up when very long string inputs (greater than 2 billion bytes - in length) are provided as arguments to a few specific C-language interfaces, - and even then only under special circumstances. - - - -CVE-2022-24854 - -Not a bug -This CVE describes a bug in an application that uses SQLite, not in SQLite itself. - SQLite is doing everything correctly. The application grants users the ability to - run SQL statements, using SQLite, that can leak or change information that those users - should not normally have access to. This is purely an application bug. It does not - describe a malfunction or vulnerability in SQLite. - - - -CVE-2022-21227 - -Not a bug -This CVE describes a bug in a third-party packages that provides a binding - for SQLite to Node.js. The bug reported is in the third-party Node.js binding, - not in SQLite itself. Do not be confused by the use of the word "SQLite" in the - ambiguously-worded CVE description. - - - -CVE-2021-45346 - -Not a bug -This CVE is misinformation. See the discussion around - SQLite forum post 53de8864ba114bf. - - - -CVE-2021-42169 - -Not a bug -This CVE has nothing whatsoever to do with SQLite. It is about a bug in - application that happens to use SQLite. Since SQLite is mentioned in the - CVE description, the CVE is included here to emphasize that - this is not an SQLite bug. - - - -CVE-2021-36690 - -Bug not in the SQLite library -This bug is not in the SQLite core library, but rather in an - - experimental extension that is used to implement the - .expert command in the CLI. The code that contains the bug - does not appear in standard SQLite builds, though it - is included in the sqlite3.exe command-line tool. - Applications must link against the extra source code files that - implement the extension and take other deliberate actions to - activate the extension before the troublesome code can be run. - For the rare application that uses the troublesome extension, - the consequence of this bug is that malicious SQL can cause a - NULL pointer deference and denial of service. -(details) - - - CVE-2021-28305 Not a bug -This is not a bug in SQLite. The bug is in a third-party application that +This is not a bug in SQLite. The bug is in an application that uses SQLite. SQLite is mentioned by name in the CVE description, however, so we have included the CVE in the list. -CVE-2021-23404 - -Not a bug -This is not a bug in SQLite. The bug is in a third-party application that - uses SQLite and includes "sqlite" in its name. This CVE is included on the - list because it mentions SQLite even though the bug has nothing to do - with SQLite. - - - CVE-2021-20227 3.34.1
    (2021-01-20) @@ -520,21 +394,10 @@ -CVE-2021-20223 - -3.34.0
    (2020-12-01) -The problem identified by this CVE is not a vulnerability. - It is a malfunction. A coding error causes FTS5 - to sometimes return inconsistent and incorrect results under obscure circumstances, - but no memory errors occur. -(details) - - - CVE-2020-15358 3.32.3
    (2020-06-18) -Malicious SQL statement causes a read past the end of a heap buffer. +Malicious SQL statement causes an read past the end of a heap buffer. (details) @@ -571,7 +434,7 @@ 3.32.0
    (2020-05-22) Malicious SQL statement causes a read-only use-after-free, - possibly resulting in an incorrect output from the snippet() + possibly resulting in a incorrect output from the snippet() SQL function of the FTS3 extension. There is no known way to exfiltrate data or crash the application using this bug. (details) @@ -682,7 +545,7 @@ CVE-2019-19924 3.31.0
    (2020-01-22) -Malicious SQL statement causes an uninitialized pointer reference and +Malicious SQL statement causes a uninitialized pointer reference and denial-of-service. (details) @@ -697,19 +560,6 @@ -CVE-2019-19646 - -3.31.0
    (2020-01-22) -The PRAGMA integrity_check command might cause the byte-code for a prepared - statement to loop indefinitely. This might enable a denial-of-service, if the - application has not taken appropriate and prudent steps - to limit the run-time of SQL statements. This is not a vulnerability, as there - are countless perfectly valid SQL queries, especially queries involving - recursive common table expressions, that also run essentially forever. -(details) - - - CVE-2019-19317 3.31.0
    (2020-01-22) @@ -721,5 +571,4 @@ -

    This page last modified on 2023-02-27 02:07:35 UTC

    diff -Nru sqlite3-3.42.0/www/datatype3.html sqlite3-3.44.0-0/www/datatype3.html --- sqlite3-3.42.0/www/datatype3.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/datatype3.html 2023-11-04 14:24:19.000000000 +0000 @@ -3,7 +3,7 @@ -Datatypes In SQLite +Datatypes In SQLite Version 3 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    -Datatypes In SQLite +Datatypes In SQLite Version 3
    @@ -176,18 +152,14 @@ of a value is associated with the value itself, not with its container. The dynamic type system of SQLite is backwards compatible with the more common static type systems of other database engines -in the sense that SQL statements that work on statically typed databases +in the sense that SQL statements that work on statically typed databases should work the same way in SQLite. However, the dynamic typing in SQLite allows it to do things which are not possible in traditional rigidly typed -databases. Flexible typing is a feature of SQLite, not a bug.

    - -

    Update: -As of version 3.37.0 (2021-11-27), SQLite provides STRICT tables -that do rigid type enforcement, for developers who prefer that kind of thing. +databases.

    -

    2. Storage Classes and Datatypes

    +

    2. Storage Classes and Datatypes

    Each value stored in an SQLite database (or manipulated by the database engine) has one of the following storage classes:

    @@ -195,7 +167,7 @@
  • NULL. The value is a NULL value.

    -
  • INTEGER. The value is a signed integer, stored in 0, 1, +

  • INTEGER. The value is a signed integer, stored in 1, 2, 3, 4, 6, or 8 bytes depending on the magnitude of the value.

  • REAL. The value is a floating point value, stored as @@ -209,12 +181,10 @@

  • A storage class is more general than a datatype. -The INTEGER storage class, for example, includes 7 different integer -datatypes of different lengths. -This makes a difference on disk. -But as soon as INTEGER values are read off of disk and into memory for -processing, they are converted to the most general datatype -(8-byte signed integer). +The INTEGER storage class, for example, includes 6 different integer +datatypes of different lengths. This makes a difference on disk. But +as soon as INTEGER values are read off of disk and into memory for processing, +they are converted to the most general datatype (8-byte signed integer). And so for the most part, "storage class" is indistinguishable from "datatype" and the two terms can be used interchangeably.

    @@ -238,14 +208,9 @@

    SQLite does not have a separate Boolean storage class. Instead, Boolean values are stored as integers 0 (false) and 1 (true).

    -

    SQLite recognizes the keywords "TRUE" and "FALSE", -as of version 3.23.0 (2018-04-02) but those keywords are -really just alternative spellings for the integer literals 1 and 0 -respectively. - -

    2.2. Date and Time Datatype

    +

    2.2. Date and Time Datatype

    SQLite does not have a storage class set aside for storing dates and/or times. @@ -261,7 +226,7 @@ 1970-01-01 00:00:00 UTC.

  • -

    Applications can choose to store dates and times in any of these +

    Applications can chose to store dates and times in any of these formats and freely convert between formats using the built-in date and time functions.

    @@ -366,8 +331,7 @@

    3.1. Determination Of Column Affinity

    -

    For tables not declared as STRICT, -the affinity of a column is determined by the declared type +

    The affinity of a column is determined by the declared type of the column, according to the following rules in the order shown:

      @@ -478,7 +442,7 @@

      • The right-hand operand of an IN or NOT IN - operator has no affinity if the operand is a list, or has the same + operator has no affinity if the operand is a list and has the same affinity as the affinity of the result set expression if the operand is a SELECT. @@ -644,7 +608,7 @@ can be converted into numeric values if the text content is a well-formed integer or real literal, but not a hexadecimal integer literal. BLOB values are converted into TEXT values by simply interpreting -the binary BLOB content as a text string in the current database +the binary BLOB context as a text string in the current database encoding.

        Affinity is applied to operands of a comparison operator prior to @@ -666,7 +630,7 @@ binary comparisons "a >= b AND a <= c", even if that means different affinities are applied to 'a' in each of the comparisons. Datatype conversions in comparisons of the -form "x IN (SELECT y ...)" are handled as if +form "x IN (SELECT y ...)" are handled is if the comparison were really "x=y". The expression "a IN (x, y, z, ...)" is equivalent to "a = +x OR a = +y OR a = +z OR ...". @@ -737,7 +701,7 @@

    -

    All of the results in the example are the same if the comparisons are +

    All of the result in the example are the same if the comparisons are commuted - if expressions of the form "a<40" are rewritten as "40>a". @@ -793,7 +757,7 @@

    7. Collating Sequences

    When SQLite compares two strings, it uses a collating sequence or -collating function (two terms for the same thing) to determine which +collating function (two words for the same thing) to determine which string is greater or if the two strings are equal. SQLite has three built-in collating functions: BINARY, NOCASE, and RTRIM.

    @@ -861,7 +825,7 @@ collating function assignment (rule 1 above) if any subexpression of the operand uses the postfix COLLATE operator. Thus, if a COLLATE operator is used -anywhere in a comparison expression, the collating function defined +anywhere in a comparision expression, the collating function defined by that operator is used for string comparison regardless of what table columns might be a part of that expression. If two or more COLLATE operator subexpressions appear anywhere in a comparison, the @@ -964,4 +928,3 @@
    - diff -Nru sqlite3-3.42.0/www/datatypes.html sqlite3-3.44.0-0/www/datatypes.html --- sqlite3-3.42.0/www/datatypes.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/datatypes.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Datatypes In SQLite Version 2

    @@ -351,5 +327,4 @@ are treated as numbers and are therefore indistinct. But the SELECT statement on the right returns two rows since 0 and 0.0 are treated a strings which are different.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/dbhash.html sqlite3-3.44.0-0/www/dbhash.html --- sqlite3-3.42.0/www/dbhash.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/dbhash.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -189,5 +165,4 @@ called dbhash.c. To build the dbhash program manually, simply compile the dbhash.c source file and link it against the SQLite library. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/dbpage.html sqlite3-3.44.0-0/www/dbpage.html --- sqlite3-3.42.0/www/dbpage.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/dbpage.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -232,5 +208,4 @@ JOIN sqlite_dbpage(dblist.name) AS dbpage WHERE dbpage.pgno=1;
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/dbstat.html sqlite3-3.44.0-0/www/dbstat.html --- sqlite3-3.42.0/www/dbstat.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/dbstat.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -356,5 +332,4 @@ WHERE s1.rowid+1=s2.rowid; DROP TABLE s;
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/debugging.html sqlite3-3.44.0-0/www/debugging.html --- sqlite3-3.42.0/www/debugging.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/debugging.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Debugging Hints

    @@ -152,44 +128,43 @@
  • -

    The SQLITE_ENABLE_TREETRACE and SQLITE_ENABLE_WHERETRACE options +

    The SQLITE_ENABLE_SELECTTRACE and SQLITE_ENABLE_WHERETRACE options are not documented in compile-time options document because they are not officially supported. What they do is activate the -".treetrace" and ".wheretrace" dot-commands in the command-line +".selecttrace" and ".wheretrace" dot-commands in the command-line shell, which provide low-level tracing output for the logic that -generates code for SELECT and DML statements and WHERE clauses, respectively. +generates code for SELECT statements and WHERE clauses, respectively.

  • -

    Call sqlite3ShowExpr() and similar from the debugger. +

    Call sqlite3TreeViewExpr() and similar from the debugger.

    When compiled with SQLITE_DEBUG, SQLite includes routines that will -print out various internal abstract syntax tree structures as ASCII-art graphs. +print out various internal parse tree structures as ASCII-art graphs. This can be very useful in a debugging in order to understand the variables -that SQLite is working with. The following routines are available: +that SQLite is working with. +

    For example, in gdb, to see the complete hierarchy of an Expr node +(that is to say, the Expr node and all of its children), given a pointer +"pExpr" to that node, type: + + +print sqlite3TreeViewExpr(0, pExpr, 0) + + +

    The two "0" parameters do server a purpose in some contexts, but for +using these routine to print a parse tree as ASCII-art on the terminal, +they should both be "0". + +

    Other similar tree-display routines include:

      -
    • void sqlite3ShowExpr(const Expr*); -
    • void sqlite3ShowExprList(const ExprList*); -
    • void sqlite3ShowIdList(const IdList*); -
    • void sqlite3ShowSrcList(const SrcList*); -
    • void sqlite3ShowSelect(const Select*); -
    • void sqlite3ShowWith(const With*); -
    • void sqlite3ShowUpsert(const Upsert*); -
    • void sqlite3ShowTrigger(const Trigger*); -
    • void sqlite3ShowTriggerList(const Trigger*); -
    • void sqlite3ShowTriggerStep(const TriggerStep*); -
    • void sqlite3ShowTriggerStepList(const TriggerStep*); -
    • void sqlite3ShowWindow(const Window*); -
    • void sqlite3ShowWinFunc(const Window*); +
    • sqlite3TreeViewSelect(0, pSelect, 0) +
    • sqlite3TreeViewExprList(0, pList, 0, 0)
    - -

    These routines are not APIs and are subject to change. They are -for interactive debugging use only.

  • @@ -208,15 +183,15 @@
  • -

    Using the ".treetrace" and ".wheretrace" shell commands +

    Using the ".selecttrace" and ".wheretrace" shell commands

    When the command-line shell and the core SQLite library are both compiled with SQLITE_DEBUG and -SQLITE_ENABLE_TREETRACE and SQLITE_ENABLE_WHERETRACE, then the +SQLITE_ENABLE_SELECTTRACE and SQLITE_ENABLE_WHERETRACE, then the shell has two commands used to turn on debugging facilities for the most intricate parts of the code generator - the logic dealing with SELECT statements and WHERE clauses, respectively. -The ".treetrace" and ".wheretrace" commands each take a numeric +The ".selecttrace" and ".wheretrace" commands each take a numeric argument which can be expressed in hexadecimal. Each bit turns on various parts of debugging. Values of "0xfff" and "0xff" are commonly used. Use an argument of "0" to turn all tracing output back off. @@ -249,5 +224,4 @@ command line option.

  • -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/deterministic.html sqlite3-3.44.0-0/www/deterministic.html --- sqlite3-3.42.0/www/deterministic.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/deterministic.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -251,5 +227,4 @@ inputs, such as the built-in date/time functions, are not published. Generic application-defined SQL functions must be always deterministic or always non-deterministic. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/different.html sqlite3-3.44.0-0/www/different.html --- sqlite3-3.42.0/www/different.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/different.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Distinctive Features Of SQLite

    @@ -192,7 +168,7 @@ database engine itself can access. This makes the data more secure, but also makes it harder to access. Some SQL database engines provide the option of writing directly to disk and bypassing the filesystem - altogether. This provides added performance, but at the cost of + all together. This provides added performance, but at the cost of considerable setup and maintenance complexity.
    @@ -349,10 +325,9 @@ SQLite supports ATTACH and DETACH commands that allow multiple independent databases to be used together in the same query. - And SQLite defines APIs which allow the user to add new + And SQLite defines APIs that allows the user to add new SQL functions and collating sequences.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/doc_backlink_crossref.html sqlite3-3.44.0-0/www/doc_backlink_crossref.html --- sqlite3-3.42.0/www/doc_backlink_crossref.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/doc_backlink_crossref.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -
    - diff -Nru sqlite3-3.42.0/www/eqp.html sqlite3-3.44.0-0/www/eqp.html --- sqlite3-3.42.0/www/eqp.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/eqp.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -454,5 +430,4 @@ |--SCAN t2 `--USE TEMP B-TREE FOR ORDER BY
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/errlog.html sqlite3-3.44.0-0/www/errlog.html --- sqlite3-3.42.0/www/errlog.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/errlog.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -245,7 +221,7 @@ When a schema change occurs that requires a prepared statement to be reparsed and reprepared, that event is logged with the error code SQLITE_SCHEMA. The reparse and reprepare is normally automatic (assuming that -sqlite3_prepare_v2() has been used to prepare the statements originally, +sqlite3_prepare_v2() has been used to prepared the statements originally, which is recommended) and so these logging events are normally the only way to know that reprepares are taking place.

    @@ -289,7 +265,7 @@

    SQLite strives to keep error logger traffic low and only send messages to the error logger when there really is something wrong. Applications might further cull the error message traffic -by deliberately ignoring certain classes of error +by deliberately ignore certain classes of error messages that they do not care about. For example, an application that makes frequent database schema changes might want to ignore all SQLITE_SCHEMA errors.

    @@ -298,9 +274,9 @@

    The use of the error logger callback is highly recommended. The debugging information that the error logger provides has proven -very useful in tracking down obscure problems that occur with applications +very useful in tracking down obscure problems that occurs with applications after they get into the field. The error logger callback has also -proven useful in catching occasional errors that the application +proven useful in catching errors occasional errors that the application misses because of inconsistent checking of API return codes. Developers are encouraged to implement an error logger callback early in the development cycle in order to spot unexpected behavior quickly, @@ -308,5 +284,4 @@ If the error logger never finds a problem, then no harm is done. But failure to set up an appropriate error logger might compromise diagnostic capabilities later on.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/expridx.html sqlite3-3.44.0-0/www/expridx.html --- sqlite3-3.42.0/www/expridx.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/expridx.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -172,7 +148,7 @@

    Both of the above example queries would work fine without the acctchng_magnitude index. -The acctchng_magnitude index merely helps the queries to run +The acctchng_magnitude index index merely helps the queries to run faster, especially on databases where there are many entries in the table for each account. @@ -261,5 +237,4 @@ The ability to index expressions was added to SQLite with version 3.9.0 (2015-10-14). A database that uses an index on expressions will not be usable by earlier versions of SQLite. -

    This page last modified on 2023-02-11 20:57:33 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/famous.html sqlite3-3.44.0-0/www/famous.html --- sqlite3-3.42.0/www/famous.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/famous.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Well-Known Users of SQLite

    @@ -129,7 +105,7 @@ A few of the better-known users of SQLite are shown below in alphabetical order. This is not a complete list. -SQLite is in the +SQLite is in the public domain and so most developers use it in their projects without ever telling us.

    @@ -139,14 +115,14 @@

    - Adobe uses SQLite as the - application - file format for their + Adobe uses SQLite as the + application + file format for their Photoshop Lightroom product. SQLite is also a standard part of the - Adobe Integrated Runtime (AIR). - It is reported that + Adobe Integrated Runtime (AIR). + It is reported that Acrobat Reader also uses SQLite.

    @@ -156,8 +132,8 @@

    Airbus confirms that SQLite is being - used in the flight software for the - A350 XWB family + used in the flight software for the + A350 XWB family of aircraft.

    @@ -212,18 +188,26 @@

    Facebook uses SQLite as the SQL database - engine in their + engine in their osquery product.


    +
    +
    +

    + Flame + is a malware spy program that is reported to make heavy use of SQLite. +

    + +

    We believe that General Electric - uses SQLite in some product or - another because they have written to the SQLite developers at - least four separate times requesting + uses SQLite in some product or + another because they have written to the SQLite developers at + least four separate times requesting the US Export Control Number for SQLite. So presumably GE is using SQLite in something that they are exporting. But nobody (outside of GE) seems to know what that might be. @@ -233,9 +217,9 @@

    - uses SQLite in their - Android cell-phone - operating system, and in the + uses SQLite in their + in the Android cell-phone + operating system, and in the Chrome Web Browser.

    @@ -243,10 +227,10 @@

    - Intuit apparently uses SQLite in + Intuit apparently uses SQLite in QuickBooks and in TurboTax to judge from some error - reports from users seen + reports from users seen here and here.

    @@ -263,10 +247,10 @@

    - McAfee uses SQLite in its antivirus - programs. - Mentioned here and implied - here. + McAfee uses SQLite in its antivirus + programs. + Mentioned here and implied + here.


    @@ -291,7 +275,7 @@

    - The Navigation Data Standard uses + The Navigation Data Standard uses SQLite as its application file format.

    @@ -323,7 +307,7 @@

    - There are + There are multiple sightings of SQLite in the Skype client for Mac OS X and Windows. @@ -355,14 +339,14 @@ - Adobe uses SQLite as the - application - file format for their + Adobe uses SQLite as the + application + file format for their Photoshop Lightroom product. SQLite is also a standard part of the - Adobe Integrated Runtime (AIR). - It is reported that + Adobe Integrated Runtime (AIR). + It is reported that Acrobat Reader also uses SQLite. @@ -372,8 +356,8 @@ Airbus confirms that SQLite is being - used in the flight software for the - A350 XWB family + used in the flight software for the + A350 XWB family of aircraft. @@ -428,18 +412,26 @@ Facebook uses SQLite as the SQL database - engine in their + engine in their osquery product. + + + + + Flame + is a malware spy program that is reported to make heavy use of SQLite. + + We believe that General Electric - uses SQLite in some product or - another because they have written to the SQLite developers at - least four separate times requesting + uses SQLite in some product or + another because they have written to the SQLite developers at + least four separate times requesting the US Export Control Number for SQLite. So presumably GE is using SQLite in something that they are exporting. But nobody (outside of GE) seems to know what that might be. @@ -449,9 +441,9 @@ - uses SQLite in their - Android cell-phone - operating system, and in the + uses SQLite in their + in the Android cell-phone + operating system, and in the Chrome Web Browser. @@ -459,10 +451,10 @@ - Intuit apparently uses SQLite in + Intuit apparently uses SQLite in QuickBooks and in TurboTax to judge from some error - reports from users seen + reports from users seen here and here. @@ -479,10 +471,10 @@ - McAfee uses SQLite in its antivirus - programs. - Mentioned here and implied - here. + McAfee uses SQLite in its antivirus + programs. + Mentioned here and implied + here. @@ -507,7 +499,7 @@ - The Navigation Data Standard uses + The Navigation Data Standard uses SQLite as its application file format. @@ -539,7 +531,7 @@ - There are + There are multiple sightings of SQLite in the Skype client for Mac OS X and Windows. @@ -565,5 +557,4 @@

    -

    This page last modified on 2023-01-02 14:22:42 UTC

    diff -Nru sqlite3-3.42.0/www/faq.html sqlite3-3.44.0-0/www/faq.html --- sqlite3-3.42.0/www/faq.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/faq.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Frequently Asked Questions

    1. How do I create an AUTOINCREMENT field?
    2. What datatypes does SQLite support?
    3. SQLite lets me insert a string into a database column of type integer!
    4. Why doesn't SQLite allow me to use '0' and '0.0' as the primary key on two different rows of the same table?
    5. Can multiple applications or multiple instances of the same - application access a single database file at the same time?
    6. Is SQLite threadsafe?
    7. How do I list all tables/indices contained in an SQLite database
    8. Are there any known size limits to SQLite databases?
    9. What is the maximum size of a VARCHAR in SQLite?
    10. Does SQLite support a BLOB type?
    11. How do I add, delete or rename columns from an existing table in SQLite?
    12. I deleted a lot of data but the database file did not get any + application access a single database file at the same time?
    13. Is SQLite threadsafe?
    14. How do I list all tables/indices contained in an SQLite database
    15. Are there any known size limits to SQLite databases?
    16. What is the maximum size of a VARCHAR in SQLite?
    17. Does SQLite support a BLOB type?
    18. How do I add or delete columns from an existing table in SQLite.
    19. I deleted a lot of data but the database file did not get any smaller. Is this a bug?
    20. Can I use SQLite in my commercial product without paying royalties?
    21. How do I use a string literal that contains an embedded single-quote (') character?
    22. What is an SQLITE_SCHEMA error, and why am I getting one?
    23. I get some compiler warnings when I compile SQLite. Isn't this a problem? Doesn't it indicate poor code quality?
    24. Case-insensitive matching of Unicode characters does not work.
    25. INSERT is really slow - I can only do few dozen INSERTs per second
    26. I accidentally deleted some important information from my SQLite database. @@ -130,7 +106,7 @@ where column1 has the value "column1".
    27. How are the syntax diagrams (a.k.a. "railroad" diagrams) for SQLite generated?
    28. The SQL standard requires that a UNIQUE constraint be enforced even if one or more of the columns in the constraint are NULL, but SQLite does - not do this. Isn't that a bug?
    29. What is the Export Control Classification Number (ECCN) for SQLite?
    30. My query does not return the column name that I expect. Is this a bug?
    31. Where did my database go? (Or: How did my database become empty?)
    + not do this. Isn't that a bug?
  • What is the Export Control Classification Number (ECCN) for SQLite?
  • My query does not return the column name that I expect. Is this a bug?
  • (1) How do I create an AUTOINCREMENT field?

    Short answer: A column declared INTEGER PRIMARY KEY will autoincrement.

    @@ -357,17 +333,32 @@ column, even columns that are declared to hold some other type. BLOBs can even be used as PRIMARY KEYs.

  • -

    (11) How do I add, delete or rename columns from an existing table in SQLite?

    -

    SQLite has limited ALTER TABLE support that you can use to - add, rename or drop columns or to change the name of a table - as detailed at ALTER TABLE.

    - -

    If you want to make more complex changes in the structure or - constraints of a table or its columns, you will have to recreate it. - You can save existing data to a temporary table, drop the +

    (11) How do I add or delete columns from an existing table in SQLite.

    +

    SQLite has limited + ALTER TABLE support that you can + use to add a column to the end of a table or to change the name of + a table. + If you want to make more complex changes in the structure of a table, + you will have to recreate the + table. You can save existing data to a temporary table, drop the old table, create the new table, then copy the data back in from - the temporary table. See - Making Other Kinds Of Table Schema Changes for procedure.

  • + the temporary table.

    + +

    For example, suppose you have a table named "t1" with columns + names "a", "b", and "c" and that you want to delete column "c" from + this table. The following steps illustrate how this could be done: +

    + +
    +BEGIN TRANSACTION;
    +CREATE TEMPORARY TABLE t1_backup(a,b);
    +INSERT INTO t1_backup SELECT a,b FROM t1;
    +DROP TABLE t1;
    +CREATE TABLE t1(a,b);
    +INSERT INTO t1 SELECT a,b FROM t1_backup;
    +DROP TABLE t1_backup;
    +COMMIT;
    +

    (12) I deleted a lot of data but the database file did not get any smaller. Is this a bug?

    @@ -643,14 +634,5 @@ column name. If the result set does not use an AS clause, then SQLite is free to name the column anything it wants. See the sqlite3_column_name() documentation for further information.
    - -

    (29) Where did my database go? (Or: How did my database become empty?)

    -
    Unless opened with flags to prevent it, a SQLite database is created - if it does not already exist. Newly created databases are initially empty. - This can confuse people who inadvertantly open different database files - in different contexts, due to either a typo in the filename - or use of a relative pathname that is used with - differing current directories for the opening processes.
    -

    This page last modified on 2023-04-06 20:35:50 UTC

    diff -Nru sqlite3-3.42.0/www/fasterthanfs.html sqlite3-3.44.0-0/www/fasterthanfs.html --- sqlite3-3.42.0/www/fasterthanfs.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/fasterthanfs.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -429,7 +405,7 @@ On Android, SQLite is only about 35% faster than reading from disk.

    -
    +

    @@ -443,7 +419,7 @@ sqlite3_blob_read() interface, as shown in the next chart:

    -
    +

    @@ -461,7 +437,7 @@ or MacOS-X and over 10 times faster than Windows.

    -
    +

    @@ -512,7 +488,7 @@ setting is NORMAL instead of FULL, the transactions are not durable.

    -
    +

    @@ -537,7 +513,7 @@ data prone to corruption due to system crashes and power failures.

    -
    +

    @@ -640,5 +616,4 @@

    Finally use "adb shell" to get a shell prompt on the Android device, cd into the /data/local/tmp directory, and begin running the tests as with any other unix host. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/features.html sqlite3-3.44.0-0/www/features.html --- sqlite3-3.42.0/www/features.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/features.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Features Of SQLite

    @@ -136,7 +112,7 @@
  • Supports terabyte-sized databases and gigabyte-sized strings and blobs. (See limits.html.)
  • Small code footprint: - less than 750KiB fully configured or much less + less than 600KiB fully configured or much less with optional features omitted.
  • Simple, easy to use API.
  • Fast: In some cases, SQLite is @@ -192,5 +168,4 @@
  • More suggestions...

  • -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/fileformat2.html sqlite3-3.44.0-0/www/fileformat2.html --- sqlite3-3.42.0/www/fileformat2.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/fileformat2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -467,7 +443,7 @@

    Unused pages in the database file are stored on a freelist. The 4-byte big-endian integer at offset 32 stores the page number of the first page of the freelist, or zero if the freelist is empty. -The 4-byte big-endian integer at offset 36 stores the total +The 4-byte big-endian integer at offset 36 stores stores the total number of pages on the freelist.

    @@ -1278,8 +1254,6 @@ though this can be overridden using a COLLATE clause in the CREATE INDEX statement. - -

    2.3. Representation Of SQL Tables

    Each ordinary SQL table in the database schema is represented on-disk @@ -1313,7 +1287,7 @@ table uses an index b-tree rather than a table b-tree for storage. The key for each entry in the WITHOUT ROWID b-tree is a record composed of the columns of the PRIMARY KEY followed by all remaining columns of -the table. The primary key columns appear in the order that they were +the table. The primary key columns appear in the order they they were declared in the PRIMARY KEY clause and the remaining columns appear in the order they occur in the CREATE TABLE statement. @@ -1335,10 +1309,10 @@ the same table, which will have the exact same representation on disk:

    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c)) WITHOUT ROWID;
    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c,a,c)) WITHOUT ROWID;
    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,A,a,C)) WITHOUT ROWID;
    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,a,a,a,c)) WITHOUT ROWID;
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c)) WITHOUT ROWID);
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c,a,c)) WITHOUT ROWID);
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,A,a,C)) WITHOUT ROWID);
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,a,a,a,c)) WITHOUT ROWID);
     

    The first example above is the preferred definition of the table, @@ -1564,7 +1538,7 @@

    There is a single row in the sqlite_sequence table for each ordinary table that uses AUTOINCREMENT. The name of the table (as it appears in -sqlite_schema.name) is in the sqlite_sequence.name field and the largest +sqlite_schema.name) is in the sqlite_sequence.main field and the largest INTEGER PRIMARY KEY ever inserted into that table is in the sqlite_sequence.seq field. New automatically generated integer primary keys for AUTOINCREMENT @@ -1616,7 +1590,7 @@ except for partial indexes.) The second integer is the approximate number of rows in the index that have the same value in the first column of the index. The third -integer is the number of rows in the index that have +integer is the number number of rows in the index that have the same value for the first two columns. The N-th integer (for N>1) is the estimated average number of rows in the index which have the same value for the first N-1 columns. For @@ -2201,5 +2175,4 @@ information about the format of the wal-index will be provided here. Additional details on the format of the wal-index are contained in the separate WAL-index File Format document.

    -

    This page last modified on 2023-01-25 11:14:04 UTC

    diff -Nru sqlite3-3.42.0/www/fileformat.html sqlite3-3.44.0-0/www/fileformat.html --- sqlite3-3.42.0/www/fileformat.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/fileformat.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -467,7 +443,7 @@

    Unused pages in the database file are stored on a freelist. The 4-byte big-endian integer at offset 32 stores the page number of the first page of the freelist, or zero if the freelist is empty. -The 4-byte big-endian integer at offset 36 stores the total +The 4-byte big-endian integer at offset 36 stores stores the total number of pages on the freelist.

    @@ -1278,8 +1254,6 @@ though this can be overridden using a COLLATE clause in the CREATE INDEX statement. - -

    2.3. Representation Of SQL Tables

    Each ordinary SQL table in the database schema is represented on-disk @@ -1313,7 +1287,7 @@ table uses an index b-tree rather than a table b-tree for storage. The key for each entry in the WITHOUT ROWID b-tree is a record composed of the columns of the PRIMARY KEY followed by all remaining columns of -the table. The primary key columns appear in the order that they were +the table. The primary key columns appear in the order they they were declared in the PRIMARY KEY clause and the remaining columns appear in the order they occur in the CREATE TABLE statement. @@ -1335,10 +1309,10 @@ the same table, which will have the exact same representation on disk:

    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c)) WITHOUT ROWID;
    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c,a,c)) WITHOUT ROWID;
    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,A,a,C)) WITHOUT ROWID;
    -CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,a,a,a,c)) WITHOUT ROWID;
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c)) WITHOUT ROWID);
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c,a,c)) WITHOUT ROWID);
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,A,a,C)) WITHOUT ROWID);
    +CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,a,a,a,c)) WITHOUT ROWID);
     

    The first example above is the preferred definition of the table, @@ -1564,7 +1538,7 @@

    There is a single row in the sqlite_sequence table for each ordinary table that uses AUTOINCREMENT. The name of the table (as it appears in -sqlite_schema.name) is in the sqlite_sequence.name field and the largest +sqlite_schema.name) is in the sqlite_sequence.main field and the largest INTEGER PRIMARY KEY ever inserted into that table is in the sqlite_sequence.seq field. New automatically generated integer primary keys for AUTOINCREMENT @@ -1616,7 +1590,7 @@ except for partial indexes.) The second integer is the approximate number of rows in the index that have the same value in the first column of the index. The third -integer is the number of rows in the index that have +integer is the number number of rows in the index that have the same value for the first two columns. The N-th integer (for N>1) is the estimated average number of rows in the index which have the same value for the first N-1 columns. For @@ -2201,5 +2175,4 @@ information about the format of the wal-index will be provided here. Additional details on the format of the wal-index are contained in the separate WAL-index File Format document.

    -

    This page last modified on 2023-01-25 11:14:04 UTC

    diff -Nru sqlite3-3.42.0/www/fileio.html sqlite3-3.44.0-0/www/fileio.html --- sqlite3-3.42.0/www/fileio.html 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/www/fileio.html 2023-11-04 14:24:19.000000000 +0000 @@ -0,0 +1,1980 @@ + + + + + +No Title + + + +
    + + + +
    +
    +Small. Fast. Reliable.
    Choose any three. +
    + + +
    + + + + + +
    +
    + +
    + + + + + + + +
    SQLite File IO Specification
    +
    Table Of Contents
    +
    + Javascript is required for some features of this document, including + table of contents, figure numbering and internal references (section + numbers and hyper-links. + +
    + +

    Overview

    +

    + SQLite stores an entire database within a single file, the format of + which is described in the SQLite File Database File Format + document ff_sqlitert_requirements. Each database file is + stored within a file system, presumably provided by the host operating + system. Instead of interfacing with the operating system directly, + the host application is required to supply an adaptor component that + implements the SQLite Virtual File System interface + (described in capi_sqlitert_requirements). The adaptor + component is responsible for translating the calls made by SQLite to + the VFS interface into calls to the file-system interface + provided by the operating system. This arrangement is depicted in figure + figure_vfs_role. +

    +

    Figure - Virtual File System (VFS) Adaptor +

    +

    + Although it would be easy to design a system that uses the VFS + interface to read and update the content of a database file stored + within a file-system, there are several complicated issues that need + to be addressed by such a system: +

      +
    1. SQLite is required to implement atomic and durable + transactions (the 'A' and 'D' from the ACID acronym), even if an + application, operating system or power failure occurs midway through or + shortly after updating a database file. +

      To implement atomic transactions in the face of potential + application, operating system or power failures, database writers write + a copy of those portions of the database file that they are going to + modify into a second file, the journal file, before writing + to the database file. If a failure does occur while modifying the + database file, SQLite can reconstruct the original database + (before the modifications were attempted) based on the contents of + the journal file. +

    2. SQLite is required to implement isolated transactions (the 'I' + from the ACID acronym). +

      This is done by using the file locking facilities provided by the + VFS adaptor to serialize writers (write transactions) and preventing + readers (read transactions) from accessing database files while writers + are midway through updating them. +

    3. For performance reasons, it is advantageous to minimize the + quantity of data read and written to and from the file-system. +

      As one might expect, the amount of data read from the database + file is minimized by caching portions of the database file in main + memory. Additionally, multiple updates to the database file that + are part of the same write transaction may be cached in + main memory and written to the file together, allowing for + more efficient IO patterns and eliminating the redundant write + operations that could take place if part of the database file is + modified more than once within a single write transaction. +

    +

    + System requirement references for the above points. +

    + This document describes in detail the way that SQLite uses the API + provided by the VFS adaptor component to solve the problems and implement + the strategies enumerated above. It also specifies the assumptions made + about the properties of the system that the VFS adaptor provides + access to. For example, specific assumptions about the extent of + data corruption that may occur if a power failure occurs while a + database file is being updated are presented in section + fs_characteristics. +

    + This document does not specify the details of the interface that must + be implemented by the VFS adaptor component, that is left to + capi_sqlitert_requirements. +

    Relationship to Other Documents

    +

    + Related to C-API requirements: +

      +
    1. Opening a connection. +
    2. Closing a connection. +
    +

    + Related to SQL requirements: +

      +
    1. Opening a read-only transaction. +
    2. Terminating a read-only transaction. +
    3. Opening a read-write transaction. +
    4. Committing a read-write transaction. +
    5. Rolling back a read-write transaction. +
    6. Opening a statement transaction. +
    7. Committing a statement transaction. +
    8. Rolling back a statement transaction. +
    9. Committing a multi-file transaction. +
    +

    + Related to file-format requirements: +

      +
    1. Pinning (reading) a database page. +
    2. Unpinning a database page. +
    3. Modifying the contents of a database page. +
    4. Appending a new page to the database file. +
    5. Truncating a page from the end of the database file. +
    +

    Document Structure

    +

    + Section vfs_assumptions of this document describes the + various assumptions made about the system to which the VFS adaptor + component provides access. The basic capabilities and functions + required from the VFS implementation are presented along with the + description of the VFS interface in + capi_sqlitert_requirements. Section + vfs_assumptions complements this by describing in more + detail the assumptions made about VFS implementations on which the + algorithms presented in this document depend. Some of these assumptions + relate to performance issues, but most concern the expected state of + the file-system following a failure that occurs midway through + modifying a database file. +

    + Section database_connections introduces the concept of + a database connection, a combination of a file-handle and + in-memory cache used to access a database file. It also describes the + VFS operations required when a new database connection is + created (opened), and when one is destroyed (closed). +

    + Section reading_data describes the steps required to + open a read transaction and read data from a database file. +

    + Section writing_data describes the steps required to + open a write transaction and write data to a database file. +

    + Section rollback describes the way in which aborted + write transactions may be rolled back (reverted), either as + a result of an explicit user directive or because an application, + operating system or power failure occurred while SQLite was midway + through updating a database file. +

    + Section page_cache_algorithms describes some of the + algorithms used to determine exactly which portions of the database + file are cached by a page cache, and the effect that they + have on the quantity and nature of the required VFS operations. + It may at first seem odd to include the page cache, which is + primarily an implementation detail, in this document. However, it is + necessary to acknowledge and describe the page cache in order to + provide a more complete explanation of the nature and quantity of IO + performed by SQLite. +

    Glossary

    +

    + After this document is ready, make the vocabulary consistent and + then add a glossary here. +

    VFS Adaptor Related Assumptions

    +

    + This section documents those assumptions made about the system that + the VFS adaptor provides access to. The assumptions noted in section + fs_characteristics are particularly important. If these + assumptions are not true, then a power or operating system failure + may cause SQLite databases to become corrupted. +

    Performance Related Assumptions

    +

    + SQLite uses the assumptions in this section to try to speed up + reading from and writing to the database file. +

    + It is assumed that writing a series of sequential blocks of data to + a file in order is faster than writing the same blocks in an arbitrary + order. +

    System Failure Related Assumptions

    +

    + In the event of an operating system or power failure, the various + combinations of file-system software and storage hardware available + provide varying levels of guarantee as to the integrity of the data + written to the file system just before or during the failure. The exact + combination of IO operations that SQLite is required to perform in + order to safely modify a database file depend on the exact + characteristics of the target platform. +

    + This section describes the assumptions that SQLite makes about the + content of a file-system following a power or system failure. In + other words, it describes the extent of file and file-system corruption + that such an event may cause. +

    + SQLite queries an implementation for file-system characteristics + using the xDeviceCharacteristics() and xSectorSize() methods of the + database file file-handle. These two methods are only ever called + on file-handles open on database files. They are not called for + journal files, master-journal files or + temporary database files. +

    + The file-system sector size value determined by calling the + xSectorSize() method is a power of 2 value between 512 and 32768, + inclusive reference to exactly how this is + determined. SQLite assumes that the underlying storage + device stores data in blocks of sector-size bytes each, + sectors. It is also assumed that each aligned block of + sector-size bytes of each file is stored in a single device + sector. If the file is not an exact multiple of sector-size + bytes in size, then the final device sector is partially empty. +

    + Normally, SQLite assumes that if a power failure occurs while + updating any portion of a sector then the contents of the entire + device sector is suspect following recovery. After writing to + any part of a sector within a file, it is assumed that the modified + sector contents are held in a volatile buffer somewhere within + the system (main memory, disk cache etc.). SQLite does not assume + that the updated data has reached the persistent storage media, until + after it has successfully synced the corresponding file by + invoking the VFS xSync() method. Syncing a file causes all + modifications to the file up until that point to be committed to + persistent storage. +

    + Based on the above, SQLite is designed around a model of the + file-system whereby any sector of a file written to is considered to be + in a transient state until after the file has been successfully + synced. Should a power or system failure occur while a sector + is in a transient state, it is impossible to predict its contents + following recovery. It may be written correctly, not written at all, + overwritten with random data, or any combination thereof. +

    + For example, if the sector-size of a given file-system is + 2048 bytes, and SQLite opens a file and writes a 1024 byte block + of data to offset 3072 of the file, then according to the model + the second sector of the file is in the transient state. If a + power failure or operating system crash occurs before or during + the next call to xSync() on the file handle, then following system + recovery SQLite assumes that all file data between byte offsets 2048 + and 4095, inclusive, is invalid. It also assumes that since the first + sector of the file, containing the data from byte offset 0 to 2047 + inclusive, is valid, since it was not in a transient state when the + crash occurred. +

    + Assuming that any and all sectors in the transient state may be + corrupted following a power or system failure is a very pessimistic + approach. Some modern systems provide more sophisticated guarantees + than this. SQLite allows the VFS implementation to specify at runtime + that the current platform supports zero or more of the following + properties: +

      +
    • The safe-append property. If a system supports the + safe-append property, it means that when a file is extended + the new data is written to the persistent media before the size + of the file itself is updated. This guarantees that if a failure + occurs after a file has been extended, following recovery + the write operations that extended the file will appear to have + succeeded or not occurred at all. It is not possible for invalid + or garbage data to appear in the extended region of the file. +

    • The atomic-write property. A system that supports this + property also specifies the size or sizes of the blocks that it + is capable of writing. Valid sizes are powers of two greater than + 512. If a write operation modifies a block of n bytes, + where n is one of the block sizes for which atomic-write + is supported, then it is impossible for an aligned write of n + bytes to cause data corruption. If a failure occurs after such + a write operation and before the applicable file handle is + synced, then following recovery it will appear as if the + write operation succeeded or did not take place at all. It is not + possible that only part of the data specified by the write operation + was written to persistent media, nor is it possible for any content + of the sectors spanned by the write operation to be replaced with + garbage data, as it is normally assumed to be. +

    • The sequential-write property. A system that supports the + sequential-write property guarantees that the various write + operations on files within the same file-system are written to the + persistent media in the same order that they are performed by the + application and that each operation is concluded before the next + is begun. If a system supports the sequential-write + property, then the model used to determine the possible states of + the file-system following a failure is different. +

      If a system supports sequential-write it is assumed that + syncing any file within the file system flushes all write + operations on all files (not just the synced file) to + the persistent media. If a failure does occur, it is not known + whether or not any of the write operations performed by SQLite + since the last time a file was synced. SQLite is able to + assume that if the write operations of unknown status are arranged + in the order that they occurred: +

        +
      1. the first n operations will have been executed + successfully, +
      2. the next operation puts all device sectors that it modifies + into the transient state, so that following recovery each + sector may be partially written, completely written, not + written at all or populated with garbage data, +
      3. the remaining operations will not have had any effect on + the contents of the file-system. +
      +
    +

    Failure Related Assumption Details

    +

    + This section describes how the assumptions presented in the parent + section apply to the individual API functions and operations provided + by the VFS to SQLite for the purposes of modifying the contents of the + file-system. +

    + SQLite manipulates the contents of the file-system using a combination + of the following four types of operation: +

      +
    • Create file operations. SQLite may create new files + within the file-system by invoking the xOpen() method of + the sqlite3_io_methods object. +
    • Delete file operations. SQLite may remove files from the + file system by calling the xDelete() method of the + sqlite3_io_methods object. +
    • Truncate file operations. SQLite may truncate existing + files by invoking the xTruncate() method of the sqlite3_file + object. +
    • Write file operations. SQLite may modify the contents + and increase the size of a file by files by invoking the xWrite() + method of the sqlite3_file object. +
    +

    + Additionally, all VFS implementations are required to provide the + sync file operation, accessed via the xSync() method of the + sqlite3_file object, used to flush create, write and truncate operations + on a file to the persistent storage medium. +

    + The formalized assumptions in this section refer to system failure + events. In this context, this should be interpreted as any failure that + causes the system to stop operating. For example a power failure or + operating system crash. +

    + SQLite does not assume that a create file operation has actually + modified the file-system records within persistent storage until + after the file has been successfully synced. +

    + If a system failure occurs during or after a "create file" + operation, but before the created file has been synced, then + SQLite assumes that it is possible that the created file may not + exist following system recovery. +

    + Of course, it is also possible that it does exist following system + recovery. +

    + If a "create file" operation is executed by SQLite, and then the + created file synced, then SQLite assumes that the file-system + modifications corresponding to the "create file" operation have been + committed to persistent media. It is assumed that if a system + failure occurs any time after the file has been successfully + synced, then the file is guaranteed to appear in the file-system + following system recovery. +

    + A delete file operation (invoked by a call to the VFS xDelete() + method) is assumed to be an atomic and durable operation. +

    +

    + If a system failure occurs at any time after a "delete file" + operation (call to the VFS xDelete() method) returns successfully, it is + assumed that the file-system will not contain the deleted file following + system recovery. +

    + If a system failure occurs during a "delete file" operation, + it is assumed that following system recovery the file-system will + either contain the file being deleted in the state it was in before + the operation was attempted, or not contain the file at all. It is + assumed that it is not possible for the file to have become corrupted + purely as a result of a failure occurring during a "delete file" + operation. +

    + The effects of a truncate file operation are not assumed to + be made persistent until after the corresponding file has been + synced. +

    + If a system failure occurs during or after a "truncate file" + operation, but before the truncated file has been synced, then + SQLite assumes that the size of the truncated file is either as large + or larger than the size that it was to be truncated to. +

    + If a system failure occurs during or after a "truncate file" + operation, but before the truncated file has been synced, then + it is assumed that the contents of the file up to the size that the + file was to be truncated to are not corrupted. +

    + The above two assumptions may be interpreted to mean that if a + system failure occurs after file truncation but before the truncated + file is synced, the contents of the file following the point + at which it was to be truncated may not be trusted. They may contain + the original file data, or may contain garbage. +

    + If a "truncate file" operation is executed by SQLite, and then the + truncated file synced, then SQLite assumes that the file-system + modifications corresponding to the "truncate file" operation have been + committed to persistent media. It is assumed that if a system + failure occurs any time after the file has been successfully + synced, then the effects of the file truncation are guaranteed + to appear in the file system following recovery. +

    + A write file operation modifies the contents of an existing file + within the file-system. It may also increase the size of the file. + The effects of a write file operation are not assumed to + be made persistent until after the corresponding file has been + synced. +

    + If a system failure occurs during or after a "write file" + operation, but before the corresponding file has been synced, + then it is assumed that the content of all sectors spanned by the + write file operation are untrustworthy following system + recovery. This includes regions of the sectors that were not + actually modified by the write file operation. +

    + If a system failure occurs on a system that supports the + atomic-write property for blocks of size N bytes + following an aligned write of N + bytes to a file but before the file has been successfully synced, + then is assumed following recovery that all sectors spanned by the + write operation were correctly updated, or that none of the sectors were + modified at all. +

    + If a system failure occurs on a system that supports the + safe-append following a write operation that appends data + to the end of the file without modifying any of the existing file + content but before the file has been successfully synced, + then is assumed following recovery that either the data was + correctly appended to the file, or that the file size remains + unchanged. It is assumed that it is impossible that the file be + extended but populated with incorrect data. +

    + Following a system recovery, if a device sector is deemed to be + untrustworthy as defined by A21008 and neither A21011 or A21012 + apply to the range of bytes written, then no assumption can be + made about the content of the sector following recovery. It is + assumed that it is possible for such a sector to be written + correctly, not written at all, populated with garbage data or any + combination thereof. +

    + If a system failure occurs during or after a "write file" + operation that causes the file to grow, but before the corresponding + file has been synced, then it is assumed that the size of + the file following recovery is as large or larger than it was when + it was most recently synced. +

    + If a system supports the sequential-write property, then further + assumptions may be made with respect to the state of the file-system + following recovery from a system failure. Specifically, it is + assumed that create, truncate, delete and write file operations are + applied to the persistent representation in the same order as they + are performed by SQLite. Furthermore, it is assumed that the + file-system waits until one operation is safely written to the + persistent media before the next is attempted, just as if the relevant + file were synced following each operation. +

    + If a system failure occurs on a system that supports the + sequential-write property, then it is assumed that all + operations completed before the last time any file was synced + have been successfully committed to persistent media. +

    + If a system failure occurs on a system that supports the + sequential-write property, then it is assumed that the set + of possible states that the file-system may be in following recovery + is the same as if each of the write operations performed since the most + recent time a file was synced was itself followed by a sync + file operation, and that the system failure may have occurred during + any of the write or sync file operations. +

    +

    Database Connections

    +

    + Within this document, the term database connection has a slightly + different meaning from that which one might assume. The handles returned + by the sqlite3_open() and sqlite3_open16() + APIs (reference) are referred to as database + handles. A database connection is a connection to a single + database file using a single file-handle, which is held open for the + lifetime of the connection. Using the SQL ATTACH syntax, multiple + database connections may be accessed via a single database + handle. Or, using SQLite's shared-cache mode feature, multiple + database handles may access a single database connection. +

    + Usually, a new database connection is opened whenever the user opens + new database handle on a real database file (not an in-memory + database) or when a database file is attached to an existing database + connection using the SQL ATTACH syntax. However if the shared-cache + mode feature is enabled, then the database file may be accessed through + an existing database connection. For more information on + shared-cache mode, refer to Reference. The + various IO operations required to open a new connection are detailed in + section open_new_connection of this document. +

    + Similarly, a database connection is usually closed when the user + closes a database handle that is open on a real database file or + has had one or more real database files attached to it using the ATTACH + mechanism, or when a real database file is detached from a database + connection using the DETACH syntax. Again, the exception is if + shared-cache mode is enabled. In this case, a database + connection is not closed until its number of users reaches zero. + The IO related steps required to close a database connection are + described in section closing_database_connection. +

    + After sections 4 and 5 are finished, come back here and see if we can add a + list of state items associated with each database connection to make things + easier to understand. i.e each database connection has a file handle, a set + of entries in the page cache, an expected page size etc. +

    Opening a New Connection

    +

    + This section describes the VFS operations that take place when a + new database connection is created. +

    + Opening a new database connection is a two-step process: +

      +
    1. A file-handle is opened on the database file. +
    2. If step 1 was successful, an attempt is made to read the + database file header from the database file using the + new file-handle. +
    +

    + In step 2 of the procedure above, the database file is not locked + before it is read from. This is the only exception to the locking + rules described in section reading_data. +

    + The reason for attempting to read the database file header + is to determine the page-size used by the database file. + Because it is not possible to be certain as to the page-size + without holding at least a shared lock on the database file + (because some other database connection might have changed it + since the database file header was read), the value read from the + database file header is known as the expected page size. +

    +When a new database connection is required, SQLite shall attempt +to open a file-handle on the database file. If the attempt fails, then +no new database connection is created and an error returned. +

    +When a new database connection is required, after opening the +new file-handle, SQLite shall attempt to read the first 100 bytes +of the database file. If the attempt fails for any other reason than +that the opened file is less than 100 bytes in size, then +the file-handle is closed, no new database connection is created +and an error returned instead. +

    +If the database file header is successfully read from a newly +opened database file, the connections expected page-size shall +be set to the value stored in the page-size field of the +database header. +

    +If the database file header cannot be read from a newly opened +database file (because the file is less than 100 bytes in size), the +connections expected page-size shall be set to the compile time +value of the SQLITE_DEFAULT_PAGESIZE option. +

    Closing a Connection

    +

    + This section describes the VFS operations that take place when an + existing database connection is closed (destroyed). +

    + Closing a database connection is a simple matter. The open VFS + file-handle is closed and in-memory page cache related resources + are released. +

    +When a database connection is closed, SQLite shall close the +associated file handle at the VFS level. +

    +When a database connection is closed, all associated page +cache entries shall be discarded. +

    The Page Cache

    +

    + The contents of an SQLite database file are formatted as a set of + fixed size pages. See ff_sqlitert_requirements for a + complete description of the format used. The page size used + for a particular database is stored as part of the database file + header at a well-known offset within the first 100 bytes of the + file. Almost all read and write operations performed by SQLite on + database files are done on blocks of data page-size bytes + in size. +

    + All SQLite database connections running within a single process share + a single page cache. The page cache caches data read from + database files in main-memory on a per-page basis. When SQLite requires + data from a database file to satisfy a database query, it checks the + page cache for usable cached versions of the required database + pages before loading it from the database file. If no usable cache + entry can be found and the database page data is loaded from the database + file, it is cached in the page cache in case the same data is + needed again later. Because reading from the database file is assumed to + be an order of magnitude slower than reading from main-memory, caching + database page content in the page cache to minimize the number + of read operations performed on the database file is a significant + performance enhancement. +

    + The page cache is also used to buffer database write operations. + When SQLite is required to modify one of more of the database pages + that make up a database file, it first modifies the cached version of + the page in the page cache. At that point the page is considered + a "dirty" page. At some point later on, the new content of the "dirty" + page is copied from the page cache into the database file via + the VFS interface. Buffering writes in the page cache can reduce + the number of write operations required on the database file (in cases + where the same page is updated twice) and allows optimizations based + on the assumptions outlined in section fs_performance. +

    + Database read and write operations, and the way in which they interact + with and use the page cache, are described in detail in sections + reading_data and writing_data of this document, + respectively. +

    + At any one time, the page cache contains zero or more page cache + entries, each of which has the following data associated with it: +

      +
    • + A reference to the associated database connection. Each + entry in the page cache is associated with a single database + connection; the database connection that created the entry. + A page cache entry is only ever used by the database + connection that created it. Page cache entries are not shared between + database connections. +

    • + The page number of the cached page. Pages are sequentially + numbered within a database file starting from page 1 (page 1 begins at + byte offset 0). Refer to ff_sqlitert_requirements for + details. +

    • + The cached data; a blob of data page-size bytes in size. +

    +

    + The first two elements in the list above, the associated database + connection and the page number, uniquely identify the + page cache entry. At no time may the page cache contain two + entries for which both the database connection and page + number are identical. Or, put another way, a single database + connection never caches more than one copy of a database page + within the page cache. +

    + At any one time, each page cache entry may be said to be a clean + page, a non-writable dirty page or a writable dirty page, + according to the following definitions: +

      +
    • A clean page is one for which the cached data + currently matches the contents of the corresponding page of + the database file. The page has not been modified since it was + loaded from the file. +

    • A dirty page is a page cache entry for which + the cached data has been modified since it was loaded from the database + file, and so no longer matches the current contents of the + corresponding database file page. A dirty page is one that is + currently buffering a modification made to the database file as part + of a write transaction. +

    • Within this document, the term non-writable dirty + page is used specifically to refer to a page cache + entry with modified content for which it is not yet safe to update + the database file with. It is not safe to update a database file with + a buffered write if a power or system failure that occurs during or + soon after the update may cause the database to become corrupt + following system recovery, according to the assumptions made in + section fs_assumption_details. +

    • A dirty page for which it would be safe to update the + corresponding database file page with the modified contents of + without risking database corruption is known as a + writable dirty page. +

    +

    + The exact logic used to determine if a page cache entry with + modified content is a dirty page or writable page is + presented in section page_cache_algorithms. +

    + Because main-memory is a limited resource, the page cache cannot + be allowed to grow indefinitely. As a result, unless all database files + opened by database connections within the process are quite small, + sometimes data must be discarded from the page cache. In practice + this means page cache entries must be purged to make room + for new ones. If a page cache entry being removed from the page + cache to free main-memory is a dirty page, then its contents + must be saved into the database file before it can be discarded without + data loss. The following two sub-sections describe the algorithms used by + the page cache to determine exactly when existing page cache + entries are purged (discarded). +

    Page Cache Configuration

    +

    + Describe the parameters set to configure the page cache limits. +

    Page Cache Algorithms

    +

    + Requirements describing the way in which the configuration parameters + are used. About LRU etc. +

    Reading Data

    +

    + In order to return data from the database to the user, for example as + the results of a SELECT query, SQLite must at some point read data + from the database file. Usually, data is read from the database file in + aligned blocks of page-size bytes. The exception is when the + database file header fields are being inspected, before the + page-size used by the database can be known. +

    + With two exceptions, a database connection must have an open + transaction (either a read-only transaction or a + read/write transaction) on the database before data may be + read from the database file. +

    + The two exceptions are: +

      +
    • When an attempt is made to read the 100 byte database file + header immediately after opening the database connection + (see section open_new_connection). When this occurs + no lock is held on the database file. +
    • Data read while in the process of opening a read-only transaction + (see section open_read_only_trans). These read + operations occur after a shared lock is held on the database + file. +
    +

    + Once a transaction has been opened, reading data from a database + connection is a simple operation. Using the xRead() method of the + file-handle open on the database file, the required database file + pages are read one at a time. SQLite never reads partial pages and + always uses a single call to xRead() for each required page. +

    + After reading the data for a database page, SQLite stores the raw + page of data in the page cache. Each time a page of data is + required by the upper layers, the page cache is queried + to see if it contains a copy of the required page stored by + the current database connection. If such an entry can be + found, then the required data is read from the page cache instead + of the database file. Only a connection with an open transaction + transaction (either a read-only transaction or a + read/write transaction) on the database may read data from the + page cache. In this sense reading from the page cache is no + different to reading from the database file. +

    + Refer to section page_cache_algorithms for a description + of exactly how and for how long page data is stored in the + page cache. +

    +Except for the read operation required by H35070 and those reads made +as part of opening a read-only transaction, SQLite shall ensure that +a database connection has an open read-only or read/write +transaction when any data is read from the database file. +

    +Aside from those read operations described by H35070 and H21XXX, SQLite +shall read data from the database file in aligned blocks of +page-size bytes, where page-size is the database page size +used by the database file. +

    +SQLite shall ensure that a database connection has an open +read-only or read/write transaction before using data stored in the page +cache to satisfy user queries. +

    Opening a Read-Only Transaction

    +

    + Before data may be read from a database file or queried from + the page cache, a read-only transaction must be + successfully opened by the associated database connection (this is true + even if the connection will eventually write to the database, as a + read/write transaction may only be opened by upgrading from a + read-only transaction). This section describes the procedure + for opening a read-only transaction. +

    + The key element of a read-only transaction is that the + file-handle open on the database file obtains and holds a + shared-lock on the database file. Because a connection requires + an exclusive-lock before it may actually modify the contents + of the database file, and by definition while one connection is holding + a shared-lock no other connection may hold an + exclusive-lock, holding a shared-lock guarantees that + no other process may modify the database file while the read-only + transaction remains open. This ensures that read-only + transactions are sufficiently isolated from the transactions of + other database users (see section overview). +

    Obtaining the shared lock itself on the database file is quite + simple, SQLite just calls the xLock() method of the database file + handle. Some of the other processes that take place as part of + opening the read-only transaction are quite complex. The + steps that SQLite is required to take to open a read-only + transaction, in the order in which they must occur, is as follows: +

      +
    1. A shared-lock is obtained on the database file. +
    2. The connection checks if a hot journal file exists in the + file-system. If one does, then it is rolled back before continuing. +
    3. The connection checks if the data in the page cache may + still be trusted. If not, all page cache data is discarded. +
    4. If the file-size is not zero bytes and the page cache does not + contain valid data for the first page of the database, then the + data for the first page must be read from the database. +
    +

    + Of course, an error may occur while attempting any of the 4 steps + enumerated above. If this happens, then the shared-lock is + released (if it was obtained) and an error returned to the user. + Step 2 of the procedure above is described in more detail in section + hot_journal_detection. Section cache_validation + describes the process identified by step 3 above. Further detail + on step 4 may be found in section read_page_one. +

    +When required to open a read-only transaction using a +database connection, SQLite shall first attempt to obtain +a shared-lock on the file-handle open on the database file. +

    +If, while opening a read-only transaction, SQLite fails to obtain +the shared-lock on the database file, then the process is +abandoned, no transaction is opened and an error returned to the user. +

    + The most common reason an attempt to obtain a shared-lock may + fail is that some other connection is holding an exclusive or + pending lock. However it may also fail because some other + error (e.g. an IO or comms related error) occurs within the call to the + xLock() method. +

    +While opening a read-only transaction, after successfully +obtaining a shared lock on the database file, SQLite shall +attempt to detect and roll back a hot journal file associated +with the same database file. +

    +If, while opening a read-only transaction, SQLite encounters +an error while attempting to detect or roll back a hot journal +file, then the shared-lock on the database file is released, +no transaction is opened and an error returned to the user. +

    + Section hot_journal_detection contains a description of + and requirements governing the detection of a hot-journal file referred + to in the above requirements. +

    +Assuming no errors have occurred, then after attempting to detect and +roll back a hot journal file, if the page cache contains +any entries associated with the current database connection, +then SQLite shall validate the contents of the page cache by +testing the file change counter. This procedure is known as +cache validation. +

    + The cache validation process is described in detail in section + cache_validation +

    +If the cache validate procedure prescribed by H35040 is required and +does not prove that the page cache entries associated with the +current database connection are valid, then SQLite shall discard +all entries associated with the current database connection from +the page cache. +

    + The numbered list above notes that the data for the first page of the + database file, if it exists and is not already loaded into the page + cache, must be read from the database file before the read-only + transaction may be considered opened. This is handled by + requirement H35240. +

    Hot Journal Detection

    +

    + This section describes the procedure that SQLite uses to detect a + hot journal file. If a hot journal file is detected, + this indicates that at some point the process of writing a + transaction to the database was interrupted and a recovery operation + (hot journal rollback) needs to take place. This section does + not describe the process of hot journal rollback (see section + hot_journal_rollback) or the processes by which a + hot journal file may be created (see section + writing_data). +

    + The procedure used to detect a hot-journal file is quite + complex. The following steps take place: +

      +
    1. Using the VFS xAccess() method, SQLite queries the file-system + to see if the journal file associated with the database exists. + If it does not, then there is no hot-journal file. +
    2. By invoking the xCheckReservedLock() method of the file-handle + opened on the database file, SQLite checks if some other connection + holds a reserved lock or greater. If some other connection + does hold a reserved lock, this indicates that the other + connection is midway through a read/write transaction (see + section writing_data). In this case the + journal file is not a hot-journal and must not be + rolled back. +
    3. Using the xFileSize() method of the file-handle opened + on the database file, SQLite checks if the database file is + 0 bytes in size. If it is, the journal file is not considered + to be a hot journal file. Instead of rolling back the + journal file, in this case it is deleted from the file-system + by calling the VFS xDelete() method. Technically, + there is a race condition here. This step should be moved to + after the exclusive lock is held. +
    4. An attempt is made to upgrade to an exclusive lock on the + database file. If the attempt fails, then all locks, including + the recently obtained shared lock are dropped. The attempt + to open a read-only transaction has failed. This occurs + when some other connection is also attempting to open a + read-only transaction and the attempt to gain the + exclusive lock fails because the other connection is also + holding a shared lock. It is left to the other connection + to roll back the hot journal. +
      + It is important that the file-handle lock is upgraded + directly from shared to exclusive in this case, + instead of first upgrading to reserved or pending + locks as is required when obtaining an exclusive lock to + write to the database file (section writing_data). + If SQLite were to first upgrade to a reserved or + pending lock in this scenario, then a second process also + trying to open a read-transaction on the database file might + detect the reserved lock in step 2 of this process, + conclude that there was no hot journal, and commence + reading data from the database file. +
    5. The xAccess() method is invoked again to detect if the journal + file is still in the file system. If it is, then it is a + hot-journal file and SQLite tries to roll it back (see section + rollback). +
    +

    Master journal file pointers? +

    + The following requirements describe step 1 of the above procedure in + more detail. +

    +When required to attempt to detect a hot-journal file, SQLite +shall first use the xAccess() method of the VFS layer to check if a +journal file exists in the file-system. +

    +If the call to xAccess() required by H35140 fails (due to an IO error or +similar), then SQLite shall abandon the attempt to open a read-only +transaction, relinquish the shared lock held on the database +file and return an error to the user. +

    +When required to attempt to detect a hot-journal file, if the +call to xAccess() required by H35140 indicates that a journal file does +not exist, then SQLite shall conclude that there is no hot-journal +file in the file system and therefore that no hot journal +rollback is required. +

    + The following requirements describe step 2 of the above procedure in + more detail. +

    +When required to attempt to detect a hot-journal file, if the +call to xAccess() required by H35140 indicates that a journal file +is present, then the xCheckReservedLock() method of the database file +file-handle is invoked to determine whether or not some other +process is holding a reserved or greater lock on the database +file. +

    +If the call to xCheckReservedLock() required by H35160 fails (due to an +IO or other internal VFS error), then SQLite shall abandon the attempt +to open a read-only transaction, relinquish the shared lock +held on the database file and return an error to the user. +

    +If the call to xCheckReservedLock() required by H35160 indicates that +some other database connection is holding a reserved +or greater lock on the database file, then SQLite shall conclude that +there is no hot journal file. In this case the attempt to detect +a hot journal file is concluded. +

    + The following requirements describe step 3 of the above procedure in + more detail. +

    +If while attempting to detect a hot-journal file the call to +xCheckReservedLock() indicates that no process holds a reserved +or greater lock on the database file, then SQLite shall open +a file handle on the potentially hot journal file using the VFS xOpen() +method. +

    +If the call to xOpen() required by H35440 fails (due to an IO or other +internal VFS error), then SQLite shall abandon the attempt to open a +read-only transaction, relinquish the shared lock held on +the database file and return an error to the user. +

    +After successfully opening a file-handle on a potentially hot journal +file, SQLite shall query the file for its size in bytes using the +xFileSize() method of the open file handle. +

    +If the call to xFileSize() required by H35450 fails (due to an IO or +other internal VFS error), then SQLite shall abandon the attempt to open +a read-only transaction, relinquish the shared lock held on +the database file, close the file handle opened on the journal file and +return an error to the user. +

    +If the size of a potentially hot journal file is revealed to be zero +bytes by a query required by H35450, then SQLite shall close the +file handle opened on the journal file and delete the journal file using +a call to the VFS xDelete() method. In this case SQLite shall conclude +that there is no hot journal file. +

    +If the call to xDelete() required by H35450 fails (due to an IO or +other internal VFS error), then SQLite shall abandon the attempt to open +a read-only transaction, relinquish the shared lock held on +the database file and return an error to the user. +

    + The following requirements describe step 4 of the above procedure in + more detail. +

    +If the size of a potentially hot journal file is revealed to be greater +than zero bytes by a query required by H35450, then SQLite shall attempt +to upgrade the shared lock held by the database connection +on the database file directly to an exclusive lock. +

    +If an attempt to upgrade to an exclusive lock prescribed by +H35470 fails for any reason, then SQLite shall release all locks held by +the database connection and close the file handle opened on the +journal file. The attempt to open a read-only transaction +shall be deemed to have failed and an error returned to the user. +

    + Finally, the following requirements describe step 5 of the above + procedure in more detail. +

    +If, as part of the hot journal file detection process, the +attempt to upgrade to an exclusive lock mandated by H35470 is +successful, then SQLite shall query the file-system using the xAccess() +method of the VFS implementation to test whether or not the journal +file is still present in the file-system. +

    +If the call to xAccess() required by H35490 fails (due to an IO or +other internal VFS error), then SQLite shall abandon the attempt to open +a read-only transaction, relinquish the lock held on the +database file, close the file handle opened on the journal file and +return an error to the user. +

    +If the call to xAccess() required by H35490 reveals that the journal +file is no longer present in the file system, then SQLite shall abandon +the attempt to open a read-only transaction, relinquish the +lock held on the database file, close the file handle opened on the +journal file and return an SQLITE_BUSY error to the user. +

    +If the xAccess() query required by H35490 reveals that the journal +file is still present in the file system, then SQLite shall conclude +that the journal file is a hot journal file that needs to +be rolled back. SQLite shall immediately begin hot journal +rollback. +

    Cache Validation

    +

    + When a database connection opens a read transaction, the + page cache may already contain data associated with the + database connection. However, if another process has modified + the database file since the cached pages were loaded it is possible that + the cached data is invalid. +

    + SQLite determines whether or not the page cache entries belonging + to the database connection are valid or not using the file + change counter, a field in the database file header. The + file change counter is a 4-byte big-endian integer field stored + starting at byte offset 24 of the database file header. Before the + conclusion of a read/write transaction that modifies the contents + of the database file in any way (see section writing_data), + the value stored in the file change counter is incremented. When + a database connection unlocks the database file, it stores the + current value of the file change counter. Later, while opening a + new read-only transaction, SQLite checks the value of the file + change counter stored in the database file. If the value has not + changed since the database file was unlocked, then the page cache + entries can be trusted. If the value has changed, then the page + cache entries cannot be trusted and all entries associated with + the current database connection are discarded. +

    +When a file-handle open on a database file is unlocked, if the +page cache contains one or more entries belonging to the +associated database connection, SQLite shall store the value +of the file change counter internally. +

    +When required to perform cache validation as part of opening +a read transaction, SQLite shall read a 16 byte block +starting at byte offset 24 of the database file using the xRead() +method of the database connections file handle. +

    + Why a 16 byte block? Why not 4? (something to do with encrypted + databases). +

    +While performing cache validation, after loading the 16 byte +block as required by H35190, SQLite shall compare the 32-bit big-endian +integer stored in the first 4 bytes of the block to the most +recently stored value of the file change counter (see H35180). +If the values are not the same, then SQLite shall conclude that +the contents of the cache are invalid. +

    + Requirement H35050 (section open_read_only_trans) + specifies the action SQLite is required to take upon determining that + the cache contents are invalid. +

    Page 1 and the Expected Page Size

    +

    + As the last step in opening a read transaction on a database + file that is more than 0 bytes in size, SQLite is required to load + data for page 1 of the database into the page cache, if it is + not already there. This is slightly more complicated than it seems, + as the database page-size is no known at this point. +

    + Even though the database page-size cannot be known for sure, + SQLite is usually able to guess correctly by assuming it to be equal to + the connections expected page size. The expected page size + is the value of the page-size field read from the + database file header while opening the database connection + (see section open_new_connection), or the page-size + of the database file when the most read transaction was concluded. +

    +During the conclusion of a read transaction, before unlocking +the database file, SQLite shall set the connections +expected page size to the current database page-size. +

    +As part of opening a new read transaction, immediately after +performing cache validation, if there is no data for database +page 1 in the page cache, SQLite shall read N bytes from +the start of the database file using the xRead() method of the +connections file handle, where N is the connections current +expected page size value. +

    +If page 1 data is read as required by H35230, then the value of the +page-size field that appears in the database file header that +consumes the first 100 bytes of the read block is not the same as the +connections current expected page size, then the +expected page size is set to this value, the database file is +unlocked and the entire procedure to open a read transaction +is repeated. +

    +If page 1 data is read as required by H35230, then the value of the +page-size field that appears in the database file header that +consumes the first 100 bytes of the read block is the same as the +connections current expected page size, then the block of data +read is stored in the page cache as page 1. +

    Reading Database Data

    +

    + Add something about checking the page-cache first etc. +

    Ending a Read-only Transaction

    +

    + To end a read-only transaction, SQLite simply relinquishes the + shared lock on the file-handle open on the database file. No + other action is required. +

    +When required to end a read-only transaction, SQLite shall +relinquish the shared lock held on the database file by +calling the xUnlock() method of the file-handle. +

    + See also requirements H35180 and H35210 above. +

    Writing Data

    +

    + Using DDL or DML SQL statements, SQLite users may modify the contents and + size of a database file. Exactly how changes to the logical database are + translated to modifications to the database file is described in + ff_sqlitert_requirements. From the point of view of the + sub-systems described in this document, each DDL or DML statement executed + results in the contents of zero or more database file pages being + overwritten with new data. A DDL or DML statement may also append or + truncate one or more pages to or from the end of the database file. One + or more DDL and/or DML statements are grouped together to make up a + single write transaction. A write transaction is required + to have the special properties described in section overview; + a write transaction must be isolated, durable and atomic. +

    + SQLite accomplishes these goals using the following techniques: +

      +
    • + To ensure that write transactions are isolated, before + beginning to modify the contents of the database file to reflect the + results of a write transaction, SQLite obtains an exclusive + lock on the database file. The lock is not relinquished + until the write transaction is concluded. Because reading from + the database file requires a shared lock (see section + reading_data) and holding an exclusive + lock guarantees that no other database connection is holding + or can obtain a shared lock, this ensures that no other + connection may read data from the database file at a point when + a write transaction has been partially applied. +

    • Ensuring that write transactions are atomic is the most + complex task required of the system. In this case, atomic means + that even if a system failure occurs, an attempt to commit a write + transaction to the database file either results in all changes + that are a part of the transaction being successfully applied to the + database file, or none of the changes are successfully applied. There + is no chance that a subset of the changes only are applied. Hence from + the point of view of an external observer, the write transaction + appears to be an atomic event. +

      + Of course, it is usually not possible to atomically apply all the + changes required by a write transaction to a database file + within the file-system. For example, if a write transaction + requires ten pages of a database file to be modified, and a power + outage causes a system failure after sqlite has modified only five + pages, then the database file will almost certainly be in an + inconsistent state following system recovery. +

      + SQLite solves this problem by using a journal file. In almost + all cases, before the database file is modified in any way, + SQLite stores sufficient information in the journal file to + allow the original the database file to be reconstructed if a system + failure occurs while the database file is being updated to reflect + the modifications made by the write transaction. Each time + SQLite opens a database file, it checks if such a system failure has + occurred and, if so, + reconstructs the database file based on the contents + of the journal file. The procedure used to detect whether or not this + process, coined hot journal rollback, is required is described + in section hot_journal_detection. Hot journal rollback + itself is described in section hot_journal_rollback. +

      + The same technique ensures that an SQLite database file cannot be + corrupted by a system failure that occurs at an inopportune moment. + If a system failure does occur before SQLite has had a chance to + execute sufficient sync file operations to ensure that the + changes that make up a write transaction have made it safely + to persistent storage, then the journal file will be used + to restore the database to a known good state following system + recovery. +

    • + So that write transactions are durable in the face of + a system failure, SQLite executes a sync file operation on the + database file before concluding the write transaction +

    +

    + The page cache is used to buffer modifications to the database + file image before they are written to the database file. When + the contents of a page is required to be modified as the results of + an operation within a write transaction, the modified copy is + stored in the page cache. Similarly, if new pages are appended + to the end of a database file, they are added to the page cache + instead of being immediately written to the database file within the + file-system. +

    + Ideally, all changes for an entire write transaction are buffered in + the page cache until the end of the transaction. When the user commits + the transaction, all changes are applied to the database file in the + most efficient way possible, taking into account the assumptions + enumerated in section fs_performance. Unfortunately, since + main-memory is a limited resource, this is not always possible for + large transactions. In this case changes are buffered in the page + cache until some internal condition or limit is reached, + then written out to the database file in order to free resources + as they are required. Section page_cache_algorithms + describes the circumstances under which changes are flushed through + to the database file mid-transaction to free page cache resources. +

    + Even if an application or system failure does not occur while a + write transaction is in progress, a rollback operation to restore + the database file and page cache to the state that it was in before + the transaction started may be required. This may occur if the user + explicitly requests transaction rollback (by issuing a "ROLLBACK" command), + or automatically, as a result of encountering an SQL constraint (see + sql_sqlitert_requirements). For this reason, the original page + content is stored in the journal file before the page is even + modified within the page cache. +

    + Introduce the following sub-sections. +

    Journal File Format

    +

    + This section describes the format used by an SQLite journal file. +

    + A journal file consists of one or more journal headers, zero + or more journal records and optionally a master journal + pointer. Each journal file always begins with a + journal header, followed by zero or more journal records. + Following this may be a second journal header followed by a + second set of zero or more journal records and so on. There + is no limit to the number of journal headers a journal file + may contain. Following the journal headers and their accompanying + sets of journal records may be the optional master journal + pointer. Or, the file may simply end following the final journal + record. +

    + This section only describes the format of the journal file and the + various objects that make it up. But because a journal file may be + read by an SQLite process following recovery from a system failure + (hot journal rollback, see section + hot_journal_rollback) it is also important to describe + the way the file is created and populated within the file-system + using a combination of write file, sync file and + truncate file operations. These are described in section + write_transactions. +

    Journal Header Format

    +

    + A journal header is sector-size bytes in size, where + sector-size is the value returned by the xSectorSize method of + the file handle opened on the database file. Only the first 28 bytes + of the journal header are used, the remainder may contain garbage + data. The first 28 bytes of each journal header consists of an + eight byte block set to a well-known value, followed by five big-endian + 32-bit unsigned integer fields. +

    +

    Figure - Journal Header Format +

    +

    + Figure figure_journal_header graphically depicts the layout + of a journal header. The individual fields are described in + the following table. The offsets in the 'byte offset' column of the + table are relative to the start of the journal header. + +
    Byte offsetSize in bytesDescription +
    08The journal magic field always contains a + well-known 8-byte string value used to identify SQLite + journal files. The well-known sequence of byte values + is: +
    0xd9 0xd5 0x05 0xf9 0x20 0xa1 0x63 0xd7
    +
    84This field, the record count, is set to the + number of journal records that follow this + journal header in the journal file. +
    124The checksum initializer field is set to a + pseudo-random value. It is used as part of the + algorithm to calculate the checksum for all journal + records that follow this journal header. +
    164This field, the database page count, is set + to the number of pages that the database file + contained before any modifications associated with + write transaction are applied. +
    204This field, the sector size, is set to the + sector size of the device on which the + journal file was created, in bytes. This value + is required when reading the journal file to determine + the size of each journal header. +
    244The page size field contains the database page + size used by the corresponding database file + when the journal file was created, in bytes. +
    +

    + All journal headers are positioned in the file so that they + start at a sector size aligned offset. To achieve this, unused + space may be left between the start of the second and subsequent + journal headers and the end of the journal records + associated with the previous header. +

    Journal Record Format

    +

    + Each journal record contains the original data for a database page + modified by the write transaction. If a rollback is required, then + this data may be used to restore the contents of the database page to the + state it was in before the write transaction was started. +

    +

    Figure - Journal Record Format +

    +

    + A journal record, depicted graphically by figure + figure_journal_record, contains three fields, as described + in the following table. Byte offsets are relative to the start of the + journal record. + +
    Byte offsetSize in bytesDescription +
    04The page number of the database page associated with + this journal record, stored as a 4 byte + big-endian unsigned integer. +
    4page-size + This field contains the original data for the page, + exactly as it appeared in the database file before the + write transaction began. +
    4 + page-size4 + This field contains a checksum value, calculated based + on the contents of the journaled database page data + (the previous field) and the values stored in the + checksum initializer field of the preceding + journal header. +
    +

    + The set of journal records that follow a journal header + in a journal file are packed tightly together. There are no + alignment requirements for journal records as there are for + journal headers. +

    Master Journal Pointer

    +

    + To support atomic transactions that modify more than one + database file, SQLite sometimes includes a master journal pointer + record in a journal file. Multiple file transactions are + described in section multifile_transactions. A + master journal pointer contains the name of a master journal-file + along with a check-sum and some well known values that allow + the master journal pointer to be recognized as such when + the journal file is read during a rollback operation (section + rollback). +

    + As is the case for a journal header, the start of a master + journal pointer is always positioned at a sector size + aligned offset. If the journal record or journal header + that appears immediately before the master journal pointer does + not end at an aligned offset, then unused space is left between the + end of the journal record or journal header and the start + of the master journal pointer. +

    +

    Figure - Master Journal Pointer Format +

    +

    + A master journal pointer, depicted graphically by figure + figure_master_journal_ptr, contains five fields, as + described in the following table. Byte offsets are relative to the + start of the master journal pointer. + +
    Byte offsetSize in bytesDescription +
    04This field, the locking page number, is always + set to the page number of the database locking page + stored as a 4-byte big-endian integer. The locking page + is the page that begins at byte offset 230 of the + database file. Even if the database file is large enough to + contain the locking page, the locking page is + never used to store any data and so the first four bytes of of a + valid journal record will never contain this value. For + further description of the locking page, refer to + ff_sqlitert_requirements. +
    4name-length + The master journal name field contains the name of the + master journal file, encoded as a utf-8 string. There is no + nul-terminator appended to the string. +
    4 + name-length4 + The name-length field contains the length of the + previous field in bytes, formatted as a 4-byte big-endian + unsigned integer. +
    8 + name-length4 + The checksum field contains a checksum value stored as + a 4-byte big-endian signed integer. The checksum value is + calculated as the sum of the bytes that make up the + master journal name field, interpreting each byte as + an 8-bit signed integer. +
    12 + name-length8 + Finally, the journal magic field always contains a + well-known 8-byte string value; the same value stored in the + first 8 bytes of a journal header. The well-known + sequence of bytes is: +
    0xd9 0xd5 0x05 0xf9 0x20 0xa1 0x63 0xd7
    +
    +

    Write Transactions

    +

    + This section describes the progression of an SQLite write + transaction. From the point of view of the systems described in + this document, most write transactions consist of three steps: +

      +
    1. The write transaction is opened. This process is described + in section opening_a_write_transaction. +

    2. The end-user executes DML or DDL SQL statements that require the + structure of the database file of the database file to be modified. + These modifications may be any combination of operations to +

      • modify the content of an existing database page, +
      • append a new database page to the database file image, or +
      • truncate (discard) a database page from the end of the + database file. +
      + These operations are described in detail in section + modifying_appending_truncating. How user DDL or DML + SQL statements are mapped to combinations of these three operations + is described in ff_sqlitert_requirements. +
    3. The write transaction is concluded and the changes made + permanently committed to the database. The process required to + commit a transaction is described in section + committing_a_transaction. +

    +

    + As an alternative to step 3 above, the transaction may be rolled back. + Transaction rollback is described in section rollback. + Finally, it is also important to remember that a write transaction + may be interrupted by a system failure at any point. In this + case, the contents of the file-system (the database file and + journal file) must be left in such a state so as to enable + the database file to be restored to the state it was in before + the interrupted write transaction was started. This is known + as hot journal rollback, and is described in section + hot_journal_rollback. Section + fs_assumption_details describes the assumptions made + regarding the effects of a system failure on the file-system + contents following recovery. +

    Beginning a Write Transaction

    +

    + Before any database pages may be modified within the page cache, + the database connection must open a write transaction. + Opening a write transaction requires that the database + connection obtains a reserved lock (or greater) on the + database file. Because obtaining a reserved lock on + a database file guarantees that no other database + connection may hold or obtain a reserved lock or greater, + it follows that no other database connection may have an + open write transaction. +

    + A reserved lock on the database file may be thought of + as an exclusive lock on the journal file. No + database connection may read from or write to a journal + file without a reserved or greater lock on the corresponding + database file. +

    + Before opening a write transaction, a database connection + must have an open read transaction, opened via the procedure + described in section open_read_only_trans. This ensures + that there is no hot-journal file that needs to be rolled back + and that any data stored in the page cache can be trusted. +

    + Once a read transaction has been opened, upgrading to a + write transaction is a two step process, as follows: +

      +
    1. A reserved lock is obtained on the database file. +
    2. The journal file is opened and created if necessary (using + the VFS xOpen method), and a journal file header written + to the start of it using a single call to the file handles xWrite + method. +
    +

    + Requirements describing step 1 of the above procedure in detail: +

    +When required to open a write transaction on the database, +SQLite shall first open a read transaction, if the database +connection in question has not already opened one. +

    +When required to open a write transaction on the database, after +ensuring a read transaction has already been opened, SQLite +shall obtain a reserved lock on the database file by calling +the xLock method of the file-handle open on the database file. +

    +If an attempt to acquire a reserved lock prescribed by +requirement H35360 fails, then SQLite shall deem the attempt to +open a write transaction to have failed and return an error +to the user. +

    + Requirements describing step 2 of the above procedure in detail: +

    +When required to open a write transaction on the database, after +obtaining a reserved lock on the database file, SQLite shall +open a read/write file-handle on the corresponding journal file. +

    +When required to open a write transaction on the database, after +opening a file-handle on the journal file, SQLite shall append +a journal header to the (currently empty) journal file. +

    Writing a Journal Header

    +

    + Requirements describing how a journal header is appended to + a journal file: +

    +When required to append a journal header to the journal +file, SQLite shall do so by writing a block of sector-size +bytes using a single call to the xWrite method of the file-handle +open on the journal file. The block of data written shall begin +at the smallest sector-size aligned offset at or following the current +end of the journal file. +

    +The first 8 bytes of the journal header required to be written +by H35680 shall contain the following values, in order from byte offset 0 +to 7: 0xd9, 0xd5, 0x05, 0xf9, 0x20, 0xa1, 0x63 and 0xd7. +

    +Bytes 8-11 of the journal header required to be written by +H35680 shall contain 0x00. +

    +Bytes 12-15 of the journal header required to be written by +H35680 shall contain the number of pages that the database file +contained when the current write-transaction was started, +formatted as a 4-byte big-endian unsigned integer. +

    +Bytes 16-19 of the journal header required to be written by +H35680 shall contain pseudo-randomly generated values. +

    +Bytes 20-23 of the journal header required to be written by +H35680 shall contain the sector size used by the VFS layer, +formatted as a 4-byte big-endian unsigned integer. +

    +Bytes 24-27 of the journal header required to be written by +H35680 shall contain the page size used by the database at +the start of the write transaction, formatted as a 4-byte +big-endian unsigned integer. +

    + Modifying, Adding or Truncating a Database Page +

    +

    + When the end-user executes a DML or DDL SQL statement to modify the + database schema or content, SQLite is required to update the database + file image to reflect the new database state. This involves modifying + the content of, appending or truncating one of more database file + pages. Instead of modifying the database file directly using the VFS + interface, changes are first buffered within the page cache. +

    + Before modifying a database page within the page cache that + may need to be restored by a rollback operation, the page must be + journalled. Journalling a page is the process of copying + that pages original data into the journal file so that it can be + recovered if the write transaction is rolled back. The process + of journalling a page is described in section + journalling_a_page. +

    +When required to modify the contents of an existing database page that +existed and was not a free-list leaf page when the write +transaction was opened, SQLite shall journal the page if it has not +already been journalled within the current write transaction. +

    +When required to modify the contents of an existing database page, +SQLite shall update the cached version of the database page content +stored as part of the page cache entry associated with the page. +

    + When a new database page is appended to a database file, there is + no requirement to add a record to the journal file. If a + rollback is required the database file will simply be truncated back + to its original size based on the value stored at byte offset 12 + of the journal file. +

    +When required to append a new database page to the database file, +SQLite shall create a new page cache entry corresponding to +the new page and insert it into the page cache. The dirty +flag of the new page cache entry shall be set. +

    + If required to truncate a database page from the end of the database + file, the associated page cache entry is discarded. The adjusted + size of the database file is stored internally. The database file + is not actually truncated until the current write transaction + is committed (see section committing_a_transaction). +

    +When required to truncate (remove) a database page that existed and was +not a free-list leaf page when the write transaction was +opened from the end of a database file, SQLite shall journal the page if +it has not already been journalled within the current write +transaction. +

    +When required to truncate a database page from the end of the database +file, SQLite shall discard the associated page cache entry +from the page cache. +

    Journalling a Database Page

    +

    + A page is journalled by adding a journal record to the + journal file. The format of a journal record is described + in section journal_record_format. +

    +When required to journal a database page, SQLite shall first +append the page number of the page being journalled to the +journal file, formatted as a 4-byte big-endian unsigned integer, +using a single call to the xWrite method of the file-handle opened +on the journal file. +

    +When required to journal a database page, if the attempt to +append the page number to the journal file is successful, +then the current page data (page-size bytes) shall be appended +to the journal file, using a single call to the xWrite method of the +file-handle opened on the journal file. +

    +When required to journal a database page, if the attempt to +append the current page data to the journal file is successful, +then SQLite shall append a 4-byte big-endian integer checksum value +to the to the journal file, using a single call to the xWrite method +of the file-handle opened on the journal file. +

    + The checksum value written to the journal file immediately after + the page data (requirement H35290), is a function of both the page + data and the checksum initializer field stored in the + journal header (see section journal_header_format). + Specifically, it is the sum of the checksum initializer and + the value of every 200th byte of page data interpreted as an 8-bit + unsigned integer, starting with the (page-size % 200)'th + byte of page data. For example, if the page-size is 1024 bytes, + then a checksum is calculated by adding the values of the bytes at + offsets 23, 223, 423, 623, 823 and 1023 (the last byte of the page) + together with the value of the checksum initializer. +

    +The checksum value written to the journal file by the write +required by H35290 shall be equal to the sum of the checksum +initializer field stored in the journal header (H35700) and +every 200th byte of the page data, beginning with the +(page-size % 200)th byte. +

    + The '%' character is used in requirement H35300 to represent the + modulo operator, just as it is in programming languages such as C, Java + and Javascript. +

    Syncing the Journal File

    +

    + Even after the original data of a database page has been written into + the journal file using calls to the journal file file-handle xWrite + method (section journalling_a_page), it is still not + safe to write to the page within the database file. This is because + in the event of a system failure the data written to the journal file + may still be corrupted (see section fs_characteristics). + Before the page can be updated within the database itself, the + following procedure takes place: +

      +
    1. The xSync method of the file-handle opened on the journal file + is called. This operation ensures that all journal records + in the journal file have been written to persistent storage, and + that they will not become corrupted as a result of a subsequent + system failure. +
    2. The journal record count field (see section + journal_header_format) of the most recently written + journal header in the journal file is updated to contain the + number of journal records added to the journal file since + the header was written. +
    3. The xSync method is called again, to ensure that the update to + the journal record count has been committed to persistent + storage. +
    +

    + If all three of the steps enumerated above are executed successfully, + then it is safe to modify the content of the journalled + database pages within the database file itself. The combination of + the three steps above is referred to as syncing the journal file. +

    +When required to sync the journal file, SQLite shall invoke the +xSync method of the file handle open on the journal file. +

    +When required to sync the journal file, after invoking the +xSync method as required by H35750, SQLite shall update the record +count of the journal header most recently written to the +journal file. The 4-byte field shall be updated to contain +the number of journal records that have been written to the +journal file since the journal header was written, +formatted as a 4-byte big-endian unsigned integer. +

    +When required to sync the journal file, after updating the +record count field of a journal header as required by +H35760, SQLite shall invoke the xSync method of the file handle open +on the journal file. +

    Upgrading to an Exclusive Lock

    +

    + Before the content of a page modified within the page cache may + be written to the database file, an exclusive lock must be held + on the database file. The purpose of this lock is to prevent another + connection from reading from the database file while the first + connection is midway through writing to it. Whether the reason for + writing to the database file is because a transaction is being committed, + or to free up space within the page cache, upgrading to an + exclusive lock always occurs immediately after + syncing the journal file. +

    +When required to upgrade to an exclusive lock as part of a write +transaction, SQLite shall first attempt to obtain a pending lock +on the database file if one is not already held by invoking the xLock +method of the file handle opened on the database file. +

    +When required to upgrade to an exclusive lock as part of a write +transaction, after successfully obtaining a pending lock SQLite +shall attempt to obtain an exclusive lock by invoking the +xLock method of the file handle opened on the database file. +

    + What happens if the exclusive lock cannot be obtained? It is not + possible for the attempt to upgrade from a reserved to a pending + lock to fail. +

    Committing a Transaction

    +

    + Committing a write transaction is the final step in updating the + database file. Committing a transaction is a seven step process, + summarized as follows: +

      +
    1. + The database file header change counter field is incremented. + The change counter, described in + ff_sqlitert_requirements, is used by the cache + validation procedure described in section + cache_validation. +

    2. + The journal file is synced. The steps required to sync the + journal file are described in section + syncing_journal_file. +

    3. + Upgrade to an exclusive lock on the database file, if an + exclusive lock is not already held. Upgrading to an + exclusive lock is described in section + upgrading_to_exclusive_lock. +

    4. + Copy the contents of all dirty pages stored in the page + cache into the database file. The set of dirty pages are written + to the database file in page number order in order to improve + performance (see the assumptions in section fs_performance + for details). +

    5. + The database file is synced to ensure that all updates are stored + safely on the persistent media. +

    6. + The file-handle open on the journal file is closed and the + journal file itself deleted. At this point the write transaction + transaction has been irrevocably committed. +

    7. + The database file is unlocked. +

    +

    + Expand on and explain the above a bit. +

    + The following requirements describe the steps enumerated above in more + detail. +

    +When required to commit a write-transaction, SQLite shall +modify page 1 to increment the value stored in the change counter +field of the database file header. +

    + The change counter is a 4-byte big-endian integer field stored + at byte offset 24 of the database file. The modification to page 1 + required by H35800 is made using the process described in section + modifying_appending_truncating. If page 1 has not already + been journalled as a part of the current write-transaction, then + incrementing the change counter may require that page 1 be + journalled. In all cases the page cache entry corresponding to + page 1 becomes a dirty page as part of incrementing the change + counter value. +

    +When required to commit a write-transaction, after incrementing +the change counter field, SQLite shall sync the journal +file. +

    +When required to commit a write-transaction, after syncing +the journal file as required by H35810, if an exclusive lock +on the database file is not already held, SQLite shall attempt to +upgrade to an exclusive lock. +

    +When required to commit a write-transaction, after syncing +the journal file as required by H35810 and ensuring that an +exclusive lock is held on the database file as required by +H35830, SQLite shall copy the contents of all dirty page +stored in the page cache into the database file using +calls to the xWrite method of the database connection file +handle. Each call to xWrite shall write the contents of a single +dirty page (page-size bytes of data) to the database +file. Dirty pages shall be written in order of page number, +from lowest to highest. +

    +When required to commit a write-transaction, after copying the +contents of any dirty pages to the database file as required +by H35830, SQLite shall sync the database file by invoking the xSync +method of the database connection file handle. +

    +When required to commit a write-transaction, after syncing +the database file as required by H35840, SQLite shall close the +file-handle opened on the journal file and delete the +journal file from the file system via a call to the VFS +xDelete method. +

    +When required to commit a write-transaction, after deleting +the journal file as required by H35850, SQLite shall relinquish +all locks held on the database file by invoking the xUnlock +method of the database connection file handle. +

    + Is the shared lock held after committing a write transaction? +

    Purging a Dirty Page

    +

    + Usually, no data is actually written to the database file until the + user commits the active write transaction. The exception is + if a single write transaction contains too many modifications + to be stored in the page cache. In this case, some of the + database file modifications stored in the page cache must be + applied to the database file before the transaction is committed so + that the associated page cache entries can be purged from the + page cache to free memory. Exactly when this condition is reached and + dirty pages must be purged is described in section + page_cache_algorithms. +

    + Before the contents of the page cache entry can be written into + the database file, the page cache entry must meet the criteria + for a writable dirty page, as defined in section + page_cache_algorithms. If the dirty page selected by the + algorithms in section page_cache_algorithms for purging, + SQLite is required to sync the journal file. Immediately after + the journal file is synced, all dirty pages associated with the + database connection are classified as writable dirty pages. +

    +When required to purge a non-writable dirty page from the +page cache, SQLite shall sync the journal file before +proceeding with the write operation required by H35670. +

    +After syncing the journal file as required by H35640, SQLite +shall append a new journal header to the journal file +before proceeding with the write operation required by H35670. +

    + Appending a new journal header to the journal file is described + in section writing_journal_header. +

    + Once the dirty page being purged is writable, it is simply written + into the database file. +

    +When required to purge a page cache entry that is a +dirty page SQLite shall write the page data into the database +file, using a single call to the xWrite method of the database +connection file handle. +

    Multi-File Transactions

    +

    Statement Transactions

    +

    Rollback

    +

    Hot Journal Rollback

    +

    Transaction Rollback

    +

    Statement Rollback

    +

    References

    + +
    [1] + C API Requirements Document. +
    [2] + SQL Requirements Document. +
    [3] + File Format Requirements Document. +
    + + diff -Nru sqlite3-3.42.0/www/flextypegood.html sqlite3-3.44.0-0/www/flextypegood.html --- sqlite3-3.42.0/www/flextypegood.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/flextypegood.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,495 +0,0 @@ - - - - - -The Advantages Of Flexible Typing - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -
    - - - - - -

    1. Introduction

    - -

    SQLite provides developers with the freedom to store content in -any desired format, regardless of the declared datatype of the column. -Some people find this feature troublesome. Some developers are shocked -to discover that it is possible to insert text into a column marked INTEGER. - -

    This article advocates in favor of the flexible type rules -in SQLite. - -

    2. About Flexible Typing

    - -

    Details regarding the flexible type system of SQLite are found -in the separate Datatypes In SQLite document. Here is a quick -summary: - -

      -
    • Datatype names on column definitions are optional. A column definition - can consist of just the column name and nothing else. -

    • When datatype names are provided, they can be just about any text. - SQLite attempts to deduce the preferred datatype for the column based - on the datatype name in the column definition, but that preferred - datatype is advisory, not mandatory. The preferred datatype is - call the "column affinity". -

    • An attempt is made to transform incoming data into the preferred - datatype of the column. (All SQL database engines do this, not - just SQLite.) If this transformation is successful, all is well. - But if unsuccessful, instead of raising an error, SQLite just stores - the content using its original datatype. -

    • The above can lead to situations that advocates of rigid typing - find incommodious: -

      -
      Column DatatypeTypes Allowed In That Column -
      INTEGERINTEGER, REAL, TEXT, BLOB -
      REALREAL, TEXT, BLOB -
      TEXTTEXT, BLOB -
      BLOBINTEGER, REAL, TEXT, BLOB -
      -
    • Note that an INTEGER or REAL value will never end up being stored - in a TEXT column, since an INTEGER or REAL value can and always will - be converted into its equivalent TEXT representation. Similarly, - an INTEGER will never be stored in a REAL column because it will - always be converted into a REAL. But TEXT does not always look like - an INTEGER or REAL value and so cannot always be converted. And a - BLOB cannot be converted into anything and nothing else can be - converted into a BLOB. -

    - - -

    3. Cases Where Flexible Typing Is Useful

    - -

    Some readers, upon first encountering flexible typing in SQLite, ask -themselves "how could this ever be useful?" Here is an -attempt to answer that question: - -

    3.1. Attribute tables

    - -

    Many applications, especially those that use SQLite as an -application file format, need a place to store miscellaneous attributes -such as thumbnail images (as BLOB values), short pieces of text (such -as the user's name), as well as numeric, date, and JSON values. It is -convenient to create a single table to handle this storage: - -

    CREATE TABLE attribute(name TEXT PRIMARY KEY, value) WITHOUT ROWID;
    -
    - -

    Without flexible typing, such a table would need to be more complex, -with separate columns for each possible type of data. Flexible typing -of the "value" column makes the table conceptually simpler, more -space-efficient, and easier to access and update. - -

    In the Fossil version control system, each -repository has a CONFIG table that is used to store all kinds of settings -with every possible datatype. The user-specific configuration file -for Fossil (the ~/.fossil file) is a separate SQLite database that contains -a single attribute table hold the user-specific state across all -repositories. - -

    Some applications use an SQLite database as a pure key-value store -The database schema contains a single table that looks something like this: - -

    CREATE TABLE storage(name TEXT PRIMARY KEY, value ANYTHING);
    -
    - -

    3.2. The "value" column output from the json_tree virtual tables

    - -

    The json_tree and json_each table-valued functions that are -built into SQLite both have a "value" column that can hold values of -type INTEGER, REAL, or TEXT depending on the type of the corresponding -JSON field. For example: - -

    SELECT typeof(value) FROM json_each('{"a":1,"b":2.5,"c":"hello"}');
    -
    - -

    The query above returns three rows of one column with values -"integer", "real", and "text", respectively. - -

    3.3. Storage for dirty data

    - -

    Analysts sometimes encounter CSV files where some columns contain -a mixture of integer, real, and text data. CSV files that are obtained -from Excel spreadsheet exports commonly have this trait, for example. -When importing such "dirty data" into an SQL database, it is convenient -to have flexibly typed columns to import into. - -

    Dirty data is not restricted to CSV files coming out of Excel, of -course. There are many data sources in which a single field might -contain a mix of types. For example, a data column might contain the number -of seconds since 1970 sometimes, or a text date string in other cases. -It is desirable to clean up these inconsistent representations, -but at the same time it is convenient to be able to store all the different -representations in the same column of the intermediate database while the -cleanup is underway. - -

    3.4. Dynamic programming languages

    - -

    SQLite began as a TCL extension that later escaped into the wild. -TCL is a dynamic language in the sense that the programmer does not need -to be aware of datatypes. Under the hood, TCL keeps careful track of the -datatype of every value, but to the developer and user of a TCL program, -everything looks like a string. Flexible typing is a natural fit for -use with dynamic programming languages like TCL and others, since with -a dynamic programming language, you can not always predict in advance what -datatype a variable will hold. So when you need to store the value of that -variable into the database, having a database that supports flexible -typing makes storage much easier. - -

    3.5. Data typename cross-compatibility

    - -

    Every SQL database engine seems to have its own unique set of supported -datatype names: - -

      -
    • BIGINT -
    • UNSIGNED SMALL INT -
    • TEXT -
    • VARCHAR -
    • VARYING CHARACTER -
    • NATIONAL VARYING CHARACTER -
    • NVARCHAR -
    • JSON -
    • REAL -
    • FLOAT -
    • DOUBLE PRECISION -
    • ... and so forth ... -
    - -

    The fact that SQLite will accept any of these names as a valid typename, -and let you store any kind of content into the column, increases the chances -that a script written to run on some other SQL database engine will also -work in SQLite. - -

    3.6. Repurposing unused or disused columns in legacy databases

    - -

    Because an SQLite database file is a single file on disk, some -applications use SQLite as an application file format. This means -that a single instance of the application might, over the course of its -life, talk to hundreds or thousands of separate databases, each in a separate -file. When such applications evolve over years, some columns in the -underlying database will have their meanings altered subtly. Or, it might -be desirable to repurpose an existing column to serve two or more purposes. -This is much easier to do if the column has a flexible datatype. - -

    4. Perceived Disadvantages of Flexible Typing (With Rebuttals)

    - -

    The following perceived disadvantages of flexible typing were - gleaned and compiled from countless posts on Hacker News and - Reddit and similar forums where developers discuss these sorts of - things. If you can think of other reasons why flexible typing - is a bad idea, please contact the SQLite developers or leave a - post on the SQLite Forum so - that your idea can be added to the list. - - -

    4.1. We've never done it that way before

    - -

    Many skeptics of flexible typing simply express -shock and disbelief, without offering any rationale for why they think -flexible typing is a bad idea. Without supporting arguments, one must -assume their reason for not liking flexible typing is that it is different -from what they are used to. - -

    Presumably, many developers who are aghast at SQLite's flexible -typing feel this way because they have just never encountered anything -like it before. All prior exposure to databases and especially SQL -databases has involved rigid typing, and the readers mental model of -SQL includes rigid typing as a fundamental feature. Flexible typing -upsets their world-view. - -

    Yes, flexible typing is a new way of thinking about data in an -SQL database. But new is not necessary bad. Sometimes, and I think -especially in the case of flexible typing, innovation leads to improvement. - -

    4.2. Rigid type enforcement helps prevent application bugs

    - -

    It has become a point of doctrine among many programmers that the -best way to prevent application bugs is strict type enforcement. But I -find no evidence in support of this. - -

    To be sure, strict type enforcement does help prevent some kinds of -bugs in lower-level languages like C and C++ that present a model that is -close to machine hardware. But this does not seem to -be the case for higher-abstraction languages in which all data is -passed around in a "Value" superclass of some kind which is subclassed -for the various lower-level data types. When everything is a Value -object, specific datatypes cease to be important. - -

    This technical note is being writing by the original author of SQLite. -I having been writing TCL programs for 27 years. TCL has no type enforcement -whatsoever. The "Value" class in TCL (called Tcl_Obj) can hold many -different datatypes, but it presents the content to the program and to -the application user as a string. And I've had a lot of bugs in -those TCL programs over the years. But I do not recall a single instance -where the bugs might have been caught by a rigid type system. I have -also written a lot of C code over a span of 35 years, not the -least of which is SQLite itself. I have found the type system in C -to be very helpful at finding and preventing problems. For the -Fossil Version Control System, which is written -in C, I have even implemented supplemental static analysis programs that -scan the Fossil source code prior to compilation, looking for problems -that compilers miss. This works well for compiled programs. - -

    The SQL language model is a higher-level abstraction than C/C++. -In SQLite, every data item is stored in memory as an "sqlite3_value" object. -There are subclasses of this object for strings, integer, floating-point -numbers, blobs, and other representations. Everything is passed around -inside the SQL language implemented by SQLite as "sqlite3_value" objects -so the underlying datatype does not really matter. I have never found -rigid type enforcement to be helpful in languages like TCL and SQLite -that have a single "Value" superclass used to represent any data element. -Fossil makes extensive use of SQLite in its implementation. There have -been many bugs in Fossil over its 14-years history, but I cannot recall -a single bug that might have been prevented by rigid type enforcement in -the SQLite. Some C-language bugs might have been caught by better type -enforcement (which is why I wrote the supplemental source code scanners), -but no SQL bugs. - -

    Based on decades of experience, I reject the thesis that rigid -type enforcement helps prevent application bugs. I will accept and -believe a slightly modified thesis: Rigid type enforcement helps to -prevent applications bugs in languages that lack a single -top-level "Value" superclass. But SQLite does have the -single "sqlite3_value" superclass, so that proverb does not apply. - -

    4.3. Rigid type enforcement prevents data pollution

    - -

    Some people contend that if you have rigorous constraints on the -schema, and especially strict enforcement of column datatypes, this -will help prevent incorrect data from being added to the database. -This is not true. It is true that type enforcement might help prevent -egregiously incorrect data from getting into the system. -But type enforcement is no help in prevent subtly incorrect data -from being recorded. - -

    So, for example, rigid type enforcement can successfully prevent -the customer name (text) from being inserted into integer -Customer.creditScore column. On the other hand, if that mistake occurs, -it is very easy to spot the problem and find all affected rows. -But type enforcement is no help in preventing a bug where the customer -family name and given name are reversed, since both are text fields. - -

    (Aside: Decades ago, I worked on a team where there was a woman -named "Merritt Tracy". "Merritt" was her given name and "Tracy" was -her family name. She reported that she spent an inordinate amount of -time and energy trying to correct databases that had "Tracy" has her -given name and "Merritt" as her family name.) - -

    By suppressing easy-to-detect errors and passing through only the -hard-to-detect errors, rigid type enforcement can actually make it more -difficult to find and fix bugs. Data errors tend to cluster. If you have -20 different data sources, most of the data errors will usually come -from just 2 or 3 of those sources. The presence of egregious -errors (such as text in an integer column) is a convenient early warning -signal that something is amiss. The source of the problem can be -tracked quickly and extra scrutiny applied to the source of the -egregious errors, thus hopefully also fixing the subtle errors too. -When egregious errors are suppressed, you lose an important signal -that helps you to detect and fix the subtle errors. - -

    Data errors are inevitable. They will happen regardless of how -much type checking is done. Rigid type enforcement can catch only -a small subset of those cases - the most obvious cases. It does -nothing to help find and fix the more subtle cases. And, by suppressing -the signal of which data sources are problematic, it can sometimes -make the subtle errors more difficult to locate. - -

    4.4. Other SQL database engines don't work this way

    - -

    Because SQLite is less restrictive and allows you to do more things, -SQL scripts that work on other database engines will also usually work -on SQLite, but script written initially for SQLite might not work -on more restrictive database engines. This can cause problems when -developers user SQLite for prototyping and testing and then migrate their -application to a more restrictive SQL engine for deployment. If the -application was (unintentionally) taking advantage of the flexible -typing available in SQLite, then it will fail when migrated. - -

    People use this problem to argue that SQLite should be more -restrictive about datatypes. But you could just as easily turn -that argument around and say that other database engines should be -more flexible with regard to datatypes. The application was working -correctly under SQLite, prior to be migrated, after all. If rigid -type enforcement is really all that useful, why did it break an -application that was previously working? - -

    5. If You Insist On Rigid Type Enforcement...

    - -

    As of SQLite version 3.37.0 (2021-11-27), SQLite supports this -development style using STRICT tables. - -

    If you find a real-world case where STRICT tables prevented or -would have prevented a bug in an application, please post a message to the -SQLite Forum so that we can add your story -to this document. - -

    6. Embrace Freedom

    - -

    If flexible typing in an SQL database is a new concept to you, -I encourage you to give it a try. It probably will not cause you -any problems and it might make your program simpler and easier to -write and maintain. I think that even if you are skeptical at first, -if you will just give flexible typing a try, you will eventually -come to realize that it is a better approach and will start -encouraging other database vendors to support at least an ANY -datatype if not complete SQLite-style type flexibility. - -

    Most of the time, flexible typing does not matter because a column -stores a single well-defined type. But occasionally you will run -across situations where having a flexible type system makes the -solution to your problem cleaner and easier. -

    This page last modified on 2023-04-29 00:28:20 UTC

    - diff -Nru sqlite3-3.42.0/www/floatingpoint.html sqlite3-3.44.0-0/www/floatingpoint.html --- sqlite3-3.42.0/www/floatingpoint.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/floatingpoint.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -162,7 +138,7 @@

    SQLite stores integer values in the 64-bit twos-complement -format¹. +format. This gives a storage range of -9223372036854775808 to +9223372036854775807, inclusive. Integers within this range are exact. @@ -170,7 +146,7 @@ So-called "REAL" or floating point values are stored in the IEEE 754 Binary-64 -format¹. +format. This gives a range of positive values between approximately 1.7976931348623157e+308 and 4.9406564584124654e-324 with an equivalent range of negative values. A binary64 can also be 0.0 (and -0.0), positive @@ -188,10 +164,6 @@ values, in SQLite or in any other product. This is not an SQLite limitation. It is a mathematical limitation inherent in the design of floating-point numbers. -


    ¹ -Exception: The R-Tree extension stores information as 32-bit floating -point or integer values. -

    1.1. Floating-Point Accuracy

    @@ -393,7 +365,7 @@ blob into the floating-point value that the binary64 encoding represents.

    So, for example, if you read -on +on Wikipedia that the encoding for the minimum positive binary64 value is 0x0000000000000001, then you can find the corresponding floating point value like this: @@ -481,5 +453,4 @@ SELECT decimal_mul(ieee754_mantissa(c.n),pow2.v) FROM pow2, c WHERE pow2.x=ieee754_exponent(c.n);

    -

    This page last modified on 2022-11-21 14:37:06 UTC

    diff -Nru sqlite3-3.42.0/www/footprint.html sqlite3-3.44.0-0/www/footprint.html --- sqlite3-3.42.0/www/footprint.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/footprint.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -216,5 +192,4 @@ Performance was measured by running speedtest1 using cachegrind and observing the "I refs" output. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/foreignkeys.html sqlite3-3.44.0-0/www/foreignkeys.html --- sqlite3-3.42.0/www/foreignkeys.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/foreignkeys.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -368,7 +344,7 @@

    In order to use foreign key constraints in SQLite, the library must - be compiled with neither SQLITE_OMIT_FOREIGN_KEY nor + be compiled with neither SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined. If SQLITE_OMIT_TRIGGER is defined but SQLITE_OMIT_FOREIGN_KEY is not, then SQLite behaves as it did prior to version 3.6.19 (2009-10-14) @@ -937,8 +913,7 @@ foreign key constraints are not checked when a table is created. There is nothing stopping the user from creating a foreign key definition that refers to a parent table that does not exist, or to parent key columns that - do not exist or are not collectively bound by a PRIMARY KEY or UNIQUE - constraint. + do not exist or are not collectively bound by a PRIMARY KEY or UNIQUE constraint.

    The ALTER TABLE command works differently in two respects when foreign @@ -1042,5 +1017,4 @@ of foreign key actions. It is not possible to disable recursive foreign key actions.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/formatchng.html sqlite3-3.44.0-0/www/formatchng.html --- sqlite3-3.42.0/www/formatchng.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/formatchng.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,78 +89,189 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    File Format Changes in SQLite

    The underlying file format for SQLite databases does not -change in incompatible ways. There are literally trillions of +change in incompatible ways. There are literally hundreds of billions, +perhaps trillions, of SQLite database files in circulation and the SQLite developers are committing to supporting those files for decades into the future.

    -Prior to SQLite version 3.0.0 (2004-06-18), the file format did -sometimes change from one release to the next. But since that time, -the file format has been fully backwards compatible. +This document describes incompatibilities that have occurred in +SQLite prior to 2004. Since 2004, there have been enhancements to +SQLite such that newer database files are unreadable by older versions +of the SQLite library. But the most recent versions of the SQLite +library should be able to read and write any older SQLite database +file without any problems.

    -By "backwards compatible" we mean that -newer versions of SQLite can always read and write database files created -by older versions of SQLite. -It is often also the case that SQLite is "forwards compatible", that -older versions of SQLite can read and write database files created by -newer versions of SQLite. But there are sometimes forward compatibility -breaks. Sometimes new features are added to the file format. For -example, WAL mode was added in version 3.7.0 (2010-07-21). -SQLite 3.7.0 and later can read and write all database files created -by earlier versions of SQLite. And earlier versions of SQLite can -read and write database files created by SQLite 3.7.0 and later -as long as the database does not use WAL mode. But versions of -SQLite prior to version 3.7.0 cannot read nor write SQLite database files -that make use of WAL mode. +In other words, since 2004 all SQLite releases have been backwards +compatible, though not necessarily forwards compatible.

    -

    Summary

    +

    +The following table summarizes the SQLite file format changes that have +occurred since version 1.0.0: +

    -
      -
    • -Newer versions of SQLite can always read and/or write database files -created by older versions of SQLite, back to version 3.0.0 (2004-06-18). - -

    • -Older versions of SQLite back to version 3.0.0 can read and write -database files created by newer versions of SQLite as long as the -database does not make use of newer features that are unknown to that -older version. -

    -

    This page last modified on 2022-09-13 14:04:46 UTC

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    Version ChangeApprox. DateDescription Of File Format Change
    1.0.32 to 2.0.02001-09-20Version 1.0.X of SQLite used the GDBM library as its backend + interface to the disk. Beginning in version 2.0.0, GDBM was replaced + by a custom B-Tree library written especially for SQLite. The new + B-Tree backend is twice as fast as GDBM, supports atomic commits and + rollback, and stores an entire database in a single disk file instead + using a separate file for each table as GDBM does. The two + file formats are not even remotely similar.
    2.0.8 to 2.1.02001-10-12The same basic B-Tree format is used but the details of the + index keys were changed in order to provide better query + optimization opportunities. Some of the headers were also changed in order + to increase the maximum size of a row from 64KB to 24MB.

    + + This change is an exception to the version number rule described above + in that it is neither forwards or backwards compatible. A complete + reload of the database is required. This is the only exception.

    2.1.7 to 2.2.02001-12-21Beginning with version 2.2.0, SQLite no longer builds an index for + an INTEGER PRIMARY KEY column. Instead, it uses that column as the actual + B-Tree key for the main table.

    Version 2.2.0 and later of the library + will automatically detect when it is reading a 2.1.x database and will + disable the new INTEGER PRIMARY KEY feature. In other words, version + 2.2.x is backwards compatible to version 2.1.x. But version 2.1.x is not + forward compatible with version 2.2.x. If you try to open + a 2.2.x database with an older 2.1.x library and that database contains + an INTEGER PRIMARY KEY, you will likely get a coredump. If the database + schema does not contain any INTEGER PRIMARY KEYs, then the version 2.1.x + and version 2.2.x database files will be identical and completely + interchangeable.

    +
    2.2.5 to 2.3.02002-01-30Beginning with version 2.3.0, SQLite supports some additional syntax + (the "ON CONFLICT" clause) in the CREATE TABLE and CREATE INDEX statements + that are stored in the SQLITE_MASTER table. If you create a database that + contains this new syntax, then try to read that database using version 2.2.5 + or earlier, the parser will not understand the new syntax and you will get + an error. Otherwise, databases for 2.2.x and 2.3.x are interchangeable.
    2.3.3 to 2.4.02002-03-10Beginning with version 2.4.0, SQLite added support for views. + Information about views is stored in the SQLITE_MASTER table. If an older + version of SQLite attempts to read a database that contains VIEW information + in the SQLITE_MASTER table, the parser will not understand the new syntax + and initialization will fail. Also, the + way SQLite keeps track of unused disk blocks in the database file + changed slightly. + If an older version of SQLite attempts to write a database that + was previously written by version 2.4.0 or later, then it may leak disk + blocks.
    2.4.12 to 2.5.02002-06-17Beginning with version 2.5.0, SQLite added support for triggers. + Information about triggers is stored in the SQLITE_MASTER table. If an older + version of SQLite attempts to read a database that contains a CREATE TRIGGER + in the SQLITE_MASTER table, the parser will not understand the new syntax + and initialization will fail. +
    2.5.6 to 2.6.02002-07-17A design flaw in the layout of indices required a file format change + to correct. This change appeared in version 2.6.0.

    + + If you use version 2.6.0 or later of the library to open a database file + that was originally created by version 2.5.6 or earlier, an attempt to + rebuild the database into the new format will occur automatically. + This can take some time for a large database. (Allow 1 or 2 seconds + per megabyte of database under Unix - longer under Windows.) This format + conversion is irreversible. It is strongly suggested + that you make a backup copy of older database files prior to opening them + with version 2.6.0 or later of the library, in case there are errors in + the format conversion logic.

    + + Version 2.6.0 or later of the library cannot open read-only database + files from version 2.5.6 or earlier, since read-only files cannot be + upgraded to the new format.

    +
    2.6.3 to 2.7.02002-08-13

    Beginning with version 2.7.0, SQLite understands two different + datatypes: text and numeric. Text data sorts in memcmp() order. + Numeric data sorts in numerical order if it looks like a number, + or in memcmp() order if it does not.

    + +

    When SQLite version 2.7.0 or later opens a 2.6.3 or earlier database, + it assumes all columns of all tables have type "numeric". For 2.7.0 + and later databases, columns have type "text" if their datatype + string contains the substrings "char" or "clob" or "blob" or "text". + Otherwise they are of type "numeric".

    + +

    Because "text" columns have a different sort order from numeric, + indices on "text" columns occur in a different order for version + 2.7.0 and later database. Hence version 2.6.3 and earlier of SQLite + will be unable to read a 2.7.0 or later database. But version 2.7.0 + and later of SQLite will read earlier databases.

    +
    2.7.6 to 2.8.02003-02-14

    Version 2.8.0 introduces a change to the format of the rollback + journal file. The main database file format is unchanged. Versions + 2.7.6 and earlier can read and write 2.8.0 databases and vice versa. + Version 2.8.0 can rollback a transaction that was started by version + 2.7.6 and earlier. But version 2.7.6 and earlier cannot rollback a + transaction started by version 2.8.0 or later.

    + +

    The only time this would ever be an issue is when you have a program + using version 2.8.0 or later that crashes with an incomplete + transaction, then you try to examine the database using version 2.7.6 or + earlier. The 2.7.6 code will not be able to read the journal file + and thus will not be able to rollback the incomplete transaction + to restore the database.

    +
    2.8.14 to 3.0.02004-06-18

    Version 3.0.0 is a major upgrade for SQLite that incorporates + support for UTF-16, BLOBs, and a more compact encoding that results + in database files that are typically 25% to 50% smaller. The new file + format is very different and is completely incompatible with the + version 2 file format.

    +
    +
    diff -Nru sqlite3-3.42.0/www/fts3.html sqlite3-3.44.0-0/www/fts3.html --- sqlite3-3.42.0/www/fts3.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/fts3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -196,33 +172,33 @@

    Overview

    - FTS3 and FTS4 are SQLite virtual table modules that allows users to perform - full-text searches on a set of documents. The most common (and effective) + FTS3 and FTS4 are SQLite virtual table modules that allows users to perform + full-text searches on a set of documents. The most common (and effective) way to describe full-text searches is "what Google, Yahoo, and Bing do - with documents placed on the World Wide Web". Users input a term, or series - of terms, perhaps connected by a binary operator or grouped together into a - phrase, and the full-text query system finds the set of documents that best - matches those terms considering the operators and groupings the user has + with documents placed on the World Wide Web". Users input a term, or series + of terms, perhaps connected by a binary operator or grouped together into a + phrase, and the full-text query system finds the set of documents that best + matches those terms considering the operators and groupings the user has specified. This article describes the deployment and usage of FTS3 and FTS4.

    FTS1 and FTS2 are obsolete full-text search modules for SQLite. There are known issues with these older modules and their use should be avoided. - Portions of the original FTS3 code were contributed to the SQLite project - by Scott Hess of Google. It is now + Portions of the original FTS3 code were contributed to the SQLite project + by Scott Hess of Google. It is now developed and maintained as part of SQLite.

    1. Introduction to FTS3 and FTS4

    - The FTS3 and FTS4 extension modules allows users to create special tables with a + The FTS3 and FTS4 extension modules allows users to create special tables with a built-in full-text index (hereafter "FTS tables"). The full-text index allows the user to efficiently query the database for all rows that contain one or more words (hereafter "tokens"), even if the table contains many large documents.

    - For example, if each of the 517430 documents in the + For example, if each of the 517430 documents in the "Enron E-Mail Dataset" is inserted into both an FTS table and an ordinary SQLite table created using the following SQL script: @@ -246,7 +222,7 @@ the LIKE query matches rows that contain terms such as "linuxophobe" or "EnterpriseLinux" (as it happens, the Enron E-Mail Dataset does not actually contain any such terms), whereas the MATCH query on the FTS3 table - selects only those rows that contain "linux" as a discrete token. Both + selects only those rows that contain "linux" as a discrete token. Both searches are case-insensitive. The FTS3 table consumes around 2006 MB on disk compared to just 1453 MB for the ordinary table. Using the same hardware configuration used to perform the SELECT queries above, the FTS3 @@ -267,9 +243,9 @@ very common (present in a large percentage of table rows).

  • FTS4 supports some additional options that may used with the matchinfo() - function. + function. -

  • Because it stores extra information on disk in two new +

  • Because it stores extra information on disk in two new shadow tables in order to support the performance optimizations and extra matchinfo() options, FTS4 tables may consume more disk space than the equivalent table created using FTS3. Usually the overhead @@ -279,13 +255,13 @@ declaration, but this comes at the expense of sacrificing some of the extra supported matchinfo() options. -

  • FTS4 provides hooks (the compress and uncompress - options) allowing data to be stored in a compressed +

  • FTS4 provides hooks (the compress and uncompress + options) allowing data to be stored in a compressed form, reducing disk usage and IO.

  • - FTS4 is an enhancement to FTS3. + FTS4 is an enhancement to FTS3. FTS3 has been available since SQLite version 3.5.0 (2007-09-04) The enhancements for FTS4 were added with SQLite version 3.7.4 (2010-12-07). @@ -300,22 +276,22 @@ more disk space than FTS3, though only a percent of two in most cases.

    - For newer applications, FTS4 is recommended; though if compatibility with older - versions of SQLite is important, then FTS3 will usually serve just as well. + For newer applications, FTS4 is recommended; though if compatibility with older + versions of SQLite is important, then FTS3 will usually serve just as well.

    1.2. Creating and Destroying FTS Tables

    - Like other virtual table types, new FTS tables are created using a + Like other virtual table types, new FTS tables are created using a CREATE VIRTUAL TABLE statement. The module name, which follows the USING keyword, is either "fts3" or "fts4". The virtual table module arguments may - be left empty, in which case an FTS table with a single user-defined + be left empty, in which case an FTS table with a single user-defined column named "content" is created. Alternatively, the module arguments - may be passed a list of comma separated column names. + may be passed a list of comma separated column names.

    If column names are explicitly provided for the FTS table as part of - the CREATE VIRTUAL TABLE statement, then a datatype name may be optionally + the CREATE VIRTUAL TABLE statement, then a datatype name may be optionally specified for each column. This is pure syntactic sugar, the supplied typenames are not used by FTS or the SQLite core for any purpose. The same applies to any constraints specified along with an @@ -346,7 +322,7 @@ <tokenizer args> is an optional list of whitespace separated qualifiers to pass to the tokenizer implementation. A tokenizer specification may be placed anywhere in the column list, but at most one tokenizer declaration is - allowed for each CREATE VIRTUAL TABLE statement. See below for a + allowed for each CREATE VIRTUAL TABLE statement. See below for a detailed description of using (and, if necessary, implementing) a tokenizer.

    -- Create an FTS table named "papers" with two columns that uses
    @@ -379,20 +355,20 @@
     
       

    As well as the columns named by the user (or the "content" column if no - module arguments were specified as part of the CREATE VIRTUAL TABLE + module arguments were specified as part of the CREATE VIRTUAL TABLE statement), each FTS table has a "rowid" column. The rowid of an FTS - table behaves in the same way as the rowid column of an ordinary SQLite - table, except that the values stored in the rowid column of an FTS table - remain unchanged if the database is rebuilt using the VACUUM command. + table behaves in the same way as the rowid column of an ordinary SQLite + table, except that the values stored in the rowid column of an FTS table + remain unchanged if the database is rebuilt using the VACUUM command. For FTS tables, "docid" is allowed as an alias along with the usual "rowid", - "oid" and "_oid_" identifiers. Attempting to insert or update a row with a - docid value that already exists in the table is an error, just as it would + "oid" and "_oid_" identifiers. Attempting to insert or update a row with a + docid value that already exists in the table is an error, just as it would be with an ordinary SQLite table.

    There is one other subtle difference between "docid" and the normal SQLite - aliases for the rowid column. Normally, if an INSERT or UPDATE statement - assigns discrete values to two or more aliases of the rowid column, SQLite + aliases for the rowid column. Normally, if an INSERT or UPDATE statement + assigns discrete values to two or more aliases of the rowid column, SQLite writes the rightmost of such values specified in the INSERT or UPDATE statement to the database. However, assigning a non-NULL value to both the "docid" and one or more of the SQLite rowid aliases when inserting or @@ -423,19 +399,19 @@

    To support full-text queries, FTS maintains an inverted index that maps from each unique term or word that appears in the dataset to the locations - in which it appears within the table contents. For the curious, a + in which it appears within the table contents. For the curious, a complete description of the data structure used to store this index within the database file appears below. A feature of this data structure is that at any time the database may contain not one index b-tree, but several different b-trees that are incrementally - merged as rows are inserted, updated and deleted. This technique improves + merged as rows are inserted, updated and deleted. This technique improves performance when writing to an FTS table, but causes some overhead for - full-text queries that use the index. Evaluating the special "optimize" command, + full-text queries that use the index. Evaluating the special "optimize" command, an SQL statement of the form "INSERT INTO <fts-table>(<fts-table>) VALUES('optimize')", causes FTS to merge all existing index b-trees into a single large b-tree containing the entire index. This can be an expensive operation, - but may speed up future queries. + but may speed up future queries.

    For example, to optimize the full-text index for an FTS table named @@ -450,7 +426,7 @@ the section describing the simple fts queries for an explanation.

    - There is another, deprecated, method for invoking the optimize + There is another, deprecated, method for invoking the optimize operation using a SELECT statement. New code should use statements similar to the INSERT above to optimize FTS structures. @@ -469,13 +445,13 @@

  • Query by rowid. If the WHERE clause of the SELECT statement contains a sub-clause of the form "rowid = ?", where ? is an SQL expression, - FTS is able to retrieve the requested row directly using the equivalent + FTS is able to retrieve the requested row directly using the equivalent of an SQLite INTEGER PRIMARY KEY index.

  • Full-text query. If the WHERE clause of the SELECT statement contains - a sub-clause of the form "<column> MATCH ?", FTS is able to use - the built-in full-text index to restrict the search to those documents + a sub-clause of the form "<column> MATCH ?", FTS is able to use + the built-in full-text index to restrict the search to those documents that match the full-text query string specified as the right-hand operand of the MATCH clause.

  • @@ -483,7 +459,7 @@

    If neither of these two query strategies can be used, all queries on FTS tables are implemented using a linear scan of the entire - table. If the table contains large amounts of data, this may be an + table. If the table contains large amounts of data, this may be an impractical approach (the first example on this page shows that a linear scan of 1.5 GB of data takes around 30 seconds using a modern PC). @@ -501,12 +477,12 @@

    In all of the full-text queries above, the right-hand operand of the MATCH operator is a string consisting of a single term. In this case, the MATCH - expression evaluates to true for all documents that contain one or more - instances of the specified word ("sqlite", "search" or "database", depending + expression evaluates to true for all documents that contain one or more + instances of the specified word ("sqlite", "search" or "database", depending on which example you look at). Specifying a single term as the right-hand - operand of the MATCH operator results in the simplest and most common type + operand of the MATCH operator results in the simplest and most common type of full-text query possible. However more complicated queries are possible, - including phrase searches, term-prefix searches and searches for documents + including phrase searches, term-prefix searches and searches for documents containing combinations of terms occurring within a defined proximity of each other. The various ways in which the full-text index may be queried are described below. @@ -519,7 +495,7 @@

    The paragraph above notes that a MATCH operator with a simple term as the right-hand operand evaluates to true for all documents that contain the - specified term. In this context, the "document" may refer to either the + specified term. In this context, the "document" may refer to either the data stored in a single column of a row of an FTS table, or to the contents of all columns in a single row, depending on the identifier used as the left-hand operand to the MATCH operator. If the identifier specified as @@ -527,7 +503,7 @@ then the document that the search term must be contained in is the value stored in the specified column. However, if the identifier is the name of the FTS table itself, then the MATCH operator evaluates to true - for each row of the FTS table for which any column contains the search + for each row of the FTS table for which any column contains the search term. The following example demonstrates this:

    -- Example schema
    @@ -544,21 +520,21 @@
     SELECT * FROM mail WHERE mail    MATCH 'software';    -- Selects rows 1, 2 and 3
     SELECT * FROM mail WHERE mail    MATCH 'slow';        -- Selects rows 1 and 3
     
    - +

    At first glance, the final two full-text queries in the example above seem to be syntactically incorrect, as there is a table name ("mail") used as an SQL expression. The reason this is acceptable is that each FTS table actually has a HIDDEN column with the same name as the table itself (in this case, "mail"). The value stored in this - column is not meaningful to the application, but can be used as the + column is not meaningful to the application, but can be used as the left-hand operand to a MATCH operator. This special column may also be passed as an argument to the FTS auxiliary functions.

    - The following example illustrates the above. The expressions "docs", - "docs.docs" and "main.docs.docs" all refer to column "docs". However, the - expression "main.docs" does not refer to any column. It could be used to + The following example illustrates the above. The expressions "docs", + "docs.docs" and "main.docs.docs" all refer to column "docs". However, the + expression "main.docs" does not refer to any column. It could be used to refer to a table, but a table name is not allowed in the context in which it is used below. @@ -571,52 +547,52 @@ SELECT * FROM docs WHERE main.docs.docs MATCH 'sqlite'; -- OK. SELECT * FROM docs WHERE main.docs MATCH 'sqlite'; -- Error.

    - +

    1.5. Summary

    From the users point of view, FTS tables are similar to ordinary SQLite - tables in many ways. Data may be added to, modified within and removed - from FTS tables using the INSERT, UPDATE and DELETE commands just as - it may be with ordinary tables. Similarly, the SELECT command may be used + tables in many ways. Data may be added to, modified within and removed + from FTS tables using the INSERT, UPDATE and DELETE commands just as + it may be with ordinary tables. Similarly, the SELECT command may be used to query data. The following list summarizes the differences between FTS and ordinary tables:

      -
    1. +

    2. As with all virtual table types, it is not possible to create indices or triggers attached to FTS tables. Nor is it possible to use the ALTER TABLE command to add extra columns to FTS tables (although it is possible to use ALTER TABLE to rename an FTS table). -

    3. +

    4. Data-types specified as part of the "CREATE VIRTUAL TABLE" statement used to create an FTS table are ignored completely. Instead of the normal rules for applying type affinity to inserted values, all values inserted into FTS table columns (except the special rowid column) are converted to type TEXT before being stored. -

    5. +

    6. FTS tables permit the special alias "docid" to be used to refer to the rowid column supported by all virtual tables. -

    7. +

    8. The FTS MATCH operator is supported for queries based on the built-in - full-text index. + full-text index. -

    9. - The FTS auxiliary functions, snippet(), offsets(), and matchinfo() are +

    10. + The FTS auxiliary functions, snippet(), offsets(), and matchinfo() are available to support full-text queries.

    11. - Every FTS table has a hidden column with the + Every FTS table has a hidden column with the same name as the table itself. The value contained in each row for the hidden column is a blob that is only useful as the left operand of a MATCH operator, or as the left-most argument to one of the FTS auxiliary functions. - +

    @@ -629,7 +605,7 @@ enabled by default. To build SQLite with FTS functionality enabled, define the preprocessor macro SQLITE_ENABLE_FTS3 when compiling. New applications should also define the SQLITE_ENABLE_FTS3_PARENTHESIS macro to enable the - enhanced query syntax (see below). Usually, this is done by adding the + enhanced query syntax (see below). Usually, this is done by adding the following two switches to the compiler command line:

    -DSQLITE_ENABLE_FTS3
    @@ -659,12 +635,12 @@
     
     

    If a build of SQLite does not include the FTS modules, then any attempt to prepare an - SQL statement to create an FTS3 or FTS4 table or to drop or access an existing - FTS table in any way will fail. The error message returned will be similar + SQL statement to create an FTS3 or FTS4 table or to drop or access an existing + FTS table in any way will fail. The error message returned will be similar to "no such module: ftsN" (where N is either 3 or 4).

    - If the C version of the ICU library + If the C version of the ICU library is available, then FTS may also be compiled with the SQLITE_ENABLE_ICU pre-processor macro defined. Compiling with this macro enables an FTS tokenizer that uses the ICU library to split a document into terms @@ -672,21 +648,21 @@

    -DSQLITE_ENABLE_ICU
     
    - +

    3. Full-text Index Queries

    - The most useful thing about FTS tables is the queries that may be - performed using the built-in full-text index. Full-text queries are - performed by specifying a clause of the form - "<column> MATCH <full-text query expression>" as part of the WHERE - clause of a SELECT statement that reads data from an FTS table. - Simple FTS queries that return all documents that + The most useful thing about FTS tables is the queries that may be + performed using the built-in full-text index. Full-text queries are + performed by specifying a clause of the form + "<column> MATCH <full-text query expression>" as part of the WHERE + clause of a SELECT statement that reads data from an FTS table. + Simple FTS queries that return all documents that contain a given term are described above. In that discussion the right-hand operand of the MATCH operator was assumed to be a string consisting of a - single term. This section describes the more complex query types supported + single term. This section describes the more complex query types supported by FTS tables, and how they may be utilized by specifying a more complex query expression as the right-hand operand of a MATCH operator. @@ -696,7 +672,7 @@

      -
    • Token or token prefix queries. +

    • Token or token prefix queries. An FTS table may be queried for all documents that contain a specified term (the simple case described above), or for all documents that contain a term with a specified prefix. As we have @@ -719,7 +695,7 @@

      • - Normally, a token or token prefix query is matched against the FTS table + Normally, a token or token prefix query is matched against the FTS table column specified as the left-hand side of the MATCH operator. Or, if the special column with the same name as the FTS table itself is specified, against all columns. This may be overridden by specifying a column-name @@ -727,7 +703,7 @@ between the ":" and the term to query for, but not between the column-name and the ":" character. For example:

      - +
      -- Query the database for documents for which the term "linux" appears in
       -- the document title, and the term "problems" appears in either the title
       -- or body of the document.
      @@ -778,11 +754,11 @@
       
       
       
        -
      • NEAR queries. +

      • NEAR queries. A NEAR query is a query that returns documents that contain a two or - more nominated terms or phrases within a specified proximity of each - other (by default with 10 or less intervening terms). A NEAR query is - specified by putting the keyword "NEAR" between two phrase, token or + more nominated terms or phrases within a specified proximity of each + other (by default with 10 or less intervening terms). A NEAR query is + specified by putting the keyword "NEAR" between two phrase, token or token prefix queries. To specify a proximity other than the default, an operator of the form "NEAR/<N>" may be used, where <N> is the maximum number of intervening terms allowed. @@ -797,7 +773,7 @@ -- Search for a document that contains the terms "sqlite" and "database" with -- not more than 10 intervening terms. This matches the only document in --- table docs (since there are only six terms between "SQLite" and "database" +-- table docs (since there are only six terms between "SQLite" and "database" -- in the document). SELECT * FROM docs WHERE docs MATCH 'sqlite NEAR database'; @@ -830,7 +806,8 @@ data as in the block of examples above:

      -
      -- The following query selects documents that contains an instance of the term 
      +
      +-- The following query selects documents that contains an instance of the term 
       -- "sqlite" separated by two or fewer terms from an instance of the term "acid",
       -- which is in turn separated by two or fewer terms from an instance of the term
       -- "relational".
      @@ -848,8 +825,8 @@
       

      The three basic query types described above may be used to query the full-text index for the set of documents that match the specified criteria. Using the - FTS query expression language it is possible to perform various set - operations on the results of basic queries. There are currently three + FTS query expression language it is possible to perform various set + operations on the results of basic queries. There are currently three supported operations:

        @@ -864,11 +841,11 @@

        The FTS modules may be compiled to use one of two slightly different versions - of the full-text query syntax, the "standard" query syntax and the "enhanced" - query syntax. The basic term, term-prefix, phrase and NEAR queries described - above are the same in both versions of the syntax. The way in which set - operations are specified is slightly different. The following two sub-sections - describe the part of the two query syntaxes that pertains to set operations. + of the full-text query syntax, the "standard" query syntax and the "enhanced" + query syntax. The basic term, term-prefix, phrase and NEAR queries described + above are the same in both versions of the syntax. The way in which set + operations are specified is slightly different. The following two sub-sections + describe the part of the two query syntaxes that pertains to set operations. Refer to the description of how to compile fts for compilation notes.

        @@ -878,12 +855,12 @@

        The enhanced query syntax supports the AND, OR and NOT binary set operators. Each of the two operands to an operator may be a basic FTS query, or the - result of another AND, OR or NOT set operation. Operators must be entered + result of another AND, OR or NOT set operation. Operators must be entered using capital letters. Otherwise, they are interpreted as basic term queries instead of set operators.

        - The AND operator may be implicitly specified. If two basic queries appear + The AND operator may be implicitly specified. If two basic queries appear with no operator separating them in an FTS query string, the results are the same as if the two basic queries were separated by an AND operator. For example, the query expression "implicit operator" is a more succinct @@ -923,7 +900,7 @@

      - The examples above all use basic full-text term queries as both operands of + The examples above all use basic full-text term queries as both operands of the set operations demonstrated. Phrase and NEAR queries may also be used, as may the results of other set operations. When more than one set operation is present in an FTS query, the precedence of operators is as follows: @@ -973,7 +950,7 @@

      1. Only the implicit version of the AND operator is supported. Specifying the string "AND" as part of a standard query syntax query is - interpreted as a term query for the set of documents containing the term + interpreted as a term query for the set of documents containing the term "and".

      @@ -982,7 +959,7 @@

      1. -
      2. The NOT operator is not supported. Instead of the NOT +

      3. The NOT operator is not supported. Instead of the NOT operator, the standard query syntax supports a unary "-" operator that may be applied to basic term and term-prefix queries (but not to phrase or NEAR queries). A term or term-prefix that has a unary "-" operator @@ -997,10 +974,10 @@

      -
    1. The relative precedence of the set operations is different. +

    2. The relative precedence of the set operations is different. In particular, using the standard query syntax the "OR" operator has a higher precedence than "AND". The precedence of operators when using the - standard query syntax is: + standard query syntax is:

    @@ -1011,7 +988,7 @@
    1. - The following example illustrates precedence of operators using the standard + The following example illustrates precedence of operators using the standard query syntax:
    @@ -1053,14 +1030,12 @@ offsets both return an empty string, and the matchinfo function returns a blob value zero bytes in size. - -

    All three auxiliary functions extract a set of "matchable phrases" from the FTS query expression to work with. The set of matchable phrases for a given query consists of all phrases (including unquoted tokens and token prefixes) in the expression except those that are prefixed with - a unary "-" operator (standard syntax) or are part of a sub-expression + a unary "-" operator (standard syntax) or are part of a sub-expression that is used as the right-hand operand of a NOT operator.

    @@ -1075,24 +1050,24 @@ types to satisfy the NEAR condition.

  • If the matchable phrase in the FTS query is restricted to matching - data in a specified FTS table column, then only phrase matches that + data in a specified FTS table column, then only phrase matches that occur within that column are considered.
  • - +

    4.1. The Offsets Function

    - For a SELECT query that uses the full-text index, the offsets() function + For a SELECT query that uses the full-text index, the offsets() function returns a text value containing a series of space-separated integers. For - each term in each phrase match of the current row, - there are four integers in the returned list. Each set of four integers is + each term in each phrase match of the current row, + there are four integers in the returned list. Each set of four integers is interpreted as follows:

    Integer Interpretation -
    0 +
    0 The column number that the term instance occurs in (0 for the leftmost column of the FTS table, 1 for the next leftmost, etc.).
    1 @@ -1140,7 +1115,7 @@

    The snippet function is used to create formatted fragments of document text - for display as part of a full-text query results report. The snippet function + for display as part of a full-text query results report. The snippet function may be passed between one and six arguments, as follows:

    @@ -1162,19 +1137,19 @@ zero. A negative value indicates that the text may be extracted from any column.
    5 -15 - The absolute value of this integer argument is used as the - (approximate) number of tokens to include in the returned text + The absolute value of this integer argument is used as the + (approximate) number of tokens to include in the returned text value. The maximum allowable absolute value is 64. The value of this argument is referred to as N in the discussion below.

    The snippet function first attempts to find a fragment of text consisting - of |N| tokens within the current row that contains at least one phrase - match for each matchable phrase matched somewhere in the current row, + of |N| tokens within the current row that contains at least one phrase + match for each matchable phrase matched somewhere in the current row, where |N| is the absolute value of the sixth argument passed to the snippet function. If the text stored in a single column contains less than - |N| tokens, then the entire column value is considered. Text fragments + |N| tokens, then the entire column value is considered. Text fragments may not span multiple columns.

    @@ -1210,7 +1185,7 @@ the best coverage are selected.

    - If N is a negative value, and no single fragment can be found + If N is a negative value, and no single fragment can be found containing the required phrase matches, the snippet function searches for two fragments of |N| tokens each, then three, then four. In other words, if the specified value of N is negative, the sizes @@ -1220,8 +1195,8 @@

    After the M fragments have been located, where M is between two and four as described in the paragraphs above, they are joined together - in sorted order with the "ellipses" text separating them. The three - modifications enumerated earlier are performed on the text before it is + in sorted order with the "ellipses" text separating them. The three + modifications enumerated earlier are performed on the text before it is returned.

    Note: In this block of examples, newlines and whitespace characters have
    @@ -1232,10 +1207,10 @@
     -- Create and populate an FTS table.
     CREATE VIRTUAL TABLE text USING fts4();
     INSERT INTO text VALUES('
    -  During 30 Nov-1 Dec, 2-3oC drops. Cool in the upper portion, minimum temperature 14-16oC
    -  and cool elsewhere, minimum temperature 17-20oC. Cold to very cold on mountaintops,
    -  minimum temperature 6-12oC. Northeasterly winds 15-30 km/hr. After that, temperature
    -  increases. Northeasterly winds 15-30 km/hr.
    +  During 30 Nov-1 Dec, 2-3oC drops. Cool in the upper portion, minimum temperature 14-16oC 
    +  and cool elsewhere, minimum temperature 17-20oC. Cold to very cold on mountaintops, 
    +  minimum temperature 6-12oC. Northeasterly winds 15-30 km/hr. After that, temperature 
    +  increases. Northeasterly winds 15-30 km/hr.     
     ');
     
     -- The following query returns the text value:
    @@ -1266,38 +1241,38 @@
     
     

    The matchinfo function is called with either one or two arguments. As for - all auxiliary functions, the first argument must be the special + all auxiliary functions, the first argument must be the special FTS hidden column. The second argument, if it is specified, must be a text value comprised only of the characters 'p', 'c', 'n', 'a', 'l', 's', 'x', 'y' and 'b'. If no second argument is explicitly supplied, it defaults to "pcx". The second argument is referred to as the "format string" below.

    - Characters in the matchinfo format string are processed from left to right. + Characters in the matchinfo format string are processed from left to right. Each character in the format string causes one or more 32-bit unsigned integer values to be added to the returned array. The "values" column in the following table contains the number of integer values appended to the output buffer for each supported format string character. In the formula - given, cols is the number of columns in the FTS table, and - phrases is the number of matchable phrases in - the query. + given, cols is the number of columns in the FTS table, and + phrases is the number of matchable phrases in + the query.

    CharacterValuesDescription
    p 1 The number of matchable phrases in the query.
    c 1 The number of user defined columns in the FTS table (i.e. not including the docid or the FTS hidden column). -
    x 3 * cols * phrases +
    x 3 * cols * phrases For each distinct combination of a phrase and table column, the following three values:
      -
    • In the current row, the number of times the phrase appears in +
    • In the current row, the number of times the phrase appears in the column.
    • The total number of times the phrase appears in the column in all rows in the FTS table. -
    • The total number of rows in the FTS table for which the +
    • The total number of rows in the FTS table for which the column contains at least one instance of the phrase.
    The first set of three values corresponds to the left-most column @@ -1313,7 +1288,7 @@ hits_all_rows = array[3 * (c + p*cols) + 1] docs_with_hits = array[3 * (c + p*cols) + 2] -
    ycols * phrases +
    ycols * phrases For each distinct combination of a phrase and table column, the @@ -1323,7 +1298,7 @@ 'y' flag is zero for any phrase that is part of a sub-expression that does not match the current row. This makes a difference for expressions that contain AND operators that are descendants of OR - operators. For example, consider the expression: + operators. For example, consider the expression:
               a OR (b AND c)
     
    @@ -1350,7 +1325,7 @@ For queries that use OR expressions, or those that use LIMIT or return many rows, the 'y' matchinfo option may be faster than 'x'. -
    b((cols+31)/32) * phrases +
    b((cols+31)/32) * phrases @@ -1388,20 +1363,20 @@
    a cols For each column, the average number of tokens in the text values stored in the column (considering all rows in the FTS4 table). This value is only available when querying FTS4 tables, - not FTS3. + not FTS3.
    l cols For each column, the length of the value stored in the current row of the FTS4 table, in tokens. This value is only available when querying FTS4 tables, not FTS3. And only if the "matchinfo=fts3" directive was not specified as part of the "CREATE VIRTUAL TABLE" statement used to create the FTS4 table. -
    s cols For each column, the length of the longest +
    s cols For each column, the length of the longest subsequence of phrase matches that the column value has in common with the query text. For example, if a table column contains the text 'a b c d e' and the query is 'a c "d e"', then the length of the longest common subsequence is 2 (phrase "c" followed by phrase "d e"). - - + +

    @@ -1416,7 +1391,7 @@ -- In the following query, no format string is specified and so it defaults -- to "pcx". It therefore returns a single row consisting of a single blob -- value 80 bytes in size (20 32-bit integers - 1 for "p", 1 for "c" and --- 3*2*3 for "x"). If each block of 4 bytes in the blob is interpreted +-- 3*2*3 for "x"). If each block of 4 bytes in the blob is interpreted -- as an unsigned integer in machine byte-order, the values will be: -- -- 3 2 1 3 2 0 1 1 1 2 2 0 1 1 0 0 0 1 1 1 @@ -1463,9 +1438,9 @@

    The matchinfo function provides all the information required to calculate - probabilistic "bag-of-words" relevancy scores such as + probabilistic "bag-of-words" relevancy scores such as Okapi BM25/BM25F that may - be used to order results in a full-text search application. Appendix A of this + be used to order results in a full-text search application. Appendix A of this document, "search application tips", contains an example of using the matchinfo() function efficiently. @@ -1473,8 +1448,8 @@

    5. Fts4aux - Direct Access to the Full-Text Index

    - As of version 3.7.6 (2011-04-12), - SQLite includes a new virtual table module called + As of version 3.7.6 (2011-04-12), + SQLite includes a new virtual table module called "fts4aux", which can be used to inspect the full-text index of an existing FTS table directly. Despite its name, fts4aux works just as well with FTS3 tables as it does with FTS4 tables. Fts4aux tables are read-only. The only @@ -1489,7 +1464,7 @@ database (for example, to create a TEMP fts4aux table that will access an FTS3 table in the MAIN database) use the two-argument form and give the name of the target database (ex: "main") in the first argument and the name - of the FTS3/4 table as the second argument. (The two-argument form of + of the FTS3/4 table as the second argument. (The two-argument form of fts4aux was added for SQLite version 3.7.17 (2013-05-20) and will throw an error in prior releases.) For example: @@ -1507,15 +1482,15 @@

    For each term present in the FTS table, there are between 2 and N+1 rows in the fts4aux table, where N is the number of user-defined columns in - the associated FTS table. An fts4aux table always has the same four columns, + the associated FTS table. An fts4aux table always has the same four columns, as follows, from left to right:

    -
    Column NameColumn Contents -
    term +
    term Contains the text of the term for this row. -
    col - This column may contain either the text value '*' (i.e. a single +
    col + This column may contain either the text value '*' (i.e. a single character, U+002a) or an integer between 0 and N-1, where N is again the number of user-defined columns in the corresponding FTS table. @@ -1534,7 +1509,7 @@ This column also always contains an integer value greater than zero.

    If the "col" column contains the value '*', then this column - contains the total number of instances of the term in all rows of the + contains the total number of instances of the term in all rows of the FTS table (in any column). Otherwise, if col contains an integer value, then this column contains the total number of instances of the term that appear in the FTS table column identified by the col @@ -1579,29 +1554,29 @@

    - In the example, the values in the "term" column are all lower case, + In the example, the values in the "term" column are all lower case, even though they were inserted into table "ft" in mixed case. This is because an fts4aux table contains the terms as extracted from the document text - by the tokenizer. In this case, since table "ft" uses the + by the tokenizer. In this case, since table "ft" uses the simple tokenizer, this means all terms have been folded to lower case. Also, there is (for example) no row with column "term" set to "apple" and column "col" set to 1. Since there are no instances of the term "apple" in column 1, no row is present in the fts4aux table.

    - During a transaction, some of the data written to an FTS table may be - cached in memory and written to the database only when the transaction is - committed. However the implementation of the fts4aux module is only able - to read data from the database. In practice this means that if an fts4aux - table is queried from within a transaction in which the associated - FTS table has been modified, the results of the query are likely to reflect + During a transaction, some of the data written to an FTS table may be + cached in memory and written to the database only when the transaction is + committed. However the implementation of the fts4aux module is only able + to read data from the database. In practice this means that if an fts4aux + table is queried from within a transaction in which the associated + FTS table has been modified, the results of the query are likely to reflect only a (possibly empty) subset of the changes made.

    6. FTS4 Options

    - If the "CREATE VIRTUAL TABLE" statement specifies module FTS4 (not FTS3), + If the "CREATE VIRTUAL TABLE" statement specifies module FTS4 (not FTS3), then special directives - FTS4 options - similar to the "tokenize=*" option may also appear in place of column names. An FTS4 option consists of the option name, followed by an "=" character, followed by the option value. @@ -1635,17 +1610,17 @@ each row. The use of the languageid option allows the same FTS4 table to hold text in multiple languages or scripts, each with different tokenizer rules, and to query each language independently of the others. - -

    matchinfo + +
    matchinfo When set to the value "fts3", the matchinfo option reduces the amount of information stored by FTS4 with the consequence that the "l" option of matchinfo() is no longer available. -
    notindexed +
    notindexed This option is used to specify the name of a column for which data is not indexed. Values stored in columns that are not indexed are not matched by MATCH queries. Nor are they recognized by auxiliary functions. - A single CREATE VIRTUAL TABLE statement may have any number of notindexed + A single CREATE VIRTUAL TABLE statement may have any number of notindexed options.
    order @@ -1654,14 +1629,14 @@ The "order" option may be set to either "DESC" or "ASC" (in upper or lower case). If it is set to "DESC", then FTS4 stores its data in such a way as to optimize returning results in descending order by docid. - If it is set to "ASC" (the default), then the data structures are + If it is set to "ASC" (the default), then the data structures are optimized for returning results in ascending order by docid. In other words, if many of the queries run against the FTS4 table use "ORDER BY - docid DESC", then it may improve performance to add the "order=desc" + docid DESC", then it may improve performance to add the "order=desc" option to the CREATE VIRTUAL TABLE statement.
    prefix - This option may be set to a comma-separated list of positive non-zero + This option may be set to a comma-separated list of positive non-zero integers. For each integer N in the list, a separate index is created in the database file to optimize prefix queries where the query term is N bytes in length, not including the '*' character, @@ -1676,7 +1651,7 @@

    When using FTS4, specifying a column name that contains an "=" character and is not either a "tokenize=*" specification or a recognized FTS4 option - is an error. With FTS3, the first token in the unrecognized directive is + is an error. With FTS3, the first token in the unrecognized directive is interpreted as a column name. Similarly, specifying multiple "tokenize=*" directives in a single table declaration is an error when using FTS4, whereas the second and subsequent "tokenize=*" directives are interpreted as column @@ -1709,13 +1684,13 @@ The compress and uncompress options allow FTS4 content to be stored in the database in a compressed form. Both options should be set to the name of an SQL scalar function registered using sqlite3_create_function() - that accepts a single argument. + that accepts a single argument.

    - The compress function should return a compressed version of the value - passed to it as an argument. Each time data is written to the FTS4 table, - each column value is passed to the compress function and the result value - stored in the database. The compress function may return any type of SQLite + The compress function should return a compressed version of the value + passed to it as an argument. Each time data is written to the FTS4 table, + each column value is passed to the compress function and the result value + stored in the database. The compress function may return any type of SQLite value (blob, text, real, integer or null).

    @@ -1728,7 +1703,7 @@

    If the specified compress or uncompress functions do not exist, the table may still be created. An error is not returned until the FTS4 table is - read (if the uncompress function does not exist) or written (if it is the + read (if the uncompress function does not exist) or written (if it is the compress function that does not exist).

    -- Create an FTS4 table that stores data in compressed form. This
    @@ -1757,7 +1732,7 @@
       The content option can be used in two ways:
     
     

      -
    • The indexed documents are not stored within the SQLite database +

    • The indexed documents are not stored within the SQLite database at all (a "contentless" FTS4 table), or

    • The indexed documents are stored in a database table created and @@ -1765,8 +1740,8 @@

    - Because the indexed documents themselves are usually much larger than - the full-text index, the content option can be used to achieve + Because the indexed documents themselves are usually much larger than + the full-text index, the content option can be used to achieve significant space savings.

    @@ -1820,7 +1795,7 @@ Errors related to attempting to retrieve column values other than docid are runtime errors that occur within sqlite3_step(). In some cases, for example if the MATCH expression in a SELECT query matches zero rows, there - may be no error at all even if a statement does refer to column values + may be no error at all even if a statement does refer to column values other than docid.

    @@ -1828,12 +1803,12 @@

    An "external content" FTS4 table is similar to a contentless table, except - that if evaluation of a query requires the value of a column other than - docid, FTS4 attempts to retrieve that value from a table (or view, or + that if evaluation of a query requires the value of a column other than + docid, FTS4 attempts to retrieve that value from a table (or view, or virtual table) nominated by the user (hereafter referred to as the "content table"). The FTS4 module never writes to the content table, and writing to the content table does not affect the full-text index. It is the - responsibility of the user to ensure that the content table and the + responsibility of the user to ensure that the content table and the full-text index are consistent.

    @@ -1848,7 +1823,7 @@

    - Assuming the nominated table does exist, then its columns must be the same + Assuming the nominated table does exist, then its columns must be the same as or a superset of those defined for the FTS table. The external table must also be in the same database file as the FTS table. In other words, The external table cannot be in a different database file connected using @@ -1873,7 +1848,7 @@ -- The following query returns a single row with two columns containing -- the text values "i j" and "k l". -- --- The query uses the full-text index to discover that the MATCH +-- The query uses the full-text index to discover that the MATCH -- term matches the row with docid=3. It then retrieves the values -- of columns b and c from the row with rowid=3 in the content table -- to return. @@ -1901,7 +1876,7 @@ When a row is deleted from an external content FTS4 table, FTS4 needs to retrieve the column values of the row being deleted from the content table. This is so that FTS4 can update the full-text index entries for each token - that occurs within the deleted row to indicate that row has been + that occurs within the deleted row to indicate that row has been deleted. If the content table row cannot be found, or if it contains values inconsistent with the contents of the FTS index, the results can be difficult to predict. The FTS index may be left containing entries corresponding to the @@ -1917,10 +1892,10 @@

    CREATE TABLE t1_real(id INTEGER PRIMARY KEY, a, b, c, d);
     CREATE VIRTUAL TABLE t1_fts USING fts4(content="t1_real", b, c);
     
    --- This works. When the row is removed from the FTS table, FTS retrieves
    --- the row with rowid=123 and tokenizes it in order to determine the entries
    +-- This works. When the row is removed from the FTS table, FTS retrieves 
    +-- the row with rowid=123 and tokenizes it in order to determine the entries 
     -- that must be removed from the full-text index.
    ---
    +-- 
     DELETE FROM t1_fts WHERE rowid = 123;
     DELETE FROM t1_real WHERE rowid = 123;
     
    @@ -1933,7 +1908,7 @@
     DELETE FROM t1_fts WHERE rowid = 123;
     
    -

    +

    Instead of writing separately to the full-text index and the content table, some users may wish to use database triggers to keep the full-text index up to date with respect to the set of documents stored in the content table. @@ -2028,7 +2003,7 @@ more than once for any single tokenizer object. The fact that different languages might be tokenized differently is one reason why no single FTS query can return rows with different languageid values. - + @@ -2037,14 +2012,14 @@

    6.4. The matchinfo= option

    - The matchinfo option may only be set to the value "fts3". + The matchinfo option may only be set to the value "fts3". Attempting to set matchinfo to anything other than "fts3" is an error. If this option is specified, then some of the extra information stored by FTS4 is omitted. This reduces the amount of disk space consumed by an FTS4 table until it is almost the same as the amount that would be used by the equivalent FTS3 table, but also means that the data accessed by passing the 'l' flag to the matchinfo() function is - not available. + not available. @@ -2064,7 +2039,7 @@

    - Values stored in unindexed columns are not eligible to match MATCH + Values stored in unindexed columns are not eligible to match MATCH operators. They do not influence the results of the offsets() or matchinfo() auxiliary functions. Nor will the snippet() function ever return a snippet based on a value stored in an unindexed column. @@ -2077,18 +2052,18 @@

    The FTS4 prefix option causes FTS to index term prefixes of specified lengths in the same way that it always indexes complete terms. The prefix option - must be set to a comma separated list of positive non-zero integers. - For each value N in the list, prefixes of length N bytes (when encoded + must be set to a comma separated list of positive non-zero integers. + For each value N in the list, prefixes of length N bytes (when encoded using UTF-8) are indexed. FTS4 uses term prefix indexes to speed up prefix queries. The cost, of course, is that indexing term prefixes as - well as complete terms increases the database size and slows down write + well as complete terms increases the database size and slows down write operations on the FTS4 table.

    Prefix indexes may be used to optimize prefix queries in two cases. If the query is for a prefix of N bytes, then a prefix index created with "prefix=N" provides the best optimization. Or, if no "prefix=N" - index is available, a "prefix=N+1" index may be used instead. + index is available, a "prefix=N+1" index may be used instead. Using a "prefix=N+1" index is less efficient than a "prefix=N" index, but is better than no prefix index at all. @@ -2170,7 +2145,7 @@

    The "integrity-check" command causes SQLite to read and verify the accuracy of all inverted indices in an FTS3/4 table by comparing - those inverted indices against the original content. The + those inverted indices against the original content. The "integrity-check" command silently succeeds if the inverted indices are all ok, but will fail with an SQLITE_CORRUPT error if any problems are found. @@ -2240,8 +2215,8 @@

    The "automerge=N" command (where N is an integer between 0 and 15, inclusive) is used to configure an FTS3/4 tables "automerge" parameter, - which controls automatic incremental inverted index merging. The default - automerge value for new tables is 0, meaning that automatic incremental + which controls automatic incremental inverted index merging. The default + automerge value for new tables is 0, meaning that automatic incremental merging is completely disabled. If the value of the automerge parameter is modified using the "automerge=N" command, the new parameter value is stored persistently in the database and is used by all subsequently @@ -2249,11 +2224,11 @@

    Setting the automerge parameter to a non-zero value enables automatic - incremental merging. This causes SQLite to do a small amount of inverted - index merging after every INSERT operation. The amount of merging - performed is designed so that the FTS3/4 table never reaches a point - where it has 16 segments at the same level and hence has to do a large - merge in order to complete an insert. In other words, automatic + incremental merging. This causes SQLite to do a small amount of inverted + index merging after every INSERT operation. The amount of merging + performed is designed so that the FTS3/4 table never reaches a point + where it has 16 segments at the same level and hence has to do a large + merge in order to complete an insert. In other words, automatic incremental merging is designed to prevent spiky INSERT performance.

    @@ -2261,7 +2236,7 @@ every INSERT, UPDATE, and DELETE operation on an FTS3/4 table run a little slower, since extra time must be used to do the incremental merge. For maximum performance, it is recommended that applications - disable automatic incremental merge and instead use the + disable automatic incremental merge and instead use the "merge" command in an idle process to keep the inverted indices well merged. But if the structure of an application does not easily allow for idle processes, the use of automatic incremental merge is @@ -2273,7 +2248,7 @@ merge. If the value is set to N, the system waits until there are at least N segments on a single level before beginning to incrementally merge them. Setting a lower value of N causes segments to be merged more - quickly, which may speed up full-text queries and, if the workload + quickly, which may speed up full-text queries and, if the workload contains UPDATE or DELETE operations as well as INSERTs, reduce the space on disk consumed by the full-text index. However, it also increases the amount of data written to disk. @@ -2281,13 +2256,13 @@

    For general use in cases where the workload contains few UPDATE or DELETE operations, a good choice for automerge is 8. If the workload contains - many UPDATE or DELETE commands, + many UPDATE or DELETE commands, or if query speed is a concern, it may be advantageous to reduce automerge to 2.

    For reasons of backwards compatibility, the "automerge=1" command sets - the automerge parameter to 8, not 1 (a value of 1 would make no sense + the automerge parameter to 8, not 1 (a value of 1 would make no sense anyway, as merging data from a single segment is a no-op). @@ -2295,18 +2270,18 @@

    8. Tokenizers

    - An FTS tokenizer is a set of rules for extracting terms from a document - or basic FTS full-text query. + An FTS tokenizer is a set of rules for extracting terms from a document + or basic FTS full-text query.

    - Unless a specific tokenizer is specified as part of the CREATE - VIRTUAL TABLE statement used to create the FTS table, the default + Unless a specific tokenizer is specified as part of the CREATE + VIRTUAL TABLE statement used to create the FTS table, the default tokenizer, "simple", is used. The simple tokenizer extracts tokens from - a document or basic FTS full-text query according to the following + a document or basic FTS full-text query according to the following rules:

      -
    • A term is a contiguous sequence of eligible characters, where +

    • A term is a contiguous sequence of eligible characters, where eligible characters are all alphanumeric characters and all characters with Unicode codepoint values greater than or equal to 128. All other characters are @@ -2321,15 +2296,15 @@

      For example, when a document containing the text "Right now, they're very - frustrated.", the terms extracted from the document and added to the + frustrated.", the terms extracted from the document and added to the full-text index are, in order, "right now they re very frustrated". Such - a document would match a full-text query such as "MATCH 'Frustrated'", + a document would match a full-text query such as "MATCH 'Frustrated'", as the simple tokenizer transforms the term in the query to lowercase before searching the full-text index.

      - As well as the "simple" tokenizer, the FTS source code features a tokenizer - that uses the Porter + As well as the "simple" tokenizer, the FTS source code features a tokenizer + that uses the Porter Stemming algorithm. This tokenizer uses the same rules to separate the input document into terms including folding all terms into lower case, but also uses the Porter Stemming algorithm to reduce related English language @@ -2340,10 +2315,10 @@ useful than the more intelligible output produced by the simple tokenizer. Using the porter tokenizer, the document not only matches full-text queries such as "MATCH 'Frustrated'", but also queries such as "MATCH 'Frustration'", - as the term "Frustration" is reduced by the Porter stemmer algorithm to + as the term "Frustration" is reduced by the Porter stemmer algorithm to "frustrat" - just as "Frustrated" is. So, when using the porter tokenizer, FTS is able to find not just exact matches for queried terms, but matches - against similar English language terms. For more information on the + against similar English language terms. For more information on the Porter Stemmer algorithm, please refer to the page linked above.

      @@ -2463,7 +2438,7 @@

      - The arguments passed to the "tokenchars=" or "separators=" options are + The arguments passed to the "tokenchars=" or "separators=" options are case-sensitive. In the example above, specifying that "X" is a separator character does not affect the way "x" is handled. @@ -2513,11 +2488,11 @@

      Prior to SQLite version 3.11.0 (2016-02-15), the arguments to - fts3_tokenizer() could be literal strings or BLOBs. They did not have to + fts3_tokenzer() could be literal strings or BLOBs. They did not have to be bound parameters. But that could lead to security problems in the event of an SQL injection. Hence, the legacy behavior is now disabled by default. But the old legacy behavior can be enabled, for backwards - compatibility in applications that really need it, + compatibility in applications that really need it, by calling sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER,1,0). @@ -2584,7 +2559,7 @@

      8.2. Querying Tokenizers

      The "fts3tokenize" virtual table can be used to directly access any - tokenizer. The following SQL demonstrates how to create an instance + tokenizer. The following SQL demonstrates how to create an instance of the fts3tokenize virtual table:

      CREATE VIRTUAL TABLE tok1 USING fts3tokenize('porter');
      @@ -2602,11 +2577,11 @@
       CREATE VIRTUAL TABLE text2 USING fts4(tokenize=unicode61 "tokenchars=@." "separators=123");
       CREATE VIRTUAL TABLE tokens2 USING fts3tokenize(unicode61, "tokenchars=@.", "separators=123");
       
      - +

      Once the virtual table is created, it can be queried as follows: -

      SELECT token, start, end, position
      +

      SELECT token, start, end, position 
         FROM tok1
        WHERE input='This is a test sentence.';
       
      @@ -2614,7 +2589,7 @@

      The virtual table will return one row of output for each token in the input string. The "token" column is the text of the token. The "start" and "end" columns are the byte offset to the beginning and end of the - token in the original input string. + token in the original input string. The "position" column is the sequence number of the token in the original input string. There is also an "input" column which is simply a copy of the input string that is specified in @@ -2646,16 +2621,16 @@ of whether or not there exists an FTS3 or FTS4 table that actually uses that tokenizer. - +

      9. Data Structures

      This section describes at a high-level the way the FTS module stores its - index and content in the database. It is not necessary to read or - understand the material in this section in order to use FTS in an - application. However, it may be useful to application developers attempting - to analyze and understand FTS performance characteristics, or to developers + index and content in the database. It is not necessary to read or + understand the material in this section in order to use FTS in an + application. However, it may be useful to application developers attempting + to analyze and understand FTS performance characteristics, or to developers contemplating enhancements to the existing FTS feature set.

      @@ -2674,7 +2649,7 @@ The leftmost column of the "%_content" table is an INTEGER PRIMARY KEY field named "docid". Following this is one column for each column of the FTS virtual table as declared by the user, named by prepending the column name - supplied by the user with "cN", where N is the index of the + supplied by the user with "cN", where N is the index of the column within the table, numbered from left to right starting with 0. Data types supplied as part of the virtual table declaration are not used as part of the %_content table declaration. For example: @@ -2687,7 +2662,7 @@

      - The %_content table contains the unadulterated data inserted by the user + The %_content table contains the unadulterated data inserted by the user into the FTS virtual table by the user. If the user does not explicitly supply a "docid" value when inserting records, one is selected automatically by the system. @@ -2699,7 +2674,7 @@ specified as part of the CREATE VIRTUAL TABLE statement. If they are created, the schema of the two tables is as follows:

      CREATE TABLE %_stat(
      -  id INTEGER PRIMARY KEY,
      +  id INTEGER PRIMARY KEY, 
         value BLOB
       );
       
      @@ -2715,7 +2690,7 @@
         of N FTS varints, where N is the number of user-defined columns
         in the table. Each varint in the "size" blob is the number of tokens in the
         corresponding column of the associated row in the FTS table. The %_stat table
      -  always contains a single row with the "id" column set to 0. The "value"
      +  always contains a single row with the "id" column set to 0. The "value" 
         column contains a blob consisting of N+1 FTS varints, where N
         is again the number of user-defined columns in the FTS table. The first
         varint in the blob is set to the total number of rows in the FTS table. The
      @@ -2723,9 +2698,9 @@
         the corresponding column for all rows of the FTS table.
       
       

      - The two remaining tables, %_segments and %_segdir, are used to store the - full-text index. Conceptually, this index is a lookup table that maps each - term (word) to the set of docid values corresponding to records in the + The two remaining tables, %_segments and %_segdir, are used to store the + full-text index. Conceptually, this index is a lookup table that maps each + term (word) to the set of docid values corresponding to records in the %_content table that contain one or more occurrences of the term. To retrieve all documents that contain a specified term, the FTS module queries this index to determine the set of docid values for records that @@ -2750,7 +2725,7 @@

      - The schema depicted above is not designed to store the full-text index + The schema depicted above is not designed to store the full-text index directly. Instead, it is used to store one or more b-tree structures. There is one b-tree for each row in the %_segdir table. The %_segdir table row contains the root node and various meta-data associated with the @@ -2782,12 +2757,12 @@ contents of all segment b-trees. If a term is present in more than one segment b-tree, then it maps to the union of each individual doclist. If, for a single term, the same docid occurs in more than one doclist, then only - the doclist that is part of the most recently created segment b-tree is - considered valid. + the doclist that is part of the most recently created segment b-tree is + considered valid.

      Multiple b-tree structures are used instead of a single b-tree to reduce - the cost of inserting records into FTS tables. When a new record is + the cost of inserting records into FTS tables. When a new record is inserted into an FTS table that already contains a lot of data, it is likely that many of the terms in the new record are already present in a large number of existing records. If a single b-tree were used, then @@ -2801,13 +2776,13 @@ (as the FTS code may have to look up individual terms in more than one b-tree and merge the results), but it has been found that in practice this overhead is often negligible. - +

      9.2. Variable Length Integer (varint) Format

      Integer values stored as part of segment b-tree nodes are encoded using the FTS varint format. This encoding is similar, but not identical, to - the SQLite varint format. + the SQLite varint format.

      An encoded FTS varint consumes between one and ten bytes of space. The @@ -2820,7 +2795,7 @@ stored using less space.

      - The final byte of an encoded FTS varint has its most significant bit + The final byte of an encoded FTS varint has its most significant bit cleared. All preceding bytes have the most significant bit set. Data is stored in the remaining seven least significant bits of each byte. The first byte of the encoded representation contains the least significant @@ -2831,11 +2806,11 @@

      DecimalHexadecimalEncoded Representation -
      430x000000000000002B0x2B -
      2008150x000000000003106F0xEF 0xA0 0x0C +
      430x000000000000002B0x2B +
      2008150x000000000003106F0x9C 0xA0 0x0C
      -10xFFFFFFFFFFFFFFFF0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0xFF 0x01
      - +

      9.3. Segment B-Tree Format

      @@ -2843,14 +2818,14 @@ Segment b-trees are prefix-compressed b+-trees. There is one segment b-tree for each row in the %_segdir table (see above). The root node of the segment b-tree is stored as a blob in the "root" field of the corresponding row - of the %_segdir table. All other nodes (if any exist) are stored in the + of the %_segdir table. All other nodes (if any exist) are stored in the "blob" column of the %_segments table. Nodes within the %_segments table are identified by the integer value in the blockid field of the corresponding row. The following table describes the fields of the %_segdir table:

      -
      Column Interpretation -
      level +
      level Between them, the contents of the "level" and "idx" fields define the relative age of the segment b-tree. The smaller the value stored in the "level" field, the more recently the segment b-tree was created. If two @@ -2860,11 +2835,11 @@ for both the "level" and "idx" fields.
      idx See above.
      start_block - The blockid that corresponds to the node with the smallest blockid that + The blockid that corresponds to the node with the smallest blockid that belongs to this segment b-tree. Or zero if the entire segment b-tree fits on the root node. If it exists, this node is always a leaf node.
      leaves_end_block - The blockid that corresponds to the leaf node with the largest blockid + The blockid that corresponds to the leaf node with the largest blockid that belongs to this segment b-tree. Or zero if the entire segment b-tree fits on the root node.
      end_block @@ -2894,8 +2869,8 @@ value stored in the "start_block" column of the corresponding %_segdir row, and finishing at the blockid value stored in the "leaves_end_block" field of the same row. It is therefore possible to iterate through all the - leaves of a segment b-tree, in key order, by traversing the %_segments - table in blockid order from "start_block" to "leaves_end_block". + leaves of a segment b-tree, in key order, by traversing the %_segments + table in blockid order from "start_block" to "leaves_end_block".

      9.3.1. Segment B-Tree Leaf Nodes

      @@ -2916,7 +2891,7 @@

      9.3.2. Segment B-Tree Interior Nodes

      - The following diagram depicts the format of a segment b-tree interior + The following diagram depicts the format of a segment b-tree interior (non-leaf) node.

      @@ -2929,13 +2904,13 @@

      A doclist consists of an array of 64-bit signed integers, serialized using - the FTS varint format. Each doclist entry is made up of a series of two + the FTS varint format. Each doclist entry is made up of a series of two or more integers, as follows:

      1. The docid value. The first entry in a doclist contains the literal docid - value. The first field of each subsequent doclist entry contains the - difference between the new docid and the previous one (always a positive + value. The first field of each subsequent doclist entry contains the + difference between the new docid and the previous one (always a positive number).
      2. Zero or more term-offset lists. A term-offset list is present for each column of the FTS virtual table that contains the term. A term-offset @@ -2946,8 +2921,8 @@
      3. The column number (1 for the second leftmost column, etc.). This field is omitted for any term-offset list associated with column 0.
      4. A list of term-offsets, sorted from smallest to largest. Instead - of storing the term-offset value literally, each integer stored - is the difference between the current term-offset and the previous + of storing the term-offset value literally, each integer stored + is the difference between the current term-offset and the previous one (or zero if the current term-offset is the first), plus 2.
    • Constant value 0. @@ -2965,8 +2940,8 @@

      For doclists for which the term appears in more than one column of the FTS - virtual table, term-offset lists within the doclist are stored in column - number order. This ensures that the term-offset list associated with + virtual table, term-offset lists within the doclist are stored in column + number order. This ensures that the term-offset list associated with column 0 (if any) is always first, allowing the first two fields of the term-offset list to be omitted in this case. @@ -2976,7 +2951,7 @@

      10.1. UTF-16 byte-order-mark problem

      For UTF-16 databases, when using the "simple" tokenizer, it is possible to use -malformed unicode strings to cause the +malformed unicode strings to cause the integrity-check special command to falsely report corruption, or for auxiliary functions to return incorrect results. More specifically, the bug can be triggered by any of the following: @@ -2989,13 +2964,13 @@
    • Malformed UTF-8 that SQLite converts to a UTF-16 byte-order-mark is - embedded at the beginning of an SQL string literal value inserted + embedded at the beginning of an SQL string literal value inserted into an FTS3 table.

    • A text value created by casting a blob that begins with the two bytes 0xFF and 0xFE, in either possible order, is inserted into an FTS3 table. For example: - +

      INSERT INTO fts_table(col) VALUES(CAST(X'FEFF' AS TEXT));
       
    • @@ -3025,22 +3000,22 @@

      FTS is primarily designed to support Boolean full-text queries - queries - to find the set of documents that match a specified criteria. However, many + to find the set of documents that match a specified criteria. However, many (most?) search applications require that results are somehow ranked in order of "relevance", where "relevance" is defined as the likelihood that the user who performed the search is interested in a specific element of the returned set of documents. When using a search engine to find documents on the world - wide web, the user expects that the most useful, or "relevant", documents - will be returned as the first page of results, and that each subsequent page - contains progressively less relevant results. Exactly how a machine can + wide web, the user expects that the most useful, or "relevant", documents + will be returned as the first page of results, and that each subsequent page + contains progressively less relevant results. Exactly how a machine can determine document relevance based on a users query is a complicated problem and the subject of much ongoing research.

      - One very simple scheme might be to count the number of instances of the + One very simple scheme might be to count the number of instances of the users search terms in each result document. Those documents that contain many instances of the terms are considered more relevant than those with - a small number of instances of each term. In an FTS application, the + a small number of instances of each term. In an FTS application, the number of term instances in each result could be determined by counting the number of integers in the return value of the offsets function. The following example shows a query that could be used to obtain the @@ -3054,7 +3029,7 @@ -- the following query could be used to return the titles of the 10 documents that contain -- the greatest number of instances of the users query terms. Hopefully, these 10 -- documents will be those that the users considers more or less the most "relevant". -SELECT title FROM documents +SELECT title FROM documents WHERE documents MATCH <query> ORDER BY countintegers(offsets(documents)) DESC LIMIT 10 OFFSET 0 @@ -3063,19 +3038,19 @@

      The query above could be made to run faster by using the FTS matchinfo function to determine the number of query term instances that appear in each - result. The matchinfo function is much more efficient than the offsets + result. The matchinfo function is much more efficient than the offsets function. Furthermore, the matchinfo function provides extra information regarding the overall number of occurrences of each query term in the entire - document set (not just the current row) and the number of documents in which + document set (not just the current row) and the number of documents in which each query term appears. This may be used (for example) to attach a higher - weight to less common terms which may increase the overall computed relevancy + weight to less common terms which may increase the overall computed relevancy of those results the user considers more interesting.

      -- If the application supplies an SQLite user function called "rank" that
       -- interprets the blob of data returned by matchinfo and returns a numeric
       -- relevancy based on it, then the following SQL may be used to return the
       -- titles of the 10 most relevant documents in the dataset for a users query.
      -SELECT title FROM documents
      +SELECT title FROM documents 
         WHERE documents MATCH <query>
         ORDER BY rank(matchinfo(documents)) DESC
         LIMIT 10 OFFSET 0
      @@ -3092,11 +3067,11 @@
         which may be quite large). This means that if the users query matches
         several thousand documents, many megabytes of "title" and "content" data
         may be loaded from disk into memory even though they will never be used
      -  for any purpose.
      +  for any purpose. 
       
       

      - The SQL query in the following example block is one solution to this - problem. In SQLite, when a sub-query + The SQL query in the following example block is one solution to this + problem. In SQLite, when a sub-query used in a join contains a LIMIT clause, the results of the sub-query are calculated and stored in temporary table before the main query is executed. This means that SQLite will load only the docid and matchinfo data for each @@ -3106,11 +3081,11 @@ and docid values are gleaned entirely from the full-text index, this results in dramatically less data being loaded from the database into memory. -

      SELECT title FROM documents JOIN (
      -    SELECT docid, rank(matchinfo(documents)) AS rank
      +

      SELECT title FROM documents JOIN ( 
      +    SELECT docid, rank(matchinfo(documents)) AS rank 
           FROM documents
           WHERE documents MATCH <query>
      -    ORDER BY rank DESC
      +    ORDER BY rank DESC 
           LIMIT 10 OFFSET 0
       ) AS ranktable USING(docid)
       ORDER BY ranktable.rank DESC
      @@ -3123,7 +3098,7 @@
       

      1. The snippet function cannot be used with the above query. Because - the outer query does not include a "WHERE ... MATCH" clause, the snippet + the outer query does not include a "WHERE ... MATCH" clause, the snippet function may not be used with it. One solution is to duplicate the WHERE clause used by the sub-query in the outer query. The overhead associated with this is usually negligible. @@ -3138,8 +3113,8 @@

      - This version of the query is very similar to that used by the - sqlite.org documentation search + This version of the query is very similar to that used by the + sqlite.org documentation search application.

      -- This table stores the static weight assigned to each document in FTS table
      @@ -3156,11 +3131,11 @@
       --   2. The sub-query joins the documents table with the document_data table, so that
       --      implementation of the rank function has access to the static weight assigned
       --      to each document.
      -SELECT title, snippet(documents) FROM documents JOIN (
      +SELECT title, snippet(documents) FROM documents JOIN ( 
           SELECT docid, rank(matchinfo(documents), documents_data.weight) AS rank
           FROM documents JOIN documents_data USING(docid)
           WHERE documents MATCH <query>
      -    ORDER BY rank DESC
      +    ORDER BY rank DESC 
           LIMIT 10 OFFSET 0
       ) AS ranktable USING(docid)
       WHERE documents MATCH <query>
      @@ -3169,18 +3144,18 @@
       
       

      All the example queries above return the ten most relevant query results. - By modifying the values used with the OFFSET and LIMIT clauses, a query - to return (say) the next ten most relevant results is easy to construct. + By modifying the values used with the OFFSET and LIMIT clauses, a query + to return (say) the next ten most relevant results is easy to construct. This may be used to obtain the data required for a search applications second and subsequent pages of results.

      - The next block contains an example rank function that uses matchinfo data - implemented in C. Instead of a single weight, it allows a weight to be + The next block contains an example rank function that uses matchinfo data + implemented in C. Instead of a single weight, it allows a weight to be externally assigned to each column of each document. It may be registered with SQLite like any other user function using sqlite3_create_function. -

      Security Warning: Because it is just an ordinary SQL function, +

      Security Warning: Because it is just an ordinary SQL function, rank() may be invoked as part of any SQL query in any context. This means that the first argument passed may not be a valid matchinfo blob. Implementors should take care to handle this case without causing buffer @@ -3283,5 +3258,4 @@ sqlite3_result_error(pCtx, "wrong number of arguments to function rank()", -1); }

      -

      This page last modified on 2023-02-27 02:07:35 UTC

      - + diff -Nru sqlite3-3.42.0/www/fts5.html sqlite3-3.44.0-0/www/fts5.html --- sqlite3-3.42.0/www/fts5.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/fts5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      +
      @@ -147,7 +123,7 @@ ROLLBACK TO
    • Subqueries, including correlated subqueries
    • Up to 64-way joins -
    • LEFT, RIGHT, and FULL OUTER JOINs +
    • LEFT JOIN
    • DISTINCT, ORDER BY, GROUP BY, HAVING, LIMIT, and OFFSET
    • UNION, UNION ALL, INTERSECT, and EXCEPT
    • A rich library of standard SQL functions @@ -183,5 +159,4 @@ There are many more features not listed above. SQLite may be small in size and have "Lite" in its name, but it is not lacking in capability. -

      This page last modified on 2022-05-10 17:29:14 UTC

      - +

      diff -Nru sqlite3-3.42.0/www/gencol.html sqlite3-3.44.0-0/www/gencol.html --- sqlite3-3.42.0/www/gencol.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/gencol.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    • @@ -157,7 +133,7 @@ are columns of a table whose values are a function of other columns in the same row. Generated columns can be read, but their values can not be directly -written. The only way to change the value of a generated column is to +written. The only way to change the value of a generated columns is to modify the values of the other columns used to calculate the generated column. @@ -233,7 +209,7 @@

    • Generated columns can occur anywhere in the table definition. Generated -columns can be interspersed among ordinary columns. It is not necessary +columns can be interspersed among ordinary columns. It not necessary to put generated columns at the end of the list of columns in the table definition, as is shown in the examples above.

    • @@ -278,11 +254,6 @@ only by the datatype and COLLATE clause on the column definition. The datatype and collating sequence of the GENERATED ALWAYS AS expression have no affect on the datatype and collating sequence of the column itself. - -

    • -Generated columns are not included in the list of columns provided by -the PRAGMA table_info statement. But they are included in the output of -the newer PRAGMA table_xinfo statement.

    • 3. Compatibility

      @@ -304,5 +275,4 @@ generated columns, using SQLite version 3.31.0 or later, and then try to read or write that database file using an earlier version of SQLite that does not understand generated columns. -

      This page last modified on 2022-11-09 20:11:26 UTC

      - +

      diff -Nru sqlite3-3.42.0/www/geopoly.html sqlite3-3.44.0-0/www/geopoly.html --- sqlite3-3.42.0/www/geopoly.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/geopoly.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -179,11 +155,9 @@ similar operations.

      -The source code for Geopoly is included in the amalgamation. However, -depending on configuration options and the a particular version of SQLite -you are using, the Geopoly extension may or may not be enabled by default. -To ensure that Geopoly is enabled for your build, -add the -DSQLITE_ENABLE_GEOPOLY=1 compile-time option. +The source code for Geopoly is included in the amalgamation but is not +included in the library unless the -DSQLITE_ENABLE_GEOPOLY compile-time option +is used.

      Geopoly operates on "simple" polygons - that is, polygons for which @@ -471,7 +445,18 @@ As an example, the following graphic:

      - + + 3 + 4 + 5 + 6 + 7 + 8 + 10 + 12 + 16 + 20 +

      Was generated by this script: @@ -566,5 +551,4 @@ The underlying R-Tree implementation uses bounding boxes to limit the search space. Then the geoploy_overlap() and/or geopoly_within() routines further refine the search to the exact answer. -

      This page last modified on 2023-02-20 00:00:42 UTC

      - +

      diff -Nru sqlite3-3.42.0/www/getthecode.html sqlite3-3.44.0-0/www/getthecode.html --- sqlite3-3.42.0/www/getthecode.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/getthecode.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -149,7 +125,7 @@

      3. Obtaining Code Directly From the Version Control System

      For any historical version of SQLite, the source tree can be obtained -from the Fossil version control system, +from the Fossil version control system, either downloading a tarball or ZIP archive for a specific version, or by cloning the entire project history. @@ -157,28 +133,28 @@ servers:

      -https://www.sqlite.org/src (Dallas)
      -https://www2.sqlite.org/src (Newark)
      -https://www3.sqlite.org/src (San Francisco)
      +https://www.sqlite.org/cgi/src (Dallas)
      +https://www2.sqlite.org/cgi/src (Newark)
      +https://www3.sqlite.org/cgi/src (San Francisco)

      The documentation is maintained in separate source repositories on those same servers:

      -https://www.sqlite.org/docsrc (Dallas)
      -https://www2.sqlite.org/docsrc (Newark)
      -https://www3.sqlite.org/docsrc (San Francisco)
      +https://www.sqlite.org/cgi/docsrc (Dallas)
      +https://www2.sqlite.org/cgi/docsrc (Newark)
      +https://www3.sqlite.org/cgi/docsrc (San Francisco)

      To download a specific historical version, first locate the specific version desired by visiting the timeline page on one of these servers -(for example: https://www.sqlite.org/src/timeline). If +(for example: http://www.sqlite.org/cgi/src/timeline). If you know the approximate date of the version you want to download, you can add a query parameter like "c=YYYY-MM-DD" to the "timeline" URL to see a timeline centered on that date. For example, to see all the check-ins that occurred around August 26, 2013, visit -https://www.sqlite.org/src/timeline?c=2013-08-26. +http://www.sqlite.org/cgi/src/timeline?c=2013-08-26. If you are looking for an official release, visit the chronology page, click on the date to the left of the release you are looking for, and that will take you immediately to the @@ -194,7 +170,7 @@

      4. Cloning The Complete Development History

      To clone the entire history of SQLite, first go to the -https://www.fossil-scm.org/download.html page and grab a precompiled binary +http://www.fossil-scm.org/download.html page and grab a precompiled binary for the Fossil version control program. Or get the source code on the same page and compile it yourself. @@ -211,7 +187,7 @@ executable someplace on your $PATH or %PATH%. After you have Fossil installed, do this: -

      fossil clone https://www.sqlite.org/src sqlite.fossil
      +

      fossil clone http://www.sqlite.org/cgi/src sqlite.fossil
       

      The command above @@ -235,7 +211,6 @@ prefix of a SHA1 hash for a specific check-in, or VERSION can be a tag such as "version-3.8.8". Every time you run "fossil update" it will automatically reach out to the original repository at -https://www.sqlite.org/src to obtain new check-ins that might have been +http://www.sqlite.org/cgi/src to obtain new check-ins that might have been made by others since your previous update. -

      This page last modified on 2022-04-18 02:55:50 UTC

      - +

      diff -Nru sqlite3-3.42.0/www/hirely.html sqlite3-3.44.0-0/www/hirely.html --- sqlite3-3.42.0/www/hirely.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/hirely.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -169,5 +145,4 @@

      All of these factors combine to make SQLite a very trouble-free software library. -

      This page last modified on 2022-01-08 05:02:57 UTC

      - +

      diff -Nru sqlite3-3.42.0/www/howitworks.html sqlite3-3.44.0-0/www/howitworks.html --- sqlite3-3.42.0/www/howitworks.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/howitworks.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -307,7 +283,7 @@

      Of course, not every language fits neatly into one of the -above categories. This applies to both SQL database engines +above catagories. This applies to both SQL database engines and more familiar imperative programming languages. Javascript is famous for using a hybrid execution model, where the code is initially compiled into a tree of objects, but might be @@ -340,7 +316,7 @@ Whitespace and comment tokens are discarded. All other tokens are fed into an LALR(1) Parser -that analyzes the structure of the input program and generates an +that analysis the structure of the input program and generates an Abstract Syntax Tree (AST) for the input program. @@ -384,4 +360,3 @@ individual SQL statement.

      - diff -Nru sqlite3-3.42.0/www/howtocompile.html sqlite3-3.44.0-0/www/howtocompile.html --- sqlite3-3.42.0/www/howtocompile.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/howtocompile.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -151,7 +127,7 @@ -

      Overview

      +

      Overview

      SQLite is ANSI-C source code. @@ -162,19 +138,19 @@

      This article does not contain a step-by-step recipe for compiling SQLite. That would be difficult since each development situation is different. -Rather, this article describes and illustrates the principles behind the +Rather, this article describes and illustrates the principals behind the compilation of SQLite. Typical compilation commands are provided as examples with the expectation that application developers can use these examples as guidance for developing their own custom compilation procedures. In other words, this article provides ideas and insights, not turnkey solutions.

      -

      1. Amalgamation Versus Individual Source Files

      +

      1. Amalgamation Versus Individual Source Files

      SQLite is built from over one hundred files of C code and script spread across multiple directories. The implementation of SQLite is pure ANSI-C, but many of the C-language source code files are either -generated or transformed by auxiliary C programs and AWK, SED, and TCL +generated or transformed by auxiliary C programs and AWK, SED, and TCL scripts prior to being incorporated into the finished SQLite library. Building the necessary C programs and transforming and/or creating the C-language source code for SQLite is a complex process.

      @@ -188,8 +164,8 @@ steps have already been carried out so there are no auxiliary C programs to configure and compile and no scripts to run. And, because the entire library is contained in a single translation unit, compilers are able to -do more advanced optimizations resulting in a 5% to 10% performance -improvement. For these reasons, the amalgamation source file +do more advanced optimizations resulting in a 5% to 10% performance +improvement. For these reasons, the amalgamation source file ("sqlite3.c") is recommended for all applications.

      @@ -202,7 +178,7 @@ using just the prebuilt amalgamation source file downloaded from the website. For those situations, it is recommended that a customized amalgamation be built (as described below) -and used. In other words, even if a project requires building SQLite +and used. In other words, even if a project requires building SQLite beginning with individual source files, it is still recommended that an amalgamation source file be used as an intermediate step.

      @@ -215,7 +191,7 @@
      • sqlite3.c: The SQLite amalgamation source file -
      • sqlite3.h: The header files that accompanies sqlite3.c and +
      • sqlite3.h: The header files that accompanies sqlite3.c and defines the C-language interfaces to SQLite.
      • shell.c: The command-line interface program itself. This is the C source code file that contains the definition of @@ -233,11 +209,11 @@ cl shell.c sqlite3.c -Fesqlite3.exe
      -

      On Unix systems (or on Windows using cygwin or mingw+msys) +

      On unix systems (or on Windows using cygwin or mingw+msys) the command typically looks something like this:

      -gcc shell.c sqlite3.c -lpthread -ldl -lm -o sqlite3
      +gcc shell.c sqlite3.c -lpthread -ldl -lm
       

      The pthreads library is needed to make SQLite threadsafe. But @@ -245,7 +221,7 @@ in a non-threadsafe mode and thereby omit the pthreads library:

      -gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl -lm -o sqlite3
      +gcc -DSQLITE_THREADSAFE=0 shell.c sqlite3.c -ldl -lm
       

      The -ldl library is needed to support dynamic loading, the @@ -255,36 +231,34 @@ option:

      -gcc -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c -o sqlite3
      +gcc -DSQLITE_THREADSAFE=0 -DSQLITE_OMIT_LOAD_EXTENSION shell.c sqlite3.c
       
      -

      One might want to provide other compile-time options such as

      - - - -

      In order to see extra commentary in EXPLAIN listings, add the --DSQLITE_ENABLE_EXPLAIN_COMMENTS option. Add -DHAVE_READLINE and -the -lreadline and -lncurses libraries to get command-line editing -support. One might also want to specify some compiler optimization -switches. (The precompiled CLI available for download from the SQLite -website uses "-Os".) There are countless possible variations here. A -command to compile a full-featured shell might look something like -this:

      +

      One might want to provide other compile-time options such as +-DSQLITE_ENABLE_FTS4 or -DSQLITE_ENABLE_FTS5 for full-text search, +-DSQLITE_ENABLE_RTREE for the R*Tree search engine extension, +-DSQLITE_ENABLE_JSON1 to include JSON SQL functions, or +-DSQLITE_ENABLE_DBSTAT_VTAB for the dbstat virtual table. +In order to see extra commentary in EXPLAIN listings, add the +-DSQLITE_ENABLE_EXPLAIN_COMMENTS option. +On unix systems, add -DHAVE_USLEEP=1 if the host machine supports the +usleep() system call. Add -DHAVE_READLINE and the -lreadline +and -lncurses libraries to get command-line editing support. +One might also want to +specify some compiler optimization switches. (The precompiled +CLI available for download from the SQLite website uses "-Os".) +There are countless possible variations here. A command to +compile a full-featured shell might look something like this:

       gcc -Os -I. -DSQLITE_THREADSAFE=0 -DSQLITE_ENABLE_FTS4 \
          -DSQLITE_ENABLE_FTS5 -DSQLITE_ENABLE_JSON1 \
          -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_EXPLAIN_COMMENTS \
      -   -DHAVE_READLINE \
      +   -DHAVE_USLEEP -DHAVE_READLINE \
          shell.c sqlite3.c -ldl -lm -lreadline -lncurses -o sqlite3
       
      -

      The key point is this: Building the CLI consists of compiling +

      The key point is this: Building the CLI consists of compiling together two C-language files. The shell.c file contains the definition of the entry point and the user input loop and the SQLite amalgamation sqlite3.c contains the complete implementation @@ -298,9 +272,9 @@ the regular amalgamation. The result is a new amalgamated source file called "tclsqlite3.c". This single source file is all that is needed to generate a shared library that can be loaded into a -standard -tclsh or -wish using the +standard +tclsh or +wish using the TCL load command, or to generate a standalone tclsh that comes with SQLite built in. A copy of the tcl amalgamation @@ -343,7 +317,7 @@ the SQLite amalgamation contains a lot of C-code that is generated by auxiliary programs and scripts. Many of the compile-time options effect this generated code and must be supplied to the code -generators before the amalgamation is assembled. The set of +generators before the amalgamation is assembled. The set of compile-time options that must be passed into the code generators can vary from one release of SQLite to the next, but at the time of this writing (circa SQLite 3.6.20, 2009-11-04) the set of options that must @@ -370,7 +344,7 @@

      To build a custom amalgamation, first download the original individual -source files onto a Unix or Unix-like development platform. +source files onto a unix or unix-like development platform. Be sure to get the original source files not the "preprocessed source files". One can obtain the complete set of original source files either from the download page or directly @@ -406,7 +380,7 @@

      5. Building A Windows DLL

      To build a DLL of SQLite for use in Windows, first acquire the -appropriate amalgamated source code files, sqlite3.c and sqlite3.h. +appropriate amalgamated source code files, sqlite3.c and sqlite3.h. These can either be downloaded from the SQLite website or custom generated from sources as shown above.

      @@ -443,7 +417,7 @@ compile-time options include:

        -
      • -Os - Optimize for size. +

      • -Os - Optimize for size. Make the DLL as small as possible.

      • -O2 - Optimize for speed. This will make the DLL larger by @@ -458,5 +432,4 @@ This enables some extra APIs that are required by some common systems, including Ruby-on-Rails.

      -

      This page last modified on 2023-03-06 12:28:27 UTC

      diff -Nru sqlite3-3.42.0/www/howtocorrupt.html sqlite3-3.44.0-0/www/howtocorrupt.html --- sqlite3-3.42.0/www/howtocorrupt.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/howtocorrupt.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      +
      Note: The hyperlinks on the download page only work if you have Javascript enabled in your web browser. -

      This page last modified on 2022-01-08 05:02:57 UTC

      Binary files /tmp/tmpzdm9j_aj/x_36KoQHlP/sqlite3-3.42.0/www/images/foreignlogos/bloomberg.png and /tmp/tmpzdm9j_aj/4OSJ1hZg2o/sqlite3-3.44.0-0/www/images/foreignlogos/bloomberg.png differ Binary files /tmp/tmpzdm9j_aj/x_36KoQHlP/sqlite3-3.42.0/www/images/foreignlogos/expensify.png and /tmp/tmpzdm9j_aj/4OSJ1hZg2o/sqlite3-3.44.0-0/www/images/foreignlogos/expensify.png differ Binary files /tmp/tmpzdm9j_aj/x_36KoQHlP/sqlite3-3.42.0/www/images/foreignlogos/flame.gif and /tmp/tmpzdm9j_aj/4OSJ1hZg2o/sqlite3-3.44.0-0/www/images/foreignlogos/flame.gif differ Binary files /tmp/tmpzdm9j_aj/x_36KoQHlP/sqlite3-3.42.0/www/images/sschart20221116.jpg and /tmp/tmpzdm9j_aj/4OSJ1hZg2o/sqlite3-3.44.0-0/www/images/sschart20221116.jpg differ diff -Nru sqlite3-3.42.0/www/imposter.html sqlite3-3.44.0-0/www/imposter.html --- sqlite3-3.42.0/www/imposter.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/imposter.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -347,5 +323,4 @@ use imposter tables in an application. Imposter tables are intended for use in the laboratory by experts.

      -

      This page last modified on 2022-01-08 05:02:57 UTC

      diff -Nru sqlite3-3.42.0/www/index.html sqlite3-3.44.0-0/www/index.html --- sqlite3-3.42.0/www/index.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/index.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,10 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      + + @@ -175,7 +151,7 @@

      In-memory databases are allowed to use shared cache if they are opened using a URI filename. If the unadorned ":memory:" name is used to specify the in-memory database, then that database always has a private -cache and is only visible to the database connection that originally +cache and is this only visible to the database connection that originally opened it. However, the same in-memory database can be opened by two or more database connections as follows: @@ -230,23 +206,22 @@ ATTACH DATABASE '' AS aux2; -

      A different temporary file is created each time so that, just as +

      A different temporary file is created each time, so that just like as with the special ":memory:" string, two database connections to temporary databases each have their own private database. Temporary databases are automatically deleted when the connection that created them closes.

      Even though a disk file is allocated for each temporary database, in -practice the temporary database usually resides in the in-memory pager cache -and hence there is very little difference between a pure in-memory database +practice the temporary database usually resides in the in-memory pager +cache and hence is very little difference between a pure in-memory database created by ":memory:" and a temporary database created by an empty filename. The sole difference is that a ":memory:" database must remain in memory -at all times whereas parts of a temporary database might be flushed to disk -if the database becomes large or if SQLite comes under memory pressure.

      +at all times whereas parts of a temporary database might be flushed to +disk if database becomes large or if SQLite comes under memory pressure.

      The previous paragraphs describe the behavior of temporary databases under the default SQLite configuration. An application can use the temp_store pragma and the SQLITE_TEMP_STORE compile-time parameter to force temporary databases to behave as pure in-memory databases, if desired.

      -

      This page last modified on 2022-04-18 02:55:50 UTC

      diff -Nru sqlite3-3.42.0/www/intern-v-extern-blob.html sqlite3-3.44.0-0/www/intern-v-extern-blob.html --- sqlite3-3.42.0/www/intern-v-extern-blob.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/intern-v-extern-blob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -133,7 +109,7 @@ To try to answer this, we ran 49 test cases with various BLOB sizes and SQLite page sizes on a Linux workstation (Ubuntu circa 2011 with the Ext4 filesystem on a fast SATA disk). -For each test case, a database was created containing 100MB of BLOB +For each test case, a database was created that contains 100MB of BLOB content. The sizes of the BLOBs ranged from 10KB to 1MB. The number of BLOBs varied in order to keep the total BLOB content at about 100MB. (Hence, 100 BLOBs for the 1MB size and 10000 BLOBs for the 10K size and @@ -208,5 +184,4 @@

      Of course, your mileage may vary depending on hardware, filesystem, and operating system. Double-check these figures on target hardware before committing to a particular design. -

      This page last modified on 2022-04-18 02:55:50 UTC

      diff -Nru sqlite3-3.42.0/www/invalidutf.html sqlite3-3.44.0-0/www/invalidutf.html --- sqlite3-3.42.0/www/invalidutf.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/invalidutf.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,230 +0,0 @@ - - - - - -Invalid UTF Policy - - - -
      - - - -
      -
      -Small. Fast. Reliable.
      Choose any three. -
      - - -
      -
      - - - -
      -
      -
      - -
      -
      -
      -Invalid UTF Policy -
      -
      - - - - - -

      1. Garbage In, Garbage Out

      - -

      -With regard to invalid UTF, SQLite follows a policy of -Garbage-In, Garbage-Out (GIGO). If you insert invalid UTF -into an SQLite database, then try to query that data, what you get back out -might not be exactly what you put in. If you put garbage in, then you -may not complain if you get different garbage back out. - -

      -For the purposes of this discussion, "invalid UTF" can mean any of -the following circumstances: - -

        -
      • -Invalid surrogate pairs in UTF-16. - -

      • -Invalid multi-byte sequences in UTF-8. - -

      • -Using more bytes of UTF-8 than necessary to represent a single -code point. (Example: encoding 'A' as the two-byte sequence -0xc1, 0x01 instead of just a single 0x41 byte.) - -

      • -NUL characters (U+0000) embedded in strings. - -

      • -Invalid sequences of combining characters. - -

      • -UTF-8 or UTF-16 bytes sequences that encode numbers that are not -defined Unicode characters. - -

      - -

      1.1. Invalid UTF will never cause memory errors

      - -

      -If you insert invalid UTF into an SQLite database, then SQLite makes -no guarantees about what text you might get back out. But it does -promise that invalid UTF will never cause memory errors -(array overruns, reads or writes of uninitialized memory, etc), at -least for the built-in processing of SQLite. -In other words, invalid UTF will not cause SQLite to crash. - -

      -This promise only applies to the core SQLite components, not -application-provided extensions, of course. -If an application adds new application-defined SQL functions or -virtual tables or collating sequences or other extensions, and a -database contains invalid UTF, then invalid UTF might get passed -into those extensions. If the invalid UTF causes one of those -extensions to crash, then that is a problem with the extension, -not with SQLite. - -

      2. No enforcement of text formatting rules

      - -

      -SQLite does not try to enforce UTF formatting rules. You can -insert invalid UTF into a TEXT field and SQLite will not complain -about this. It stores the invalid TEXT as best it can. SQLite -sees its role in the world as a storage engine, not a text format -validation engine. - -

      3. Best effort to preserve text

      - -

      -SQLite does not promise to always preserve invalid UTF, but it does -make an effort. Generally speaking, if you insert invalid UTF into -SQLite, you will get the exact same byte sequence back out, as long -as you do not ask SQLite to transform the text in any way. - -

      -For example, if you insert some UTF-16LE with invalid surrogates into -a TEXT column of a table of a database that has PRAGMA encoding=UTF16LE, -then later query that column using sqlite3_column_text16(), you will -probably get back the same exact invalid UTF-16. But if you insert the -same invalid UTF-16LE content in a PRAGMA encoding=UTF8 database, -the content must be converted into UTF8 when it is stored, which could -cause irreversible changes to the content. Or if you insert that -same invalid UTF-16LE content into a PRAGMA encoding=UTF16LE database -but then read it out using sqlite3_column_text(), then a UTF16 to -UTF8 conversion must occur during the read-out and that conversion might -introduce irreversible changes. - -

      -Or, suppose you are doing everything using UTF-8 (the most common case). -Invalid UTF-8 will normally pass through the database without any change -in its byte sequence. However, if you try to transform the invalid -UTF-8 with SQL function like substr() or replace() -or if you try to do string matching with the LIKE operator, then -you might get unexpected results. - -

      -So, in other words, SQLite does not actively try to subvert your -invalid text. But when you ask SQLite to make transformations of invalid -UTF, there are no guarantees that those transformations will be reversible -or even sensible. -

      This page last modified on 2022-04-18 02:55:50 UTC

      - diff -Nru sqlite3-3.42.0/www/isolation.html sqlite3-3.44.0-0/www/isolation.html --- sqlite3-3.42.0/www/isolation.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/isolation.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -154,7 +130,7 @@

      -If two database connections share the same cache and the reader has +If two database connections shared the same cache and the reader has enabled the read_uncommitted pragma, then the reader will be able to see changes made by the writer before the writer transaction commits. The combined use of shared cache mode and the read_uncommitted pragma @@ -170,15 +146,16 @@ at a time to an SQLite database. There can be multiple database connections open at the same time, and all of those database connections can write to the database file, but they have to take turns. SQLite uses locks -to serialize the writes automatically; this is not something that -the applications using SQLite need to worry about.

      +to serialization of the writes automatically; this is not something that +the applications using SQLite need to worry with.

      Isolation And Concurrency

      SQLite implements isolation and concurrency control (and atomicity) using -transient journal files that appear in the same directory as the database file. +transient +journal files that appear in the same directory in as the database file. There are two major "journal modes". The older "rollback mode" corresponds to using the "DELETE", "PERSIST", or "TRUNCATE" options to the journal_mode pragma. In rollback mode, @@ -204,15 +181,15 @@ In rollback mode, SQLite implements isolation by locking the database file and preventing any reads by other database connections while each write transaction is underway. -Readers can be active at the beginning of a write, before any content +Readers can be be active at the beginning of a write, before any content is flushed to disk and while all changes are still held in the writer's private memory space. But before any changes are made to the database file -on disk, all readers must be (temporarily) expelled in order to give the writer +on disk, all readers must be (temporally) expelled in order to give the writer exclusive access to the database file. Hence, readers are prohibited from seeing incomplete transactions by virtue of being locked out of the database while the transaction is being written to disk. Only after the transaction is -completely written and synced to disk and committed are the readers allowed +completely written and synced to disk and commits are the readers allowed back into the database. Hence readers never get a chance to see partially written changes.

      @@ -238,7 +215,7 @@ X can subsequently do a SELECT against the records that Y modified but X will see the older unmodified entries because Y's changes are all invisible to X while X is holding a read transaction. If X wants to see -the changes that Y made, then X must end its read transaction and +the changes that Y made, then X must ends its read transaction and start a new one (by running COMMIT followed by another BEGIN.)

      @@ -366,5 +343,4 @@ connections.

      -

      This page last modified on 2022-04-18 02:55:50 UTC

      diff -Nru sqlite3-3.42.0/www/json1.html sqlite3-3.44.0-0/www/json1.html --- sqlite3-3.42.0/www/json1.html 2023-05-16 13:43:12.000000000 +0000 +++ sqlite3-3.44.0-0/www/json1.html 2023-11-04 14:24:19.000000000 +0000 @@ -3,7 +3,7 @@ -JSON Functions And Operators +The JSON1 Extension @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      -JSON Functions And Operators +The JSON1 Extension
      @@ -126,31 +102,28 @@ Table Of Contents +

      Keyword Index

      @@ -174,7 +150,6 @@
    • application-defined SQL function
    • application-defined window functions
    • application_id pragma
    • -
    • appreciate the freedom
    • Appropriate Uses For SQLite
    • approximate ANALYZE
    • .archive command
    • @@ -194,7 +169,6 @@
    • attack resistance
    • authorizer callback
    • authorizer method
    • -
    • auto modifier
    • auto_vacuum pragma
    • autocommit mode
    • AUTOINCREMENT
    • @@ -204,7 +178,6 @@
    • automatic_index pragma
    • automatically running ANALYZE
    • "automerge" command
    • -
    • auxiliary columns
    • auxiliary columns in r-tree tables
    • auxiliary function mapping
    • avg() aggregate function
    • @@ -214,8 +187,6 @@
    • backup API
    • backup method
    • bare aggregate terms
    • -
    • base64() SQL function
    • -
    • base85() SQL function
    • bcvtab
    • BEGIN
    • BEGIN EXCLUSIVE
    • @@ -320,12 +291,9 @@
    • column-def syntax diagram
    • column-name-list
    • column-name-list syntax diagram
    • -
    • columnar output modes
    • colUsed field
    • -
    • comma option
    • Command Line Interface
    • command-line interface
    • -
    • command-line options
    • command-line shell
    • commands
    • comment
    • @@ -371,7 +339,6 @@
    • conflict resolution mode
    • conflict-clause
    • conflict-clause syntax diagram
    • -
    • .connection
    • constant-propagation optimization
    • contentless fts4 tables
    • copy method
    • @@ -385,7 +352,6 @@
    • count_changes pragma
    • coverage testing vs. fuzz testing
    • covering index
    • -
    • covering indexes
    • covering indices
    • CPU cycles used
    • CPU performance measurement
    • @@ -437,12 +403,9 @@
    • datatype
    • date and time datatype
    • date and time functions
    • -
    • date()
    • -
    • date() SQL function
    • -
    • date/time modifiers
    • +
    • date() SQL function
    • date/time special case
    • -
    • datetime()
    • -
    • datetime() SQL function
    • +
    • datetime() SQL function
    • dbghints
    • dbhash
    • dbhash.exe
    • @@ -460,7 +423,6 @@
    • default value
    • default_cache_size pragma
    • defense against dark arts
    • -
    • defense against the dark arts
    • defensive code
    • defer_foreign_keys pragma
    • degrees() SQL function
    • @@ -488,12 +450,12 @@
    • -DHAVE_MALLOC_USABLE_SIZE
    • -DHAVE_SQLITE_CONFIG_H
    • -DHAVE_STRCHRNUL
    • +
    • -DHAVE_USLEEP
    • -DHAVE_UTIME
    • DISTINCT
    • documents by category
    • dot-commands
    • double-quoted string literal
    • -
    • double-quoted string misfeature
    • download page
    • drop column
    • DROP INDEX
    • @@ -566,7 +528,6 @@
    • -DSQLITE_ENABLE_MEMORY_MANAGEMENT
    • -DSQLITE_ENABLE_MEMSYS3
    • -DSQLITE_ENABLE_MEMSYS5
    • -
    • -DSQLITE_ENABLE_NORMALIZE
    • -DSQLITE_ENABLE_NULL_TRIM
    • -DSQLITE_ENABLE_OFFSET_SQL_FUNC
    • -DSQLITE_ENABLE_PREUPDATE_HOOK
    • @@ -586,14 +547,12 @@
    • -DSQLITE_ENABLE_UNKNOWN_SQL_FUNCTION
    • -DSQLITE_ENABLE_UNLOCK_NOTIFY
    • -DSQLITE_ENABLE_UPDATE_DELETE_LIMIT
    • -
    • -DSQLITE_EXTERN
    • -DSQLITE_EXTRA_DURABLE
    • -DSQLITE_FTS3_MAX_EXPR_DEPTH
    • -DSQLITE_HAVE_ISNAN
    • -DSQLITE_HAVE_ZLIB
    • -DSQLITE_INTROSPECTION_PRAGMAS
    • -DSQLITE_LIKE_DOESNT_MATCH_BLOBS
    • -
    • -DSQLITE_MAX_ALLOCATION_SIZE
    • -DSQLITE_MAX_MEMORY
    • -DSQLITE_MAX_MMAP_SIZE
    • -DSQLITE_MAX_SCHEMA_RETRY
    • @@ -636,7 +595,6 @@
    • -DSQLITE_OMIT_INCRBLOB
    • -DSQLITE_OMIT_INTEGRITY_CHECK
    • -DSQLITE_OMIT_INTROSPECTION_PRAGMAS
    • -
    • -DSQLITE_OMIT_JSON
    • -DSQLITE_OMIT_LIKE_OPTIMIZATION
    • -DSQLITE_OMIT_LOAD_EXTENSION
    • -DSQLITE_OMIT_LOCALTIME
    • @@ -662,7 +620,6 @@
    • -DSQLITE_OMIT_VIEW
    • -DSQLITE_OMIT_VIRTUALTABLE
    • -DSQLITE_OMIT_WAL
    • -
    • -DSQLITE_OMIT_WINDOWFUNC
    • -DSQLITE_OMIT_WSD
    • -DSQLITE_OMIT_XFER_OPT
    • -DSQLITE_OS_OTHER
    • @@ -675,9 +632,8 @@
    • -DSQLITE_SECURE_DELETE
    • -DSQLITE_SORTER_PMASZ
    • -DSQLITE_SOUNDEX
    • -
    • -DSQLITE_STDCALL
    • -DSQLITE_STMTJRNL_SPILL
    • -
    • -DSQLITE_SYSAPI
    • +
    • -DSQLITE_SYSCALL
    • -DSQLITE_TCLAPI
    • -DSQLITE_TEMP_STORE
    • -DSQLITE_THREADSAFE
    • @@ -720,7 +676,6 @@
    • .expert command
    • explain query plan
    • export to excel
    • -
    • export to TSV
    • expr
    • expr syntax diagram
    • expression affinity
    • @@ -733,7 +688,6 @@
    • Extending FTS5
    • extension loading
    • external content fts4 tables
    • -
    • extract
    • factored-select-stmt
    • factored-select-stmt syntax diagram
    • faster than the filesystem
    • @@ -741,6 +695,7 @@
    • file control opcode
    • file format
    • file format version numbers
    • +
    • file I/O
    • file I/O functions
    • file locking and concurrency control
    • file locking states
    • @@ -751,8 +706,6 @@
    • filter-clause syntax diagram
    • flattened
    • flattening optimization
    • -
    • flexible type system
    • -
    • Flexible typing is a feature
    • floor() SQL function
    • footprint
    • foreign key actions
    • @@ -763,7 +716,6 @@
    • foreign_key_check pragma
    • foreign_key_list pragma
    • foreign_keys pragma
    • -
    • format() SQL function
    • forum
    • frame boundary
    • frame specification
    • @@ -827,16 +779,13 @@
    • FTS5 query syntax
    • FTS5 rank configuration option
    • FTS5 rebuild command
    • -
    • FTS5 secure-delete command
    • -
    • fts5 shadow tables
    • +
    • fts5 shadow tables
    • FTS5 snippet
    • FTS5 Strings
    • fts5 technical differences
    • FTS5 tokenizers
    • FTS5 usermerge option
    • fts5vocab
    • -
    • FULL JOIN
    • -
    • FULL OUTER JOIN
    • Full-featured SQL
    • full-text search
    • full_column_names pragma
    • @@ -868,11 +817,9 @@
    • get the canonical source code
    • glob() SQL function
    • GROUP BY
    • -
    • GROUP BY clause
    • group_concat() aggregate function
    • GROUPS frames
    • hard_heap_limit pragma
    • -
    • hash join
    • HAVE_FDATASYNC
    • HAVE_GMTIME_R
    • HAVE_ISNAN
    • @@ -881,9 +828,8 @@
    • HAVE_MALLOC_USABLE_SIZE
    • HAVE_SQLITE_CONFIG_H
    • HAVE_STRCHRNUL
    • +
    • HAVE_USLEEP
    • HAVE_UTIME
    • -
    • HAVING
    • -
    • HAVING clause
    • hazards of upgrading to the NGQP
    • hex() SQL function
    • hexadecimal integer literals
    • @@ -915,7 +861,6 @@
    • iif() SQL function
    • "immutable" query parameter
    • .import
    • -
    • .import command
    • .imposter dot-command
    • imposter tables
    • IN operator
    • @@ -931,10 +876,8 @@
    • index_list pragma
    • index_xinfo pragma
    • INDEXED BY
    • -
    • indexed expression
    • indexed-column
    • indexed-column syntax diagram
    • -
    • Indexes
    • indexes on expressions
    • indexing
    • indexing tutorial
    • @@ -953,9 +896,6 @@
    • internal table
    • Internal Versus External BLOBs
    • interrupt method
    • -
    • invalid UTF
    • -
    • IS DISTINCT FROM
    • -
    • IS NOT DISTINCT FROM
    • IS NOT operator
    • IS operator
    • isolation
    • @@ -973,16 +913,12 @@
    • JSON paths
    • json SQL function
    • json1
    • -
    • JSON5
    • -
    • JSON5 extensions
    • json_array
    • json_array SQL function
    • json_array_length
    • json_array_length SQL function
    • json_each
    • json_each table-valued function
    • -
    • json_error_position
    • -
    • json_error_position SQL function
    • json_extract
    • json_extract SQL function
    • json_group_array
    • @@ -1009,9 +945,7 @@
    • json_type SQL function
    • json_valid
    • json_valid SQL function
    • -
    • julianday modifier
    • -
    • julianday()
    • -
    • julianday() SQL function
    • +
    • julianday() SQL function
    • Kennedy
    • keyword index
    • keywords
    • @@ -1040,7 +974,6 @@
    • literal-value
    • literal-value syntax diagram
    • ln() SQL function
    • -
    • .load command
    • load_extension() SQL function
    • loadable extension
    • loadext
    • @@ -1094,7 +1027,6 @@
    • "mode" query parameter
    • modeof
    • "modeof" query parameter
    • -
    • modifiers
    • module_list pragma
    • most used
    • most widely deployed
    • @@ -1110,7 +1042,6 @@
    • NOCASE collating function
    • "nolock" query parameter
    • non-deterministic functions
    • -
    • non-standard SELECT syntax
    • NOT EXISTS operator
    • NOT IN operator
    • NOT INDEXED
    • @@ -1131,14 +1062,10 @@
    • omitfeatures
    • ON CONFLICT
    • ON CONFLICT clause
    • -
    • on-disk format
    • .once
    • onecolumn method
    • opcode definitions
    • opcodes
    • -
    • .open
    • -
    • .open command
    • -
    • OPEN_EXRESCODE
    • OPEN_NOFOLLOW
    • openclose callback
    • OpenOffice case study
    • @@ -1148,14 +1075,12 @@
    • or optimization
    • or-connected-terms
    • order by
    • -
    • orderByConsumed
    • ordering-term
    • ordering-term syntax diagram
    • ordinary common table expressions
    • OS backend
    • OSS Fuzz
    • .output
    • -
    • output mode
    • over-clause
    • over-clause syntax diagram
    • overflow page
    • @@ -1183,7 +1108,6 @@
    • pointer leak
    • pointer passing interface
    • pointer types
    • -
    • pointer value
    • porting SQLite
    • pow() SQL function
    • power-safe
    • @@ -1252,7 +1176,6 @@
    • PRAGMA stats
    • PRAGMA synchronous
    • PRAGMA table_info
    • -
    • PRAGMA table_list
    • PRAGMA table_xinfo
    • PRAGMA temp_store
    • PRAGMA temp_store_directory
    • @@ -1274,7 +1197,6 @@
    • prefix queries
    • prefix query
    • prepared statement
    • -
    • preupdate method
    • PRIMARY KEY
    • PRIMARY KEY constraint
    • primary versus extended result codes
    • @@ -1290,8 +1212,6 @@
    • "psow" query parameter
    • public-domain
    • push-down optimization
    • -
    • qbox
    • -
    • qbox output mode
    • QPSG
    • qualified-table-name
    • qualified-table-name syntax diagram
    • @@ -1338,7 +1258,6 @@
    • record format
    • .recover dot-command
    • recovery
    • -
    • recovery extension
    • recursive common table expression
    • recursive query
    • recursive-cte
    • @@ -1369,8 +1288,6 @@
    • returning-clause
    • returning-clause syntax diagram
    • reverse_unordered_selects pragma
    • -
    • RIGHT and FULL OUTER JOIN
    • -
    • RIGHT JOIN
    • Robson proof
    • ROLLBACK
    • rollback journal
    • @@ -1380,7 +1297,6 @@
    • rollback_hook method
    • round() SQL function
    • row value
    • -
    • row value IN operator
    • ROWID
    • rowid table
    • rowvalue
    • @@ -1391,12 +1307,8 @@
    • rules for determining column affinity
    • rules for determining column affinity in VIEWs
    • Run-Time Loadable Extensions
    • -
    • safe command-line option
    • -
    • --safe command-line option
    • -
    • SAVEPOINT bug
    • savepoint-stmt
    • savepoint-stmt syntax diagram
    • -
    • scan status flags
    • scanstatus options
    • .schema
    • schema format
    • @@ -1410,7 +1322,6 @@
    • segment btree
    • select
    • SELECT query
    • -
    • SELECT statement
    • select-core
    • select-core syntax diagram
    • select-stmt
    • @@ -1428,7 +1339,7 @@
    • Session Extension C-language Interface
    • Session Module C-API function list
    • .sha3sum dot-command
    • -
    • shadow table
    • +
    • shadow tables
    • shadowtabs
    • shared cache
    • shared cache mode
    • @@ -1496,7 +1407,6 @@
    • sqlite3_analyzer.exe
    • sqlite3_api_routines
    • sqlite3_auto_extension
    • -
    • sqlite3_autovacuum_pages
    • sqlite3_backup
    • sqlite3_backup_finish()
    • sqlite3_backup_init()
    • @@ -1532,7 +1442,6 @@
    • sqlite3_carray_bind
    • sqlite3_changegroup
    • sqlite3_changes
    • -
    • sqlite3_changes64
    • sqlite3_changeset_iter
    • sqlite3_clear_bindings
    • sqlite3_close
    • @@ -1586,7 +1495,6 @@
    • sqlite3_db_filename
    • sqlite3_db_handle
    • sqlite3_db_mutex
    • -
    • sqlite3_db_name
    • sqlite3_db_readonly
    • sqlite3_db_release_memory
    • sqlite3_db_status
    • @@ -1598,7 +1506,6 @@
    • sqlite3_errcode
    • sqlite3_errmsg
    • sqlite3_errmsg16
    • -
    • sqlite3_error_offset
    • sqlite3_errstr
    • sqlite3_exec
    • sqlite3_expanded_sql
    • @@ -1607,7 +1514,6 @@
    • sqlite3_extended_result_codes
    • sqlite3_file
    • sqlite3_file_control
    • -
    • sqlite3_filename
    • sqlite3_filename_database
    • sqlite3_filename_journal
    • sqlite3_filename_wal
    • @@ -1625,7 +1531,6 @@
    • sqlite3_int64
    • sqlite3_interrupt
    • sqlite3_io_methods
    • -
    • sqlite3_is_interrupted
    • sqlite3_keyword_check
    • sqlite3_keyword_count
    • sqlite3_keyword_name
    • @@ -1755,7 +1660,6 @@
    • sqlite3_stmt_readonly
    • sqlite3_stmt_scanstatus
    • sqlite3_stmt_scanstatus_reset
    • -
    • sqlite3_stmt_scanstatus_v2
    • sqlite3_stmt_status
    • sqlite3_str
    • sqlite3_str_append
    • @@ -1780,7 +1684,6 @@
    • sqlite3_thread_cleanup
    • sqlite3_threadsafe
    • sqlite3_total_changes
    • -
    • sqlite3_total_changes64
    • sqlite3_trace
    • sqlite3_trace_v2
    • sqlite3_transfer_bindings
    • @@ -1799,7 +1702,6 @@
    • sqlite3_value_bytes16
    • sqlite3_value_double
    • sqlite3_value_dup
    • -
    • sqlite3_value_encoding
    • sqlite3_value_free
    • sqlite3_value_frombind
    • sqlite3_value_int
    • @@ -1826,13 +1728,8 @@
    • sqlite3_vtab_collation
    • sqlite3_vtab_config
    • sqlite3_vtab_cursor
    • -
    • sqlite3_vtab_distinct
    • -
    • sqlite3_vtab_in
    • -
    • sqlite3_vtab_in_first
    • -
    • sqlite3_vtab_in_next
    • sqlite3_vtab_nochange
    • sqlite3_vtab_on_conflict
    • -
    • sqlite3_vtab_rhs_value
    • sqlite3_wal_autocheckpoint
    • sqlite3_wal_checkpoint
    • sqlite3_wal_checkpoint_v2
    • @@ -1883,7 +1780,6 @@
    • sqlite3session_indirect
    • sqlite3session_isempty
    • sqlite3session_memory_used
    • -
    • sqlite3session_object_config
    • sqlite3session_patchset
    • sqlite3session_patchset_strm
    • sqlite3session_table_filter
    • @@ -1927,9 +1823,8 @@
    • SQLITE_CHANGESET_NOTFOUND
    • SQLITE_CHANGESET_OMIT
    • SQLITE_CHANGESET_REPLACE
    • -
    • SQLITE_CHANGESETAPPLY_IGNORENOOP
    • -
    • SQLITE_CHANGESETAPPLY_INVERT
    • -
    • SQLITE_CHANGESETAPPLY_NOSAVEPOINT
    • +
    • SQLITE_CHANGESETAPPLY_INVERT
    • +
    • SQLITE_CHANGESETAPPLY_NOSAVEPOINT
    • SQLITE_CHANGESETSTART_INVERT
    • SQLITE_CHECKPOINT_FULL
    • SQLITE_CHECKPOINT_PASSIVE
    • @@ -1968,7 +1863,6 @@
    • SQLITE_CONSTRAINT
    • SQLITE_CONSTRAINT_CHECK
    • SQLITE_CONSTRAINT_COMMITHOOK
    • -
    • SQLITE_CONSTRAINT_DATATYPE
    • SQLITE_CONSTRAINT_FOREIGNKEY
    • SQLITE_CONSTRAINT_FUNCTION
    • SQLITE_CONSTRAINT_NOTNULL
    • @@ -2008,8 +1902,6 @@
    • SQLITE_DBCONFIG_MAX
    • SQLITE_DBCONFIG_NO_CKPT_ON_CLOSE
    • SQLITE_DBCONFIG_RESET_DATABASE
    • -
    • SQLITE_DBCONFIG_REVERSE_SCANORDER
    • -
    • SQLITE_DBCONFIG_STMT_SCANSTATUS
    • SQLITE_DBCONFIG_TRIGGER_EQP
    • SQLITE_DBCONFIG_TRUSTED_SCHEMA
    • SQLITE_DBCONFIG_WRITABLE_SCHEMA
    • @@ -2098,7 +1990,6 @@
    • SQLITE_ENABLE_MEMORY_MANAGEMENT
    • SQLITE_ENABLE_MEMSYS3
    • SQLITE_ENABLE_MEMSYS5
    • -
    • SQLITE_ENABLE_NORMALIZE
    • SQLITE_ENABLE_NULL_TRIM
    • SQLITE_ENABLE_OFFSET_SQL_FUNC
    • SQLITE_ENABLE_PREUPDATE_HOOK
    • @@ -2122,7 +2013,6 @@
    • SQLITE_ERROR_MISSING_COLLSEQ
    • SQLITE_ERROR_RETRY
    • SQLITE_ERROR_SNAPSHOT
    • -
    • SQLITE_EXTERN
    • SQLITE_EXTRA_DURABLE
    • SQLITE_FAIL
    • SQLITE_FCNTL_BEGIN_ATOMIC_WRITE
    • @@ -2150,7 +2040,6 @@
    • SQLITE_FCNTL_PRAGMA
    • SQLITE_FCNTL_RBU
    • SQLITE_FCNTL_RESERVE_BYTES
    • -
    • SQLITE_FCNTL_RESET_CACHE
    • SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE
    • SQLITE_FCNTL_SET_LOCKPROXYFILE
    • SQLITE_FCNTL_SIZE_HINT
    • @@ -2185,11 +2074,9 @@
    • SQLITE_INDEX_CONSTRAINT_ISNULL
    • SQLITE_INDEX_CONSTRAINT_LE
    • SQLITE_INDEX_CONSTRAINT_LIKE
    • -
    • SQLITE_INDEX_CONSTRAINT_LIMIT
    • SQLITE_INDEX_CONSTRAINT_LT
    • SQLITE_INDEX_CONSTRAINT_MATCH
    • SQLITE_INDEX_CONSTRAINT_NE
    • -
    • SQLITE_INDEX_CONSTRAINT_OFFSET
    • SQLITE_INDEX_CONSTRAINT_REGEXP
    • SQLITE_INDEX_SCAN_UNIQUE
    • SQLITE_INNOCUOUS
    • @@ -2270,7 +2157,6 @@
    • SQLITE_LOCKED_SHAREDCACHE
    • SQLITE_LOCKED_VTAB
    • sqlite_master table
    • -
    • SQLITE_MAX_ALLOCATION_SIZE
    • SQLITE_MAX_ATTACHED
    • SQLITE_MAX_COLUMN
    • SQLITE_MAX_COMPOUND_SELECT
    • @@ -2314,7 +2200,6 @@
    • SQLITE_NOTADB
    • SQLITE_NOTFOUND
    • SQLITE_NOTICE
    • -
    • SQLITE_NOTICE_RBU
    • SQLITE_NOTICE_RECOVER_ROLLBACK
    • SQLITE_NOTICE_RECOVER_WAL
    • SQLITE_NULL
    • @@ -2357,7 +2242,6 @@
    • SQLITE_OMIT_INCRBLOB
    • SQLITE_OMIT_INTEGRITY_CHECK
    • SQLITE_OMIT_INTROSPECTION_PRAGMAS
    • -
    • SQLITE_OMIT_JSON
    • SQLITE_OMIT_LIKE_OPTIMIZATION
    • SQLITE_OMIT_LOAD_EXTENSION
    • SQLITE_OMIT_LOCALTIME
    • @@ -2383,14 +2267,12 @@
    • SQLITE_OMIT_VIEW
    • SQLITE_OMIT_VIRTUALTABLE
    • SQLITE_OMIT_WAL
    • -
    • SQLITE_OMIT_WINDOWFUNC
    • SQLITE_OMIT_WSD
    • SQLITE_OMIT_XFER_OPT
    • SQLITE_OPEN_AUTOPROXY
    • SQLITE_OPEN_CREATE
    • SQLITE_OPEN_DELETEONCLOSE
    • SQLITE_OPEN_EXCLUSIVE
    • -
    • SQLITE_OPEN_EXRESCODE
    • SQLITE_OPEN_FULLMUTEX
    • SQLITE_OPEN_MAIN_DB
    • SQLITE_OPEN_MAIN_JOURNAL
    • @@ -2436,14 +2318,11 @@
    • SQLITE_ROW
    • SQLITE_RTREE_INT_ONLY
    • SQLITE_SAVEPOINT
    • -
    • SQLITE_SCANSTAT_COMPLEX
    • SQLITE_SCANSTAT_EST
    • SQLITE_SCANSTAT_EXPLAIN
    • SQLITE_SCANSTAT_NAME
    • -
    • SQLITE_SCANSTAT_NCYCLE
    • SQLITE_SCANSTAT_NLOOP
    • SQLITE_SCANSTAT_NVISIT
    • -
    • SQLITE_SCANSTAT_PARENTID
    • SQLITE_SCANSTAT_SELECTID
    • SQLITE_SCHEMA
    • sqlite_schema table
    • @@ -2452,8 +2331,6 @@
    • sqlite_sequence
    • SQLITE_SERIALIZE_NOCOPY
    • SQLITE_SESSION_CONFIG_STRMSIZE
    • -
    • SQLITE_SESSION_OBJCONFIG_ROWID
    • -
    • SQLITE_SESSION_OBJCONFIG_SIZE
    • SQLITE_SHM_EXCLUSIVE
    • SQLITE_SHM_LOCK
    • SQLITE_SHM_NLOCK
    • @@ -2478,15 +2355,11 @@
    • SQLITE_STATUS_SCRATCH_OVERFLOW
    • SQLITE_STATUS_SCRATCH_SIZE
    • SQLITE_STATUS_SCRATCH_USED
    • -
    • SQLITE_STDCALL
    • sqlite_stmt
    • SQLITE_STMT virtual table
    • SQLITE_STMTJRNL_SPILL
    • SQLITE_STMTSTATUS counter
    • SQLITE_STMTSTATUS_AUTOINDEX
    • -
    • SQLITE_STMTSTATUS_FILTER HIT
    • -
    • SQLITE_STMTSTATUS_FILTER_HIT
    • -
    • SQLITE_STMTSTATUS_FILTER_MISS
    • SQLITE_STMTSTATUS_FULLSCAN_STEP
    • SQLITE_STMTSTATUS_MEMUSED
    • SQLITE_STMTSTATUS_REPREPARE
    • @@ -2497,7 +2370,7 @@
    • SQLITE_SYNC_DATAONLY
    • SQLITE_SYNC_FULL
    • SQLITE_SYNC_NORMAL
    • -
    • SQLITE_SYSAPI
    • +
    • SQLITE_SYSCALL
    • SQLITE_TCLAPI
    • sqlite_temp_schema
    • SQLITE_TEMP_STORE
    • @@ -2516,7 +2389,6 @@
    • SQLITE_TESTCTRL_ISKEYWORD
    • SQLITE_TESTCTRL_LAST
    • SQLITE_TESTCTRL_LOCALTIME_FAULT
    • -
    • SQLITE_TESTCTRL_LOGEST
    • SQLITE_TESTCTRL_NEVER_CORRUPT
    • SQLITE_TESTCTRL_ONCE_RESET_THRESHOLD
    • SQLITE_TESTCTRL_OPTIMIZATIONS
    • @@ -2566,7 +2438,6 @@
    • SQLITE_VTAB_CONSTRAINT_SUPPORT
    • SQLITE_VTAB_DIRECTONLY
    • SQLITE_VTAB_INNOCUOUS
    • -
    • SQLITE_VTAB_USES_ALL_SCHEMAS
    • SQLITE_WARNING
    • SQLITE_WARNING_AUTOINDEX
    • SQLITE_WIN32_DATA_DIRECTORY_TYPE
    • @@ -2584,16 +2455,10 @@
    • status parameters
    • storage class
    • strategies
    • -
    • strftime()
    • -
    • strftime() SQL function
    • -
    • STRICT
    • -
    • STRICT table
    • -
    • strict type checking
    • +
    • strftime() SQL function
    • subprograms
    • Subqueries
    • subquery co-routines
    • -
    • subsec modifier
    • -
    • subsecond modifier
    • substr() SQL function
    • sum() aggregate function
    • super-journal
    • @@ -2602,17 +2467,13 @@
    • synchronous pragma
    • syntax diagrams
    • table b-tree
    • -
    • table data format
    • table-constraint
    • table-constraint syntax diagram
    • -
    • table-options
    • -
    • table-options syntax diagram
    • table-or-subquery
    • table-or-subquery syntax diagram
    • table-valued function
    • table-valued functions in the FROM clause
    • table_info pragma
    • -
    • table_list pragma
    • table_xinfo pragma
    • .tables
    • tables_used virtual table
    • @@ -2644,7 +2505,6 @@
    • TCL interface last_insert_rowid method
    • TCL interface nullvalue method
    • TCL interface onecolumn method
    • -
    • TCL interface preupdate method
    • TCL interface profile method
    • TCL interface progress method
    • TCL interface restore method
    • @@ -2677,8 +2537,6 @@
    • testing
    • text encoding
    • TH3
    • -
    • the -> and ->> operators
    • -
    • the -> operator
    • the .fullschema dot-command
    • the amalgamation
    • the ext3 barrier problem
    • @@ -2702,8 +2560,7 @@
    • threading mode
    • threads pragma
    • three test harnesses
    • -
    • time()
    • -
    • time() SQL function
    • +
    • time() SQL function
    • timeout method
    • tokenizer
    • torn page
    • @@ -2732,7 +2589,6 @@
    • UINT collating sequence
    • undefined BEFORE trigger behavior
    • undo/redo
    • -
    • unhex() SQL function
    • unicode() SQL function
    • unicode61
    • Uniform Resource Identifier
    • @@ -2743,17 +2599,11 @@
    • UNIQUE
    • unique constraint
    • unique index
    • -
    • unixepoch()
    • -
    • unixepoch() function
    • -
    • unixepoch() SQL function
    • unlikely() SQL function
    • unlink corruption
    • unlinked database files
    • unlock_notify method
    • unprotected sqlite3_value
    • -
    • unsafe-testing command-line option
    • -
    • --unsafe-testing command-line option
    • -
    • untrusted database files
    • UPDATE
    • UPDATE FROM
    • --update option
    • @@ -2774,7 +2624,6 @@
    • URI filenames in sqlite3_open()
    • URI query parameters
    • usable size
    • -
    • use of shared cache mode is discouraged
    • user-defined window functions
    • user_version pragma
    • using SQLite for websites
    • @@ -2785,7 +2634,6 @@
    • VACUUM INTO
    • vacuum-stmt
    • vacuum-stmt syntax diagram
    • -
    • value argument
    • VALUES
    • VALUES clause
    • variable-length integer
    • @@ -2924,29 +2772,9 @@
    • Version 3.35.4
    • Version 3.35.5
    • Version 3.36.0
    • -
    • Version 3.37.0
    • -
    • Version 3.37.1
    • -
    • Version 3.37.2
    • -
    • Version 3.38.0
    • -
    • Version 3.38.1
    • -
    • Version 3.38.2
    • -
    • Version 3.38.3
    • -
    • Version 3.38.4
    • -
    • Version 3.38.5
    • -
    • Version 3.39.0
    • -
    • Version 3.39.1
    • -
    • Version 3.39.2
    • -
    • Version 3.39.3
    • -
    • Version 3.39.4
    • Version 3.4.0
    • Version 3.4.1
    • Version 3.4.2
    • -
    • Version 3.40.0
    • -
    • Version 3.40.1
    • -
    • Version 3.41.0
    • -
    • Version 3.41.1
    • -
    • Version 3.41.2
    • -
    • Version 3.42.0
    • Version 3.5.0
    • Version 3.5.1
    • Version 3.5.2
    • @@ -3104,7 +2932,6 @@
    • with-clause syntax diagram
    • WITHOUT rowid
    • WITHOUT ROWID virtual table
    • -
    • wrapping text
    • writable_schema pragma
    • write-ahead log
    • writer starvation
    • @@ -3139,5 +2966,4 @@
    • Zipfile virtual table
    • -

      This page last modified on 2022-01-08 05:02:57 UTC

      diff -Nru sqlite3-3.42.0/www/lang_aggfunc.html sqlite3-3.44.0-0/www/lang_aggfunc.html --- sqlite3-3.42.0/www/lang_aggfunc.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/lang_aggfunc.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -128,8 +104,8 @@

      1. Syntax

      aggregate-function-invocation: -

      -
      +

      +
      @@ -192,8 +168,8 @@

      expr: -

      -
      %f fractional seconds: SS.SSS
      %H hour: 00-24
      %j day of year: 001-366 -
      %J Julian day number (fractional) +
      %J Julian day number
      %m month: 01-12
      %M minute: 00-59
      %s seconds since 1970-01-01 @@ -247,34 +187,23 @@

      -All other date and time functions can be expressed +Notice that all other date and time functions can be expressed in terms of strftime():

      -
      FunctionEquivalent (or nearly) strftime() +
      FunctionEquivalent strftime()
      date(...) strftime('%Y-%m-%d', ...)
      time(...) strftime('%H:%M:%S', ...)
      datetime(...) strftime('%Y-%m-%d %H:%M:%S', ...) -
      julianday(...) strftime('%J', ...) -- (numeric return) -
      unixepoch(...) strftime('%s', ...) -- (numeric return) +
      julianday(...) strftime('%J', ...)

      -The date(), time(), and datetime() functions all return text, and so their -strftime() equivalents are exact. However, the julianday() -and unixepoch() functions return numeric values. Their strftime() equivalents -return a string that is the text representation of the corresponding number. -

      - -

      -The main reasons for providing functions other than strftime() are -for convenience and for efficiency. The julianday() and unixepoch() -functions return real and integer values respectively, and do not -incur the format conversion costs or inexactitude resulting from use -of the '%J' or '%s' format specifiers with the strftime() function. +The only reasons for providing functions other than strftime() is +for convenience and for efficiency.

      2. Time Values

      @@ -312,8 +241,6 @@ Format 12 is the Julian day number expressed as an integer or floating point value. -Format 12 might also be interpreted as a unix timestamp if it is immediately followed -either the 'auto' or 'unixepoch' modifier.

      @@ -342,13 +269,7 @@ represent the Julian day number.

      -

      -The time-value (and all modifiers) may be omitted, in which case a time -value of 'now' is assumed. - - - -

      3. Modifiers

      +

      3. Modifiers

      The time value can be followed by zero or more modifiers that alter date and/or time. Each modifier @@ -368,12 +289,8 @@

    • start of day
    • weekday N
    • unixepoch -
    • julianday -
    • auto
    • localtime -
    • utc -
    • subsec -
    • subsecond +
    • utc
    • The first six modifiers (1 through 6) @@ -382,14 +299,14 @@ The 's' character at the end of the modifier names is optional. Note that "±NNN months" works by rendering the original date into the YYYY-MM-DD format, adding the ±NNN to the MM month value, then -normalizing the result. Thus, for example, the date 2001-03-31 modified +normalizing the result. Thus, for example, the data 2001-03-31 modified by '+1 month' initially yields 2001-04-31, but April only has 30 days so the date is normalized to 2001-05-01. A similar effect occurs when the original date is February 29 of a leapyear and the modifier is ±N years where N is not a multiple of four.

      The "start of" modifiers (7 through 9) shift the date backwards -to the beginning of the subject month, year or day.

      +to the beginning of the current month, year or day.

      The "weekday" modifier advances the date forward, if necessary, to the next date where the weekday number is N. Sunday is 0, Monday is 1, @@ -412,45 +329,9 @@ dates between 0000-01-01 00:00:00 and 5352-11-01 10:52:47 (unix times of -62167219200 through 106751991167).

      - - -

      The "julianday" modifier must immediately follow the initial -time-value which must be of the form DDDDDDDDD. Any other use of -the 'julianday' modifier is an error and causes the function to return NULL. -The 'julianday' modifier forces the time-value number to be interpreted -as a julian-day number. As this is the default behavior, the 'julianday' -modifier is scarcely more than a no-op. The only difference is that -adding 'julianday' forces the DDDDDDDDD time-value format, and causes -a NULL to be returned if any other time-value format is used. - - - -

      The "auto" modifier must immediately follow the initial time-value. -If the time-value is numeric (the DDDDDDDDDD format) then the 'auto' -modifier causes the time-value to interpreted as either a julian day -number or a unix timestamp, depending on its magnitude. If the value -is between 0.0 and 5373484.499999, then it is interpreted as a julian -day number (corresponding to dates between --4713-11-24 12:00:00 and 9999-12-31 23:59:59, inclusive). For numeric -values outside of the range of valid julian day numbers, but within -the range of -210866760000 to 253402300799, the 'auto' modifier causes -the value to be interpreted as a unix timestamp. Other numeric values -are out of range and cause a NULL return. The 'auto' modifier is a no-op -for text time-values. - -

      The 'auto' modifier can be used to work with date/time values even in -cases where it is not known if the julian day number or unix timestamp -formats are in use. The 'auto' modifier will automatically select the -appropriate format. However, there is a region of ambiguity. Unix -timestamps for the first 63 days of 1970 will be interpreted as julian -day numbers. The 'auto' modifier is very useful when the dataset is -guaranteed to not contain any dates within that region, but should be -avoided for applications that might make use of dates in the opening -months of 1970. - -

      The "localtime" modifier (14) assumes the time value to its left is in +

      The "localtime" modifier (12) assumes the time value to its left is in Universal Coordinated Time (UTC) and adjusts that time value so that it is in localtime. If "localtime" follows a time that is not UTC, then the behavior is undefined. @@ -460,41 +341,11 @@ If the time to the left is not in localtime, then the result of "utc" is undefined.

      - - -

      -The "subsecond" modifier (which may be abbreviated as just -"subsec") increases the resolution of the output for -datetime(), time(), and unixepoch(), and for the "%s" -format string in strftime(). The "subsecond" -modifier has no effect on other date/time functions. -The current implemention increases the resolution from seconds -to milliseconds, but this might increase to a higher resolution -in future releases of SQLite. When "subsec" is used with -datetime() or time(), the seconds field at the end is -followed by a decimal point and one or more digits to show -fractional seconds. When "subsec" is used with unixepoch(), -the result is a floating point value which is the number of -seconds and fractional seconds since 1970-01-01. - -

      -The "subsecond" and "subsec" modifiers have the special property -that they can occur as the first argument to date/time functions -(or as the first argument after the format string for strftime()). -When this occurs, the time value that is normally in the first -argument is understood to be "now". For example, a short cut to -get the current time in seconds since 1970 with millisecond -precision is to say: - -

      - SELECT unixepoch('subsec'); -
      -

      4. Examples

      Compute the current date.

      -

      SELECT date();
      +

      SELECT date('now');

      Compute the last day of the current month.

      @@ -504,8 +355,7 @@

      Compute the date and time given a unix timestamp 1092941466.

      - SELECT datetime(1092941466, 'unixepoch');
      - SELECT datetime(1092941466, 'auto'); -- Does not work for early 1970! + SELECT datetime(1092941466, 'unixepoch');

      Compute the date and time given a unix timestamp 1092941466, and @@ -518,8 +368,7 @@

      Compute the current unix timestamp.

      - SELECT unixepoch();
      - SELECT strftime('%s'); + SELECT strftime('%s','now');

      Compute the number of days since the signing of the US Declaration @@ -532,7 +381,7 @@

      Compute the number of seconds since a particular moment in 2004:

      - SELECT unixepoch() - unixepoch('2004-01-01 02:34:56'); + SELECT strftime('%s','now') - strftime('%s','2004-01-01 02:34:56');

      @@ -544,8 +393,8 @@ SELECT date('now','start of year','+9 months','weekday 2'); -

      Compute the time since the unix epoch in seconds with -millisecond precision:

      +

      Compute the time since the unix epoch in seconds +(like strftime('%s','now') except includes fractional part):

      SELECT (julianday('now') - 2440587.5)*86400.0; @@ -563,6 +412,7 @@ attempts to map the year into an equivalent year within this range, do the calculation, then map the year back.

      +

      These functions only work for dates between 0000-01-01 00:00:00 and 9999-12-31 23:59:59 (julian day numbers 1721059.5 through 5373484.5). For dates outside that range, the results of these @@ -578,7 +428,6 @@

      All internal computations assume the Gregorian calendar -system. They also assume that every -day is exactly 86400 seconds in duration; no leap seconds are incorporated.

      -

      This page last modified on 2023-05-04 20:20:12 UTC

      +system. It is also assumed that every +day is exactly 86400 seconds in duration.

      diff -Nru sqlite3-3.42.0/www/lang_delete.html sqlite3-3.44.0-0/www/lang_delete.html --- sqlite3-3.42.0/www/lang_delete.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/lang_delete.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -152,8 +128,8 @@

      1. Overview

      delete-stmt: -

      -
      +

      +
      @@ -220,8 +196,8 @@

      common-table-expression: -

      -
      :AAAAA colon followed by an identifier name holds a spot for a -named parameter with the name :AAAA. +A colon followed by an identifier name holds a spot for a +named parameter with the name :AAAA. Named parameters are also numbered. The number assigned is one greater than the largest parameter number already assigned. If this means the parameter would be assigned a number greater than SQLITE_MAX_VARIABLE_NUMBER, it is @@ -2739,7 +2598,7 @@ one or more occurrences of "::" and a suffix enclosed in "(...)" containing any text at all. This syntax is the form of a variable name in the Tcl programming language. The presence -of this syntax results from the fact that SQLite is really a +of this syntax results from the fact that SQLite is really a Tcl extension that has escaped into the wild.
      @@ -2758,7 +2617,7 @@ -

      5. The LIKE, GLOB, REGEXP, MATCH, and extract operators

      +

      5. The LIKE, GLOB, REGEXP, and MATCH operators

      The LIKE operator does a pattern matching comparison. The operand to the right of the LIKE operator contains the pattern and the left hand operand contains the string to match against the pattern. @@ -2799,7 +2658,7 @@

      The GLOB operator is similar to LIKE but uses the Unix file globbing syntax for its wildcards. Also, GLOB is case sensitive, unlike LIKE. Both GLOB and LIKE may be preceded by -the NOT keyword to invert the sense of the test. The infix GLOB +the NOT keyword to invert the sense of the test. The infix GLOB operator is implemented by calling the function glob(Y,X) and can be modified by overriding that function.

      @@ -2821,27 +2680,22 @@ But extensions can override the match() function with more helpful logic.

      - - -

      The extract operators act as a special syntax for functions -"->"() and "->>"(). Default implementations for these functions -perform JSON subcomponent extraction, -but extensions can override them for other purposes.

      -

      6. The BETWEEN operator

      The BETWEEN operator is logically equivalent to a pair of comparisons. -"x BETWEEN y AND z" is -equivalent to +"x BETWEEN y AND z" is +equivalent to "x>=y AND x<=z" except that with BETWEEN, the x expression is only evaluated once. +The precedence of the BETWEEN operator is the same as the precedence +as operators == and != and LIKE and groups left to right.

      7. The CASE expression

      A CASE expression serves a role similar to IF-THEN-ELSE in other -programming languages. +programming languages.

      The optional expression that occurs in between the CASE keyword and the first WHEN keyword is called the "base" expression. There are two @@ -2859,8 +2713,8 @@

      A NULL result is considered untrue when evaluating WHEN terms.

      In a CASE with a base expression, the base expression is evaluated just -once and the result is compared against the evaluation of each WHEN -expression from left to right. The result of the CASE expression is the +once and the result is compared against the evaluation of each WHEN +expression from left to right. The result of the CASE expression is the evaluation of the THEN expression that corresponds to the first WHEN expression for which the comparison is true. Or, if none of the WHEN expressions evaluate to a value equal to the base expression, the result @@ -2871,17 +2725,17 @@

      When comparing a base expression against a WHEN expression, the same collating sequence, affinity, and NULL-handling rules apply as if the base expression and WHEN expression are respectively the left- and -right-hand operands of an = operator.

      +right-hand operands of an = operator.

      -

      If the base -expression is NULL then the result of the CASE is always the result +

      If the base +expression is NULL then the result of the CASE is always the result of evaluating the ELSE expression if it exists, or NULL if it does not. -

      Both forms of the CASE expression use lazy, or short-circuit, +

      Both forms of the CASE expression use lazy, or short-circuit, evaluation. -

      The only difference between the following two CASE expressions is that -the x expression is evaluated exactly once in the first example but +

      The only difference between the following two CASE expressions is that +the x expression is evaluated exactly once in the first example but might be evaluated multiple times in the second:

        @@ -2910,7 +2764,7 @@
         each of those values must be scalars and the left expression must also
         be a scalar.
         The right-hand side of an IN or NOT IN operator can be a
        -table name or table-valued function name in which
        +table name or table-valued function name in which 
         case the right-hand side is understood to be subquery of
         the form "(SELECT * FROM name)".
         When the right operand is an empty set, the result of IN is false and the
        @@ -2968,7 +2822,7 @@
         
         

        Note that SQLite allows the parenthesized list of scalar values on the right-hand side of an IN or NOT IN operator to be an empty list but -most other SQL database engines and the SQL92 standard require +most other SQL database database engines and the SQL92 standard require the list to contain at least one element.

        9. Table Column Names

        @@ -2977,7 +2831,7 @@ statement or one of the following special identifiers: "ROWID", "OID", or "_ROWID_". The three special identifiers describe the -unique integer key (the rowid) associated with every +unique integer key (the rowid) associated with every row of every table and so are not available on WITHOUT ROWID tables. The special identifiers only refer to the row key if the CREATE TABLE statement does not define a real column with the same name. @@ -2988,11 +2842,11 @@

        10. The EXISTS operator

        -

        The EXISTS operator always evaluates to one of the integer values 0 -and 1. If executing the SELECT statement specified as the right-hand +

        The EXISTS operator always evaluates to one of the integer values 0 +and 1. If executing the SELECT statement specified as the right-hand operand of the EXISTS operator would return one or more rows, then the EXISTS operator evaluates to 1. If executing the SELECT would return -no rows at all, then the EXISTS operator evaluates to 0. +no rows at all, then the EXISTS operator evaluates to 0.

        The number of columns in each row returned by the SELECT statement (if any) and the specific values returned have no effect on the results @@ -3015,15 +2869,14 @@

        A subquery that returns a single column is a scalar subquery and can be used most anywhere. A subquery that returns two or more columns is a row value -subquery and can only be used as an operand of a comparison operator or as -the value in an UPDATE SET clause whose column name list has the same size. +subquery and can only be used as the operand of a comparison operator.

        12. Correlated Subqueries

        -

        A SELECT statement used as either a scalar subquery or as the -right-hand operand of an IN, NOT IN or EXISTS expression may contain +

        A SELECT statement used as either a scalar subquery or as the +right-hand operand of an IN, NOT IN or EXISTS expression may contain references to columns in the outer query. Such a subquery is known as a correlated subquery. A correlated subquery is reevaluated each time its result is required. An uncorrelated subquery is evaluated only once @@ -3034,7 +2887,7 @@

        13. CAST expressions

        A CAST expression of the form "CAST(expr AS type-name)" -is used to convert the value of expr to +is used to convert the value of expr to a different storage class specified by type-name. A CAST conversion is similar to the conversion that takes place when a column affinity is applied to a value except that with @@ -3053,8 +2906,8 @@

    Affinity of type-name Conversion Processing
    NONE - Casting a value to a type-name with no affinity + NONE + Casting a value to a type-name with no affinity causes the value to be converted into a BLOB. Casting to a BLOB consists of first casting the value to TEXT in the encoding of the database connection, then @@ -3065,7 +2918,7 @@ To cast a BLOB value to TEXT, the sequence of bytes that make up the BLOB is interpreted as text encoded using the database encoding.

    - Casting an INTEGER or REAL value into TEXT renders the value as if via + Casting an INTEGER or REAL value into TEXT renders the value as if via sqlite3_snprintf() except that the resulting TEXT uses the encoding of the database connection. @@ -3098,11 +2951,11 @@

    When casting to INTEGER, if the text looks like a floating point value with an exponent, the exponent will be ignored because it is no part of the integer prefix. For example, - "CAST('123e+5' AS INTEGER)" results in 123, not in 12300000. + "(CAST '123e+5' AS INTEGER)" results in 123, not in 12300000.

    The CAST operator understands decimal - integers only — conversion of hexadecimal integers stops - at the "x" in the "0x" prefix of the hexadecimal integer string + integers only — conversion of hexadecimal integers stops + at the "x" in the "0x" prefix of the hexadecimal integer string and thus result of the CAST is always zero.

    A cast of a REAL value into an INTEGER results in the integer @@ -3127,7 +2980,7 @@ exponent) and the value is small enough to fit in a 64-bit signed integer, then the result will be INTEGER. Input text that looks like floating point (there is a decimal point and/or - an exponent) and the text describes a value that + an exponent) and the text describes a value that can be losslessly converted back and forth between IEEE 754 64-bit float and a 51-bit signed integer, then the result is INTEGER. (In the previous sentence, a 51-bit integer is specified since that is one @@ -3141,7 +2994,7 @@

    -

    Note that the result from casting any non-BLOB value into a +

    Note that the result from casting any non-BLOB value into a BLOB and the result from casting any BLOB value into a non-BLOB value may be different depending on whether the database encoding is UTF-8, UTF-16be, or UTF-16le. @@ -3151,7 +3004,7 @@

    14. Boolean Expressions

    -

    The SQL language features several contexts where an expression is +

    The SQL language features several contexts where an expression is evaluated and the result converted to a boolean (true or false) value. These contexts are: @@ -3164,13 +3017,13 @@

    To convert the results of an SQL expression to a boolean value, SQLite -first casts the result to a NUMERIC value in the same way as a -CAST expression. A numeric zero value (integer value 0 or real +first casts the result to a NUMERIC value in the same way as a +CAST expression. A numeric zero value (integer value 0 or real value 0.0) is considered to be false. A NULL value is still NULL. All other values are considered true.

    For example, the values NULL, 0.0, 0, 'english' and '0' are all considered -to be false. Values 1, 1.0, 0.1, -0.1 and '1english' are considered to +to be false. Values 1, 1.0, 0.1, -0.1 and '1english' are considered to be true.

    Beginning with SQLite 3.23.0 (2018-04-02), SQLite recognizes the @@ -3182,9 +3035,9 @@

    The boolean identifiers TRUE and FALSE are usually just aliases for the integer values 1 and 0, respectively. However, if TRUE or FALSE -occur on the right-hand side of an IS operator, then the IS operator -evaluates the left-hand operand as a boolean value and returns an appropriate -answer. +occur on the right-hand side of an IS operator, then they form new +unary postfix operators "IS TRUE" and "IS FALSE" which test the boolean +value of the operand on the left.

    15. Functions

    SQLite supports many simple, aggregate, @@ -3373,5 +3226,4 @@ single argument is an aggregate and the max() function with two or more arguments is a simple function. Aggregate functions can usually also be used as window functions. -

    This page last modified on 2023-03-20 10:33:41 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/lang.html sqlite3-3.44.0-0/www/lang.html --- sqlite3-3.42.0/www/lang.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/lang.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQL As Understood By SQLite

    @@ -124,7 +100,7 @@ while at the same time adding a few features of its own. This document attempts to describe precisely what parts of the SQL language SQLite does -and does not support. A list of SQL keywords is +and does not support. A list of SQL keywords is also provided. The SQL language syntax is described by syntax diagrams. @@ -180,7 +156,7 @@

    The routines sqlite3_prepare_v2(), sqlite3_prepare(), -sqlite3_prepare16(), sqlite3_prepare16_v2(), +sqlite3_prepare16(), sqlite3_prepare16_v2(), sqlite3_exec(), and sqlite3_get_table() accept an SQL statement list (sql-stmt-list) which is a semicolon-separated list of statements.

    @@ -430,4 +406,3 @@
    - diff -Nru sqlite3-3.42.0/www/lang_indexedby.html sqlite3-3.44.0-0/www/lang_indexedby.html --- sqlite3-3.42.0/www/lang_indexedby.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/lang_indexedby.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -133,8 +109,8 @@ is not portable to other SQL database engines.

    qualified-table-name: -

    -
    +

    +
    @@ -256,5 +232,4 @@ use the sqlite3_stmt_status() interface to detect index misuse rather than the INDEXED BY phrase described here.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/lang_insert.html sqlite3-3.44.0-0/www/lang_insert.html --- sqlite3-3.42.0/www/lang_insert.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/lang_insert.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -128,8 +104,8 @@

    1. Overview

    insert-stmt: -

    -
    +

    +
    @@ -337,8 +313,8 @@

    common-table-expression: -

    -
    @@ -3192,4 +3141,3 @@ compatibility with SqlServer and Oracle, SQLite does not enforce this rule.

    - diff -Nru sqlite3-3.42.0/www/lemon.html sqlite3-3.44.0-0/www/lemon.html --- sqlite3-3.42.0/www/lemon.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/lemon.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -234,7 +210,7 @@ Lemon has the concept of a "fallback" token. The SQL language contains a large number of keywords and these keywords have the potential to collide with identifier names. -Lemon has the ability to designate some keywords as being able to +Lemon has the ability to designate some keywords has being able to "fallback" to an identifier. If the keyword appears in the input token stream in a context that would otherwise be a syntax error, the token is automatically transformed into its fallback before the syntax error @@ -291,5 +267,4 @@ was written before then, and SQLite afterwards. There is a clear difference in the coding styles of these two products, with SQLite seeming to be cleaner, more readable, and easier to maintain. -

    This page last modified on 2022-04-18 02:55:50 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/limits.html sqlite3-3.44.0-0/www/limits.html --- sqlite3-3.42.0/www/limits.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/limits.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -502,7 +478,7 @@

    Every database consists of one or more "pages". Within a single database, -every page is the same size, but different databases can have page sizes +every page is the same size, but different database can have page sizes that are powers of two between 512 and 65536, inclusive. The maximum size of a database file is 4294967294 pages. At the maximum page size of 65536 bytes, this translates into a maximum database size of @@ -531,5 +507,4 @@ is proportional to the size of the schema. -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/loadext.html sqlite3-3.44.0-0/www/loadext.html --- sqlite3-3.42.0/www/loadext.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/loadext.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -180,7 +156,7 @@ routine for additional information.

    Note that different operating systems use different filename -suffixes for their shared libraries. Windows uses ".dll", Mac uses +suffixes for their shared libraries. Windows use ".dll", Mac uses ".dylib", and most unixes other than mac use ".so". If you want to make your code portable, you can omit the suffix from the shared library filename and the appropriate suffix will be added automatically @@ -408,7 +384,7 @@

    The default behavior for a loadable extension is that it is unloaded from process memory when the database connection that originally invoked -sqlite3_load_extension() closes. (In other words, the xDlClose method +sqlite3_load_extension() closes. (In other words, the xDlUnload method of the sqlite3_vfs object is called for all extensions when a database connection closes.) However, if the initialization procedure returns SQLITE_OK_LOAD_PERMANENTLY instead of SQLITE_OK, then the extension will @@ -480,7 +456,7 @@ xDlOpen(), xDlError(), xDlSym(), and xDlClose() methods of the sqlite3_vfs object. These methods are implemented using the dlopen() library on unix (which explains why SQLite commonly -needs to be linked against the "-ldl" library on unix systems) +need to be linked against the "-ldl" library on unix systems) and using LoadLibrary() API on Windows. In a custom VFS for unusual systems, these methods can all be omitted, in which case the run-time extension loading mechanism will not work (though @@ -489,5 +465,4 @@ SQLite can be compiled with SQLITE_OMIT_LOAD_EXTENSION to omit the extension loading code from the build. -

    This page last modified on 2022-04-18 02:55:50 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/lockingv3.html sqlite3-3.44.0-0/www/lockingv3.html --- sqlite3-3.42.0/www/lockingv3.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/lockingv3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    @@ -667,7 +643,7 @@ the first INSERT, UPDATE, or DELETE statement is executed. No EXCLUSIVE lock is acquired until either the memory cache fills up and must be spilled to disk or until the transaction commits. In this way, -the system delays blocking read access to the file until the +the system delays blocking read access to the file file until the last possible moment.

    @@ -693,5 +669,4 @@ commands can be executed against other tables in the database. But none of these changes will commit until the original SELECT statement finishes.

    -

    This page last modified on 2022-08-10 18:45:48 UTC

    diff -Nru sqlite3-3.42.0/www/locrsf.html sqlite3-3.44.0-0/www/locrsf.html --- sqlite3-3.42.0/www/locrsf.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/locrsf.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -193,5 +169,4 @@ Implementation of mechanisms such as encryption that prevent the preservation of content by a trusted repository.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/lts.html sqlite3-3.44.0-0/www/lts.html --- sqlite3-3.42.0/www/lts.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/lts.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -237,5 +213,4 @@ US Library Of Congress who have identified SQLite as a recommended storage format for the preservation of digital content. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/malloc.html sqlite3-3.44.0-0/www/malloc.html --- sqlite3-3.42.0/www/malloc.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/malloc.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -1066,7 +1042,7 @@ to some extent on the length of the filename of the database file, but rarely exceeds 2KB on 32-bit systems. (More space is required on 64-bit systems due to the increased size of pointers.) -Each parser object uses about 1.6KB of memory. Thus, elements 3 through 6 +Each parser object uses about 1.6KB of memory. Thus, elements 3 through 7 above can easily be controlled to keep the maximum memory allocation size below 2KB.

    @@ -1138,5 +1114,4 @@

    Update: As of SQLite version 3.7.0 (2010-07-21), all of SQLite memory allocation interfaces are considered stable and will be supported in future releases.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/memstat.html sqlite3-3.44.0-0/www/memstat.html --- sqlite3-3.42.0/www/memstat.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/memstat.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -199,5 +175,4 @@ the interfaces, with the initial -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/mingw.html sqlite3-3.44.0-0/www/mingw.html --- sqlite3-3.42.0/www/mingw.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/mingw.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    @@ -240,5 +216,4 @@

    And you are done...

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/mmap.html sqlite3-3.44.0-0/www/mmap.html --- sqlite3-3.42.0/www/mmap.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/mmap.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    @@ -135,7 +111,7 @@
    1. Many operations, especially I/O intensive operations, can be - faster since content need not be copied between kernel space + faster since content does need to be copied between kernel space and user space.

    2. The SQLite library may need less RAM since it shares pages with @@ -273,5 +249,4 @@ is the default mmap_size of the process and the Y is the new hard upper bound. The hard upper bound cannot be increased above its compile-time setting using SQLITE_CONFIG_MMAP_SIZE but it can be reduced or zeroed.

      -

      This page last modified on 2022-04-18 02:55:50 UTC

      diff -Nru sqlite3-3.42.0/www/mostdeployed.html sqlite3-3.44.0-0/www/mostdeployed.html --- sqlite3-3.42.0/www/mostdeployed.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/mostdeployed.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -186,5 +162,4 @@ might be higher for SQLite and so SQLite might be the single most widely deployed and used software component.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/news.html sqlite3-3.44.0-0/www/news.html --- sqlite3-3.42.0/www/news.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/news.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,209 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Recent News

    -

    2023-05-16 - Version 3.42.0

    -Version 3.42.0 is a routine enhancement release of SQLite. -Key enhancements in this release are added support for -JSON5 and the FTS5 secure-delete command. See the -change log for a -summary of all enhancements in this release. -

    2023-03-22 - Version 3.41.2

    -Version 3.41.2 is a patch release that fixes multiple -fuzzer-found problems in prior releases. The worst problems -include reads (not writes) past the end of a buffer. Upgrading -is recommended. -

    2023-03-10 - Version 3.41.1

    -Version 3.41.1 is a patch release that fixes various obscure -problems found in 3.41.0 and reported by users. Upgrading -is optional. -

    2023-02-21 - Version 3.41.0

    -Version 3.41.0 is a routine enhancement release. -

    2022-12-28 - Version 3.40.1

    -Version 3.40.1 is a patch release that fixes some obscure problems -in version 3.40.0. The problems fixed have no impact on most applications. -Upgrading is only necessary if you encounter problems. -

    -The two most important fixes are these: -

      -
    • -Fix the safe command-line option on the CLI so that it -correctly disallows functions with side-effects. This is a bug -in the CLI — not a bug in the -SQLite library — and it only affects the --safe command-line -option, making that option less than fully "safe". As the number -of systems that use the --safe command-line option in the CLI is -approximately zero, this is not considered an important bug. However, -a third-party wrote a CVE against it which caused considerable angst -among maintainers, so it seems good to get the fix into circulation -sooner rather than wait on the next major release. -

    • -The optional memsys5 memory allocator picked up a bug that might -put it into an infinite loop for very large (500MiB) allocations. -Almost all systems use their native memory allocator, not memsys5. -Memsys5 is only used if SQLite is compiled using SQLITE_ENABLE_MEMSYS5 -and then initialized using sqlite3_config(SQLITE_CONFIG_HEAP). -Very, very few systems do this, and so the problem is not considered -to be serious. -

    -

    -See the branch-3.40 timeline -for a complete listing of changes that have gone into this patch release. -


    2022-11-16 - Version 3.40.0

    -Version 3.40.0 is a new feature release of SQLite. See the -change log for details. -Key enhancements in this release include: -
      -
    1. -Official support for compiling -SQLite to WASM -and running it in a web browser. -

    2. -New and improved recovery extension for extracting -data from corrupted database files. -

    -

    -This release also includes performance enhancements and -improvements to the query planner. -

    -A psychological milestone: The performance benchmark that -the SQLite developers have used for many years has for -the first time dropped below 1 billion CPU cycles -(measured using cachegrind) when run in WAL mode. -This is less than half the number of CPU cycles used as -recently as 8 years ago. (The graph below shows SQLite using -a rollback journal which uses fewer CPU cycles at the expense -of extra I/O. The benchmark passed through the 1 billion cycle -barrier for rollback journals for the previous release.) -

    - -

    -

    2022-09-29 - Version 3.39.4

    -Version 3.39.4 is a security release that addresses a single -long-standing problem in the FTS3 extension. An attacker -who is able to execute arbitrary SQL statements and who can create -a corrupt database that is 2GB or larger in size might be able to trick -FTS3 into overflowing an integer used to size a memory allocation, -causing the allocation to be too small and ultimately resulting in -a buffer overrun. The release also includes fixes for other -obscure weaknesses, as described in the release notes. -

    2022-09-05 - Version 3.39.3

    -Version 3.39.3 is a patch release that fixes a few obscure problems -in the 3.39.0 release. See the release notes for details. -

    2022-07-21 - Version 3.39.2

    -Version 3.39.2 is a security release that addresses multiple long-standing -issues in SQLite. The most severe problem is identified by CVE-2022-35737. -That issue is associated with the auxiliary C-language APIs -of SQLite and cannot be reached using SQL or database inputs, and hence is -unlikely to affect your application. Nevertheless, upgrading is recommended. -The other issues are comparatively minor. -This release also fixes a performance regression that appeared in version -3.39.0 that might affect some multi-way joins that use LEFT JOIN. -

    2022-07-13 - Version 3.39.1

    -Version 3.39.1 is a patch release that fixes a few minor problem in version -3.39.0. Upgrading is optional. -

    2022-06-25 - Version 3.39.0

    -Version 3.39.0 is regular maintenance release of SQLite. The key enhancement -in this release is added support for RIGHT and FULL JOIN. There are other -language and performance enhancements as well — see the -release notes for details. -

    2022-05-06 - Version 3.38.5

    -The 3.38.4 patch release included a minor change to the CLI source code -that did not work. The release manager only ran a subset of the normal -release tests, and hence did not catch the problem. As a result, the CLI -will segfault when using columnar output modes in version 3.38.4. This -blunder did not affect the core SQLite library. It only affected the CLI. -

    -Take-away lesson: Always run all of your tests prior to -a release - even a trival patch release. Always. -

    -The 3.38.5 patch release fixes the 3.38.4 blunder. -


    2022-05-04 - Version 3.38.4

    -Another user-discovered problem in the new Bloom filter optimization -is fixed in this patch release. Without the fix, it is possible for -a multi-way join that uses a Bloom filters for two or more tables in -the join to enter an infinite loop if the key constraint on one of those -tables contains a NULL value. -

    2022-04-27 - Version 3.38.3

    -Version 3.38.3 fixes a bug in the automatic-index and Bloom filter -construction logic that might cause SQLite to be overly aggressive -in the use of ON clause constraints, resulting in an incorrect -automatic-index or Bloom filter that excludes some valid rows from -output. The bug was introduced in version 3.38.0. Other minor -changes were tossed in to complete the patch. -

    2022-03-26 - Version 3.38.2

    -Version 3.38.2 fixes another bug in the new Bloom filter -optimization that might cause incorrect answers for a -LEFT JOIN that has an IS NULL constraint on the right-hand -table. -

    2022-03-12 - Version 3.38.1

    -Version 3.38.1 fixes a pair of bugs in the Bloom filter -optimization that was introduced in version 3.38.0. These -bugs might cause incorrect answers for some obscure queries. -Various other minor problems and documentation typos were -fixed at the same time. -

    2022-02-22 - Version 3.38.0

    -Version 3.38.0 is a routine maintenance release of -SQLite. There are various minor enhancements and -about a 0.5% reduction in the number of CPU cycles -used. See the -release notes for -more detail. -

    2022-01-06 - Version 3.37.2

    -Version 3.37.2 fixes a -database corruption bug. You are -encouraged to upgrade, especially if you are using SAVEPOINT.

    - -

    The problem first appeared in version 3.35.0 (2021-03-12) and -affects all subsequent releases through 3.37.1. -If temporary files are store in memory (which is not the default -behavior, but is sometimes selected by applications using either --DSQLITE_TEMP_STORE or PRAGMA temp_store) and -if a SAVEPOINT is rolled back and then subsequent changes -within the same transaction are committed, the database file might -(with low but non-zero probability) go corrupt. -


    2021-12-30 - Version 3.37.1

    -Version 3.37.1 fixes a bug in the UPSERT logic, introduced by -the UPSERT enhancements of version 3.35.0, that can cause -incorrect byte-code to be generated in some cases, resulting -in an infinite loop in the byte code, or a NULL-pointer dereference. -This patch release also fixes some other minor problems with -assert() statements and in the CLI. -

    2021-11-27 - Version 3.37.0

    -Version 3.37.0 is a routine maintenance release of SQLite. -The biggest new feature in this release is support for -STRICT tables. Other enhancements are described in -the release notes. -

    2021-06-18 - Version 3.36.0

    +

    2021-06-18 - Version 3.36.0

    Version 3.36.0 is a routine maintenance release of SQLite. There are no new major features, only incremental improvements to existing features and small performance improvements. @@ -761,5 +565,4 @@

    Old news... -

    This page last modified on 2023-05-16 10:48:13 UTC

    diff -Nru sqlite3-3.42.0/www/np1queryprob.html sqlite3-3.44.0-0/www/np1queryprob.html --- sqlite3-3.42.0/www/np1queryprob.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/np1queryprob.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -512,5 +488,4 @@ PRAGMA localdb.freelist_count; PRAGMA localdb.page_count;
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/nulinstr.html sqlite3-3.44.0-0/www/nulinstr.html --- sqlite3-3.42.0/www/nulinstr.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/nulinstr.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -135,12 +111,12 @@

    1. -The length() SQL function only counts characters up to and excluding +The length() SQL function only counts characters up through and excluding the first NUL.

    2. -The quote() SQL function only shows characters up to and excluding +The quote() SQL function only shows characters up through and excluding the first NUL.

    3. @@ -217,7 +193,7 @@

      If this expression returns a non-zero value N, then there exists an embedded NUL at the N-th character position. Thus to count the number -of rows that contain embedded NUL characters: +fo rows that contain embedded NUL characters:

      SELECT count(*) FROM t1 WHERE instr(b,char(0))>0;
       
      @@ -233,5 +209,4 @@

      UPDATE t1 SET b=substr(b,1,instr(b,char(0)))
        WHERE instr(b,char(0));
       
      -

      This page last modified on 2022-05-23 22:21:54 UTC

      diff -Nru sqlite3-3.42.0/www/nulls.html sqlite3-3.44.0-0/www/nulls.html --- sqlite3-3.42.0/www/nulls.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/nulls.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    NULL Handling in SQLite Versus Other Database Engines

    @@ -341,7 +317,7 @@ Notes:   1.  -Older versions of firebird omit all NULLs from SELECT DISTINCT +Older versions of firebird omits all NULLs from SELECT DISTINCT and from UNION. 2.  @@ -370,8 +346,8 @@ -- I have about decided that SQL's treatment of NULLs is capricious and cannot be -- deduced by logic. It must be discovered by experiment. To that end, I have -- prepared the following script to test how various SQL databases deal with NULL. --- My aim is to use the information gathered from this script to make SQLite as --- much like other databases as possible. +-- My aim is to use the information gather from this script to make SQLite as much +-- like other databases as possible. -- -- If you could please run this script in your database engine and mail the results -- to me at drh@hwaci.com, that will be a big help. Please be sure to identify the @@ -401,7 +377,7 @@ select a+60, case b when c then 1 else 0 end from t1; select a+70, case c when b then 1 else 0 end from t1; --- What happens when you multiply a NULL by zero? +-- What happens when you multiple a NULL by zero? select a+80, b*0 from t1; select a+90, b*c from t1; @@ -436,5 +412,4 @@ drop table t1; drop table t2;
    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/oldnews.html sqlite3-3.44.0-0/www/oldnews.html --- sqlite3-3.42.0/www/oldnews.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/oldnews.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -127,12 +103,12 @@

    SQLite version 3.9.1 is a small patch to version 3.9.0 that includes -a few simple build script and #ifdef tweaks to make the code easier to -compile on a wider variety of platform. There are no functional changes, +a few simple build script and #ifdef tweaks to make the code easier to +compile on a wider variety of platform. There are no functional changes, except for a single -minor bug-fix in -the json1 extension to stop it from recognizing form-feed -(ASCII 0x0c) as a whitespace character, in conformance with +minor bug-fix in +the json1 extension to stop it from recognizing form-feed +(ASCII 0x0c) as a whitespace character, in conformance with RFC7159.


    2015-10-14 - Release 3.9.0

    SQLite version 3.9.0 is a regularly schedule maintenance release. @@ -156,7 +132,7 @@ See the change log for details.


    2015-05-20 - Release 3.8.10.2

    Yikes! Index corruption after a sequence of valid SQL statements! -

    It has been many years since anything like +

    It has been many years since anything like this bug has snuck into an official SQLite release. But for the pasts seven months (version 3.8.7 through version 3.8.10.1) @@ -182,11 +158,11 @@ This release features performance improvements, fixes to several arcane bugs found by the AFL fuzzer, the new "sqldiff.exe" command-line utility, improvements to the documentation, and other enhancements. - See the release notes for + See the release notes for additional information.


    2015-04-08 - Release 3.8.9

    SQLite version 3.8.9 is a regularly scheduled maintenance release. - New features in this release include the + New features in this release include the PRAGMA index_xinfo command, the sqlite3_status64() interface, and the ".dbinfo" command of the command-line shell. See the release notes for @@ -264,7 +240,7 @@ the previous release are minimal.

    The primary reason for this release is to enhance the ROLLBACK command - so that it allows running queries on the same database connection to + so that it allows running queries on the same database connection to continue running as long as the ROLLBACK does not change the schema. In all previous versions of SQLite, a ROLLBACK would cause pending queries to stop immediately and return SQLITE_ABORT or @@ -273,7 +249,7 @@ are allowed to continue running if the schema is unmodified.

    In addition to the ROLLBACK enhancement, this patch release also - includes fixes for three obscure bugs. See the + includes fixes for three obscure bugs. See the change log for details.


    2014-10-30 - Release 3.8.7.1

    SQLite version 3.8.7.1 is a bug-fix release.

    @@ -308,7 +284,7 @@ has an unmeasurably small performance impact. But the improvements add up. Measured on a well-defined workload (which the SQLite developers use as a proxy for a typical application workload) using cachegrind on Linux - and compiled with gcc 4.8.1 and -Os on x64 linux, the current release + and compiled with gcc 4.8.1 and -Os on x64 linux, the current release does over 20% more work for the same number of CPU cycles compared to the previous release. Cachegrind is not a real CPU, and the workload used for measurement is only a proxy. So your performance may vary. @@ -349,7 +325,7 @@

    Other noteworthy changes include the addition of support for hexadecimal integers (ex: 0x1234), and performance enhancements - to the IN operator which, according to + to the IN operator which, according to mailing list reports, help some queries run up to five times faster.

    @@ -360,7 +336,7 @@ test program. On the other hand, the compiled binary for version 3.8.6 is about 5% larger than 3.8.0. - The size increase is + The size increase is due in part to the addition of new features such as WITHOUT ROWID tables and common table expressions.

    2014-06-04 - Release 3.8.5

    @@ -373,7 +349,7 @@ is recommended to prevent future problems.

    In addition to bug fixes, the 3.8.5 release adds improvements to the - query planner, especially regarding sorting using indices and handling + query planner, especially regarding sorting using indices and handling OR terms in the WHERE clause for WITHOUT ROWID tables. The ".system" and ".once" dot-commands were added to the command-line interface. And @@ -385,7 +361,7 @@ result. See ticket 98825a79ce145 for details. - This release adds a + This release adds a one-character change to a single line of code to fix the problem.


    2014-03-26 - Release 3.8.4.2

    @@ -415,14 +391,14 @@

    SQLite version 3.8.4 is a maintenance release featuring performance enhancements and fixes for a number of obscure bugs. There are no significant new features in SQLite version 3.8.4. - However, the number of CPU cycles (measured by valgrind) needed to + However, the number of CPU cycles (measured by valgrind) needed to do many common operations has be reduced by about 12% relative to the previous release, and by about 25% relative to version 3.7.16 from approximately one year ago.

    Version 3.8.4 of SQLite fixes several corner-case bugs that were found since the previous release. These bugs were unlikely to appear - in practice, and none represent a security vulnerability. + in practice, and none represent a security vulnerability. Nevertheless, developers are encouraged to upgrade from all prior releases.


    2014-02-11 - Release 3.8.3.1

    SQLite version 3.8.3.1 fixes a bug present in versions 3.8.1, @@ -451,7 +427,7 @@

    The most visible change in version 3.8.3 is the addition of support for common table expressions. It is now possible to write a single SELECT statement that will query a tree or graph, using either - a depth-first or a breadth-first search. A single SQLite query will + a depth-first or a breadth-first search. A single SQLite query will even solve Sudoku puzzles or compute the Mandelbrot set. As part of this change, SQLite now accepts a VALUES clause anyplace that a SELECT statement is valid.

    @@ -467,14 +443,14 @@

    Version 3.8.2 adds support for WITHOUT ROWID tables. This is a significant extension to SQLite. Database files that contain WITHOUT ROWID tables are not readable or writable by prior versions of SQLite, however - databases that do not use WITHOUT ROWID tables are fully backwards + databases that do not use WITHOUT ROWID tables are fully backwards and forwards compatible.

    The 3.8.2 release contains a potentially incompatible change. In - all prior versions of SQLite, a cast from a very large positive + all prior versions of SQLite, a cast from a very large positive floating point number into an integer resulted in the most negative integer. In other words, CAST(+99.9e99 to INT) would yield -9223372036854775808. - This behavior came about because it is what x86/x64 hardware does + This behavior came about because it is what x86/x64 hardware does for the equivalent cast in the C language. But the behavior is bizarre. And so it has been changed effective with this release so that a cast from a floating point number into an integer returns the integer @@ -484,7 +460,7 @@ value being accessed is really a floating point number, they are also affected by this change.

    -

    Besides the two changes mentioned above, the 3.8.2 release also +

    Besides the two changes mentioned above, the 3.8.2 release also includes a number of performance enhancements. The skip-scan optimization is now available for databases that have been processed by ANALYZE. Constant SQL functions are now factored out of @@ -495,13 +471,13 @@


    2013-10-17 - Release 3.8.1

    SQLite version 3.8.1 is a regularly scheduled maintenance release. Upgrading from the previous release is optional, though you should upgrade - if you are using partial indices as there was a + if you are using partial indices as there was a bug related to partial indices in the previous release that could result in an incorrect answer for count(*) queries.

    The next generation query planner that was premiered in the previous - release continues to work well. + release continues to work well. The new query planner has been tweaked slightly in the current release to help it make better decisions in some cases, but is largely unchanged. Two new SQL functions, likelihood() and @@ -523,12 +499,12 @@ PRAGMA stats statement can be used to view row size estimates.

    Version 3.8.1 adds the SQLITE_ENABLE_STAT4 compile-time option. - STAT4 is very similar to STAT3 in that it uses samples from indices to + STAT4 is very similar to STAT3 in that it uses samples from indices to try to guess how many rows of the index will be satisfy by WHERE clause constraints. The difference is that STAT4 samples all columns of the index whereas the older STAT3 only sampled the left-most column. Users of STAT3 are encouraged to upgrade to STAT4. Application developers should - use STAT3 and STAT4 with caution since both options, by design, violate + use STAT3 and STAT4 with caution since both options, by design, violate the query planner stability guarantee, making it more difficult to ensure uniform performance is widely-deployed and mass-produced embedded applications. @@ -547,7 +523,7 @@ breaking legacy programs that rely on undefined behavior in previous SQLite releases, and so the minor version number was incremented for that reason. - But the risks are low and there is a query planner checklist is + But the risks are low and there is a query planner checklist is available to application developers to aid in avoiding problems.

    SQLite version 3.8.0 is actually one of the most heavily tested @@ -564,9 +540,9 @@ changes in this release.

    There are many bug fixes in version 3.7.17. But this does not indicate - that 3.7.16 was a problematic release. All of the bugs in 3.7.17 are - obscure and are unlikely to impact any particular application. And most - of the bugs that are fixed in 3.7.17 predate 3.7.16 and have been in + that 3.7.16 was a problematic release. All of the bugs in 3.7.17 are + obscure and are unlikely to impact any particular application. And most + of the bugs that are fixed in 3.7.17 predate 3.7.16 and have been in the code for years without ever before being noticed. Nevertheless, due to the large number of fixes, all users are encouraged to upgrade when possible. @@ -580,12 +556,12 @@

    As far as we know, this bug has never been seen in the wild. The problem was discovered by the SQLite developers while writing stress tests for a separate component of SQLite. Those stress tests have not yet - found any problems with the component they were intended to verify, but + found any problems with the component they were intended to verify, but they did find the bug which is the subject of this patch release.

    Other than updates to version numbers, the only difference between this release and 3.7.16.1 is a two-character change in a single identifier, - which is contained in the windows-specific OS interface logic. There + which is contained in the windows-specific OS interface logic. There are no changes in this release (other than version numbers) for platforms other than Windows.


    2013-03-29 - Release 3.7.16.1

    @@ -643,11 +619,11 @@ was also being cached within expressions. If an expression was part of the schema and contained a cached collating function, it would point to the collating function in the database connection that originally parsed the - schema. If that database connection closed while other database + schema. If that database connection closed while other database connections using the same shared cache continued to operate, they other database connections would try to use the deallocated collating function in the database connection that closed. The fix in version 3.7.15 was to - not cache collating function pointers in the expression structure but + not cache collating function pointers in the expression structure but instead look them up each time a new statement is prepared.

    This release also contains some important enhancements to the query planner @@ -658,10 +634,10 @@ the original table, under the theory that indices contain less information and are thus smaller and hence require less disk I/O to scan.

    -

  • Enhance the IN operator to allow it to make use of +

  • Enhance the IN operator to allow it to make use of indices that have numeric affinity.

    -

  • Do a better job of recognizing when an ORDER BY clause can be +

  • Do a better job of recognizing when an ORDER BY clause can be implemented using indices - especially in cases where the ORDER BY clause contains terms from two or more tables in a join.

    @@ -705,7 +681,7 @@ SQLite version 3.7.13 adds support for WinRT and metro style applications for Microsoft Windows 8. The 3.7.13 release is coming sooner than is usual after the previous release in order to get - this new capability into the hands of developers. To use SQLite in + this new capability into the hands of developers. To use SQLite in a metro style application, compile with the -DSQLITE_OS_WINRT flag. Because of the increased application security and safety requirements of WinRT, all database @@ -716,7 +692,7 @@ the same on WinRT as it does on every other system.

    Also in this release: when a database is opened using URI filenames - and the mode=memory query parameter + and the mode=memory query parameter then the database is an in-memory database, just as if it had been named ":memory:". But, if shared cache mode is enabled, then all other database connections that specify the same URI filename @@ -744,7 +720,7 @@ is recommended. See the change summary for details.


  • 2012-03-20 - Version 3.7.11

    SQLite version 3.7.11 is a regularly scheduled maintenance release - which was rushed out early due to a + which was rushed out early due to a bug in the query optimizer introduced in the previous release. The bug is obscure - it changes a LEFT JOIN into an INNER JOIN in some cases when there is a 3-way join @@ -764,7 +740,7 @@

    The SQLITE_CONFIG_PCACHE mechanism has been replaced with SQLITE_CONFIG_PCACHE2. If you do not know what this mechanism - is (it is an extreme corner-case and is seldom used) then this + is (it is an extreme corner-case and is seldom used) then this change will not effect you in the least.

    The default schema format number for new database files has changed @@ -772,7 +748,7 @@ using schema format 4 for six years. But up unto now, the default schema format has been 1 so that older versions of SQLite could read and write databases generated by newer versions of SQLite. But those - older versions of SQLite have become so scarce now that it seems + older versions of SQLite have become so scarce now that it seems reasonable to make the new format the default.

    SQLite is changing some of the assumptions it makes above the behavior @@ -794,7 +770,7 @@ use this statement to tell SQLite how many pages of the database files it should hold in its cache at once. The total memory requirement would depend on the database page size. Now, if you give PRAGMA cache_size - a negative value -N, it will allocate roughly N + a negative value -N, it will allocate roughly N kibibytes of memory to cache, divided up according to page size. This enhancement allows programs to more easily control their memory usage.

    @@ -815,7 +791,7 @@ query-planner functionality formerly available using SQLITE_ENABLE_STAT2 is now available through SQLITE_ENABLE_STAT3. The enhanced query planning is still disabled by default. However, future releases of SQLite might - convert STAT3 from an enable-option to a disable-option so that it is + convert STAT3 from an enable-option to a disable-option so that it is available by default and is only omitted upon request.

    The FTS4 full-text search engine has been enhanced such that tokens in @@ -824,11 +800,11 @@ search string were simply ignored. Hence, if a legacy application was including "^" characters in FTS4 search strings, thinking that they would always be ignored, then those legacy applications might break with this - update. The fix is simply remove the "^" characters from the search + update. The fix is simply remove the "^" characters from the search string.

    See the change summary for additional changes associated - with this release. + with this release.


    2011-September-19 - Version 3.7.8

    SQLite version 3.7.8 is a quarterly maintenance release. Upgrading from versions 3.7.6.3, 3.7.7, or 3.7.7.1 is optional. Upgrading from other @@ -839,12 +815,12 @@ index for CREATE INDEX. The new algorithm does approximately the same number of comparisons and I/Os as before, but the I/Os are much more sequential and so runtimes are greatly reduced when the size of the - set being sorted is larger than the filesystem cache. The performance - improvement can be dramatic - orders of magnitude faster - for large CREATE INDEX commands. On the other hand, + set being sorted is larger than the filesystem cache. The performance + improvement can be dramatic - orders of magnitude faster + for large CREATE INDEX commands. On the other hand, the code is slightly slower (1% or 2%) for a small CREATE INDEX. Since CREATE INDEX is not an - operation that commonly occurs on a speed-critical path, we feel that + operation that commonly occurs on a speed-critical path, we feel that this tradeoff is a good one. The slight slowdown for small CREATE INDEX statements might be recovered in a future release. ORDER BY and GROUP BY operations should now be faster for all cases, large and small.

    @@ -852,7 +828,7 @@

    The query planner has been enhanced to do a better job of handling the DISTINCT keyword on SELECT statements.

    -

    There has been a lot of work on the default VFSes. The Unix VFS has +

    There has been a lot of work on the default VFSes. The unix VFS has been enhanced to include more overrideable system calls - a feature requested by Chromium to make it easier to build SQLite into a sandbox. The windows VFS has been enhanced to be more resistant to interference from @@ -881,13 +857,13 @@

    This release adds support for naming database files using URI filenames. URI filenames are disabled by default (for backwards compatibility) but applications are encouraged to enable them since incompatibilities are - likely to be exceedingly rare and the feature is useful. See the + likely to be exceedingly rare and the feature is useful. See the URI filename documentation for details.

    -

    Most of the other enhancements in this release involve +

    Most of the other enhancements in this release involve virtual tables. The virtual table interface has been enhanced to - support SAVEPOINT and ON CONFLICT clause processing, and the built-in - RTREE and FTS3/FTS4 have been augmented to take advantage of + support SAVEPOINT and ON CONFLICT clause processing, and the built-in + RTREE and FTS3/FTS4 have been augmented to take advantage of the new capability. This means, for example, that it is now possible to use the REPLACE command on FTS3/FTS4 and RTREE tables.

    @@ -910,7 +886,7 @@ release has not given any problems, so we expect this to be a very stable release.

    2011-05-19 - Version 3.7.6.3

    - SQLite version 3.7.6.3 is a patch release that fixes a + SQLite version 3.7.6.3 is a patch release that fixes a single bug associated with WAL mode. The bug has been in SQLite ever since WAL was added, but the problem is very obscure and so nobody has noticed @@ -940,7 +916,7 @@ during that transaction, appends them to the WAL, and sets the commit flag on the last page. Now, if SQLite comes under memory pressure, it might try to free up memory space by writing changed pages to the WAL - prior to the commit. We call this "spilling" the cache to WAL. There + prior to the commit. We call this "spilling" the cache to WAL. There is nothing wrong with spilling cache to WAL. But if the memory pressure is severe, it might be that by the time COMMIT is run, all changed pages for the transaction have already been spilled to WAL @@ -962,11 +938,11 @@

    Upgrading from version 3.7.6.1 is only needed on NetBSD.


    2011-04-13 - Version 3.7.6.1

    SQLite version 3.7.6.1 fixes a single bug in 3.7.6 that can cause a - segfault if SQLITE_FCNTL_SIZE_HINT is used on a Unix build that has + segfault if SQLITE_FCNTL_SIZE_HINT is used on a unix build that has SQLITE_ENABLE_LOCKING_MODE set to 0 and is compiled with HAVE_POSIX_FALLOCATE.

    -

    Upgrading from 3.7.6 is only needed for users effected by the +

    Upgrading from 3.7.6 is only needed for users effected by the configuration-specific bug described above. There are no other changes to the code.


    2011-04-12 - Version 3.7.6

    @@ -975,7 +951,7 @@ releases prior to 3.7.5 is recommended.

    2011-02-01 - Version 3.7.5

    SQLite version 3.7.5 is a regularly scheduled bi-monthly maintenance - release of SQLite. Due to the discovery and fix of + release of SQLite. Due to the discovery and fix of an obscure bug that could cause database corruption, upgrading from all prior releases of SQLite is recommended. This bug was found during code @@ -1007,11 +983,11 @@ release of SQLite. Upgrading from version 3.7.2 and version 3.7.3 is optional. Upgrading from all other SQLite releases is recommended.

    -

    This release features full-text search enhancements. The older +

    This release features full-text search enhancements. The older FTS3 virtual table is still fully supported, and should also run faster. In addition, the new FTS4 virtual table is added. FTS4 follows the same syntax as FTS3 but holds additional metadata which - facilitates some performance improvements and more advanced + facilitates some performance improvements and more advanced matchinfo() output. Look for further full-text search enhancements in subsequent releases.

    @@ -1020,7 +996,7 @@ more easily understand how SQLite is performing their queries.

    Thanks to an account from the folks at http://www.devio.us/, OpenBSD - has been added to the list of platforms upon which we + has been added to the list of platforms upon which we test SQLite prior to every release. That list of platforms now includes:

    @@ -1036,7 +1012,7 @@

    The previous release of SQLite (version 3.7.3) has proven to be very robust. The only serious issue discovered was ticket 80ba201079 that - describes an incorrect query result that can occur under very + describes an incorrect query result that can occur under very unusual circumstances. The ticket description contains details of the problem. Suffice it to say here that the problem is very obscure and is unlikely to effect most applications and so upgrading is optional. @@ -1047,14 +1023,14 @@ Upgrading from all other releases is recommended.

    This release adds two new interfaces (really just variations on existing - interfaces). The sqlite3_create_function_v2() interface adds a - destructor for the application-data pointer. The new + interfaces). The sqlite3_create_function_v2() interface adds a + destructor for the application-data pointer. The new sqlite3_soft_heap_limit64() interface allows the soft heap limit to - be set to a value greater than 231.

    + be set to a value greater than 231.

    The RTREE extension has been enhanced with the ability to have an application-defined query region. This might - be used, for example, to locate all objects within + be used, for example, to locate all objects within the field of view of a camera.

    The 3.7.3 release also includes some performance enhancements, including @@ -1066,7 +1042,7 @@ multiple times to partially reduce the size of a database file that contains many hundreds of unused database pages. The original bug reports together with links - to the patch that fixes it can be seen + to the patch that fixes it can be seen here.

    This bug has been in the code for at least a year and possibly longer. @@ -1076,7 +1052,7 @@

    The bug is impossible to hit without using incremental_vacuum and is very difficult to hit even with incremental_vacuum. And the kind of - corruption that the bug causes can usually be fixed + corruption that the bug causes can usually be fixed simply by running VACUUM. Nevertheless, because the bug can result in database corruption, it is recommended that all SQLite users upgrade to version 3.7.2 or later. @@ -1092,7 +1068,7 @@ application-visible effects. The purpose was to reorganize the code in ways that make it easier to prove correctness.

    -

    The 3.7.1 release adds new experimental methods for obtained more +

    The 3.7.1 release adds new experimental methods for obtained more detailed memory usage information and for controlling database file fragmentation. And the query planner now does a better job of optimizing the LIKE and GLOB operators.

    @@ -1121,7 +1097,7 @@ of WAL mode.

    2010-03-30 - Version 3.6.23.1

    SQLite version 3.6.23.1 is a patch release to fix a bug in the - offsets() function of FTS3 at the request of the Mozilla. + offsets() function of FTS3 at the request of the Mozilla.

    2010-03-09 - Version 3.6.23

    SQLite version 3.6.23 is a regular bimonthly release of SQLite. Upgrading from the prior release is purely optional.

    @@ -1144,7 +1120,7 @@ an anachronism.

    2010-01-06 - Version 3.6.22

    SQLite version 3.6.22 is a bug-fix release. Two bugs have been fixed - that might cause incorrect query results. + that might cause incorrect query results.
    • Ticket 31338dca7e describes a @@ -1168,7 +1144,7 @@ a certain set of traces, this version uses 12% fewer CPU instructions than the previous release (as measured by Valgrind). In addition, the FTS3 extension has been through an extensive cleanup and rework and - the sqlite3_trace() interface has been modified to insert + the sqlite3_trace() interface has been modified to insert bound parameter values into its output.

    2009-11-04 - Version 3.6.20

    SQLite version 3.6.20 is a general maintenance release. The @@ -1225,14 +1201,14 @@ bugs are serious and all are obscure, so upgrading is optional.

    The SQLite core continues to have 100% branch test coverage - and so despite the many changes in this release, the developers + and so despite the many changes in this release, the developers believe that this version of SQLite is stable and ready for production use.


    2009-08-10 - Version 3.6.17

    This is a monthly maintenance release with a focus of bug fixes, performance improvements, and increased test coverage. This is the first release of SQLite since 100% branch test coverage - was achieved on the SQLite core.

    + was achieved on the SQLite core.

    In addition, a new interface sqlite3_strnicmp() is provided for the convenience of extension writers.

    @@ -1245,18 +1221,18 @@ (exclusive of the VFS backend and of extensions such as FTS3 and RTREE) when compiled for SuSE 10.1 Linux on x86. The SQLite developers pledge to maintain branch test coverage at 100% in all future releases. - Ongoing work will strive for 100% branch test coverage on the + Ongoing work will strive for 100% branch test coverage on the operating-system backends and extensions as well.

    2009-06-27 - Version 3.6.16

    SQLite version 3.6.16 is another general maintenance release containing performance and robustness enhancements. A single notable bug was fixed - (ticket #3929). This bug can cause INSERT or UPDATE statements to fail + (ticket #3929). This bug cause cause INSERT or UPDATE statements to fail on indexed tables that have AFTER triggers that modify the same table and index.

    2009-06-15 - Version 3.6.15

    SQLite version 3.6.15 is a general maintenance release containing performance and robustness enhancements and fixes for various obscure - bugs. + bugs.

    2009-05-25 - Version 3.6.14.2

    SQLite version 3.6.14.2 fixes an obscure bug in the code generator (ticket #3879) @@ -1272,7 +1248,7 @@ users of 3.6.14 and 3.5.14.1 upgrade to this release.

    2009-05-19 - Version 3.6.14.1

    SQLite version 3.6.14.1 is a patch release to version 3.6.14 with - minimal changes that fixes three bugs. Upgrading is only necessary + minimal changes that fixes three bugs. Upgrading is only necessary for users who are impacted by one or more of those bugs.

    2009-05-07 - Version 3.6.14

    SQLite version 3.6.14 provides new performance enhancements in @@ -1284,7 +1260,7 @@ in the WHERE clause are now able to use indexing.

    A new optional asynchronous I/O backend is available for - Unix and Windows. The asynchronous backend gives the illusion of faster + unix and windows. The asynchronous backend gives the illusion of faster response time by pushing slow write operations into a background thread. The tradeoff for faster response time is that more memory is required (to hold the content of the pending writes) and if a power failure or @@ -1319,7 +1295,7 @@ This release fixes a bug that was introduced into SQLite version 3.6.4 and that can cause database corruption in obscure cases. This bug has never been seen in the wild; it was first detected by internal stress - tests and required substantial analysis before it could be shown to + tests and required substantial analysis before it could be shown to potentially lead to corruption. So we feel that SQLite versions 3.6.4, 3.6.5, and 3.6.6 are safe to use for development work. But upgrading to this patch release or later is recommended prior to deploying @@ -1328,7 +1304,7 @@

    We have taken the unusual step of issuing a patch release in order to get the fix for this bug into circulation quickly. SQLite version 3.6.7 will continue on its normal path of development with an anticipated - release in mid December. + release in mid December.


    2008-11-19 - Version 3.6.6

    SQLite version 3.6.5 is released. This is a quick turn-around release that fixes a bug in virtual tables and FTS3 that snuck into @@ -1336,7 +1312,7 @@ application-defined page cache mechanism.

    2008-11-12 - Version 3.6.5

    SQLite version 3.6.5 is released. There are various minor feature - enhancements and numerous obscure bug fixes. + enhancements and numerous obscure bug fixes. The change log contains the details. Upgrading is optional.

    2008-11-01 - Bloomberg Joins SQLite Consortium

    @@ -1355,13 +1331,13 @@ SQLite version 3.6.2 contains rewrites of the page-cache subsystem and the procedures for matching identifiers to table columns in SQL statements. These changes are designed to better modularize the code and make it more - maintainable and reliable moving forward. Nearly 5000 non-comment lines + maintainable and reliable moving forward. Nearly 5000 non-comment lines of core code (about 11.3%) have changed from the previous release. Nevertheless, there should be no application-visible changes, other than bug fixes.

    2008-08-06 - Version 3.6.1

    SQLite version 3.6.1 is a stabilization and performance enhancement - release. + release.

    2008-07-16 - Version 3.6.0 beta

    Version 3.6.0 makes changes to the VFS object in order to make SQLite more easily portable to a wider variety of platforms. @@ -1386,7 +1362,7 @@ design. These incompatibilities will only effect programmers who write their own custom VFS layers (typically embedded device builders). The planned VFS changes will be much smaller - than the changes that occurred on the + than the changes that occurred on the 3.4.2 to 3.5.0 transaction that occurred last September.

    @@ -1405,7 +1381,7 @@

    This release of SQLite is considered stable and ready for production use.


    2008-03-17 - Version 3.5.7

    - Version 3.5.7 fixes several minor and obscure bugs, especially + Version 3.5.7 fixes several minor and obscure bugs, especially in the autoconf-generated makefile. Upgrading is optional. This release of SQLite is considered stable and ready for production use.

    2008-02-06 - Version 3.5.6

    @@ -1437,27 +1413,27 @@ Symbian as charter members. As noted in the press release, the Consortium's goal is to promote the continuing vitality and - independence of SQLite. + independence of SQLite.

    2007-11-27 - Version 3.5.3

    This is an incremental release that fixes several minor problems. Upgrading is optional. If Version 3.5.2 or 3.5.1 is working fine for you, then there is no pressing need to change to 3.5.3.

    -

    The prebuilt binaries and the amalgamation found on the +

    The prebuilt binaries and the amalgamation found on the download page include the FTS3 fulltext search extension module. We are doing this on an experimental basis and are not promising to provide prebuilt binaries with FTS3 in the future.


    2007-11-05 - Version 3.5.2

    This is an incremental release that fixes several minor problems, - adds some obscure features, and provides some performance tweaks. + adds some obscure features, and provides some performance tweaks. Upgrading is optional.

    The experimental compile-time option SQLITE_OMIT_MEMORY_ALLOCATION is no longer supported. On the other hand, it is now possible to compile SQLite so that it uses a static array for all its dynamic memory allocation needs and never calls - malloc. Expect to see additional radical changes to the memory + malloc. Expect to see additional radical changes to the memory allocation subsystem in future releases.


    2007-10-04 - Version 3.5.1

    Fix a long-standing bug that might cause database corruption if a @@ -1470,7 +1446,7 @@

    2007-09-04 - Version 3.5.0 alpha

    The OS interface layer and the memory allocation subsystems in SQLite have been reimplemented. The published API is largely unchanged - but the (unpublished) OS interface has been modified extensively. + but the (unpublished) OS interface has been modified extensively. Applications that implement their own OS interface will require modification. See 34to35.html for details.

    @@ -1480,24 +1456,24 @@ the user community time to test and evaluate the changes before we freeze the new design.

    2007-08-13 - Version 3.4.2

    - While stress-testing the + While stress-testing the soft_heap_limit feature, a bug that could lead to database corruption was discovered and fixed. - Though the consequences of this bug are severe, the chances of hitting + Though the consequences of this bug are severe, the chances of hitting it in a typical application are remote. Upgrading is recommended - only if you use the + only if you use the sqlite3_soft_heap_limit interface.

    2007-07-20 - Version 3.4.1

    This release fixes a bug in VACUUM that - can lead to database corruption. The bug was introduced in version + can lead to database corruption. The bug was introduced in version 3.3.14. Upgrading is recommended for all users. Also included are a slew of other more routine enhancements and bug fixes.

    2007-06-18 - Version 3.4.0

    - This release fixes two separate bugs either of which + This release fixes two separate bugs either of which can lead to database corruption. Upgrading is strongly recommended. If you must continue using an older version of SQLite, please at least read about how to avoid these bugs @@ -1506,7 +1482,7 @@ This release also adds explicit limits on the sizes and quantities of things SQLite will handle. The new limits might causes compatibility problems for existing applications that - use excessively large strings, BLOBs, tables, or SQL statements. + use excessively large strings, BLOBs, tables, or SQL statements. The new limits can be increased at compile-time to work around any problems that arise. Nevertheless, the version number of this release is 3.4.0 instead of 3.3.18 in order to call attention to the possible @@ -1515,7 +1491,7 @@ There are also new features, including incremental BLOB I/O and incremental vacuum. - See the change log + See the change log for additional information.

    2007-04-25 - Version 3.3.17

    This version fixes a bug in the forwards-compatibility logic of SQLite @@ -1525,11 +1501,11 @@ use, it probably does not matter.

    2007-04-18 - Version 3.3.16

    Performance improvements added in 3.3.14 but mistakenly turned off - in 3.3.15 have been reinstated. A bug has been fixed that prevented + in 3.3.15 have been reinstated. A bug has been fixed that prevented VACUUM from running if a NULL value was in a UNIQUE column.

    2007-04-09 - Version 3.3.15

    An annoying bug introduced in 3.3.14 has been fixed. There are - also many enhancements to the test suite. + also many enhancements to the test suite.

    2007-04-02 - Version 3.3.14

    This version focuses on performance improvements. If you recompile the amalgamation using GCC option -O3 (the precompiled binaries @@ -1539,7 +1515,7 @@ adds support for exclusive access mode.

    2007-02-13 - Version 3.3.13

    - This version fixes a subtle bug in the ORDER BY optimizer that can + This version fixes a subtle bug in the ORDER BY optimizer that can occur when using joins. There are also a few minor enhancements. Upgrading is recommended.

    2007-01-27 - Version 3.3.12

    @@ -1566,7 +1542,7 @@ shell and enhancements to the query optimizer. Upgrading is recommended.

    2006-10-09 - Version 3.3.8

    - Version 3.3.8 adds support for full-text search using the + Version 3.3.8 adds support for full-text search using the FTS1 module. There are also minor bug fixes. Upgrade only if you want to try out the new full-text search capabilities or if you are having problems with 3.3.7. @@ -1579,8 +1555,9 @@ one of the obscure bugs that have been fixed or if you want to try out the new features.

    2006-06-19 - New Book About SQLite

    - The Definitive Guide to SQLite, - a 2nd edition book by Mike Owens and Grant Allen, + The Definitive Guide to SQLite, + a new book by + Mike Owens is now available from Apress. The books covers the latest SQLite internals as well as the native C interface and bindings for PHP, Python, @@ -1594,7 +1571,7 @@ provides some minor new features and performance enhancements. Upgrade only if you are having problems or need one of the new features.

    2006-02-11 - Version 3.3.4

    - This release fixes several bugs, including a + This release fixes several bugs, including a blunder that might cause a deadlock on multithreaded systems. Anyone using SQLite in a multithreaded environment should probably upgrade.

    2006-01-31 - Version 3.3.3 stable

    @@ -1714,8 +1691,8 @@

    Version 3.1.2 is also the first stable release of the 3.1 series. SQLite 3.1 features added support for correlated subqueries, autovacuum, autoincrement, ALTER TABLE, and - other enhancements. See the - release notes + other enhancements. See the + release notes for version 3.1.0 for a detailed description of the changes available in the 3.1 series.


    2005-02-01 - Version 3.1.1 (beta) Released

    @@ -1723,7 +1700,7 @@ website. Version 3.1.1 is fully backwards compatible with the 3.0 series and features many new features including Autovacuum and correlated subqueries. The - release notes + release notes From version 3.1.0 apply equally to this release beta. A stable release is expected within a couple of weeks.

    2005-01-21 - Version 3.1.0 (alpha) Released

    @@ -1731,7 +1708,7 @@ website. Version 3.1.0 is fully backwards compatible with the 3.0 series and features many new features including Autovacuum and correlated subqueries. See the - release notes + release notes for details.

    This is an alpha release. A beta release is expected in about a week @@ -1739,9 +1716,9 @@


    2004-11-09 - SQLite at the 2004 International PHP Conference

    There was a talk on the architecture of SQLite and how to optimize SQLite queries at the 2004 International PHP Conference in Frankfurt, - Germany.
    - Obsolete URL: http://www.sqlite.org/php2004/page-001.html
    - Slides from that talk are available. + Germany. + + Slides from that talk are available.

    2004-10-11 - Version 3.0.8

    Version 3.0.8 of SQLite contains several code optimizations and minor bug fixes and adds support for DEFERRED, IMMEDIATE, and EXCLUSIVE @@ -1752,13 +1729,13 @@ There will be a talk on the use of SQLite in Tcl/Tk at the 11th Tcl/Tk Conference this week in New Orleans. Visit http://www.tcl-lang.org/community/tcl2004/ - for details.
    - Obsolete URL: http://www.sqlite.org/tclconf2004/page-001.html
    - Slides from the talk are available. + for details. + + Slides from the talk are available.

    2004-09-18 - Version 3.0.7

    Version 3.0 has now been in use by multiple projects for several months with no major difficulties. We consider it stable and - ready for production use. + ready for production use.

    2004-09-02 - Version 3.0.6 (beta)

    Because of some important changes to sqlite3_step(), we have decided to @@ -1780,7 +1757,7 @@ a final or stable release.

    Version 3.0 adds support for internationalization and a new - more compact file format. + more compact file format. Details. The API and file format have been fixed since 3.0.2. All regression tests pass (over 100000 tests) and the test suite @@ -1797,7 +1774,7 @@


    2004-06-30 - Version 3.0.2 (beta) Released

    The first beta release of SQLite version 3.0 is now available. Version 3.0 adds support for internationalization and a new - more compact file format. + more compact file format. Details. As of this release, the API and file format are frozen. All regression tests pass (over 100000 tests) and the test suite @@ -1824,7 +1801,7 @@ Additional information.

    Our intent is to freeze the file format and API on 2004-07-01. - Users are encouraged to review and evaluate this alpha release carefully + Users are encouraged to review and evaluate this alpha release carefully and submit any feedback prior to that date.

    The 2.8 series of SQLite will continue to be supported with bug @@ -1850,5 +1827,4 @@

    Plans are to continue to support SQLite version 2.8 with bug fixes. But all new development will occur in version 3.0.


    -

    This page last modified on 2023-02-27 02:07:35 UTC

    diff -Nru sqlite3-3.42.0/www/omitted.html sqlite3-3.44.0-0/www/omitted.html --- sqlite3-3.42.0/www/omitted.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/omitted.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQL Features That SQLite Does Not Implement

    @@ -131,7 +107,10 @@ -
    Complete ALTER TABLE support  +
    RIGHT and FULL OUTER JOIN  + LEFT OUTER JOIN is implemented, but not RIGHT OUTER JOIN or + FULL OUTER JOIN. +
    Complete ALTER TABLE support  Only the RENAME TABLE, ADD COLUMN, RENAME COLUMN, and DROP COLUMN variants of the ALTER TABLE command are supported. Other kinds of ALTER TABLE operations such as @@ -153,5 +132,4 @@ for an embedded database engine.
    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/onefile.html sqlite3-3.44.0-0/www/onefile.html --- sqlite3-3.42.0/www/onefile.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/onefile.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Single-file Cross-platform Database

    @@ -164,5 +140,4 @@ but those extra files are not part of the steady-state database. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/opcode.html sqlite3-3.44.0-0/www/opcode.html --- sqlite3-3.42.0/www/opcode.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/opcode.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -160,7 +136,7 @@

    SQLite works by translating SQL statements into bytecode and then running that bytecode in a virtual machine. This document -describes how the bytecode engine works. +describes how how the bytecode engine works.

    This document describes SQLite internals. The information provided here is not needed for routine application development using SQLite. @@ -217,8 +193,8 @@ that corresponds to the version of SQLite that ran the EXPLAIN. Otherwise, the description of the opcodes may not be accurate. This document is derived from SQLite - version 3.42.0 check-in -831d0fb2836b7 dated 2023-05-16. + version 3.36.0 check-in +5c9a6c06871cb dated 2021-06-18. @@ -441,20 +417,20 @@

    4. The Opcodes

    -

    There are currently 186 +

    There are currently 179 opcodes defined by the virtual machine. All currently defined opcodes are described in the table below. This table was generated automatically by scanning the source code from the file -vdbe.c. +vdbe.c.

    Remember: The VDBE opcodes are not part of the interface definition for SQLite. The number of opcodes and their names and meanings change from one release of SQLite to the next. The opcodes shown in the table below are valid for SQLite - version 3.42.0 check-in -831d0fb2836b7 dated 2023-05-16. + version 3.36.0 check-in +5c9a6c06871cb dated 2021-06-18. @@ -561,26 +537,6 @@

    This instruction causes the VM to halt. -BeginSubrtn -Mark the beginning of a subroutine that can be entered in-line -or that can be called using Gosub. The subroutine should -be terminated by an Return instruction that has a P1 operand that -is the same as the P2 operand to this opcode and that has P3 set to 1. -If the subroutine is entered in-line, then the Return will simply -fall through. But if the subroutine is entered using Gosub, then -the Return will jump back to the first instruction after the Gosub.

    - -

    This routine works by loading a NULL into the P2 register. When the -return address register contains a NULL, the Return instruction is -a no-op that simply falls through to the next instruction (assuming that -the Return opcode has a P3 value of 1). Thus if the subroutine is -entered in-line, then the Return will cause in-line execution to -continue. But if the subroutine is entered via Gosub, then the -Return will cause a return to the address following the Gosub.

    - -

    This opcode is identical to Null. It has a different name -only to make the byte code easier to read and verify. - BitAnd Take the bit-wise AND of the values in register P1 and P2 and store the result in register P3. @@ -598,8 +554,7 @@ Blob P4 points to a blob of data P1 bytes long. Store this -blob in register P2. If P4 is a NULL pointer, then construct -a zero-filled blob that is P1 bytes long in P2. +blob in register P2. Cast Force the value in register P1 to be the type defined by P2.

    @@ -624,6 +579,15 @@ completes into mem[P3+2]. However on an error, mem[P3+1] and mem[P3+2] are initialized to -1. +ChngCntRow +Output value in register P1 as the chance count for a DML statement, +due to the "PRAGMA count_changes=ON" setting. Or, if there was a +foreign key error in the statement, trigger the error now.

    + +

    This opcode is a variant of ResultRow that checks the foreign key +immediate constraint count and throws an error if the count is +non-zero. The P2 opcode must be 1. + Clear Delete all contents of the database table or index whose root page in the database file is given by P1. But, unlike Destroy, do not @@ -644,9 +608,6 @@ Close a cursor previously opened as P1. If P1 is not currently open, this instruction is a no-op. -ClrSubtype -Clear the subtype from register P1. - CollSeq P4 is a pointer to a CollSeq object. If the next call to a user function or aggregate calls sqlite3GetFuncCollSeq(), this collation sequence will @@ -665,7 +626,7 @@ Interpret the data that cursor P1 points to as a structure built using the MakeRecord instruction. (See the MakeRecord opcode for additional information about the format of the data.) Extract the P2-th column -from this record. If there are less than (P2+1) +from this record. If there are less that (P2+1) values in the record, extract a NULL.

    The value extracted is stored in register P3.

    @@ -674,12 +635,10 @@ if the P4 argument is a P4_MEM use the value of the P4 argument as the result.

    -

    If the OPFLAG_LENGTHARG bit is set in P5 then the result is guaranteed -to only be used by the length() function or the equivalent. The content -of large blobs is not loaded, thus saving CPU cycles. If the -OPFLAG_TYPEOFARG bit is set then the result will only be used by the -typeof() function or the IS NULL or IS NOT NULL operators or the -equivalent. In this case, all content loading can be omitted. +

    If the OPFLAG_LENGTHARG and OPFLAG_TYPEOFARG bits are set on P5 then +the result is guaranteed to only be used as the argument of a length() +or typeof() function, respectively. The loading of large blobs can be +skipped for length() and all content loading can be skipped for typeof(). ColumnsUsed This opcode (which only exists if SQLite was compiled with @@ -706,9 +665,7 @@

    The comparison is a sort comparison, so NULLs compare equal, NULLs are less than numbers, numbers are less than strings, -and strings are less than blobs.

    - -

    This opcode must be immediately followed by an Jump opcode. +and strings are less than blobs. Concat Add the text in register P1 onto the end of the text in @@ -724,11 +681,6 @@ Copy Make a copy of registers P1..P1+P3 into registers P2..P2+P3.

    -

    If the 0x0002 bit of P5 is set then also clear the MEM_Subtype flag in the -destination. The 0x0001 bit of P5 indicates that this Copy opcode cannot -be merged. The 0x0001 bit is used by the query planner and does not -come into play during query execution.

    -

    This instruction makes a deep copy of the value. A duplicate is made of any string or blob constant. See also SCopy. @@ -933,37 +885,11 @@ that might help the statement run faster but which does not affect the correctness of operation. -Filter -Compute a hash on the key contained in the P4 registers starting -with r[P3]. Check to see if that hash is found in the -bloom filter hosted by register P1. If it is not present then -maybe jump to P2. Otherwise fall through.

    - -

    False negatives are harmless. It is always safe to fall through, -even if the value is in the bloom filter. A false negative causes -more CPU cycles to be used, but it should still yield the correct -answer. However, an incorrect answer may well arise from a -false positive - if the jump is taken when it should fall through. - -FilterAdd -Compute a hash on the P4 registers starting with r[P3] and -add that hash to the bloom filter contained in r[P1]. - FinishSeek If cursor P1 was previously moved via DeferredSeek, complete that seek operation now, without further delay. If the cursor seek has already occurred, this instruction is a no-op. -FkCheck -Halt with an SQLITE_CONSTRAINT error if there are any unresolved -foreign key constraint violations. If there are no foreign key -constraint violations, this is a no-op.

    - -

    FK constraint violations are also checked when the prepared statement -exits. This opcode is used to raise foreign key constraint errors prior -to returning results such as a row change count or the result of a -RETURNING clause. - FkCounter Increment a "constraint counter" by P2 (P2 may be negative or positive). If P1 is non-zero, the database constraint counter is incremented @@ -1082,8 +1008,7 @@ an UPDATE or DELETE statement and the index entry to be updated or deleted is not found. For some uses of IdxDelete (example: the EXCEPT operator) it does not matter that no matching -entry is found. For those cases, P5 is zero. Also, do not raise -this (self-correcting and non-critical) error if in writable_schema mode. +entry is found. For those cases, P5 is zero. IdxGE The P4 register values beginning with P3 form an unpacked index @@ -1194,8 +1119,7 @@ in P1 is NULL then take the jump if and only if P3 is non-zero. IfNotOpen -If cursor P1 is not open or if P1 is set to a NULL row using the -NullRow opcode, then jump to instruction P2. Otherwise, fall through. +If cursor P1 is not open, jump to instruction P2. Otherwise, fall through. IfNotZero Register P1 must contain an integer. If the content of register P1 is @@ -1207,9 +1131,7 @@ Check the cursor P1 to see if it is currently pointing at a NULL row. If it is, then set register P3 to NULL and jump immediately to P2. If P1 is not on a NULL row, then fall through without making any -changes.

    - -

    If P1 is not an open cursor, then this opcode is a no-op. +changes. IfPos Register P1 must contain an integer. @@ -1341,34 +1263,6 @@

  • If P3==1 and P4==0 then r[P2] := r[P1] IS NOT FALSE -IsType -Jump to P2 if the type of a column in a btree is one of the types specified -by the P5 bitmask.

    - -

    P1 is normally a cursor on a btree for which the row decode cache is -valid through at least column P3. In other words, there should have been -a prior Column for column P3 or greater. If the cursor is not valid, -then this opcode might give spurious results. -The the btree row has fewer than P3 columns, then use P4 as the -datatype.

    - -

    If P1 is -1, then P3 is a register number and the datatype is taken -from the value in that register.

    - -

    P5 is a bitmask of data types. SQLITE_INTEGER is the least significant -(0x01) bit. SQLITE_FLOAT is the 0x02 bit. SQLITE_TEXT is 0x04. -SQLITE_BLOB is 0x08. SQLITE_NULL is 0x10.

    - -

    WARNING: This opcode does not reliably distinguish between NULL and REAL -when P1>=0. If the database contains a NaN value, this opcode will think -that the datatype is REAL when it should be NULL. When P1<0 and the value -is already stored in register P3, then this opcode does reliably -distinguish between NULL and REAL. The problem only arises then P1>=0.

    - -

    Take the jump to address P2 if and only if the datatype of the -value determined by P1 and P3 corresponds to one of the bits in the -P5 bitmask.

    - JournalMode Change the journal mode of database P1 to P3. P3 must be one of the PAGER_JOURNALMODE_XXX values. If changing between the various rollback @@ -1381,10 +1275,8 @@ Jump Jump to the instruction at address P1, P2, or P3 depending on whether -in the most recent Compare instruction the P1 vector was less than, -equal to, or greater than the P2 vector, respectively.

    - -

    This opcode must immediately follow an Compare opcode. +in the most recent Compare instruction the P1 vector was less than +equal to, or greater than the P2 vector, respectively. Last The next use of the Rowid or Column or Prev instruction for P1 @@ -1531,6 +1423,9 @@ omitted if that index had been unique. P3 is usually 0. P3 is always either 0 or 1.

    +

    P4 is always of type P4_ADVANCE. The function pointer points to +sqlite3BtreeNext().

    +

    If P5 is positive and the jump is taken, then event counter number P5-1 in the prepared statement is incremented.

    @@ -1620,10 +1515,7 @@ NullRow Move the cursor P1 to a null row. Any Column operations that occur while the cursor is on the null row will always -write a NULL.

    - -

    If cursor P1 is not previously opened, open it now to a special -pseudo-cursor that always returns NULL for every column. +write a NULL. Offset Store in register r[P3] the byte offset into the database file that is the @@ -1640,7 +1532,7 @@ OffsetLimit This opcode performs a commonly used computation associated with -LIMIT and OFFSET processing. r[P1] holds the limit counter. r[P3] +LIMIT and OFFSET process. r[P1] holds the limit counter. r[P3] holds the offset counter. The opcode computes the combined value of the LIMIT and OFFSET and stores that value in r[P2]. The r[P2] value computed is the total number of rows that will need to be @@ -1812,8 +1704,9 @@ Set the permutation used by the Compare operator in the next instruction. The permutation is stored in the P4 operand.

    -

    The permutation is only valid for the next opcode which must be -an Compare that has the OPFLAG_PERMUTE bit set in P5.

    +

    The permutation is only valid until the next Compare that has +the OPFLAG_PERMUTE bit set in P5. Typically the Permutation should +occur immediately prior to the Compare.

    The first integer in the P4 integer array is the length of the array and does not become part of the permutation. @@ -1836,6 +1729,9 @@ omitted if that index had been unique. P3 is usually 0. P3 is always either 0 or 1.

    +

    P4 is always of type P4_ADVANCE. The function pointer points to +sqlite3BtreePrevious().

    +

    If P5 is positive and the jump is taken, then event counter number P5-1 in the prepared statement is incremented. @@ -1976,25 +1872,8 @@ the result row. Return -Jump to the address stored in register P1. If P1 is a return address -register, then this accomplishes a return from a subroutine.

    - -

    If P3 is 1, then the jump is only taken if register P1 holds an integer -values, otherwise execution falls through to the next opcode, and the -Return becomes a no-op. If P3 is 0, then register P1 must hold an -integer or else an assert() is raised. P3 should be set to 1 when -this opcode is used in combination with BeginSubrtn, and set to 0 -otherwise.

    - -

    The value in register P1 is unchanged by this opcode.

    - -

    P2 is not used by the byte-code engine. However, if P2 is positive -and also less than the current address, then the "EXPLAIN" output -formatter in the CLI will indent all opcodes from the P2 opcode up -to be not including the current Return. P2 should be the first opcode -in the subroutine from which this opcode is returning. Thus the P2 -value is a byte-code indentation hint. See tag-20220407a in -wherecode.c and shell.c. +Jump to the next instruction after the address in register P1. After +the jump, register P1 becomes undefined. Rewind The next use of the Rowid or Column or Next instruction for P1 @@ -2003,9 +1882,6 @@ If the table or index is not empty, fall through to the following instruction.

    -

    If P2 is zero, that is an assertion that the P1 table is never -empty and hence the jump will never be taken.

    -

    This opcode leaves the cursor configured to move in forward order, from the beginning toward the end. In other words, the cursor is configured to use Next, not Prev. @@ -2237,8 +2113,8 @@

    This opcode uses the P1 through P4 operands of the subsequent SeekGE. In the text that follows, the operands of the subsequent SeekGE opcode are denoted as SeekOP.P1 through SeekOP.P4. Only -the P1, P2 and P5 operands of this opcode are also used, and are called -This.P1, This.P2 and This.P5.

    +the P1 and P2 operands of this opcode are also used, and are called +This.P1 and This.P2.

    This opcode helps to optimize IN operators on a multi-column index where the IN operator is on the later terms of the index by avoiding @@ -2248,51 +2124,29 @@

    The SeekGE.P3 and SeekGE.P4 operands identify an unpacked key which is the desired entry that we want the cursor SeekGE.P1 to be pointing -to. Call this SeekGE.P3/P4 row the "target".

    +to. Call this SeekGE.P4/P5 row the "target".

    If the SeekGE.P1 cursor is not currently pointing to a valid row, then this opcode is a no-op and control passes through into the SeekGE.

    If the SeekGE.P1 cursor is pointing to a valid row, then that row might be the target row, or it might be near and slightly before the -target row, or it might be after the target row. If the cursor is -currently before the target row, then this opcode attempts to position -the cursor on or after the target row by invoking sqlite3BtreeStep() -on the cursor between 1 and This.P1 times.

    - -

    The This.P5 parameter is a flag that indicates what to do if the -cursor ends up pointing at a valid row that is past the target -row. If This.P5 is false (0) then a jump is made to SeekGE.P2. If -This.P5 is true (non-zero) then a jump is made to This.P2. The P5==0 -case occurs when there are no inequality constraints to the right of -the IN constraing. The jump to SeekGE.P2 ends the loop. The P5!=0 case -occurs when there are inequality constraints to the right of the IN -operator. In that case, the This.P2 will point either directly to or -to setup code prior to the IdxGT or IdxGE opcode that checks for -loop terminate.

    - -

    Possible outcomes from this opcode:

      - -

    1. If the cursor is initally not pointed to any valid row, then -fall through into the subsequent SeekGE opcode.

      - -

    2. If the cursor is left pointing to a row that is before the target -row, even after making as many as This.P1 calls to -sqlite3BtreeNext(), then also fall through into SeekGE.

      - -

    3. If the cursor is left pointing at the target row, either because it -was at the target row to begin with or because one or more -sqlite3BtreeNext() calls moved the cursor to the target row, -then jump to This.P2..,

      - -

    4. If the cursor started out before the target row and a call to -to sqlite3BtreeNext() moved the cursor off the end of the index -(indicating that the target row definitely does not exist in the -btree) then jump to SeekGE.P2, ending the loop.

      - -

    5. If the cursor ends up on a valid row that is past the target row -(indicating that the target row does not exist in the btree) then -jump to SeekOP.P2 if This.P5==0 or to This.P2 if This.P5>0. +target row. This opcode attempts to position the cursor on the target +row by, perhaps by invoking sqlite3BtreeStep() on the cursor +between 0 and This.P1 times.

      + +

      There are three possible outcomes from this opcode:

        + +

      1. If after This.P1 steps, the cursor is still pointing to a place that +is earlier in the btree than the target row, then fall through +into the subsquence SeekGE opcode.

        + +

      2. If the cursor is successfully moved to the target row by 0 or more +sqlite3BtreeNext() calls, then jump to This.P2, which will land just +past the IdxGT or IdxGE opcode that follows the SeekGE.

        + +

      3. If the cursor ends up past the target row (indicating the the target +row does not exist in the btree) then jump to SeekOP.P2.
      Sequence @@ -2477,30 +2331,6 @@ halts. The sqlite3_step() wrapper function might then reprepare the statement and rerun it from the beginning. -TypeCheck -Apply affinities to the range of P2 registers beginning with P1. -Take the affinities from the Table object in P4. If any value -cannot be coerced into the correct type, then raise an error.

      - -

      This opcode is similar to Affinity except that this opcode -forces the register type to the Table column type. This is used -to implement "strict affinity".

      - -

      GENERATED ALWAYS AS ... STATIC columns are only checked if P3 -is zero. When P3 is non-zero, no type checking occurs for -static generated columns. Virtual columns are computed at query time -and so they are never checked.

      - -

      Preconditions:

      - -

        -
      • P2 should be the number of non-virtual columns in the -table of P4. -
      • Table P4 should be a STRICT table. -

      - -

      If any precondition is false, an assertion fault occurs. - Vacuum Vacuum the entire database P1. P1 is 0 for "main", and 2 or more for an attached database. The "temp" database may not be vacuumed.

      @@ -2560,14 +2390,6 @@

      A jump is made to P2 if the result set after filtering would be empty. -VInitIn -Set register P2 to be a pointer to a ValueList object for cursor P1 -with cache register P3 and output register P3+1. This ValueList object -can be used as the first argument to sqlite3_vtab_in_first() and -sqlite3_vtab_in_next() to extract all of the values stored in the P1 -cursor. Register P3 is used to hold the values returned by -sqlite3_vtab_in_first() and sqlite3_vtab_in_next(). - VNext Advance virtual table P1 to the next row in its result set and jump to instruction P2. Or, if the virtual table has reached @@ -2628,5 +2450,4 @@

  • -

    This page last modified on 2022-08-10 18:45:48 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/optoverview.html sqlite3-3.44.0-0/www/optoverview.html --- sqlite3-3.42.0/www/optoverview.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/optoverview.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -147,7 +123,6 @@ - @@ -183,8 +158,9 @@ Given a single SQL statement, there might be dozens, hundreds, or even thousands of ways to implement that statement, depending on the complexity of the statement itself and of the underlying database schema. The - task of the query planner is to select the algorithm that minimizes - disk I/O and CPU overhead. + task of the query planner is to select an algorithm from among the many + choices that provides the answer with a minimum of disk I/O and CPU + overhead.

    @@ -218,7 +194,7 @@

    All terms of the WHERE clause are analyzed to see if they can be satisfied using indexes. - To be usable by an index a term must usually be of one of the following + To be usable by an index a term must be of one of the following forms:

    
    @@ -236,8 +212,6 @@
       column IN (expression-list)
       column IN (subquery)
       column IS NULL
    -  column LIKE pattern
    -  column GLOB pattern
     

    @@ -273,7 +247,6 @@ used in the foregoing text, one can substitute "indexed expression" (meaning a copy of the expression that appears in the CREATE INDEX statement) and everything will work the same. - @@ -709,7 +682,7 @@ exactly the same thing on inner joins.

    - For an OUTER JOIN the situation is more complex. The following + For a LEFT OUTER JOIN the situation is more complex. The following two queries are not equivalent:

    SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.x=tab2.y;
    @@ -1226,7 +1199,7 @@
     
       
  • If the sub-query is a compound SELECT, then -
      +
      1. all compound operators must be UNION ALL, and
      2. no terms with the subquery compound may be aggregate or DISTINCT, and @@ -1305,8 +1278,7 @@ the result must be stored for a transient table. Also, because the co-routine does not need to run to completion before the outer query begins its work, the first rows of output can appear much sooner, and if - the overall query is abandoned before it has finished, less work is done - overall. + the overall query is aborted, less work is done overall.

        On the other hand, if the result of the subquery must be scanned multiple @@ -1442,29 +1414,6 @@ appears in the names of internal indexes for legacy reasons and does not indicate that internal indexes and automatic indexes are related. - - -

        14.1. Hash Joins

        - -

        - An automatic index is about the same thing as a - hash join. The only difference - is that a B-Tree is used instead of a hash table. If you are willing to - say that the transient B-Tree constructed for an automatic index is - really just a fancy hash table, then a query that uses an automatic - index is just a hash join. - -

        - SQLite constructs a transient index instead of a hash table in this - instance because it already has a robust and high performance B-Tree - implementation at hand, whereas a hash-table would need to be added. - Adding a separate hash table implementation to handle this one case - would increase the size of the library (which is designed for use on - low-memory embedded devices) for minimal performance gain. SQLite might - be enhanced with a hash-table implementation someday, but for now it seems - better to continue using automatic indexes in cases where client/server - database engines might use a hash join. -

        15. The Push-Down Optimization

        @@ -1524,7 +1473,7 @@ imperfect. It sometimes returns a false negative. In other words, it sometimes fails to reduce the strength of a LEFT JOIN when doing so was in fact possible. For example, the prover does not know - the datetime() SQL function will always return NULL if its first + the datetime() SQL function will always return NULL if its first argument is NULL, and so it will not recognize that the LEFT JOIN in the following query could be strength-reduced: @@ -1620,5 +1569,4 @@ if those two constraints are true, then it must also be the case that "a=5" is true. This means that the desired row can be looked up quickly using a value of 5 for the INTEGER PRIMARY KEY. -

        This page last modified on 2023-02-27 02:07:35 UTC

        - +

        diff -Nru sqlite3-3.42.0/www/partialindex.html sqlite3-3.44.0-0/www/partialindex.html --- sqlite3-3.42.0/www/partialindex.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/partialindex.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
  • @@ -173,8 +149,8 @@

    create-index-stmt: -

    -
    +

    +
    @@ -268,8 +244,8 @@

    expr: -

    -
    -

    The team_id field cannot be unique because there are usually multiple people +

    The team_id field cannot be unique because there usually multiple people on the same team. One cannot make the combination of team_id and is_team_leader unique since there are usually multiple non-leaders on each team. The solution to enforcing one leader per team is to create a unique index @@ -2690,5 +2639,4 @@ as its schema contains no partial indexes. A database that is unreadable by legacy versions of SQLite can be made readable simply by running DROP INDEX on the partial indexes.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/pgszchng2016.html sqlite3-3.44.0-0/www/pgszchng2016.html --- sqlite3-3.42.0/www/pgszchng2016.html 2023-05-16 13:43:13.000000000 +0000 +++ sqlite3-3.44.0-0/www/pgszchng2016.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -185,5 +161,4 @@ 4096-byte page size might actually result in a smaller file, once substantial content is added.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/pragma.html sqlite3-3.44.0-0/www/pragma.html --- sqlite3-3.42.0/www/pragma.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/pragma.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    PRAGMA Statements

    @@ -159,8 +135,8 @@

    PRAGMA command syntax

    pragma-stmt: -

    -
    +

    +
    @@ -214,8 +190,8 @@

    pragma-value: -

    -
    +

    +
    @@ -242,8 +218,8 @@

    signed-number: -

    -
    -

    then the locking mode applies only to the named database. If no +

    Then the locking mode applies only to the named database. If no database name qualifier precedes the "locking_mode" keyword then the locking mode is applied to all databases, including any new databases added by subsequent ATTACH commands.

    @@ -1436,7 +1415,7 @@

    The PRAGMA mmap_size statement will never increase the amount of address space used for memory-mapped I/O above the hard limit set by the SQLITE_MAX_MMAP_SIZE compile-time option, - nor the hard limit set at startup-time by the second argument to + nor the hard limit set start-time by the second argument to sqlite3_config(SQLITE_CONFIG_MMAP_SIZE)

    The size of the memory-mapped I/O region cannot be changed while @@ -1676,16 +1655,10 @@ schema changes. As each SQL statement runs, the schema version is checked to ensure that the schema has not changed since the SQL statement was prepared. - Subverting this mechanism by using "PRAGMA schema_version=N" - to change the value of the schema_version + Subverting this mechanism by using "PRAGMA schema_version" may cause SQL statement to run using an obsolete schema, which can lead to incorrect answers and/or database corruption. - It is always safe to read the schema_version, but changing the - schema_version can cause problems. For this reason, attempts - to change the value of schema_version are a silent no-op when - defensive mode is enabled for a - database connection.

    @@ -1695,7 +1668,7 @@

    For the purposes of this pragma, the VACUUM command is considered - a schema change, since VACUUM will usually alter the "rootpage" + a schema change, since VACUUM will usual alter the "rootpage" values for entries in the sqlite_schema table. @@ -1735,16 +1708,6 @@ the secure-delete flag on one database connection changes it for them all.

    - -

    Limitation: - The secure_delete pragma only causes deleted content to be scrubbed - from ordinary tables. If virtual tables store content in - shadow tables, then deleting content from the virtual table does - not necessarily remove forensic traces from the shadow tables. - In particular, the FTS3 and FTS5 virtual tables that come - bundled with SQLite might leave forensic traces in their shadow tables - even if the secure_delete pragma is enabled. -

    PRAGMA short_column_names

    PRAGMA short_column_names; @@ -1860,7 +1823,7 @@ a checkpoint, but no sync operations occur during most transactions. With synchronous=FULL in WAL mode, an additional sync operation of the WAL file happens after each transaction commit. - The extra WAL sync following each transaction helps ensure that + The extra WAL sync following each transaction help ensure that transactions are durable across a power loss. Transactions are consistent with or without the extra syncs provided by synchronous=FULL. @@ -1876,59 +1839,22 @@ PRAGMA table_info


    PRAGMA schema.table_info(table-name);

    -

    This pragma returns one row for each normal column - in the named table. - Columns in the result set include: "name" (its name); "type" - (data type if given, else ''); "notnull" (whether or not the column - can be NULL); "dflt_value" (the default value for the column); - and "pk" (either zero for columns that are not part of the primary key, - or the 1-based index of the column within the primary key).

    -

    The "cid" column should not be taken to mean more than - "rank within the current result set".

    +

    This pragma returns one row for each column in the named table. + Columns in the result set include the column name, + data type, whether or not the column can be NULL, and the default + value for the column. The "pk" column in the result set is zero + for columns that are not part of the primary key, and is the index of + the column in the primary key for columns that are part of the primary + key.

    The table named in the table_info pragma can also be a view.

    -

    This pragma does not show information about generated columns or - hidden columns. Use PRAGMA table_xinfo to get a more complete list - of columns that includes generated and hidden columns. - - PRAGMA table_list


    -

    PRAGMA table_list; -
    PRAGMA
    schema.table_list; -
    PRAGMA table_list(
    table-name);

    -

    This pragma returns information about the tables and views in the schema, - one table per row of output. The table_list pragma first appeared - in SQLite version 3.37.0 (2021-11-27). As of its initial release - the columns returned by the table_list pragma include those listed below. - Future versions of SQLite will probably add additional columns of - output. -

    -

      -
    1. schema: the schema in which the table or view appears - (for example "main" or "temp"). -
    2. name: the name of the table or view. -
    3. type: the type of object - one of "table", "view", - "shadow" (for shadow tables), or "virtual" for - virtual tables. -
    4. ncol: the number of columns in the table, including - generated columns and hidden columns. -
    5. wr: 1 if the table is a WITHOUT ROWID table or 0 if is not. -
    6. strict: 1 if the table is a STRICT table or 0 if it is not. -
    7. Additional columns will likely be added in future releases. -
    -

    - The default behavior is to show all tables in all schemas. If the - schema. name appears before the pragma, then only tables in that - one schema are shown. If a table-name argument is supplied, then - only information about that one table is returned. +

    See also: PRAGMA table_xinfo PRAGMA table_xinfo


    PRAGMA schema.table_xinfo(table-name);

    This pragma returns one row for each column in the named table, - including generated columns and hidden columns. - The output has the same columns as for PRAGMA table_info plus - a column, "hidden", whose value signifies a normal column (0), - a dynamic or stored generated column (2 or 3), - or a hidden column in a virtual table (1). The rows for which - this field is non-zero are those omitted for PRAGMA table_info. + including hidden columns in virtual tables. + The output is the same as for PRAGMA table_info except that + hidden columns are shown rather than being omitted. PRAGMA temp_store


    PRAGMA temp_store; @@ -1939,8 +1865,8 @@ When temp_store is DEFAULT (0), the compile-time C preprocessor macro SQLITE_TEMP_STORE is used to determine where temporary tables and indices are stored. When - temp_store is MEMORY (2) temporary tables and indices are kept - as if they were in pure in-memory databases. + temp_store is MEMORY (2) temporary tables and indices are kept in + as if they were pure in-memory databases memory. When temp_store is FILE (1) temporary tables and indices are stored in a file. The temp_store_directory pragma can be used to specify the directory containing temporary files when @@ -2070,7 +1996,7 @@
    PRAGMA
    schema.user_version = integer ; -

    The user_version pragma will get or set +

    The user_version pragma will to get or set the value of the user-version integer at offset 60 in the database header. The user-version is an integer that is available to applications to use however they want. SQLite @@ -2243,18 +2169,14 @@ connection that is not in WAL mode.

    PRAGMA writable_schema
    -

    PRAGMA writable_schema = boolean;
    - PRAGMA writable_schema = RESET

    +

    PRAGMA writable_schema = boolean;

    When this pragma is on, and the SQLITE_DBCONFIG_DEFENSIVE flag is off, then the sqlite_schema table can be changed using ordinary UPDATE, INSERT, and DELETE - statements. If the argument is "RESET" then schema writing is - disabled (as with "PRAGMA writable_schema=OFF") and, in addition, the - schema is reloaded. Warning: + statements. Warning: misuse of this pragma can easily result in a corrupt database file.


    -

    This page last modified on 2023-02-16 21:36:11 UTC

    diff -Nru sqlite3-3.42.0/www/printf.html sqlite3-3.44.0-0/www/printf.html --- sqlite3-3.42.0/www/printf.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/printf.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -161,7 +137,7 @@ accessible via the following interfaces:

      -
    • format() → an SQL function returning the formatted string +
    • printf() → an SQL function returning the formatted string
    • sqlite3_mprintf() → Store the formatted string in memory obtained sqlite3_malloc64().
    • sqlite3_snprintf() → Store the formatted string in a static buffer @@ -191,13 +167,12 @@

    • We know of no way to use the standard library printf() C interface to -implement the format() SQL function feature of SQLite. The built-in +implement the printf() SQL function feature of SQLite. The built-in printf() implementation can be easily adapted to that task, however.

    • The printf() in SQLite supports new non-standard substitution -types (%q, %Q, %w, and %z), and enhanced substitution -behavior (%s and %z) that are useful both internally to SQLite +types (%q, %Q, %w, and %z) that are useful both internally to SQLite and to applications using SQLite. Standard library printf()s cannot normally be extended in this way. @@ -325,27 +300,24 @@ - The argument is either a zero-terminated string that is displayed, - or a null pointer which is treated as an empty string. For + The argument is a zero-terminated string that is displayed. For the %z type in C-language interfaces, sqlite3_free() is invoked - on the string after it has been copied into the output. The %s and %z - substitutions are identical for the SQL printf() function, with - a NULL argument treated as an empty string.

      - The %s substitution is universal among printf functions, but - the %z substitution and safe treatment of null pointers - are SQLite enhancements, not found in other + on the string after it has be copied into the output. The %s and %z + substitutions are identical for the SQL printf() function.

      + The %s substitution is universal, but + the %z substitution is an SQLite enhancement, not found in other printf() implementations. c For the C-language interfaces, the argument is an integer which - is interpreted as a character. For the format() SQL function the + is interpreted as a character. For the printf() SQL function the argument is a string from which the first character is extracted and displayed. p The argument is a pointer which is displayed as a hexadecimal address. Since the SQL language has no concept of a pointer, the %p substitution - for the format() SQL function works like %x. + for the printf() SQL function works like %x. n The argument is a pointer to an integer. Nothing is displayed for @@ -390,7 +362,7 @@

      The length of the argument value can be specified by one or more letters that occur just prior to the substitution type letter. In SQLite, the length only matter for integer types. The length is ignored for the -format() SQL function which always uses 64-bit values. The following +printf() SQL function which always uses 64-bit values. The following table shows the length specifiers allowed by SQLite:

      @@ -460,9 +432,6 @@ character to be repeated N times. This is a non-standard extension found only in SQLite. -

      If the precision is a single "*" character instead of a number, then the -actual precision value is read as an integer from the argument list. -

      2.5. The Options Flags Field

      Flags consist of zero or more characters that immediately follow the @@ -489,14 +458,9 @@ numbers. 0 -(The zero-padding option) -Prepend as many "0" characters to numeric substitutions as necessary to +Prepend as many "0" characters to numeric substitutions as necessary to expand the value out to the specified width. If the width field is omitted, then this flag is a no-op. -Infinity and NaN (Not-A-Number) floating point values are normally rendered -as "Inf" and "NaN", respectively, but with the zero-padding option enabled -they are rendered as "9.0e+999" and "null". In other words, with the zero-padding -option, floating-point Infinity and NaN are rendered as valid SQL and JSON literals. # This is the "alternate-form-1" flag. @@ -505,14 +469,10 @@ For %o, %x, and %X substitutions, the alternate-form-1 flag cause the value to be prepended with "0", "0x", or "0X", respectively. - - , -The comma option causes comma separators to be added to the output of numeric -substitutions (%d, %f, and similar) before every 3rd digits to the left of -the decimal point. No commas are added for digits to the right of the decimal point. -This can help humans to more easily discern the magnitude of large integer values. -For example, +This flag causes comma-separators to be added to the output of %d and %i +substitutions, between every 3 digits from the left. This can help humans +to more easily discern the magnitude of large integer values. For example, the value 2147483647 would be rendered as "2147483647" using "%d" but would appear as "2,147,483,647" with "%,d". This flag is a non-standard extension. @@ -536,7 +496,7 @@ printf.c source file. All the various interfaces invoke (sometimes indirectly) this one core function. The sqlite3VXPrintf() function began as code written by the first author -of SQLite (Hipp) when he was a graduate student at Duke University in the +of SQLite (Hipp) when he was a graduate student a Duke University in the late 1980s. Hipp kept this printf() implementation in his personal toolbox until he started working on SQLite in 2000. The code was incorporated into the SQLite source tree on 2000-10-08 @@ -548,11 +508,9 @@ printf() implementation, but those two implementations have since diverged.

      -The sqlite3_snprintf() function has its buffer pointer and buffer size -arguments reversed from what is found in the standard C library snprintf() -routine. This is because there was no snprintf() routine in the -standard C library +The reason that the sqlite3_snprintf() has its buffer pointer and buffer size +arguments reversed from what is found in the standard library snprintf() routine +is because there was no snprintf() routine in the standard C library when Hipp was first implementing his version, and he chose a different order than the designers of the standard C library. -

      This page last modified on 2023-05-04 17:35:51 UTC

      - +

      diff -Nru sqlite3-3.42.0/www/privatebranch.html sqlite3-3.44.0-0/www/privatebranch.html --- sqlite3-3.42.0/www/privatebranch.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/privatebranch.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -528,5 +504,4 @@

    Then continue to merge the changes in "trunk" with your "private" changes as described in section 3.7.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/profile.html sqlite3-3.44.0-0/www/profile.html --- sqlite3-3.42.0/www/profile.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/profile.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,409 +0,0 @@ - - - - - -Profiling SQL Queries - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -
    -
    -
    -Profiling SQL Queries -
    - - -
    - - - - -

    1. Overview

    - -

    SQLite contains built-in support for profiling SQL queries, but it is not -enabled by default. In order to enable support for query profiling, SQLite must -be compiled with the following option: - -

    -DSQLITE_ENABLE_STMT_SCANSTATUS
    -
    - -

    Building SQLite with this option enables the sqlite3_stmt_scanstatus_v2() -API, which provides access to the various profiling metrics. The remainder of -this page discusses the profiling reports generated by the SQLite -command-line shell using these metrics, rather than the API directly. - -

    The profiling reports generated by the shell are very similar to the query -plan reports generated by the EXPLAIN QUERY PLAN command. This page assumes -that the reader is familiar with this format. - -

    Within a command-line shell compiled with the option above, query profiling -is enabled using the ".scanstats on" command: - -

    sqlite> .scanstats on
    -
    - -

    Once enabled, the shell automatically outputs a query profile after each -SQL query executed. Query profiling can be disabled using ".scanstats off". -For example: - -

    sqlite> .scanstats on
    -sqlite> SELECT a FROM t1, t2 WHERE a IN (1,2,3) AND a=d+e;
    -QUERY PLAN (cycles=255831538 [100%])
    -|--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?)     (cycles=60048488 [23%] loops=1 rows=3)
    -`--SCAN t2                                           (cycles=133558052 [52%] loops=3 rows=150000)
    -
    - -

    2. Simple Cases - Rows, Loops and Cycles

    - -

    Consider a database with the following schema: - -

    CREATE VIRTUAL TABLE ft USING fts5(text);
    -CREATE TABLE t1(a, b);
    -CREATE TABLE t2(c INTEGER PRIMARY KEY, d);
    -
    - -

    Then, after first executing ".scanstats on": - -

    sqlite3> SELECT * FROM t1, t2 WHERE t2.c=t1.a;
    -<...query results...>
    -QUERY PLAN (cycles=1140768 [100%])
    -|--SCAN t1                                           (cycles=455974 [40%] loops=1 rows=500)
    -`--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?)     (cycles=619820 [54%] loops=500 rows=250)
    -
    - -

    The text in the example above following the snipped -"<...query results...>" is the profile report for the join query just -executed. The parts of the profile report that are similar to the -EXPLAIN QUERY PLAN output indicate that the query is implemented by doing a -full table-scan of table "t1", with a lookup by INTEGER PRIMARY KEY on table -"t2" for each row visited. - -

    The "loops=1" notation on the "SCAN t1" line indicates that this loop - the -full-table scan of table "t1" - ran exactly once. "rows=500" indicates that -that single scan visited 500 rows. - -

    The "SEARCH t2 USING ..." line contains the annotation "loops=500" to indicate -that this "loop" (really a lookup by INTEGER PRIMARY KEY) ran 500 times. -Which makes sense - it ran once for each row visited by the full-table scan -of "t1". "rows=250" means that, altogether, those 500 loops visited 250 rows. -In other words, only half of the INTEGER PRIMARY KEY lookups on table t2 were -successful, for the other half of the lookups there was no row to find. - -

    The loop-count for a SEARCH or SCAN entry is not necessarily the same as the -number of rows output by the outer loop. For example, if the query above -were modified as follows: - -

    sqlite3> SELECT * FROM t1, t2 WHERE t1.b<=100 AND t2.c=t1.a;
    -<...query results...>
    -QUERY PLAN (cycles=561002 [100%])
    -|--SCAN t1                                           (cycles=345950 [62%] loops=1 rows=500)
    -`--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?)     (cycles=128690 [23%] loops=100 rows=50)
    -
    - -

    This time, even though the "SCAN t1" loop still visits 500 rows, the -"SEARCH t2" lookup is only performed 100 times. This is because SQLite -was able to discard rows from t1 that did not match the "t1.b<=100" -constraint. - -

    The "cycles" measurements are based on the -CPU time-stamp counter -, and so are a good proxy for wall-clock time. For the query above, the -total number of cycles was 561002. For each of the two loops ("SCAN t1..." and -"SEARCH t2..."), the cycles count represents the time spent in operations that -can be directly attributed to that loop only. Specifically, this is the time -spent navigating and extracting data from the database b-trees for that loop. -These values never quite add up to the total cycles for the query, as there are -other internal operations performed by SQLite that are not directly -attributable to either loop. - -

    The cycles count for the "SCAN t1" loop was 345950 - 62% of the total for the -query. The 100 lookups peformed by the "SEARCH t1" loop took 128690 cycles, 23% -of the total. - -

    When a virtual table is used, the "rows" and "loops" metrics have the same -meaning as for loops on regular SQLite tables. The "cycles" meaurement is the -total cycles consumed within virtual table methods associated with the loop. -For example: - -

    sqlite3> SELECT * FROM ft('sqlite'), t2 WHERE t2.c=ft.rowid;
    -<...query results...>
    -QUERY PLAN (cycles=836434 [100%]
    -|--SCAN ft VIRTUAL TABLE INDEX 0:M1                  (cycles=739602 [88%] loops=1 rows=48)
    -`--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?)     (cycles=62866 [8%] loops=48 rows=25)
    -
    - -

    In this case the single query (loops=1) on fts5 table "ft" returned 48 rows -(rows=48) and consumed 739602 cycles (cycles=739602), which was roughly 88% of -the total query time. - -

    3. Complex Cases - Rows, Loops and Cycles

    - -

    Using the same schema as in the previous section, consider this more -complicated example: - -

    sqlite3> WITH cnt(i) AS (
    -  SELECT 1 UNION SELECT i+1 FROM cnt WHERE i<100
    -)
    -SELECT
    -  *, (SELECT d FROM t2 WHERE c=ft.rowid)
    -FROM
    -  (SELECT count(*), a FROM t1 GROUP BY a) AS v1 CROSS JOIN
    -  ft('sqlite'),
    -  cnt
    -WHERE cnt.i=ft.rowid AND v1.a=ft.rowid;
    -<...query results...>
    -QUERY PLAN (cycles=177665334 [100%])
    -|--CO-ROUTINE v1                                        (cycles=4500444 [3%])
    -|  |--SCAN t1                                           (cycles=397052 [0%] loops=1 rows=500)
    -|  `--USE TEMP B-TREE FOR GROUP BY
    -|--MATERIALIZE cnt                                      (cycles=1275068 [1%])
    -|  |--SETUP
    -|  |  `--SCAN CONSTANT ROW
    -|  `--RECURSIVE STEP
    -|     `--SCAN cnt                                       (cycles=129166 [0%] loops=100 rows=100)
    -|--SCAN v1                                              (loops=1 rows=500)
    -|--SCAN ft VIRTUAL TABLE INDEX 0:M1=                    (cycles=161874340 [91%] loops=500 rows=271)
    -|--SCAN cnt                                             (cycles=7336350 [4%] loops=95 rows=9500)
    -`--CORRELATED SCALAR SUBQUERY 3                         (cycles=168538 [0%] loops=37)
    -   `--SEARCH t2 USING INTEGER PRIMARY KEY (rowid=?)     (cycles=94724 [0%] loops=37 rows=21)
    -
    - -

    The most complicated part of the example above is understanding the query -plan - the portion of the report that would also be generated by an -EXPLAIN QUERY PLAN command. Other points of interest are: - -

      -
    • Sub-query "v1" is implemented as a co-routine. - In this case the sub-query is reported on separately, and a "cycles" - count is available for the entire sub-query. There is also a "SCAN v1" - line - this represents the invocation of the sub-query co-routine - from the main query. This entry has no cycles associated with it, as - the entire cost of the sub-query is attributed to the co-routine. - It does have "loops" and "rows" values - the sub-query is scanned - once and returns 500 rows. - -

    • Recursive sub-query "cnt" is materialized (cached in a temp - table) before the main query is run. The entire cost of the materialization - is attributed to the "MATERIALIZE cnt" element. There is also a - "SCAN cnt" item representing the scans of the materialized sub-query. - The cycles value associated with this item represents the time taken - to scan the temp-table containing the materialized sub-query, which is - separate from the cycles used to populate it. - -

    • There are cycles and loops measurements for the scalar sub-query - as well. These represent the total cycles consumed while executing the - sub-query and the number of times it was executed, respectively. - -

    • Where one item is a parent of another, as in "CORRELATED SCALAR - SUBQUERY 3" and "SEARCH t2 USING...", then the cycles value associated - with the parent includes those cycles associated with all child elements. - In all cases, the percentage values relate to the total cycles used by - the query, not the cycles used by the parent. -

    - -

    The following query uses an automatic index and -an external sort: - -

    sqlite> SELECT * FROM
    -  t2,
    -  (SELECT count(*) AS cnt, d FROM t2 GROUP BY d) AS v2
    -WHERE v2.d=t2.d AND t2.d>100
    -ORDER BY v2.cnt;
    -<...query results...>
    -QUERY PLAN (cycles=6234376 [100%])
    -|--MATERIALIZE v2                                     (cycles=2351916 [38%])
    -|  |--SCAN t2                                         (cycles=188428 [3%] loops=1 rows=250)
    -|  `--USE TEMP B-TREE FOR GROUP BY
    -|--SCAN t2                                            (cycles=455736 [7%] loops=1 rows=250)
    -|--CREATE AUTOMATIC INDEX ON v2(d, cnt)               (cycles=1668380 [27%] loops=1 rows=250)
    -|--SEARCH v2 USING AUTOMATIC COVERING INDEX (d=?)     (cycles=932824 [15%] loops=200 rows=200)
    -`--USE TEMP B-TREE FOR ORDER BY                       (cycles=662456 [11%] loops=1 rows=200)
    -
    - -

    Points of interest are: - -

      -
    • This query materializes the sub-query into a temp table, then creates - an automatic (i.e. transient) index on it, then uses that index to optimize - the join. All three of these steps - "MATERIALIZE v2", "CREATE AUTOMATIC - INDEX" and "SEARCH ... USING AUTOMATIC INDEX" have separate cycle counts. - The "rows" associated with the "CREATE AUTOMATIC INDEX" line represents the - total number of rows included in the index. The "loops" and "rows" associated - with the "SEARCH ... USING AUTOMATIC INDEX" line represent the number of - lookups the index was used for and the total number of rows found by those - lookups. - -

    • The external sort "USE TEMP B-TREE FOR ORDER BY" is also accounted - for separately. The cycles count represents the extra cycles consumed by - sorting the returned rows, above those that would have been used if the rows - were returned in arbitrary order. The rows count represents the number of - rows sorted. -

    - -

    4. Planner Estimates

    - -

    As well as ".scanstats on" to enable profiling and ".scanstats off" to -disable it, the shell also accepts ".scanstats est": - -

    sqlite> .scanstats est
    -
    - -

    This enables a special kind of profiling report that includes two extra -values associated with each "SCAN..." and "SEARCH..." element of a query -profile: - -

      -
    • rpl (rows per loop): This is the value of the "rows" metric - divided by that of the "loops" metric. -
    • est (estimate): This is the number of rows per loop that the - query planner estimated would be returned by the current query - element. If this value is radically different from the actual - rows per loop value and query performance is unsatisfactory, - the quality of this estimate may be improved by running ANALYZE. -
    - -
    sqlite> SELECT a FROM t1, t2 WHERE a IN (1,2,3) AND a=d+e ORDER BY a;
    -<query results...>
    -QUERY PLAN (cycles=264725190 [100%]
    -|--SEARCH t1 USING INTEGER PRIMARY KEY (rowid=?)     (cycles=60511568 [23%] loops=1 rows=3 rpl=3.0 est=3.0)
    -`--SCAN t2                                           (cycles=139461608 [53%] loops=3 rows=150000 rpl=50000.0 est=1048576.0)
    -
    - - - - - - -

    This page last modified on 2023-02-27 02:07:35 UTC

    - diff -Nru sqlite3-3.42.0/www/prosupport.html sqlite3-3.44.0-0/www/prosupport.html --- sqlite3-3.42.0/www/prosupport.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/prosupport.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -140,24 +116,24 @@ Private, expert email advice from the developers of SQLite. $1500/year -More Info
    -Purchase +More Info
    +Purchase 3.Technical Support. High-priority email and phone support directly from the SQLite developers. Guaranteed response time available as an option. -$8K-85K/year -More Info
    -Request A Quote +$8K-50K/year +More Info
    +Request A Quote 4.SQLite Consortium Membership. Premium enterprise support including on-site visits and access to all proprietary extensions and test suites. -$120K/year -More Info
    -Request A Quote +$85K/year +More Info
    +Request A Quote
    @@ -175,26 +151,26 @@ Private, expert email advice from the developers of SQLite.

    Cost: $1500/year -

    More Info -Purchase +

    More Info +Purchase

  • Technical Support. High-priority email and phone support directly from the SQLite developers. Guaranteed response time available as an option. -

    Cost: $8K-85K/year -

    More Info -Request A Quote +

    Cost: $8K-50K/year +

    More Info +Request A Quote

  • SQLite Consortium Membership. Premium enterprise support including on-site visits and access to all proprietary extensions and test suites. -

    Cost: $120K/year -

    More Info -Request A Quote +

    Cost: $85K/year +

    More Info +Request A Quote

  • @@ -205,15 +181,15 @@
    - +
    5.SQLite License. - Warranty of title and perpetual right-to-use for the SQLite source code. + Warranty of title and perpetual right-to-use for the SQLite source code. $6000 one time feeMore Info
    -Purchase
    More Info
    +Purchase
    6.SQLite Encryption Extension (SEE). - A drop-in replacement for public-domain SQLite source code that has - the added ability to read/write AES-encrypted databases. + A drop-in replacement for public-domain SQLite source code that has + the added ability to read/write AES-encrypted databases. $2000 one time fee More Info
    @@ -221,8 +197,8 @@
    7.Compressed And Encrypted Read-Only Database (CEROD). A drop-in replacement for public-domain SQLite source code - that has the added ability to read database that has been both - compressed and encrypted. + that has the added ability to read database that has been both + compressed and encrypted. $2000 one time fee More Info
    @@ -242,16 +218,16 @@
    1. SQLite License. - Warranty of title and perpetual right-to-use for the SQLite source code. + Warranty of title and perpetual right-to-use for the SQLite source code.

      Cost: $6000 one time fee -

      More Info -Purchase +

      More Info +Purchase

    2. SQLite Encryption Extension (SEE). - A drop-in replacement for public-domain SQLite source code that has - the added ability to read/write AES-encrypted databases. + A drop-in replacement for public-domain SQLite source code that has + the added ability to read/write AES-encrypted databases.

      Cost: $2000 one time fee

      More Info @@ -260,8 +236,8 @@

    3. Compressed And Encrypted Read-Only Database (CEROD). A drop-in replacement for public-domain SQLite source code - that has the added ability to read database that has been both - compressed and encrypted. + that has the added ability to read database that has been both + compressed and encrypted.

      Cost: $2000 one time fee

      More Info @@ -287,15 +263,15 @@ - +
      9.TH3 Testing Support. The TH3 test harness - is an aviation-grade test suite for SQLite. SQLite developers + is an aviation-grade test suite for SQLite. SQLite developers can run TH3 on specialized hardware and/or using specialized - compile-time options, according to customer specification, - either remotely or on customer premises. Pricing for this + compile-time options, according to customer specification, + either remotely or on customer premises. Pricing for this services is on a case-by-case basis depending on requirements. callMore Info
      -Request A Quote
      More Info
      +Request A Quote

      @@ -303,15 +279,15 @@
    4. TH3 Testing Support. The TH3 test harness - is an aviation-grade test suite for SQLite. SQLite developers + is an aviation-grade test suite for SQLite. SQLite developers can run TH3 on specialized hardware and/or using specialized - compile-time options, according to customer specification, - either remotely or on customer premises. Pricing for this + compile-time options, according to customer specification, + either remotely or on customer premises. Pricing for this services is on a case-by-case basis depending on requirements.

      Cost: call -

      More Info -Request A Quote +

      More Info +Request A Quote

    @@ -331,18 +307,18 @@ any problems with SQLite that you are likely to have.

    If you do not want to discuss your issues on a public and open forum, an -Annual Maintenance +Annual Maintenance Subscription or "AMS" might serve your needs better. An AMS entitles you to private email support directly from the developers of SQLite. The level of support with an AMS is similar to the support one -gets from the public forum except that an AMS includes a unilateral +gets from the public forum except that an AMS includes a unilateral promise of non-disclosure, so with an AMS you can discuss your issues with the SQLite developers in private, without the whole world watching. An AMS costs $1500 per year.

    Users with more advanced support needs can opt for a -Technical Support +Technical Support Agreement. Technical support agreements are customized to the needs of each individual client, but generally include direct telephone support @@ -352,8 +328,8 @@ in the range of $8000 to $35000 per year.

    If SQLite is "mission critical" to your company, then you may -want to become an -SQLite Consortium +want to become an +SQLite Consortium Member. The SQLite Consortium is a collaboration of companies who sponsor ongoing development of SQLite in exchange for enterprise-level technical support, on-site @@ -365,8 +341,8 @@

    Software Licenses

    -

    The SQLite source code is in the -public domain, +

    The SQLite source code is in the +public domain, and is free for use by anyone and for any purpose. No license is required. However, some users desire a license so that they can have warranty of title, or just @@ -375,26 +351,26 @@ and warranty of title for the core SQLite source code is available for this purpose.

    -

    The +

    The SQLite Encryption Extension (SEE), the ZIPVFS Extension, and the Compressed and -Encrypted ReadOnly Database (CEROD) extension are enhanced versions +Encrypted ReadOnly Database (CEROD) extension are enhanced versions of SQLite that handle encrypted and/or compressed databases. SEE can read and write encrypted databases. SEE encrypts all database content, including metadata, so that the database -file appears as white noise. ZIPVFS -compresses the database on-the-fly using application-supplied +file appears as white noise. ZIPVFS +compresses the database on-the-fly using application-supplied compression and decompression functions. CEROD reads a compressed database that is -also optionally encrypted. All of SEE, ZIPVFS, and CEROD are -supplied in source code form only; the licensee is responsible for -compiling the products for their chosen platform. It is not difficult +also optionally encrypted. All of SEE, ZIPVFS, and CEROD are +supplied in source code form only; the licensee is responsible for +compiling the products for their chosen platform. It is not difficult to compile any of these extension. All products come in the form of an -{amalgamated source file} -named "sqlite3.c". So compiling SEE, ZIPVFS, or CEROD into an application -is simply a matter of substituting the SEE-, ZIPVFS-, or CEROD-enabled sqlite3.c +amalgamated source file +named "sqlite3.c". So compiling SEE, ZIPVFS, or CEROD into an application +is simply a matter of substituting the SEE-, ZIPVFS-, or CEROD-enabled sqlite3.c source file in place of the public-domain sqlite3.c source file and recompiling. Licenses for SEE, ZIPVFS, and CEROD are perpetual. All three extension can read and write ordinary, @@ -403,7 +379,7 @@

    Testing Services

    -

    The Test Harness #3 (TH3) is +

    The Test Harness #3 (TH3) is a suite of test cases for SQLite that provide 100% branch test coverage (and 100% modified condition/decision coverage) for the core SQLite in an as-deployed configuration using only published and documented interfaces. @@ -417,15 +393,15 @@

    About The SQLite Team

    Paid support options and products are provided by -Hipp, Wyrick & Company, Inc., (Hwaci), a +Hipp, Wyrick & Company, Inc., (Hwaci), a Georgia -corporation +corporation with headquarters in Charlotte, North Carolina and has been in business since 1992. Hwaci has an international team of -employees and associates representing the best available talent. +employees and associates representing the best available talent. We are a 100% engineering company. There is no sales staff. Our goal is to provide outstanding service and honest advice @@ -434,11 +410,10 @@

    Hwaci is a small company but it is also closely held and debt-free and has low fixed costs, which means that it is largely immune to buy-outs, -take-overs, and market down-turns. Hwaci intends to -continue operating in its current form, and at roughly its current +take-overs, and market down-turns. Hwaci intends to +continue operating in its current form, and at roughly its current size until at least the year 2050. We expect to be here when you need us, even if that need is many years in the future.

    -

    This page last modified on 2023-01-02 14:22:42 UTC

    diff -Nru sqlite3-3.42.0/www/psow.html sqlite3-3.44.0-0/www/psow.html --- sqlite3-3.42.0/www/psow.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/psow.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -282,5 +258,4 @@ none of the standard VFSes will ever set any of the atomic bits in the xDeviceCharacteristics() vector. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/qmplan.html sqlite3-3.44.0-0/www/qmplan.html --- sqlite3-3.42.0/www/qmplan.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/qmplan.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -143,7 +119,7 @@ - + @@ -167,6 +143,12 @@ +
    + +This document is a work-in-progress. It is incomplete and unverified. + +
    +

    1. Overview

    @@ -186,11 +168,11 @@ for a full-up DO-178B implementation is vast. SQLite strives to be nimble and low-ceremony, and to that end, much of the required DO-178B documentation is omitted. We retain only those parts that -genuinely improve quality for an open-source software project such +genuinely improve quality for a open-source software project such as SQLite.

    -The purpose of this document is to brief the reader on how the +The purpose of this document is to brief the reader on how SQLite development team functions on a daily basis, as they continuously enhance the SQLite software and work to improve its already high reliability. The document achieves its purpose if a competent developer can be @@ -214,7 +196,7 @@

    -See About SQLite for an overview of the +See About SQLite for an overview of the SQLite software and what it does and how it is different.

    2.1. Software Life Cycle

    @@ -247,8 +229,7 @@ sqlite-dev mailing lists about two weeks prior to the anticipated release. Approximately one week prior to release, the lead developer declares "pencils down" after which only bug-fix check-ins are -allowed on trunk. A new -release checklist +allowed on trunk. A new release checklist is created and updated as needed. As items of the checklist are verified, they are checked off and turn green. The release occurs when all elements of the checklist are green. That process normally @@ -258,9 +239,9 @@

    Occasionally, a serious problem is found and a small "patch" release -must be made against a regular maintenance release. Patches are distinct +must be made against a regular maintenance release. Patch are distinct from maintenance releases in that the number of lines of code changed -from the previous release is small. Every effort is made to avoid +from the previous release is very small. Every effort is made to avoid patch releases by making sure that maintenance releases are bug free.

    @@ -348,13 +329,12 @@

  • 100% MC/DC in an as-delivered configuration
  • Testing of both source code and object code
  • Testing on multiple platforms and with multiple compilers -
  • Fuzz testing
  • Code change inspection
  • Dynamic and static analysis of the code
  • The testing process is controlled by the -release testing checklists. The checklists succinctly summarize +release testing checklists. The checklists succinctly summary all steps necessary to fully validate SQLite, and they record when and by whom each validation step was performed. @@ -392,11 +372,11 @@

    In addition to the official repositories, the developers typically keep complete clones of all software on their personal machines. -And there are other clones scattered about the internet. +And there are uncountable clones scattered about the internet.

    5.3. Repositories

    -

    The SQLite source is broken up into multiple repositories, each described +

    The SQLite code is broken up into multiple repositories, each described in a separate section below.

    5.3.1. SQLite Source Code

    @@ -404,16 +384,18 @@

    The SQLite source code and the TCL test suite are stored together in a single repository. This one repository is all that is required to build the SQLite. The source repository is public and is -readable by anonymous passersby on the internet. +readable by anonymous passers by on the internet.

    -

    5.3.2. SQLite Documentation Sources

    +

    There is an unofficial and unsanctioned Git clone of this repository +at https://github.com/mackyle/sqlite. + +

    5.3.2. SQLite Documentation Sources

    The documentation sources include documentation text and images with the scripts and makefile needed to construct the SQLite website documentation. @@ -424,14 +406,14 @@

    The makefiles and scripts used to generate the documentation gather text from baseline documents in the documentation source repository. Additional text is extracted from comments in the SQLite source code. -Requirements coverage information is extracted from special comments in the +Requirements coverage information is extract from special comments in the TCL test suite which is part of the source repository, and from -comments in the TH3 test suite which is in a separate private repository. +comments in the TH3 test suite which is a separate private repository.

    5.3.3. SQL Logic Test

    @@ -458,27 +440,22 @@

    -

    5.3.5. Dbsqlfuzz

    +

    5.3.5. Test Harness #3 Private Extensions

    -The dbsqlfuzz module is a -libFuzzer-based fuzzer -for SQLite. Dbsqlfuzz fuzzes both the SQL and the database file at -the same time. Dbsqlfuzz uses a customized mutator. - -

    -Dbsqlfuzz seems to work better at finding problems than any other -fuzzer available. For that reason, it is kept private. We do not -want hacker gaining access to this technology. +At one point, TH3 was sometimes licensed to third-parties. +Such licensing no longer occurs. However, back when it was +occurring, some of the TH3 test cases contained information that +was sensitive and could not be released even to licensees. This +sensitive information is stored in yet another repository.

    5.4. Software Verification Results

    @@ -494,71 +471,13 @@

    6. Software Requirements Standards And Data

    -

    In the SQLite project, the "requirements" are the project documentation. -Special markup in the documentation text indentifies individual requirements. -The requirement numbers are based on a cryptographic hash of normalized -requirement text, so that it is impossible to change the requirement text -without also changing the requirement number. - -

    Documentation text (and hence requirement text) is taken from the -SQLite Documentation source repository, described above, and also from -comments in the implementation. The makefiles to build the documentation -are in the documentation source repository. - -

    When the documentation is build, requirements are identified and labeled. -The documentation build process also scans for test cases that verify -each requirement and constructs a matrix showing which requirements have -been testing and identifying the specific test cases that test those -requirements. +

    TBD...

    7. Software Design And Coding Standards

    -

    Objective coding standards for SQLite are minimal: - -

      -
    • 2-space indentation -
    • No lines over 80 characters in length -
    • No tabs -
    - -

    All other design and coding rules are subjective. The -goal here is to make the software so that it is readable -and maintainable through the year 2050. To that end, we look -for succinct yet useful comments (no boilerplate), carefully -chosen variable names, and careful explanation of the meaning -of each data structure and the role of each code block. +

    TBD...

    8. Problem Reports

    -

    All problems are fixed expeditiously. There are no lingering problems -in the sQLite software. - -

    The Fossil version control system utilized by -SQLite contains built-in support for tracking trouble-tickets. This built-in -ticket system is used to track and document many historical problems. - -

    The SQLite Community Forum is a place -where anybody on the internet can go to ask questions about or report bugs -against SQLite. Bugs found by third-parties are often reported initially -on the Forum. Forum-reported bugs will sometimes be transferred to tickets, -though recent practice as been to just deal with the bugs on the Forum. -The Forum has an excellent full-text search feature, is mirrored to -multiple machines, and is just as searchable and survivable as the ticket -system, so it seems unnecessary to duplicate Forum-originated bug reports -into the ticket system. The public locations of the Forum are: - -

    - -

    -As with the source repositories, the Forum is also synced to various -private machines. -Note that because of the way Fossil works, the "backups" are more than just -read-only backups. They can also function as data inputs. All content -entered is synced to all repositories, regardless of which repository is -used for insertion. -

    This page last modified on 2022-04-18 02:55:50 UTC

    - +

    TBD... +

    diff -Nru sqlite3-3.42.0/www/queryplanner.html sqlite3-3.44.0-0/www/queryplanner.html --- sqlite3-3.42.0/www/queryplanner.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/queryplanner.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -132,7 +108,7 @@ - + @@ -603,7 +579,7 @@ -

    1.7. Covering Indexes

    +

    1.7. Covering Indices

    The "price of California oranges" query was made more efficient through @@ -1033,5 +1009,4 @@ tables and that appears as the right-most term in indexes is replaced by the PRIMARY KEY.

    -

    This page last modified on 2022-10-26 13:30:36 UTC

    diff -Nru sqlite3-3.42.0/www/queryplanner-ng.html sqlite3-3.44.0-0/www/queryplanner-ng.html --- sqlite3-3.42.0/www/queryplanner-ng.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/queryplanner-ng.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -263,7 +239,7 @@

    The QPSG means that if all of your queries run efficiently during testing, and if your application does not change the schema, then SQLite will not suddenly decide to start using a different -query plan, possibly causing a performance problem after your application +query plan, possibly causing a performance problem, after your application is released to users. If your application works in the lab, it will continue working the same way after deployment.

    @@ -441,7 +417,7 @@ being outside of it.

    The arrows from the small circles labeled with "*" indicate the cost -of running each loop with no dependencies. The outermost loop must use this +of running each loop with no dependencies. The outer loop must use this *-cost. Inner loops have the option of using the *-cost or a cost assuming one of the other terms is in an outer loop, whichever gives the best result. One can think of the *-costs as a short-hand notation indicating @@ -1049,4 +1025,3 @@ NGQP is just a new enhancement to SQLite that makes the application run a little faster and which requires no new developer thought or action.

    - diff -Nru sqlite3-3.42.0/www/quickstart.html sqlite3-3.44.0-0/www/quickstart.html --- sqlite3-3.42.0/www/quickstart.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/quickstart.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -226,5 +202,4 @@ how to compile the program shown above. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/quirks.html sqlite3-3.44.0-0/www/quirks.html --- sqlite3-3.42.0/www/quirks.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/quirks.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    +
    @@ -156,7 +132,7 @@ -

    1. The RBU Extension

    +

    1. The RBU Extension

    The RBU extension is an add-on for SQLite designed for use with large SQLite database files on low-power devices at the edge of a network. RBU @@ -761,5 +737,4 @@ return rc; }

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/recovery.html sqlite3-3.44.0-0/www/recovery.html --- sqlite3-3.42.0/www/recovery.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/recovery.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,391 +0,0 @@ - - - - - -Recovering Data From A Corrupt SQLite Database - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -
    -
    -
    -Recovering Data From A Corrupt SQLite Database -
    - - -
    - - - - -

    1. Recovering (Some) Data From A Corrupt SQLite Database

    - -

    -SQLite databases are remarkably rebust. Application faults and -power failures typically leave the content of the database intact. -However, it is possible to corrupt an SQLite database. -For example, hardware malfunctions can damage the database file, or a -rogue process can open the database and overwrite parts of it. - -

    -Given a corrupt database file, it is sometimes desirable to try to -salvage as much data from the file as possible. The recovery API -is designed to facilitate this. - -

    1.1. Limitations

    - -

    -It is sometimes possible to perfectly restore a database that has -gone corrupt, but that is the exception. Usually -the recovered database will be defective in a number of ways: - -

      -
    • -Some content might be permanently deleted and unrecoverable. -This can happen, for example, if a rogue process overwrites part -of the database file. - -

    • -Previously deleted content might reappear. Normally when SQLite -does a DELETE operation, it does not actually overwrite the old content -but instead remembers that space is available for reuse during the next -INSERT. If such deleted content is still in the file when a recovery -is attempted, it might be extracted and "resurrected". - -

    • -Recovered content might be altered. -For example, the value stored in a particular row -might change from 48 to 49. Or it might change from an integer into -a string or blob. A value that was NULL might become an integer. -A string value might become a BLOB. And so forth. - -

    • -Constraints may not be valid after recovery. CHECK constraints, -FOREIGN KEY constraints, UNIQUE constraints, type constraints on -STRICT tables - any of these might be violated in the recovered -database. - -

    • -Content might be moved from one table into another. -

    - -

    -The recovery API does as good of a job as it can at restoring a database, -but the results will always be suspect. Sometimes (for example if the -corruption is restricted to indexes) the recovery will perfectly restore -the database content. However in other cases, the recovery will be imperfect. -The impact of this imperfection depends on the application. A database that -holds a list of bookmarks is still a list of bookmarks after recovery. -A few bookmarks might be missing or added or altered after recovery, but -the list is "fuzzy" and imperfect to begin with so adding a bit more -uncertainty will not be fatal to the application. But if an accounting -database goes corrupt and is subsequently recovered, the books might be -out of balance. - -

    -It is best to think of the recovery API as a salvage undertaking. -Recovery will extract as much usable data as it can from the wreck -of the old database, but some parts may be damaged beyond repair and -some rework and testing should be performed prior to returning the -recovered database to service. - -

    2. Recovery Using The ".recover" Command In The CLI

    - -

    -The easiest way to manually recover a corrupt database is using -the Command Line Interface or "CLI" for SQLite. The CLI is a program -named "sqlite3". Use it to recover a corrupt database file using -a command similar to the following: - -

    sqlite3 corrupt.db .recover >data.sql
    -
    - -

    -This will generate SQL text in the file named "data.sql" that can be used -to reconstruct the original database: - -

    sqlite3 recovered.db <data.sql
    -
    - -

    -The ".recover" option is actually a command that is issued to the -CLI. That command can accept arguments. For example, by running: - -

    sqlite3 corruptdb ".recover --ignore-freelist" >data.sql
    -
    - -

    -Notice that the ".recover" command and its arguments must be contained -in quotes. The following options are supported: - -

    -

    -
    --ignore-freelist
    -

    -Ignore pages of the database that appear to be part of the -freelist. Normally the freelist is scanned, and if it contains -pages that look like they have content, that content is output. -But if the page really is on the freelist, that can mean that -previously deleted information is reintroduced into the database. -

    - -
    --lost-and-found TABLE
    -

    -If content is found during recovery that cannot be associated -with a particular table, it is put into the "lost_and_found" -table. Use this option to change the name of the -"lost_and_found" table to "TABLE". -

    - -
    --no-rowids
    -

    -If this option is provided, then rowid values that are not also -INTEGER PRIMARY KEY values are not extracted from the -corrupt database. -

    - -
    - -

    3. Building The Recovery API Into An Application

    - -

    3.1. Source Code Files

    - -

    If you want to build the recovery API into your application, you will -need to add some source files to your build, above and beyond the usual -"sqlite3.c" and "sqlite3.h" source files. You will need: - -

    -

    - - - - - - - - - - - - -
    -sqlite3recover.c - -This is the main source file that implements the recovery API. -
    -sqlite3recover.h - -This is the header file that goes with sqlite3recover.h. -
    -dbdata.c - -This file implements two virtual tables name "sqlite_dbdata" and -"sqlite_dbptr" that required by sqlite3recover.c. -
    -
    - -

    -The two C source file above need to be linked into your application in the -same way as "sqlite3.c" is linked in. And the header file needs to be -accessible to the compiler when the C files are being compiled. - -

    -Additionally, the application, or more specifically the sqlite3.c linked -into the application, must be compiled with the following option: -

    -        -DSQLITE_ENABLE_DBPAGE_VTAB
    -
    - -

    3.2. How To Implement Recovery

    - -

    These are the basic steps needed to recover content from a corrupt -Database: - -

      -
    1. -Creates an sqlite3_recover handle by calling either -sqlite3_recover_init() or sqlite3_recover_init_sql(). -Use sqlite3_recover_init() to store the recovered content -in a separate database and use sqlite3_recover_init_sql() -to generate SQL text that will reconstruct the database. - -

    2. -Make zero or more calls to sqlite3_recover_config() to set -options on the new sqlite3_recovery handle. - -

    3. -Invoke sqlite3_recover_step() repeatedly -until it returns something other than SQLITE_OK. If it -returns SQLITE_DONE, then the recovery operation completed without -error. If it returns some other non-SQLITE_OK value, then an error -has occurred. The sqlite3_recover_run() interface is also -available as a convenience wrapper that simply invokes -sqlite3_recover_step() repeatedly until it returns something other -than SQLITE_DONE. - -

    4. -Retrieves any error code and English language error message using the -sqlite3_recover_errcode() and sqlite3_recover_errmsg() interfaces, -respectively. - -

    5. -Invoke sqlite3_recover_finish() to destroy the sqlite3_recover object. -

    - -

    -Details of the interface are described in comments in the -sqlite3_recover.h header file. - -

    3.3. Example Implementations

    - - -

    -Examples of how the recovery extension is used by SQLite itself -can be seen at the following links: - -

    -

    This page last modified on 2023-02-28 11:22:37 UTC

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_0.html sqlite3-3.44.0-0/www/releaselog/3_0_0.html --- sqlite3-3.42.0/www/releaselog/3_0_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.0 On 2004-06-18

    1. *** Alpha Release - Research And Testing Use Only *** @@ -131,10 +107,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_1.html sqlite3-3.44.0-0/www/releaselog/3_0_1.html --- sqlite3-3.42.0/www/releaselog/3_0_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.1 On 2004-06-22

    1. *** Alpha Release - Research And Testing Use Only *** @@ -123,10 +99,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_2.html sqlite3-3.44.0-0/www/releaselog/3_0_2.html --- sqlite3-3.42.0/www/releaselog/3_0_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,42 +89,17 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.2 On 2004-06-30

    1. The first beta release for SQLite 3.0.

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_3.html sqlite3-3.44.0-0/www/releaselog/3_0_3.html --- sqlite3-3.42.0/www/releaselog/3_0_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.3 On 2004-07-22

    1. The second beta release for SQLite 3.0.
    2. Add support for "PRAGMA page_size" to adjust the page size of @@ -124,10 +100,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_4.html sqlite3-3.44.0-0/www/releaselog/3_0_4.html --- sqlite3-3.42.0/www/releaselog/3_0_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.4 On 2004-08-09

    1. CREATE TABLE and DROP TABLE now work correctly as prepared statements.
    2. Fix a bug in VACUUM and UNIQUE indices.
    3. @@ -127,10 +103,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_5.html sqlite3-3.44.0-0/www/releaselog/3_0_5.html --- sqlite3-3.42.0/www/releaselog/3_0_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.5 On 2004-08-29

    1. Support for ":AAA" style bind parameter names.
    2. Added the new sqlite3_bind_parameter_name() interface.
    3. @@ -132,10 +108,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_6.html sqlite3-3.44.0-0/www/releaselog/3_0_6.html --- sqlite3-3.42.0/www/releaselog/3_0_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.6 On 2004-09-02

    1. Better detection and handling of corrupt database files.
    2. The sqlite3_step() interface returns SQLITE_BUSY if it is unable @@ -126,10 +102,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_7.html sqlite3-3.44.0-0/www/releaselog/3_0_7.html --- sqlite3-3.42.0/www/releaselog/3_0_7.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_7.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.7 On 2004-09-18

    1. The BTree module allocates large buffers using malloc() instead of off of the stack, in order to play better on machines with limited @@ -124,7 +100,7 @@
    2. New interface: sqlite3_bind_parameter_index()
    3. Add support for wildcard parameters of the form: "?nnn"
    4. Fix problems found on 64-bit systems.
    5. -
    6. Removed encode.c file (containing unused routines) from the +
    7. Removed encode.c file (containing unused routines) from the version 3.0 source tree.
    8. The sqlite3_trace() callbacks occur before each statement is executed, not when the statement is compiled.
    9. @@ -133,10 +109,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_0_8.html sqlite3-3.44.0-0/www/releaselog/3_0_8.html --- sqlite3-3.42.0/www/releaselog/3_0_8.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_0_8.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.0.8 On 2004-10-12

    1. Add support for DEFERRED, IMMEDIATE, and EXCLUSIVE transactions.
    2. Allow new user-defined functions to be created when there are @@ -132,10 +108,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_10_0.html sqlite3-3.44.0-0/www/releaselog/3_10_0.html --- sqlite3-3.42.0/www/releaselog/3_10_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_10_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.10.0 On 2016-01-06

      General improvements:

    1. Added support for LIKE, GLOB, and REGEXP operators on virtual tables. @@ -154,7 +130,7 @@
    2. Fix inconsistent integer to floating-point comparison operations that could result in a corrupt index if the index is created on a table column that contains both large integers and floating point values - of similar magnitude. Ticket + of similar magnitude. Ticket 38a97a87a6.
    3. Fix an infinite-loop in the query planner that could occur on malformed common table expressions. @@ -167,10 +143,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_10_1.html sqlite3-3.44.0-0/www/releaselog/3_10_1.html --- sqlite3-3.42.0/www/releaselog/3_10_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_10_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.10.1 On 2016-01-14

    Prior changes from version 3.10.0 (2016-01-06):

    + +

    SQLite Release 3.10.1 On 2016-01-14

    Changes in version 3.10.0 (2016-01-06):

      General improvements:

    1. Added support for LIKE, GLOB, and REGEXP operators on virtual tables. @@ -155,13 +131,13 @@
    2. Fix inconsistent integer to floating-point comparison operations that could result in a corrupt index if the index is created on a table column that contains both large integers and floating point values - of similar magnitude. Ticket + of similar magnitude. Ticket 38a97a87a6.
    3. Fix an infinite-loop in the query planner that could occur on malformed common table expressions.
    4. Various bug fixes in the sqldiff tool.
    -

    Changes in this specific patch release, version 3.10.1 (2016-01-14):

    +

    Additional changes in version 3.10.1 (2016-01-14):

      New feature:

    1. Add the SQLITE_FCNTL_JOURNAL_POINTER file control. @@ -176,10 +152,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_10_2.html sqlite3-3.44.0-0/www/releaselog/3_10_2.html --- sqlite3-3.42.0/www/releaselog/3_10_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_10_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.10.2 On 2016-01-20

    Prior changes from version 3.10.0 (2016-01-06):

    + +

    SQLite Release 3.10.2 On 2016-01-20

    Changes in version 3.10.0 (2016-01-06):

      General improvements:

    1. Added support for LIKE, GLOB, and REGEXP operators on virtual tables. @@ -155,13 +131,13 @@
    2. Fix inconsistent integer to floating-point comparison operations that could result in a corrupt index if the index is created on a table column that contains both large integers and floating point values - of similar magnitude. Ticket + of similar magnitude. Ticket 38a97a87a6.
    3. Fix an infinite-loop in the query planner that could occur on malformed common table expressions.
    4. Various bug fixes in the sqldiff tool.
    -

    Prior changes from version 3.10.1 (2016-01-14):

    +

    Additional changes in version 3.10.1 (2016-01-14):

      New feature:

    1. Add the SQLITE_FCNTL_JOURNAL_POINTER file control. @@ -170,11 +146,11 @@ when a scalar subquery attempts to use the block sorting optimization. Ticket cb3aa0641d9a4.
    -

    Changes in this specific patch release, version 3.10.2 (2016-01-20):

    +

    Additional changes in version 3.10.2 (2016-01-20):

      Critical bug fix:

    1. Version 3.10.0 introduced a case-folding bug in the LIKE operator which is fixed - by this patch release. Ticket + by this patch release. Ticket 80369eddd5c94.

      Other miscellaneous bug fixes:

    2. Fix a use-after-free that can occur when SQLite is compiled with -DSQLITE_HAS_CODEC. @@ -188,10 +164,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_1_0.html sqlite3-3.44.0-0/www/releaselog/3_1_0.html --- sqlite3-3.42.0/www/releaselog/3_1_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_1_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.1.0 On 2005-01-21

    1. Autovacuum support added
    2. CURRENT_TIME, CURRENT_DATE, and CURRENT_TIMESTAMP added
    3. @@ -133,10 +109,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_11_0.html sqlite3-3.44.0-0/www/releaselog/3_11_0.html --- sqlite3-3.42.0/www/releaselog/3_11_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_11_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.11.0 On 2016-02-15

      General improvements:

    1. Enhanced WAL mode so that it works efficiently with transactions that are @@ -128,7 +104,7 @@ a covering index as part of the OR optimization.
    2. Avoid recomputing NOT NULL and CHECK constraints on unchanged columns in UPDATE statement. -
    3. Many micro-optimizations, resulting in a library that is +
    4. Many micro-optimizations, resulting in a library that is faster than the previous release.

      Enhancements to the command-line shell:

    5. By default, the shell is now in "auto-explain" mode. The output of @@ -156,7 +132,7 @@
    6. Reenable the xCurrentTime and xGetLastError methods in the built-in unix VFSes as long as SQLITE_OMIT_DEPRECATED is not defined.

      Backwards Compatibility: -

    7. Because of continuing security concerns, the two-argument version +
    8. Because of continuing security concerns, the two-argument version of of the seldom-used and little-known fts3_tokenizer() function is disabled unless SQLite is compiled with the SQLITE_ENABLE_FTS3_TOKENIZER.

      Hashes: @@ -167,10 +143,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_11_1.html sqlite3-3.44.0-0/www/releaselog/3_11_1.html --- sqlite3-3.42.0/www/releaselog/3_11_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_11_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.11.1 On 2016-03-03

    Prior changes from version 3.11.0 (2016-02-15):

    + +

    SQLite Release 3.11.1 On 2016-03-03

    Changes in version 3.11.0 (2016-02-15):

      General improvements:

    1. Enhanced WAL mode so that it works efficiently with transactions that are @@ -129,7 +105,7 @@ a covering index as part of the OR optimization.
    2. Avoid recomputing NOT NULL and CHECK constraints on unchanged columns in UPDATE statement. -
    3. Many micro-optimizations, resulting in a library that is +
    4. Many micro-optimizations, resulting in a library that is faster than the previous release.

      Enhancements to the command-line shell:

    5. By default, the shell is now in "auto-explain" mode. The output of @@ -157,11 +133,11 @@
    6. Reenable the xCurrentTime and xGetLastError methods in the built-in unix VFSes as long as SQLITE_OMIT_DEPRECATED is not defined.

      Backwards Compatibility: -

    7. Because of continuing security concerns, the two-argument version +
    8. Because of continuing security concerns, the two-argument version of of the seldom-used and little-known fts3_tokenizer() function is disabled unless SQLite is compiled with the SQLITE_ENABLE_FTS3_TOKENIZER.
    -

    Changes in this specific patch release, version 3.11.1 (2016-03-03):

    +

    Additional changes in version 3.11.1 (2016-03-03):

    1. Improvements to the Makefiles and build scripts used by VisualStudio.
    2. Fix an FTS5 issue in which the 'optimize' command could cause index corruption. @@ -174,10 +150,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_1_1.html sqlite3-3.44.0-0/www/releaselog/3_1_1.html --- sqlite3-3.42.0/www/releaselog/3_1_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_1_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.1.1 On 2005-02-01

    1. Automatic caching of prepared statements in the TCL interface
    2. ATTACH and DETACH as well as some other operations cause existing @@ -124,10 +100,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_12_0.html sqlite3-3.44.0-0/www/releaselog/3_12_0.html --- sqlite3-3.42.0/www/releaselog/3_12_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_12_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.12.0 On 2016-03-29

      Potentially Disruptive Change: -

    1. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. - The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so +
    2. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. + The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so the same amount of cache memory is used by default. See the application note on the version 3.12.0 page size change for further information. @@ -140,7 +116,7 @@ accesses in a 3-way or higher join where constraints on the virtual table are split across two or more other tables of the join.
    3. More efficient handling of application-defined SQL functions, especially - in cases where the application defines hundreds or thousands of + in cases where the application defines hundreds or thousands of custom functions.
    4. The query planner considers the LIMIT clause when estimating the cost of ORDER BY. @@ -156,7 +132,7 @@ be enabled or disabled at run-time.
    5. Added the sqlite3rbu_bp_progress() interface to the RBU extension. -
    6. The PRAGMA defer_foreign_keys=ON statement now also disables +
    7. The PRAGMA defer_foreign_keys=ON statement now also disables RESTRICT actions on foreign key.
    8. Added the sqlite3_system_errno() interface.
    9. Added the SQLITE_DEFAULT_SYNCHRONOUS and SQLITE_DEFAULT_WAL_SYNCHRONOUS @@ -179,10 +155,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_12_1.html sqlite3-3.44.0-0/www/releaselog/3_12_1.html --- sqlite3-3.42.0/www/releaselog/3_12_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_12_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.12.1 On 2016-04-08

    Prior changes from version 3.12.0 (2016-03-29):

    + +

    SQLite Release 3.12.1 On 2016-04-08

    Changes in version 3.12.0 (2016-03-29):

      Potentially Disruptive Change: -

    1. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. - The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so +
    2. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. + The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so the same amount of cache memory is used by default. See the application note on the version 3.12.0 page size change for further information. @@ -141,7 +117,7 @@ accesses in a 3-way or higher join where constraints on the virtual table are split across two or more other tables of the join.
    3. More efficient handling of application-defined SQL functions, especially - in cases where the application defines hundreds or thousands of + in cases where the application defines hundreds or thousands of custom functions.
    4. The query planner considers the LIMIT clause when estimating the cost of ORDER BY. @@ -157,7 +133,7 @@ be enabled or disabled at run-time.
    5. Added the sqlite3rbu_bp_progress() interface to the RBU extension. -
    6. The PRAGMA defer_foreign_keys=ON statement now also disables +
    7. The PRAGMA defer_foreign_keys=ON statement now also disables RESTRICT actions on foreign key.
    8. Added the sqlite3_system_errno() interface.
    9. Added the SQLITE_DEFAULT_SYNCHRONOUS and SQLITE_DEFAULT_WAL_SYNCHRONOUS @@ -174,12 +150,12 @@ Ticket 5e3c886796e5512e.
    10. Fix a harmless TSAN warning associated with the sqlite3_db_readonly() interface.
    -

    Changes in this specific patch release, version 3.12.1 (2016-04-08):

    +

    Additional changes in version 3.12.1 (2016-04-08):

    1. Fix a boundary condition error introduced by version 3.12.0 that can result in a crash during heavy SAVEPOINT usage. Ticket 7f7f8026eda38. -
    2. Fix views so that they inherit column datatypes from the +
    3. Fix views so that they inherit column datatypes from the table that they are defined against, when possible.
    4. Fix the query planner so that IS and IS NULL operators are able to drive an index on a LEFT OUTER JOIN. @@ -190,10 +166,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_12_2.html sqlite3-3.44.0-0/www/releaselog/3_12_2.html --- sqlite3-3.42.0/www/releaselog/3_12_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_12_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.12.2 On 2016-04-18

    Prior changes from version 3.12.0 (2016-03-29):

    + +

    SQLite Release 3.12.2 On 2016-04-18

    Changes in version 3.12.0 (2016-03-29):

      Potentially Disruptive Change: -

    1. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. - The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so +
    2. The SQLITE_DEFAULT_PAGE_SIZE is increased from 1024 to 4096. + The SQLITE_DEFAULT_CACHE_SIZE is changed from 2000 to -2000 so the same amount of cache memory is used by default. See the application note on the version 3.12.0 page size change for further information. @@ -141,7 +117,7 @@ accesses in a 3-way or higher join where constraints on the virtual table are split across two or more other tables of the join.
    3. More efficient handling of application-defined SQL functions, especially - in cases where the application defines hundreds or thousands of + in cases where the application defines hundreds or thousands of custom functions.
    4. The query planner considers the LIMIT clause when estimating the cost of ORDER BY. @@ -157,7 +133,7 @@ be enabled or disabled at run-time.
    5. Added the sqlite3rbu_bp_progress() interface to the RBU extension. -
    6. The PRAGMA defer_foreign_keys=ON statement now also disables +
    7. The PRAGMA defer_foreign_keys=ON statement now also disables RESTRICT actions on foreign key.
    8. Added the sqlite3_system_errno() interface.
    9. Added the SQLITE_DEFAULT_SYNCHRONOUS and SQLITE_DEFAULT_WAL_SYNCHRONOUS @@ -174,17 +150,17 @@ Ticket 5e3c886796e5512e.
    10. Fix a harmless TSAN warning associated with the sqlite3_db_readonly() interface.
    -

    Prior changes from version 3.12.1 (2016-04-08):

    +

    Additional changes in version 3.12.1 (2016-04-08):

    1. Fix a boundary condition error introduced by version 3.12.0 that can result in a crash during heavy SAVEPOINT usage. Ticket 7f7f8026eda38. -
    2. Fix views so that they inherit column datatypes from the +
    3. Fix views so that they inherit column datatypes from the table that they are defined against, when possible.
    4. Fix the query planner so that IS and IS NULL operators are able to drive an index on a LEFT OUTER JOIN.
    -

    Changes in this specific patch release, version 3.12.2 (2016-04-18):

    +

    Additional changes in version 3.12.2 (2016-04-18):

    1. Fix a backwards compatibility problem in version 3.12.0 and 3.12.1: Columns declared as "INTEGER" PRIMARY KEY (with quotes around @@ -206,10 +182,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_1_2.html sqlite3-3.44.0-0/www/releaselog/3_1_2.html --- sqlite3-3.42.0/www/releaselog/3_1_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_1_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.1.2 On 2005-02-15

    1. Fix a bug that can lead to database corruption if there are two open connections to the same database and one connection does a VACUUM @@ -128,10 +104,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_13_0.html sqlite3-3.44.0-0/www/releaselog/3_13_0.html --- sqlite3-3.42.0/www/releaselog/3_13_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_13_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.13.0 On 2016-05-18

    1. Postpone I/O associated with TEMP files for as long as possible, with the hope that the I/O can ultimately be avoided completely. @@ -126,7 +102,7 @@ and EXPLAIN QUERY PLAN on each statement that is evaluated.
    2. Improved unicode filename handling in the command-line shell on Windows.
    3. Improved resistance against goofy query planner decisions caused by - incomplete or incorrect modifications to the sqlite_stat1 + incomplete or incorrect modifications to the sqlite_stat1 table by the application.
    4. Added the sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION) interface which allows the sqlite3_load_extension() C-API to be enabled while keeping the @@ -139,7 +115,7 @@ causing it to compute incorrect answers with a self-referential subquery in the WHERE clause. Fix for ticket dc6ebeda9396087 -
    5. Fix a possible segfault with DELETE when table is a rowid table with an +
    6. Fix a possible segfault with DELETE when table is a rowid table with an INTEGER PRIMARY KEY and the WHERE clause contains a OR and the table has one or more indexes that are able to trigger the OR optimization, but none of the indexes reference any table columns other than the INTEGER PRIMARY KEY. @@ -174,7 +150,7 @@
    7. Fix a boundary condition error introduced by version 3.12.0 that can result in a crash during heavy SAVEPOINT usage. Ticket 7f7f8026eda38. -
    8. Fix views so that they inherit column datatypes from the +
    9. Fix views so that they inherit column datatypes from the table that they are defined against, when possible.
    10. Fix the query planner so that IS and IS NULL operators are able to drive an index on a LEFT OUTER JOIN. @@ -182,10 +158,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_1_3.html sqlite3-3.44.0-0/www/releaselog/3_1_3.html --- sqlite3-3.42.0/www/releaselog/3_1_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_1_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.1.3 On 2005-02-19

    1. Fix a problem with VACUUM on databases from which tables containing AUTOINCREMENT have been dropped.
    2. @@ -125,10 +101,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_14_1.html sqlite3-3.44.0-0/www/releaselog/3_14_1.html --- sqlite3-3.42.0/www/releaselog/3_14_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_14_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.14.1 On 2016-08-11

    Prior changes from version 3.14 (2016-08-08):

    + +

    SQLite Release 3.14.1 On 2016-08-11

    Changes in version 3.14 (2016-08-08):


      @@ -134,7 +110,7 @@ SQLITE_OK_LOAD_PERMANENTLY return code from the extension entry point.
    1. Added the SQLITE_DBSTATUS_CACHE_USED_SHARED option to sqlite3_db_status(). -
    2. Add the +
    3. Add the vfsstat.c loadable extension - a VFS shim that measures I/O together with an eponymous virtual table that provides access to the measurements. @@ -148,7 +124,7 @@ eponymous virtual tables.
    4. Added the "win32-none" VFS, analogous to the "unix-none" VFS, that works like the default "win32" VFS except that it ignores all file locks. -
    5. The query planner uses a full scan of a partial index instead of a +
    6. The query planner uses a full scan of a partial index instead of a full scan of the main table, in cases where that makes sense.
    7. Allow table-valued functions to appear on the right-hand side of an IN operator.
    8. Created the dbhash.exe command-line utility. @@ -172,7 +148,7 @@ for some obscure queries following the ORDER BY LIMIT optimization introduced in version 3.12.0.
    -

    Changes in this specific patch release, version 3.14.1 (2016-08-11):

    +

    Additional changes in version 3.14.1 (2016-08-11):

    1. A performance enhancement to the page-cache "truncate" operation reduces COMMIT time by dozens of milliseconds on systems with a @@ -185,10 +161,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_14_2.html sqlite3-3.44.0-0/www/releaselog/3_14_2.html --- sqlite3-3.42.0/www/releaselog/3_14_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_14_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.14.2 On 2016-09-12

    Prior changes from version 3.14 (2016-08-08):

    + +

    SQLite Release 3.14.2 On 2016-09-12

    Changes in version 3.14 (2016-08-08):


      @@ -134,7 +110,7 @@ SQLITE_OK_LOAD_PERMANENTLY return code from the extension entry point.
    1. Added the SQLITE_DBSTATUS_CACHE_USED_SHARED option to sqlite3_db_status(). -
    2. Add the +
    3. Add the vfsstat.c loadable extension - a VFS shim that measures I/O together with an eponymous virtual table that provides access to the measurements. @@ -148,7 +124,7 @@ eponymous virtual tables.
    4. Added the "win32-none" VFS, analogous to the "unix-none" VFS, that works like the default "win32" VFS except that it ignores all file locks. -
    5. The query planner uses a full scan of a partial index instead of a +
    6. The query planner uses a full scan of a partial index instead of a full scan of the main table, in cases where that makes sense.
    7. Allow table-valued functions to appear on the right-hand side of an IN operator.
    8. Created the dbhash.exe command-line utility. @@ -172,14 +148,14 @@ for some obscure queries following the ORDER BY LIMIT optimization introduced in version 3.12.0.
    -

    Prior changes from version 3.14.1 (2016-08-11):

    +

    Additional changes in version 3.14.1 (2016-08-11):

    1. A performance enhancement to the page-cache "truncate" operation reduces COMMIT time by dozens of milliseconds on systems with a large page cache.
    2. Fix to the --rbu option of sqldiff.
    -

    Changes in this specific patch release, version 3.14.2 (2016-09-12):

    +

    Additional changes in version 3.14.2 (2016-09-12):

    1. Improved support for using the STDCALL calling convention in winsqlite3.dll.
    2. Fix the sqlite3_trace_v2() interface so that it is disabled if either the @@ -190,7 +166,7 @@ that its input is not interactive.
    3. Correct affinity computations for a SELECT on the RHS of an IN operator. Fix for ticket 199df4168c. -
    4. The ORDER BY LIMIT optimization is not valid unless the inner-most IN operator +
    5. The ORDER BY LIMIT optimization is not valid unless the inner-most IN operator loop is actually used by the query plan. Fix for ticket 0c4df46116e90f92.
    6. Fix an internal code generator problem that was causing some DELETE operations @@ -202,10 +178,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_1_4.html sqlite3-3.44.0-0/www/releaselog/3_1_4.html --- sqlite3-3.42.0/www/releaselog/3_1_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_1_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.1.4 On 2005-03-11

    1. Fix a bug in autovacuum that could cause database corruption if a CREATE UNIQUE INDEX fails because of a constraint violation. @@ -122,7 +98,7 @@ version 3.1 is turned on.
    2. The F_FULLSYNC ioctl (currently only supported on Mac OS X) is disabled if the synchronous pragma is set to something other than "full".
    3. -
    4. Add additional forward compatibility to the future version 3.2 database +
    5. Add additional forward compatibility to the future version 3.2 database file format.
    6. Fix a bug in WHERE clauses of the form (rowid<'2')
    7. New SQLITE_OMIT_... compile-time options added
    8. @@ -133,10 +109,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_14.html sqlite3-3.44.0-0/www/releaselog/3_14.html --- sqlite3-3.42.0/www/releaselog/3_14.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_14.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.14 On 2016-08-08


      @@ -133,7 +109,7 @@ SQLITE_OK_LOAD_PERMANENTLY return code from the extension entry point.
    1. Added the SQLITE_DBSTATUS_CACHE_USED_SHARED option to sqlite3_db_status(). -
    2. Add the +
    3. Add the vfsstat.c loadable extension - a VFS shim that measures I/O together with an eponymous virtual table that provides access to the measurements. @@ -147,7 +123,7 @@ eponymous virtual tables.
    4. Added the "win32-none" VFS, analogous to the "unix-none" VFS, that works like the default "win32" VFS except that it ignores all file locks. -
    5. The query planner uses a full scan of a partial index instead of a +
    6. The query planner uses a full scan of a partial index instead of a full scan of the main table, in cases where that makes sense.
    7. Allow table-valued functions to appear on the right-hand side of an IN operator.
    8. Created the dbhash.exe command-line utility. @@ -177,10 +153,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_15_0.html sqlite3-3.44.0-0/www/releaselog/3_15_0.html --- sqlite3-3.42.0/www/releaselog/3_15_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_15_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.15.0 On 2016-10-14

    1. Added support for row values.
    2. Allow deterministic SQL functions in the WHERE clause of a partial index. @@ -146,7 +122,7 @@ table are initialized doing "Xfer Optimization" on "INSERT ... SELECT" statements. Fix for ticket 7b3328086a5c116c. -
    3. Make sure the ORDER BY LIMIT optimization +
    4. Make sure the ORDER BY LIMIT optimization (from check-in 559733b09e) works with IN operators on INTEGER PRIMARY KEYs. Fix for ticket 96c1454c @@ -157,10 +133,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_15_1.html sqlite3-3.44.0-0/www/releaselog/3_15_1.html --- sqlite3-3.42.0/www/releaselog/3_15_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_15_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.15.1 On 2016-11-04

    Prior changes from version 3.15.0 (2016-10-14):

    + +

    SQLite Release 3.15.1 On 2016-11-04

    Changes in version 3.15.0 (2016-10-14):

    1. Added support for row values.
    2. Allow deterministic SQL functions in the WHERE clause of a partial index. @@ -147,19 +123,19 @@ table are initialized doing "Xfer Optimization" on "INSERT ... SELECT" statements. Fix for ticket 7b3328086a5c116c. -
    3. Make sure the ORDER BY LIMIT optimization +
    4. Make sure the ORDER BY LIMIT optimization (from check-in 559733b09e) works with IN operators on INTEGER PRIMARY KEYs. Fix for ticket 96c1454c
    -

    Changes in this specific patch release, version 3.15.1 (2016-11-04):

    +

    Additional changes in version 3.15.1 (2016-11-04):

    1. Added SQLITE_FCNTL_WIN32_GET_HANDLE file control opcode.
    2. Fix the VACUUM command so that it spills excess content to disk rather than holding everything in memory, and possible causing an out-of-memory error for larger database files. This fixes an issue introduced by version 3.15.0. -
    3. Fix a case (present since 3.8.0 - 2013-08-26) +
    4. Fix a case (present since 3.8.0 - 2013-08-26) where OR-connected terms in the ON clause of a LEFT JOIN might cause incorrect results. Ticket 34a579141b2c5ac. @@ -173,10 +149,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_15_2.html sqlite3-3.44.0-0/www/releaselog/3_15_2.html --- sqlite3-3.42.0/www/releaselog/3_15_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_15_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.15.2 On 2016-11-28

    Prior changes from version 3.15.0 (2016-10-14):

    + +

    SQLite Release 3.15.2 On 2016-11-28

    Changes in version 3.15.0 (2016-10-14):

    1. Added support for row values.
    2. Allow deterministic SQL functions in the WHERE clause of a partial index. @@ -147,19 +123,19 @@ table are initialized doing "Xfer Optimization" on "INSERT ... SELECT" statements. Fix for ticket 7b3328086a5c116c. -
    3. Make sure the ORDER BY LIMIT optimization +
    4. Make sure the ORDER BY LIMIT optimization (from check-in 559733b09e) works with IN operators on INTEGER PRIMARY KEYs. Fix for ticket 96c1454c
    -

    Prior changes from version 3.15.1 (2016-11-04):

    +

    Additional changes in version 3.15.1 (2016-11-04):

    1. Added SQLITE_FCNTL_WIN32_GET_HANDLE file control opcode.
    2. Fix the VACUUM command so that it spills excess content to disk rather than holding everything in memory, and possible causing an out-of-memory error for larger database files. This fixes an issue introduced by version 3.15.0. -
    3. Fix a case (present since 3.8.0 - 2013-08-26) +
    4. Fix a case (present since 3.8.0 - 2013-08-26) where OR-connected terms in the ON clause of a LEFT JOIN might cause incorrect results. Ticket 34a579141b2c5ac. @@ -167,11 +143,11 @@ might cause incorrect results. Ticket fef4bb4bd9185ec8f.
    -

    Changes in this specific patch release, version 3.15.2 (2016-11-28):

    +

    Additional changes in version 3.15.2 (2016-11-28):

    1. Multiple bug fixes to the row value logic that was introduced in version 3.15.0.
    2. Fix a NULL pointer dereference in ATTACH/DETACH following a maliciously constructed - syntax error. Ticket + syntax error. Ticket 2f1b168ab4d4844.
    3. Fix a crash that can occur following an out-of-memory condition in the built-in instr() function. @@ -184,10 +160,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_1_5.html sqlite3-3.44.0-0/www/releaselog/3_1_5.html --- sqlite3-3.42.0/www/releaselog/3_1_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_1_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.1.5 On 2005-03-11

    1. The ioctl on Mac OS X to control syncing to disk is F_FULLFSYNC, not F_FULLSYNC. The previous release had it wrong.
    2. @@ -122,10 +98,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_16_0.html sqlite3-3.44.0-0/www/releaselog/3_16_0.html --- sqlite3-3.42.0/www/releaselog/3_16_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_16_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.16.0 On 2017-01-02

    1. Uses 9% fewer CPU cycles. (See the CPU performance measurement report for details on how this performance increase was computed.) @@ -124,7 +100,7 @@ for the full span of supported dates.
    2. Changed the default configuration of the lookaside memory allocator from 500 slots of 128 bytes each into 125 slots of 512 bytes each. -
    3. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if +
    4. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if the "x" column appears in a LIKE or GLOB operator.
    5. Enhanced sqlite3_interrupt() so that it interrupts checkpoint operations that are in process. @@ -151,10 +127,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_16_1.html sqlite3-3.44.0-0/www/releaselog/3_16_1.html --- sqlite3-3.42.0/www/releaselog/3_16_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_16_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.16.1 On 2017-01-03

    Prior changes from version 3.16.0 (2017-01-02):

    + +

    SQLite Release 3.16.1 On 2017-01-03

    Changes in version 3.16.0 (2017-01-02):

    1. Uses 9% fewer CPU cycles. (See the CPU performance measurement report for details on how this performance increase was computed.) @@ -125,7 +101,7 @@ for the full span of supported dates.
    2. Changed the default configuration of the lookaside memory allocator from 500 slots of 128 bytes each into 125 slots of 512 bytes each. -
    3. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if +
    4. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if the "x" column appears in a LIKE or GLOB operator.
    5. Enhanced sqlite3_interrupt() so that it interrupts checkpoint operations that are in process. @@ -146,7 +122,7 @@ 2df0107b.
    6. Correctly handle the integer literal -0x8000000000000000 in the query planner.
    -

    Changes in this specific patch release, version 3.16.1 (2017-01-03):

    +

    Additional changes in version 3.16.1 (2017-01-03):

    1. Fix a bug concerning the use of row values within triggers (see ticket 8c9458e7) @@ -159,10 +135,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_16_2.html sqlite3-3.44.0-0/www/releaselog/3_16_2.html --- sqlite3-3.42.0/www/releaselog/3_16_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_16_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.16.2 On 2017-01-06

    Prior changes from version 3.16.0 (2017-01-02):

    + +

    SQLite Release 3.16.2 On 2017-01-06

    Changes in version 3.16.0 (2017-01-02):

    1. Uses 9% fewer CPU cycles. (See the CPU performance measurement report for details on how this performance increase was computed.) @@ -125,7 +101,7 @@ for the full span of supported dates.
    2. Changed the default configuration of the lookaside memory allocator from 500 slots of 128 bytes each into 125 slots of 512 bytes each. -
    3. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if +
    4. Enhanced "WHERE x NOT NULL" partial indexes so that they are usable if the "x" column appears in a LIKE or GLOB operator.
    5. Enhanced sqlite3_interrupt() so that it interrupts checkpoint operations that are in process. @@ -146,16 +122,16 @@ 2df0107b.
    6. Correctly handle the integer literal -0x8000000000000000 in the query planner.
    -

    Prior changes from version 3.16.1 (2017-01-03):

    +

    Additional changes in version 3.16.1 (2017-01-03):

    1. Fix a bug concerning the use of row values within triggers (see ticket 8c9458e7) that was in version 3.15.0 but was not reported until moments after the 3.16.0 release was published.
    -

    Changes in this specific patch release, version 3.16.2 (2017-01-06):

    +

    Additional changes in version 3.16.2 (2017-01-06):

      -
    1. Fix the REPLACE statement for +
    2. Fix the REPLACE statement for WITHOUT ROWID tables that lack secondary indexes so that it works correctly with triggers and foreign keys. This was a new bug caused by performance optimizations added in version 3.16.0. @@ -180,10 +156,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_1_6.html sqlite3-3.44.0-0/www/releaselog/3_1_6.html --- sqlite3-3.42.0/www/releaselog/3_1_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_1_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.1.6 On 2005-03-17

    1. Fix a bug that could cause database corruption when inserting record into tables with around 125 columns.
    2. @@ -125,10 +101,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_17_0.html sqlite3-3.44.0-0/www/releaselog/3_17_0.html --- sqlite3-3.42.0/www/releaselog/3_17_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_17_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.17.0 On 2017-02-13

    1. Approximately 25% better performance from the R-Tree extension.
        @@ -126,9 +102,9 @@
    2. Add the SQLITE_DEFAULT_LOOKASIDE compile-time option.
    3. Increase the default lookaside - size from 512,125 to 1200,100 - as this provides better performance while only adding 56KB - of extra memory per connection. Memory-sensitive + size from 512,125 to 1200,100 + as this provides better performance while only adding 56KB + of extra memory per connection. Memory-sensitive applications can restore the old default at compile-time, start-time, or run-time.
    4. Use compiler built-ins __builtin_sub_overflow(), __builtin_add_overflow(), @@ -154,12 +130,12 @@ extension.
    5. In the command-line shell, enhance the ".mode" command so that it restores the default column and row separators for modes "line", - "list", "column", and "tcl". + "list", "column", and "tcl".
    6. Enhance the SQLITE_DIRECT_OVERFLOW_READ option so that it works in WAL mode as long as the pages being read are not in the WAL file. -
    7. Enhance the +
    8. Enhance the Lemon parser generator - so that it can store the parser object as a stack variable rather than + so that it can store the parser object as a stack variable rather than allocating space from the heap and make use of that enhancement in the amalgamation.
    9. Other performance improvements. Uses about 6.5% fewer CPU cycles. @@ -182,10 +158,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_18_0.html sqlite3-3.44.0-0/www/releaselog/3_18_0.html --- sqlite3-3.42.0/www/releaselog/3_18_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_18_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,42 +89,18 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.18.0 On 2017-03-30

    1. Added the PRAGMA optimize command
    2. The SQLite version identifier returned by the sqlite_source_id() SQL function and the sqlite3_sourceid() C API and found in the SQLITE_SOURCE_ID macro is now a 64-digit SHA3-256 hash instead of a 40-digit SHA1 hash.
    3. Added the json_patch() SQL function to the JSON1 extension. -
    4. Enhance the LIKE optimization so that it works for arbitrary expressions on +
    5. Enhance the LIKE optimization so that it works for arbitrary expressions on the left-hand side as long as the LIKE pattern on the right-hand side does not begin with a digit or minus sign. -
    6. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in +
    7. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in the FTS3, FTS4, and FTS5 extensions to ensure that the sqlite3_last_insert_rowid() interface always returns reasonable values.
    8. Enhance PRAGMA integrity_check and PRAGMA quick_check so that they verify @@ -135,7 +111,7 @@ to put comma separators at the thousands marks for integers, if the "," format modifier is used in between the "%" and the "d" (example: "%,d").
    9. Added the -DSQLITE_MAX_MEMORY=N compile-time option. -
    10. Added the .sha3sum dot-command and the .selftest dot-command +
    11. Added the .sha3sum dot-command and the .selftest dot-command to the command-line shell
    12. Begin enforcing SQLITE_LIMIT_VDBE_OP. This can be used, for example, to prevent excessively large prepared statements in systems that accept SQL queries from @@ -161,10 +137,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_18_1.html sqlite3-3.44.0-0/www/releaselog/3_18_1.html --- sqlite3-3.42.0/www/releaselog/3_18_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_18_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,43 +89,19 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.18.1 On 2017-06-16

    Prior changes from version 3.18.0 (2017-03-30):

    + +

    SQLite Release 3.18.1 On 2017-06-16

    Changes in version 3.18.0 (2017-03-30):

    1. Added the PRAGMA optimize command
    2. The SQLite version identifier returned by the sqlite_source_id() SQL function and the sqlite3_sourceid() C API and found in the SQLITE_SOURCE_ID macro is now a 64-digit SHA3-256 hash instead of a 40-digit SHA1 hash.
    3. Added the json_patch() SQL function to the JSON1 extension. -
    4. Enhance the LIKE optimization so that it works for arbitrary expressions on +
    5. Enhance the LIKE optimization so that it works for arbitrary expressions on the left-hand side as long as the LIKE pattern on the right-hand side does not begin with a digit or minus sign. -
    6. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in +
    7. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in the FTS3, FTS4, and FTS5 extensions to ensure that the sqlite3_last_insert_rowid() interface always returns reasonable values.
    8. Enhance PRAGMA integrity_check and PRAGMA quick_check so that they verify @@ -136,7 +112,7 @@ to put comma separators at the thousands marks for integers, if the "," format modifier is used in between the "%" and the "d" (example: "%,d").
    9. Added the -DSQLITE_MAX_MEMORY=N compile-time option. -
    10. Added the .sha3sum dot-command and the .selftest dot-command +
    11. Added the .sha3sum dot-command and the .selftest dot-command to the command-line shell
    12. Begin enforcing SQLITE_LIMIT_VDBE_OP. This can be used, for example, to prevent excessively large prepared statements in systems that accept SQL queries from @@ -156,7 +132,7 @@
    13. The sqlite3_trace_v2() output for nested SQL statements should always begin with a "--" comment marker.
    -

    Changes in this specific patch release, version 3.18.1 (2017-06-16):

    +

    Additional changes in version 3.18.1 (2017-06-16):

    1. Fix a bug associated with auto_vacuum that can lead to database corruption. The bug was introduced in version 3.16.0 (2017-01-02). @@ -168,10 +144,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_18_2.html sqlite3-3.44.0-0/www/releaselog/3_18_2.html --- sqlite3-3.42.0/www/releaselog/3_18_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_18_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,43 +89,19 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.18.2 On 2017-06-17

    Prior changes from version 3.18.0 (2017-03-30):

    + +

    SQLite Release 3.18.2 On 2017-06-17

    Changes in version 3.18.0 (2017-03-30):

    1. Added the PRAGMA optimize command
    2. The SQLite version identifier returned by the sqlite_source_id() SQL function and the sqlite3_sourceid() C API and found in the SQLITE_SOURCE_ID macro is now a 64-digit SHA3-256 hash instead of a 40-digit SHA1 hash.
    3. Added the json_patch() SQL function to the JSON1 extension. -
    4. Enhance the LIKE optimization so that it works for arbitrary expressions on +
    5. Enhance the LIKE optimization so that it works for arbitrary expressions on the left-hand side as long as the LIKE pattern on the right-hand side does not begin with a digit or minus sign. -
    6. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in +
    7. Added the sqlite3_set_last_insert_rowid() interface and use the new interface in the FTS3, FTS4, and FTS5 extensions to ensure that the sqlite3_last_insert_rowid() interface always returns reasonable values.
    8. Enhance PRAGMA integrity_check and PRAGMA quick_check so that they verify @@ -136,7 +112,7 @@ to put comma separators at the thousands marks for integers, if the "," format modifier is used in between the "%" and the "d" (example: "%,d").
    9. Added the -DSQLITE_MAX_MEMORY=N compile-time option. -
    10. Added the .sha3sum dot-command and the .selftest dot-command +
    11. Added the .sha3sum dot-command and the .selftest dot-command to the command-line shell
    12. Begin enforcing SQLITE_LIMIT_VDBE_OP. This can be used, for example, to prevent excessively large prepared statements in systems that accept SQL queries from @@ -156,13 +132,13 @@
    13. The sqlite3_trace_v2() output for nested SQL statements should always begin with a "--" comment marker.
    -

    Prior changes from version 3.18.1 (2017-06-16):

    +

    Additional changes in version 3.18.1 (2017-06-16):

    1. Fix a bug associated with auto_vacuum that can lead to database corruption. The bug was introduced in version 3.16.0 (2017-01-02). Ticket fda22108.
    -

    Changes in this specific patch release, version 3.18.2 (2017-06-17):

    +

    Additional changes in version 3.18.2 (2017-06-17):

    1. Fix a bug that might cause duplicate output rows when an IN operator is used in the WHERE clause. @@ -174,10 +150,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_19_0.html sqlite3-3.44.0-0/www/releaselog/3_19_0.html --- sqlite3-3.42.0/www/releaselog/3_19_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_19_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.19.0 On 2017-05-22

    1. The SQLITE_READ authorizer callback is invoked once with a column name that is an empty string @@ -172,10 +148,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_19_1.html sqlite3-3.44.0-0/www/releaselog/3_19_1.html --- sqlite3-3.42.0/www/releaselog/3_19_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_19_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.19.1 On 2017-05-24

    Prior changes from version 3.19.0 (2017-05-22):

    + +

    SQLite Release 3.19.1 On 2017-05-24

    Changes in version 3.19.0 (2017-05-22):

    1. The SQLITE_READ authorizer callback is invoked once with a column name that is an empty string @@ -167,7 +143,7 @@ excess stack usage in the recursive descent parser. Fix for ticket 981329adeef51011052.
    -

    Changes in this specific patch release, version 3.19.1 (2017-05-24):

    +

    Additional changes in version 3.19.1 (2017-05-24):

    1. Fix a bug in the LEFT JOIN flattening optimization. Ticket cad1ab4cb7b0fc. @@ -179,10 +155,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_19_2.html sqlite3-3.44.0-0/www/releaselog/3_19_2.html --- sqlite3-3.42.0/www/releaselog/3_19_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_19_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.19.2 On 2017-05-25

    Prior changes from version 3.19.0 (2017-05-22):

    + +

    SQLite Release 3.19.2 On 2017-05-25

    Changes in version 3.19.0 (2017-05-22):

    1. The SQLITE_READ authorizer callback is invoked once with a column name that is an empty string @@ -167,13 +143,13 @@ excess stack usage in the recursive descent parser. Fix for ticket 981329adeef51011052.
    -

    Prior changes from version 3.19.1 (2017-05-24):

    +

    Additional changes in version 3.19.1 (2017-05-24):

    1. Fix a bug in the LEFT JOIN flattening optimization. Ticket cad1ab4cb7b0fc.
    2. Remove a surplus semicolon that was causing problems for older versions of MSVC.
    -

    Changes in this specific patch release, version 3.19.2 (2017-05-25):

    +

    Additional changes in version 3.19.2 (2017-05-25):

    1. Fix more bugs in the LEFT JOIN flattening optimization. Ticket 7fde638e94287d2c. @@ -184,10 +160,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_19_3.html sqlite3-3.44.0-0/www/releaselog/3_19_3.html --- sqlite3-3.42.0/www/releaselog/3_19_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_19_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.19.3 On 2017-06-08

    Prior changes from version 3.19.0 (2017-05-22):

    + +

    SQLite Release 3.19.3 On 2017-06-08

    Changes in version 3.19.0 (2017-05-22):

    1. The SQLITE_READ authorizer callback is invoked once with a column name that is an empty string @@ -167,18 +143,18 @@ excess stack usage in the recursive descent parser. Fix for ticket 981329adeef51011052.
    -

    Prior changes from version 3.19.1 (2017-05-24):

    +

    Additional changes in version 3.19.1 (2017-05-24):

    1. Fix a bug in the LEFT JOIN flattening optimization. Ticket cad1ab4cb7b0fc.
    2. Remove a surplus semicolon that was causing problems for older versions of MSVC.
    -

    Prior changes from version 3.19.2 (2017-05-25):

    +

    Additional changes in version 3.19.2 (2017-05-25):

    1. Fix more bugs in the LEFT JOIN flattening optimization. Ticket 7fde638e94287d2c.
    -

    Changes in this specific patch release, version 3.19.3 (2017-06-08):

    +

    Additional changes in version 3.19.3 (2017-06-08):

    1. Fix a bug associated with auto_vacuum that can lead to database corruption. The bug was introduced in version 3.16.0 (2017-01-02). @@ -190,10 +166,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_20_0.html sqlite3-3.44.0-0/www/releaselog/3_20_0.html --- sqlite3-3.42.0/www/releaselog/3_20_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_20_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,38 +89,14 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.20.0 On 2017-08-01

    1. Update the text of error messages returned by sqlite3_errmsg() for some error codes.
    2. Add new pointer passing interfaces. -
    3. Backwards-incompatible changes to some extensions in order to take - advantage of the improved security offered by the new +
    4. Backwards-incompatible changes to some extensions in order to take + advantage of the improved security offered by the new pointer passing interfaces:
      1. Extending FTS5 → requires sqlite3_bind_pointer() to find @@ -164,20 +140,20 @@
      2. Query planner enhancements:
        1. When generating individual loops for each ORed term of an OR scan, - move any constant WHERE expressions outside of the loop, as is + move any constant WHERE expressions outside of the loop, as is done for top-level loops.
        2. The query planner examines the values of bound parameters to help determine if a partial index is usable. -
        3. When deciding between two plans with the same estimated cost, bias +
        4. When deciding between two plans with the same estimated cost, bias the selection toward the one that does not use the sorter.
        5. Evaluate WHERE clause constraints involving correlated subqueries last, in the hope that they never have be evaluated at all. -
        6. Do not use the flattening optimization for a sub-query on the RHS +
        7. Do not use the flattening optimization for a sub-query on the RHS of a LEFT JOIN if that subquery reads data from a virtual table as doing so prevents the query planner from creating automatic indexes on the results of the sub-query, which can slow down the query.
        -
      3. Add SQLITE_STMTSTATUS_REPREPARE, SQLITE_STMTSTATUS_RUN, +
      4. Add SQLITE_STMTSTATUS_REPREPARE, SQLITE_STMTSTATUS_RUN, and SQLITE_STMTSTATUS_MEMUSED options for the sqlite3_stmt_status() interface.
      5. Provide PRAGMA functions for @@ -199,9 +175,9 @@
      6. Fix the query planner so that it knows not to use automatic indexes on the right table of LEFT JOIN if the WHERE clause uses the IS operator. Fix for ce68383bf6aba. -
      7. Ensure that the query planner knows that any column of a - flattened LEFT JOIN can be NULL even - if that column is labeled with "NOT NULL". Fix for ticket +
      8. Ensure that the query planner knows that any column of a + flattened LEFT JOIN can be NULL even + if that column is labeled with "NOT NULL". Fix for ticket 892fc34f173e99d8.
      9. Fix rare false-positives in PRAGMA integrity_check when run on a database connection with attached databases. Ticket @@ -216,10 +192,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_20_1.html sqlite3-3.44.0-0/www/releaselog/3_20_1.html --- sqlite3-3.42.0/www/releaselog/3_20_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_20_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,39 +89,15 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

      SQLite Release 3.20.1 On 2017-08-24

      Prior changes from version 3.20.0 (2017-08-01):

      + +

      SQLite Release 3.20.1 On 2017-08-24

      Changes in version 3.20.0 (2017-08-01):

      1. Update the text of error messages returned by sqlite3_errmsg() for some error codes.
      2. Add new pointer passing interfaces. -
      3. Backwards-incompatible changes to some extensions in order to take - advantage of the improved security offered by the new +
      4. Backwards-incompatible changes to some extensions in order to take + advantage of the improved security offered by the new pointer passing interfaces:
        1. Extending FTS5 → requires sqlite3_bind_pointer() to find @@ -165,20 +141,20 @@
        2. Query planner enhancements:
          1. When generating individual loops for each ORed term of an OR scan, - move any constant WHERE expressions outside of the loop, as is + move any constant WHERE expressions outside of the loop, as is done for top-level loops.
          2. The query planner examines the values of bound parameters to help determine if a partial index is usable. -
          3. When deciding between two plans with the same estimated cost, bias +
          4. When deciding between two plans with the same estimated cost, bias the selection toward the one that does not use the sorter.
          5. Evaluate WHERE clause constraints involving correlated subqueries last, in the hope that they never have be evaluated at all. -
          6. Do not use the flattening optimization for a sub-query on the RHS +
          7. Do not use the flattening optimization for a sub-query on the RHS of a LEFT JOIN if that subquery reads data from a virtual table as doing so prevents the query planner from creating automatic indexes on the results of the sub-query, which can slow down the query.
          -
        3. Add SQLITE_STMTSTATUS_REPREPARE, SQLITE_STMTSTATUS_RUN, +
        4. Add SQLITE_STMTSTATUS_REPREPARE, SQLITE_STMTSTATUS_RUN, and SQLITE_STMTSTATUS_MEMUSED options for the sqlite3_stmt_status() interface.
        5. Provide PRAGMA functions for @@ -200,9 +176,9 @@
        6. Fix the query planner so that it knows not to use automatic indexes on the right table of LEFT JOIN if the WHERE clause uses the IS operator. Fix for ce68383bf6aba. -
        7. Ensure that the query planner knows that any column of a - flattened LEFT JOIN can be NULL even - if that column is labeled with "NOT NULL". Fix for ticket +
        8. Ensure that the query planner knows that any column of a + flattened LEFT JOIN can be NULL even + if that column is labeled with "NOT NULL". Fix for ticket 892fc34f173e99d8.
        9. Fix rare false-positives in PRAGMA integrity_check when run on a database connection with attached databases. Ticket @@ -211,7 +187,7 @@ dodgy CREATE TABLE declarations are used. Ticket bc115541132dad136
        -

        Changes in this specific patch release, version 3.20.1 (2017-08-24):

        +

        Additional changes in version 3.20.1 (2017-08-24):

        1. Fix a potential memory leak in the new sqlite3_result_pointer() interface. Ticket 7486aa54b968e9b5. @@ -222,10 +198,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_0.html sqlite3-3.44.0-0/www/releaselog/3_2_0.html --- sqlite3-3.42.0/www/releaselog/3_2_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.2.0 On 2005-03-21

        1. Added support for ALTER TABLE ADD COLUMN.
        2. Added support for the "T" separator in ISO-8601 date/time strings.
        3. @@ -124,10 +100,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_21_0.html sqlite3-3.44.0-0/www/releaselog/3_21_0.html --- sqlite3-3.42.0/www/releaselog/3_21_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_21_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,34 +89,10 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.21.0 On 2017-10-24

          -
        1. Take advantage of the atomic-write capabilities in the +
        2. Take advantage of the atomic-write capabilities in the F2FS filesystem when available, for greatly reduced transaction overhead. This currently requires the SQLITE_ENABLE_BATCH_ATOMIC_WRITE compile-time option. @@ -152,7 +128,7 @@
        3. Added the swarm virtual table to the existing union virtual table extension. -
        4. Added the +
        5. Added the sqlite_dbpage virtual table for providing direct access to pages of the database file. The source code is built into the amalgamation and @@ -200,10 +176,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_1.html sqlite3-3.44.0-0/www/releaselog/3_2_1.html --- sqlite3-3.42.0/www/releaselog/3_2_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.2.1 On 2005-03-29

        1. Fix a memory allocation error in the new ADD COLUMN comment.
        2. Documentation updates
        3. @@ -122,10 +98,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_22_0.html sqlite3-3.44.0-0/www/releaselog/3_22_0.html --- sqlite3-3.42.0/www/releaselog/3_22_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_22_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.22.0 On 2018-01-22

        1. The output of sqlite3_trace_v2() now shows each individual SQL statement run within a trigger. -
        2. Add the ability to read from WAL mode databases even if the application +
        3. Add the ability to read from WAL mode databases even if the application lacks write permission on the database and its containing directory, as long as the -shm and -wal files exist in that directory.
        4. Added the rtreecheck() scalar SQL function to the R-Tree extension. @@ -128,7 +104,7 @@
        5. Added support for the "^" initial token syntax in FTS5.
        6. New extensions:
            -
          1. The Zipfile virtual table can read and write a +
          2. The Zipfile virtual table can read and write a ZIP Archive.
          3. Added the fsdir(PATH) table-valued function to the fileio.c extension, @@ -154,7 +130,7 @@ set biases the decision toward the use of co-routines.
          4. The planner avoids query plans that use indexes with unknown collating functions. -
          5. The planner omits unused LEFT JOINs even if they are not the +
          6. The planner omits unused LEFT JOINs even if they are not the right-most joins of a query.
        7. Other performance optimizations: @@ -176,12 +152,12 @@
        8. Enhance the ".lint fkey-indexes" command so that it works with WITHOUT ROWID tables.
        9. If the filename argument to the shell is a ZIP archive rather than - an SQLite database, then the shell automatically opens that ZIP + an SQLite database, then the shell automatically opens that ZIP archive using the Zipfile virtual table.
        10. Added the edit() SQL function.
        11. Added the .excel command to simplify exporting database content to a spreadsheet. -
        12. Databases are opened using +
        13. Databases are opened using Append VFS when the --append flag is used on the command line or with the .open command. @@ -218,10 +194,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_2.html sqlite3-3.44.0-0/www/releaselog/3_2_2.html --- sqlite3-3.42.0/www/releaselog/3_2_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.2.2 On 2005-06-12

        1. Added the sqlite3_db_handle() API
        2. Added the sqlite3_get_autocommit() API
        3. @@ -128,10 +104,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_23_0.html sqlite3-3.44.0-0/www/releaselog/3_23_0.html --- sqlite3-3.42.0/www/releaselog/3_23_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_23_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.23.0 On 2018-04-02

        1. Add the sqlite3_serialize() and sqlite3_deserialize() interfaces when the SQLITE_ENABLE_DESERIALIZE compile-time option is used. @@ -156,7 +132,7 @@
        2. Fix the parser to accept valid row value syntax. Ticket 7310e2fb3d046a5
        3. Fix the query planner so that it takes into account dependencies in - the arguments to table-valued functions in subexpressions in + the arguments to table-valued functions in subexpressions in the WHERE clause. Ticket 80177f0c226ff54
        4. Fix incorrect result with complex OR-connected WHERE and STAT4. @@ -215,10 +191,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_23_1.html sqlite3-3.44.0-0/www/releaselog/3_23_1.html --- sqlite3-3.42.0/www/releaselog/3_23_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_23_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.23.1 On 2018-04-10

        Prior changes from version 3.23.0 (2018-04-02):

        + +

        SQLite Release 3.23.1 On 2018-04-10

        Changes in version 3.23.0 (2018-04-02):

        1. Add the sqlite3_serialize() and sqlite3_deserialize() interfaces when the SQLITE_ENABLE_DESERIALIZE compile-time option is used. @@ -157,7 +133,7 @@
        2. Fix the parser to accept valid row value syntax. Ticket 7310e2fb3d046a5
        3. Fix the query planner so that it takes into account dependencies in - the arguments to table-valued functions in subexpressions in + the arguments to table-valued functions in subexpressions in the WHERE clause. Ticket 80177f0c226ff54
        4. Fix incorrect result with complex OR-connected WHERE and STAT4. @@ -210,7 +186,7 @@ b850dd159918af56.
      -

      Changes in this specific patch release, version 3.23.1 (2018-04-10):

      +

      Additional changes in version 3.23.1 (2018-04-10):

      1. Fix two problems in the new LEFT JOIN strength reduction optimization. Tickets 1e39b966ae9ee739 @@ -232,10 +208,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_3.html sqlite3-3.44.0-0/www/releaselog/3_2_3.html --- sqlite3-3.42.0/www/releaselog/3_2_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.2.3 On 2005-08-21

      1. Added support for the CAST operator
      2. Tcl interface allows BLOB values to be transferred to user-defined @@ -147,10 +123,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_24_0.html sqlite3-3.44.0-0/www/releaselog/3_24_0.html --- sqlite3-3.42.0/www/releaselog/3_24_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_24_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.24.0 On 2018-06-04

      1. Add support for PostgreSQL-style UPSERT.
      2. Add support for auxiliary columns in r-tree tables. @@ -133,7 +109,7 @@
      3. Added the SQLITE_DBCONFIG_RESET_DATABASE option to the sqlite3_db_config() API.

        CLI Enhancements: -

      4. Automatically intercepts the raw EXPLAIN QUERY PLAN +
      5. Automatically intercepts the raw EXPLAIN QUERY PLAN output and reformats it into an ASCII-art graph.
      6. Lines that begin with "#" and that are not in the middle of an SQL statement are interpreted as comments. @@ -142,8 +118,8 @@

        Performance:

      7. UPDATE avoids unnecessary low-level disk writes when the contents of the database file do not actually change. - For example, "UPDATE t1 SET x=25 WHERE y=?" generates no extra - disk I/O if the value in column x is already 25. Similarly, + For example, "UPDATE t1 SET x=25 WHERE y=?" generates no extra + disk I/O if the value in column x is already 25. Similarly, when doing UPDATE on records that span multiple pages, only the subset of pages that actually change are written to disk. This is a low-level performance optimization only and does not @@ -155,7 +131,7 @@ LIMIT is small relative to the number of unrestricted output rows.
      8. The OR optimization is allowed to proceed even if the OR expression has also been converted into an IN - expression. Uses of the OR optimization are now also + expression. Uses of the OR optimization are now also more clearly shown in the EXPLAIN QUERY PLAN output.
      9. The query planner is more aggressive about using automatic indexes for views and subqueries for which it is @@ -188,10 +164,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_4.html sqlite3-3.44.0-0/www/releaselog/3_2_4.html --- sqlite3-3.42.0/www/releaselog/3_2_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.2.4 On 2005-08-24

      1. Fix a bug introduced in the previous release that can cause a segfault while generating code @@ -124,10 +100,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_25_0.html sqlite3-3.44.0-0/www/releaselog/3_25_0.html --- sqlite3-3.42.0/www/releaselog/3_25_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_25_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.25.0 On 2018-09-15

      1. Add support for window functions
      2. Enhancements the ALTER TABLE command: @@ -175,10 +151,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_25_1.html sqlite3-3.44.0-0/www/releaselog/3_25_1.html --- sqlite3-3.42.0/www/releaselog/3_25_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_25_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

      SQLite Release 3.25.1 On 2018-09-18

      Prior changes from version 3.25.0 (2018-09-15):

      + +

      SQLite Release 3.25.1 On 2018-09-18

      Changes in version 3.25.0 (2018-09-15):

      1. Add support for window functions
      2. Enhancements the ALTER TABLE command: @@ -170,7 +146,7 @@ Fix for ticket c94369cae9b561b1f996d0054b
      -

      Changes in this specific patch release, version 3.25.1 (2018-09-18):

      +

      Additional changes in version 3.25.1 (2018-09-18):

      1. Extra sanity checking added to ALTER TABLE in the 3.25.0 release sometimes raises a false-positive @@ -178,7 +154,7 @@ updates a virtual table. The false-positive caused the ALTER TABLE to rollback, thus leaving the schema unchanged. Ticket b41031ea2b537237. -
      2. The fix in the 3.25.0 release for the endless-loop in the byte-code +
      3. The fix in the 3.25.0 release for the endless-loop in the byte-code associated with the ORDER BY LIMIT optimization did not work for some queries involving window functions. An additional correction is required. Ticket @@ -190,10 +166,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_25_2.html sqlite3-3.44.0-0/www/releaselog/3_25_2.html --- sqlite3-3.42.0/www/releaselog/3_25_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_25_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

      SQLite Release 3.25.2 On 2018-09-25

      Prior changes from version 3.25.0 (2018-09-15):

      + +

      SQLite Release 3.25.2 On 2018-09-25

      Changes in version 3.25.0 (2018-09-15):

      1. Add support for window functions
      2. Enhancements the ALTER TABLE command: @@ -170,7 +146,7 @@ Fix for ticket c94369cae9b561b1f996d0054b
      -

      Prior changes from version 3.25.1 (2018-09-18):

      +

      Additional changes in version 3.25.1 (2018-09-18):

      1. Extra sanity checking added to ALTER TABLE in the 3.25.0 release sometimes raises a false-positive @@ -178,13 +154,13 @@ updates a virtual table. The false-positive caused the ALTER TABLE to rollback, thus leaving the schema unchanged. Ticket b41031ea2b537237. -
      2. The fix in the 3.25.0 release for the endless-loop in the byte-code +
      3. The fix in the 3.25.0 release for the endless-loop in the byte-code associated with the ORDER BY LIMIT optimization did not work for some queries involving window functions. An additional correction is required. Ticket 510cde277783b5fb
      -

      Changes in this specific patch release, version 3.25.2 (2018-09-25):

      +

      Additional changes in version 3.25.2 (2018-09-25):

      1. Add the PRAGMA legacy_alter_table=ON command that causes the "ALTER TABLE RENAME" command to behave as it did in SQLite versions 3.24.0 @@ -204,10 +180,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_25_3.html sqlite3-3.44.0-0/www/releaselog/3_25_3.html --- sqlite3-3.42.0/www/releaselog/3_25_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_25_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

      SQLite Release 3.25.3 On 2018-11-05

      Prior changes from version 3.25.0 (2018-09-15):

      + +

      SQLite Release 3.25.3 On 2018-11-05

      Changes in version 3.25.0 (2018-09-15):

      1. Add support for window functions
      2. Enhancements the ALTER TABLE command: @@ -170,7 +146,7 @@ Fix for ticket c94369cae9b561b1f996d0054b
      -

      Prior changes from version 3.25.1 (2018-09-18):

      +

      Additional changes in version 3.25.1 (2018-09-18):

      1. Extra sanity checking added to ALTER TABLE in the 3.25.0 release sometimes raises a false-positive @@ -178,13 +154,13 @@ updates a virtual table. The false-positive caused the ALTER TABLE to rollback, thus leaving the schema unchanged. Ticket b41031ea2b537237. -
      2. The fix in the 3.25.0 release for the endless-loop in the byte-code +
      3. The fix in the 3.25.0 release for the endless-loop in the byte-code associated with the ORDER BY LIMIT optimization did not work for some queries involving window functions. An additional correction is required. Ticket 510cde277783b5fb
      -

      Prior changes from version 3.25.2 (2018-09-25):

      +

      Additional changes in version 3.25.2 (2018-09-25):

      1. Add the PRAGMA legacy_alter_table=ON command that causes the "ALTER TABLE RENAME" command to behave as it did in SQLite versions 3.24.0 @@ -198,7 +174,7 @@
      2. Fixes for various other compiler warnings and minor problems associated with obscure configurations.
      -

      Changes in this specific patch release, version 3.25.3 (2018-11-05):

      +

      Additional changes in version 3.25.3 (2018-11-05):

      1. Disallow the use of window functions in the recursive part of a CTE. Ticket e8275b415a2f03bee @@ -218,10 +194,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_5.html sqlite3-3.44.0-0/www/releaselog/3_2_5.html --- sqlite3-3.42.0/www/releaselog/3_2_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.2.5 On 2005-08-27

      1. Fix a bug effecting DELETE and UPDATE statements that changed more than 40960 rows.
      2. @@ -128,10 +104,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_26_0.html sqlite3-3.44.0-0/www/releaselog/3_26_0.html --- sqlite3-3.42.0/www/releaselog/3_26_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_26_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.26.0 On 2018-12-01

      1. Optimization: When doing an UPDATE on a table with indexes on expressions, do not update the expression indexes if they do not refer to any of the columns @@ -122,7 +98,7 @@
      2. Allow the xBestIndex() method of virtual table implementations to return SQLITE_CONSTRAINT to indicate that the proposed query plan is unusable and should not be given further consideration. -
      3. Added the SQLITE_DBCONFIG_DEFENSIVE option which disables the ability to +
      4. Added the SQLITE_DBCONFIG_DEFENSIVE option which disables the ability to create corrupt database files using ordinary SQL.
      5. Added support for read-only shadow tables when the SQLITE_DBCONFIG_DEFENSIVE option is enabled. @@ -158,10 +134,10 @@
    5. Enhancements to the session extension:
        -
      1. Added the SQLITE_CHANGESETAPPLY_INVERT flag +
      2. Added the SQLITE_CHANGESETAPPLY_INVERT flag
      3. Added the sqlite3changeset_start_v2() interface and the SQLITE_CHANGESETSTART_INVERT flag. -
      4. Added the +
      5. Added the changesetfuzz.c test-case generator utility.
      @@ -172,10 +148,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_6.html sqlite3-3.44.0-0/www/releaselog/3_2_6.html --- sqlite3-3.42.0/www/releaselog/3_2_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.2.6 On 2005-09-17

    1. Fix a bug that can cause database corruption if a VACUUM (or autovacuum) fails and is rolled back on a database that is @@ -134,10 +110,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_27_0.html sqlite3-3.44.0-0/www/releaselog/3_27_0.html --- sqlite3-3.42.0/www/releaselog/3_27_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_27_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.27.0 On 2019-02-07

    1. Added the VACUUM INTO command -
    2. Issue an SQLITE_WARNING message on the error log if a +
    3. Issue an SQLITE_WARNING message on the error log if a double-quoted string literal is used.
    4. The sqlite3_normalized_sql() interface works on any prepared statement created using sqlite3_prepare_v2() or sqlite3_prepare_v3(). It is no @@ -143,15 +119,15 @@
    5. Enhancements to the CLI, mostly to support testing and debugging of the SQLite library itself:
        -
      1. Add support for ".open --hexdb". The - "dbtotxt" utility - program used to generate the text for the "hexdb" is added to the +
      2. Add support for ".open --hexdb". The + "dbtotxt" utility + program used to generate the text for the "hexdb" is added to the source tree.
      3. Add support for the "--maxsize N" option on ".open --deserialize".
      4. Add the "--memtrace" command-line option, to show all memory allocations and deallocations.
      5. Add the ".eqp trace" option on builds with SQLITE_DEBUG, to enable - bytecode program listing with indentation and + bytecode program listing with indentation and PRAGMA vdbe_trace all in one step.
      6. Add the ".progress" command for accessing the sqlite3_progress_handler() interface. @@ -159,7 +135,7 @@
      7. Add options "--expanded", "--normalized", "--plain", "--profile", "--row", "--stmt", and "--close" to the ".trace" command.
      -
    6. Increased robustness against malicious SQL that is run against a +
    7. Increased robustness against malicious SQL that is run against a maliciously corrupted database.

      Bug fixes:

    8. Do not use a partial index to do a table scan on an IN operator. @@ -181,7 +157,7 @@ NULL value into a NOT NULL column even if the NOT NULL column has a default value of NULL. Ticket e6f1f2e34dceeb1ed6 -
    9. Fix a problem with the use of window functions used within +
    10. Fix a problem with the use of window functions used within correlated subqueries. Ticket d0866b26f83e9c55e3
    11. Fix the ALTER TABLE RENAME COLUMN command so that it works for tables @@ -198,10 +174,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_27_1.html sqlite3-3.44.0-0/www/releaselog/3_27_1.html --- sqlite3-3.42.0/www/releaselog/3_27_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_27_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.27.1 On 2019-02-08

    Prior changes from version 3.27.0 (2019-02-07):

    + +

    SQLite Release 3.27.1 On 2019-02-08

    Changes in version 3.27.0 (2019-02-07):

    1. Added the VACUUM INTO command -
    2. Issue an SQLITE_WARNING message on the error log if a +
    3. Issue an SQLITE_WARNING message on the error log if a double-quoted string literal is used.
    4. The sqlite3_normalized_sql() interface works on any prepared statement created using sqlite3_prepare_v2() or sqlite3_prepare_v3(). It is no @@ -144,15 +120,15 @@
    5. Enhancements to the CLI, mostly to support testing and debugging of the SQLite library itself:
        -
      1. Add support for ".open --hexdb". The - "dbtotxt" utility - program used to generate the text for the "hexdb" is added to the +
      2. Add support for ".open --hexdb". The + "dbtotxt" utility + program used to generate the text for the "hexdb" is added to the source tree.
      3. Add support for the "--maxsize N" option on ".open --deserialize".
      4. Add the "--memtrace" command-line option, to show all memory allocations and deallocations.
      5. Add the ".eqp trace" option on builds with SQLITE_DEBUG, to enable - bytecode program listing with indentation and + bytecode program listing with indentation and PRAGMA vdbe_trace all in one step.
      6. Add the ".progress" command for accessing the sqlite3_progress_handler() interface. @@ -160,7 +136,7 @@
      7. Add options "--expanded", "--normalized", "--plain", "--profile", "--row", "--stmt", and "--close" to the ".trace" command.
      -
    6. Increased robustness against malicious SQL that is run against a +
    7. Increased robustness against malicious SQL that is run against a maliciously corrupted database.

      Bug fixes:

    8. Do not use a partial index to do a table scan on an IN operator. @@ -182,7 +158,7 @@ NULL value into a NOT NULL column even if the NOT NULL column has a default value of NULL. Ticket e6f1f2e34dceeb1ed6 -
    9. Fix a problem with the use of window functions used within +
    10. Fix a problem with the use of window functions used within correlated subqueries. Ticket d0866b26f83e9c55e3
    11. Fix the ALTER TABLE RENAME COLUMN command so that it works for tables @@ -192,7 +168,7 @@ a table that uses an expression index. Ticket bb4bdb9f7f654b0bb9
    -

    Changes in this specific patch release, version 3.27.1 (2019-02-08):

    +

    Additional changes in version 3.27.1 (2019-02-08):

    1. Fix a bug in the query optimizer: an adverse interaction between the OR optimization and the optimization that tries to use values @@ -206,10 +182,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_27_2.html sqlite3-3.44.0-0/www/releaselog/3_27_2.html --- sqlite3-3.42.0/www/releaselog/3_27_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_27_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.27.2 On 2019-02-25

    Prior changes from version 3.27.0 (2019-02-07):

    + +

    SQLite Release 3.27.2 On 2019-02-25

    Changes in version 3.27.0 (2019-02-07):

    1. Added the VACUUM INTO command -
    2. Issue an SQLITE_WARNING message on the error log if a +
    3. Issue an SQLITE_WARNING message on the error log if a double-quoted string literal is used.
    4. The sqlite3_normalized_sql() interface works on any prepared statement created using sqlite3_prepare_v2() or sqlite3_prepare_v3(). It is no @@ -144,15 +120,15 @@
    5. Enhancements to the CLI, mostly to support testing and debugging of the SQLite library itself:
        -
      1. Add support for ".open --hexdb". The - "dbtotxt" utility - program used to generate the text for the "hexdb" is added to the +
      2. Add support for ".open --hexdb". The + "dbtotxt" utility + program used to generate the text for the "hexdb" is added to the source tree.
      3. Add support for the "--maxsize N" option on ".open --deserialize".
      4. Add the "--memtrace" command-line option, to show all memory allocations and deallocations.
      5. Add the ".eqp trace" option on builds with SQLITE_DEBUG, to enable - bytecode program listing with indentation and + bytecode program listing with indentation and PRAGMA vdbe_trace all in one step.
      6. Add the ".progress" command for accessing the sqlite3_progress_handler() interface. @@ -160,7 +136,7 @@
      7. Add options "--expanded", "--normalized", "--plain", "--profile", "--row", "--stmt", and "--close" to the ".trace" command.
      -
    6. Increased robustness against malicious SQL that is run against a +
    7. Increased robustness against malicious SQL that is run against a maliciously corrupted database.

      Bug fixes:

    8. Do not use a partial index to do a table scan on an IN operator. @@ -182,7 +158,7 @@ NULL value into a NOT NULL column even if the NOT NULL column has a default value of NULL. Ticket e6f1f2e34dceeb1ed6 -
    9. Fix a problem with the use of window functions used within +
    10. Fix a problem with the use of window functions used within correlated subqueries. Ticket d0866b26f83e9c55e3
    11. Fix the ALTER TABLE RENAME COLUMN command so that it works for tables @@ -192,7 +168,7 @@ a table that uses an expression index. Ticket bb4bdb9f7f654b0bb9
    -

    Prior changes from version 3.27.1 (2019-02-08):

    +

    Additional changes in version 3.27.1 (2019-02-08):

    1. Fix a bug in the query optimizer: an adverse interaction between the OR optimization and the optimization that tries to use values @@ -200,9 +176,9 @@ expression. Ticket 4e8e4857d32d401f
    -

    Changes in this specific patch release, version 3.27.2 (2019-02-25):

    +

    Additional changes in version 3.27.2 (2019-02-25):

      -
    1. Fix a bug in the IN operator that was introduced by an +
    2. Fix a bug in the IN operator that was introduced by an attempted optimization in version 3.27.0. Ticket df46dfb631f75694
    3. Fix a bug causing a crash when a window function is misused. Ticket @@ -215,10 +191,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_7.html sqlite3-3.44.0-0/www/releaselog/3_2_7.html --- sqlite3-3.42.0/www/releaselog/3_2_7.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_7.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.2.7 On 2005-09-24

    1. GROUP BY now considers NULLs to be equal again, as it should
    2. @@ -129,10 +105,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_28_0.html sqlite3-3.44.0-0/www/releaselog/3_28_0.html --- sqlite3-3.42.0/www/releaselog/3_28_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_28_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.28.0 On 2019-04-16

    1. Enhanced window functions:
        @@ -155,7 +131,7 @@ new --insert option that works like --update used to work.
    2. Added the fossildelta.c - extension that can create, apply, and deconstruct the + extension that can create, apply, and deconstruct the Fossil DVCS file delta format that is used by the RBU extension.
    3. Added the SQLITE_DBCONFIG_WRITABLE_SCHEMA verb for the sqlite3_db_config() @@ -174,10 +150,10 @@ tokenizer method object even without the sqlite3_db_config(SQLITE_DBCONFIG_ENABLE_FTS3_TOKENIZER) setting if the second argument is a bound parameter -
    +
  • Improved robustness against corrupt database files.
  • Miscellaneous performance enhancements -
  • Established a Git mirror of the offical SQLite source tree. +
  • Established a Git mirror of the offical SQLite source tree. The canonical sources for SQLite are maintained using the Fossil DVCS at https://sqlite.org/src. The Git mirror can be seen at https://github.com/sqlite/sqlite. @@ -188,10 +164,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_2_8.html sqlite3-3.44.0-0/www/releaselog/3_2_8.html --- sqlite3-3.42.0/www/releaselog/3_2_8.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_2_8.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,45 +89,20 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.2.8 On 2005-12-19

    1. Fix an obscure bug that can cause database corruption under the -following unusual circumstances: A large INSERT or UPDATE statement which +following unusual circumstances: A large INSERT or UPDATE statement which is part of an even larger transaction fails due to a uniqueness constraint but the containing transaction commits.

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_29_0.html sqlite3-3.44.0-0/www/releaselog/3_29_0.html --- sqlite3-3.42.0/www/releaselog/3_29_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_29_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.29.0 On 2019-07-10

    1. Added the SQLITE_DBCONFIG_DQS_DML and SQLITE_DBCONFIG_DQS_DDL actions to sqlite3_db_config() for activating and deactivating @@ -150,10 +126,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_30_0.html sqlite3-3.44.0-0/www/releaselog/3_30_0.html --- sqlite3-3.42.0/www/releaselog/3_30_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_30_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.30.0 On 2019-10-04

    1. Add support for the FILTER clause on aggregate functions.
    2. Add support for the NULLS FIRST and NULLS LAST syntax in ORDER BY clauses. @@ -150,10 +126,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_30_1.html sqlite3-3.44.0-0/www/releaselog/3_30_1.html --- sqlite3-3.42.0/www/releaselog/3_30_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_30_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.30.1 On 2019-10-10

    Prior changes from version 3.30.0 (2019-10-04):

    + +

    SQLite Release 3.30.1 On 2019-10-10

    Changes in version 3.30.0 (2019-10-04):

    1. Add support for the FILTER clause on aggregate functions.
    2. Add support for the NULLS FIRST and NULLS LAST syntax in ORDER BY clauses. @@ -145,10 +121,10 @@ being used inside triggers and views.
    3. The legacy SQLITE_ENABLE_STAT3 compile-time option is now a no-op.
    -

    Changes in this specific patch release, version 3.30.1 (2019-10-10):

    +

    Additional changes in version 3.30.1 (2019-10-10):

    1. Fix a bug in the query flattener that might cause a segfault -for nested queries that use the new +for nested queries that use the new FILTER clause on aggregate functions. Ticket 1079ad19993d13fa
    2. Cherrypick fixes for other obscure problems found since the 3.30.0 @@ -160,10 +136,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_0.html sqlite3-3.44.0-0/www/releaselog/3_3_0.html --- sqlite3-3.42.0/www/releaselog/3_3_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.3.0 On 2006-01-11

    1. CHECK constraints
    2. IF EXISTS and IF NOT EXISTS clauses on CREATE/DROP TABLE/INDEX.
    3. @@ -135,10 +111,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_10.html sqlite3-3.44.0-0/www/releaselog/3_3_10.html --- sqlite3-3.42.0/www/releaselog/3_3_10.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_10.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,54 +89,29 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.3.10 On 2007-01-09

      -
    1. Fix bugs in the implementation of the new +
    2. Fix bugs in the implementation of the new sqlite3_prepare_v2() API that can lead to segfaults.
    3. -
    4. Fix 1-second round-off errors in the +
    5. Fix 1-second round-off errors in the strftime() function
    6. Enhance the Windows OS layer to provide detailed error codes
    7. Work around a win2k problem so that SQLite can use single-character database file names
    8. The user_version and -schema_version pragmas +schema_version pragmas correctly set their column names in the result set
    9. Documentation updates

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_31_0.html sqlite3-3.44.0-0/www/releaselog/3_31_0.html --- sqlite3-3.42.0/www/releaselog/3_31_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_31_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.31.0 On 2020-01-22

    1. Add support for generated columns.
    2. Add the sqlite3_hard_heap_limit64() interface and the corresponding @@ -161,10 +137,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_11.html sqlite3-3.44.0-0/www/releaselog/3_3_11.html --- sqlite3-3.42.0/www/releaselog/3_3_11.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_11.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,34 +89,10 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.3.11 On 2007-01-22

      -
    1. Fix another bug in the implementation of the new +
    2. Fix another bug in the implementation of the new sqlite3_prepare_v2() API. We'll get it right eventually...
    3. Fix a bug in the IS NULL optimization that was added in version 3.3.9 - @@ -129,10 +105,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_31_1.html sqlite3-3.44.0-0/www/releaselog/3_31_1.html --- sqlite3-3.42.0/www/releaselog/3_31_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_31_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    SQLite Release 3.31.1 On 2020-01-27

    Prior changes from version 3.31.0 (2020-01-22):

    + +

    SQLite Release 3.31.1 On 2020-01-27

    Changes in version 3.31.0 (2020-01-22):

    1. Add support for generated columns.
    2. Add the sqlite3_hard_heap_limit64() interface and the corresponding @@ -156,11 +132,11 @@ tables with both generated columns and descending indexes. Ticket 6484e6ce678fffab
    -

    Changes in this specific patch release, version 3.31.1 (2020-01-27):

    +

    Additional changes in version 3.31.1 (2020-01-27):

    1. Revert the data layout for an internal-use-only SQLite data structure. Applications that use SQLite should never reference internal SQLite - data structures, but some do anyhow, and a change to one such + data structures, but some do anyhow, and a change to one such data structure in 3.30.0 broke a popular and widely-deployed application. Reverting that change in SQLite, at least temporarily, gives developers of misbehaving applications time to fix their code. @@ -174,10 +150,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_12.html sqlite3-3.44.0-0/www/releaselog/3_3_12.html --- sqlite3-3.42.0/www/releaselog/3_3_12.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_12.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.3.12 On 2007-01-27

    1. Fix another bug in the IS NULL optimization that was added in version 3.3.9.
    2. @@ -127,10 +103,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_13.html sqlite3-3.44.0-0/www/releaselog/3_3_13.html --- sqlite3-3.42.0/www/releaselog/3_3_13.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_13.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.3.13 On 2007-02-13

    1. Add a "fragmentation" measurement in the output of sqlite3_analyzer.
    2. Add the COLLATE operator used to explicitly set the collating sequence @@ -122,9 +98,9 @@ additional testing.
    3. Allow up to 64 tables in a join - the old limit was 32.
    4. Added two new experimental functions: -randomblob() and -hex(). -Their intended use is to facilitate generating +randomBlob() and +hex(). +Their intended use is to facilitate generating UUIDs.
    5. Fix a problem where @@ -138,10 +114,9 @@

    A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

    - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_14.html sqlite3-3.44.0-0/www/releaselog/3_3_14.html --- sqlite3-3.42.0/www/releaselog/3_3_14.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_14.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Release 3.3.14 On 2007-04-02

    1. Fix a bug (ticket #2273) that could cause a segfault when the IN operator - is used one term of a two-column index and the right-hand side of + is used one one term of a two-column index and the right-hand side of the IN operator contains a NULL.
    2. Added a new OS interface method for determining the sector size of underlying media: sqlite3OsSectorSize().
    3. @@ -130,7 +106,7 @@
      1. Do not read the last page of an overflow chain when deleting the row - just add that page to the freelist.
      2. -
      3. Do not store pages being deleted in the +
      4. Do not store pages being deleted in the rollback journal.
      5. Do not read in the (meaningless) content of pages extracted from the freelist.
      6. @@ -149,7 +125,7 @@ limitations.
      7. Add a makefile target "sqlite3.c" that builds an amalgamation containing the core SQLite library C code in a single file.
      8. -
      9. Get the library working correctly when compiled +
      10. Get the library working correctly when compiled with GCC option "-fstrict-aliasing".
      11. Removed the vestigal SQLITE_PROTOCOL error.
      12. Improvements to test coverage, other minor bugs fixed, @@ -159,10 +135,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_15.html sqlite3-3.44.0-0/www/releaselog/3_3_15.html --- sqlite3-3.42.0/www/releaselog/3_3_15.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_15.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.3.15 On 2007-04-09

      1. Fix a bug introduced in 3.3.14 that caused a rollback of CREATE TEMP TABLE to leave the database connection wedged.
      2. @@ -129,10 +105,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_16.html sqlite3-3.44.0-0/www/releaselog/3_3_16.html --- sqlite3-3.42.0/www/releaselog/3_3_16.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_16.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.3.16 On 2007-04-18

      1. Fix a bug that caused VACUUM to fail if NULLs appeared in a UNIQUE column.
      2. @@ -130,10 +106,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_17.html sqlite3-3.44.0-0/www/releaselog/3_3_17.html --- sqlite3-3.42.0/www/releaselog/3_3_17.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_17.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.3.17 On 2007-04-25

      1. When the "write_version" value of the database header is larger than what the library understands, make the database read-only instead of @@ -124,10 +100,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_1.html sqlite3-3.44.0-0/www/releaselog/3_3_1.html --- sqlite3-3.42.0/www/releaselog/3_3_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.3.1 On 2006-01-16

      1. Countless bug fixes
      2. Speed improvements
      3. @@ -124,10 +100,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_32_0.html sqlite3-3.44.0-0/www/releaselog/3_32_0.html --- sqlite3-3.42.0/www/releaselog/3_32_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_32_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.32.0 On 2020-05-22

      1. Added support for approximate ANALYZE using the PRAGMA analysis_limit command. @@ -155,10 +131,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_32_1.html sqlite3-3.44.0-0/www/releaselog/3_32_1.html --- sqlite3-3.42.0/www/releaselog/3_32_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_32_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

      SQLite Release 3.32.1 On 2020-05-25

      Prior changes from version 3.32.0 (2020-05-22):

      + +

      SQLite Release 3.32.1 On 2020-05-25

      Changes in version 3.32.0 (2020-05-22):

      1. Added support for approximate ANALYZE using the PRAGMA analysis_limit command. @@ -151,7 +127,7 @@
      2. The ESCAPE clause of a LIKE operator now overrides wildcard characters, so that the behavior matches what PostgreSQL does.
      -

      Changes in this specific patch release, version 3.32.1 (2020-05-25):

      +

      Additional changes in version 3.32.1 (2020-05-25):

      1. Fix two long-standing bugs that allow malicious SQL statements to crash the process that is running SQLite. These bugs were announced @@ -165,10 +141,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_32_2.html sqlite3-3.44.0-0/www/releaselog/3_32_2.html --- sqlite3-3.42.0/www/releaselog/3_32_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_32_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

      SQLite Release 3.32.2 On 2020-06-04

      Prior changes from version 3.32.0 (2020-05-22):

      + +

      SQLite Release 3.32.2 On 2020-06-04

      Changes in version 3.32.0 (2020-05-22):

      1. Added support for approximate ANALYZE using the PRAGMA analysis_limit command. @@ -151,7 +127,7 @@
      2. The ESCAPE clause of a LIKE operator now overrides wildcard characters, so that the behavior matches what PostgreSQL does.
      -

      Prior changes from version 3.32.1 (2020-05-25):

      +

      Additional changes in version 3.32.1 (2020-05-25):

      1. Fix two long-standing bugs that allow malicious SQL statements to crash the process that is running SQLite. These bugs were announced @@ -159,7 +135,7 @@ not specific to the 3.32.0 release.
      2. Other minor compiler-warning fixes and whatnot.
      -

      Changes in this specific patch release, version 3.32.2 (2020-06-04):

      +

      Additional changes in version 3.32.2 (2020-06-04):

      1. Fix a long-standing bug in the byte-code engine that can cause a COMMIT command report as success when in fact it failed @@ -172,10 +148,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_32_3.html sqlite3-3.44.0-0/www/releaselog/3_32_3.html --- sqlite3-3.42.0/www/releaselog/3_32_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_32_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

      SQLite Release 3.32.3 On 2020-06-18

      Prior changes from version 3.32.0 (2020-05-22):

      + +

      SQLite Release 3.32.3 On 2020-06-18

      Changes in version 3.32.0 (2020-05-22):

      1. Added support for approximate ANALYZE using the PRAGMA analysis_limit command. @@ -151,7 +127,7 @@
      2. The ESCAPE clause of a LIKE operator now overrides wildcard characters, so that the behavior matches what PostgreSQL does.
      -

      Prior changes from version 3.32.1 (2020-05-25):

      +

      Additional changes in version 3.32.1 (2020-05-25):

      1. Fix two long-standing bugs that allow malicious SQL statements to crash the process that is running SQLite. These bugs were announced @@ -159,14 +135,14 @@ not specific to the 3.32.0 release.
      2. Other minor compiler-warning fixes and whatnot.
      -

      Prior changes from version 3.32.2 (2020-06-04):

      +

      Additional changes in version 3.32.2 (2020-06-04):

      1. Fix a long-standing bug in the byte-code engine that can cause a COMMIT command report as success when in fact it failed to commit. Ticket 810dc8038872e212
      -

      Changes in this specific patch release, version 3.32.3 (2020-06-18):

      +

      Additional changes in version 3.32.3 (2020-06-18):

      1. Various minor bug fixes including fixes for tickets 8f157e8010b22af0, @@ -182,10 +158,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_2.html sqlite3-3.44.0-0/www/releaselog/3_3_2.html --- sqlite3-3.42.0/www/releaselog/3_3_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.3.2 On 2006-01-24

      1. Bug fixes and speed improvements. Improved test coverage.
      2. Changes to the OS-layer interface: mutexes must now be recursive.
      3. @@ -124,10 +100,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_33_0.html sqlite3-3.44.0-0/www/releaselog/3_33_0.html --- sqlite3-3.42.0/www/releaselog/3_33_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_33_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.33.0 On 2020-08-14

      1. Support for UPDATE FROM following the PostgreSQL syntax.
      2. Increase the maximum size of database files to 281 TB. @@ -156,10 +132,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_3.html sqlite3-3.44.0-0/www/releaselog/3_3_3.html --- sqlite3-3.42.0/www/releaselog/3_3_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.3.3 On 2006-01-31

      1. Removed support for an ON CONFLICT clause on CREATE INDEX - it never worked correctly so this should not present any backward compatibility @@ -129,10 +105,9 @@

      A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

      - diff -Nru sqlite3-3.42.0/www/releaselog/3_34_0.html sqlite3-3.44.0-0/www/releaselog/3_34_0.html --- sqlite3-3.42.0/www/releaselog/3_34_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_34_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

      SQLite Release 3.34.0 On 2020-12-01

      1. Added the sqlite3_txn_state() interface for reporting on the current transaction state of the database connection. @@ -142,10 +118,10 @@
      2. Query planner improvements:
        1. Improved estimates for the cost of running a DISTINCT operator. -
        2. When doing an UPDATE or DELETE using a multi-column index where - only a few of the earlier columns of the index are useful for the - index lookup, postpone doing the main table seek until after all - WHERE clause constraints have been evaluated, in case those +
        3. When doing an UPDATE or DELETE using a multi-column index where + only a few of the earlier columns of the index are useful for the + index lookup, postpone doing the main table seek until after all + WHERE clause constraints have been evaluated, in case those constraints can be covered by unused later terms of the index, thus avoiding unnecessary main table seeks.
        4. The new OP_SeekScan opcode is used to improve performance of @@ -173,10 +149,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_34_1.html sqlite3-3.44.0-0/www/releaselog/3_34_1.html --- sqlite3-3.42.0/www/releaselog/3_34_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_34_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.34.1 On 2021-01-20

        Prior changes from version 3.34.0 (2020-12-01):

        + +

        SQLite Release 3.34.1 On 2021-01-20

        Changes in version 3.34.0 (2020-12-01):

        1. Added the sqlite3_txn_state() interface for reporting on the current transaction state of the database connection. @@ -143,10 +119,10 @@
        2. Query planner improvements:
          1. Improved estimates for the cost of running a DISTINCT operator. -
          2. When doing an UPDATE or DELETE using a multi-column index where - only a few of the earlier columns of the index are useful for the - index lookup, postpone doing the main table seek until after all - WHERE clause constraints have been evaluated, in case those +
          3. When doing an UPDATE or DELETE using a multi-column index where + only a few of the earlier columns of the index are useful for the + index lookup, postpone doing the main table seek until after all + WHERE clause constraints have been evaluated, in case those constraints can be covered by unused later terms of the index, thus avoiding unnecessary main table seeks.
          4. The new OP_SeekScan opcode is used to improve performance of @@ -167,7 +143,7 @@ Pikchr scripts and rendered as SVG for improved legibility and ease of maintenance.
          -

          Changes in this specific patch release, version 3.34.1 (2021-01-20):

          +

          Additional changes in version 3.34.1 (2021-01-20):

          1. Fix a potential use-after-free bug when processing a a subquery with both a correlated WHERE clause and a "HAVING 0" clause and where the parent @@ -181,10 +157,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_4.html sqlite3-3.44.0-0/www/releaselog/3_3_4.html --- sqlite3-3.42.0/www/releaselog/3_3_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.3.4 On 2006-02-11

          1. Fix a blunder in the Unix mutex implementation that can lead to deadlock on multithreaded systems.
          2. @@ -131,10 +107,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_35_0.html sqlite3-3.44.0-0/www/releaselog/3_35_0.html --- sqlite3-3.42.0/www/releaselog/3_35_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_35_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.35.0 On 2021-03-12

          1. Added built-in SQL math functions(). (Requires the -DSQLITE_ENABLE_MATH_FUNCTIONS compile-time option.) @@ -141,7 +117,7 @@
          2. Query planner/optimizer improvements:
            1. Enhancements to the min/max optimization so that it works better - with the IN operator and the OP_SeekScan optimization of the + with the IN operator and the OP_SeekScan optimization of the previous release.
            2. Attempt to process EXISTS operators in the WHERE clause as if they were IN operators, in cases where this is a valid transformation @@ -186,10 +162,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_35_1.html sqlite3-3.44.0-0/www/releaselog/3_35_1.html --- sqlite3-3.42.0/www/releaselog/3_35_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_35_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

            SQLite Release 3.35.1 On 2021-03-15

            Prior changes from version 3.35.0 (2021-03-12):

            + +

            SQLite Release 3.35.1 On 2021-03-15

            Changes in version 3.35.0 (2021-03-12):

            1. Added built-in SQL math functions(). (Requires the -DSQLITE_ENABLE_MATH_FUNCTIONS compile-time option.) @@ -142,7 +118,7 @@
            2. Query planner/optimizer improvements:
              1. Enhancements to the min/max optimization so that it works better - with the IN operator and the OP_SeekScan optimization of the + with the IN operator and the OP_SeekScan optimization of the previous release.
              2. Attempt to process EXISTS operators in the WHERE clause as if they were IN operators, in cases where this is a valid transformation @@ -181,7 +157,7 @@ is an "ESCAPE '_'" clause.
            -

            Changes in this specific patch release, version 3.35.1 (2021-03-15):

            +

            Additional changes in version 3.35.1 (2021-03-15):

            1. Fix a bug in the new DROP COLUMN feature when used on columns that are indexed and that are quoted in the index @@ -194,10 +170,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_35_2.html sqlite3-3.44.0-0/www/releaselog/3_35_2.html --- sqlite3-3.42.0/www/releaselog/3_35_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_35_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

            SQLite Release 3.35.2 On 2021-03-17

            Prior changes from version 3.35.0 (2021-03-12):

            + +

            SQLite Release 3.35.2 On 2021-03-17

            Changes in version 3.35.0 (2021-03-12):

            1. Added built-in SQL math functions(). (Requires the -DSQLITE_ENABLE_MATH_FUNCTIONS compile-time option.) @@ -142,7 +118,7 @@
            2. Query planner/optimizer improvements:
              1. Enhancements to the min/max optimization so that it works better - with the IN operator and the OP_SeekScan optimization of the + with the IN operator and the OP_SeekScan optimization of the previous release.
              2. Attempt to process EXISTS operators in the WHERE clause as if they were IN operators, in cases where this is a valid transformation @@ -181,17 +157,17 @@ is an "ESCAPE '_'" clause.
            -

            Prior changes from version 3.35.1 (2021-03-15):

            +

            Additional changes in version 3.35.1 (2021-03-15):

            1. Fix a bug in the new DROP COLUMN feature when used on columns that are indexed and that are quoted in the index definition.
            2. Improve the built-in documentation for the .dump command in the CLI.
            -

            Changes in this specific patch release, version 3.35.2 (2021-03-17):

            +

            Additional changes in version 3.35.2 (2021-03-17):

              -
            1. Fix a problem in the - appendvfs.c +
            2. Fix a problem in the + appendvfs.c extension that was introduced into version 3.35.0.
            3. Ensure that date/time functions with no arguments (which generate responses that depend on the current time) are treated as @@ -210,10 +186,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_35_3.html sqlite3-3.44.0-0/www/releaselog/3_35_3.html --- sqlite3-3.42.0/www/releaselog/3_35_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_35_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

            SQLite Release 3.35.3 On 2021-03-26

            Prior changes from version 3.35.0 (2021-03-12):

            + +

            SQLite Release 3.35.3 On 2021-03-26

            Changes in version 3.35.0 (2021-03-12):

            1. Added built-in SQL math functions(). (Requires the -DSQLITE_ENABLE_MATH_FUNCTIONS compile-time option.) @@ -142,7 +118,7 @@
            2. Query planner/optimizer improvements:
              1. Enhancements to the min/max optimization so that it works better - with the IN operator and the OP_SeekScan optimization of the + with the IN operator and the OP_SeekScan optimization of the previous release.
              2. Attempt to process EXISTS operators in the WHERE clause as if they were IN operators, in cases where this is a valid transformation @@ -181,17 +157,17 @@ is an "ESCAPE '_'" clause.
            -

            Prior changes from version 3.35.1 (2021-03-15):

            +

            Additional changes in version 3.35.1 (2021-03-15):

            1. Fix a bug in the new DROP COLUMN feature when used on columns that are indexed and that are quoted in the index definition.
            2. Improve the built-in documentation for the .dump command in the CLI.
            -

            Prior changes from version 3.35.2 (2021-03-17):

            +

            Additional changes in version 3.35.2 (2021-03-17):

              -
            1. Fix a problem in the - appendvfs.c +
            2. Fix a problem in the + appendvfs.c extension that was introduced into version 3.35.0.
            3. Ensure that date/time functions with no arguments (which generate responses that depend on the current time) are treated as @@ -204,7 +180,7 @@ See forum thread 140a67d3d2 for details.
            -

            Changes in this specific patch release, version 3.35.3 (2021-03-26):

            +

            Additional changes in version 3.35.3 (2021-03-26):

            1. Enhance the OP_OpenDup opcode of the bytecode engine so that it works even if the cursor being duplicated itself came from OP_OpenDup. Fix for @@ -221,7 +197,7 @@ Forum post aa5a0431c99e.
            2. Fix some incorrect assert() statements.
            3. Fix to the SELECT statement syntax diagram so that the FROM clause - syntax is shown correctly. + syntax is shown correctly. Forum post 9ed02582fe.
            4. Fix the EBCDIC character classifier so that it understands newlines as whitespace. Forum post 58540ce22dcd. @@ -237,10 +213,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_35_4.html sqlite3-3.44.0-0/www/releaselog/3_35_4.html --- sqlite3-3.42.0/www/releaselog/3_35_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_35_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

            SQLite Release 3.35.4 On 2021-04-02

            Prior changes from version 3.35.0 (2021-03-12):

            + +

            SQLite Release 3.35.4 On 2021-04-02

            Changes in version 3.35.0 (2021-03-12):

            1. Added built-in SQL math functions(). (Requires the -DSQLITE_ENABLE_MATH_FUNCTIONS compile-time option.) @@ -142,7 +118,7 @@
            2. Query planner/optimizer improvements:
              1. Enhancements to the min/max optimization so that it works better - with the IN operator and the OP_SeekScan optimization of the + with the IN operator and the OP_SeekScan optimization of the previous release.
              2. Attempt to process EXISTS operators in the WHERE clause as if they were IN operators, in cases where this is a valid transformation @@ -181,17 +157,17 @@ is an "ESCAPE '_'" clause.
            -

            Prior changes from version 3.35.1 (2021-03-15):

            +

            Additional changes in version 3.35.1 (2021-03-15):

            1. Fix a bug in the new DROP COLUMN feature when used on columns that are indexed and that are quoted in the index definition.
            2. Improve the built-in documentation for the .dump command in the CLI.
            -

            Prior changes from version 3.35.2 (2021-03-17):

            +

            Additional changes in version 3.35.2 (2021-03-17):

              -
            1. Fix a problem in the - appendvfs.c +
            2. Fix a problem in the + appendvfs.c extension that was introduced into version 3.35.0.
            3. Ensure that date/time functions with no arguments (which generate responses that depend on the current time) are treated as @@ -204,7 +180,7 @@ See forum thread 140a67d3d2 for details.
            -

            Prior changes from version 3.35.3 (2021-03-26):

            +

            Additional changes in version 3.35.3 (2021-03-26):

            1. Enhance the OP_OpenDup opcode of the bytecode engine so that it works even if the cursor being duplicated itself came from OP_OpenDup. Fix for @@ -221,7 +197,7 @@ Forum post aa5a0431c99e.
            2. Fix some incorrect assert() statements.
            3. Fix to the SELECT statement syntax diagram so that the FROM clause - syntax is shown correctly. + syntax is shown correctly. Forum post 9ed02582fe.
            4. Fix the EBCDIC character classifier so that it understands newlines as whitespace. Forum post 58540ce22dcd. @@ -231,9 +207,9 @@ avoid trying to materialize a table with an infinite number of rows. Forum post b52a020ce4.
            -

            Changes in this specific patch release, version 3.35.4 (2021-04-02):

            +

            Additional changes in version 3.35.4 (2021-04-02):

              -
            1. Fix a defect in the query planner optimization identified by +
            2. Fix a defect in the query planner optimization identified by item 8b above. Ticket de7db14784a08053.
            3. Fix a defect in the new RETURNING syntax. Ticket @@ -250,10 +226,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_35_5.html sqlite3-3.44.0-0/www/releaselog/3_35_5.html --- sqlite3-3.42.0/www/releaselog/3_35_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_35_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

            SQLite Release 3.35.5 On 2021-04-19

            Prior changes from version 3.35.0 (2021-03-12):

            + +

            SQLite Release 3.35.5 On 2021-04-19

            Changes in version 3.35.0 (2021-03-12):

            1. Added built-in SQL math functions(). (Requires the -DSQLITE_ENABLE_MATH_FUNCTIONS compile-time option.) @@ -142,7 +118,7 @@
            2. Query planner/optimizer improvements:
              1. Enhancements to the min/max optimization so that it works better - with the IN operator and the OP_SeekScan optimization of the + with the IN operator and the OP_SeekScan optimization of the previous release.
              2. Attempt to process EXISTS operators in the WHERE clause as if they were IN operators, in cases where this is a valid transformation @@ -181,17 +157,17 @@ is an "ESCAPE '_'" clause.
            -

            Prior changes from version 3.35.1 (2021-03-15):

            +

            Additional changes in version 3.35.1 (2021-03-15):

            1. Fix a bug in the new DROP COLUMN feature when used on columns that are indexed and that are quoted in the index definition.
            2. Improve the built-in documentation for the .dump command in the CLI.
            -

            Prior changes from version 3.35.2 (2021-03-17):

            +

            Additional changes in version 3.35.2 (2021-03-17):

              -
            1. Fix a problem in the - appendvfs.c +
            2. Fix a problem in the + appendvfs.c extension that was introduced into version 3.35.0.
            3. Ensure that date/time functions with no arguments (which generate responses that depend on the current time) are treated as @@ -204,7 +180,7 @@ See forum thread 140a67d3d2 for details.
            -

            Prior changes from version 3.35.3 (2021-03-26):

            +

            Additional changes in version 3.35.3 (2021-03-26):

            1. Enhance the OP_OpenDup opcode of the bytecode engine so that it works even if the cursor being duplicated itself came from OP_OpenDup. Fix for @@ -221,7 +197,7 @@ Forum post aa5a0431c99e.
            2. Fix some incorrect assert() statements.
            3. Fix to the SELECT statement syntax diagram so that the FROM clause - syntax is shown correctly. + syntax is shown correctly. Forum post 9ed02582fe.
            4. Fix the EBCDIC character classifier so that it understands newlines as whitespace. Forum post 58540ce22dcd. @@ -231,9 +207,9 @@ avoid trying to materialize a table with an infinite number of rows. Forum post b52a020ce4.
            -

            Prior changes from version 3.35.4 (2021-04-02):

            +

            Additional changes in version 3.35.4 (2021-04-02):

              -
            1. Fix a defect in the query planner optimization identified by +
            2. Fix a defect in the query planner optimization identified by item 8b above. Ticket de7db14784a08053.
            3. Fix a defect in the new RETURNING syntax. Ticket @@ -244,7 +220,7 @@
            4. Fix an assertion associated with aggregate function processing that was incorrectly triggered by the push-down optimization.
            -

            Changes in this specific patch release, version 3.35.5 (2021-04-19):

            +

            Additional changes in version 3.35.5 (2021-04-19):

            1. Fix defects in the new ALTER TABLE DROP COLUMN feature that could corrupt the database file. @@ -257,10 +233,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_5.html sqlite3-3.44.0-0/www/releaselog/3_3_5.html --- sqlite3-3.42.0/www/releaselog/3_3_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.3.5 On 2006-04-05

            1. CHECK constraints use conflict resolution algorithms correctly.
            2. The SUM() function throws an error on integer overflow.
            3. @@ -138,10 +114,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_36_0.html sqlite3-3.44.0-0/www/releaselog/3_36_0.html --- sqlite3-3.42.0/www/releaselog/3_36_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_36_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.36.0 On 2021-06-18

            1. Improvement to the EXPLAIN QUERY PLAN output to make it easier to understand. @@ -126,7 +102,7 @@ the legacy behavior for applications that need it.
            2. The sqlite3_deserialize() and sqlite3_serialize() interfaces are now enabled by default. The -DSQLITE_ENABLE_DESERIALIZE compile-time option is - no longer required. Instead, there is a new -DSQLITE_OMIT_DESERIALIZE + no longer required. Instead, there is is a new -DSQLITE_OMIT_DESERIALIZE compile-time option to omit those interfaces.
            3. The "memdb" VFS now allows the same in-memory database to be shared among multiple database connections in the same process as long as the @@ -139,6 +115,7 @@
            4. The REGEXP extension is now included in CLI builds. +

              Hashes:

            5. SQLITE_SOURCE_ID: 2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5
            6. SHA3-256 for sqlite3.c: 2a8e87aaa414ac2d45ace8eb74e710935423607a8de0fafcb36bbde5b952d157 @@ -146,10 +123,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_6.html sqlite3-3.44.0-0/www/releaselog/3_3_6.html --- sqlite3-3.42.0/www/releaselog/3_3_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.3.6 On 2006-06-06

            1. Plays better with virus scanners on Windows
            2. Faster :memory: databases
            3. @@ -131,10 +107,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_37_0.html sqlite3-3.44.0-0/www/releaselog/3_37_0.html --- sqlite3-3.42.0/www/releaselog/3_37_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_37_0.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,164 +0,0 @@ - - - - - -SQLite Release 3.37.0 On 2021-11-27 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.37.0 On 2021-11-27

              -
            1. STRICT tables provide a prescriptive style of data type management, - for developers who prefer that kind of thing. -
            2. When adding columns that contain a - CHECK constraint or a generated column containing a NOT NULL constraint, - the ALTER TABLE ADD COLUMN now checks new constraints against - preexisting rows in the database and will only proceed if no constraints - are violated. -
            3. Added the PRAGMA table_list statement. -
            4. CLI enhancements: -
                -
              1. Add the .connection command, allowing the CLI to keep multiple database - connections open at the same time. -
              2. Add the --safe command-line option that disables - dot-commands and SQL statements that might cause side-effects that extend - beyond the single database file named on the command-line. -
              3. Performance improvements when reading SQL statements - that span many lines. -
              -
            5. Added the sqlite3_autovacuum_pages() interface. -
            6. The sqlite3_deserialize() does not and has never worked for the TEMP - database. That limitation is now noted in the documentation. -
            7. The query planner now omits ORDER BY clauses on subqueries and views - if removing those clauses does not change the semantics of the query. -
            8. The generate_series table-valued function extension is modified so that - the first parameter ("START") is now required. This is done as a way to - demonstrate how to write table-valued functions with required parameters. - The legacy behavior is available using the -DZERO_ARGUMENT_GENERATE_SERIES - compile-time option. -
            9. Added new sqlite3_changes64() and sqlite3_total_changes64() interfaces. -
            10. Added the SQLITE_OPEN_EXRESCODE flag option to sqlite3_open_v2(). -
            11. Use less memory to hold the database schema. - -

              Hashes: -

            12. SQLITE_SOURCE_ID: 2021-11-27 14:13:22 bd41822c7424d393a30e92ff6cb254d25c26769889c1499a18a0b9339f5d6c8a -
            13. SHA3-256 for sqlite3.c: a202a950ab401cda052e81259e96d6e64ad91faaaaf5690d769f64c2ab962f27 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_37_1.html sqlite3-3.44.0-0/www/releaselog/3_37_1.html --- sqlite3-3.42.0/www/releaselog/3_37_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_37_1.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,175 +0,0 @@ - - - - - -SQLite Release 3.37.1 On 2021-12-30 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.37.1 On 2021-12-30

            Prior changes from version 3.37.0 (2021-11-27):

            -

              -
            1. STRICT tables provide a prescriptive style of data type management, - for developers who prefer that kind of thing. -
            2. When adding columns that contain a - CHECK constraint or a generated column containing a NOT NULL constraint, - the ALTER TABLE ADD COLUMN now checks new constraints against - preexisting rows in the database and will only proceed if no constraints - are violated. -
            3. Added the PRAGMA table_list statement. -
            4. CLI enhancements: -
                -
              1. Add the .connection command, allowing the CLI to keep multiple database - connections open at the same time. -
              2. Add the --safe command-line option that disables - dot-commands and SQL statements that might cause side-effects that extend - beyond the single database file named on the command-line. -
              3. Performance improvements when reading SQL statements - that span many lines. -
              -
            5. Added the sqlite3_autovacuum_pages() interface. -
            6. The sqlite3_deserialize() does not and has never worked for the TEMP - database. That limitation is now noted in the documentation. -
            7. The query planner now omits ORDER BY clauses on subqueries and views - if removing those clauses does not change the semantics of the query. -
            8. The generate_series table-valued function extension is modified so that - the first parameter ("START") is now required. This is done as a way to - demonstrate how to write table-valued functions with required parameters. - The legacy behavior is available using the -DZERO_ARGUMENT_GENERATE_SERIES - compile-time option. -
            9. Added new sqlite3_changes64() and sqlite3_total_changes64() interfaces. -
            10. Added the SQLITE_OPEN_EXRESCODE flag option to sqlite3_open_v2(). -
            11. Use less memory to hold the database schema. - -
            -

            Changes in this specific patch release, version 3.37.1 (2021-12-30):

            -

              -
            1. Fix a bug introduced by the UPSERT enhancements of version 3.35.0 that - can cause incorrect byte-code to be generated for some obscure but valid - SQL, possibly resulting in a NULL-pointer dereference. -
            2. Fix an OOB read that can occur in FTS5 when reading corrupt database files. -
            3. Improved robustness of the --safe option in the CLI. -
            4. Other minor fixes to assert() statements and test cases. - -

              Hashes: -

            5. SQLITE_SOURCE_ID: 2021-12-30 15:30:28 378629bf2ea546f73eee84063c5358439a12f7300e433f18c9e1bddd948dea62 -
            6. SHA3-256 for sqlite3.c: 915afb3f29c2d217ea0c283326a9df7d505e6c73b40236f0b33ded91f812d174 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_37_2.html sqlite3-3.44.0-0/www/releaselog/3_37_2.html --- sqlite3-3.42.0/www/releaselog/3_37_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_37_2.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,190 +0,0 @@ - - - - - -SQLite Release 3.37.2 On 2022-01-06 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.37.2 On 2022-01-06

            Prior changes from version 3.37.0 (2021-11-27):

            -

              -
            1. STRICT tables provide a prescriptive style of data type management, - for developers who prefer that kind of thing. -
            2. When adding columns that contain a - CHECK constraint or a generated column containing a NOT NULL constraint, - the ALTER TABLE ADD COLUMN now checks new constraints against - preexisting rows in the database and will only proceed if no constraints - are violated. -
            3. Added the PRAGMA table_list statement. -
            4. CLI enhancements: -
                -
              1. Add the .connection command, allowing the CLI to keep multiple database - connections open at the same time. -
              2. Add the --safe command-line option that disables - dot-commands and SQL statements that might cause side-effects that extend - beyond the single database file named on the command-line. -
              3. Performance improvements when reading SQL statements - that span many lines. -
              -
            5. Added the sqlite3_autovacuum_pages() interface. -
            6. The sqlite3_deserialize() does not and has never worked for the TEMP - database. That limitation is now noted in the documentation. -
            7. The query planner now omits ORDER BY clauses on subqueries and views - if removing those clauses does not change the semantics of the query. -
            8. The generate_series table-valued function extension is modified so that - the first parameter ("START") is now required. This is done as a way to - demonstrate how to write table-valued functions with required parameters. - The legacy behavior is available using the -DZERO_ARGUMENT_GENERATE_SERIES - compile-time option. -
            9. Added new sqlite3_changes64() and sqlite3_total_changes64() interfaces. -
            10. Added the SQLITE_OPEN_EXRESCODE flag option to sqlite3_open_v2(). -
            11. Use less memory to hold the database schema. - -
            -

            Prior changes from version 3.37.1 (2021-12-30):

            -

              -
            1. Fix a bug introduced by the UPSERT enhancements of version 3.35.0 that - can cause incorrect byte-code to be generated for some obscure but valid - SQL, possibly resulting in a NULL-pointer dereference. -
            2. Fix an OOB read that can occur in FTS5 when reading corrupt database files. -
            3. Improved robustness of the --safe option in the CLI. -
            4. Other minor fixes to assert() statements and test cases. - -
            -

            Changes in this specific patch release, version 3.37.2 (2022-01-06):

            -

              -
            1. Fix a bug introduced - in version 3.35.0 (2021-03-12) that - can cause database corruption - if a SAVEPOINT is rolled back while in PRAGMA temp_store=MEMORY mode, - and other changes are made, and then the outer transaction commits. - Check-in 73c2b50211d3ae26 -
            2. Fix a long-standing problem with ON DELETE CASCADE and ON UPDATE CASCADE - in which a cache of the bytecode used to implement the cascading change - was not being reset following a local DDL change. - Check-in 5232c9777fe4fb13. -
            3. Other minor fixes that should not impact production builds. - -

              Hashes: -

            4. SQLITE_SOURCE_ID: 2022-01-06 13:25:41 872ba256cbf61d9290b571c0e6d82a20c224ca3ad82971edc46b29818d5d17a0 -
            5. SHA3-256 for sqlite3.c: 1bb01c382295cba85ec4685cedc52a7477cdae71cc37f1ad0f48719a17af1e1e - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_7.html sqlite3-3.44.0-0/www/releaselog/3_3_7.html --- sqlite3-3.42.0/www/releaselog/3_3_7.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_7.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,48 +89,23 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.3.7 On 2006-08-12

            1. Added support for virtual tables (beta)
            2. Added support for dynamically loaded extensions (beta)
            3. -
            4. The +
            5. The sqlite3_interrupt() routine can be called for a different thread
            6. Added the MATCH operator.
            7. -
            8. The default file format is now 1. +
            9. The default file format is now 1.

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_38_0.html sqlite3-3.44.0-0/www/releaselog/3_38_0.html --- sqlite3-3.42.0/www/releaselog/3_38_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_38_0.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ - - - - - -SQLite Release 3.38.0 On 2022-02-22 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.38.0 On 2022-02-22

              -
            1. Added the -> and ->> operators for easier processing of JSON. - The new operators are compatible with MySQL and PostgreSQL. -
            2. The JSON functions are now built-ins. It is no longer necessary - to use the -DSQLITE_ENABLE_JSON1 compile-time option to enable JSON - support. JSON is on by default. Disable the JSON interface using - the new -DSQLITE_OMIT_JSON compile-time option. -
            3. Enhancements to date and time functions: -
                -
              1. Added the unixepoch() function. -
              2. Added the auto modifier and the julianday modifier. -
              -
            4. Rename the printf() SQL function to format() for better - compatibility. The original printf() name is retained as an alias - for backwards compatibility. -
            5. Added the sqlite3_error_offset() interface, which can sometimes - help to localize an SQL error to a specific character in the input - SQL text, so that applications can provide better error messages. -
            6. Enhanced the interface to virtual tables as follows: -
                -
              1. Added the sqlite3_vtab_distinct() interface. -
              2. Added the sqlite3_vtab_rhs_value() interface. -
              3. Added new operator types SQLITE_INDEX_CONSTRAINT_LIMIT - and SQLITE_INDEX_CONSTRAINT_OFFSET. -
              4. Added the sqlite3_vtab_in() interface (and related) to enable - a virtual table to process IN operator constraints all at once, - rather than processing each value of the right-hand side of the - IN operator separately. -
              -
            7. CLI enhancements: -
                -
              1. Columnar output modes are enhanced to correctly handle tabs - and newlines embedded in text. -
              2. Added options like "--wrap N", "--wordwrap on", and "--quote" - to the columnar output modes. -
              3. Added the .mode qbox alias. -
              4. The .import command automatically disambiguates column names. -
              5. Use the new sqlite3_error_offset() interface to provide better - error messages. -
              -
            8. Query planner enhancements: -
                -
              1. Use a Bloom filter to speed up large analytic queries. -
              2. Use a balanced merge tree to evaluate UNION or UNION ALL - compound SELECT statements that have an ORDER BY clause. -
              -
            9. The ALTER TABLE statement is changed to silently ignores entries in the - sqlite_schema table that do not parse when PRAGMA writable_schema=ON. -

              Hashes: -

            10. SQLITE_SOURCE_ID: 2022-02-22 18:58:40 40fa792d359f84c3b9e9d6623743e1a59826274e221df1bde8f47086968a1bab - -
            11. SHA3-256 for sqlite3.c: a69af0a88d59271a2dd3c846a3e93cbd29e7c499864f6c0462a3b4160bee1762 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_38_1.html sqlite3-3.44.0-0/www/releaselog/3_38_1.html --- sqlite3-3.42.0/www/releaselog/3_38_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_38_1.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,197 +0,0 @@ - - - - - -SQLite Release 3.38.1 On 2022-03-12 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.38.1 On 2022-03-12

            Prior changes from version 3.38.0 (2022-02-22):

            -

              -
            1. Added the -> and ->> operators for easier processing of JSON. - The new operators are compatible with MySQL and PostgreSQL. -
            2. The JSON functions are now built-ins. It is no longer necessary - to use the -DSQLITE_ENABLE_JSON1 compile-time option to enable JSON - support. JSON is on by default. Disable the JSON interface using - the new -DSQLITE_OMIT_JSON compile-time option. -
            3. Enhancements to date and time functions: -
                -
              1. Added the unixepoch() function. -
              2. Added the auto modifier and the julianday modifier. -
              -
            4. Rename the printf() SQL function to format() for better - compatibility. The original printf() name is retained as an alias - for backwards compatibility. -
            5. Added the sqlite3_error_offset() interface, which can sometimes - help to localize an SQL error to a specific character in the input - SQL text, so that applications can provide better error messages. -
            6. Enhanced the interface to virtual tables as follows: -
                -
              1. Added the sqlite3_vtab_distinct() interface. -
              2. Added the sqlite3_vtab_rhs_value() interface. -
              3. Added new operator types SQLITE_INDEX_CONSTRAINT_LIMIT - and SQLITE_INDEX_CONSTRAINT_OFFSET. -
              4. Added the sqlite3_vtab_in() interface (and related) to enable - a virtual table to process IN operator constraints all at once, - rather than processing each value of the right-hand side of the - IN operator separately. -
              -
            7. CLI enhancements: -
                -
              1. Columnar output modes are enhanced to correctly handle tabs - and newlines embedded in text. -
              2. Added options like "--wrap N", "--wordwrap on", and "--quote" - to the columnar output modes. -
              3. Added the .mode qbox alias. -
              4. The .import command automatically disambiguates column names. -
              5. Use the new sqlite3_error_offset() interface to provide better - error messages. -
              -
            8. Query planner enhancements: -
                -
              1. Use a Bloom filter to speed up large analytic queries. -
              2. Use a balanced merge tree to evaluate UNION or UNION ALL - compound SELECT statements that have an ORDER BY clause. -
              -
            9. The ALTER TABLE statement is changed to silently ignores entries in the - sqlite_schema table that do not parse when PRAGMA writable_schema=ON. -
            -

            Changes in this specific patch release, version 3.38.1 (2022-03-12):

            -

              -
            1. Fix problems with the new Bloom filter optimization that might cause - some obscure queries to get an incorrect answer. -
            2. Fix the localtime modifier of the date and time functions so that - it preserves fractional seconds. -
            3. Fix the sqlite_offset SQL function so that it works correctly even - in corner cases such as when the argument is a virtual column or the - column of a view. -
            4. Fix row value IN operator constraints on virtual tables so that they - work correctly even if the virtual table implementation relies on bytecode - to filter rows that do not satisfy the constraint. -
            5. Other minor fixes to assert() statements, test cases, and documentation. - See the source code timeline - for details. - -

              Hashes: -

            6. SQLITE_SOURCE_ID: 2022-03-12 13:37:29 38c210fdd258658321c85ec9c01a072fda3ada94540e3239d29b34dc547a8cbc -
            7. SHA3-256 for sqlite3.c: 262ba071e960a8a0a6ce39307ae30244a2b0dc9fe1c4c09d0e1070d4353cd92c - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_38_2.html sqlite3-3.44.0-0/www/releaselog/3_38_2.html --- sqlite3-3.42.0/www/releaselog/3_38_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_38_2.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,209 +0,0 @@ - - - - - -SQLite Release 3.38.2 On 2022-03-26 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.38.2 On 2022-03-26

            Prior changes from version 3.38.0 (2022-02-22):

            -

              -
            1. Added the -> and ->> operators for easier processing of JSON. - The new operators are compatible with MySQL and PostgreSQL. -
            2. The JSON functions are now built-ins. It is no longer necessary - to use the -DSQLITE_ENABLE_JSON1 compile-time option to enable JSON - support. JSON is on by default. Disable the JSON interface using - the new -DSQLITE_OMIT_JSON compile-time option. -
            3. Enhancements to date and time functions: -
                -
              1. Added the unixepoch() function. -
              2. Added the auto modifier and the julianday modifier. -
              -
            4. Rename the printf() SQL function to format() for better - compatibility. The original printf() name is retained as an alias - for backwards compatibility. -
            5. Added the sqlite3_error_offset() interface, which can sometimes - help to localize an SQL error to a specific character in the input - SQL text, so that applications can provide better error messages. -
            6. Enhanced the interface to virtual tables as follows: -
                -
              1. Added the sqlite3_vtab_distinct() interface. -
              2. Added the sqlite3_vtab_rhs_value() interface. -
              3. Added new operator types SQLITE_INDEX_CONSTRAINT_LIMIT - and SQLITE_INDEX_CONSTRAINT_OFFSET. -
              4. Added the sqlite3_vtab_in() interface (and related) to enable - a virtual table to process IN operator constraints all at once, - rather than processing each value of the right-hand side of the - IN operator separately. -
              -
            7. CLI enhancements: -
                -
              1. Columnar output modes are enhanced to correctly handle tabs - and newlines embedded in text. -
              2. Added options like "--wrap N", "--wordwrap on", and "--quote" - to the columnar output modes. -
              3. Added the .mode qbox alias. -
              4. The .import command automatically disambiguates column names. -
              5. Use the new sqlite3_error_offset() interface to provide better - error messages. -
              -
            8. Query planner enhancements: -
                -
              1. Use a Bloom filter to speed up large analytic queries. -
              2. Use a balanced merge tree to evaluate UNION or UNION ALL - compound SELECT statements that have an ORDER BY clause. -
              -
            9. The ALTER TABLE statement is changed to silently ignores entries in the - sqlite_schema table that do not parse when PRAGMA writable_schema=ON. -
            -

            Prior changes from version 3.38.1 (2022-03-12):

            -

              -
            1. Fix problems with the new Bloom filter optimization that might cause - some obscure queries to get an incorrect answer. -
            2. Fix the localtime modifier of the date and time functions so that - it preserves fractional seconds. -
            3. Fix the sqlite_offset SQL function so that it works correctly even - in corner cases such as when the argument is a virtual column or the - column of a view. -
            4. Fix row value IN operator constraints on virtual tables so that they - work correctly even if the virtual table implementation relies on bytecode - to filter rows that do not satisfy the constraint. -
            5. Other minor fixes to assert() statements, test cases, and documentation. - See the source code timeline - for details. - -
            -

            Changes in this specific patch release, version 3.38.2 (2022-03-26):

            -

              -
            1. Fix a user-discovered problem with the new Bloom filter optimization - that might cause an incorrect answer when doing a LEFT JOIN with a WHERE - clause constraint that says that one of the columns on the right table of - the LEFT JOIN is NULL. See - forum thread 031e262a89b6a9d2. -
            2. Other minor patches. See the - timeline for - details. - -

              Hashes: -

            3. SQLITE_SOURCE_ID: 2022-03-26 13:51:10 d33c709cc0af66bc5b6dc6216eba9f1f0b40960b9ae83694c986fbf4c1d6f08f -
            4. SHA3-256 for sqlite3.c: 0fbac6b6999f894184899431fb77b9792324c61246b2a010d736694ccaa6d613 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_38_3.html sqlite3-3.44.0-0/www/releaselog/3_38_3.html --- sqlite3-3.42.0/www/releaselog/3_38_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_38_3.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,221 +0,0 @@ - - - - - -SQLite Release 3.38.3 On 2022-04-27 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.38.3 On 2022-04-27

            Prior changes from version 3.38.0 (2022-02-22):

            -

              -
            1. Added the -> and ->> operators for easier processing of JSON. - The new operators are compatible with MySQL and PostgreSQL. -
            2. The JSON functions are now built-ins. It is no longer necessary - to use the -DSQLITE_ENABLE_JSON1 compile-time option to enable JSON - support. JSON is on by default. Disable the JSON interface using - the new -DSQLITE_OMIT_JSON compile-time option. -
            3. Enhancements to date and time functions: -
                -
              1. Added the unixepoch() function. -
              2. Added the auto modifier and the julianday modifier. -
              -
            4. Rename the printf() SQL function to format() for better - compatibility. The original printf() name is retained as an alias - for backwards compatibility. -
            5. Added the sqlite3_error_offset() interface, which can sometimes - help to localize an SQL error to a specific character in the input - SQL text, so that applications can provide better error messages. -
            6. Enhanced the interface to virtual tables as follows: -
                -
              1. Added the sqlite3_vtab_distinct() interface. -
              2. Added the sqlite3_vtab_rhs_value() interface. -
              3. Added new operator types SQLITE_INDEX_CONSTRAINT_LIMIT - and SQLITE_INDEX_CONSTRAINT_OFFSET. -
              4. Added the sqlite3_vtab_in() interface (and related) to enable - a virtual table to process IN operator constraints all at once, - rather than processing each value of the right-hand side of the - IN operator separately. -
              -
            7. CLI enhancements: -
                -
              1. Columnar output modes are enhanced to correctly handle tabs - and newlines embedded in text. -
              2. Added options like "--wrap N", "--wordwrap on", and "--quote" - to the columnar output modes. -
              3. Added the .mode qbox alias. -
              4. The .import command automatically disambiguates column names. -
              5. Use the new sqlite3_error_offset() interface to provide better - error messages. -
              -
            8. Query planner enhancements: -
                -
              1. Use a Bloom filter to speed up large analytic queries. -
              2. Use a balanced merge tree to evaluate UNION or UNION ALL - compound SELECT statements that have an ORDER BY clause. -
              -
            9. The ALTER TABLE statement is changed to silently ignores entries in the - sqlite_schema table that do not parse when PRAGMA writable_schema=ON. -
            -

            Prior changes from version 3.38.1 (2022-03-12):

            -

              -
            1. Fix problems with the new Bloom filter optimization that might cause - some obscure queries to get an incorrect answer. -
            2. Fix the localtime modifier of the date and time functions so that - it preserves fractional seconds. -
            3. Fix the sqlite_offset SQL function so that it works correctly even - in corner cases such as when the argument is a virtual column or the - column of a view. -
            4. Fix row value IN operator constraints on virtual tables so that they - work correctly even if the virtual table implementation relies on bytecode - to filter rows that do not satisfy the constraint. -
            5. Other minor fixes to assert() statements, test cases, and documentation. - See the source code timeline - for details. - -
            -

            Prior changes from version 3.38.2 (2022-03-26):

            -

              -
            1. Fix a user-discovered problem with the new Bloom filter optimization - that might cause an incorrect answer when doing a LEFT JOIN with a WHERE - clause constraint that says that one of the columns on the right table of - the LEFT JOIN is NULL. See - forum thread 031e262a89b6a9d2. -
            2. Other minor patches. See the - timeline for - details. - -
            -

            Changes in this specific patch release, version 3.38.3 (2022-04-27):

            -

              -
            1. Fix a case of the query planner be overly aggressive with optimizing automatic-index - and Bloom-filter construction, using inappropriate ON clause terms to restrict the - size of the automatic-index or Bloom filter, and resulting in missing rows in the - output. - Forum thread 0d3200f4f3bcd3a3. -
            2. Other minor patches. See the - timeline for - details. - -

              Hashes: -

            3. SQLITE_SOURCE_ID: 2022-04-27 12:03:15 9547e2c38a1c6f751a77d4d796894dec4dc5d8f5d79b1cd39e1ffc50df7b3be4 -
            4. SHA3-256 for sqlite3.c: d4d66feffad66ea82073fbb97ae9c84e3615887ebc5168226ccee28d82424517 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_38_4.html sqlite3-3.44.0-0/www/releaselog/3_38_4.html --- sqlite3-3.42.0/www/releaselog/3_38_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_38_4.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,232 +0,0 @@ - - - - - -SQLite Release 3.38.4 On 2022-05-04 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.38.4 On 2022-05-04

            Prior changes from version 3.38.0 (2022-02-22):

            -

              -
            1. Added the -> and ->> operators for easier processing of JSON. - The new operators are compatible with MySQL and PostgreSQL. -
            2. The JSON functions are now built-ins. It is no longer necessary - to use the -DSQLITE_ENABLE_JSON1 compile-time option to enable JSON - support. JSON is on by default. Disable the JSON interface using - the new -DSQLITE_OMIT_JSON compile-time option. -
            3. Enhancements to date and time functions: -
                -
              1. Added the unixepoch() function. -
              2. Added the auto modifier and the julianday modifier. -
              -
            4. Rename the printf() SQL function to format() for better - compatibility. The original printf() name is retained as an alias - for backwards compatibility. -
            5. Added the sqlite3_error_offset() interface, which can sometimes - help to localize an SQL error to a specific character in the input - SQL text, so that applications can provide better error messages. -
            6. Enhanced the interface to virtual tables as follows: -
                -
              1. Added the sqlite3_vtab_distinct() interface. -
              2. Added the sqlite3_vtab_rhs_value() interface. -
              3. Added new operator types SQLITE_INDEX_CONSTRAINT_LIMIT - and SQLITE_INDEX_CONSTRAINT_OFFSET. -
              4. Added the sqlite3_vtab_in() interface (and related) to enable - a virtual table to process IN operator constraints all at once, - rather than processing each value of the right-hand side of the - IN operator separately. -
              -
            7. CLI enhancements: -
                -
              1. Columnar output modes are enhanced to correctly handle tabs - and newlines embedded in text. -
              2. Added options like "--wrap N", "--wordwrap on", and "--quote" - to the columnar output modes. -
              3. Added the .mode qbox alias. -
              4. The .import command automatically disambiguates column names. -
              5. Use the new sqlite3_error_offset() interface to provide better - error messages. -
              -
            8. Query planner enhancements: -
                -
              1. Use a Bloom filter to speed up large analytic queries. -
              2. Use a balanced merge tree to evaluate UNION or UNION ALL - compound SELECT statements that have an ORDER BY clause. -
              -
            9. The ALTER TABLE statement is changed to silently ignores entries in the - sqlite_schema table that do not parse when PRAGMA writable_schema=ON. -
            -

            Prior changes from version 3.38.1 (2022-03-12):

            -

              -
            1. Fix problems with the new Bloom filter optimization that might cause - some obscure queries to get an incorrect answer. -
            2. Fix the localtime modifier of the date and time functions so that - it preserves fractional seconds. -
            3. Fix the sqlite_offset SQL function so that it works correctly even - in corner cases such as when the argument is a virtual column or the - column of a view. -
            4. Fix row value IN operator constraints on virtual tables so that they - work correctly even if the virtual table implementation relies on bytecode - to filter rows that do not satisfy the constraint. -
            5. Other minor fixes to assert() statements, test cases, and documentation. - See the source code timeline - for details. - -
            -

            Prior changes from version 3.38.2 (2022-03-26):

            -

              -
            1. Fix a user-discovered problem with the new Bloom filter optimization - that might cause an incorrect answer when doing a LEFT JOIN with a WHERE - clause constraint that says that one of the columns on the right table of - the LEFT JOIN is NULL. See - forum thread 031e262a89b6a9d2. -
            2. Other minor patches. See the - timeline for - details. - -
            -

            Prior changes from version 3.38.3 (2022-04-27):

            -

              -
            1. Fix a case of the query planner be overly aggressive with optimizing automatic-index - and Bloom-filter construction, using inappropriate ON clause terms to restrict the - size of the automatic-index or Bloom filter, and resulting in missing rows in the - output. - Forum thread 0d3200f4f3bcd3a3. -
            2. Other minor patches. See the - timeline for - details. - -
            -

            Changes in this specific patch release, version 3.38.4 (2022-05-04):

            -

              -
            1. Fix a byte-code problem in the Bloom filter pull-down optimization added by release - 3.38.0 in which an error in the byte code causes the byte code engine to enter an - infinite loop when the pull-down optimization encounters a NULL key. - Forum thread 2482b32700384a0f. -
            2. Other minor patches. See the - timeline for - details. - -

              Hashes: -

            3. SQLITE_SOURCE_ID: 2022-05-04 15:45:55 d402f49871152670a62f4f28cacb15d814f2c1644e9347ad7d258e562978e45e -
            4. SHA3-256 for sqlite3.c: e6a50effb021858c200e885664611ed3c5e949413ff2dca452ac7ee336b9de1d - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_38_5.html sqlite3-3.44.0-0/www/releaselog/3_38_5.html --- sqlite3-3.42.0/www/releaselog/3_38_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_38_5.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,237 +0,0 @@ - - - - - -SQLite Release 3.38.5 On 2022-05-06 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.38.5 On 2022-05-06

            Prior changes from version 3.38.0 (2022-02-22):

            -

              -
            1. Added the -> and ->> operators for easier processing of JSON. - The new operators are compatible with MySQL and PostgreSQL. -
            2. The JSON functions are now built-ins. It is no longer necessary - to use the -DSQLITE_ENABLE_JSON1 compile-time option to enable JSON - support. JSON is on by default. Disable the JSON interface using - the new -DSQLITE_OMIT_JSON compile-time option. -
            3. Enhancements to date and time functions: -
                -
              1. Added the unixepoch() function. -
              2. Added the auto modifier and the julianday modifier. -
              -
            4. Rename the printf() SQL function to format() for better - compatibility. The original printf() name is retained as an alias - for backwards compatibility. -
            5. Added the sqlite3_error_offset() interface, which can sometimes - help to localize an SQL error to a specific character in the input - SQL text, so that applications can provide better error messages. -
            6. Enhanced the interface to virtual tables as follows: -
                -
              1. Added the sqlite3_vtab_distinct() interface. -
              2. Added the sqlite3_vtab_rhs_value() interface. -
              3. Added new operator types SQLITE_INDEX_CONSTRAINT_LIMIT - and SQLITE_INDEX_CONSTRAINT_OFFSET. -
              4. Added the sqlite3_vtab_in() interface (and related) to enable - a virtual table to process IN operator constraints all at once, - rather than processing each value of the right-hand side of the - IN operator separately. -
              -
            7. CLI enhancements: -
                -
              1. Columnar output modes are enhanced to correctly handle tabs - and newlines embedded in text. -
              2. Added options like "--wrap N", "--wordwrap on", and "--quote" - to the columnar output modes. -
              3. Added the .mode qbox alias. -
              4. The .import command automatically disambiguates column names. -
              5. Use the new sqlite3_error_offset() interface to provide better - error messages. -
              -
            8. Query planner enhancements: -
                -
              1. Use a Bloom filter to speed up large analytic queries. -
              2. Use a balanced merge tree to evaluate UNION or UNION ALL - compound SELECT statements that have an ORDER BY clause. -
              -
            9. The ALTER TABLE statement is changed to silently ignores entries in the - sqlite_schema table that do not parse when PRAGMA writable_schema=ON. -
            -

            Prior changes from version 3.38.1 (2022-03-12):

            -

              -
            1. Fix problems with the new Bloom filter optimization that might cause - some obscure queries to get an incorrect answer. -
            2. Fix the localtime modifier of the date and time functions so that - it preserves fractional seconds. -
            3. Fix the sqlite_offset SQL function so that it works correctly even - in corner cases such as when the argument is a virtual column or the - column of a view. -
            4. Fix row value IN operator constraints on virtual tables so that they - work correctly even if the virtual table implementation relies on bytecode - to filter rows that do not satisfy the constraint. -
            5. Other minor fixes to assert() statements, test cases, and documentation. - See the source code timeline - for details. - -
            -

            Prior changes from version 3.38.2 (2022-03-26):

            -

              -
            1. Fix a user-discovered problem with the new Bloom filter optimization - that might cause an incorrect answer when doing a LEFT JOIN with a WHERE - clause constraint that says that one of the columns on the right table of - the LEFT JOIN is NULL. See - forum thread 031e262a89b6a9d2. -
            2. Other minor patches. See the - timeline for - details. - -
            -

            Prior changes from version 3.38.3 (2022-04-27):

            -

              -
            1. Fix a case of the query planner be overly aggressive with optimizing automatic-index - and Bloom-filter construction, using inappropriate ON clause terms to restrict the - size of the automatic-index or Bloom filter, and resulting in missing rows in the - output. - Forum thread 0d3200f4f3bcd3a3. -
            2. Other minor patches. See the - timeline for - details. - -
            -

            Prior changes from version 3.38.4 (2022-05-04):

            -

              -
            1. Fix a byte-code problem in the Bloom filter pull-down optimization added by release - 3.38.0 in which an error in the byte code causes the byte code engine to enter an - infinite loop when the pull-down optimization encounters a NULL key. - Forum thread 2482b32700384a0f. -
            2. Other minor patches. See the - timeline for - details. - -
            -

            Changes in this specific patch release, version 3.38.5 (2022-05-06):

            -

              -
            1. Fix a blunder in the CLI of the 3.38.4 release. - -

              Hashes: -

            2. SQLITE_SOURCE_ID: 2022-05-06 15:25:27 78d9c993d404cdfaa7fdd2973fa1052e3da9f66215cff9c5540ebe55c407d9fe -
            3. SHA3-256 for sqlite3.c: b05ef42ed234009b4b3dfb36c5f5ccf6d728da80f25ee560291269cf6cfe635f - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_8.html sqlite3-3.44.0-0/www/releaselog/3_3_8.html --- sqlite3-3.42.0/www/releaselog/3_3_8.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_8.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.3.8 On 2006-10-09

            1. Support for full text search using the FTS1 module (beta)
            2. Added Mac OS X locking patches (beta - disabled by default)
            3. @@ -130,10 +106,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_39_0.html sqlite3-3.44.0-0/www/releaselog/3_39_0.html --- sqlite3-3.42.0/www/releaselog/3_39_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_39_0.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,152 +0,0 @@ - - - - - -SQLite Release 3.39.0 On 2022-06-25 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.39.0 On 2022-06-25

              -
            1. Add (long overdue) support for RIGHT and FULL OUTER JOIN. -
            2. Add new binary comparison operators IS NOT DISTINCT FROM and IS DISTINCT FROM - that are equivalent to IS and IS NOT, respective, for compatibility with - PostgreSQL and SQL standards. -
            3. Add a new return code (value "3") from the sqlite3_vtab_distinct() - interface that indicates a query that has both DISTINCT and ORDER BY - clauses. -
            4. Added the sqlite3_db_name() interface. -
            5. The unix os interface resolves all symbolic links in database - filenames to create a canonical name for the database before the - file is opened. - If the SQLITE_OPEN_NOFOLLOW flag is used with sqlite3_open_v2() - or similar, the open will fail if any element of the path is a - symbolic link. -
            6. Defer materializing views until the materialization - is actually needed, thus avoiding unnecessary work if the materialization turns - out to never be used. -
            7. The HAVING clause of a SELECT statement is now allowed on any aggregate query, - even queries that do not have a GROUP BY clause. -
            8. Many microoptimizations collectively reduce CPU cycles by about 2.3%. -

              Hashes: -

            9. SQLITE_SOURCE_ID: 2022-06-25 14:57:57 14e166f40dbfa6e055543f8301525f2ca2e96a02a57269818b9e69e162e98918 -
            10. SHA3-256 for sqlite3.c: d9c439cacad5e4992d0d25989cfd27a4c4f59a3183c97873bc03f0ad1aa78b7a - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_39_1.html sqlite3-3.44.0-0/www/releaselog/3_39_1.html --- sqlite3-3.42.0/www/releaselog/3_39_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_39_1.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,172 +0,0 @@ - - - - - -SQLite Release 3.39.1 On 2022-07-13 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.39.1 On 2022-07-13

            Prior changes from version 3.39.0 (2022-06-25):

            -

              -
            1. Add (long overdue) support for RIGHT and FULL OUTER JOIN. -
            2. Add new binary comparison operators IS NOT DISTINCT FROM and IS DISTINCT FROM - that are equivalent to IS and IS NOT, respective, for compatibility with - PostgreSQL and SQL standards. -
            3. Add a new return code (value "3") from the sqlite3_vtab_distinct() - interface that indicates a query that has both DISTINCT and ORDER BY - clauses. -
            4. Added the sqlite3_db_name() interface. -
            5. The unix os interface resolves all symbolic links in database - filenames to create a canonical name for the database before the - file is opened. - If the SQLITE_OPEN_NOFOLLOW flag is used with sqlite3_open_v2() - or similar, the open will fail if any element of the path is a - symbolic link. -
            6. Defer materializing views until the materialization - is actually needed, thus avoiding unnecessary work if the materialization turns - out to never be used. -
            7. The HAVING clause of a SELECT statement is now allowed on any aggregate query, - even queries that do not have a GROUP BY clause. -
            8. Many microoptimizations collectively reduce CPU cycles by about 2.3%. -
            -

            Changes in this specific patch release, version 3.39.1 (2022-07-13):

            -

              -
            1. Fix an incorrect result from a query that uses a view that contains a compound - SELECT in which only one arm contains a RIGHT JOIN and where the view is not - the first FROM clause term of the query that contains the view. - forum post 174afeae5734d42d. -
            2. Fix some harmless compiler warnings. -
            3. Fix a long-standing problem with ALTER TABLE RENAME that can only arise - if the sqlite3_limit(SQLITE_LIMIT_SQL_LENGTH) is set to a very small value. -
            4. Fix a long-standing problem in FTS3 that can only arise when compiled with - the SQLITE_ENABLE_FTS3_PARENTHESIS compile-time option. -
            5. Fix the build so that is works when the SQLITE_DEBUG and - SQLITE_OMIT_WINDOWFUNC compile-time options are both provided at the - same time. -
            6. Fix the initial-prefix optimization for the REGEXP extension so that it works - correctly even if the prefix contains characters that require a 3-byte UTF8 - encoding. -
            7. Enhance the sqlite_stmt virtual table so that it buffers all of its output. -

              Hashes: -

            8. SQLITE_SOURCE_ID: 2022-07-13 19:41:41 7c16541a0efb3985578181171c9f2bb3fdc4bad6a2ec85c6e31ab96f3eff201f -
            9. SHA3-256 for sqlite3.c: 6d13fcf1c31133da541d1eb8a83552d746f39b81a0657bd4077fed0221749511 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_39_2.html sqlite3-3.44.0-0/www/releaselog/3_39_2.html --- sqlite3-3.42.0/www/releaselog/3_39_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_39_2.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,180 +0,0 @@ - - - - - -SQLite Release 3.39.2 On 2022-07-21 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.39.2 On 2022-07-21

            Prior changes from version 3.39.0 (2022-06-25):

            -

              -
            1. Add (long overdue) support for RIGHT and FULL OUTER JOIN. -
            2. Add new binary comparison operators IS NOT DISTINCT FROM and IS DISTINCT FROM - that are equivalent to IS and IS NOT, respective, for compatibility with - PostgreSQL and SQL standards. -
            3. Add a new return code (value "3") from the sqlite3_vtab_distinct() - interface that indicates a query that has both DISTINCT and ORDER BY - clauses. -
            4. Added the sqlite3_db_name() interface. -
            5. The unix os interface resolves all symbolic links in database - filenames to create a canonical name for the database before the - file is opened. - If the SQLITE_OPEN_NOFOLLOW flag is used with sqlite3_open_v2() - or similar, the open will fail if any element of the path is a - symbolic link. -
            6. Defer materializing views until the materialization - is actually needed, thus avoiding unnecessary work if the materialization turns - out to never be used. -
            7. The HAVING clause of a SELECT statement is now allowed on any aggregate query, - even queries that do not have a GROUP BY clause. -
            8. Many microoptimizations collectively reduce CPU cycles by about 2.3%. -
            -

            Prior changes from version 3.39.1 (2022-07-13):

            -

              -
            1. Fix an incorrect result from a query that uses a view that contains a compound - SELECT in which only one arm contains a RIGHT JOIN and where the view is not - the first FROM clause term of the query that contains the view. - forum post 174afeae5734d42d. -
            2. Fix some harmless compiler warnings. -
            3. Fix a long-standing problem with ALTER TABLE RENAME that can only arise - if the sqlite3_limit(SQLITE_LIMIT_SQL_LENGTH) is set to a very small value. -
            4. Fix a long-standing problem in FTS3 that can only arise when compiled with - the SQLITE_ENABLE_FTS3_PARENTHESIS compile-time option. -
            5. Fix the build so that is works when the SQLITE_DEBUG and - SQLITE_OMIT_WINDOWFUNC compile-time options are both provided at the - same time. -
            6. Fix the initial-prefix optimization for the REGEXP extension so that it works - correctly even if the prefix contains characters that require a 3-byte UTF8 - encoding. -
            7. Enhance the sqlite_stmt virtual table so that it buffers all of its output. -
            -

            Changes in this specific patch release, version 3.39.2 (2022-07-21):

            -

              -
            1. Fix a performance regression in the query planner associated with rearranging - the order of FROM clause terms in the presences of a LEFT JOIN. -
            2. Apply fixes for CVE-2022-35737, Chromium bugs 1343348 and 1345947, - forum post 3607259d3c, and - other minor problems discovered by internal testing. -

              Hashes: -

            3. SQLITE_SOURCE_ID: 2022-07-21 15:24:47 698edb77537b67c41adc68f9b892db56bcf9a55e00371a61420f3ddd668e6603 -
            4. SHA3-256 for sqlite3.c: bffbaafa94706f0ed234f183af3eb46e6485e7e2c75983173ded76e0da805f11 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_39_3.html sqlite3-3.44.0-0/www/releaselog/3_39_3.html --- sqlite3-3.42.0/www/releaselog/3_39_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_39_3.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,193 +0,0 @@ - - - - - -SQLite Release 3.39.3 On 2022-09-05 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.39.3 On 2022-09-05

            Prior changes from version 3.39.0 (2022-06-25):

            -

              -
            1. Add (long overdue) support for RIGHT and FULL OUTER JOIN. -
            2. Add new binary comparison operators IS NOT DISTINCT FROM and IS DISTINCT FROM - that are equivalent to IS and IS NOT, respective, for compatibility with - PostgreSQL and SQL standards. -
            3. Add a new return code (value "3") from the sqlite3_vtab_distinct() - interface that indicates a query that has both DISTINCT and ORDER BY - clauses. -
            4. Added the sqlite3_db_name() interface. -
            5. The unix os interface resolves all symbolic links in database - filenames to create a canonical name for the database before the - file is opened. - If the SQLITE_OPEN_NOFOLLOW flag is used with sqlite3_open_v2() - or similar, the open will fail if any element of the path is a - symbolic link. -
            6. Defer materializing views until the materialization - is actually needed, thus avoiding unnecessary work if the materialization turns - out to never be used. -
            7. The HAVING clause of a SELECT statement is now allowed on any aggregate query, - even queries that do not have a GROUP BY clause. -
            8. Many microoptimizations collectively reduce CPU cycles by about 2.3%. -
            -

            Prior changes from version 3.39.1 (2022-07-13):

            -

              -
            1. Fix an incorrect result from a query that uses a view that contains a compound - SELECT in which only one arm contains a RIGHT JOIN and where the view is not - the first FROM clause term of the query that contains the view. - forum post 174afeae5734d42d. -
            2. Fix some harmless compiler warnings. -
            3. Fix a long-standing problem with ALTER TABLE RENAME that can only arise - if the sqlite3_limit(SQLITE_LIMIT_SQL_LENGTH) is set to a very small value. -
            4. Fix a long-standing problem in FTS3 that can only arise when compiled with - the SQLITE_ENABLE_FTS3_PARENTHESIS compile-time option. -
            5. Fix the build so that is works when the SQLITE_DEBUG and - SQLITE_OMIT_WINDOWFUNC compile-time options are both provided at the - same time. -
            6. Fix the initial-prefix optimization for the REGEXP extension so that it works - correctly even if the prefix contains characters that require a 3-byte UTF8 - encoding. -
            7. Enhance the sqlite_stmt virtual table so that it buffers all of its output. -
            -

            Prior changes from version 3.39.2 (2022-07-21):

            -

              -
            1. Fix a performance regression in the query planner associated with rearranging - the order of FROM clause terms in the presences of a LEFT JOIN. -
            2. Apply fixes for CVE-2022-35737, Chromium bugs 1343348 and 1345947, - forum post 3607259d3c, and - other minor problems discovered by internal testing. -
            -

            Changes in this specific patch release, version 3.39.3 (2022-09-05):

            -

              -
            1. Use a statement journal on DML statement affecting two or more database - rows if the statement makes use of a SQL functions that might abort. See - forum thread 9b9e4716c0d7bbd1. -
            2. Use a mutex to protect the PRAGMA temp_store_directory and - PRAGMA data_store_directory statements, even though they are deprecated and - documented as not being threadsafe. See - forum post 719a11e1314d1c70. -
            3. Other bug and warning fixes. See the - timeline - for details. -

              Hashes: -

            4. SQLITE_SOURCE_ID: 2022-09-05 11:02:23 4635f4a69c8c2a8df242b384a992aea71224e39a2ccab42d8c0b0602f1e826e8 -
            5. SHA3-256 for sqlite3.c: 2fc273cf8032b601c9e06207efa0ae80eb73d5a1d283eb91096c815fa9640257 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_39_4.html sqlite3-3.44.0-0/www/releaselog/3_39_4.html --- sqlite3-3.42.0/www/releaselog/3_39_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_39_4.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ - - - - - -SQLite Release 3.39.4 On 2022-09-29 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.39.4 On 2022-09-29

            Prior changes from version 3.39.0 (2022-06-25):

            -

              -
            1. Add (long overdue) support for RIGHT and FULL OUTER JOIN. -
            2. Add new binary comparison operators IS NOT DISTINCT FROM and IS DISTINCT FROM - that are equivalent to IS and IS NOT, respective, for compatibility with - PostgreSQL and SQL standards. -
            3. Add a new return code (value "3") from the sqlite3_vtab_distinct() - interface that indicates a query that has both DISTINCT and ORDER BY - clauses. -
            4. Added the sqlite3_db_name() interface. -
            5. The unix os interface resolves all symbolic links in database - filenames to create a canonical name for the database before the - file is opened. - If the SQLITE_OPEN_NOFOLLOW flag is used with sqlite3_open_v2() - or similar, the open will fail if any element of the path is a - symbolic link. -
            6. Defer materializing views until the materialization - is actually needed, thus avoiding unnecessary work if the materialization turns - out to never be used. -
            7. The HAVING clause of a SELECT statement is now allowed on any aggregate query, - even queries that do not have a GROUP BY clause. -
            8. Many microoptimizations collectively reduce CPU cycles by about 2.3%. -
            -

            Prior changes from version 3.39.1 (2022-07-13):

            -

              -
            1. Fix an incorrect result from a query that uses a view that contains a compound - SELECT in which only one arm contains a RIGHT JOIN and where the view is not - the first FROM clause term of the query that contains the view. - forum post 174afeae5734d42d. -
            2. Fix some harmless compiler warnings. -
            3. Fix a long-standing problem with ALTER TABLE RENAME that can only arise - if the sqlite3_limit(SQLITE_LIMIT_SQL_LENGTH) is set to a very small value. -
            4. Fix a long-standing problem in FTS3 that can only arise when compiled with - the SQLITE_ENABLE_FTS3_PARENTHESIS compile-time option. -
            5. Fix the build so that is works when the SQLITE_DEBUG and - SQLITE_OMIT_WINDOWFUNC compile-time options are both provided at the - same time. -
            6. Fix the initial-prefix optimization for the REGEXP extension so that it works - correctly even if the prefix contains characters that require a 3-byte UTF8 - encoding. -
            7. Enhance the sqlite_stmt virtual table so that it buffers all of its output. -
            -

            Prior changes from version 3.39.2 (2022-07-21):

            -

              -
            1. Fix a performance regression in the query planner associated with rearranging - the order of FROM clause terms in the presences of a LEFT JOIN. -
            2. Apply fixes for CVE-2022-35737, Chromium bugs 1343348 and 1345947, - forum post 3607259d3c, and - other minor problems discovered by internal testing. -
            -

            Prior changes from version 3.39.3 (2022-09-05):

            -

              -
            1. Use a statement journal on DML statement affecting two or more database - rows if the statement makes use of a SQL functions that might abort. See - forum thread 9b9e4716c0d7bbd1. -
            2. Use a mutex to protect the PRAGMA temp_store_directory and - PRAGMA data_store_directory statements, even though they are deprecated and - documented as not being threadsafe. See - forum post 719a11e1314d1c70. -
            3. Other bug and warning fixes. See the - timeline - for details. -
            -

            Changes in this specific patch release, version 3.39.4 (2022-09-29):

            -

              -
            1. Fix the build on Windows so that it works with -DSQLITE_OMIT_AUTOINIT -
            2. Fix a long-standing problem in the btree balancer that might, in rare cases, - cause database corruption if the application uses an - application-defined page cache. -
            3. Enhance SQLITE_DBCONFIG_DEFENSIVE so that it disallows CREATE TRIGGER - statements if one or more of the statements in the body of the trigger write - into shadow tables. -
            4. Fix a possible integer overflow in the size computation for a memory allocation - in FTS3. -
            5. Fix a misuse of the sqlite3_set_auxdata() interface in the - ICU Extension. -

              Hashes: -

            6. SQLITE_SOURCE_ID: 2022-09-29 15:55:41 a29f9949895322123f7c38fbe94c649a9d6e6c9cd0c3b41c96d694552f26b309 -
            7. SHA3-256 for sqlite3.c: f65082298127e2ddae6539beb94f5204b591df64ba2c7da83c7d0faffd6959d8 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_3_9.html sqlite3-3.44.0-0/www/releaselog/3_3_9.html --- sqlite3-3.42.0/www/releaselog/3_3_9.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_3_9.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.3.9 On 2007-01-04

            1. Fix bugs in pager.c that could lead to database corruption if two processes both try to recover a hot journal at the same instant
            2. @@ -150,10 +126,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_40_0.html sqlite3-3.44.0-0/www/releaselog/3_40_0.html --- sqlite3-3.42.0/www/releaselog/3_40_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_40_0.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,181 +0,0 @@ - - - - - -SQLite Release 3.40.0 On 2022-11-16 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.40.0 On 2022-11-16

              -
            1. Add support for compiling SQLite to WASM - and running it in web browsers. NB: The WASM build and its interfaces - are considered "beta" and are subject to minor changes if the need - arises. We anticipate finalizing the interface for the next release. -
            2. Add the recovery extension that might be able to recover some content - from a corrupt database file. -
            3. Query planner enhancements: -
                -
              1. Recognize covering indexes on tables with more than 63 columns where - columns beyond the 63rd column are used in the query and/or are - referenced by the index. -
              2. Extract the values of expressions contained within expression indexes - where practical, rather than recomputing the expression. -
              3. The NOT NULL and IS NULL operators (and their equivalents) avoid - loading the content of large strings and BLOB values from disk. -
              4. Avoid materializing a view on which a full scan is performed - exactly once. Use and discard the rows of the view as they are computed. -
              5. Allow flattening of a subquery that is the right-hand operand of - a LEFT JOIN in an aggregate query. -
              -
            4. A new typedef named sqlite3_filename is added and used to represent - the name of a database file. Various interfaces are - modified to use the new typedef instead of "char*". This interface - change should be fully backwards compatible, though it might cause - (harmless) compiler warnings when rebuilding some legacy applications. -
            5. Add the sqlite3_value_encoding() interface. -
            6. Security enhancement: SQLITE_DBCONFIG_DEFENSIVE is augmented to prohibit - changing the schema_version. The schema_version - becomes read-only in defensive mode. -
            7. Enhancements to the PRAGMA integrity_check statement: -
                -
              1. Columns in non-STRICT tables with TEXT affinity should not contain numeric values. -
              2. Columns in non-STRICT tables with NUMERIC affinity should not - contain TEXT values that could be converted into numbers. -
              3. Verify that the rows of a WITHOUT ROWID table are in the correct order. -
              -
            8. Enhance the VACUUM INTO statement so that it honors the - PRAGMA synchronous setting. -
            9. Enhance the sqlite3_strglob() and sqlite3_strlike() APIs so that they are able - to accept NULL pointers for their string parameters and still generate a sensible - result. -
            10. Provide the new SQLITE_MAX_ALLOCATION_SIZE compile-time option for limiting - the size of memory allocations. -
            11. Change the algorithm used by SQLite's built-in pseudo-random number generator (PRNG) - from RC4 to Chacha20. -
            12. Allow two or more indexes to have the same name as long as they are all in - separate schemas. -
            13. Miscellaneous performance optimizations result in about 1% fewer CPU cycles - used on typical workloads. -

              Hashes: -

            14. SQLITE_SOURCE_ID: 2022-11-16 12:10:08 89c459e766ea7e9165d0beeb124708b955a4950d0f4792f457465d71b158d318 -
            15. SHA3-256 for sqlite3.c: ab8da6bc754642989e67d581f26683dc705b068cea671970f0a7d32cfacbad19 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_40_1.html sqlite3-3.44.0-0/www/releaselog/3_40_1.html --- sqlite3-3.42.0/www/releaselog/3_40_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_40_1.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,191 +0,0 @@ - - - - - -SQLite Release 3.40.1 On 2022-12-28 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.40.1 On 2022-12-28

            Prior changes from version 3.40.0 (2022-11-16):

            -

              -
            1. Add support for compiling SQLite to WASM - and running it in web browsers. NB: The WASM build and its interfaces - are considered "beta" and are subject to minor changes if the need - arises. We anticipate finalizing the interface for the next release. -
            2. Add the recovery extension that might be able to recover some content - from a corrupt database file. -
            3. Query planner enhancements: -
                -
              1. Recognize covering indexes on tables with more than 63 columns where - columns beyond the 63rd column are used in the query and/or are - referenced by the index. -
              2. Extract the values of expressions contained within expression indexes - where practical, rather than recomputing the expression. -
              3. The NOT NULL and IS NULL operators (and their equivalents) avoid - loading the content of large strings and BLOB values from disk. -
              4. Avoid materializing a view on which a full scan is performed - exactly once. Use and discard the rows of the view as they are computed. -
              5. Allow flattening of a subquery that is the right-hand operand of - a LEFT JOIN in an aggregate query. -
              -
            4. A new typedef named sqlite3_filename is added and used to represent - the name of a database file. Various interfaces are - modified to use the new typedef instead of "char*". This interface - change should be fully backwards compatible, though it might cause - (harmless) compiler warnings when rebuilding some legacy applications. -
            5. Add the sqlite3_value_encoding() interface. -
            6. Security enhancement: SQLITE_DBCONFIG_DEFENSIVE is augmented to prohibit - changing the schema_version. The schema_version - becomes read-only in defensive mode. -
            7. Enhancements to the PRAGMA integrity_check statement: -
                -
              1. Columns in non-STRICT tables with TEXT affinity should not contain numeric values. -
              2. Columns in non-STRICT tables with NUMERIC affinity should not - contain TEXT values that could be converted into numbers. -
              3. Verify that the rows of a WITHOUT ROWID table are in the correct order. -
              -
            8. Enhance the VACUUM INTO statement so that it honors the - PRAGMA synchronous setting. -
            9. Enhance the sqlite3_strglob() and sqlite3_strlike() APIs so that they are able - to accept NULL pointers for their string parameters and still generate a sensible - result. -
            10. Provide the new SQLITE_MAX_ALLOCATION_SIZE compile-time option for limiting - the size of memory allocations. -
            11. Change the algorithm used by SQLite's built-in pseudo-random number generator (PRNG) - from RC4 to Chacha20. -
            12. Allow two or more indexes to have the same name as long as they are all in - separate schemas. -
            13. Miscellaneous performance optimizations result in about 1% fewer CPU cycles - used on typical workloads. -
            -

            Changes in this specific patch release, version 3.40.1 (2022-12-28):

            -

              -
            1. Fix the --safe command-line option to the CLI - such that it correctly disallows the - use of SQL functions like writefile() that can cause harmful side-effects. -
            2. Fix a potential infinite loop in the memsys5 alternative memory allocator. This - bug was introduced by a performance optimization in version 3.39.0. -
            3. Various other obscure fixes. -

              Hashes: -

            4. SQLITE_SOURCE_ID: 2022-12-28 14:03:47 df5c253c0b3dd24916e4ec7cf77d3db5294cc9fd45ae7b9c5e82ad8197f38a24 -
            5. SHA3-256 for sqlite3.c: 4d6800e9032ff349376fe612e422b49ba5eb4e378fac0b3e405235d09dd366ab - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_4_0.html sqlite3-3.44.0-0/www/releaselog/3_4_0.html --- sqlite3-3.42.0/www/releaselog/3_4_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_4_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.4.0 On 2007-06-18

            1. Fix a bug that can lead to database corruption if an SQLITE_BUSY error occurs in the middle of an explicit transaction and that transaction @@ -122,7 +98,7 @@
            2. Fix a bug that can lead to database corruption if autovacuum mode is on and a malloc() failure follows a CREATE TABLE or CREATE INDEX statement which itself follows a cache overflow inside a transaction. See - ticket #2418. + ticket #2418.
            3. Added explicit upper bounds on the sizes and quantities of things SQLite can process. This change might cause @@ -131,14 +107,14 @@ release is 3.4.0 instead of 3.3.18.
            4. Added support for Incremental BLOB I/O.
            5. Added the sqlite3_bind_zeroblob() API - and the zeroblob() SQL function.
            6. + and the zeroblob() SQL function.
            7. Added support for Incremental Vacuum.
            8. Added the SQLITE_MIXED_ENDIAN_64BIT_FLOAT compile-time option to support ARM7 processors with goofy endianness.
            9. Removed all instances of sprintf() and strcpy() from the core library.
            10. Added support for - International Components for Unicode (ICU) + International Components for Unicode (ICU) to the full-text search extensions.
            11. In the Windows OS driver, reacquire a SHARED lock if an attempt to acquire an EXCLUSIVE lock fails. Ticket #2354
            12. @@ -164,7 +140,7 @@
            13. Fix a bug in the handling of UTF16 codepoint 0xE000
            14. Consider explicit collate clauses when matching WHERE constraints to indices in the query optimizer. Ticket #2391
            15. -
            16. Fix the query optimizer to correctly handle constant expressions in +
            17. Fix the query optimizer to correctly handle constant expressions in the ON clause of a LEFT JOIN. Ticket #2403
            18. Fix the query optimizer to handle rowid comparisons to NULL correctly. Ticket #2404
            19. @@ -174,10 +150,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_41_0.html sqlite3-3.44.0-0/www/releaselog/3_41_0.html --- sqlite3-3.42.0/www/releaselog/3_41_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_41_0.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,192 +0,0 @@ - - - - - -SQLite Release 3.41.0 On 2023-02-21 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.41.0 On 2023-02-21

              -
            1. Query planner improvements: -
                -
              1. Make use of indexed expressions within an aggregate query that - includes a GROUP BY clause. -
              2. The query planner has improved awareness of when an index is - a covering index and adjusts predicted runtimes accordingly. -
              3. The query planner is more aggressive about using co-routines rather - than materializing subqueries and views. -
              4. Queries against the built-in table-valued functions json_tree() and - json_each() will now usually treat "ORDER BY rowid" as a no-op. -
              5. Enhance the ability of the query planner to use indexed expressions - even if the expression has been modified by the - constant-propagation optimization. - (See forum thread 0a539c7.) -
              -
            2. Add the built-in unhex() SQL function. -
            3. Add the base64 and base85 application-defined functions as an extension and - include that extension in the CLI. -
            4. Add the sqlite3_stmt_scanstatus_v2() interface. (This interface is only - available if SQLite is compiled using SQLITE_ENABLE_STMT_SCANSTATUS.) -
            5. In-memory databases created using sqlite3_deserialize() now report their - filename as an empty string, not as 'x'. -
            6. Changes to the CLI: -
                -
              1. Add the new base64() and base85() SQL functions -
              2. Enhanced EXPLAIN QUERY PLAN output using the new sqlite3_stmt_scanstatus_v2() - interface when compiled using SQLITE_ENABLE_STMT_SCANSTATUS. -
              3. The ".scanstats est" command provides query planner estimates in profiles. -
              4. The continuation prompt indicates if the input is currently inside of a - string literal, identifier literal, comment, trigger definition, etc. -
              5. Enhance the --safe command-line option to disallow dangerous SQL functions. -
              6. The double-quoted string misfeature is now disabled by default for CLI - builds. Legacy use cases can reenable the misfeature at run-time using - the ".dbconfig dqs_dml on" and ".dbconfig dqs_ddl on" - commands. -
              -
            7. Enhance the PRAGMA integrity_check command so that it detects when text strings in - a table are equivalent to but not byte-for-byte identical to the same strings in the index. -
            8. Enhance the carray table-valued function so that it is able to bind an array of - BLOB objects. -
            9. Added the sqlite3_is_interrupted() interface. -
            10. Long-running calls to sqlite3_prepare() and similar now invoke the - progress handler callback and react to sqlite3_interrupt(). -
            11. The sqlite3_vtab_in_first() and sqlite3_vtab_in_next() functions are enhanced so that - they reliably detect if they are invoked on a parameter that was not selected for - multi-value IN processing using sqlite3_vtab_in(). - They return SQLITE_ERROR instead of SQLITE_MISUSE in this case. -
            12. The parser now ignores excess parentheses around a subquery on the right-hand side - of an IN operator, so that SQLite now works the same as PostgreSQL in this regard. - Formerly, SQLite treated the subquery as an expression with an implied "LIMIT 1". -
            13. Added the SQLITE_FCNTL_RESET_CACHE option to the sqlite3_file_control() API. -
            14. Makefile improvements: -
                -
              1. The new makefile target "sqlite3r.c" builds an amalgamation that includes - the recovery extension. -
              2. New makefile targets "devtest" and "releasetest" for running a - quick developmental test prior to doing a check-in and for doing a full - release test, respectively. -
              -
            15. Miscellaneous performance enhancements. -

              Hashes: -

            16. SQLITE_SOURCE_ID: 2023-02-21 18:09:37 05941c2a04037fc3ed2ffae11f5d2260706f89431f463518740f72ada350866d -
            17. SHA3-256 for sqlite3.c: 02bd9e678460946810801565667fdb8f0c29c78e51240512d2e5bb3dbdee7464 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_41_1.html sqlite3-3.44.0-0/www/releaselog/3_41_1.html --- sqlite3-3.42.0/www/releaselog/3_41_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_41_1.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,207 +0,0 @@ - - - - - -SQLite Release 3.41.1 On 2023-03-10 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.41.1 On 2023-03-10

            Prior changes from version 3.41.0 (2023-02-21):

            -

              -
            1. Query planner improvements: -
                -
              1. Make use of indexed expressions within an aggregate query that - includes a GROUP BY clause. -
              2. The query planner has improved awareness of when an index is - a covering index and adjusts predicted runtimes accordingly. -
              3. The query planner is more aggressive about using co-routines rather - than materializing subqueries and views. -
              4. Queries against the built-in table-valued functions json_tree() and - json_each() will now usually treat "ORDER BY rowid" as a no-op. -
              5. Enhance the ability of the query planner to use indexed expressions - even if the expression has been modified by the - constant-propagation optimization. - (See forum thread 0a539c7.) -
              -
            2. Add the built-in unhex() SQL function. -
            3. Add the base64 and base85 application-defined functions as an extension and - include that extension in the CLI. -
            4. Add the sqlite3_stmt_scanstatus_v2() interface. (This interface is only - available if SQLite is compiled using SQLITE_ENABLE_STMT_SCANSTATUS.) -
            5. In-memory databases created using sqlite3_deserialize() now report their - filename as an empty string, not as 'x'. -
            6. Changes to the CLI: -
                -
              1. Add the new base64() and base85() SQL functions -
              2. Enhanced EXPLAIN QUERY PLAN output using the new sqlite3_stmt_scanstatus_v2() - interface when compiled using SQLITE_ENABLE_STMT_SCANSTATUS. -
              3. The ".scanstats est" command provides query planner estimates in profiles. -
              4. The continuation prompt indicates if the input is currently inside of a - string literal, identifier literal, comment, trigger definition, etc. -
              5. Enhance the --safe command-line option to disallow dangerous SQL functions. -
              6. The double-quoted string misfeature is now disabled by default for CLI - builds. Legacy use cases can reenable the misfeature at run-time using - the ".dbconfig dqs_dml on" and ".dbconfig dqs_ddl on" - commands. -
              -
            7. Enhance the PRAGMA integrity_check command so that it detects when text strings in - a table are equivalent to but not byte-for-byte identical to the same strings in the index. -
            8. Enhance the carray table-valued function so that it is able to bind an array of - BLOB objects. -
            9. Added the sqlite3_is_interrupted() interface. -
            10. Long-running calls to sqlite3_prepare() and similar now invoke the - progress handler callback and react to sqlite3_interrupt(). -
            11. The sqlite3_vtab_in_first() and sqlite3_vtab_in_next() functions are enhanced so that - they reliably detect if they are invoked on a parameter that was not selected for - multi-value IN processing using sqlite3_vtab_in(). - They return SQLITE_ERROR instead of SQLITE_MISUSE in this case. -
            12. The parser now ignores excess parentheses around a subquery on the right-hand side - of an IN operator, so that SQLite now works the same as PostgreSQL in this regard. - Formerly, SQLite treated the subquery as an expression with an implied "LIMIT 1". -
            13. Added the SQLITE_FCNTL_RESET_CACHE option to the sqlite3_file_control() API. -
            14. Makefile improvements: -
                -
              1. The new makefile target "sqlite3r.c" builds an amalgamation that includes - the recovery extension. -
              2. New makefile targets "devtest" and "releasetest" for running a - quick developmental test prior to doing a check-in and for doing a full - release test, respectively. -
              -
            15. Miscellaneous performance enhancements. -
            -

            Changes in this specific patch release, version 3.41.1 (2023-03-10):

            -

              -
            1. Provide compile-time options -DHAVE_LOG2=0 and -DHAVE_LOG10=0 to enable SQLite to be - compiled on systems that omit the standard library functions log2() and log10(), repectively. -
            2. Ensure that the datatype for column t1.x in - "CREATE TABLE t1 AS SELECT CAST(7 AS INT) AS x;" continues to be INT and is not NUM, - for historical compatibility. -
            3. Enhance PRAGMA integrity_check to detect when extra bytes appear at the end of an - index record. -
            4. Fix various obscure bugs reported by the user community. See the - timeline of changes - for details. - -

              Hashes: -

            5. SQLITE_SOURCE_ID: 2023-03-10 12:13:52 20399f3eda5ec249d147ba9e48da6e87f969d7966a9a896764ca437ff7e737ff -
            6. SHA3-256 for sqlite3.c: d0d9db8425570f4a57def04fb8f4ac84f5c3e4e71d3d4d10472e3639c5fdf09f - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_41_2.html sqlite3-3.44.0-0/www/releaselog/3_41_2.html --- sqlite3-3.42.0/www/releaselog/3_41_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_41_2.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,228 +0,0 @@ - - - - - -SQLite Release 3.41.2 On 2023-03-22 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.41.2 On 2023-03-22

            Prior changes from version 3.41.0 (2023-02-21):

            -

              -
            1. Query planner improvements: -
                -
              1. Make use of indexed expressions within an aggregate query that - includes a GROUP BY clause. -
              2. The query planner has improved awareness of when an index is - a covering index and adjusts predicted runtimes accordingly. -
              3. The query planner is more aggressive about using co-routines rather - than materializing subqueries and views. -
              4. Queries against the built-in table-valued functions json_tree() and - json_each() will now usually treat "ORDER BY rowid" as a no-op. -
              5. Enhance the ability of the query planner to use indexed expressions - even if the expression has been modified by the - constant-propagation optimization. - (See forum thread 0a539c7.) -
              -
            2. Add the built-in unhex() SQL function. -
            3. Add the base64 and base85 application-defined functions as an extension and - include that extension in the CLI. -
            4. Add the sqlite3_stmt_scanstatus_v2() interface. (This interface is only - available if SQLite is compiled using SQLITE_ENABLE_STMT_SCANSTATUS.) -
            5. In-memory databases created using sqlite3_deserialize() now report their - filename as an empty string, not as 'x'. -
            6. Changes to the CLI: -
                -
              1. Add the new base64() and base85() SQL functions -
              2. Enhanced EXPLAIN QUERY PLAN output using the new sqlite3_stmt_scanstatus_v2() - interface when compiled using SQLITE_ENABLE_STMT_SCANSTATUS. -
              3. The ".scanstats est" command provides query planner estimates in profiles. -
              4. The continuation prompt indicates if the input is currently inside of a - string literal, identifier literal, comment, trigger definition, etc. -
              5. Enhance the --safe command-line option to disallow dangerous SQL functions. -
              6. The double-quoted string misfeature is now disabled by default for CLI - builds. Legacy use cases can reenable the misfeature at run-time using - the ".dbconfig dqs_dml on" and ".dbconfig dqs_ddl on" - commands. -
              -
            7. Enhance the PRAGMA integrity_check command so that it detects when text strings in - a table are equivalent to but not byte-for-byte identical to the same strings in the index. -
            8. Enhance the carray table-valued function so that it is able to bind an array of - BLOB objects. -
            9. Added the sqlite3_is_interrupted() interface. -
            10. Long-running calls to sqlite3_prepare() and similar now invoke the - progress handler callback and react to sqlite3_interrupt(). -
            11. The sqlite3_vtab_in_first() and sqlite3_vtab_in_next() functions are enhanced so that - they reliably detect if they are invoked on a parameter that was not selected for - multi-value IN processing using sqlite3_vtab_in(). - They return SQLITE_ERROR instead of SQLITE_MISUSE in this case. -
            12. The parser now ignores excess parentheses around a subquery on the right-hand side - of an IN operator, so that SQLite now works the same as PostgreSQL in this regard. - Formerly, SQLite treated the subquery as an expression with an implied "LIMIT 1". -
            13. Added the SQLITE_FCNTL_RESET_CACHE option to the sqlite3_file_control() API. -
            14. Makefile improvements: -
                -
              1. The new makefile target "sqlite3r.c" builds an amalgamation that includes - the recovery extension. -
              2. New makefile targets "devtest" and "releasetest" for running a - quick developmental test prior to doing a check-in and for doing a full - release test, respectively. -
              -
            15. Miscellaneous performance enhancements. -
            -

            Prior changes from version 3.41.1 (2023-03-10):

            -

              -
            1. Provide compile-time options -DHAVE_LOG2=0 and -DHAVE_LOG10=0 to enable SQLite to be - compiled on systems that omit the standard library functions log2() and log10(), repectively. -
            2. Ensure that the datatype for column t1.x in - "CREATE TABLE t1 AS SELECT CAST(7 AS INT) AS x;" continues to be INT and is not NUM, - for historical compatibility. -
            3. Enhance PRAGMA integrity_check to detect when extra bytes appear at the end of an - index record. -
            4. Fix various obscure bugs reported by the user community. See the - timeline of changes - for details. - -
            -

            Changes in this specific patch release, version 3.41.2 (2023-03-22):

            -

              -
            1. Multiple fixes for reads past the end of memory buffers - (NB: reads not writes) in the following circumstances: -
                -
              1. When processing a corrupt database file using the non-standard - SQLITE_ENABLE_STAT4 compile-time option. -
              2. In the CLI when the sqlite3_error_offset() routine returns an out-of-range value - (see also the fix to sqlite3_error_offset() below). -
              3. In the recovery extension. -
              4. In FTS3 when processing a corrupt database file. -
              -
            2. Fix the sqlite3_error_offset() so that it does not return out-of-range values when - reporting errors associated with generated columns. -
            3. Multiple fixes in the query optimizer for problems that cause incorrect - results for bizarre, fuzzer-generated queries. -
            4. Increase the size of the reference counter in the page cache object to 64 bits to - ensure that the counter never overflows. -
            5. Fix a performance regression caused by a bug fix in patch release 3.41.1. -
            6. Fix a few incorrect assert() statements. -

              Hashes: -

            7. SQLITE_SOURCE_ID: 2023-03-22 11:56:21 0d1fc92f94cb6b76bffe3ec34d69cffde2924203304e8ffc4155597af0c191da -
            8. SHA3-256 for sqlite3.c: c83f68b7aac1e7d3ed0fcdb9857742f024449e1300bfb3375131a6180b36cf7c - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_4_1.html sqlite3-3.44.0-0/www/releaselog/3_4_1.html --- sqlite3-3.42.0/www/releaselog/3_4_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_4_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.4.1 On 2007-07-20

            1. Fix a bug in VACUUM that can lead to database corruptio if two @@ -139,17 +115,16 @@
            2. Add the capability of "hidden" columns in virtual tables.
            3. Use the macro SQLITE_PRIVATE (defaulting to "static") on all internal functions in the amalgamation.
            4. -
            5. Add pluggable tokenizers and ICU +
            6. Add pluggable tokenizers and ICU tokenization support to FTS2
            7. Other minor bug fixes and documentation enhancements

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_42_0.html sqlite3-3.44.0-0/www/releaselog/3_42_0.html --- sqlite3-3.42.0/www/releaselog/3_42_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_42_0.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,177 +0,0 @@ - - - - - -SQLite Release 3.42.0 On 2023-05-16 - - - -
            - - - -
            -
            -Small. Fast. Reliable.
            Choose any three. -
            - - -
            -
            - - - -
            -
            -
            - -

            SQLite Release 3.42.0 On 2023-05-16

              -
            1. Add the FTS5 secure-delete command. This option causes all forensic traces - to be removed from the FTS5 inverted index when content is deleted. -
            2. Enhance the JSON SQL functions to support JSON5 extensions. -
            3. The SQLITE_CONFIG_LOG and SQLITE_CONFIG_PCACHE_HDRSZ calls to sqlite3_config() - are now allowed to occur after sqlite3_initialize(). -
            4. New sqlite3_db_config() options: SQLITE_DBCONFIG_STMT_SCANSTATUS and - SQLITE_DBCONFIG_REVERSE_SCANORDER. -
            5. Query planner improvements: -
                -
              1. Enable the "count-of-view" optimization by default. -
              2. Avoid computing unused columns in subqueries. -
              3. Improvements to the push-down optimization. -
              -
            6. Enhancements to the CLI: -
                -
              1. Add the --unsafe-testing command-line option. Without this option, some - dot-commands (ex: ".testctrl") are now disabled because those commands - that are intended for testing only and can cause malfunctions misused. -
              2. Allow commands ".log on" and ".log off", even in --safe mode. -
              3. "--" as a command-line argument means all subsequent arguments that - start with "-" are interpreted as normal non-option argument. -
              4. Magic parameters ":inf" and ":nan" bind to floating point literals - Infinity and NaN, respectively. -
              5. The --utf8 command-line option omits all translation to or from - MBCS on the Windows console for interactive sessions, and sets - the console code page for UTF-8 I/O during such sessions. - The --utf8 option is a no-op on all other platforms. -
              -
            7. Add the ability for application-defined SQL functions to have the same name - as join keywords: CROSS, FULL, INNER, LEFT, NATURAL, OUTER, or RIGHT. -
            8. Enhancements to PRAGMA integrity_check: -
                -
              1. Detect and raise an error when a NaN value is stored in a NOT NULL column. -
              2. Improved error message output identifies the root page of a b-tree when - an error is found within a b-tree. -
              -
            9. Allow the session extension to be configured to capture changes from - tables that lack an explicit ROWID. -
            10. Added the subsecond modifier to the date and time functions. -
            11. Negative values passed into sqlite3_sleep() are henceforth interpreted as 0. -
            12. The maximum recursion depth for JSON arrays and objects is lowered from 2000 - to 1000. -
            13. Extended the built-in printf() function so the comma option now works with - floating-point conversions in addition to integer conversions. -
            14. Miscellaneous bug fixes and performance optimizations -

              Hashes: -

            15. SQLITE_SOURCE_ID: 2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0 -
            16. SHA3-256 for sqlite3.c: 6aa3fadf000000625353bbaa1e83af114c40c240a0aa5a2c1c2aabcfc28d4f92 - -

            - -

            A complete list of SQLite releases - in a single page and a chronology are both also available. - A detailed history of every - check-in is available at - - SQLite version control site.

            - - diff -Nru sqlite3-3.42.0/www/releaselog/3_4_2.html sqlite3-3.44.0-0/www/releaselog/3_4_2.html --- sqlite3-3.42.0/www/releaselog/3_4_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_4_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.4.2 On 2007-08-13

            1. Fix a database corruption bug that might occur if a ROLLBACK command is executed in auto-vacuum mode -and a very small sqlite3_soft_heap_limit is set. +and a very small sqlite3_soft_heap_limit is set. Ticket #2565.
            2. Add the ability to run a full regression test with a small @@ -126,7 +102,7 @@
            3. Fix other minor problems with using small soft heap limits. -
            4. Work-around for +
            5. Work-around for GCC bug 32575.
            6. Improved error detection of misused aggregate functions. @@ -137,10 +113,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_0.html sqlite3-3.44.0-0/www/releaselog/3_5_0.html --- sqlite3-3.42.0/www/releaselog/3_5_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.0 On 2007-09-04

            1. Redesign the OS interface layer. See 34to35.html for details. @@ -124,8 +100,8 @@ threads in the process, not just the single thread in which they are invoked. *** Potentially incompatible change *** -
            2. Added the sqlite3_open_v2() interface. -
            3. Reimplemented the memory allocation subsystem and made it +
            4. Added the sqlite3_open_v2() interface. +
            5. Reimplemented the memory allocation subsystem and made it replaceable at compile-time.
            6. Created a new mutex subsystem and made it replicable at compile-time. @@ -135,10 +111,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_1.html sqlite3-3.44.0-0/www/releaselog/3_5_1.html --- sqlite3-3.42.0/www/releaselog/3_5_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.1 On 2007-10-04

            1. Nota Bene: We are not using terms "alpha" or "beta" on this release because the code is stable and because if we use those terms, @@ -138,10 +114,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_2.html sqlite3-3.44.0-0/www/releaselog/3_5_2.html --- sqlite3-3.42.0/www/releaselog/3_5_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.2 On 2007-11-05

            1. Dropped support for the SQLITE_OMIT_MEMORY_ALLOCATION compile-time option. @@ -131,10 +107,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_3.html sqlite3-3.44.0-0/www/releaselog/3_5_3.html --- sqlite3-3.42.0/www/releaselog/3_5_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.3 On 2007-11-27

            1. Move website and documentation files out of the source tree into a separate CM system. @@ -139,10 +115,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_4.html sqlite3-3.44.0-0/www/releaselog/3_5_4.html --- sqlite3-3.42.0/www/releaselog/3_5_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,50 +89,26 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.4 On 2007-12-14

            1. Fix a critical bug in UPDATE or DELETE that occurs when an OR REPLACE clause or a trigger causes rows in the same table to be deleted as side effects. (See ticket #2832.) The most likely result of this bug is a segmentation fault, though database corruption is a possibility.
            2. -
            3. Bring the processing of ORDER BY into compliance with the +
            4. Bring the processing of ORDER BY into compliance with the SQL standard for case where a result alias and a table column name are in conflict. Correct behavior is to prefer the result alias. Older versions of SQLite incorrectly picked the table column. (See ticket #2822.)
            5. The VACUUM command preserves -the setting of the +the setting of the legacy_file_format pragma. (Ticket #2804.)
            6. Productize and officially support the group_concat() SQL function.
            7. Better optimization of some IN operator expressions.
            8. -
            9. Add the ability to change the +
            10. Add the ability to change the auto_vacuum status of a database by setting the auto_vaccum pragma and VACUUMing the database.
            11. Prefix search in FTS3 is much more efficient.
            12. @@ -144,10 +120,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_5.html sqlite3-3.44.0-0/www/releaselog/3_5_5.html --- sqlite3-3.42.0/www/releaselog/3_5_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.5 On 2008-01-31

            1. Convert the underlying virtual machine to be a register-based machine rather than a stack-based machine. The only user-visible change @@ -124,10 +100,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_6.html sqlite3-3.44.0-0/www/releaselog/3_5_6.html --- sqlite3-3.42.0/www/releaselog/3_5_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.6 On 2008-02-06

            1. Fix a bug (ticket #2913) that prevented virtual tables from working in a LEFT JOIN. @@ -127,10 +103,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_7.html sqlite3-3.44.0-0/www/releaselog/3_5_7.html --- sqlite3-3.42.0/www/releaselog/3_5_7.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_7.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.7 On 2008-03-17

            1. Fix a bug (ticket #2927) in the register allocation for compound selects - introduced by the new VM code in version 3.5.5.
            2. @@ -141,10 +117,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_8.html sqlite3-3.44.0-0/www/releaselog/3_5_8.html --- sqlite3-3.42.0/www/releaselog/3_5_8.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_8.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.8 On 2008-04-16

            1. Expose SQLite's internal pseudo-random number generator (PRNG) via the sqlite3_randomness() interface
            2. @@ -145,10 +121,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_5_9.html sqlite3-3.44.0-0/www/releaselog/3_5_9.html --- sqlite3-3.42.0/www/releaselog/3_5_9.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_5_9.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.5.9 On 2008-05-14

            1. Added experimental support for the journal_mode PRAGMA and persistent journal.
            2. @@ -139,10 +115,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_0.html sqlite3-3.44.0-0/www/releaselog/3_6_0.html --- sqlite3-3.42.0/www/releaselog/3_6_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.0 On 2008-07-16

            1. Modifications to the virtual file system interface to support a wider range of embedded systems. @@ -135,7 +111,7 @@ but as it has the potential to break legacy applications that depend on the older buggy behavior, we mark that as a *** Potentially incompatible change ***
            2. -
            3. The result column names generated for compound subqueries have been +
            4. The result column names generated for compound subqueries have been simplified to show only the name of the column of the original table and omit the table name. This makes SQLite operate more like other SQL database engines.
            5. @@ -152,10 +128,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_10.html sqlite3-3.44.0-0/www/releaselog/3_6_10.html --- sqlite3-3.42.0/www/releaselog/3_6_10.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_10.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.10 On 2009-01-15

            1. Fix a cache coherency problem that could lead to database corruption. Ticket #3584. @@ -122,10 +98,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_11.html sqlite3-3.44.0-0/www/releaselog/3_6_11.html --- sqlite3-3.42.0/www/releaselog/3_6_11.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_11.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.11 On 2009-02-18

            1. Added the hot-backup interface.
            2. Added new commands ".backup" and ".restore" to the CLI. @@ -127,10 +103,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_12.html sqlite3-3.44.0-0/www/releaselog/3_6_12.html --- sqlite3-3.42.0/www/releaselog/3_6_12.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_12.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.12 On 2009-03-31

            1. Fixed a bug that caused database corruption when an incremental_vacuum is rolled back in an in-memory database. Ticket #3761. @@ -131,10 +107,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_13.html sqlite3-3.44.0-0/www/releaselog/3_6_13.html --- sqlite3-3.42.0/www/releaselog/3_6_13.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_13.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.13 On 2009-04-13

            1. Fix a bug in version 3.6.12 that causes a segfault when running a count(*) on the sqlite_master table of an empty database. Ticket #3774. -
            2. Fix a bug in version 3.6.12 that causes a segfault that when - inserting into a table using a DEFAULT value where there is a +
            3. Fix a bug in version 3.6.12 that causes a segfault that when + inserting into a table using a DEFAULT value where there is a function as part of the DEFAULT value expression. Ticket #3791.
            4. Fix data structure alignment issues on Sparc. Ticket #3777.
            5. Other minor bug fixes. @@ -127,10 +103,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_14_1.html sqlite3-3.44.0-0/www/releaselog/3_6_14_1.html --- sqlite3-3.42.0/www/releaselog/3_6_14_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_14_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.14.1 On 2009-05-19

            1. Fix a bug in group_concat(), ticket #3841
            2. Fix a performance bug in the pager cache, ticket #3844 @@ -124,10 +100,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_14_2.html sqlite3-3.44.0-0/www/releaselog/3_6_14_2.html --- sqlite3-3.42.0/www/releaselog/3_6_14_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_14_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.14.2 On 2009-05-25

            1. Fix a code generator bug introduced in version 3.6.14. This bug can cause incorrect query results under obscure circumstances. @@ -123,10 +99,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_14.html sqlite3-3.44.0-0/www/releaselog/3_6_14.html --- sqlite3-3.42.0/www/releaselog/3_6_14.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_14.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.14 On 2009-05-07

            1. Added the optional asynchronous VFS module.
            2. Enhanced the query optimizer so that virtual tables are able to @@ -129,10 +105,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_15.html sqlite3-3.44.0-0/www/releaselog/3_6_15.html --- sqlite3-3.42.0/www/releaselog/3_6_15.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_15.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.15 On 2009-06-15

            1. Refactor the internal representation of SQL expressions so that they use less memory on embedded platforms. @@ -133,14 +109,14 @@
            2. Continuing improvements to the test suite and fixes to obscure bugs and inconsistencies that the test suite improvements are uncovering. +

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_16_1.html sqlite3-3.44.0-0/www/releaselog/3_6_16_1.html --- sqlite3-3.42.0/www/releaselog/3_6_16_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_16_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,43 +89,18 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.16.1 On 2009-10-30

              -
            1. A small patch to version 3.6.16 to fix +
            2. A small patch to version 3.6.16 to fix the OP_If bug.

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_16.html sqlite3-3.44.0-0/www/releaselog/3_6_16.html --- sqlite3-3.42.0/www/releaselog/3_6_16.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_16.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.16 On 2009-06-27

            1. Fix a bug (ticket #3929) that occasionally causes INSERT or UPDATE operations to fail on an indexed table that has a self-modifying trigger. @@ -123,10 +99,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_17.html sqlite3-3.44.0-0/www/releaselog/3_6_17.html --- sqlite3-3.42.0/www/releaselog/3_6_17.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_17.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.17 On 2009-08-10

            1. Expose the sqlite3_strnicmp() interface for use by extensions and applications. @@ -126,10 +102,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_18.html sqlite3-3.44.0-0/www/releaselog/3_6_18.html --- sqlite3-3.42.0/www/releaselog/3_6_18.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_18.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,42 +89,18 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.18 On 2009-09-11

            1. Versioning of the SQLite source code has transitioned from CVS to Fossil.
            2. Query planner enhancements. -
            3. The SQLITE_ENABLE_STAT2 compile-time option causes the ANALYZE +
            4. The SQLITE_ENABLE_STAT2 compile-time option causes the ANALYZE command to collect a small histogram of each index, to help SQLite better select among competing range query indices.
            5. Recursive triggers can be enabled using the PRAGMA recursive_triggers - statement. -
            6. Delete triggers fire when rows are removed due to a + statement. +
            7. Delete triggers fire when rows are removed due to a REPLACE conflict resolution. This feature is only enabled when recursive triggers are enabled.
            8. Added the SQLITE_OPEN_SHAREDCACHE and SQLITE_OPEN_PRIVATECACHE @@ -139,10 +115,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_19.html sqlite3-3.44.0-0/www/releaselog/3_6_19.html --- sqlite3-3.42.0/www/releaselog/3_6_19.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_19.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.19 On 2009-10-14

            1. Added support for foreign key constraints. Foreign key constraints are disabled by default. Use the foreign_keys pragma to turn them on. @@ -129,10 +105,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_1.html sqlite3-3.44.0-0/www/releaselog/3_6_1.html --- sqlite3-3.42.0/www/releaselog/3_6_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.1 On 2008-08-06

            1. Added the lookaside memory allocator for a speed improvement in excess of 15% on some workloads. (Your mileage may vary.)
            2. @@ -133,10 +109,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_20.html sqlite3-3.44.0-0/www/releaselog/3_6_20.html --- sqlite3-3.42.0/www/releaselog/3_6_20.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_20.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,34 +89,10 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.20 On 2009-11-04

              -
            1. Optimizer enhancement: prepared statements are automatically +
            2. Optimizer enhancement: prepared statements are automatically re-compiled when a binding on the RHS of a LIKE operator changes or when any range constraint changes under SQLITE_ENABLE_STAT2.
            3. Various minor bug fixes and documentation enhancements. @@ -124,10 +100,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_21.html sqlite3-3.44.0-0/www/releaselog/3_6_21.html --- sqlite3-3.42.0/www/releaselog/3_6_21.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_21.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.21 On 2009-12-07

            1. The SQL output resulting from sqlite3_trace() is now modified to include the values of bound parameters. @@ -144,10 +120,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_22.html sqlite3-3.44.0-0/www/releaselog/3_6_22.html --- sqlite3-3.42.0/www/releaselog/3_6_22.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_22.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.22 On 2010-01-06

            1. Fix bugs that can (rarely) lead to incorrect query results when the CAST or OR operators are used in the WHERE clause of a query. @@ -124,10 +100,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_23_1.html sqlite3-3.44.0-0/www/releaselog/3_6_23_1.html --- sqlite3-3.42.0/www/releaselog/3_6_23_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_23_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.23.1 On 2010-03-26

            1. Fix a bug in the offsets() function of FTS3
            2. Fix a missing "sync" that when omitted could lead to database @@ -124,10 +100,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_23.html sqlite3-3.44.0-0/www/releaselog/3_6_23.html --- sqlite3-3.42.0/www/releaselog/3_6_23.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_23.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.23 On 2010-03-09

            1. Added the secure_delete pragma.
            2. Added the sqlite3_compileoption_used() and @@ -136,10 +112,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_2.html sqlite3-3.44.0-0/www/releaselog/3_6_2.html --- sqlite3-3.42.0/www/releaselog/3_6_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.2 On 2008-08-30

            1. Split the pager subsystem into separate pager and pcache subsystems.
            2. Factor out identifier resolution procedures into separate files.
            3. @@ -123,10 +99,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_3.html sqlite3-3.44.0-0/www/releaselog/3_6_3.html --- sqlite3-3.42.0/www/releaselog/3_6_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.3 On 2008-09-22

            1. Fix for a bug in the SELECT DISTINCT logic that was introduced by the prior version.
            2. @@ -123,10 +99,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_4.html sqlite3-3.44.0-0/www/releaselog/3_6_4.html --- sqlite3-3.42.0/www/releaselog/3_6_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.4 On 2008-10-15

            1. Add option support for LIMIT and ORDER BY clauses on DELETE and UPDATE statements. Only works if SQLite is compiled with @@ -131,17 +107,16 @@ documentation for the genfkey program for automatically generating triggers to enforce foreign key constraints.
            2. Added the SQLITE_OMIT_TRUNCATE_OPTIMIZATION compile-time option.
            3. -
            4. The SQL language documentation is converted to use +
            5. The SQL language documentation is converted to use syntax diagrams instead of BNF.
            6. Other minor bug fixes

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_5.html sqlite3-3.44.0-0/www/releaselog/3_6_5.html --- sqlite3-3.42.0/www/releaselog/3_6_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.5 On 2008-11-12

            1. Add the MEMORY option to the journal_mode pragma.
            2. Added the sqlite3_db_mutex() interface.
            3. @@ -135,10 +111,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_6_1.html sqlite3-3.44.0-0/www/releaselog/3_6_6_1.html --- sqlite3-3.42.0/www/releaselog/3_6_6_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_6_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.6.1 On 2008-11-22

            1. Fix a bug in the page cache that can lead database corruption following a rollback. This bug was first introduced in version 3.6.4.
            2. @@ -123,10 +99,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_6_2.html sqlite3-3.44.0-0/www/releaselog/3_6_6_2.html --- sqlite3-3.42.0/www/releaselog/3_6_6_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_6_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.6.2 On 2008-11-26

            1. Fix a bug in the b-tree delete algorithm that seems like it might be able to cause database corruption. The bug was first introduced in @@ -124,10 +100,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_6.html sqlite3-3.44.0-0/www/releaselog/3_6_6.html --- sqlite3-3.42.0/www/releaselog/3_6_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.6 On 2008-11-19

            1. Fix a #define that prevented memsys5 from compiling
            2. Fix a problem in the virtual table commit mechanism that was causing @@ -125,10 +101,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_7.html sqlite3-3.44.0-0/www/releaselog/3_6_7.html --- sqlite3-3.42.0/www/releaselog/3_6_7.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_7.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.7 On 2008-12-16

            1. Reorganize the Unix interface in os_unix.c
            2. Added support for "Proxy Locking" on Mac OS X.
            3. @@ -131,10 +107,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_8.html sqlite3-3.44.0-0/www/releaselog/3_6_8.html --- sqlite3-3.42.0/www/releaselog/3_6_8.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_8.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.8 On 2009-01-12

            1. Added support for nested transactions
            2. Enhanced the query optimizer so that it is able to use - multiple indices to efficiently process + multiple indices to efficiently process OR-connected constraints in a WHERE clause.
            3. Added support for parentheses in FTS3 query patterns using the @@ -127,10 +103,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_6_9.html sqlite3-3.44.0-0/www/releaselog/3_6_9.html --- sqlite3-3.42.0/www/releaselog/3_6_9.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_6_9.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.6.9 On 2009-01-14

            1. Fix two bugs, which when combined might result in incorrect query results. Both bugs were harmless by themselves; only when @@ -123,10 +99,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_0_1.html sqlite3-3.44.0-0/www/releaselog/3_7_0_1.html --- sqlite3-3.42.0/www/releaselog/3_7_0_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_0_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.0.1 On 2010-08-04

            1. Fix a potential database corruption bug that can occur if version 3.7.0 and version 3.6.23.1 alternately write to the same database file. @@ -126,10 +102,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_0.html sqlite3-3.44.0-0/www/releaselog/3_7_0.html --- sqlite3-3.42.0/www/releaselog/3_7_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.0 On 2010-07-21

            1. Added support for write-ahead logging.
            2. Query planner enhancement - automatic transient indices are created @@ -130,10 +106,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_10.html sqlite3-3.44.0-0/www/releaselog/3_7_10.html --- sqlite3-3.42.0/www/releaselog/3_7_10.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_10.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.10 On 2012-01-16

            1. The default schema format number is changed from 1 to 4. This means that, unless @@ -155,7 +131,7 @@ and rmdir() instead of locking files with open() and unlink().
            2. Enhancements to the test_quota.c extension to support stdio-like interfaces with quotas. -
            3. Change the unix VFS to be tolerant of read() system calls that return +
            4. Change the unix VFS to be tolerant of read() system calls that return less then the full number of requested bytes.
            5. Change both unix and windows VFSes to report a sector size of 4096 instead of the old default of 512. @@ -177,17 +153,16 @@
            6. Bug fix: Fix problems that can result from 32-bit integer overflow. Ticket ac00f496b7e2 -
            7. SQLITE_SOURCE_ID: +
            8. SQLITE_SOURCE_ID: "2012-01-16 13:28:40 ebd01a8deffb5024a5d7494eef800d2366d97204"
            9. SHA1 for sqlite3.c: 6497cbbaad47220bd41e2e4216c54706e7ae95d4

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_11.html sqlite3-3.44.0-0/www/releaselog/3_7_11.html --- sqlite3-3.42.0/www/releaselog/3_7_11.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_11.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.11 On 2012-03-20

            1. Enhance the INSERT syntax to allow multiple rows to be inserted via the VALUES clause. @@ -126,31 +102,30 @@
            2. Added the SQLITE_FCNTL_PRAGMA file control, giving VFS implementations the ability to add new PRAGMA statements or to override built-in PRAGMAs. -
            3. Queries of the form: "SELECT max(x), y FROM table" returns the +
            4. Queries of the form: "SELECT max(x), y FROM table" returns the value of y on the same row that contains the maximum x value. -
            5. Added support for the FTS4 languageid option. +
            6. Added support for the FTS4 languageid option.
            7. Documented support for the FTS4 content option. This feature has actually been in the code since version 3.7.9 but is only now considered to be officially supported.
            8. Pending statements no longer block ROLLBACK. Instead, the pending statement will return SQLITE_ABORT upon next access after the ROLLBACK.
            9. Improvements to the handling of CSV inputs in the command-line shell -
            10. Fix a bug introduced +
            11. Fix a bug introduced in version 3.7.10 that might cause a LEFT JOIN to be incorrectly converted into an INNER JOIN if the WHERE clause indexable terms connected by OR. -
            12. SQLITE_SOURCE_ID: +
            13. SQLITE_SOURCE_ID: "2012-03-20 11:35:50 00bb9c9ce4f465e6ac321ced2a9d0062dc364669"
            14. SHA1 for sqlite3.c: d460d7eda3a9dccd291aed2a9fda868b9b120a10

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_12_1.html sqlite3-3.44.0-0/www/releaselog/3_7_12_1.html --- sqlite3-3.42.0/www/releaselog/3_7_12_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_12_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,49 +89,24 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.12.1 On 2012-05-22

              -
            1. Fix a bug +
            2. Fix a bug (ticket c2ad16f997) in the 3.7.12 release that can cause a segfault for certain obscure nested aggregate queries.
            3. Fix various other minor test script problems. -
            4. SQLITE_SOURCE_ID: +
            5. SQLITE_SOURCE_ID: "2012-05-22 02:45:53 6d326d44fd1d626aae0e8456e5fa2049f1ce0789"
            6. SHA1 for sqlite3.c: d494e8d81607f0515d4f386156fb0fd86d5ba7df

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_12.html sqlite3-3.44.0-0/www/releaselog/3_7_12.html --- sqlite3-3.42.0/www/releaselog/3_7_12.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_12.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.12 On 2012-05-14

            1. Add the SQLITE_DBSTATUS_CACHE_WRITE option for sqlite3_db_status().
            2. Optimize the typeof() and length() SQL functions so that they avoid @@ -150,7 +126,7 @@
            3. Bug fix: Do not optimize away an ORDER BY clause that has the same terms as a UNIQUE index unless those terms are also NOT NULL. Ticket 2a5629202f. -
            4. SQLITE_SOURCE_ID: +
            5. SQLITE_SOURCE_ID: "2012-05-14 01:41:23 8654aa9540fe9fd210899d83d17f3f407096c004"
            6. SHA1 for sqlite3.c: 57e2104a0f7b3f528e7f6b7a8e553e2357ccd2e1 @@ -158,10 +134,9 @@

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_13.html sqlite3-3.44.0-0/www/releaselog/3_7_13.html --- sqlite3-3.42.0/www/releaselog/3_7_13.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_13.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.13 On 2012-06-11

            1. In-memory databases that are specified using URI filenames are allowed to use shared cache, @@ -135,17 +111,16 @@ return SQLITE_MISUSE on any attempt to overload or replace a virtual table module. The destructor is always called in this case, in accordance with historical and current documentation. -
            2. SQLITE_SOURCE_ID: +
            3. SQLITE_SOURCE_ID: "2012-06-11 02:05:22 f5b5a13f7394dc143aa136f1d4faba6839eaa6dc"
            4. SHA1 for sqlite3.c: ff0a771d6252545740ba9685e312b0e3bb6a641b

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_14_1.html sqlite3-3.44.0-0/www/releaselog/3_7_14_1.html --- sqlite3-3.42.0/www/releaselog/3_7_14_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_14_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,51 +89,26 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.14.1 On 2012-10-04

              -
            1. Fix a bug (ticket -[d02e1406a58ea02d]]) +
            2. Fix a bug (ticket +[d02e1406a58ea02d]]) that causes a segfault on a LEFT JOIN that includes an OR in the ON clause.
            3. Work around a bug in the optimizer in the VisualStudio-2012 compiler that causes invalid code to be generated when compiling SQLite on ARM.
            4. Fix the TCL interface so that the "nullvalue" setting is honored for TCL implementations of SQL functions. -
            5. SQLITE_SOURCE_ID: +
            6. SQLITE_SOURCE_ID: "2012-10-04 19:37:12 091570e46d04e84b67228e0bdbcd6e1fb60c6bdb"
            7. SHA1 for sqlite3.c: 62aaecaacab3a4bf4a8fe4aec1cfdc1571fe9a44

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_14.html sqlite3-3.44.0-0/www/releaselog/3_7_14.html --- sqlite3-3.42.0/www/releaselog/3_7_14.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_14.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.14 On 2012-09-03

            1. Drop built-in support for OS/2. If you need to upgrade an OS/2 application to use this or a later version of SQLite, @@ -122,7 +98,7 @@ sqlite3_vfs_register() interface. The code removed in this release can serve as a baseline for the application-defined VFS.
            2. Ensure that floating point values are preserved exactly when reconstructing - a database from the output of the ".dump" command of the + a database from the output of the ".dump" command of the command-line shell.
            3. Added the sqlite3_close_v2() interface.
            4. Updated the command-line shell so that it can be built using @@ -140,17 +116,16 @@ contained within subqueries.
            5. Enhance the query planner so that it will try to use a covering index on queries that make use of or optimization. -
            6. SQLITE_SOURCE_ID: +
            7. SQLITE_SOURCE_ID: "2012-09-03 15:42:36 c0d89d4a9752922f9e367362366efde4f1b06f2a"
            8. SHA1 for sqlite3.c: 5fdf596b29bb426001f28b488ff356ae14d5a5a6

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_15_1.html sqlite3-3.44.0-0/www/releaselog/3_7_15_1.html --- sqlite3-3.42.0/www/releaselog/3_7_15_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_15_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,49 +89,24 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.15.1 On 2012-12-19

            1. Fix a bug, introduced in version 3.7.15, that causes a segfault if the AS name of a result column of a SELECT statement is used as a logical - term in the WHERE clause. Ticket + term in the WHERE clause. Ticket a7b7803e8d1e869. -
            2. SQLITE_SOURCE_ID: +
            3. SQLITE_SOURCE_ID: "2012-12-19 20:39:10 6b85b767d0ff7975146156a99ad673f2c1a23318"
            4. SHA1 for sqlite3.c: bbbaa68061e925bd4d7d18d7e1270935c5f7e39a

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_15_2.html sqlite3-3.44.0-0/www/releaselog/3_7_15_2.html --- sqlite3-3.42.0/www/releaselog/3_7_15_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_15_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,49 +89,24 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.15.2 On 2013-01-09

            1. Fix a bug, introduced in version 3.7.15, that causes an ORDER BY clause to be optimized out of a three-way join when the ORDER BY is actually required. Ticket 598f5f7596b055 -
            2. SQLITE_SOURCE_ID: +
            3. SQLITE_SOURCE_ID: "2013-01-09 11:53:05 c0e09560d26f0a6456be9dd3447f5311eb4f238f"
            4. SHA1 for sqlite3.c: 5741f47d1bc38aa0a8c38f09e60a5fe0031f272d

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_15.html sqlite3-3.44.0-0/www/releaselog/3_7_15.html --- sqlite3-3.42.0/www/releaselog/3_7_15.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_15.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.15 On 2012-12-12

            1. Added the sqlite3_errstr() interface.
            2. Avoid invoking the sqlite3_trace() callback multiple times when a @@ -154,17 +130,16 @@
            3. Bug fix: Avoid segfault when using the COLLATE operator inside of a CHECK constraint or view in shared cache mode. -
            4. SQLITE_SOURCE_ID: +
            5. SQLITE_SOURCE_ID: "2012-12-12 13:36:53 cd0b37c52658bfdf992b1e3dc467bae1835a94ae"
            6. SHA1 for sqlite3.c: 2b413611f5e3e3b6ef5f618f2a9209cdf25cbcff"

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_16_1.html sqlite3-3.44.0-0/www/releaselog/3_7_16_1.html --- sqlite3-3.42.0/www/releaselog/3_7_16_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_16_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.16.1 On 2013-03-29

            1. Added the PRAGMA foreign_key_check command.
            2. Added new extended error codes for all SQLITE_CONSTRAINT errors @@ -122,7 +98,7 @@ cannot be opened because it needs rollback recovery but is read-only.
            3. Added SQL functions unicode(A) and char(X1,...,XN).
            4. Performance improvements for PRAGMA incremental_vacuum, especially in - cases where the number of free pages is greater than what will fit on a + cases where the number of free pages is greater than what will fit on a single trunk page of the freelist.
            5. Improved optimization of queries containing aggregate min() or max().
            6. Enhance virtual tables so that they can potentially use an index when @@ -148,11 +124,11 @@ the two tables involved.
            7. Remove all uses of umask() in the unix VFS.
            8. Added the PRAGMA vdbe_addoptrace and PRAGMA vdbe_debug commands. -
            9. Change to use strncmp() or the equivalent instead of memcmp() when +
            10. Change to use strncmp() or the equivalent instead of memcmp() when comparing non-zero-terminated strings.
            11. Update cygwin interfaces to omit deprecated API calls.
            12. Enhance the spellfix1 extension so that the edit distance cost table can - be changed at runtime by inserting a string like 'edit_cost_table=TABLE' + be changed at runtime by inserting a string like 'edit_cost_table=TABLE' into the "command" field.
            13. Bug fix: repair a long-standing problem that could cause incorrect query @@ -183,17 +159,16 @@
            14. The SQLITE_OMIT_MERGE_SORT option has been removed. The merge sorter is now a required component of SQLite.
            15. Fixed lots of spelling errors in the source-code comments -
            16. SQLITE_SOURCE_ID: +
            17. SQLITE_SOURCE_ID: "2013-03-29 13:44:34 527231bc67285f01fb18d4451b28f61da3c4e39d"
            18. SHA1 for sqlite3.c: 7a91ceceac9bcf47ceb8219126276e5518f7ff5a

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_16_2.html sqlite3-3.44.0-0/www/releaselog/3_7_16_2.html --- sqlite3-3.42.0/www/releaselog/3_7_16_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_16_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.16.2 On 2013-04-12

            1. Added the PRAGMA foreign_key_check command.
            2. Added new extended error codes for all SQLITE_CONSTRAINT errors @@ -122,7 +98,7 @@ cannot be opened because it needs rollback recovery but is read-only.
            3. Added SQL functions unicode(A) and char(X1,...,XN).
            4. Performance improvements for PRAGMA incremental_vacuum, especially in - cases where the number of free pages is greater than what will fit on a + cases where the number of free pages is greater than what will fit on a single trunk page of the freelist.
            5. Improved optimization of queries containing aggregate min() or max().
            6. Enhance virtual tables so that they can potentially use an index when @@ -148,11 +124,11 @@ the two tables involved.
            7. Remove all uses of umask() in the unix VFS.
            8. Added the PRAGMA vdbe_addoptrace and PRAGMA vdbe_debug commands. -
            9. Change to use strncmp() or the equivalent instead of memcmp() when +
            10. Change to use strncmp() or the equivalent instead of memcmp() when comparing non-zero-terminated strings.
            11. Update cygwin interfaces to omit deprecated API calls.
            12. Enhance the spellfix1 extension so that the edit distance cost table can - be changed at runtime by inserting a string like 'edit_cost_table=TABLE' + be changed at runtime by inserting a string like 'edit_cost_table=TABLE' into the "command" field.
            13. Bug fix: repair a long-standing problem that could cause incorrect query @@ -187,21 +163,20 @@
            14. Fix a bug (present since version 3.7.13) that could result in database corruption on windows if two or more processes try to access the same database file at the same time and immediately after third process crashed in the middle of committing - to that same file. See ticket + to that same file. See ticket 7ff3120e4f for further information. -
            15. SQLITE_SOURCE_ID: +
            16. SQLITE_SOURCE_ID: "2013-04-12 11:52:43 cbea02d93865ce0e06789db95fd9168ebac970c7"
            17. SHA1 for sqlite3.c: d466b54789dff4fb0238b9232e74896deaefab94

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_16.html sqlite3-3.44.0-0/www/releaselog/3_7_16.html --- sqlite3-3.42.0/www/releaselog/3_7_16.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_16.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.16 On 2013-03-18

            1. Added the PRAGMA foreign_key_check command.
            2. Added new extended error codes for all SQLITE_CONSTRAINT errors @@ -122,7 +98,7 @@ cannot be opened because it needs rollback recovery but is read-only.
            3. Added SQL functions unicode(A) and char(X1,...,XN).
            4. Performance improvements for PRAGMA incremental_vacuum, especially in - cases where the number of free pages is greater than what will fit on a + cases where the number of free pages is greater than what will fit on a single trunk page of the freelist.
            5. Improved optimization of queries containing aggregate min() or max().
            6. Enhance virtual tables so that they can potentially use an index when @@ -148,11 +124,11 @@ the two tables involved.
            7. Remove all uses of umask() in the unix VFS.
            8. Added the PRAGMA vdbe_addoptrace and PRAGMA vdbe_debug commands. -
            9. Change to use strncmp() or the equivalent instead of memcmp() when +
            10. Change to use strncmp() or the equivalent instead of memcmp() when comparing non-zero-terminated strings.
            11. Update cygwin interfaces to omit deprecated API calls.
            12. Enhance the spellfix1 extension so that the edit distance cost table can - be changed at runtime by inserting a string like 'edit_cost_table=TABLE' + be changed at runtime by inserting a string like 'edit_cost_table=TABLE' into the "command" field.
            13. Bug fix: repair a long-standing problem that could cause incorrect query @@ -166,17 +142,16 @@
            14. Bug fix: Make sure the schema is up-to-date prior to running pragmas table_info, index_list, index_info, and foreign_key_list. -
            15. SQLITE_SOURCE_ID: +
            16. SQLITE_SOURCE_ID: "2013-03-18 11:39:23 66d5f2b76750f3520eb7a495f6247206758f5b90"
            17. SHA1 for sqlite3.c: 7308ab891ca1b2ebc596025cfe4dc36f1ee89cf6

            A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

            - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_17.html sqlite3-3.44.0-0/www/releaselog/3_7_17.html --- sqlite3-3.42.0/www/releaselog/3_7_17.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_17.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

            SQLite Release 3.7.17 On 2013-05-20

            1. Add support for memory-mapped I/O.
            2. Add the sqlite3_strglob() convenience interface. @@ -122,9 +98,9 @@ Application ID for when SQLite is used as an application file-format. Added the PRAGMA application_id command to query and set the Application ID.
            3. Report rollback recovery in the error log as SQLITE_NOTICE_RECOVER_ROLLBACK. - Change the error log code for WAL recover from + Change the error log code for WAL recover from SQLITE_OK to SQLITE_NOTICE_RECOVER_WAL. -
            4. Report the risky uses of unlinked database files and +
            5. Report the risky uses of unlinked database files and database filename aliasing as SQLITE_WARNING messages in the error log.
            6. Added the SQLITE_TRACE_SIZE_LIMIT compile-time option.
            7. Increase the default value of SQLITE_MAX_SCHEMA_RETRY to 50 and make sure @@ -146,7 +122,7 @@
          3. Added many new loadable extensions to the source tree, including amatch, closure, fuzzer, ieee754, nextchar, regexp, spellfix, - and wholenumber. See header comments on each extension source file + and wholenumber. See header comments on each extension source file for further information about what that extension does.
          4. Enhance FTS3 to avoid using excess stack space when there are a huge number of terms on the right-hand side of the MATCH operator. A side-effect @@ -167,10 +143,10 @@ Ticket e636a050b7
          5. Bug fix: Only consider AS names from the result set as candidates for resolving - identifiers in the WHERE clause if there are no other matches. In the + identifiers in the WHERE clause if there are no other matches. In the ORDER BY clause, AS names take priority over any column names. Ticket 2500cdb9be05 -
          6. Bug fix: Do not allow a virtual table to cancel the ORDER BY clause unless +
          7. Bug fix: Do not allow a virtual table to cancel the ORDER BY clause unless all outer loops are guaranteed to return no more than one row result. Ticket ba82a4a41eac1.
          8. Bug fix: Do not suppress the ORDER BY clause on a virtual table query if @@ -189,23 +165,22 @@ doing an UPDATE that changes the rowid. Ticket 0eb70d77cb05bb2272
          9. Bug fix: Do not move WHERE clause terms inside OR expressions that are - contained within an ON clause of a LEFT JOIN. Ticket + contained within an ON clause of a LEFT JOIN. Ticket f2369304e4
          10. Bug fix: Make sure an error is always reported when attempting to preform an operation that requires a collating sequence that is missing. Ticket 0fc59f908b -
          11. SQLITE_SOURCE_ID: +
          12. SQLITE_SOURCE_ID: "2013-05-20 00:56:22 118a3b35693b134d56ebd780123b7fd6f1497668"
          13. SHA1 for sqlite3.c: 246987605d0503c700a08b9ee99a6b5d67454aab

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_1.html sqlite3-3.44.0-0/www/releaselog/3_7_1.html --- sqlite3-3.42.0/www/releaselog/3_7_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.1 On 2010-08-23

          1. Added new commands SQLITE_DBSTATUS_SCHEMA_USED and SQLITE_DBSTATUS_STMT_USED to the sqlite3_db_status() interface, in @@ -136,10 +112,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_2.html sqlite3-3.44.0-0/www/releaselog/3_7_2.html --- sqlite3-3.42.0/www/releaselog/3_7_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.2 On 2010-08-24

          1. Fix an old and very obscure bug that can lead to corruption of the @@ -123,10 +99,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_3.html sqlite3-3.44.0-0/www/releaselog/3_7_3.html --- sqlite3-3.42.0/www/releaselog/3_7_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.3 On 2010-10-08

          1. Added the sqlite3_create_function_v2() interface that includes a destructor callback. @@ -127,7 +103,7 @@ SQLITE_ENABLE_MEMORY_MANAGEMENT is not set.
          2. Added the sqlite3_soft_heap_limit64() interface as a replacement for sqlite3_soft_heap_limit(). -
          3. The ANALYZE command now gathers statistics on tables even if they +
          4. The ANALYZE command now gathers statistics on tables even if they have no indices.
          5. Tweaks to the query planner to help it do a better job of finding the most efficient query plan for each query. @@ -145,10 +121,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_4.html sqlite3-3.44.0-0/www/releaselog/3_7_4.html --- sqlite3-3.42.0/www/releaselog/3_7_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.4 On 2010-12-07

          1. Added the sqlite3_blob_reopen() interface to allow an existing sqlite3_blob object to be rebound to a new row. @@ -127,10 +103,11 @@
          2. Added PRAGMA checkpoint_fullfsync.
          3. Added the SQLITE_FCNTL_FILE_POINTER option to sqlite3_file_control(). -
          4. Added support for FTS4 and enhancements +
          5. Added support for FTS4 and enhancements to the FTS matchinfo() function.
          6. Added the test_superlock.c module which provides example - code for obtaining an exclusive lock to a rollback or WAL database. + code for obtaining an exclusive lock to a rollback + or WAL database.
          7. Added the test_multiplex.c module which provides an example VFS that provides multiplexing (sharding) of a DB, splitting it over multiple files of fixed size. @@ -140,10 +117,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_5.html sqlite3-3.44.0-0/www/releaselog/3_7_5.html --- sqlite3-3.42.0/www/releaselog/3_7_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.5 On 2011-02-01

          1. Added the sqlite3_vsnprintf() interface.
          2. Added the SQLITE_DBSTATUS_LOOKASIDE_HIT, @@ -131,13 +107,13 @@ VACUUM that could (in theory) cause database corruption.
          3. Enhance the sqlite3_trace() mechanism so that nested SQL statements such as might be generated by virtual tables are shown but are shown - in comments and without parameter expansion. This + in comments and without parameter expansion. This greatly improves tracing output when using the FTS3/4 and/or RTREE virtual tables.
          4. Change the xFileControl() methods on all built-in VFSes to return SQLITE_NOTFOUND instead of SQLITE_ERROR for an unrecognized operation code. -
          5. The SQLite core invokes the SQLITE_FCNTL_SYNC_OMITTED +
          6. The SQLite core invokes the SQLITE_FCNTL_SYNC_OMITTED file control to the VFS in place of a call to xSync if the database has PRAGMA synchronous set to OFF. @@ -145,10 +121,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_6_1.html sqlite3-3.44.0-0/www/releaselog/3_7_6_1.html --- sqlite3-3.42.0/www/releaselog/3_7_6_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_6_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.6.1 On 2011-04-13

          1. Fix a bug in 3.7.6 that only appears if the SQLITE_FCNTL_SIZE_HINT file control is used with a build of SQLite that makes use of the @@ -127,10 +103,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_6_2.html sqlite3-3.44.0-0/www/releaselog/3_7_6_2.html --- sqlite3-3.42.0/www/releaselog/3_7_6_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_6_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.6.2 On 2011-04-17

          1. Fix the function prototype for the open(2) system call to agree with POSIX. Without this fix, pthreads does not work correctly on NetBSD. @@ -126,10 +102,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_6_3.html sqlite3-3.44.0-0/www/releaselog/3_7_6_3.html --- sqlite3-3.42.0/www/releaselog/3_7_6_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_6_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.6.3 On 2011-05-19

          1. Fix a problem with WAL mode which could cause transactions to silently rollback if the cache_size is set very small (less than 10) @@ -123,10 +99,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_6.html sqlite3-3.44.0-0/www/releaselog/3_7_6.html --- sqlite3-3.42.0/www/releaselog/3_7_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.6 On 2011-04-12

          1. Added the sqlite3_wal_checkpoint_v2() interface and enhanced the wal_checkpoint pragma to support blocking checkpoints. @@ -147,10 +123,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_7_1.html sqlite3-3.44.0-0/www/releaselog/3_7_7_1.html --- sqlite3-3.42.0/www/releaselog/3_7_7_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_7_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,34 +89,10 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.7.1 On 2011-06-28

            -
          1. Fix a bug causing +
          2. Fix a bug causing PRAGMA case_sensitive_like statements compiled using sqlite3_prepare() to fail with an SQLITE_SCHEMA error.
          3. SQLITE_SOURCE_ID: @@ -126,10 +102,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_7.html sqlite3-3.44.0-0/www/releaselog/3_7_7.html --- sqlite3-3.42.0/www/releaselog/3_7_7.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_7.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.7 On 2011-06-23

          1. Add support for URI filenames
          2. Add the sqlite3_vtab_config() interface in @@ -135,10 +111,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_8.html sqlite3-3.44.0-0/www/releaselog/3_7_8.html --- sqlite3-3.42.0/www/releaselog/3_7_8.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_8.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.8 On 2011-09-19

          1. Orders of magnitude performance improvement for CREATE INDEX on very large tables. @@ -124,7 +100,7 @@
          2. Allow more system calls to be overridden in the unix VFS - to provide better support for chromium sandboxes.
          3. Increase the default size of a lookahead cache line from 100 to 128 bytes. -
          4. Enhancements to the test_quota.c module so that it can track +
          5. Enhancements to the test_quota.c module so that it can track preexisting files.
          6. Bug fix: Virtual tables now handle IS NOT NULL constraints correctly.
          7. Bug fixes: Correctly handle nested correlated subqueries used with @@ -136,10 +112,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_7_9.html sqlite3-3.44.0-0/www/releaselog/3_7_9.html --- sqlite3-3.42.0/www/releaselog/3_7_9.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_7_9.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.7.9 On 2011-11-01

          1. If a search token (on the right-hand side of the MATCH operator) in FTS4 begins with "^" then that token must be the first in its field @@ -135,7 +111,7 @@
          2. Enhanced the query planner so that it can factor terms in and out of OR expressions in the WHERE clause in an effort to find better indices.
          3. Added the SQLITE_DIRECT_OVERFLOW_READ compile-time option, causing - overflow pages to be read directly from the database file, + overflow pages to be read directly from the database file, bypassing the page cache.
          4. Remove limits on the magnitude of precision and width value in the format specifiers of the sqlite3_mprintf() family of string rendering @@ -155,17 +131,16 @@
          5. Fix a bug in virtual table implementation that causes a crash if an FTS4 table is dropped inside a transaction and a SAVEPOINT occurs afterwards. -
          6. SQLITE_SOURCE_ID: +
          7. SQLITE_SOURCE_ID: "2011-11-01 00:52:41 c7c6050ef060877ebe77b41d959e9df13f8c9b5e"
          8. SHA1 for sqlite3.c: becd16877f4f9b281b91c97e106089497d71bb47

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_0_1.html sqlite3-3.44.0-0/www/releaselog/3_8_0_1.html --- sqlite3-3.42.0/www/releaselog/3_8_0_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_0_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.8.0.1 On 2013-08-29

          1. Add support for partial indexes
          2. Cut-over to the next generation query planner for faster and better query plans. -
          3. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of +
          4. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of rows generated by each loop in a join.
          5. Added the FTS4 notindexed option, allowing non-indexed columns in an FTS4 table.
          6. Added the SQLITE_STMTSTATUS_VM_STEP option to sqlite3_stmt_status(). @@ -138,7 +114,7 @@
          7. Issue an SQLITE_WARNING_AUTOINDEX warning on the SQLITE_CONFIG_LOG whenever the query planner uses an automatic index.
          8. Added the SQLITE_FTS3_MAX_EXPR_DEPTH compile-time option. -
          9. Added an optional 5th parameter defining the collating sequence to the +
          10. Added an optional 5th parameter defining the collating sequence to the next_char() extension SQL function.
          11. The SQLITE_BUSY_SNAPSHOT extended error code is returned in WAL mode when a read transaction cannot be upgraded to a write transaction because the read is @@ -146,7 +122,7 @@
          12. Enhancements to the sqlite3_analyzer utility program to provide size information separately for each individual index of a table, in addition to the aggregate size. -
          13. Allow read transactions to be freely opened and closed by SQL statements run +
          14. Allow read transactions to be freely opened and closed by SQL statements run from within the implementation of application-defined SQL functions if the function is called by a SELECT statement that does not access any database table.
          15. Disable the use of posix_fallocate() on all (unix) systems unless the @@ -159,28 +135,27 @@
          16. Bug fix: Bare identifiers in ORDER BY clauses bind more tightly to output column names, but identifiers in expressions bind more tightly to input column names. Identifiers in GROUP BY clauses always prefer output column names, however. -
          17. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the +
          18. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the move to NGQP.

            -
          1. Fix an off-by-one error that caused quoted empty string at the end of a +
          2. Fix an off-by-one error that caused quoted empty string at the end of a CRNL-terminated line of CSV input to be misread by the command-line shell.
          3. Fix a query planner bug involving a LEFT JOIN with a BETWEEN or LIKE/GLOB constraint and then another INNER JOIN to the right that involves an OR constraint.
          4. Fix a query planner bug that could result in a segfault when querying tables with a UNIQUE or PRIMARY KEY constraint with more than four columns. -
          5. SQLITE_SOURCE_ID: +
          6. SQLITE_SOURCE_ID: "2013-08-29 17:35:01 352362bc01660edfbda08179d60f09e2038a2f49"
          7. SHA1 for sqlite3.c: 99906bf63e6cef63d6f3d7f8526ac4a70e76559e

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_0_2.html sqlite3-3.44.0-0/www/releaselog/3_8_0_2.html --- sqlite3-3.42.0/www/releaselog/3_8_0_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_0_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.8.0.2 On 2013-09-03

          1. Add support for partial indexes
          2. Cut-over to the next generation query planner for faster and better query plans. -
          3. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of +
          4. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of rows generated by each loop in a join.
          5. Added the FTS4 notindexed option, allowing non-indexed columns in an FTS4 table.
          6. Added the SQLITE_STMTSTATUS_VM_STEP option to sqlite3_stmt_status(). @@ -138,7 +114,7 @@
          7. Issue an SQLITE_WARNING_AUTOINDEX warning on the SQLITE_CONFIG_LOG whenever the query planner uses an automatic index.
          8. Added the SQLITE_FTS3_MAX_EXPR_DEPTH compile-time option. -
          9. Added an optional 5th parameter defining the collating sequence to the +
          10. Added an optional 5th parameter defining the collating sequence to the next_char() extension SQL function.
          11. The SQLITE_BUSY_SNAPSHOT extended error code is returned in WAL mode when a read transaction cannot be upgraded to a write transaction because the read is @@ -146,7 +122,7 @@
          12. Enhancements to the sqlite3_analyzer utility program to provide size information separately for each individual index of a table, in addition to the aggregate size. -
          13. Allow read transactions to be freely opened and closed by SQL statements run +
          14. Allow read transactions to be freely opened and closed by SQL statements run from within the implementation of application-defined SQL functions if the function is called by a SELECT statement that does not access any database table.
          15. Disable the use of posix_fallocate() on all (unix) systems unless the @@ -159,11 +135,11 @@
          16. Bug fix: Bare identifiers in ORDER BY clauses bind more tightly to output column names, but identifiers in expressions bind more tightly to input column names. Identifiers in GROUP BY clauses always prefer output column names, however. -
          17. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the +
          18. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the move to NGQP.

            -
          1. Fix an off-by-one error that caused quoted empty string at the end of a +
          2. Fix an off-by-one error that caused quoted empty string at the end of a CRNL-terminated line of CSV input to be misread by the command-line shell.
          3. Fix a query planner bug involving a LEFT JOIN with a BETWEEN or LIKE/GLOB constraint and then another INNER JOIN to the right that involves an OR constraint. @@ -173,17 +149,16 @@

          1. Fix a bug in the optimization that attempts to omit unused LEFT JOINs -
          2. SQLITE_SOURCE_ID: +
          3. SQLITE_SOURCE_ID: "2013-09-03 17:11:13 7dd4968f235d6e1ca9547cda9cf3bd570e1609ef"
          4. SHA1 for sqlite3.c: 6cf0c7b46975a87a0dc3fba69c229a7de61b0c21

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_0.html sqlite3-3.44.0-0/www/releaselog/3_8_0.html --- sqlite3-3.42.0/www/releaselog/3_8_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.8.0 On 2013-08-26

          1. Add support for partial indexes
          2. Cut-over to the next generation query planner for faster and better query plans. -
          3. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of +
          4. The EXPLAIN QUERY PLAN output no longer shows an estimate of the number of rows generated by each loop in a join.
          5. Added the FTS4 notindexed option, allowing non-indexed columns in an FTS4 table.
          6. Added the SQLITE_STMTSTATUS_VM_STEP option to sqlite3_stmt_status(). @@ -138,7 +114,7 @@
          7. Issue an SQLITE_WARNING_AUTOINDEX warning on the SQLITE_CONFIG_LOG whenever the query planner uses an automatic index.
          8. Added the SQLITE_FTS3_MAX_EXPR_DEPTH compile-time option. -
          9. Added an optional 5th parameter defining the collating sequence to the +
          10. Added an optional 5th parameter defining the collating sequence to the next_char() extension SQL function.
          11. The SQLITE_BUSY_SNAPSHOT extended error code is returned in WAL mode when a read transaction cannot be upgraded to a write transaction because the read is @@ -146,7 +122,7 @@
          12. Enhancements to the sqlite3_analyzer utility program to provide size information separately for each individual index of a table, in addition to the aggregate size. -
          13. Allow read transactions to be freely opened and closed by SQL statements run +
          14. Allow read transactions to be freely opened and closed by SQL statements run from within the implementation of application-defined SQL functions if the function is called by a SELECT statement that does not access any database table.
          15. Disable the use of posix_fallocate() on all (unix) systems unless the @@ -159,20 +135,19 @@
          16. Bug fix: Bare identifiers in ORDER BY clauses bind more tightly to output column names, but identifiers in expressions bind more tightly to input column names. Identifiers in GROUP BY clauses always prefer output column names, however. -
          17. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the +
          18. Bug fixes: Multiple problems in the legacy query optimizer were fixed by the move to NGQP. -
          19. SQLITE_SOURCE_ID: +
          20. SQLITE_SOURCE_ID: "2013-08-26 04:50:08 f64cd21e2e23ed7cff48f7dafa5e76adde9321c2"
          21. SHA1 for sqlite3.c: b7347f4b4c2a840e6ba12040093d606bd16ea21e

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_10_1.html sqlite3-3.44.0-0/www/releaselog/3_8_10_1.html --- sqlite3-3.42.0/www/releaselog/3_8_10_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_10_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

          SQLite Release 3.8.10.1 On 2015-05-09

          Prior changes from version 3.8.10 (2015-05-07):

          + +

          SQLite Release 3.8.10.1 On 2015-05-09

          Changes in version 3.8.10 (2015-05-07):

          1. Added the sqldiff.exe utility program for computing the differences between two SQLite database files. -
          2. Added the matchinfo y flag to the +
          3. Added the matchinfo y flag to the matchinfo() function of FTS3.
          4. Performance improvements for ORDER BY, VACUUM, CREATE INDEX, PRAGMA integrity_check, and PRAGMA quick_check. @@ -133,7 +109,7 @@ compiled with the SQLITE_ENABLE_DBSTAT_VTAB option.
          -

          Changes in this specific patch release, version 3.8.10.1 (2015-05-09):

          +

          Additional changes in version 3.8.10.1 (2015-05-09):

          1. Make sqlite3_compileoption_used() responsive to the SQLITE_ENABLE_DBSTAT_VTAB compile-time option. @@ -146,10 +122,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_10_2.html sqlite3-3.44.0-0/www/releaselog/3_8_10_2.html --- sqlite3-3.42.0/www/releaselog/3_8_10_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_10_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

          SQLite Release 3.8.10.2 On 2015-05-20

          Prior changes from version 3.8.10 (2015-05-07):

          + +

          SQLite Release 3.8.10.2 On 2015-05-20

          Changes in version 3.8.10 (2015-05-07):

          1. Added the sqldiff.exe utility program for computing the differences between two SQLite database files. -
          2. Added the matchinfo y flag to the +
          3. Added the matchinfo y flag to the matchinfo() function of FTS3.
          4. Performance improvements for ORDER BY, VACUUM, CREATE INDEX, PRAGMA integrity_check, and PRAGMA quick_check. @@ -133,7 +109,7 @@ compiled with the SQLITE_ENABLE_DBSTAT_VTAB option.
          -

          Prior changes from version 3.8.10.1 (2015-05-09):

          +

          Additional changes in version 3.8.10.1 (2015-05-09):

          1. Make sqlite3_compileoption_used() responsive to the SQLITE_ENABLE_DBSTAT_VTAB compile-time option. @@ -141,10 +117,10 @@
          2. Fix minor issues with the dbstat virtual table.
          -

          Changes in this specific patch release, version 3.8.10.2 (2015-05-20):

          +

          Additional changes in version 3.8.10.2 (2015-05-20):

          1. Fix an index corruption issue introduced by version 3.8.7. An index - with a TEXT key can be corrupted by an INSERT into the corresponding + with a TEXT key can be corrupted by an INSERT into the corresponding table if the table has two nested triggers that convert the key value to INTEGER and back to TEXT again. Ticket 34cd55d68e0 @@ -155,10 +131,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_10.html sqlite3-3.44.0-0/www/releaselog/3_8_10.html --- sqlite3-3.42.0/www/releaselog/3_8_10.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_10.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.8.10 On 2015-05-07

          1. Added the sqldiff.exe utility program for computing the differences between two SQLite database files. -
          2. Added the matchinfo y flag to the +
          3. Added the matchinfo y flag to the matchinfo() function of FTS3.
          4. Performance improvements for ORDER BY, VACUUM, CREATE INDEX, PRAGMA integrity_check, and PRAGMA quick_check. @@ -137,10 +113,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_11_1.html sqlite3-3.44.0-0/www/releaselog/3_8_11_1.html --- sqlite3-3.42.0/www/releaselog/3_8_11_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_11_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

          SQLite Release 3.8.11.1 On 2015-07-29

          Prior changes from version 3.8.11 (2015-07-27):

          + +

          SQLite Release 3.8.11.1 On 2015-07-29

          Changes in version 3.8.11 (2015-07-27):

          1. Added the experimental RBU extension. Note that this extension is experimental and subject to change in incompatible ways. @@ -141,10 +117,10 @@ use for the initial set page cache lines. Set the default preallocation to 100 pages. Yields about a 5% performance increase on common workloads.
          2. Miscellaneous micro-optimizations result in 22.3% more work for the same - number of CPU cycles relative to the previous release. + number of CPU cycles relative to the previous release. SQLite now runs twice as fast as version 3.8.0 and three times as fast as version 3.3.9. - (Measured using + (Measured using cachegrind on the speedtest1.c workload on Ubuntu 14.04 x64 with gcc 4.8.2 and -Os. Your performance may vary.) @@ -165,7 +141,7 @@ so that they actually do provide a 64-bit answer.
          -

          Changes in this specific patch release, version 3.8.11.1 (2015-07-29):

          +

          Additional changes in version 3.8.11.1 (2015-07-29):

          1. Restore an undocumented side-effect of PRAGMA cache_size: force the database schema to be parsed if the database has not been previously accessed. @@ -177,10 +153,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_11.html sqlite3-3.44.0-0/www/releaselog/3_8_11.html --- sqlite3-3.42.0/www/releaselog/3_8_11.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_11.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.8.11 On 2015-07-27

          1. Added the experimental RBU extension. Note that this extension is experimental and subject to change in incompatible ways. @@ -140,10 +116,10 @@ use for the initial set page cache lines. Set the default preallocation to 100 pages. Yields about a 5% performance increase on common workloads.
          2. Miscellaneous micro-optimizations result in 22.3% more work for the same - number of CPU cycles relative to the previous release. + number of CPU cycles relative to the previous release. SQLite now runs twice as fast as version 3.8.0 and three times as fast as version 3.3.9. - (Measured using + (Measured using cachegrind on the speedtest1.c workload on Ubuntu 14.04 x64 with gcc 4.8.2 and -Os. Your performance may vary.) @@ -170,10 +146,9 @@

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_1.html sqlite3-3.44.0-0/www/releaselog/3_8_1.html --- sqlite3-3.42.0/www/releaselog/3_8_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

          SQLite Release 3.8.1 On 2013-10-17

          1. Added the unlikely() and likelihood() SQL functions to be used as hints to the query planner. @@ -127,7 +103,7 @@
        3. Added the soft_heap_limit pragma.
        4. Added support for SQLITE_ENABLE_STAT4 -
        5. Added support for "sz=NNN" parameters at the end of +
        6. Added support for "sz=NNN" parameters at the end of sqlite_stat1.stat fields used to specify the average length in bytes for table and index rows.
        7. Avoid running foreign-key constraint checks on an UPDATE if none of the @@ -156,17 +132,16 @@ there is a partial index on the table. Ticket a5c8ed66ca. -
        8. SQLITE_SOURCE_ID: +
        9. SQLITE_SOURCE_ID: "2013-10-17 12:57:35 c78be6d786c19073b3a6730dfe3fb1be54f5657a"
        10. SHA1 for sqlite3.c: 0a54d76566728c2ba96292a49b138e4f69a7c391

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_2.html sqlite3-3.44.0-0/www/releaselog/3_8_2.html --- sqlite3-3.42.0/www/releaselog/3_8_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.2 On 2013-12-06

        1. Changed the defined behavior for the CAST expression when floating point values - greater than +9223372036854775807 are cast into integers so that the + greater than +9223372036854775807 are cast into into integers so that the result is the largest possible integer, +9223372036854775807, instead of - the smallest possible integer, -9223372036854775808. After this change, + the smallest possible integer, -9223372036854775808. After this change, CAST(9223372036854775809.0 as INT) yields +9223372036854775807 instead of -9223372036854775808.  Potentially Incompatible Change! @@ -141,17 +117,16 @@
        2. Enhanced the ".timer" feature of the command-line shell so that it shows wall-clock time in addition to system and user times. -
        3. SQLITE_SOURCE_ID: +
        4. SQLITE_SOURCE_ID: "2013-12-06 14:53:30 27392118af4c38c5203a04b8013e1afdb1cebd0d"
        5. SHA1 for sqlite3.c: 6422c7d69866f5ea3db0968f67ee596e7114544e

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_3_1.html sqlite3-3.44.0-0/www/releaselog/3_8_3_1.html --- sqlite3-3.42.0/www/releaselog/3_8_3_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_3_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.3.1 On 2014-02-11

        1. Fix a bug (ticket 4c86b126f2) that causes rows to go missing on some queries with OR clauses and @@ -127,10 +103,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_3.html sqlite3-3.44.0-0/www/releaselog/3_8_3.html --- sqlite3-3.42.0/www/releaselog/3_8_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.3 On 2014-02-03

        1. Added support for common table expressions and the WITH clause.
        2. Added the printf() SQL function. @@ -139,17 +115,16 @@ considers dangerous. (Ex: sprintf).
        3. Bug fix: In the command-line shell CSV import feature, do not end a field when an escaped double-quote occurs at the end of a CRLN line. -
        4. SQLITE_SOURCE_ID: +
        5. SQLITE_SOURCE_ID: "2014-02-03 13:52:03 e816dd924619db5f766de6df74ea2194f3e3b538"
        6. SHA1 for sqlite3.c: 98a07da78f71b0275e8d9c510486877adc31dbee

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_4_1.html sqlite3-3.44.0-0/www/releaselog/3_8_4_1.html --- sqlite3-3.42.0/www/releaselog/3_8_4_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_4_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.8.4.1 On 2014-03-11

        Prior changes from version 3.8.4 (2014-03-10):

        + +

        SQLite Release 3.8.4.1 On 2014-03-11

        Changes in version 3.8.4 (2014-03-10):

        1. Code optimization and refactoring for improved performance.
        2. Add the ".clone" and ".save" commands to the command-line shell. @@ -125,13 +101,13 @@
        3. Add support for coverage testing of VDBE programs using the SQLITE_TESTCTRL_VDBE_COVERAGE verb of sqlite3_test_control().
        4. Update the _FILE_OFFSET_BITS macro so that builds work again on QNX. -
        5. Change the datatype of SrcList.nSrc from type u8 to type int to work around +
        6. Change the datatype of SrcList.nSrc from type u8 to type int to work around an issue in the C compiler on AIX.
        7. Get extension loading working on Cygwin.
        8. Bug fix: Fix the char() SQL function so that it returns an empty string - rather than an "out of memory" error when called with zero arguments. + rather than an "out of memory" error when called with zero arguments.
        9. Bug fix: DISTINCT now recognizes that a zeroblob and a blob of all - 0x00 bytes are the same thing. + 0x00 bytes are the same thing. Ticket [fccbde530a]
        10. Bug fix: Compute the correct answer for queries that contain an IS NOT NULL term in the WHERE clause and also contain an OR term in the WHERE clause and @@ -154,7 +130,7 @@ the column to a floating point value approximately equal to +9223372036854775808.0.
        -

        Changes in this specific patch release, version 3.8.4.1 (2014-03-11):

        +

        Additional changes in version 3.8.4.1 (2014-03-11):

        1. Work around a C-preprocessor macro conflict that breaks the build for some configurations with Microsoft Visual Studio. @@ -166,10 +142,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_4_2.html sqlite3-3.44.0-0/www/releaselog/3_8_4_2.html --- sqlite3-3.42.0/www/releaselog/3_8_4_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_4_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.8.4.2 On 2014-03-26

        Prior changes from version 3.8.4 (2014-03-10):

        + +

        SQLite Release 3.8.4.2 On 2014-03-26

        Changes in version 3.8.4 (2014-03-10):

        1. Code optimization and refactoring for improved performance.
        2. Add the ".clone" and ".save" commands to the command-line shell. @@ -125,13 +101,13 @@
        3. Add support for coverage testing of VDBE programs using the SQLITE_TESTCTRL_VDBE_COVERAGE verb of sqlite3_test_control().
        4. Update the _FILE_OFFSET_BITS macro so that builds work again on QNX. -
        5. Change the datatype of SrcList.nSrc from type u8 to type int to work around +
        6. Change the datatype of SrcList.nSrc from type u8 to type int to work around an issue in the C compiler on AIX.
        7. Get extension loading working on Cygwin.
        8. Bug fix: Fix the char() SQL function so that it returns an empty string - rather than an "out of memory" error when called with zero arguments. + rather than an "out of memory" error when called with zero arguments.
        9. Bug fix: DISTINCT now recognizes that a zeroblob and a blob of all - 0x00 bytes are the same thing. + 0x00 bytes are the same thing. Ticket [fccbde530a]
        10. Bug fix: Compute the correct answer for queries that contain an IS NOT NULL term in the WHERE clause and also contain an OR term in the WHERE clause and @@ -154,14 +130,14 @@ the column to a floating point value approximately equal to +9223372036854775808.0.
        -

        Prior changes from version 3.8.4.1 (2014-03-11):

        +

        Additional changes in version 3.8.4.1 (2014-03-11):

        1. Work around a C-preprocessor macro conflict that breaks the build for some configurations with Microsoft Visual Studio.
        2. When computing the cost of the skip-scan optimization, take into account the fact that multiple seeks are required.
        -

        Changes in this specific patch release, version 3.8.4.2 (2014-03-26):

        +

        Additional changes in version 3.8.4.2 (2014-03-26):

        1. Fix a potential buffer overread that could result when trying to search a corrupt database file. @@ -171,10 +147,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_4_3.html sqlite3-3.44.0-0/www/releaselog/3_8_4_3.html --- sqlite3-3.42.0/www/releaselog/3_8_4_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_4_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.8.4.3 On 2014-04-03

        Prior changes from version 3.8.4 (2014-03-10):

        + +

        SQLite Release 3.8.4.3 On 2014-04-03

        Changes in version 3.8.4 (2014-03-10):

        1. Code optimization and refactoring for improved performance.
        2. Add the ".clone" and ".save" commands to the command-line shell. @@ -125,13 +101,13 @@
        3. Add support for coverage testing of VDBE programs using the SQLITE_TESTCTRL_VDBE_COVERAGE verb of sqlite3_test_control().
        4. Update the _FILE_OFFSET_BITS macro so that builds work again on QNX. -
        5. Change the datatype of SrcList.nSrc from type u8 to type int to work around +
        6. Change the datatype of SrcList.nSrc from type u8 to type int to work around an issue in the C compiler on AIX.
        7. Get extension loading working on Cygwin.
        8. Bug fix: Fix the char() SQL function so that it returns an empty string - rather than an "out of memory" error when called with zero arguments. + rather than an "out of memory" error when called with zero arguments.
        9. Bug fix: DISTINCT now recognizes that a zeroblob and a blob of all - 0x00 bytes are the same thing. + 0x00 bytes are the same thing. Ticket [fccbde530a]
        10. Bug fix: Compute the correct answer for queries that contain an IS NOT NULL term in the WHERE clause and also contain an OR term in the WHERE clause and @@ -154,21 +130,21 @@ the column to a floating point value approximately equal to +9223372036854775808.0.
        -

        Prior changes from version 3.8.4.1 (2014-03-11):

        +

        Additional changes in version 3.8.4.1 (2014-03-11):

        1. Work around a C-preprocessor macro conflict that breaks the build for some configurations with Microsoft Visual Studio.
        2. When computing the cost of the skip-scan optimization, take into account the fact that multiple seeks are required.
        -

        Prior changes from version 3.8.4.2 (2014-03-26):

        +

        Additional changes in version 3.8.4.2 (2014-03-26):

        1. Fix a potential buffer overread that could result when trying to search a corrupt database file.
        -

        Changes in this specific patch release, version 3.8.4.3 (2014-04-03):

        +

        Additional changes in version 3.8.4.3 (2014-04-03):

          -
        1. Add a +
        2. Add a one-character fix for a problem that might cause incorrect query results on a query that mixes DISTINCT, GROUP BY in a subquery, and ORDER BY. @@ -179,10 +155,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_4.html sqlite3-3.44.0-0/www/releaselog/3_8_4.html --- sqlite3-3.42.0/www/releaselog/3_8_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.4 On 2014-03-10

        1. Code optimization and refactoring for improved performance.
        2. Add the ".clone" and ".save" commands to the command-line shell. @@ -124,13 +100,13 @@
        3. Add support for coverage testing of VDBE programs using the SQLITE_TESTCTRL_VDBE_COVERAGE verb of sqlite3_test_control().
        4. Update the _FILE_OFFSET_BITS macro so that builds work again on QNX. -
        5. Change the datatype of SrcList.nSrc from type u8 to type int to work around +
        6. Change the datatype of SrcList.nSrc from type u8 to type int to work around an issue in the C compiler on AIX.
        7. Get extension loading working on Cygwin.
        8. Bug fix: Fix the char() SQL function so that it returns an empty string - rather than an "out of memory" error when called with zero arguments. + rather than an "out of memory" error when called with zero arguments.
        9. Bug fix: DISTINCT now recognizes that a zeroblob and a blob of all - 0x00 bytes are the same thing. + 0x00 bytes are the same thing. Ticket [fccbde530a]
        10. Bug fix: Compute the correct answer for queries that contain an IS NOT NULL term in the WHERE clause and also contain an OR term in the WHERE clause and @@ -158,10 +134,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_5.html sqlite3-3.44.0-0/www/releaselog/3_8_5.html --- sqlite3-3.42.0/www/releaselog/3_8_5.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_5.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.5 On 2014-06-04

        1. Added support for partial sorting by index.
        2. Enhance the query planner so that it always prefers an index that uses a superset of @@ -151,7 +127,7 @@
        3. ORDER BY ignored if the query has an identical GROUP BY. Ticket b75a9ca6b0
        4. The group_concat(x,'') SQL function returns NULL instead of an empty string - when all inputs are empty strings. + when all inputs are empty strings. Ticket 55746f9e65
        5. Fix a bug in the VDBE code generator that caused crashes when doing an INSERT INTO ... SELECT statement where the number of columns @@ -175,10 +151,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_6.html sqlite3-3.44.0-0/www/releaselog/3_8_6.html --- sqlite3-3.42.0/www/releaselog/3_8_6.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_6.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.6 On 2014-08-15

        1. Added support for hexadecimal integer literals in the SQL parser. (Ex: 0x123abc) @@ -178,10 +154,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_7_1.html sqlite3-3.44.0-0/www/releaselog/3_8_7_1.html --- sqlite3-3.42.0/www/releaselog/3_8_7_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_7_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.7.1 On 2014-10-29

        1. In PRAGMA journal_mode=TRUNCATE mode, call fsync() immediately after truncating the journal file to ensure that the transaction is durable across a power loss. @@ -131,10 +107,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_7_2.html sqlite3-3.44.0-0/www/releaselog/3_8_7_2.html --- sqlite3-3.42.0/www/releaselog/3_8_7_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_7_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.7.2 On 2014-11-18

        1. Enhance the ROLLBACK command so that pending queries are allowed to continue as long as the schema is unchanged. Formerly, a ROLLBACK would cause all pending queries to @@ -125,7 +101,7 @@ Ticket 094d39a4c95ee4.
        2. Bug fix: The %c format in sqlite3_mprintf() is able to handle precisions greater than 70.
        3. Bug fix: Do not automatically remove the DISTINCT keyword from a SELECT that forms - the right-hand side of an IN operator since it is necessary if the SELECT also + the right-hand side of an IN operator since it is necessary if the SELECT also contains a LIMIT. Ticket db87229497. @@ -135,10 +111,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_7_3.html sqlite3-3.44.0-0/www/releaselog/3_8_7_3.html --- sqlite3-3.42.0/www/releaselog/3_8_7_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_7_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,37 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.7.3 On 2014-12-05

        1. Bug fix: Ensure the cached KeyInfo objects (an internal abstraction not visible to the application) do not go stale when operating in shared cache mode and frequently closing and reopening some database connections while leaving other database connections on the - same shared cache open continuously. Ticket + same shared cache open continuously. Ticket e4a18565a36884b00edf.
        2. Bug fix: Recognize that any column in the right-hand table of a LEFT JOIN can be NULL even if the column has a NOT NULL constraint. Do not apply optimizations that @@ -132,10 +108,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_7_4.html sqlite3-3.44.0-0/www/releaselog/3_8_7_4.html --- sqlite3-3.42.0/www/releaselog/3_8_7_4.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_7_4.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.7.4 On 2014-12-09

        1. Bug fix: Add in a mutex that was omitted from the previous release.
        2. SQLITE_SOURCE_ID: "2014-12-09 01:34:36 f66f7a17b78ba617acde90fc810107f34f1a1f2e" @@ -123,10 +99,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_7.html sqlite3-3.44.0-0/www/releaselog/3_8_7.html --- sqlite3-3.42.0/www/releaselog/3_8_7.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_7.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,38 +89,14 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.7 On 2014-10-17

          Performance Enhancements:

        1. Many micro-optimizations result in 20.3% more work for the same number - of CPU cycles relative to the previous release. + of CPU cycles relative to the previous release. The cumulative performance increase since version 3.8.0 is 61%. - (Measured using + (Measured using cachegrind on the speedtest1.c workload on Ubuntu 13.10 x64 with gcc 4.8.1 and -Os. Your performance may vary.) @@ -164,7 +140,7 @@ Ticket 369d57fb8e5ccdff06f1

          Test, Debug, and Analysis Changes:

        2. Show ASCII-art abstract syntax tree diagrams using the ".selecttrace" - and ".wheretrace" commands in the + and ".wheretrace" commands in the command-line shell when compiled with SQLITE_DEBUG, SQLITE_ENABLE_SELECTTRACE, and SQLITE_ENABLE_WHERETRACE. Also provide the sqlite3TreeViewExpr() and sqlite3TreeViewSelect() entry points that can be invoked from with the @@ -180,10 +156,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_8_1.html sqlite3-3.44.0-0/www/releaselog/3_8_8_1.html --- sqlite3-3.42.0/www/releaselog/3_8_8_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_8_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.8.8.1 On 2015-01-20

        Prior changes from version 3.8.8 (2015-01-16):

        + +

        SQLite Release 3.8.8.1 On 2015-01-20

        Changes in version 3.8.8 (2015-01-16):

          New Features:

        1. Added the PRAGMA data_version command that can be used to determine if @@ -166,7 +142,7 @@
        2. Fix obscure crash bugs found by american fuzzy lop. Ticket a59ae93ee990a55. -
        3. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the +
        4. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the R-Tree extension to compute incorrect results when compiled with -O3.

          Other changes:

        5. Disable the use of the strchrnul() C-library routine unless it is @@ -175,7 +151,7 @@ likelihood(), likely(), and unlikely() SQL hint functions.
        -

        Changes in this specific patch release, version 3.8.8.1 (2015-01-20):

        +

        Additional changes in version 3.8.8.1 (2015-01-20):

        1. Fix a bug in the sorting logic, present since version 3.8.4, that can cause output to appear in the wrong order on queries that contains an ORDER BY clause, @@ -188,10 +164,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_8_2.html sqlite3-3.44.0-0/www/releaselog/3_8_8_2.html --- sqlite3-3.42.0/www/releaselog/3_8_8_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_8_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.8.8.2 On 2015-01-30

        Prior changes from version 3.8.8 (2015-01-16):

        + +

        SQLite Release 3.8.8.2 On 2015-01-30

        Changes in version 3.8.8 (2015-01-16):

          New Features:

        1. Added the PRAGMA data_version command that can be used to determine if @@ -166,7 +142,7 @@
        2. Fix obscure crash bugs found by american fuzzy lop. Ticket a59ae93ee990a55. -
        3. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the +
        4. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the R-Tree extension to compute incorrect results when compiled with -O3.

          Other changes:

        5. Disable the use of the strchrnul() C-library routine unless it is @@ -175,7 +151,7 @@ likelihood(), likely(), and unlikely() SQL hint functions.
        -

        Prior changes from version 3.8.8.1 (2015-01-20):

        +

        Additional changes in version 3.8.8.1 (2015-01-20):

        1. Fix a bug in the sorting logic, present since version 3.8.4, that can cause output to appear in the wrong order on queries that contains an ORDER BY clause, @@ -183,7 +159,7 @@ Ticket f97c4637102a3ae72b79.
        -

        Changes in this specific patch release, version 3.8.8.2 (2015-01-30):

        +

        Additional changes in version 3.8.8.2 (2015-01-30):

        1. Enhance sqlite3_wal_checkpoint_v2(TRUNCATE) interface so that it truncates the WAL file even if there is no checkpoint work to be done. @@ -195,10 +171,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_8_3.html sqlite3-3.44.0-0/www/releaselog/3_8_8_3.html --- sqlite3-3.42.0/www/releaselog/3_8_8_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_8_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.8.8.3 On 2015-02-25

        Prior changes from version 3.8.8 (2015-01-16):

        + +

        SQLite Release 3.8.8.3 On 2015-02-25

        Changes in version 3.8.8 (2015-01-16):

          New Features:

        1. Added the PRAGMA data_version command that can be used to determine if @@ -166,7 +142,7 @@
        2. Fix obscure crash bugs found by american fuzzy lop. Ticket a59ae93ee990a55. -
        3. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the +
        4. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the R-Tree extension to compute incorrect results when compiled with -O3.

          Other changes:

        5. Disable the use of the strchrnul() C-library routine unless it is @@ -175,7 +151,7 @@ likelihood(), likely(), and unlikely() SQL hint functions.
        -

        Prior changes from version 3.8.8.1 (2015-01-20):

        +

        Additional changes in version 3.8.8.1 (2015-01-20):

        1. Fix a bug in the sorting logic, present since version 3.8.4, that can cause output to appear in the wrong order on queries that contains an ORDER BY clause, @@ -183,19 +159,19 @@ Ticket f97c4637102a3ae72b79.
        -

        Prior changes from version 3.8.8.2 (2015-01-30):

        +

        Additional changes in version 3.8.8.2 (2015-01-30):

        1. Enhance sqlite3_wal_checkpoint_v2(TRUNCATE) interface so that it truncates the WAL file even if there is no checkpoint work to be done.
        -

        Changes in this specific patch release, version 3.8.8.3 (2015-02-25):

        +

        Additional changes in version 3.8.8.3 (2015-02-25):

        1. Fix a bug (ticket 2326c258d02ead33) that can lead to incorrect results if the qualifying constraint of a partial index appears in the ON clause of a LEFT JOIN. -
        2. Added the ability to link against the +
        3. Added the ability to link against the "linenoise" command-line editing library in unix builds of the command-line shell. @@ -205,10 +181,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_8.html sqlite3-3.44.0-0/www/releaselog/3_8_8.html --- sqlite3-3.42.0/www/releaselog/3_8_8.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_8.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.8 On 2015-01-16

          New Features:

        1. Added the PRAGMA data_version command that can be used to determine if @@ -165,7 +141,7 @@
        2. Fix obscure crash bugs found by american fuzzy lop. Ticket a59ae93ee990a55. -
        3. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the +
        4. Work around a GCC optimizer bug (for gcc 4.2.1 on MacOS 10.7) that caused the R-Tree extension to compute incorrect results when compiled with -O3.

          Other changes:

        5. Disable the use of the strchrnul() C-library routine unless it is @@ -179,10 +155,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_8_9.html sqlite3-3.44.0-0/www/releaselog/3_8_9.html --- sqlite3-3.42.0/www/releaselog/3_8_9.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_8_9.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.8.9 On 2015-04-08

        1. Add VxWorks-7 as an officially supported and tested platform.
        2. Added the sqlite3_status64() interface. @@ -129,7 +105,7 @@
        3. Correct miscounts in the sqlite3_analyzer.exe utility related to WITHOUT ROWID tables.
        4. Added the ".dbinfo" command to the command-line shell. -
        5. Improve the performance of fts3/4 queries that use the OR operator +
        6. Improve the performance of fts3/4 queries that use the OR operator and at least one auxiliary fts function.
        7. Fix a bug in the fts3 snippet() function causing it to omit leading separator characters from snippets that begin with the @@ -140,10 +116,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_9_0.html sqlite3-3.44.0-0/www/releaselog/3_9_0.html --- sqlite3-3.42.0/www/releaselog/3_9_0.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_9_0.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

        SQLite Release 3.9.0 On 2015-10-14

          Policy Changes:

        1. The version numbering conventions for SQLite are revised to use the @@ -139,7 +115,7 @@
        2. The query planner is now able to use partial indexes that contain AND-connected terms in the WHERE clause.
        3. The sqlite3_analyzer.exe utility is updated to report the depth of - each btree and to show the average fanout for indexes and + each btree and to show the average fanout for indexes and WITHOUT ROWID tables.
        4. Enhanced the dbstat virtual table so that it can be used as a table-valued function where the argument is the schema to be @@ -148,9 +124,9 @@
        5. The sqlite3_memory_alarm() interface, which has been deprecated and undocumented for 8 years, is changed into a no-op.

          Important fixes: -

        6. Fixed a critical bug in the +
        7. Fixed a critical bug in the SQLite Encryption Extension that - could cause the database to become unreadable and unrecoverable if a VACUUM command + could cause the database to become unreadable and unrecoverable if a VACUUM command changed the size of the encryption nonce.
        8. Added a memory barrier in the implementation of sqlite3_initialize() to help ensure that it is thread-safe. @@ -166,10 +142,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_9_1.html sqlite3-3.44.0-0/www/releaselog/3_9_1.html --- sqlite3-3.42.0/www/releaselog/3_9_1.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_9_1.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.9.1 On 2015-10-16

        Prior changes from version 3.9.0 (2015-10-14):

        + +

        SQLite Release 3.9.1 On 2015-10-16

        Changes in version 3.9.0 (2015-10-14):

          Policy Changes:

        1. The version numbering conventions for SQLite are revised to use the @@ -140,7 +116,7 @@
        2. The query planner is now able to use partial indexes that contain AND-connected terms in the WHERE clause.
        3. The sqlite3_analyzer.exe utility is updated to report the depth of - each btree and to show the average fanout for indexes and + each btree and to show the average fanout for indexes and WITHOUT ROWID tables.
        4. Enhanced the dbstat virtual table so that it can be used as a table-valued function where the argument is the schema to be @@ -149,9 +125,9 @@
        5. The sqlite3_memory_alarm() interface, which has been deprecated and undocumented for 8 years, is changed into a no-op.

          Important fixes: -

        6. Fixed a critical bug in the +
        7. Fixed a critical bug in the SQLite Encryption Extension that - could cause the database to become unreadable and unrecoverable if a VACUUM command + could cause the database to become unreadable and unrecoverable if a VACUUM command changed the size of the encryption nonce.
        8. Added a memory barrier in the implementation of sqlite3_initialize() to help ensure that it is thread-safe. @@ -162,7 +138,7 @@ c2a19d81652f40568c.
        -

        Changes in this specific patch release, version 3.9.1 (2015-10-16):

        +

        Additional changes in version 3.9.1 (2015-10-16):

        1. Fix the json1 extension so that it does not recognize ASCII form-feed as a whitespace character, in order to comply with RFC-7159. Fix for ticket @@ -176,10 +152,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_9_2.html sqlite3-3.44.0-0/www/releaselog/3_9_2.html --- sqlite3-3.42.0/www/releaselog/3_9_2.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_9_2.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.9.2 On 2015-11-02

        Prior changes from version 3.9.0 (2015-10-14):

        + +

        SQLite Release 3.9.2 On 2015-11-02

        Changes in version 3.9.0 (2015-10-14):

          Policy Changes:

        1. The version numbering conventions for SQLite are revised to use the @@ -140,7 +116,7 @@
        2. The query planner is now able to use partial indexes that contain AND-connected terms in the WHERE clause.
        3. The sqlite3_analyzer.exe utility is updated to report the depth of - each btree and to show the average fanout for indexes and + each btree and to show the average fanout for indexes and WITHOUT ROWID tables.
        4. Enhanced the dbstat virtual table so that it can be used as a table-valued function where the argument is the schema to be @@ -149,9 +125,9 @@
        5. The sqlite3_memory_alarm() interface, which has been deprecated and undocumented for 8 years, is changed into a no-op.

          Important fixes: -

        6. Fixed a critical bug in the +
        7. Fixed a critical bug in the SQLite Encryption Extension that - could cause the database to become unreadable and unrecoverable if a VACUUM command + could cause the database to become unreadable and unrecoverable if a VACUUM command changed the size of the encryption nonce.
        8. Added a memory barrier in the implementation of sqlite3_initialize() to help ensure that it is thread-safe. @@ -162,7 +138,7 @@ c2a19d81652f40568c.
        -

        Prior changes from version 3.9.1 (2015-10-16):

        +

        Additional changes in version 3.9.1 (2015-10-16):

        1. Fix the json1 extension so that it does not recognize ASCII form-feed as a whitespace character, in order to comply with RFC-7159. Fix for ticket @@ -171,9 +147,9 @@ appeared after the 3.9.0 release.
        -

        Changes in this specific patch release, version 3.9.2 (2015-11-02):

        +

        Additional changes in version 3.9.2 (2015-11-02):

          -
        1. Fix the schema parser so that it interprets certain +
        2. Fix the schema parser so that it interprets certain (obscure and ill-formed) CREATE TABLE statements the same as legacy. Fix for ticket ac661962a2aeab3c331 @@ -188,10 +164,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/3_9_3.html sqlite3-3.44.0-0/www/releaselog/3_9_3.html --- sqlite3-3.42.0/www/releaselog/3_9_3.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/3_9_3.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.9.3 On 2016-04-01

        Prior changes from version 3.9.0 (2015-10-14):

        + +

        SQLite Release 3.9.3 On 2016-04-01

        Changes in version 3.9.0 (2015-10-14):

          Policy Changes:

        1. The version numbering conventions for SQLite are revised to use the @@ -140,7 +116,7 @@
        2. The query planner is now able to use partial indexes that contain AND-connected terms in the WHERE clause.
        3. The sqlite3_analyzer.exe utility is updated to report the depth of - each btree and to show the average fanout for indexes and + each btree and to show the average fanout for indexes and WITHOUT ROWID tables.
        4. Enhanced the dbstat virtual table so that it can be used as a table-valued function where the argument is the schema to be @@ -149,9 +125,9 @@
        5. The sqlite3_memory_alarm() interface, which has been deprecated and undocumented for 8 years, is changed into a no-op.

          Important fixes: -

        6. Fixed a critical bug in the +
        7. Fixed a critical bug in the SQLite Encryption Extension that - could cause the database to become unreadable and unrecoverable if a VACUUM command + could cause the database to become unreadable and unrecoverable if a VACUUM command changed the size of the encryption nonce.
        8. Added a memory barrier in the implementation of sqlite3_initialize() to help ensure that it is thread-safe. @@ -162,7 +138,7 @@ c2a19d81652f40568c.
        -

        Prior changes from version 3.9.1 (2015-10-16):

        +

        Additional changes in version 3.9.1 (2015-10-16):

        1. Fix the json1 extension so that it does not recognize ASCII form-feed as a whitespace character, in order to comply with RFC-7159. Fix for ticket @@ -171,9 +147,9 @@ appeared after the 3.9.0 release.
        -

        Prior changes from version 3.9.2 (2015-11-02):

        +

        Additional changes in version 3.9.2 (2015-11-02):

          -
        1. Fix the schema parser so that it interprets certain +
        2. Fix the schema parser so that it interprets certain (obscure and ill-formed) CREATE TABLE statements the same as legacy. Fix for ticket ac661962a2aeab3c331 @@ -183,7 +159,7 @@ 8a2adec1.
        -

        Changes in this specific patch release, version 3.9.3 (2016-04-01):

        +

        Additional changes in version 3.9.3 (2016-04-01):

        1. Backport a simple query planner optimization @@ -194,10 +170,9 @@

        A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

        - diff -Nru sqlite3-3.42.0/www/releaselog/current.html sqlite3-3.44.0-0/www/releaselog/current.html --- sqlite3-3.42.0/www/releaselog/current.html 2023-05-16 13:43:11.000000000 +0000 +++ sqlite3-3.44.0-0/www/releaselog/current.html 2023-11-04 14:24:19.000000000 +0000 @@ -3,7 +3,7 @@ -SQLite Release 3.42.0 On 2023-05-16 +SQLite Release 3.36.0 On 2021-06-18 @@ -89,89 +89,43 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

        SQLite Release 3.42.0 On 2023-05-16

          -
        1. Add the FTS5 secure-delete command. This option causes all forensic traces - to be removed from the FTS5 inverted index when content is deleted. -
        2. Enhance the JSON SQL functions to support JSON5 extensions. -
        3. The SQLITE_CONFIG_LOG and SQLITE_CONFIG_PCACHE_HDRSZ calls to sqlite3_config() - are now allowed to occur after sqlite3_initialize(). -
        4. New sqlite3_db_config() options: SQLITE_DBCONFIG_STMT_SCANSTATUS and - SQLITE_DBCONFIG_REVERSE_SCANORDER. -
        5. Query planner improvements: -
            -
          1. Enable the "count-of-view" optimization by default. -
          2. Avoid computing unused columns in subqueries. -
          3. Improvements to the push-down optimization. -
          -
        6. Enhancements to the CLI: -
            -
          1. Add the --unsafe-testing command-line option. Without this option, some - dot-commands (ex: ".testctrl") are now disabled because those commands - that are intended for testing only and can cause malfunctions misused. -
          2. Allow commands ".log on" and ".log off", even in --safe mode. -
          3. "--" as a command-line argument means all subsequent arguments that - start with "-" are interpreted as normal non-option argument. -
          4. Magic parameters ":inf" and ":nan" bind to floating point literals - Infinity and NaN, respectively. -
          5. The --utf8 command-line option omits all translation to or from - MBCS on the Windows console for interactive sessions, and sets - the console code page for UTF-8 I/O during such sessions. - The --utf8 option is a no-op on all other platforms. -
          -
        7. Add the ability for application-defined SQL functions to have the same name - as join keywords: CROSS, FULL, INNER, LEFT, NATURAL, OUTER, or RIGHT. -
        8. Enhancements to PRAGMA integrity_check: -
            -
          1. Detect and raise an error when a NaN value is stored in a NOT NULL column. -
          2. Improved error message output identifies the root page of a b-tree when - an error is found within a b-tree. -
          -
        9. Allow the session extension to be configured to capture changes from - tables that lack an explicit ROWID. -
        10. Added the subsecond modifier to the date and time functions. -
        11. Negative values passed into sqlite3_sleep() are henceforth interpreted as 0. -
        12. The maximum recursion depth for JSON arrays and objects is lowered from 2000 - to 1000. -
        13. Extended the built-in printf() function so the comma option now works with - floating-point conversions in addition to integer conversions. -
        14. Miscellaneous bug fixes and performance optimizations + +

          SQLite Release 3.36.0 On 2021-06-18

            +
          1. Improvement to the EXPLAIN QUERY PLAN output to make it easier to + understand. +
          2. Byte-order marks at the start of a token are skipped as if they + were whitespace. +
          3. An error is raised on any attempt to access the rowid of a VIEW or subquery. + Formerly, the rowid of a VIEW would be indeterminate and often would be NULL. + The -DSQLITE_ALLOW_ROWID_IN_VIEW compile-time option is available to restore + the legacy behavior for applications that need it. +
          4. The sqlite3_deserialize() and sqlite3_serialize() interfaces are now + enabled by default. The -DSQLITE_ENABLE_DESERIALIZE compile-time option is + no longer required. Instead, there is is a new -DSQLITE_OMIT_DESERIALIZE + compile-time option to omit those interfaces. +
          5. The "memdb" VFS now allows the same in-memory database to be shared among + multiple database connections in the same process as long as the + database name begins with "/". +
          6. Back out the EXISTS-to-IN optimization (item 8b in the + SQLite 3.35.0 change log) + as it was found to slow down queries more often than speed them up. +
          7. Improve the constant-propagation optimization so that it works on + non-join queries. +
          8. The REGEXP extension is + now included in CLI builds. + +

            Hashes: -

          9. SQLITE_SOURCE_ID: 2023-05-16 12:36:15 831d0fb2836b71c9bc51067c49fee4b8f18047814f2ff22d817d25195cf350b0 -
          10. SHA3-256 for sqlite3.c: 6aa3fadf000000625353bbaa1e83af114c40c240a0aa5a2c1c2aabcfc28d4f92 +
          11. SQLITE_SOURCE_ID: 2021-06-18 18:36:39 5c9a6c06871cb9fe42814af9c039eb6da5427a6ec28f187af7ebfb62eafa66e5 +
          12. SHA3-256 for sqlite3.c: 2a8e87aaa414ac2d45ace8eb74e710935423607a8de0fafcb36bbde5b952d157

          A complete list of SQLite releases - in a single page and a chronology are both also available. + in a single page and a chronology are both also available. A detailed history of every check-in is available at SQLite version control site.

          - diff -Nru sqlite3-3.42.0/www/requirements.html sqlite3-3.44.0-0/www/requirements.html --- sqlite3-3.42.0/www/requirements.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/requirements.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -234,7 +210,13002 @@

          2.0 List Of Requirements

          +
          R-00013-61831-22423-62410-56475-12017-42000-15640
          +

          The key comes first and is separated from the value by a single "=" character. +(source: uri.html, matrix: context, detail)

          + +
          R-00090-24248-38638-40643-10159-25596-30389-07024
          +

          The third argument, aCoord[], is an array of nCoord coordinates that defines a bounding box to be tested. +(source: rtree.html, matrix: context, detail)

          + +
          R-00099-40772-25508-42886-05693-46370-34145-00683
          +

          Simply setting the locking-mode to NORMAL is not enough - locks are not released until the next time the database file is accessed. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-00109-30887-26782-37306-11423-15179-45221-18025
          +

          A virtual table module is created by filling in a persistent instance of this structure and passing a pointer to that instance to sqlite3_create_module() or sqlite3_create_module_v2(). +(source: c3ref/module.html, matrix: context, detail)

          + +
          R-00110-20874-52504-15299-56251-38354-26784-53834
          +

          SQLITE_TOOBIG might be returned if the size of a string or BLOB exceeds limits imposed by sqlite3_limit(SQLITE_LIMIT_LENGTH) or SQLITE_MAX_LENGTH. +(source: c3ref/bind_blob.html, checked-by: th3/cov1/vdbeapi03.test, matrix: context, detail)

          + +
          R-00140-37445-57377-20863-40395-21152-20469-25306
          +

          SQLite automatically serializes calls to the xInit method, so the xInit method need not be threadsafe. +(source: c3ref/pcache_methods2.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-00143-55862-36284-22296-28662-09257-51521-03944
          +

          The usual case is that the entire database file is checked. +(source: pragma.html, matrix: context, detail)

          + +
          R-00171-59428-63637-20419-61024-28048-20428-49478
          +

          In such cases, duplicate elements are filtered before being passed into the aggregate function. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-00197-14279-64967-54349-51250-28289-13484-05768
          +

          The rank of the column within the index. (0 means left-most. Key columns come before auxiliary columns.) +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-00203-32193-54208-20071-18893-56924-36288-02453
          +

          Contrary to the intuition of many, sqlite3_reset() does not reset the bindings on a prepared statement. +(source: c3ref/clear_bindings.html, checked-by: th3/req1/clearbind01.test, matrix: context, detail)

          + +
          R-00217-01605-34207-18386-37017-37707-31164-60184
          +

          To create a WITHOUT ROWID table, simply add the keywords "WITHOUT ROWID" to the end of the CREATE TABLE statement. For example: CREATE TABLE IF NOT EXISTS wordcount( word TEXT PRIMARY KEY, cnt INTEGER ) WITHOUT ROWID; +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-00220-34634-35173-21345-54000-63909-52170-35980
          +

          Otherwise, an expression has no affinity. +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-00227-21080-37302-15362-03285-23826-51380-28642
          +

          A UNIQUE constraint is similar to a PRIMARY KEY constraint, except that a single table may have any number of UNIQUE constraints. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-00243-07929-08239-44820-61576-27318-53216-12960
          +

          If the declared type of the column contains any of the strings "CHAR", "CLOB", or "TEXT" then that column has TEXT affinity. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-00267-47727-45128-11139-64344-07863-10234-35895
          +

          The initial "INSERT" keyword can be replaced by "REPLACE" or "INSERT OR action" to specify an alternative constraint conflict resolution algorithm to use during that one INSERT command. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-00279-52283-49814-15354-28909-18424-55374-18430
          +

          Returning to the example in section 1, each time an application deletes a row from the artist table (the parent table), it performs the equivalent of the following SELECT statement to search for referencing rows in the track table (the child table). SELECT rowid FROM track WHERE trackartist = ? where ? in the above is replaced with the value of the artistid column of the record being deleted from the artist table (recall that the trackartist column is the child key and the artistid column is the parent key). +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys10.test, matrix: context, detail)

          + +
          R-00293-64994-39339-33419-11494-64597-05681-15697
          +

          This SQL function is implemented using the sqlite3_result_zeroblob() routine from the C/C++ interface. +(source: lang_corefunc.html, checked-by: src/func.c, matrix: context, detail)

          + +
          R-00303-53643-59539-09278-38608-05869-19672-31996
          +

          The T argument is one of the integer type codes above. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-00311-09993-39149-44899-64441-18371-52816-22132
          +

          aConstraint[].usable is TRUE if the expr on the right-hand side can be evaluated (and thus the constraint is usable) and false if it cannot. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-00336-65009-59389-29167-11927-65433-48801-33923
          +

          PRAGMA temp_store; PRAGMA temp_store = 0 | DEFAULT | 1 | FILE | 2 | MEMORY; Query or change the setting of the "temp_store" parameter. +(source: pragma.html, matrix: context, detail)

          + +
          R-00353-01851-44275-08807-26330-41077-52452-65296
          +

          The subquery and outer query do not both use LIMIT. +(source: optoverview.html, matrix: context, detail)

          + +
          R-00359-41639-41144-27010-59632-30416-37191-53432
          +

          The view definition is removed from the database schema, but no actual data in the underlying base tables is modified. +(source: lang_dropview.html, checked-by: tcl/e_dropview.test, matrix: context, detail)

          + +
          R-00373-55350-22476-46693-17788-34313-52165-34922
          +

          PRAGMA schema.default_cache_size; PRAGMA schema.default_cache_size = Number-of-pages; This pragma queries or sets the suggested maximum number of pages of disk cache that will be allocated per open database file. +(source: pragma.html, checked-by: th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-00376-39212-00900-22873-65373-47922-05493-41094
          +

          If the parent key columns have a UNIQUE index, then that index must use the collation sequences that are specified in the CREATE TABLE statement for the parent table. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-00402-11496-45496-40393-08263-15231-62727-28991
          +

          The filename argument can be a URI filename if URI filename processing is enable on the database connection. +(source: lang_attach.html, checked-by: th3/cov1/sharedcache03.test, matrix: context, detail)

          + +
          R-00404-17670-59562-50305-44521-33242-04500-48832
          +

          For the purposes of UNIQUE constraints, NULL values are considered distinct from all other values, including other NULLs. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-00421-53597-33844-16365-55873-40811-64785-22587
          +

          The sqlite3_get_table() function evaluates one or more semicolon-separated SQL statements in the zero-terminated UTF-8 string of its 2nd parameter and returns a result table to the pointer given in its 3rd parameter. +(source: c3ref/free_table.html, checked-by: th3/req1/gettable01.test, matrix: context, detail)

          + +
          R-00442-36377-32354-02929-33916-13547-05175-00922
          +

          The number of extra bytes needed by the page header can be determined using SQLITE_CONFIG_PCACHE_HDRSZ. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/main42.test, matrix: context, detail)

          + +
          R-00449-33772-33919-59402-60829-28733-22208-04727
          +

          This feature allows WAL databases to be created, read, and written by legacy VFSes that lack the "version 2" shared-memory methods xShmMap, xShmLock, xShmBarrier, and xShmUnmap on the sqlite3_io_methods object. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-00466-56349-41436-38164-40851-28282-49107-17370
          +

          In any aggregate function that takes a single argument, that argument can be preceded by the keyword DISTINCT. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-00471-55166-06832-40836-07519-56638-61190-55255
          +

          The second column is the rowid of the row that contains the invalid REFERENCES clause, or NULL if the child table is a WITHOUT ROWID table. +(source: pragma.html, checked-by: tcl/fkey5.test, th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-00576-15510-24475-53838-43505-45493-44918-44548
          +

          Statistics gathered by ANALYZE are not automatically updated as the content of the database changes. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-00585-12080-59090-20988-60325-52895-60624-38188
          +

          The sqlite3_str_finish(X) interface may return a NULL pointer if any errors were encountered during construction of the string. +(source: c3ref/str_finish.html, matrix: context, detail)

          + +
          R-00598-03741-13790-05735-40657-11548-64969-46486
          +

          A negative LIMIT value is interpreted as "no limit". +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-00605-14249-27716-38234-38428-32294-04406-05104
          +

          Note that column must be the same column in every OR-connected subterm, although the column can occur on either the left or the right side of the = operator. +(source: optoverview.html, matrix: context, detail)

          + +
          R-00634-08585-41820-07623-11518-51863-15995-51786
          +

          If a schema name is specified as part of an object reference, it must be either "main", or "temp" or the schema-name of an attached database. +(source: lang_naming.html, checked-by: tcl/e_resolve.test, matrix: context, detail)

          + +
          R-00640-12624-18808-26941-05585-54150-12700-55718
          +

          The expression "x BETWEEN y and z" is logically equivalent to two comparisons "x >= y AND x <= z" and works with respect to collating functions as if it were two separate comparisons. +(source: datatype3.html, checked-by: th3/req1/datatype3_10.test, matrix: context, detail)

          + +
          R-00653-06026-13288-58570-29830-10892-52076-06124
          +

          If parameter zDb is NULL or points to a zero length string, then the specified operation is attempted on all WAL databases attached to database connection db. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-00693-36727-57706-32123-30185-00000-05163-54607
          +

          The legacy xGeom callback is invoked with four arguments. +(source: rtree.html, matrix: context, detail)

          + +
          R-00695-31519-05206-48434-15068-58741-03264-34333
          +

          The COMMIT command may be used to release all savepoints and commit the transaction even if the transaction was originally started by a SAVEPOINT command instead of a BEGIN command. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-00717-60341-45862-31619-05346-22343-41612-42650
          +

          Ptrmap pages must exist in any database file which has a non-zero largest root b-tree page value at offset 52 in the database header. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-00752-43975-33209-32622-59517-55856-49839-03222
          +

          The sqlite3_wal_hook() function is used to register a callback that is invoked each time data is committed to a database in wal mode. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-00767-44770-16975-15707-27043-13440-51014-32740
          +

          Compute the number of days since the signing of the US Declaration of Independence. SELECT julianday('now') - julianday('1776-07-04'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-00796-21362-00586-19798-41446-05404-46596-57988
          +

          Assuming there are no other indexes, the query above would result in a full table scan. +(source: optoverview.html, matrix: context, detail)

          + +
          R-00811-45908-10631-64940-22455-40948-51133-47487
          +

          If the xCompare argument is NULL then the collating function is deleted. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-00862-05326-51946-26490-09320-50697-05494-49603
          +

          If neither argument to nullif() defines a collating function then the BINARY is used. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-00888-53115-42960-22822-38463-42827-06390-25797
          +

          The prefix option must be set to a comma separated list of positive non-zero integers. +(source: fts3.html, matrix: context, detail)

          + +
          R-00896-24328-65526-17085-61980-08171-20681-33021
          +

          The SQLITE_CONFIG_PAGECACHE option specifies a memory pool that SQLite can use for the database page cache with the default page cache implementation. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/main42.test, matrix: context, detail)

          + +
          R-00918-16997-33541-06619-01421-44106-53820-17907
          +

          For each value N in the list, prefixes of length N bytes (when encoded using UTF-8) are indexed. +(source: fts3.html, matrix: context, detail)

          + +
          R-00971-36933-64386-25480-59601-44057-12316-57384
          +

          These routines return 1 if the input string appears to be a complete SQL statement. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-01060-48788-51013-07543-20121-01838-30879-37400
          +

          The foreign key for table child5 is an error because even though the parent key column has a unique index, the index uses a different collating sequence. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-01080-23340-38639-20728-26521-10375-12428-21631
          +

          With the legacy interface, a more specific error code (for example, SQLITE_INTERRUPT, SQLITE_SCHEMA, SQLITE_CORRUPT, and so forth) can be obtained by calling sqlite3_reset() on the prepared statement. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-01099-23153-64353-38789-60475-21260-04733-65290
          +

          The values returned by sqlite3_memory_used() and sqlite3_memory_highwater() include any overhead added by SQLite in its implementation of sqlite3_malloc(), but not overhead added by the any underlying system library routines that sqlite3_malloc() may call. +(source: c3ref/memory_highwater.html, matrix: context, detail)

          + +
          R-01209-64669-42495-37683-53345-29915-56024-34849
          +

          Each component query of a compound query (UNION, UNION ALL, EXCEPT or INTERSECT) is assigned computed separately and is given its own line in the EXPLAIN QUERY PLAN output. +(source: eqp.html, matrix: context, detail)

          + +
          R-01210-33705-17929-40552-10240-19673-31617-63915
          +

          The sqlite3_result_zeroblob(C,N) and sqlite3_result_zeroblob64(C,N) interfaces set the result of the application-defined function to be a BLOB containing all zero bytes and N bytes in size. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-01232-54838-06099-51737-48729-53565-23196-29255
          +

          It is usually an error to attempt to create a new table in a database that already contains a table, index or view of the same name. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-01244-21922-18443-41581-31463-56152-20699-08111
          +

          If X is a NULL pointer then sqlite3_msize(X) returns zero. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-01255-31602-49480-12710-05718-10731-47284-31520
          +

          The second form (with a numeric argument) sets the limit for the specified database, or for all databases if the optional database name is omitted. +(source: pragma.html, matrix: context, detail)

          + +
          R-01256-01950-44319-11761-57126-19053-46711-18121
          +

          If neither ALL or DISTINCT are present, then the behavior is as if ALL were specified. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-01265-50598-22943-30233-54647-62239-07339-33462
          +

          The result of load_extension() is always a NULL. +(source: lang_corefunc.html, checked-by: th3/cov1/func03.test, matrix: context, detail)

          + +
          R-01277-06213-42474-53306-49270-01327-38555-55249
          +

          This function sets the database handle error code and message. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-01283-11636-17384-60742-28077-41928-22950-29282
          +

          The unlikely(X) function is short-hand for likelihood(X,0.0625). +(source: lang_corefunc.html, checked-by: src/resolve.c, matrix: context, detail)

          + +
          R-01298-38284-36243-26684-29926-32770-62313-39537
          +

          The sqlite_source_id() function returns a string that identifies the specific version of the source code that was used to build the SQLite library. +(source: lang_corefunc.html, checked-by: th3/req1/func04.test, matrix: context, detail)

          + +
          R-01364-08748-27865-47497-61554-10289-43301-18311
          +

          The RETURNING clause is not available on DELETE and UPDATE statements against virtual tables. +(source: lang_returning.html, checked-by: th3/cov1/returning06.test, matrix: context, detail)

          + +
          R-01365-26226-58886-08210-39128-53586-42636-52900
          +

          When a new database is created, SQLite assigns a page size to the database based on platform and filesystem. +(source: pragma.html, matrix: context, detail)

          + +
          R-01379-47306-55874-35809-24668-39985-05961-47226
          +

          Before any information-bearing page of the database is modified, the original unmodified content of that page is written into the rollback journal. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-01386-30047-33139-62500-59847-53855-15241-35634
          +

          The first argument to the trace callback is one of the following constants. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-01391-64022-44610-46114-55308-14246-64441-26910
          +

          The "sz=NNN" argument (where NNN represents a sequence of 1 or more digits) means that the average row size over all records of the table or index is NNN bytes per row. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-01402-03601-05785-14929-05185-63336-09442-11982
          +

          If the statement that caused the trigger program to execute is itself part of a trigger program, then that trigger program resumes execution at the beginning of the next step. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-01418-51310-13172-45959-27772-51956-15619-12685
          +

          However, only "rowid" works as the keyword in the CREATE TABLE statement. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-01448-06859-29804-04457-45951-59563-33373-60665
          +

          When xSavepoint(X,N) is invoked, that is a signal to the virtual table X that it should save its current state as savepoint N. +(source: vtab.html, matrix: context, detail)

          + +
          R-01450-11152-28406-58151-44531-37891-10618-14069
          +

          As the components of a compound SELECT must be simple SELECT statements, they may not contain ORDER BY or LIMIT clauses. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-01458-26582-43530-33153-47185-57731-56963-27513
          +

          The length returned by sqlite3_str_length(X) does not include the zero-termination byte. +(source: c3ref/str_errcode.html, matrix: context, detail)

          + +
          R-01461-33534-36548-25495-56547-17079-32518-24565
          +

          The sqlite_stat4.sample BLOB for the WITHOUT ROWID table itself contains just the columns of the primary key. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-01463-03846-55774-41515-18498-48278-35486-16549
          +

          The DROP TABLE statement removes a table added with the CREATE TABLE statement. +(source: lang_droptable.html, matrix: context, detail)

          + +
          R-01470-60482-32731-19597-04026-47136-19531-00133
          +

          The sqlite3_value_type(V) interface returns the datatype code for the initial datatype of the sqlite3_value object V. The returned value is one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. +(source: c3ref/value_blob.html, checked-by: src/func.c, matrix: context, detail)

          + +
          R-01506-11053-32502-45139-47336-58914-04836-35356
          +

          The first integer on a freelist trunk page is the page number of the next freelist trunk page in the list or zero if this is the last freelist trunk page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-01515-49025-64718-16819-52124-40826-60868-48014
          +

          The column appears in a trigger or view. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-01531-37780-56063-13317-41294-63476-04645-64168
          +

          If certain kinds of errors occur within a transaction, the transaction may or may not be rolled back automatically. The errors that can cause an automatic rollback include: SQLITE_FULL: database or disk full SQLITE_IOERR: disk I/O error SQLITE_BUSY: database in use by another process SQLITE_NOMEM: out of memory +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-01544-29257-62595-06861-33076-18858-48075-56444
          +

          Note that max() is a simple function when it has 2 or more arguments but operates as an aggregate function if given only a single argument. +(source: lang_corefunc.html, checked-by: th3/req1/func05.test, matrix: context, detail)

          + +
          R-01587-15367-52926-43879-39292-01582-45706-36467
          +

          xUnpin() is called by SQLite with a pointer to a currently pinned page as its second argument. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-01592-27714-26694-24809-12949-19667-58343-14650
          +

          When the EXPLAIN QUERY PLAN phrase appears, the statement returns high-level information regarding the query plan that would have been used. +(source: lang_explain.html, checked-by: th3/cov1/vdbeaux01.test, matrix: context, detail)

          + +
          R-01612-30877-07572-17003-08953-37118-55537-45996
          +

          The "vfs" parameter may be used to specify the name of a VFS object that provides the operating system interface that should be used to access the database file on disk. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-01646-09830-46955-17168-41197-07539-61822-63814
          +

          The schema of the sqlite_stat3 table is as follows: CREATE TABLE sqlite_stat3(tbl,idx,nEq,nLt,nDLt,sample); +(source: fileformat2.html, matrix: context, detail)

          + +
          R-01665-16529-46232-20487-31256-22068-50948-28475
          +

          The sqlite_stat4.nDLt column holds a list of N integers where the K-th integer is the approximate number of entries in the index that are distinct in the first K columns and where the left-most K columns are collectively less than the left-most K columns of the sample. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-01669-33464-29023-56990-09830-45167-30109-01082
          +

          When enabled, this PRAGMA causes many SELECT statements without an ORDER BY clause to emit their results in the reverse order from what they normally would. +(source: pragma.html, checked-by: th3/req1/pragma27.test, matrix: context, detail)

          + +
          R-01707-21292-14865-10862-25623-35625-38879-45651
          +

          It is safe to call this routine from a thread different from the thread that is currently running the database operation. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-01724-22761-13278-31858-02106-19568-34768-00701
          +

          If the sub-query is a compound select, then it must not use an ORDER BY clause. +(source: optoverview.html, matrix: context, detail)

          + +
          R-01750-40559-52065-12470-48383-41757-44468-25443
          +

          SQLite always opens immutable database files read-only and it skips all file locking and change detection on immutable database files. +(source: uri.html, matrix: context, detail)

          + +
          R-01766-15387-49282-35089-26578-35550-62519-17422
          +

          The third argument is the value to bind to the parameter. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-01766-56079-01675-00227-41454-02515-08725-53568
          +

          These functions return information about the Nth result column returned by the statement, where N is the second function argument. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-01849-26079-03122-24665-29509-65417-11059-24465
          +

          Value is a big-endian 32-bit twos-complement integer. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-01862-45642-20021-42706-06373-08124-48431-44069
          +

          SQLite automatically frees the memory allocated by sqlite3_aggregate_context() when the aggregate query concludes. +(source: c3ref/aggregate_context.html, checked-by: th3/req1/aggcntx01.test, matrix: context, detail)

          + +
          R-01921-64245-04718-64212-38644-45300-05525-61121
          +

          When the right operand of an IN or NOT IN operator is a subquery, the subquery must have the same number of columns as there are columns in the row value of the left operand. +(source: lang_expr.html, checked-by: th3/cov1/rowvalue06.test, matrix: context, detail)

          + +
          R-01992-00519-59560-42589-34051-44285-27634-29157
          +

          Abs(X) returns 0.0 if X is a string or blob that cannot be converted to a numeric value. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/func01.test, matrix: context, detail)

          + +
          R-02005-53466-64191-45009-56070-04146-49679-01840
          +

          This option is used to enable or disable triggers. +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/cov1/main34.test, matrix: context, detail)

          + +
          R-02015-59187-11904-53173-61515-49878-56843-64871
          +

          An application can force the query planner to reread the statistics tables by running ANALYZE sqlite_schema. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-02045-23762-08268-15190-44661-50351-03152-06188
          +

          This character may be used in the LIKE pattern to include literal percent or underscore characters. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-02054-15343-41665-64514-11380-36685-28202-41617
          +

          For the purposes of detecting duplicate rows, two NULL values are considered to be equal. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-02060-64547-35959-63655-11509-53404-59087-08290
          +

          A NOT NULL constraint may only be attached to a column definition, not specified as a table constraint. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-02063-40503-04157-38005-61496-25541-17209-31219
          +

          The 2nd argument to the sqlite3_exec() callback function is the number of columns in the result. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-02066-39846-49596-48067-57975-02968-06614-12287
          +

          CREATE TABLE t0( a INTEGER PRIMARY KEY, b DATE DEFAULT CURRENT_TIMESTAMP, c INTEGER ); INSERT INTO t0(c) VALUES(random()) RETURNING *; In the INSERT statement above, SQLite computes the values for all three columns. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-02136-28803-61484-06431-31373-63795-12521-56561
          +

          The SQLITE_CONFIG_PMASZ option takes a single parameter which is an unsigned integer and sets the "Minimum PMA Size" for the multithreaded sorter to that integer. +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-02204-63196-34665-25585-57735-42246-07132-57008
          +

          The net effect is that putting the ON or USING clause expressions for a LEFT JOIN in the WHERE clause effectively converts the query to an ordinary INNER JOIN - albeit an inner join that runs more slowly. +(source: optoverview.html, matrix: context, detail)

          + +
          R-02216-00820-33390-20327-19071-10430-39697-32412
          +

          The argument X in sqlite3_file_control(db,SQLITE_FCNTL_VFS_POINTER,X) must be of type "sqlite3_vfs **". This opcodes will set *X to a pointer to the top-level VFS. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-02223-49279-19512-29951-11875-18036-12006-07318
          +

          Subject to filtering associated with the DISTINCT keyword, the number of rows returned by an aggregate query with a GROUP BY clause is the same as the number of groups of rows produced by applying the GROUP BY and HAVING clauses to the filtered input dataset. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-02230-09674-61561-02587-07108-44631-60022-03374
          +

          The heap limits are not enforced in the current implementation if one or more of following conditions are true: The limit value is set to zero. Memory accounting is disabled using a combination of the sqlite3_config(SQLITE_CONFIG_MEMSTATUS,...) start-time option and the SQLITE_DEFAULT_MEMSTATUS compile-time option. An alternative page cache implementation is specified using sqlite3_config(SQLITE_CONFIG_PCACHE2,...). The page cache allocates from its own memory pool supplied by sqlite3_config(SQLITE_CONFIG_PAGECACHE,...) rather than from the heap. +(source: c3ref/hard_heap_limit64.html, checked-by: th3/req1/softheaplimit02.test, matrix: context, detail)

          + +
          R-02320-27410-64858-02729-11929-10797-55740-08223
          +

          Thus for the example index above, if there is no WHERE clause term that constrains column c, then terms that constrain columns a and b can be used with the index but not terms that constrain columns d through z. +(source: optoverview.html, matrix: context, detail)

          + +
          R-02336-39303-27290-23991-25845-02494-13210-07983
          +

          The value returned is one of SQLITE_ROLLBACK, SQLITE_IGNORE, SQLITE_FAIL, SQLITE_ABORT, or SQLITE_REPLACE, according to the ON CONFLICT mode of the SQL statement that triggered the call to the xUpdate method of the virtual table. +(source: c3ref/vtab_on_conflict.html, matrix: context, detail)

          + +
          R-02347-27622-26500-11854-22896-16033-00883-33051
          +

          The %n format is silently ignored and does not consume an argument. +(source: lang_corefunc.html, checked-by: tcl/printf2.test, th3/cov1/printf08.test, matrix: context, detail)

          + +
          R-02348-55344-32378-57138-47141-59055-59036-53991
          +

          If the most recent sqlite3_* API call associated with database connection D failed, then the sqlite3_errcode(D) interface returns the numeric result code or extended result code for that API call. +(source: c3ref/errcode.html, matrix: context, detail)

          + +
          R-02355-51069-10404-51667-09139-26886-58872-12048
          +

          The sqlite3_initialize() routine initializes the SQLite library. +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-02402-03425-02840-42627-65060-52098-37241-46689
          +

          SQLite has three built-in collating functions: BINARY, NOCASE, and RTRIM. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-02424-24769-08747-39368-55205-12781-22154-40957
          +

          The second argument is the number of coordinates in each r-tree entry, and is always the same for any given R*Tree. +(source: rtree.html, matrix: context, detail)

          + +
          R-02445-31643-12462-38565-43200-47259-24553-56004
          +

          The first two constants (SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) cause sqlite3_mutex_alloc() to create a new mutex. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-02452-55255-23051-52258-05350-24145-51359-57873
          +

          This in-memory database will vanish when the database connection is closed. +(source: c3ref/open.html, checked-by: th3/cov1/sharedcache03.test, matrix: context, detail)

          + +
          R-02509-11239-04635-35453-11761-20226-62835-31660
          +

          sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c; QUERY PLAN |--SCAN TABLE t2 `--USE TEMP B-TREE FOR ORDER BY +(source: eqp.html, matrix: context, detail)

          + +
          R-02526-60953-53079-20441-57017-47857-19506-30877
          +

          Formats 8 through 10 that specify only a time assume a date of 2000-01-01. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-02535-05811-23269-15824-03293-63258-54375-28501
          +

          One can explicitly change out of WAL mode using a pragma such as this: PRAGMA journal_mode=DELETE; +(source: wal.html, checked-by: tcl/e_wal.test, matrix: context, detail)

          + +
          R-02545-26933-18999-48013-24665-54880-01582-10256
          +

          PRAGMA stats; +(source: pragma.html, checked-by: th3/cov1/index02.test, matrix: context, detail)

          + +
          R-02552-35840-06241-57542-28930-20966-35259-36291
          +

          If the filename is an empty string, then a private, temporary on-disk database will be created. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-02559-29055-33962-47817-36688-50556-57969-25403
          +

          The built-in functions used to implement LIKE and GLOB must not have been overloaded using the sqlite3_create_function() API. +(source: optoverview.html, matrix: context, detail)

          + +
          R-02597-60207-27800-53923-18122-14559-36270-03523
          +

          This pragma only changes the behavior of the SQL LIKE operator. It does not change the behavior of the sqlite3_strlike() C-language interface, which is always case insensitive. +(source: pragma.html, matrix: context, detail)

          + +
          R-02603-20369-49628-47923-33871-62989-43083-21610
          +

          The SQLITE_TRACE_SIZE_LIMIT compile-time option limits the size of bound parameter expansions. +(source: c3ref/expanded_sql.html, checked-by: th3/cov1/main16.test, matrix: context, detail)

          + +
          R-02612-37947-62500-41847-13282-34946-09245-20088
          +

          The filename for the database to be attached is the value of the expression that occurs before the AS keyword. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-02644-22131-14285-04703-01059-19073-41336-39895
          +

          In a compound SELECT statement, only the last or right-most simple SELECT may have an ORDER BY clause. +(source: lang_select.html, checked-by: tcl/select4.test, th3/req1/select02.test, matrix: context, detail)

          + +
          R-02653-06118-57159-51555-56170-47267-50367-42791
          +

          Any new SQL statements that are started after the sqlite3_interrupt() call and before the running statement count reaches zero are interrupted as if they had been running prior to the sqlite3_interrupt() call. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-02661-56399-16863-16765-39256-52589-25619-21380
          +

          If the result of the evaluating the LIMIT clause cannot be losslessly converted to an integer value, it is an error. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-02718-64874-37028-59587-06155-35657-39180-35629
          +

          zProc may be 0, in which case SQLite will try to come up with an entry point name on its own. It first tries "sqlite3_extension_init". If that does not work, it constructs a name "sqlite3_X_init" where the X is consists of the lower-case equivalent of all ASCII alphabetic characters in the filename from the last "/" to the first following "." and omitting any initial "lib". +(source: c3ref/load_extension.html, matrix: context, detail)

          + +
          R-02723-34107-58585-29932-59518-10370-60775-12212
          +

          Note that it is not necessary for all coordinates in an R*Tree index to be constrained in order for the index search to be efficient. +(source: rtree.html, matrix: context, detail)

          + +
          R-02748-19096-10502-39344-29556-06426-40271-21454
          +

          This option sets the threading mode to Single-thread. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-02752-50091-50763-13370-06213-52053-61647-05504
          +

          A cast of a REAL value into an INTEGER results in the integer between the REAL value and zero that is closest to the REAL value. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-02753-24748-27922-38844-00567-47453-02164-18624
          +

          A sequence number assigned to each index for internal tracking purposes. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-02754-60157-05684-14835-18385-12207-59168-42343
          +

          The VACUUM INTO command works the same way except that it uses the file named on the INTO clause in place of the temporary database and omits the step of copying the vacuumed database back over top of the original database. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-02776-14802-36986-43055-33540-06058-61102-35501
          +

          The cell pointer array consists of K 2-byte integer offsets to the cell contents. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-02781-38257-61601-52824-21453-60365-23021-11331
          +

          The name of the database or table or column can be returned as either a UTF-8 or UTF-16 string. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-02811-30532-06780-49040-22686-08574-20833-13918
          +

          The multi-argument min() function returns the argument with the minimum value. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, th3/req1/func03.test, matrix: context, detail)

          + +
          R-02823-24537-56381-41482-05439-43543-17760-52541
          +

          All journal headers within the same journal must contain the same database page size and sector size. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-02834-55381-03461-31664-23015-51190-16436-44295
          +

          Compute the date and time given a unix timestamp 1092941466, and compensate for your local timezone. SELECT datetime(1092941466, 'unixepoch', 'localtime'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-02854-44844-25004-52722-20972-43816-38252-26758
          +

          Transactions created using BEGIN...COMMIT do not nest. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-02878-47338-41992-43145-51267-26595-43850-16563
          +

          The sqlite3_str object is created using sqlite3_str_new(). +(source: c3ref/str.html, matrix: context, detail)

          + +
          R-02903-29630-48373-46747-65166-13763-04859-03482
          +

          The sqlite3_drop_modules(D,L) interface removes all virtual table modules from database connection D except those named on list L. +(source: c3ref/drop_modules.html, matrix: context, detail)

          + +
          R-02910-05480-32972-52841-06216-21480-55591-52930
          +

          Each expression may be optionally followed by an AS clause that determines the name of the result column. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-02944-19877-16321-40331-61553-58376-42533-63822
          +

          Common table expression are not supported for statements inside of triggers. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-02961-26666-41829-02507-08304-47031-60058-62132
          +

          A power failure or program crash or OS crash will cause the outer-most transaction to rollback, undoing all changes that have occurred within that outer transaction, even changes that have supposedly been "committed" by the RELEASE command. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-02982-34736-45462-50381-10151-04149-50124-39087
          +

          In order to maintain full backwards compatibility for legacy applications, the URI filename capability is disabled by default. +(source: uri.html, checked-by: src/global.c, matrix: context, detail)

          + +
          R-03014-26414-56458-20281-20451-13984-34730-16215
          +

          If the LIMIT expression evaluates to a negative value, then there is no upper bound on the number of rows returned. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-03038-07451-12722-63160-48218-07085-49019-00340
          +

          The DBSTAT virtual table is available on all database connections when SQLite is built using the SQLITE_ENABLE_DBSTAT_VTAB compile-time option. +(source: dbstat.html, matrix: context, detail)

          + +
          R-03040-34580-06414-61878-61161-08528-60209-55771
          +

          To change auto-vacuum modes, first use the auto_vacuum pragma to set the new desired mode, then invoke the VACUUM command to reorganize the entire database file. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-03042-35027-57621-08562-39860-20110-45272-44124
          +

          In SQLite version 3. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-03108-01565-06076-29544-14093-00699-65398-01477
          +

          If sqlite3_backup_step() cannot obtain a required file-system lock, then the busy-handler function is invoked (if one is specified). +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-03108-55458-13871-22315-35483-39116-29628-08970
          +

          The memory space used to hold strings and BLOBs is freed automatically. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, th3/req1/column02.test, th3/req1/column03.test, matrix: context, detail)

          + +
          R-03108-63659-37525-03634-22905-61973-06931-63842
          +

          The English language error message for foreign key DML errors is usually "foreign key mismatch" but can also be "no such table" if the parent table does not exist. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-03145-46390-59121-11550-39703-00062-43990-26586
          +

          This function closes an open BLOB handle. +(source: c3ref/blob_close.html, checked-by: tcl/e_blobclose.test, matrix: context, detail)

          + +
          R-03149-27046-20268-15208-62882-01338-52068-22067
          +

          The fifth argument to the BLOB and string binding interfaces controls or indicates the lifetime of the object referenced by the third parameter. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-03149-51030-29374-35692-47686-21345-30102-08346
          +

          sqlite> CREATE INDEX i4 ON t2(c); sqlite> EXPLAIN QUERY PLAN SELECT c, d FROM t2 ORDER BY c; QUERY PLAN `--SCAN TABLE t2 USING INDEX i4 +(source: eqp.html, matrix: context, detail)

          + +
          R-03153-32413-63550-60817-44903-54109-55492-28243
          +

          Applications can invoke the SQLITE_FCNTL_TEMPFILENAME file-control to have SQLite generate a temporary filename using the same algorithm that is followed to generate temporary filenames for TEMP tables and other internal uses. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-03172-04369-12643-00191-50851-55287-16649-54683
          +

          The iif(X,Y,Z) function returns the value Y if X is true, and Z otherwise. +(source: lang_corefunc.html, matrix: context, detail)

          + +
          R-03177-38447-54493-08883-15341-37081-39578-45414
          +

          The strings returned by sqlite3_sql(P) and sqlite3_normalized_sql(P) are managed by SQLite and are automatically freed when the prepared statement is finalized. +(source: c3ref/expanded_sql.html, checked-by: th3/req1/sql01.test, matrix: context, detail)

          + +
          R-03189-51135-06714-56467-07556-62916-33702-61870
          +

          As each SQL statement runs, the schema version is checked to ensure that the schema has not changed since the SQL statement was prepared. +(source: pragma.html, checked-by: src/vdbe.c, th3/req1/pragma28.test, matrix: context, detail)

          + +
          R-03236-28327-53832-55698-26984-08951-20811-30621
          +

          The callback function registered by sqlite3_profile() is invoked as each SQL statement finishes. +(source: c3ref/profile.html, checked-by: th3/cov1/main16.test, matrix: context, detail)

          + +
          R-03263-59522-08977-47312-04173-07916-12369-56758
          +

          In formats 4, 7, and 10, the fractional seconds value SS.SSS can have one or more digits following the decimal point. Exactly three digits are shown in the examples because only the first three digits are significant to the result, but the input string can have fewer or more than three digits and the date/time functions will still operate correctly. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-03265-02788-40308-03087-09490-44543-57218-37150
          +

          sqlite> EXPLAIN QUERY PLAN SELECT (SELECT b FROM t1 WHERE a=0), (SELECT a FROM t1 WHERE b=t2.c) FROM t2; |--SCAN TABLE t2 USING COVERING INDEX i4 |--SCALAR SUBQUERY | `--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) `--CORRELATED SCALAR SUBQUERY `--SEARCH TABLE t1 USING INDEX i3 (b=?) +(source: eqp.html, matrix: context, detail)

          + +
          R-03353-05327-21191-28288-58549-30161-65035-16573
          +

          If the configured action is "SET NULL", then when a parent key is deleted (for ON DELETE SET NULL) or modified (for ON UPDATE SET NULL), the child key columns of all rows in the child table that mapped to the parent key are set to contain SQL NULL values. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-03364-08004-01846-16626-35041-21418-01059-33152
          +

          This saves disk I/O but at the expense of database safety and integrity. +(source: pragma.html, checked-by: th3/req1/pragma25.test, matrix: context, detail)

          + +
          R-03366-15091-31390-29880-25655-21575-38320-18449
          +

          A column with affinity BLOB does not prefer one storage class over another and no attempt is made to coerce data from one storage class into another. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-03371-37637-45197-41040-02325-30195-01599-52807
          +

          A value of 2 means UTF-16le. +(source: fileformat2.html, checked-by: th3/req1/fileformat03.test, matrix: context, detail)

          + +
          R-03384-16988-56342-27113-15582-23905-61625-46605
          +

          If the 4th parameter to the sqlite3_result_text* interfaces or sqlite3_result_blob is a non-NULL pointer, then SQLite calls that function as the destructor on the text or BLOB result when it has finished using that result. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-03387-12896-30110-08033-64260-38467-31820-29841
          +

          For a trigger, the tbl_name column stores the name of the table or view that causes the trigger to fire. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-03407-11483-10764-04340-16731-05555-54147-57723
          +

          Each term of the ORDER BY clause is processed separately and may be matched against result columns from different SELECT statements in the compound. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-03407-34626-50961-58560-51866-04262-39023-12943
          +

          If P<=X then all P bytes of payload are stored directly on the btree page without overflow. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-03415-51114-16877-13927-48292-50475-12409-45422
          +

          This routine returns SQLITE_OK if shared cache was enabled or disabled successfully. An error code is returned otherwise. +(source: c3ref/enable_shared_cache.html, matrix: context, detail)

          + +
          R-03421-22330-15487-45434-55764-30375-36326-03914
          +

          The REPLACE command is an alias for the "INSERT OR REPLACE" variant of the INSERT command. +(source: lang_replace.html, checked-by: tcl/e_insert.test, th3/req1/replace01.test, matrix: context, detail)

          + +
          R-03421-57988-17823-20871-36963-31591-05991-31026
          +

          If the SELECT statement is a simple SELECT, then an ORDER BY may contain any arbitrary expressions. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-03473-60719-23522-47619-30011-51175-32203-58759
          +

          In an ordinary rowid table, the index entry always ends with the rowid even if the INTEGER PRIMARY KEY column is one of the columns being indexed. +(source: fileformat2.html, checked-by: th3/req1/fileformat04.test, matrix: context, detail)

          + +
          R-03478-24050-02080-63717-24763-14107-62865-40248
          +

          Application code can delete all entries from the sqlite_sequence table, but application code cannot drop the sqlite_sequence table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-03511-33422-55072-31663-17873-23476-48339-34907
          +

          If this function needs to obtain extra database locks before dirty pages can be flushed to disk, it does so. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-03529-13145-61172-45991-35853-35097-63918-09520
          +

          Each new VFS becomes the default VFS if the makeDflt flag is set. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-03587-06098-24294-21557-27164-26781-18390-63915
          +

          The sqlite3.h header file defines C-preprocessor macros SQLITE_UTF8 as 1, SQLITE_UTF16LE as 2, and SQLITE_UTF16BE as 3, to use in place of the numeric codes for the text encoding. +(source: fileformat2.html, checked-by: th3/cov1/main01.test, matrix: context, detail)

          + +
          R-03595-19994-17649-33748-29680-14364-48502-36562
          +

          The sign(X) function returns -1, 0, or +1 if the argument X is a numeric value that is negative, zero, or positive, respectively. +(source: lang_corefunc.html, matrix: context, detail)

          + +
          R-03642-28175-07234-22849-20831-22837-60337-13680
          +

          For the index above and WHERE clause like this: ... WHERE a=5 AND b IN (1,2,3) AND c IS NULL AND d='hello' The first four columns a, b, c, and d of the index would be usable since those four columns form a prefix of the index and are all bound by equality constraints. +(source: optoverview.html, matrix: context, detail)

          + +
          R-03650-18079-61121-63570-57348-35510-07530-48237
          +

          The languageid option causes the FTS4 table to have an additional hidden integer column that identifies the language of the text contained in each row. +(source: fts3.html, matrix: context, detail)

          + +
          R-03668-38040-63384-47924-51655-15922-38013-57392
          +

          SQLITE_DBSTATUS_CACHE_USED_SHARED This parameter is similar to DBSTATUS_CACHE_USED, except that if a pager cache is shared between two or more connections the bytes of heap memory used by that pager cache is divided evenly between the attached connections. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-03669-30599-21217-06896-17769-44438-31618-26741
          +

          The SQLITE_CONFIG_LOOKASIDE option takes two arguments that determine the default size of lookaside memory on each database connection. The first argument is the size of each lookaside buffer slot and the second is the number of slots allocated to each database connection. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/th3main.c, matrix: context, detail)

          + +
          R-03679-60639-59233-10900-40024-64867-37353-18498
          +

          Equals can be either = or ==. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-03718-56652-35720-52480-53179-27141-13621-15908
          +

          The database name is "main" for the main database, "temp" for the temporary database, or the name specified after the AS keyword in an ATTACH statement for an attached database. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-03733-29734-34954-23072-53116-42399-24178-53918
          +

          Rowid values may be modified using an UPDATE statement in the same way as any other column value can, either using one of the built-in aliases ("rowid", "oid" or "_rowid_") or by using an alias created by an integer primary key. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-03763-21608-02614-21475-13242-45742-42220-44388
          +

          In the legacy interface, the return value will be either SQLITE_BUSY, SQLITE_DONE, SQLITE_ROW, SQLITE_ERROR, or SQLITE_MISUSE. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-03774-63970-49348-18096-09598-62977-03168-07384
          +

          If an element of a result row is NULL then the corresponding string pointer for the sqlite3_exec() callback is a NULL pointer. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-03775-43471-64071-42182-04548-19220-35511-30117
          +

          For CURRENT_DATE, "YYYY-MM-DD". +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-03782-50113-07889-61345-45931-21509-48774-40990
          +

          In a compound SELECT, the LIMIT clause applies to the entire compound, not just the final SELECT. +(source: lang_select.html, checked-by: tcl/limit.test, th3/req1/select02.test, matrix: context, detail)

          + +
          R-03793-19254-25835-35208-42396-01402-31770-31653
          +

          If you ever delete rows or if you ever create a row with the maximum possible ROWID, then ROWIDs from previously deleted rows might be reused when creating new rows and newly created ROWIDs might not be in strictly ascending order. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-03805-18240-25396-23037-09576-28411-40508-44417
          +

          This private database will be automatically deleted as soon as the database connection is closed. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-03816-21626-17112-32643-57381-58430-16315-21594
          +

          When running in shared-cache mode, a database operation may fail with an SQLITE_LOCKED error if the required locks on the shared-cache or individual tables within the shared-cache cannot be obtained. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-03849-24470-04387-57438-43164-31085-17053-62847
          +

          The sqlite3_bind_pointer(S,I,P,T,D) routine causes the I-th parameter in prepared statement S to have an SQL value of NULL, but to also be associated with the pointer P of type T. +(source: c3ref/bind_blob.html, checked-by: th3/cov1/carray01.test, matrix: context, detail)

          + +
          R-03880-38961-16553-20098-36513-53865-60133-40229
          +

          If the input text contains no SQL (if the input is an empty string or a comment) then *ppStmt is set to NULL. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-03887-49864-52885-52230-12031-59959-26031-40096
          +

          If the PRIMARY KEY of a WITHOUT ROWID tables uses the same columns with the same collating sequence more than once, then the second and subsequent occurrences of that column in the PRIMARY KEY definition are ignored. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-03895-01427-35147-59695-24656-05504-11276-13521
          +

          SELECT objname FROM demo_index2 WHERE contained_in(boundary, :boundary) AND minX>=-81.0 AND maxX<=-79.6 AND minY>=35.0 AND maxY>=36.2; +(source: rtree.html, matrix: context, detail)

          + +
          R-03922-41160-10406-40879-23599-49045-53405-25401
          +

          If the flags parameter is zero, the BLOB is opened for read-only access. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-03934-63400-35021-15759-28695-34964-02248-59433
          +

          However, changing from "none" to "full" or "incremental" can only occur when the database is new (no tables have yet been created) or by running the VACUUM command. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-03993-24285-31190-14311-07438-62351-52230-47181
          +

          Only a single authorizer can be in place on a database connection at a time. Each call to sqlite3_set_authorizer overrides the previous call. +(source: c3ref/set_authorizer.html, checked-by: tcl/auth.test, th3/cov1/auth01.test, matrix: context, detail)

          + +
          R-03996-12088-12971-06129-31814-44621-38881-57299
          +

          The M parameter must be a valid checkpoint mode: +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/main.c, tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-04005-08111-39731-15170-36576-49560-64443-15597
          +

          SAVEPOINTs are a method of creating transactions, similar to BEGIN and COMMIT, except that the SAVEPOINT and RELEASE commands are named and may be nested. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-04042-24825-64259-53667-46708-22366-11905-57675
          +

          To do so, a foreign key definition may be added by modifying the declaration of the track table to the following: CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER, FOREIGN KEY(trackartist) REFERENCES artist(artistid) ); +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys01.test, matrix: context, detail)

          + +
          R-04132-09474-00805-46196-04402-30131-02139-26149
          +

          If the HAVING clause is an aggregate expression, it is evaluated across all rows in the group. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-04136-04681-09628-27696-46047-23040-33903-21102
          +

          If no collating function is explicitly defined, then the collating function defaults to BINARY. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-04156-06964-57164-01636-33935-16787-30855-09296
          +

          A call to sqlite3_interrupt(D) that occurs when there are no running SQL statements is a no-op and has no effect on SQL statements that are started after the sqlite3_interrupt() call returns. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-04196-57626-61591-44020-20208-08318-09157-59065
          +

          One can add a VIRTUAL column, however. +(source: gencol.html, matrix: context, detail)

          + +
          R-04207-37981-22726-45777-39517-24105-18228-28404
          +

          To cast a BLOB value to TEXT, the sequence of bytes that make up the BLOB is interpreted as text encoded using the database encoding. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-04230-65027-27281-23522-50954-57493-39965-31436
          +

          This statement detaches an additional database connection previously attached using the ATTACH statement. +(source: lang_detach.html, matrix: context, detail)

          + +
          R-04232-24861-40917-13992-27645-07811-63353-60101
          +

          Collation names that compare equal according to sqlite3_strnicmp() are considered to be the same name. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-04239-05140-34509-16246-41712-61041-39161-05924
          +

          The sqlite3_close() and sqlite3_close_v2() routines are destructors for the sqlite3 object. +(source: c3ref/close.html, checked-by: th3/th3util.c, matrix: context, detail)

          + +
          R-04239-46396-01814-35437-09500-15330-29656-29388
          +

          A single zero-byte separates the xOpen filename argument from the key of the first query parameters, each key and value, and each subsequent key from the prior value. +(source: uri.html, matrix: context, detail)

          + +
          R-04240-13860-65376-64948-20761-30630-14399-44960
          +

          When comparing values, if the parent key column has an affinity, then that affinity is applied to the child key value before the comparison is performed. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys03.test, matrix: context, detail)

          + +
          R-04272-38653-14303-01704-38451-58113-36784-29823
          +

          The "RESTRICT" action means that the application is prohibited from deleting (for ON DELETE RESTRICT) or modifying (for ON UPDATE RESTRICT) a parent key when there exists one or more child keys mapped to it. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-04300-56712-32659-65159-49842-27130-29205-32160
          +

          If the X parameter to sqlite3_realloc(X,N) is a NULL pointer then its behavior is identical to calling sqlite3_malloc(N). +(source: c3ref/free.html, checked-by: src/malloc.c, th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-04304-33529-02265-14363-24121-34151-06311-12119
          +

          The first parameter "n" is the total size of the buffer, including space for the zero terminator. +(source: c3ref/mprintf.html, checked-by: th3/req1/malloc01.test, matrix: context, detail)

          + +
          R-04382-46598-05125-45584-30241-41466-16094-28747
          +

          The text in the sqlite_schema.sql column is a copy of the original CREATE statement text that created the object, except normalized as described above and as modified by subsequent ALTER TABLE statements. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-04452-49349-54233-41206-52506-27116-05869-21475
          +

          When the callback returns SQLITE_DENY, the sqlite3_prepare_v2() or equivalent call that triggered the authorizer will fail with an error message explaining that access is denied. +(source: c3ref/set_authorizer.html, checked-by: tcl/auth.test, th3/cov1/auth01.test, matrix: context, detail)

          + +
          R-04460-38575-52121-32050-22893-58240-13310-33499
          +

          If the subquery is the right operand of a LEFT JOIN then the subquery may not be a join, and the FROM clause of the subquery may not contain a virtual table, and the outer query may not be an aggregate. +(source: optoverview.html, matrix: context, detail)

          + +
          R-04460-53386-37328-50072-27408-53032-10915-39219
          +

          The third argument is the number of slots. +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-04465-11976-19179-54741-15399-04029-28816-38507
          +

          The built-in iif(x,y,z) SQL function is logically equivalent to "CASE WHEN x THEN y ELSE z END". +(source: lang_expr.html, matrix: context, detail)

          + +
          R-04486-07266-01902-48649-32493-31514-19208-51625
          +

          Or, if the dataset contains zero rows, then each non-aggregate expression is evaluated against a row consisting entirely of NULL values. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-04532-11527-60293-16788-37808-59040-51319-08926
          +

          The LIKE operator is case sensitive by default for unicode characters that are beyond the ASCII range. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-04549-59621-55549-18042-51558-13572-61866-18080
          +

          Tables in an attached database can be referred to using the syntax schema-name.table-name. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-04558-24451-40018-59769-17015-19792-37809-52993
          +

          In this case all scalar expressions are evaluated before any assignments are made. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-04591-34196-50064-55566-45109-16204-13417-11786
          +

          If V is a NULL pointer then sqlite3_value_free(V) is a harmless no-op. +(source: c3ref/value_dup.html, matrix: context, detail)

          + +
          R-04670-35394-33055-58940-18775-32578-18606-16346
          +

          The schema of the sqlite_stat4 table is as follows: CREATE TABLE sqlite_stat4(tbl,idx,nEq,nLt,nDLt,sample); +(source: fileformat2.html, matrix: context, detail)

          + +
          R-04709-28430-14842-03600-36278-03324-37525-06420
          +

          The two syntaxes yield identical results. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-04780-55815-53305-18116-10339-17181-34629-39653
          +

          The SQLITE_CONFIG_WIN32_HEAPSIZE option is only available if SQLite is compiled for Windows with the SQLITE_WIN32_MALLOC pre-processor macro defined. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-04813-30632-36613-23233-44977-18945-21013-25400
          +

          Any number of levels of indirection are allowed. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-04813-32302-43211-64289-53860-58512-13652-55013
          +

          If a ROLLBACK operation occurs on the same database connection as a pending read or write, then the pending read or write may fail with an SQLITE_ABORT or SQLITE_ABORT_ROLLBACK error. +(source: rescode.html, checked-by: th3/cov1/vdbe14.test, matrix: context, detail)

          + +
          R-04857-57605-48133-44150-30535-05379-36560-24650
          +

          An attempt to change the journal_mode of an in-memory database to any setting other than MEMORY or OFF is ignored. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-04864-61029-16829-56446-03389-34714-38812-10063
          +

          Information about the ORDER BY clause is stored in aOrderBy[]. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-04905-26881-40783-35987-17174-16580-39842-61729
          +

          SQLite uses dynamic run-time typing. +(source: c3ref/column_decltype.html, matrix: context, detail)

          + +
          R-04922-24076-20312-31472-33218-43152-59920-55175
          +

          The sqlite_compileoption_get() SQL function is a wrapper around the sqlite3_compileoption_get() C/C++ function. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/ctime02.test, matrix: context, detail)

          + +
          R-04929-09147-56295-64072-16041-07476-46206-21781
          +

          This routine returns false if there is any possibility that the statement might change the database file. +(source: c3ref/stmt_readonly.html, matrix: context, detail)

          + +
          R-04932-55942-18064-33744-52944-17414-47744-37595
          +

          If the NATURAL keyword is in the join-operator then an implicit USING clause is added to the join-constraints. The implicit USING clause contains each of the column names that appear in both the left and right-hand input datasets. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-04945-22784-17023-15023-27622-31516-40757-39566
          +

          For example, if a prepared statement is created using the SQL text "SELECT $abc,:xyz" and if parameter $abc is bound to integer 2345 and parameter :xyz is unbound, then sqlite3_sql() will return the original string, "SELECT $abc,:xyz" but sqlite3_expanded_sql() will return "SELECT 2345,NULL". +(source: c3ref/expanded_sql.html, checked-by: th3/req1/sql01.test, matrix: context, detail)

          + +
          R-04950-25529-49153-37444-18478-06220-49910-01329
          +

          Once removed, the trigger definition is no longer present in the sqlite_schema (or sqlite_temp_schema) table and is not fired by any subsequent INSERT, UPDATE or DELETE statements. +(source: lang_droptrigger.html, checked-by: tcl/e_droptrigger.test, matrix: context, detail)

          + +
          R-04965-15290-07639-47076-03173-25539-55321-39216
          +

          If two or more COLLATE operator subexpressions appear anywhere in a comparison, the left most explicit collating function is used regardless of how deeply the COLLATE operators are nested in the expression and regardless of how the expression is parenthesized. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-04966-20924-22801-44909-48927-53251-60616-56610
          +

          The returned string pointer is valid until either the prepared statement is destroyed by sqlite3_finalize() or until the statement is automatically reprepared by the first call to sqlite3_step() for a particular run or until the next call to sqlite3_column_name() or sqlite3_column_name16() on the same column. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-04985-23577-44603-16684-59773-10654-23647-01316
          +

          The schema_version pragma will get or set the value of the schema-version integer at offset 40 in the database header. +(source: pragma.html, checked-by: th3/req1/pragma28.test, matrix: context, detail)

          + +
          R-05029-19081-65364-33409-26598-32718-22638-00652
          +

          SQLITE_STATUS_MEMORY_USED This parameter is the current amount of memory checked out using sqlite3_malloc(), either directly or indirectly. The figure includes calls made to sqlite3_malloc() by the application and internal memory usage by the SQLite library. Auxiliary page-cache memory controlled by SQLITE_CONFIG_PAGECACHE is not included in this parameter. The amount returned is the sum of the allocation sizes as reported by the xSize method in sqlite3_mem_methods. +(source: c3ref/c_status_malloc_count.html, matrix: context, detail)

          + +
          R-05038-25064-50136-23943-62126-35147-57737-05371
          +

          You can then access the ROWID using any of four different names, the original three names described above or the name given to the INTEGER PRIMARY KEY column. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-05050-19932-51228-07490-05961-18569-19924-51856
          +

          The SQLITE_CONFIG_MUTEX option takes a single argument which is a pointer to an instance of the sqlite3_mutex_methods structure. The argument specifies alternative low-level mutex routines to be used in place the mutex routines built into SQLite. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/th3main.c, matrix: context, detail)

          + +
          R-05088-64670-01812-40293-14899-41323-61587-34551
          +

          The sqlite_sequence. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-05098-06501-37096-20174-22596-42631-53516-57817
          +

          In shared cache mode, attempting to attach the same database file more than once results in an error. +(source: lang_detach.html, checked-by: tcl/shared7.test, th3/cov1/attach07.test, matrix: context, detail)

          + +
          R-05119-02637-14414-33683-07351-22342-03629-61768
          +

          The 4-byte big-endian integer at offset 36 stores stores the total number of pages on the freelist. +(source: fileformat2.html, checked-by: src/btree.c, th3/req1/pragma21.test, matrix: context, detail)

          + +
          R-05155-34454-27271-17967-48575-19068-12269-57153
          +

          The precedence of the BETWEEN operator is the same as the precedence as operators == and != and LIKE and groups left to right. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-05192-57965-21317-62763-55347-54447-59069-43394
          +

          Hence, the string '3.0e+5' is stored in a column with NUMERIC affinity as the integer 300000, not as the floating point value 300000.0. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-05196-58733-44887-26524-08639-58577-62968-38394
          +

          The "temp" database (in which TEMP tables and indices are stored) and in-memory databases always uses exclusive locking mode. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-05212-61817-14032-11419-24203-62425-34846-12664
          +

          If an error occurs, that fact is recorded in the sqlite3_str object and can be recovered by a subsequent call to sqlite3_str_errcode(X). +(source: c3ref/str_append.html, matrix: context, detail)

          + +
          R-05226-30063-38393-23337-31220-10155-17682-45217
          +

          If the application using SQLite crashes in the middle of a transaction when the MEMORY journaling mode is set, then the database file will very likely go corrupt. +(source: pragma.html, checked-by: th3/req1/pragma25.test, matrix: context, detail)

          + +
          R-05239-12850-29861-48267-58259-09367-64321-59571
          +

          If no algorithm is specified anywhere, the ABORT algorithm is used. +(source: lang_conflict.html, checked-by: th3/req1/conflict03.test, matrix: context, detail)

          + +
          R-05254-00658-23742-34136-13538-61949-20472-35341
          +

          So the following query could use the partial index: SELECT * FROM tab2 WHERE b=456 AND c<>0; -- uses partial index +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-05272-22592-13374-24756-51597-06491-53677-55023
          +

          The index for named parameters can be looked up using the sqlite3_bind_parameter_index() API if desired. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-05301-32681-11917-53839-06553-61603-43952-64876
          +

          If the query optimizer is unable to use the index specified by the INDEXED BY clause, then the query will fail with an error. +(source: lang_indexedby.html, checked-by: tcl/indexedby.test, matrix: context, detail)

          + +
          R-05363-17893-60997-09697-28202-47991-52787-63067
          +

          Views are read-only in SQLite. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-05367-01575-38544-05441-45705-50827-33382-05876
          +

          The first argument to the sqlite3_bind_*() routines is always a pointer to the sqlite3_stmt object returned from sqlite3_prepare_v2() or its variants. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-05416-39654-33473-55228-34062-26099-18988-34297
          +

          Any callback set by a previous call to sqlite3_commit_hook() for the same database connection is overridden. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-05416-57569-14245-59554-42970-16556-04782-39407
          +

          The sqlite3_create_collation_v2() works like sqlite3_create_collation() with the addition that the xDestroy callback is invoked on pArg when the collating function is deleted. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-05452-35198-10871-20803-29102-44206-02290-23562
          +

          The object returned by sqlite3_column_value() is an unprotected sqlite3_value object. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-05461-33397-24167-58750-38066-50926-47850-55199
          +

          If SQLite is compiled with the SQLITE_ENABLE_STAT4 option, then additional histogram data is collected and stored in sqlite_stat4. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-05475-27562-55227-25532-19767-14622-00601-03902
          +

          The sqlite3_backup_remaining() routine returns the number of pages still to be backed up at the conclusion of the most recent sqlite3_backup_step(). +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-05513-33819-59240-57490-36750-56355-20133-11323
          +

          It is not an error to create a table that has the same name as an existing trigger. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-05529-49311-19385-25088-51848-47183-58001-39726
          +

          If the integrity_check pragma finds problems, strings are returned (as multiple rows with a single column per row) which describe the problems. +(source: pragma.html, checked-by: th3/req1/integrityck01.test, matrix: context, detail)

          + +
          R-05617-50091-64320-09946-64698-41149-46478-61865
          +

          In the DELETE mode, the rollback journal is deleted at the conclusion of each transaction. +(source: pragma.html, checked-by: th3/req1/pragma24.test, matrix: context, detail)

          + +
          R-05644-53956-28885-25038-62165-04272-38392-10037
          +

          A WAL always grows from beginning toward the end. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-05646-15132-11020-10123-43884-18508-24247-46472
          +

          When synchronous is NORMAL (1), the SQLite database engine will still sync at the most critical moments, but less often than in FULL mode. +(source: pragma.html, matrix: context, detail)

          + +
          R-05658-50861-03980-59142-22738-32773-09138-30302
          +

          SQLite only understands the hexadecimal integer notation when it appears in the SQL statement text, not when it appears as part of the content of the database. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-05681-60460-45963-09749-31482-57327-02393-17906
          +

          If the ANALYZE command is run in order to gather statistics, a different choice might be made if the statistics indicate that the alternative is likely to run faster. +(source: optoverview.html, matrix: context, detail)

          + +
          R-05688-29289-29845-29411-51913-58756-05388-39596
          +

          PRAGMA encoding; PRAGMA encoding = 'UTF-8'; PRAGMA encoding = 'UTF-16'; PRAGMA encoding = 'UTF-16le'; PRAGMA encoding = 'UTF-16be'; +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-05693-48487-42509-32993-20525-28591-05760-18227
          +

          For the index above and WHERE clause like this: ... WHERE a=5 OR b IN (1,2,3) OR c NOT NULL OR d='hello' The index is not usable because the WHERE clause terms are connected by OR instead of AND. +(source: optoverview.html, matrix: context, detail)

          + +
          R-05702-07867-01732-07701-01060-12844-31655-42982
          +

          The key to an index b-tree is a record composed of the columns that are being indexed followed by the key of the corresponding table row. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-05723-45863-34375-13823-48994-32413-55048-46379
          +

          The sqlite_stat3.sample column holds the value of the left-most field of an index identified by sqlite_stat3.idx and sqlite_stat3.tbl. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-05731-00924-21642-36920-42396-08100-00001-17293
          +

          The table name must be unqualified for INSERT statements that occur within CREATE TRIGGER statements. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-05734-13629-21302-48631-57775-63447-36504-30462
          +

          If an INSERT statement attempts to insert a blob value, or a string or real value that cannot be losslessly converted to an integer into an integer primary key or rowid column, a "datatype mismatch" error occurs and the statement is aborted. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-05791-54928-02769-08459-30778-25258-29853-24680
          +

          Running VACUUM ensures that each table and index is largely stored contiguously within the database file. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-05898-54598-22699-61791-29592-33550-33097-15159
          +

          Otherwise, if the expression sorted by an ORDER BY clause is a column, then the collating sequence of the column is used to determine sort order. +(source: datatype3.html, checked-by: th3/req1/datatype3_10.test, matrix: context, detail)

          + +
          R-05903-08460-38037-43122-07089-54739-62474-34030
          +

          If a deferred foreign key constraint is violated, then an error is reported when the user attempts to commit the transaction if the foreign key constraint violations still exist at that point. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys22.test, matrix: context, detail)

          + +
          R-05906-34301-40279-37243-33018-07128-06632-24411
          +

          In particular, if one wants to know all "children" of a particular purchase order "?1", the query would be: SELECT po_num FROM purchaseorder WHERE parent_po=?1; +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-05912-10167-55658-18265-62443-52976-18281-50268
          +

          The journal_size_limit pragma may be used to limit the size of rollback-journal and WAL files left in the file-system after transactions or checkpoints. +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-05933-14338-14685-58376-15497-20309-09611-25931
          +

          All of the examples create a WITHOUT ROWID table with two PRIMARY KEY columns, "a" and "c", in that order, followed by two data columns "b" and "d", also in that order. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-05985-29284-11131-56196-04541-34001-38610-39560
          +

          If the right operand of an IN or NOT IN operator is a list of values, each of those values must be scalars and the left expression must also be a scalar. +(source: lang_expr.html, checked-by: th3/cov1/rowvalue06.test, matrix: context, detail)

          + +
          R-06021-09373-60954-10709-09959-52253-36320-11394
          +

          But extensions can override the match() function with more helpful logic. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-06024-54164-19422-11836-49964-56179-07103-14892
          +

          Two or more MATCH operators are allowed in the same WHERE clause, as long as they are connected by AND operators. +(source: rtree.html, checked-by: th3/cov1/rtree04.test, matrix: context, detail)

          + +
          R-06028-16857-64547-18047-60085-29491-06944-27148
          +

          Similarly, if the prefix integer is less than -9223372036854775808 then the result of the cast is exactly -9223372036854775808. +(source: lang_expr.html, checked-by: tcl/cast.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-06033-51812-54641-21311-09702-50904-10745-36536
          +

          This pragma invokes the sqlite3_hard_heap_limit64() interface with the argument N, if N is specified and N is a positive integer that is less than the current hard heap limit. +(source: pragma.html, matrix: context, detail)

          + +
          R-06044-07843-41488-27430-15484-51013-09491-52143
          +

          Each page record stores a copy of the content of a page from the database file before it was changed. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-06085-13761-54522-48441-51146-08233-07521-56188
          +

          Unless the table to which the trigger is attached is in the TEMP database, the table being updated by the trigger program must reside in the same database as it. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-06094-55152-33533-26668-27298-05995-61599-07184
          +

          Unbound parameters are interpreted as NULL. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-06121-44139-52990-59264-15521-64976-48420-00452
          +

          If X is NULL then length(X) is NULL. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-06125-22327-52915-34188-45275-42271-34098-17754
          +

          As well as SQLITE_OK and SQLITE_DONE, a call to sqlite3_backup_step() may return SQLITE_READONLY, SQLITE_NOMEM, SQLITE_BUSY, SQLITE_LOCKED, or an SQLITE_IOERR_XXX extended error code. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-06154-44456-05106-65403-18746-31073-17094-53078
          +

          The fifth argument, xCompare, is a pointer to the collating function. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-06184-64035-19129-41964-19001-40522-59120-29266
          +

          The second pointer map page will be on page J+3 and that ptrmap page will provide back pointer information for pages J+4 through 2*J+3 inclusive. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-06192-43187-09900-12561-05322-03139-09562-46958
          +

          For the right-most column of an index that is used, there can be up to two inequalities that must sandwich the allowed values of the column between two extremes. +(source: optoverview.html, matrix: context, detail)

          + +
          R-06211-52866-60944-51344-33653-00695-35099-44728
          +

          A single WAL file can be reused multiple times. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-06247-40710-32264-36174-63374-18082-50900-27234
          +

          If the busy-handler returns non-zero before the lock is available, then SQLITE_BUSY is returned to the caller. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-06268-22533-04308-14386-21741-11230-29946-31155
          +

          The cache query parameter determines if the new database is opened using shared cache mode or with a private cache. +(source: uri.html, matrix: context, detail)

          + +
          R-06289-57229-11447-28178-35750-27104-36074-23089
          +

          If the case_sensitive_like pragma is enabled as follows: PRAGMA case_sensitive_like=ON; Then the LIKE operator pays attention to case and the example above would evaluate to false. +(source: optoverview.html, matrix: context, detail)

          + +
          R-06325-15315-47203-37013-07627-21557-12001-05874
          +

          In this case, if both operands are NULL, then the IS operator evaluates to 1 (true) and the IS NOT operator evaluates to 0 (false). +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-06367-56981-61813-52742-22421-22635-19629-30966
          +

          There is a limit, set using sqlite3_limit() and SQLITE_LIMIT_ATTACHED, to the number of databases that can be simultaneously attached to a single database connection. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-06396-00487-24665-04701-02670-39583-42617-54638
          +

          The fourth parameter is an arbitrary client data pointer that is passed through into the xCreate and xConnect methods of the virtual table module when a new virtual table is be being created or reinitialized. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-06471-16287-47744-18667-43209-46484-64489-20920
          +

          If an INSERT or UPDATE statement attempts to modify the table content so that two or more rows have identical primary key values, that is a constraint violation. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-06483-27112-61838-60600-31039-16842-06931-49767
          +

          The xMutexEnd() interface is invoked exactly once for each call to sqlite3_shutdown(). +(source: c3ref/mutex_methods.html, matrix: context, detail)

          + +
          R-06497-44374-00376-59592-23814-22462-41106-13473
          +

          The strftime() routine returns the date formatted according to the format string specified as the first argument. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-06521-54703-61418-20766-12795-30140-09114-51879
          +

          Each entry in the ex25acde index consists of only the columns a, c, d, and e, in that order. +(source: fileformat2.html, checked-by: th3/req1/fileformat04.test, matrix: context, detail)

          + +
          R-06526-21822-44146-52005-29553-25229-08273-20735
          +

          If the result is a numeric value then sqlite3_column_bytes() uses sqlite3_snprintf() to convert that value to a UTF-8 string and returns the number of bytes in that string. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-06529-47362-28298-49876-57281-01728-38007-39876
          +

          Following the size varint are one or more additional varints, one per column. +(source: fileformat2.html, checked-by: src/vdbe.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-06603-49335-45148-37548-51354-29602-47904-63601
          +

          The rank of the column within the table being indexed, or -1 if the index-column is the rowid of the table being indexed and -2 if the index is on an expression. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-06617-54588-52951-29775-47412-02155-55122-34673
          +

          Each ORDER BY expression may be optionally followed by one of the keywords ASC (smaller values are returned first) or DESC (larger values are returned first). +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-06626-12911-45896-07127-03501-58228-62690-15323
          +

          The SQLITE_CONFIG_HEAP option is only available if SQLite is compiled with either SQLITE_ENABLE_MEMSYS3 or SQLITE_ENABLE_MEMSYS5 and returns SQLITE_ERROR if invoked otherwise. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3oom.c, matrix: context, detail)

          + +
          R-06630-59185-25894-35312-55008-29354-15372-24847
          +

          Each modifier is a transformation that is applied to the time value to its left. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-06640-03838-35138-60782-53418-54966-60899-05980
          +

          The sqlite3_snapshot_open() interface returns SQLITE_OK on success or an appropriate error code if it fails. +(source: c3ref/snapshot_open.html, matrix: context, detail)

          + +
          R-06681-36915-07445-41328-35159-18817-58464-46967
          +

          The largest Fibonacci weight occurs on the first element of the sequence being summed. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-06690-32088-38683-38277-10943-03715-22041-42931
          +

          The sqlite3_value_free(V) interface frees an sqlite3_value object previously obtained from sqlite3_value_dup(). +(source: c3ref/value_dup.html, matrix: context, detail)

          + +
          R-06710-22511-57136-17945-50070-33110-36192-14395
          +

          When case_sensitive_like is disabled, the default LIKE behavior is expressed. +(source: pragma.html, checked-by: th3/req1/pragma10.test, matrix: context, detail)

          + +
          R-06711-65327-14932-40385-35570-36295-04830-18729
          +

          If there are subqueries in the RETURNING clause, those subqueries may contain aggregates and window functions, but aggregates cannot occur at the top level. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-06718-34797-20809-29800-16443-15807-57069-06143
          +

          If the UNIQUE keyword appears between CREATE and INDEX then duplicate index entries are not allowed. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-06726-07466-50674-60893-18596-18216-57915-63107
          +

          A column name can be any of the names defined in the CREATE TABLE statement or one of the following special identifiers: "ROWID", "OID", or "_ROWID_". +(source: lang_expr.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-06730-09692-37737-40278-41150-46947-53359-48437
          +

          Note that the unary + operator also removes type affinity from an expression, and in some cases this can cause subtle changes in the meaning of an expression. +(source: optoverview.html, matrix: context, detail)

          + +
          R-06730-45014-00107-46861-15784-38161-55624-19541
          +

          If the argument N is negative then no change is made to the heap limit. +(source: c3ref/hard_heap_limit64.html, checked-by: th3/req1/softheaplimit01.test, matrix: context, detail)

          + +
          R-06824-28531-04860-08794-38432-46623-19840-41642
          +

          This option is used to change the name of the "main" database schema. +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, th3/cov1/maindbname01.test, matrix: context, detail)

          + +
          R-06827-27714-37662-62265-13123-35942-36667-57305
          +

          These routines provide a means to determine the database, table, and table column that is the origin of a particular result column in SELECT statement. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-06842-00595-27459-11943-09880-13369-18922-07215
          +

          If the URI contains an authority, then it must be either an empty string or the string "localhost". +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-06866-39125-55055-41490-42674-60526-11809-05930
          +

          Freeblocks are always connected in order of increasing offset. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-06868-44093-33901-50180-63066-19596-24201-39627
          +

          The collating sequence used for expressions of the form "x IN (y, z, ...)" is the collating sequence of x. +(source: datatype3.html, checked-by: th3/req1/datatype3_10.test, matrix: context, detail)

          + +
          R-06920-11647-57198-53546-22558-52613-40073-20013
          +

          If the function is registered using the sqlite3_collation_needed() API, then it is passed the names of undefined collation sequences as strings encoded in UTF-8. +(source: c3ref/collation_needed.html, matrix: context, detail)

          + +
          R-06962-29571-53557-56869-59611-31379-35849-49272
          +

          The module-name must be registered with the SQLite database connection using sqlite3_create_module() or sqlite3_create_module_v2() prior to issuing the CREATE VIRTUAL TABLE statement. +(source: lang_createvtab.html, matrix: context, detail)

          + +
          R-07016-26442-22994-35571-41506-56753-23987-59797
          +

          Each of the named columns of the new row is populated with the results of evaluating the corresponding VALUES expression. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-07046-65439-53781-18565-05582-11236-16234-65526
          +

          Any of these arguments may be NULL, in which case the corresponding element of metadata is omitted. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-07051-38416-38857-52812-51917-08930-07930-15860
          +

          If the declared type contains the string "INT" then it is assigned INTEGER affinity. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-07061-20551-45555-61970-58663-33619-01553-07889
          +

          If the source database is modified by an external process or via a database connection other than the one being used by the backup operation, then the backup will be automatically restarted by the next call to sqlite3_backup_step(). +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-07061-54920-02690-34802-26523-14617-41412-12725
          +

          To overcome this problem, SQLite attempts to flatten subqueries in the FROM clause of a SELECT. +(source: optoverview.html, matrix: context, detail)

          + +
          R-07100-06606-15404-00202-26903-38022-07639-13720
          +

          A single quote within the string can be encoded by putting two single quotes in a row - as in Pascal. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-07154-34181-57164-55597-27085-41955-25905-44172
          +

          The table might look something like this: CREATE TABLE person( person_id INTEGER PRIMARY KEY, team_id INTEGER REFERENCES team, is_team_leader BOOLEAN, -- other fields elided ); +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-07161-27322-25839-32043-58017-64022-31100-22152
          +

          The one-byte integer at offset 7 gives the number of fragmented free bytes within the cell content area. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-07178-42569-23822-25165-44123-64804-39149-01193
          +

          The first time the database is read in EXCLUSIVE mode, a shared lock is obtained and held. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-07218-15811-34586-61584-11375-61122-40476-23928
          +

          The "sqlite_autoindex_TABLE_N" name is never allocated for an INTEGER PRIMARY KEY, either in rowid tables or WITHOUT ROWID tables. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-07223-48323-28604-04641-30689-62184-47326-29698
          +

          A nested savepoint transaction may be RELEASEd while the database is in a state that does not satisfy a deferred foreign key constraint. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys15.test, matrix: context, detail)

          + +
          R-07232-03261-48010-41283-49496-35316-10713-33982
          +

          The sqlite_schema.rootpage column stores the page number of the root b-tree page for tables and indexes. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-07264-50488-37885-59359-19150-24539-64601-15119
          +

          If the INTO clause is included, then the original database file is unchanged and a new database is created in the filename given by the argument to the INTO clause. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-07272-22309-27541-26278-30152-44282-17867-64207
          +

          The default behavior is for mutexes to be enabled. +(source: c3ref/threadsafe.html, checked-by: src/sqliteInt.h, matrix: context, detail)

          + +
          R-07280-60510-42023-64617-40990-52816-04160-12840
          +

          Assuming the library is compiled with foreign key constraints enabled, it must still be enabled by the application at runtime, using the PRAGMA foreign_keys command. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys04.test, matrix: context, detail)

          + +
          R-07291-35328-43800-36980-63575-06657-13005-40237
          +

          A value of 5 (0x05) means the page is an interior table b-tree page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-07327-11967-60382-46381-13455-42235-00328-15671
          +

          The expression "CAST(4.0 AS INT)" returns an integer 4, whereas "CAST(4.0 AS NUMERIC)" leaves the value as a floating-point 4.0. +(source: datatype3.html, matrix: context, detail)

          + +
          R-07343-35026-05102-53943-15495-27224-50604-38447
          +

          An explicit DEFAULT clause may specify that the default value is NULL, a string constant, a blob constant, a signed-number, or any constant expression enclosed in parentheses. A default value may also be one of the special case-independent keywords CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-07358-23974-16513-21105-25104-49768-42018-55781
          +

          The hard_heap_limit pragma always returns the same integer that would be returned by the sqlite3_hard_heap_limit64(-1) C-language function. +(source: pragma.html, matrix: context, detail)

          + +
          R-07373-26855-08191-07958-60277-35412-28383-64233
          +

          The SQLITE_FCNTL_VFSNAME opcode can be used to obtain the names of all VFSes in the VFS stack. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-07387-29430-25270-46585-59144-29340-25578-53451
          +

          The three special identifiers describe the unique integer key (the rowid) associated with every row of every table and so are not available on WITHOUT ROWID tables. +(source: lang_expr.html, checked-by: th3/req1/expr02.test, matrix: context, detail)

          + +
          R-07391-62365-50484-20583-23156-31411-22306-43291
          +

          If the result is NULL, then sqlite3_column_bytes() returns zero. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-07434-39946-64395-56249-16923-20954-34684-05720
          +

          The RELEASE command is like a COMMIT for a SAVEPOINT. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-07443-03104-25430-52440-15603-28211-53431-58552
          +

          Shared cache is disabled by default. +(source: c3ref/enable_shared_cache.html, matrix: context, detail)

          + +
          R-07444-33850-51822-16540-61383-01460-32210-48440
          +

          Whitespace and comments that follow the final semicolon are ignored. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-07454-30568-63832-24254-44508-63507-10248-49928
          +

          If a schema name is given as the argument, then all tables and indices in that one database are analyzed. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-07474-04783-61557-15842-18544-20982-63471-50658
          +

          Transaction control statements such as BEGIN, COMMIT, ROLLBACK, SAVEPOINT, and RELEASE cause sqlite3_stmt_readonly() to return true, since the statements themselves do not actually modify the database but rather they control the timing of when other statements modify the database. +(source: c3ref/stmt_readonly.html, checked-by: th3/cov1/vdbeapi14.test, matrix: context, detail)

          + +
          R-07490-32536-65444-08514-64358-21801-57919-13418
          +

          If the specified view cannot be found and an IF EXISTS clause is present in the DROP VIEW statement, then the statement is a no-op. +(source: lang_dropview.html, checked-by: tcl/e_dropview.test, th3/cov1/build13.test, matrix: context, detail)

          + +
          R-07535-34995-01447-54565-38524-09572-39500-26944
          +

          The result of avg() is always a floating point value as long as at there is at least one non-NULL input even if all inputs are integers. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-07548-06087-12762-53515-32578-33672-61878-36013
          +

          These routines return the name assigned to a particular column in the result set of a SELECT statement. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-07548-13422-51816-60728-36638-61915-61462-20502
          +

          The ORDER BY clause on a DELETE statement is used only to determine which rows fall within the LIMIT. The order in which rows are deleted is arbitrary and is not influenced by the ORDER BY clause. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-07634-40532-31370-54179-45276-35620-20661-11259
          +

          The cache_spill pragma enables or disables the ability of the pager to spill dirty cache pages to the database file in the middle of a transaction. +(source: pragma.html, checked-by: tcl/pragma2.test, matrix: context, detail)

          + +
          R-07667-49537-57124-54989-59227-41131-33160-03537
          +

          The result of the CASE expression is the evaluation of the THEN expression that corresponds to the first WHEN expression for which the comparison is true. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-07677-41881-40135-26272-16926-18163-28954-03069
          +

          If the largest ROWID is equal to the largest possible integer (9223372036854775807) then the database engine starts picking positive candidate ROWIDs at random until it finds one that is not previously used. +(source: autoinc.html, checked-by: src/vdbe.c, th3/cov1/vdbe23.test, th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-07677-44926-50918-49822-13370-30168-54851-13094
          +

          The format for CURRENT_TIMESTAMP is "YYYY-MM-DD HH:MM:SS". +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-07686-30751-51285-58561-12727-05752-40900-44621
          +

          Hence, the content encoding for a WITHOUT ROWID table is the same as the content encoding for an ordinary rowid table, except that the order of the columns is rearranged so that PRIMARY KEY columns come first, and the content is used as the key in an index b-tree rather than as the data in a table b-tree. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-07727-56631-19058-51033-37798-11219-19213-34496
          +

          Instead of cancelling the transaction, the ROLLBACK TO command restarts the transaction again at the beginning. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-07734-01023-35400-33877-62605-53392-63637-26399
          +

          The result of total() is always a floating point value. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-07782-53619-37361-40296-27943-36501-08866-63723
          +

          To be usable by an index a term must be of one of the following forms: column = expression column IS expression column > expression column >= expression column < expression column <= expression expression = column expression > column expression >= column expression < column expression <= column column IN (expression-list) column IN (subquery) column IS NULL +(source: optoverview.html, matrix: context, detail)

          + +
          R-07796-55423-52523-43504-40552-37000-09933-05670
          +

          Returns the size in bytes of the BLOB accessible via the successfully opened BLOB handle in its only argument. +(source: c3ref/blob_bytes.html, checked-by: tcl/e_blobbytes.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-07801-24468-36344-27295-15963-50909-61997-55720
          +

          SQLITE_LIMIT_COMPOUND_SELECT The maximum number of terms in a compound SELECT statement. +(source: c3ref/c_limit_attached.html, checked-by: th3/req1/limit02.test, matrix: context, detail)

          + +
          R-07848-59274-08583-36446-01674-55219-01938-38331
          +

          The requested measurement is written into a variable pointed to by the "pOut" parameter. +(source: c3ref/stmt_scanstatus.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-07865-58192-09859-42993-29277-46278-59857-06081
          +

          The 4-byte big-endian integer at offset 92 is the value of the change counter when the version number was stored. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-07866-07572-04759-27245-06319-59551-46387-52672
          +

          The temp_store_directory pragma may modify this variable and cause it to point to memory obtained from sqlite3_malloc. +(source: c3ref/temp_directory.html, matrix: context, detail)

          + +
          R-07896-01909-17755-58747-61497-14681-53331-52466
          +

          Mutexes created using SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread. In such cases, the mutex must be exited an equal number of times before another thread can enter. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-07963-00293-13635-32107-53901-52250-25105-19603
          +

          A function implementation with a non-negative nArg parameter is a better match than a function implementation with a negative nArg. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-07986-46024-43778-44003-14770-46888-01136-33565
          +

          If an INSERT statement attempts to insert a NULL value into a rowid or integer primary key column, the system chooses an integer value to use as the rowid automatically. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-07987-54086-28782-61595-63457-13975-41237-46869
          +

          If the result is a UTF-16 string, then sqlite3_column_bytes() converts the string to UTF-8 and then returns the number of bytes. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-08013-37737-04179-14029-08100-20980-22992-19882
          +

          The application can also use a PRAGMA foreign_keys statement to determine if foreign keys are currently enabled. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys04.test, matrix: context, detail)

          + +
          R-08023-12605-32642-43845-16740-17726-48491-51878
          +

          The sqlite3_compileoption_get() function allows iterating over the list of options that were defined at compile time by returning the N-th compile time option string. +(source: c3ref/compileoption_get.html, checked-by: th3/cov1/ctime01.test, matrix: context, detail)

          + +
          R-08041-13327-32920-22476-39167-57805-60221-02084
          +

          Any operators applied to column names, including the no-op unary "+" operator, convert the column name into an expression which always has no affinity. Hence even if X and Y.Z are column names, the expressions +X and +Y.Z are not column names and have no affinity. +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-08054-15429-02256-10004-55638-18867-37025-44792
          +

          The min/max-value pair columns are stored as 32-bit floating point values for "rtree" virtual tables or as 32-bit signed integers in "rtree_i32" virtual tables. +(source: rtree.html, matrix: context, detail)

          + +
          R-08114-32142-00732-64514-48561-20765-18490-60884
          +

          SQLite takes the text result from the application from the 2nd parameter of the sqlite3_result_text* interfaces. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-08137-02757-06056-54602-11771-11326-16926-36130
          +

          The eTextRep argument determines the encoding of strings passed to the collating function callback, xCompare. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-08161-44559-11294-25208-33337-24402-63584-35626
          +

          The xShutdown() method is called by sqlite3_shutdown(). +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-08181-17347-07123-49289-35480-05775-37202-24874
          +

          The first form (without an argument) queries the current limit. +(source: pragma.html, matrix: context, detail)

          + +
          R-08185-34281-12728-08403-04938-30337-50100-31193
          +

          The sqlite3_result_blob() interface sets the result from an application-defined function to be the BLOB whose content is pointed to by the second parameter and which is N bytes long where N is the third parameter. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-08195-21952-34144-42523-58914-33404-63629-47185
          +

          This function is used to read data from an open BLOB handle into a caller-supplied buffer. N bytes of data are copied into buffer Z from the open BLOB, starting at offset iOffset. +(source: c3ref/blob_read.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-08198-48522-54017-24058-29188-47107-45936-39213
          +

          The TRUNCATE journaling mode commits transactions by truncating the rollback journal to zero-length instead of deleting it. +(source: pragma.html, checked-by: th3/req1/pragma24.test, matrix: context, detail)

          + +
          R-08220-00712-08202-21182-26079-26258-28714-22258
          +

          The sqlite3_malloc() routine returns a pointer to a block of memory at least N bytes in length, where N is the parameter. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-08224-30249-18275-36906-02216-43610-40508-55733
          +

          Rows are assigned contiguously ascending rowid values, starting with 1, in the order that they are returned by the SELECT statement. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-08267-32299-63841-11105-16971-59372-17886-11855
          +

          If Z is omitted then substr(X,Y) returns all characters through the end of the string X beginning with the Y-th. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-08308-17224-38959-45804-35149-08611-40097-56535
          +

          The default collating function for all strings is BINARY. +(source: fileformat2.html, checked-by: src/callback.c, th3/req1/fileformat05.test, matrix: context, detail)

          + +
          R-08348-34672-30710-39534-43438-18204-53248-46501
          +

          If the database is opened (and/or created) successfully, then SQLITE_OK is returned. Otherwise an error code is returned. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-08382-59936-33976-47324-12447-38582-10569-47799
          +

          Writes to the BLOB that occurred before the BLOB handle expired are not rolled back by the expiration of the handle, though of course those changes might have been overwritten by the statement that expired the BLOB handle or by other independent statements. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-08469-46782-59132-04592-41153-65090-64039-23228
          +

          PRAGMA collation_list; Return a list of the collating sequences defined for the current database connection. +(source: pragma.html, checked-by: th3/req1/pragma13.test, matrix: context, detail)

          + +
          R-08470-40933-39231-45429-29526-36251-38185-62772
          +

          The ANALYZE command gathers statistics about tables and indices and stores the collected information in internal tables of the database where the query optimizer can access the information and use it to help make better query planning choices. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-08531-36543-43368-50490-58607-10151-50307-46292
          +

          A compound SELECT created using UNION ALL operator returns all the rows from the SELECT to the left of the UNION ALL operator, and all the rows from the SELECT to the right of it. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-08551-61977-00536-43869-21824-42581-53338-42827
          +

          A value with storage class NULL is considered less than any other value (including another value with storage class NULL). +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-08570-19916-06094-14315-21140-23229-64814-49543
          +

          However, when not in write-ahead log mode, the page_size and/or auto_vacuum properties of an existing database may be changed by using the page_size and/or pragma auto_vacuum pragmas and then immediately VACUUMing the database. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-08600-21007-59699-24141-37945-25671-33905-23052
          +

          If parameter Y is present then it is used as the separator between instances of X. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-08669-22397-26856-32296-22372-63471-24126-56225
          +

          The number of columns in the rows returned by a simple SELECT statement is equal to the number of expressions in the result expression list after substitution of * and alias.* expressions. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-08680-42661-24971-27030-06181-52917-24320-47746
          +

          The second column is the number of modified pages that have been written to the write-ahead log file. +(source: pragma.html, matrix: context, detail)

          + +
          R-08681-56652-45784-02729-28742-19539-49862-48727
          +

          If any prior errors have occurred while constructing the dynamic string in sqlite3_str X, then the sqlite3_str_errcode(X) method will return an appropriate error code. +(source: c3ref/str_errcode.html, matrix: context, detail)

          + +
          R-08698-00464-45876-62927-50774-10665-22959-52892
          +

          In the second form, if the database name is omitted, the limit that is set becomes the default limit for all databases that are added to the database connection by subsequent ATTACH statements. +(source: pragma.html, matrix: context, detail)

          + +
          R-08702-09805-37818-25319-39065-12548-64378-42477
          +

          The sqlite3_commit_hook() interface registers a callback function to be invoked whenever a transaction is committed. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-08782-34587-24709-60747-46157-12897-42098-02206
          +

          sqlite3_release_memory() returns the number of bytes actually freed, which might be more or less than the amount requested. +(source: c3ref/release_memory.html, checked-by: th3/req1/releasemem01.test, matrix: context, detail)

          + +
          R-08804-63175-03781-61718-64946-14312-06461-12465
          +

          Corresponding rows in the index and table b-trees share the same rowid or primary key values and contain the same value for all indexed columns. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-08861-34280-62866-63452-63262-62491-16025-47018
          +

          If the simple SELECT is a SELECT ALL, then the entire set of result rows are returned by the SELECT. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-08903-51590-18062-24037-51123-18798-32019-19886
          +

          The sqlite3_backup_pagecount() routine returns the total number of pages in the source database at the conclusion of the most recent sqlite3_backup_step(). +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-08904-24719-11346-47287-22123-01310-57737-05262
          +

          Sum() will throw an "integer overflow" exception if all inputs are integers or NULL and an integer overflow occurs at any point during the computation. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-08908-23439-37383-27763-09062-14229-58252-49666
          +

          A CREATE TABLE command operates the same whether or not foreign key constraints are enabled. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys21.test, matrix: context, detail)

          + +
          R-08916-58393-39719-51162-04738-33368-03102-45258
          +

          This interface disables all automatic extensions previously registered using sqlite3_auto_extension(). +(source: c3ref/reset_auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-08940-21305-30374-23280-00035-42277-55348-10248
          +

          Unless it returns SQLITE_MISUSE, this function sets the database connection error code and message accessible via sqlite3_errcode() and sqlite3_errmsg() and related functions. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-08951-19801-08417-23581-55505-30558-59834-07757
          +

          When searching database schemas for a named object, objects of types that cannot be used in the context of the reference are always ignored. +(source: lang_naming.html, checked-by: tcl/e_resolve.test, matrix: context, detail)

          + +
          R-08966-11138-53751-32192-40537-45377-40964-32570
          +

          The SQLITE_CONFIG_HEAP option specifies a static memory buffer that SQLite will use for all of its dynamic memory allocation needs beyond those provided for by SQLITE_CONFIG_PAGECACHE. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/th3main.c, matrix: context, detail)

          + +
          R-08980-53124-31180-17843-61277-57445-45439-15186
          +

          The CAST operator understands decimal integers only — conversion of hexadecimal integers stops at the "x" in the "0x" prefix of the hexadecimal integer string and thus result of the CAST is always zero. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-09005-28791-60027-45340-35703-17892-19441-18649
          +

          Replacing the phrase above with any of the following creates an immediate foreign key constraint. NOT DEFERRABLE INITIALLY DEFERRED -- An immediate foreign key constraint NOT DEFERRABLE INITIALLY IMMEDIATE -- An immediate foreign key constraint NOT DEFERRABLE -- An immediate foreign key constraint DEFERRABLE INITIALLY IMMEDIATE -- An immediate foreign key constraint DEFERRABLE -- An immediate foreign key constraint +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, matrix: context, detail)

          + +
          R-09033-01493-08484-25490-18731-61378-37357-02599
          +

          As of SQLite version 3.6.19, the default setting for foreign key enforcement is OFF. +(source: pragma.html, checked-by: th3/req1/pragma18.test, th3/req1/pragma19.test, matrix: context, detail)

          + +
          R-09068-40660-27195-07118-53993-03715-03215-45426
          +

          A return of SQLITE_BUSY or SQLITE_LOCKED from sqlite3_backup_step() is not a permanent error and does not affect the return value of sqlite3_backup_finish(). +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-09101-51783-59948-59887-59676-41336-15465-57227
          +

          The ANALYZE command scans all indexes of database where there might be a choice between two or more indexes and gathers statistics on the selectiveness of those indexes. +(source: optoverview.html, matrix: context, detail)

          + +
          R-09155-31313-04558-40761-11557-49623-19488-24497
          +

          TRUNCATE This mode works the same way as RESTART with the addition that the WAL file is truncated to zero bytes upon successful completion. +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-09205-13964-09517-20139-64262-42567-60907-13459
          +

          That is to say, it always returns the value of the hard heap limit that is set after any changes imposed by this PRAGMA. +(source: pragma.html, matrix: context, detail)

          + +
          R-09224-24423-49994-35052-44782-07327-29162-57753
          +

          Call the sqlite3_enable_load_extension() routine with onoff==1 to turn extension loading on and call it with onoff==0 to turn it back off again. +(source: c3ref/enable_load_extension.html, matrix: context, detail)

          + +
          R-09247-46544-65339-05337-14094-58644-44779-17885
          +

          The immutable parameter is a boolean query parameter that indicates that the database file is stored on read-only media. +(source: c3ref/open.html, checked-by: th3/cov1/nolock01.test, matrix: context, detail)

          + +
          R-09261-46339-25709-54309-20729-08593-14367-03558
          +

          If Y is omitted then the default entry point name is used. +(source: lang_corefunc.html, checked-by: th3/cov1/func03.test, matrix: context, detail)

          + +
          R-09310-54000-20676-45974-44442-40354-59533-62372
          +

          For the GLOB operator, the column must be indexed using the built-in BINARY collating sequence. +(source: optoverview.html, matrix: context, detail)

          + +
          R-09323-30470-62004-36090-30809-61331-17692-32313
          +

          If a statement modifies the contents of the database so that an immediate foreign key constraint is in violation at the conclusion the statement, an exception is thrown and the effects of the statement are reverted. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, matrix: context, detail)

          + +
          R-09328-38790-35467-08457-46231-05327-56817-51584
          +

          SQLite keeps track of the largest ROWID using an internal table named "sqlite_sequence". +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-09347-53396-09377-17353-50136-41410-13881-29341
          +

          The MATCH operator of a custom R*Tree query function must be a top-level AND-connected term of the WHERE clause, or else it will not be usable by the R*Tree query optimizer and the query will not be runnable. +(source: rtree.html, checked-by: th3/cov1/rtree04.test, matrix: context, detail)

          + +
          R-09385-24237-02595-13081-61892-09820-41014-64589
          +

          Finally, the database is flushed to persistent storage using another xSync method call. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-09398-26102-26496-59828-02242-35200-16935-00376
          +

          Otherwise, if the ORDER BY expression is an alias to an expression that has been assigned a collation sequence using the postfix COLLATE operator, then the collation sequence assigned to the aliased expression is used. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-09479-17959-18929-07004-59700-09241-00688-08802
          +

          Indirect deadlock is also detected, so the system is also considered to be deadlocked if connection B has registered for an unlock-notify callback on the conclusion of connection C's transaction, where connection C is waiting on connection A. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-09543-06473-23021-32220-32793-21583-15245-47596
          +

          A NULL pointer can be used in place of "main" to refer to the main database file. +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-09560-44343-01686-39358-51071-41020-34735-39538
          +

          For the purposes of this pragma, the VACUUM command is considered a schema change, since VACUUM will usual alter the "rootpage" values for entries in the sqlite_schema table. +(source: pragma.html, checked-by: th3/req1/pragma28.test, matrix: context, detail)

          + +
          R-09564-22170-27375-05763-54488-45369-57253-27733
          +

          Whenever a row in the parent table of a foreign key constraint is deleted, or when the values stored in the parent key column or columns are modified, the logical sequence of events is: Execute applicable BEFORE trigger programs, Check local (non foreign key) constraints, Update or delete the row in the parent table, Perform any required foreign key actions, Execute applicable AFTER trigger programs. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys19.test, matrix: context, detail)

          + +
          R-09593-03321-24060-42412-44512-07305-25128-61318
          +

          BLOB literals are string literals containing hexadecimal data and preceded by a single "x" or "X" character. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-09594-37460-38113-48088-05045-45379-64772-49989
          +

          Because of this, SQLite is able to plan queries with 50- or 60-way joins in a matter of microseconds Join reordering is automatic and usually works well enough that programmers do not have to think about it, especially if ANALYZE has been used to gather statistics about the available indexes, though occasionally some hints from the programmer are needed. +(source: optoverview.html, matrix: context, detail)

          + +
          R-09644-54524-34605-02045-19274-34889-27316-65483
          +

          The time value can be followed by zero or more modifiers that alter date and/or time. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-09669-59284-18904-57253-21475-23488-47064-03765
          +

          Text values (odd serial types 13 and larger) sort after numeric values in the order determined by the columns collating function. +(source: fileformat2.html, checked-by: th3/req1/fileformat05.test, matrix: context, detail)

          + +
          R-09681-58560-10305-15727-00297-35868-05335-61175
          +

          The table-name specified as part of a DELETE statement within a trigger body must be unqualified. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-09702-18252-10292-02056-28728-37972-55531-64507
          +

          Thus INSERT OR FAIL, INSERT OR IGNORE, INSERT OR ROLLBACK, and INSERT OR ABORT make no changes to the return value of this routine when their insertion fails. +(source: c3ref/last_insert_rowid.html, matrix: context, detail)

          + +
          R-09704-29281-62509-09033-18405-10464-02206-26533
          +

          The sqlite3_exec() interface runs zero or more UTF-8 encoded, semicolon-separate SQL statements passed into its 2nd argument, in the context of the database connection passed in as its 1st argument. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-09708-05727-57247-34421-62723-03461-49404-45269
          +

          PRAGMA schema.table_info(table-name); This pragma returns one row for each column in the named table. +(source: pragma.html, checked-by: th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-09711-30533-26237-33578-24208-22217-47498-41477
          +

          PRAGMA module_list; This pragma returns a list of virtual table modules registered with the database connection. +(source: pragma.html, matrix: context, detail)

          + +
          R-09748-03241-62835-60245-32173-07711-55769-04429
          +

          This flag determines whether or not the F_FULLFSYNC syncing method is used on systems that support it. +(source: pragma.html, checked-by: th3/req1/pragma11b.test, matrix: context, detail)

          + +
          R-09773-34266-19272-64425-39680-64969-31410-22959
          +

          The name of the column being indexed. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-09773-40602-32968-36782-04559-37578-19507-63398
          +

          Or if no collating sequence is otherwise defined, the built-in BINARY collating sequence is used. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-09782-32948-24767-08594-36498-62288-40921-54378
          +

          If the discard parameter is zero, then the page may be discarded or retained at the discretion of page cache implementation. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-09783-65036-25423-48067-42538-45414-00279-46435
          +

          If the sub-query is a compound select, then all terms of the ORDER by clause of the parent must be simple references to columns of the sub-query. +(source: optoverview.html, matrix: context, detail)

          + +
          R-09798-06276-54780-63214-14309-15802-32530-00850
          +

          As long as the buffer size is greater than zero, sqlite3_snprintf() guarantees that the buffer is always zero-terminated. +(source: c3ref/mprintf.html, checked-by: th3/req1/malloc01.test, matrix: context, detail)

          + +
          R-09808-17554-50654-05359-25920-63839-21736-07612
          +

          SQLITE_LIMIT_SQL_LENGTH The maximum length of an SQL statement, in bytes. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-09813-17279-59166-04895-48075-17845-31813-35638
          +

          Also, GLOB is case sensitive, unlike LIKE. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-09813-48563-02406-35251-52837-06025-02382-52921
          +

          The value returned by sqlite3_changes() immediately after an INSERT, UPDATE or DELETE statement run on a view is always zero. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-09849-00220-60139-37223-30218-05088-34235-14106
          +

          A negative value for the zeroblob results in a zero-length BLOB. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-09866-00585-18081-22279-50210-42819-02133-03966
          +

          sqlite> EXPLAIN QUERY PLAN SELECT t1.*, t2.* FROM t2, t1 WHERE t1.a=1 AND t1.b>2; QUERY PLAN |--SEARCH TABLE t1 USING INDEX i2 (a=? AND b>?) `--SCAN TABLE t2 +(source: eqp.html, matrix: context, detail)

          + +
          R-09904-19077-60402-31152-09250-23294-22236-64637
          +

          The aParam[] array (size nParam) contains the parameter values passed to the SQL function on the right-hand side of the MATCH operator. +(source: rtree.html, matrix: context, detail)

          + +
          R-09933-20910-17434-57069-20423-40847-01443-50853
          +

          SQLite will invoke the destructor D with a single argument of P when it is finished using P. +(source: c3ref/bind_blob.html, checked-by: th3/cov1/bindptr01.test, matrix: context, detail)

          + +
          R-09943-43999-40050-60099-27352-31262-44628-15476
          +

          An attempt to ATTACH a database with a different text encoding from the "main" database will fail. +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-10014-60729-41170-51262-01387-53486-13666-35080
          +

          If X is the name of a rollback or WAL-mode journal file that is passed into the xOpen method of sqlite3_vfs, then sqlite3_database_file_object(X) returns a pointer to the sqlite3_file object that represents the main database file. +(source: c3ref/database_file_object.html, matrix: context, detail)

          + +
          R-10042-17899-51824-29189-33430-37310-31146-42510
          +

          If one operand has INTEGER, REAL or NUMERIC affinity and the other operand has TEXT or BLOB or no affinity then NUMERIC affinity is applied to other operand. +(source: datatype3.html, checked-by: th3/cov1/affinity01.test, th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-10099-10064-58361-57180-39744-05216-32972-43593
          +

          The histogram data is only useful if the right-hand side of the constraint is a simple compile-time constant or parameter and not an expression. +(source: optoverview.html, matrix: context, detail)

          + +
          R-10109-20452-53276-41872-63667-11760-57644-25670
          +

          If SQLITE_OMIT_TRIGGER is defined but SQLITE_OMIT_FOREIGN_KEY is not, then SQLite behaves as it did prior to version 3.6.19 (2009-10-14) - foreign key definitions are parsed and may be queried using PRAGMA foreign_key_list, but foreign key constraints are not enforced. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys05.test, matrix: context, detail)

          + +
          R-10119-21526-34528-05557-36941-47440-26835-18777
          +

          Following a successful SQLITE_FCNTL_BEGIN_ATOMIC_WRITE and prior to the closing SQLITE_FCNTL_COMMIT_ATOMIC_WRITE or SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE, SQLite will make no VFS interface calls on the same sqlite3_file file descriptor except for calls to the xWrite method and the xFileControl method with SQLITE_FCNTL_SIZE_HINT. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-10190-16965-26709-52634-48294-10827-43315-62793
          +

          The sqlite_stat3.nDLt column holds the approximate number of distinct left-most entries in the index that are less than the sample. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-10203-42688-05745-20246-57567-01031-33670-42087
          +

          The callback registered by this function replaces any existing callback registered using sqlite3_wal_hook(). +(source: c3ref/wal_autocheckpoint.html, checked-by: tcl/e_walauto.test, matrix: context, detail)

          + +
          R-10260-62465-16896-41827-00033-64414-58979-23233
          +

          PRAGMA reverse_unordered_selects; PRAGMA reverse_unordered_selects = boolean; +(source: pragma.html, checked-by: th3/req1/pragma27.test, matrix: context, detail)

          + +
          R-10284-11658-30925-56941-44506-24940-01613-45379
          +

          The depth of recursion for triggers has a hard upper limit set by the SQLITE_MAX_TRIGGER_DEPTH compile-time option and a run-time limit set by sqlite3_limit(db,SQLITE_LIMIT_TRIGGER_DEPTH,...). +(source: pragma.html, matrix: context, detail)

          + +
          R-10346-40046-35521-21776-43630-65428-20399-28702
          +

          The CREATE TRIGGER statement is used to add triggers to the database schema. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-10379-15557-17362-29530-27887-61401-49779-43037
          +

          For the static mutex types, the same mutex is returned on every call that has the same type number. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-10382-19306-57880-35714-22073-14679-32627-12019
          +

          The fourth parameter may optionally be ORed with SQLITE_DETERMINISTIC to signal that the function will always return the same result given the same inputs within a single SQL statement. +(source: c3ref/create_function.html, checked-by: th3/cov1/func11.test, matrix: context, detail)

          + +
          R-10393-27560-44275-02566-07675-36741-21342-01930
          +

          Affinity is applied to operands of a comparison operator prior to the comparison according to the following rules in the order shown: +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-10396-30188-46343-25997-25410-36538-31299-06809
          +

          Aggregate min() returns NULL if and only if there are no non-NULL values in the group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-10421-19736-31829-13989-20506-40409-64205-24100
          +

          If any other process is running a checkpoint operation at the same time, the lock cannot be obtained and SQLITE_BUSY is returned. +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/wal.c, tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-10466-53920-46827-22051-27556-17000-33700-37865
          +

          Calling sqlite3_wal_hook() replaces any previously registered write-ahead log callback. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-10470-30318-56877-28142-06718-49670-04430-59485
          +

          The usual rules for selecting a collation sequence with which to compare text values apply when evaluating expressions in a GROUP BY clause. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-10477-59572-35916-33197-44074-53826-19513-26308
          +

          Note that unlike that plain ROLLBACK command (without the TO keyword) the ROLLBACK TO command does not cancel the transaction. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-10484-47921-51855-29245-64644-01052-63397-23881
          +

          Views are removed with the DROP VIEW command. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-10514-25250-42695-33540-35883-31325-38548-55570
          +

          If pnCkpt is not NULL,then *pnCkpt is set to the total number of checkpointed frames in the log file (including any that were already checkpointed before the function was called) or to -1 if the checkpoint could not run due to an error or because the database is not in WAL mode. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-10543-26736-58011-26768-22566-64168-18081-13550
          +

          This API makes sure a global version of a function with a particular name and number of parameters exists. If no such function exists before this API is called, a new function is created. +(source: c3ref/overload_function.html, matrix: context, detail)

          + +
          R-10546-57588-48216-07313-35751-26470-62407-13922
          +

          When RAISE(IGNORE) is called, the remainder of the current trigger program, the statement that caused the trigger program to execute and any subsequent trigger programs that would have been executed are abandoned. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-10565-09557-60911-42161-01648-20022-48231-49571
          +

          The declared type of a column is used to determine the affinity of the column only. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-10596-27541-11253-59899-09809-63621-63871-56727
          +

          The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED_SHARED is always 0. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-10606-56585-07684-37439-38314-01521-03990-40264
          +

          If the sub-query is a compound SELECT, then all compound operators must be UNION ALL, and no terms with the subquery compound may be aggregate or DISTINCT, and every term within the subquery must have a FROM clause, and the outer query may not be an aggregate, DISTINCT query, or join. +(source: optoverview.html, matrix: context, detail)

          + +
          R-10645-12439-29307-46302-11314-15082-25631-53469
          +

          In particular, rows containing NULL values are not handled any differently from rows without NULL values. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-10703-10791-45515-33019-47657-62064-49123-04083
          +

          PRAGMA writable_schema = boolean; When this pragma is on, and the SQLITE_DBCONFIG_DEFENSIVE flag is off, then the sqlite_schema table can be changed using ordinary UPDATE, INSERT, and DELETE statements. +(source: pragma.html, checked-by: th3/req1/pragma30.test, matrix: context, detail)

          + +
          R-10715-11594-42361-64533-62693-34754-22491-52002
          +

          The round(X,Y) function returns a floating-point value X rounded to Y digits to the right of the decimal point. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-10722-45310-03105-41587-65268-38930-36590-56175
          +

          All intervening SAVEPOINTs are canceled, however. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-10734-24248-12820-36089-32208-53594-64364-42192
          +

          In other words, if many of the queries run against the FTS4 table use "ORDER BY docid DESC", then it may improve performance to add the "order=desc" option to the CREATE VIRTUAL TABLE statement. +(source: fts3.html, matrix: context, detail)

          + +
          R-10777-25114-28148-35067-60781-11341-59885-20930
          +

          Both the first and second forms of the pragma listed above return a single result row containing a single integer column - the value of the journal size limit in bytes. +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-10815-21922-06260-57655-10656-49970-23058-15520
          +

          When faced with the choice of using an index to satisfy WHERE clause constraints or satisfying an ORDER BY clause, SQLite does the same cost analysis described above and chooses the index that it believes will result in the fastest answer. +(source: optoverview.html, matrix: context, detail)

          + +
          R-10827-60271-29957-56948-24015-30184-30486-05573
          +

          If the journal mode could not be changed, the original journal mode is returned. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-10836-27632-25173-23493-20321-61178-46712-15199
          +

          The sqlite3_value_dup(V) interface makes a copy of the sqlite3_value object D and returns a pointer to that copy. +(source: c3ref/value_dup.html, matrix: context, detail)

          + +
          R-10872-35808-62525-46404-48063-22154-06728-34056
          +

          Transactions involving multiple attached databases are atomic, assuming that the main database is not ":memory:" and the journal_mode is not WAL. +(source: lang_attach.html, checked-by: th3/req1/attach02.test, th3/stress/crash002.test, th3/stress/crash003.test, matrix: context, detail)

          + +
          R-10883-17697-39247-15529-29929-13310-12082-24783
          +

          For the purposes of sorting rows, values are compared in the same way as for comparison expressions. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-10886-33090-42835-40467-38387-59487-39282-25653
          +

          When a connection (known as the blocked connection) fails to obtain a shared-cache lock and SQLITE_LOCKED is returned to the caller, the identity of the database connection (the blocking connection) that has locked the required resource is stored internally. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-10893-13770-29008-51080-40727-44407-18243-57719
          +

          On success, sqlite3_blob_read() returns SQLITE_OK. Otherwise, an error code or an extended error code is returned. +(source: c3ref/blob_read.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-10900-57544-37938-07934-32518-44927-61812-27434
          +

          The rollback journal file can be deleted +(source: fileformat2.html, matrix: context, detail)

          + +
          R-10927-26133-64625-21951-56674-25631-48081-51767
          +

          The ORDER BY clause on an UPDATE statement is used only to determine which rows fall within the LIMIT. The order in which rows are modified is arbitrary and is not influenced by the ORDER BY clause. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-10933-37470-14937-54231-03343-64899-21190-46936
          +

          The index for "?NNN" parameters is the value of NNN. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-10948-48115-30420-45129-26938-33308-29061-07454
          +

          The ADD COLUMN syntax is used to add a new column to an existing table. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-10964-23144-03179-07180-41128-15464-48410-22347
          +

          If the source database is modified by the using the same database connection as is used by the backup operation, then the backup database is automatically updated at the same time. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-10993-11647-55800-55293-06436-13332-42842-10882
          +

          It is only when the shared-memory wal-index is omitted, when the locking mode is EXCLUSIVE prior to the first WAL-mode database access, that the locking mode is stuck in EXCLUSIVE. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-11041-58701-63446-54854-64444-07239-52476-54830
          +

          In a database that uses ptrmap pages, all pages at locations identified by the computation in the previous paragraph must be ptrmap page and no other page may be a ptrmap page. Except, if the byte-lock page happens to fall on the same page number as a ptrmap page, then the ptrmap is moved to the following page for that one case. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-11061-58747-31587-59612-39335-16677-23352-15397
          +

          If N is less than 1 then a 1-byte random blob is returned. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-11062-21931-47759-21146-52801-65238-28754-37817
          +

          szPage will always a power of two. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-11071-28411-04078-07805-64978-64675-45980-20570
          +

          The specific value of a WHERE-clause parameter might influence the choice of query plan if the parameter is the left-hand side of a LIKE or GLOB operator or if the parameter is compared to an indexed column and the SQLITE_ENABLE_STAT4 compile-time option is enabled. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare04.test, matrix: context, detail)

          + +
          R-11078-03945-63030-33506-24033-34573-31697-17195
          +

          The implicit DELETE does not cause any SQL triggers to fire, but may invoke foreign key actions or constraint violations. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, th3/req1/foreignkeys22.test, matrix: context, detail)

          + +
          R-11127-09633-57185-22901-21397-40062-06184-59885
          +

          If there is an error, *ppStmt is set to NULL. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-11129-23371-40000-09444-50753-04787-03077-31414
          +

          END TRANSACTION is an alias for COMMIT. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-11135-63542-29250-48049-02589-36558-61016-54500
          +

          Expressions in an index may not reference other tables and may not use subqueries nor functions whose result might change (ex: random() or sqlite_version()). +(source: lang_createindex.html, matrix: context, detail)

          + +
          R-11148-40995-48554-02818-10393-13608-40990-18433
          +

          The memory returned by sqlite3_malloc(), sqlite3_realloc(), sqlite3_malloc64(), and sqlite3_realloc64() is always aligned to at least an 8 byte boundary, or to a 4 byte boundary if the SQLITE_4_BYTE_ALIGNED_MALLOC compile-time option is used. +(source: c3ref/free.html, checked-by: src/malloc.c, th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-11152-23456-02631-23120-19562-51052-54000-26119
          +

          The unlikely(X) function returns the argument X unchanged. +(source: lang_corefunc.html, checked-by: tcl/func3.test, matrix: context, detail)

          + +
          R-11162-32742-04957-49790-62717-44478-27100-43420
          +

          Datatype conversions in comparisons of the form "x IN (SELECT y ...)" are handled is if the comparison were really "x=y". +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-11180-04229-25067-24122-45632-49442-37161-45101
          +

          Internally, the BEGIN DEFERRED statement merely sets a flag on the database connection that turns off the automatic commit that would normally occur when the last statement finishes. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-11203-26095-47421-44988-44413-41576-06585-21050
          +

          The sqlite3_result_error() and sqlite3_result_error16() routines make a private copy of the error message text before they return. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-11211-21323-44589-16843-54908-31937-00970-23693
          +

          PRAGMA schema.freelist_count; Return the number of unused pages in the database file. +(source: pragma.html, checked-by: tcl/pragma2.test, th3/req1/pragma21.test, matrix: context, detail)

          + +
          R-11255-19907-56460-39957-30226-19999-22429-23256
          +

          The following command-line session demonstrates this: sqlite> PRAGMA foreign_keys; 0 sqlite> PRAGMA foreign_keys = ON; sqlite> PRAGMA foreign_keys; 1 sqlite> PRAGMA foreign_keys = OFF; sqlite> PRAGMA foreign_keys; 0 +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys04.test, matrix: context, detail)

          + +
          R-11278-45262-58259-06316-15595-38030-39158-45213
          +

          The P argument is a pointer to the database connection object and the X argument is unused. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-11295-04657-09653-04480-53801-04231-56338-07604
          +

          The operand to the right of the LIKE operator contains the pattern and the left hand operand contains the string to match against the pattern. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-11295-25445-59994-09653-28177-15735-56007-21495
          +

          If the S argument to sqlite3_txn_state(D,S) is not the name of a valid schema, then -1 is returned. +(source: c3ref/txn_state.html, matrix: context, detail)

          + +
          R-11315-64212-00710-49784-05093-45690-30554-02549
          +

          The default busy callback is NULL. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-11321-47427-17901-35193-41209-48737-39207-23278
          +

          Any leading spaces in the TEXT value are ignored when converging from TEXT to REAL. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-11345-24891-48483-09798-42153-35485-11277-64815
          +

          The 4-byte big-endian integer at offset 28 into the header stores the size of the database file in pages. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-11367-28935-40520-63725-29251-53752-16809-23090
          +

          The sqlite3_snapshot_get(D,S,P) interface attempts to make a new sqlite3_snapshot object that records the current state of schema S in database connection D. +(source: c3ref/snapshot_get.html, matrix: context, detail)

          + +
          R-11370-04520-26477-32393-15829-52644-05616-39032
          +

          Named parameters are also numbered. The number assigned is one greater than the largest parameter number already assigned. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-11423-52711-44857-10860-28486-08502-59467-30884
          +

          If either operand is a column, then the collating function of that column is used with precedence to the left operand. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-11464-18362-31752-52659-04390-24092-43500-36484
          +

          This ensures that the next writer will restart the log file from the beginning. +(source: c3ref/wal_checkpoint_v2.html, matrix: context, detail)

          + +
          R-11474-58635-26896-45851-63902-38678-33536-05238
          +

          Format 12 is the Julian day number expressed as an integer or floating point value. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-11479-62774-14648-38644-49524-53539-14021-51295
          +

          When comparing a base expression against a WHEN expression, the same collating sequence, affinity, and NULL-handling rules apply as if the base expression and WHEN expression are respectively the left- and right-hand operands of an = operator. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-11498-58022-52113-15294-58649-22171-38649-39142
          +

          In a well-formed b-tree page, the total number of bytes in fragments may not exceed 60. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-11549-19921-03928-49162-57832-06313-31858-02375
          +

          With synchronous=FULL in WAL mode, an additional sync operation of the WAL file happens after each transaction commit. +(source: pragma.html, matrix: context, detail)

          + +
          R-11553-06434-51801-18684-33273-42427-03932-31278
          +

          FULL This mode blocks (invokes the busy-handler callback) until there is no database writer and all readers are reading from the most recent database snapshot. It then checkpoints all frames in the log file and syncs the database file. +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-11564-19849-41478-44833-06358-20754-48496-53228
          +

          It is an error to specify both a schema-name and the TEMP keyword on a VIEW, unless the schema-name is "temp". +(source: lang_createview.html, matrix: context, detail)

          + +
          R-11566-63657-14865-04704-35153-27057-50201-14742
          +

          The 4-byte big-endian integer at offset 56 determines the encoding used for all text strings stored in the database. +(source: fileformat2.html, checked-by: th3/req1/fileformat03.test, matrix: context, detail)

          + +
          R-11576-11990-36701-63648-24289-51988-09315-26987
          +

          An attempt to invoke the BEGIN command within a transaction will fail with an error, regardless of whether the transaction was started by SAVEPOINT or a prior BEGIN. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-11620-22743-59737-64939-21707-40674-29550-48097
          +

          A colon followed by an identifier name holds a spot for a named parameter with the name :AAAA. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-11628-62147-05445-61752-17620-56103-14750-56419
          +

          No attempt is made to convert NULL or BLOB values. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-11643-51568-63953-16021-50557-65139-53423-53670
          +

          The sqlite3_preupdate_count(D) interface returns the number of columns in the row that is being inserted, updated, or deleted. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-11683-62380-30736-32552-21398-51660-49111-11348
          +

          The specified column of row iRow contains a value that is not a TEXT or BLOB value +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-11684-02844-26168-40557-28007-15193-14492-18686
          +

          The explicit COMMIT command runs immediately, even if there are pending SELECT statements. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-11730-53816-33732-41455-13175-02323-60121-55502
          +

          The compound SELECT operators UNION, INTERSECT and EXCEPT perform implicit comparisons between values. +(source: datatype3.html, checked-by: th3/req1/datatype3_07.test, matrix: context, detail)

          + +
          R-11740-30529-09837-33143-12061-13377-09078-25577
          +

          The sqlite3_db_status() routine returns SQLITE_OK on success and a non-zero error code on failure. +(source: c3ref/db_status.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-11802-27774-09561-41384-21841-59026-14543-36401
          +

          There can be an arbitrary number of sqlite_stat4 entries per index. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-11847-09179-40053-04599-51829-21779-50650-56945
          +

          1 if the index-column is sorted in reverse (DESC) order by the index and 0 otherwise. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-11856-19836-24274-28109-29706-17487-59516-28752
          +

          For example: -- Database schema CREATE TABLE artist( artistid INTEGER PRIMARY KEY, artistname TEXT ); CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER DEFAULT 0 REFERENCES artist(artistid) ON DELETE SET DEFAULT ); sqlite> SELECT * FROM artist; artistid artistname -------- ----------------- 3 Sammy Davis Jr. sqlite> SELECT * FROM track; trackid trackname trackartist ------- ----------------- ----------- 14 Mr. Bojangles 3 sqlite> -- Deleting the row from the parent table causes the child key sqlite> -- value of the dependent row to be set to integer value 0. However, this sqlite> -- value does not correspond to any row in the parent table. Therefore sqlite> -- the foreign key constraint is violated and an is exception thrown. sqlite> DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.'; SQL error: foreign key constraint failed sqlite> -- This time, the value 0 does correspond to a parent table row. And sqlite> -- so the DELETE statement does not violate the foreign key constraint sqlite> -- and no exception is thrown. sqlite> INSERT INTO artist VALUES(0, 'Unknown Artist'); sqlite> DELETE FROM artist WHERE artistname = 'Sammy Davis Jr.'; sqlite> SELECT * FROM artist; artistid artistname -------- ----------------- 0 Unknown Artist sqlite> SELECT * FROM track; trackid trackname trackartist ------- ----------------- ----------- 14 Mr. Bojangles 0 +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys18.test, matrix: context, detail)

          + +
          R-11896-08162-39829-09724-10165-05972-28450-60411
          +

          The "none" setting means that auto-vacuum is disabled. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-11920-30904-34388-20276-30838-60938-49360-56760
          +

          If the result is NULL, then sqlite3_column_bytes16() returns zero. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-11967-56545-48759-50416-31335-06796-11719-37759
          +

          The highwater mark is always 0. +(source: c3ref/c_dbstatus_options.html, checked-by: src/status.c, matrix: context, detail)

          + +
          R-11975-28707-46522-06276-23691-04065-63160-37521
          +

          The third and fourth parameters to this routine are passed directly through to the second and third parameters of the xFileControl method. +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-11976-23534-61150-43568-11270-52721-42271-48852
          +

          If page B is a ptrmap page then back-link information about page B+1 is provided by the first entry on the pointer map. Information about page B+2 is provided by the second entry. And so forth. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-11990-19596-61905-61628-16888-24987-31493-40559
          +

          julianday(time-value, modifier, modifier, ...) +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-12026-28971-38060-63152-02914-42384-21788-39705
          +

          The "double" variable pointed to by the V parameter will be set to the query planner's estimate for the average number of rows output from each iteration of the X-th loop. +(source: c3ref/c_scanstat_est.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-12079-51392-32585-64897-55283-05837-03077-12925
          +

          When text data is inserted into a NUMERIC column, the storage class of the text is converted to INTEGER or REAL (in order of preference) if the text is a well-formed integer or real literal, respectively. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-12104-35971-65257-58163-03125-32650-03522-02366
          +

          If no ROWID is specified on the insert, or if the specified ROWID has a value of NULL, then an appropriate ROWID is created automatically. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-12123-54095-45651-21328-13666-03690-37485-08653
          +

          The table-name specified as part of an UPDATE statement within a trigger body must be unqualified. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-12168-36613-28272-64664-28588-05948-62910-42845
          +

          Freelist leaf pages bear no information that would need to be restored on a rollback and so they are not written to the journal prior to modification, in order to reduce disk I/O. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-12183-43719-06718-33366-17178-17275-22858-03286
          +

          Table columns that do not appear in the column list are populated with the default column value (specified as part of the CREATE TABLE statement), or with NULL if no default value is specified. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-12196-28473-08182-34058-05586-50846-36474-32114
          +

          Note that calling sqlite3_busy_timeout() or evaluating PRAGMA busy_timeout=N will change the busy handler and thus clear any previously set busy handler. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-12218-18073-29146-37627-08161-54063-61072-19112
          +

          A VACUUM will fail if there is an open transaction on the database connection that is attempting to run the VACUUM. +(source: lang_vacuum.html, checked-by: src/vacuum.c, tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-12238-55120-28128-47311-07751-08633-28104-35625
          +

          Whenever a PRAGMA statement is parsed, an SQLITE_FCNTL_PRAGMA file control is sent to the open sqlite3_file object corresponding to the database file to which the pragma statement refers. +(source: c3ref/c_fcntl_begin_atomic_write.html, checked-by: src/pragma.c, tcl/multiplex4.test, matrix: context, detail)

          + +
          R-12259-19638-21315-58129-32389-49540-45137-32104
          +

          A VALUES clause cannot be followed by LIMIT. +(source: lang_select.html, checked-by: th3/req1/select02.test, matrix: context, detail)

          + +
          R-12275-20298-47772-56757-15778-39462-64033-34126
          +

          In other words, the schema-name. prefix on the table name is not allowed within triggers. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-12314-13901-08300-54236-37161-34051-04965-51279
          +

          Division by zero gives a result of NULL. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-12374-37755-19006-43319-29109-21110-40176-02153
          +

          The locking-mode is either NORMAL or EXCLUSIVE. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-12385-29357-06321-01436-47924-30729-53833-26197
          +

          If any of the sqlite3_bind_*() routines are called with a NULL pointer for the prepared statement or with a prepared statement for which sqlite3_step() has been called more recently than sqlite3_reset(), then the call will return SQLITE_MISUSE. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-12410-31217-15113-45152-04874-52421-25880-35478
          +

          This mode works the same way as SQLITE_CHECKPOINT_FULL with the addition that after checkpointing the log file it blocks (calls the busy-handler callback) until all readers are reading from the database file only. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-12452-54941-39354-45567-09766-62540-46508-43420
          +

          Note that case insensitivity only applies to latin1 characters - basically the upper and lower case letters of English in the lower 127 byte codes of ASCII. +(source: optoverview.html, checked-by: th3/cov1/pragma02.test, matrix: context, detail)

          + +
          R-12482-18070-30469-35511-31025-38188-23401-30246
          +

          Extension loading must be enabled using sqlite3_enable_load_extension() or sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,1,NULL) prior to calling this API, otherwise an error will be returned. +(source: c3ref/load_extension.html, matrix: context, detail)

          + +
          R-12507-28763-48132-30913-24133-27495-38799-45736
          +

          PRAGMA foreign_key_list(table-name); This pragma returns one row for each foreign key constraint created by a REFERENCES clause in the CREATE TABLE statement of table "table-name". +(source: pragma.html, checked-by: th3/req1/pragma17.test, matrix: context, detail)

          + +
          R-12525-60165-32842-37850-04403-38425-48242-20323
          +

          In every case the first argument is a pointer to the prepared statement that is being evaluated (the sqlite3_stmt* that was returned from sqlite3_prepare_v2() or one of its variants) and the second argument is the index of the column for which information should be returned. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, th3/req1/column02.test, th3/req1/column03.test, matrix: context, detail)

          + +
          R-12526-56546-27211-20254-24569-61288-04911-18504
          +

          When auto-vacuum is disabled and data is deleted data from a database, the database file remains the same size. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-12527-00403-29905-17103-05546-05821-61371-29057
          +

          If a NOT NULL constraint violation occurs, the REPLACE conflict resolution replaces the NULL value with the default value for that column, or if the column has no default value, then the ABORT algorithm is used. +(source: lang_conflict.html, checked-by: th3/req1/conflict02.test, matrix: context, detail)

          + +
          R-12556-35327-19465-37938-14363-50325-55527-10605
          +

          The rollback hook is invoked on a rollback that results from a commit hook returning non-zero, just as it would be with any other rollback. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-12572-62501-53672-53219-61722-28742-24509-13424
          +

          If the default value of the column is a constant NULL, text, blob or signed-number value, then that value is used directly in the new row. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-12576-53774-15482-62453-08322-32739-63345-41890
          +

          The byte-order specified by the BOM at the beginning of the text overrides the byte-order specified by the interface procedure. +(source: c3ref/result_blob.html, matrix: context, detail)

          + +
          R-12597-09253-01914-52695-40165-57043-34342-03657
          +

          If no WHEN clause is supplied, the SQL statements are executed every time the trigger fires. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-12598-40983-37822-03408-00608-51890-59841-03948
          +

          The values returned by sqlite3_column_bytes() and sqlite3_column_bytes16() do not include the zero terminators at the end of the string. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-12600-09115-43578-46772-34145-03685-53603-16884
          +

          This option is used to enable or disable views. +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/cov1/view02.test, matrix: context, detail)

          + +
          R-12600-63516-31676-50915-37777-55444-55354-15121
          +

          The cache sharing mode set by this interface effects all subsequent calls to sqlite3_open(), sqlite3_open_v2(), and sqlite3_open16(). Existing database connections continue to use the sharing mode that was in effect at the time they were opened. +(source: c3ref/enable_shared_cache.html, matrix: context, detail)

          + +
          R-12621-54688-01749-38007-62215-41521-15622-18085
          +

          The order of the entries indicates the nesting order. +(source: eqp.html, matrix: context, detail)

          + +
          R-12628-51384-03932-15263-35503-59702-54474-35956
          +

          For example, 0x1234 means the same as 4660 and 0x8000000000000000 means the same as -9223372036854775808. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-12643-30541-59599-14693-16305-56231-57085-12905
          +

          The incremental blob I/O mechanism does not work for WITHOUT ROWID tables. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-12645-39772-05350-58220-21808-12776-02132-01190
          +

          Or, if a constraint definition does not include a conflict-clause or it is a CHECK constraint, the default conflict resolution algorithm is ABORT. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-12670-39947-34778-58945-43914-57818-35055-57037
          +

          Again, in this case the call to sqlite3_backup_step() can be retried later on. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-12693-31159-47760-14933-14712-45041-12329-60921
          +

          Each SCAN or SEARCH record includes the following information: The name of the table data is read from. Whether or not an index or automatic index is used. Whether or not the covering index optimization applies. Which terms of the WHERE clause are used for indexing. +(source: eqp.html, matrix: context, detail)

          + +
          R-12720-41494-41537-21978-20786-40223-25082-25767
          +

          Mathematical operators (+, -, *, /, %, <<, >>, &, and |) interpret both operands as if they were numbers. STRING or BLOB operands automatically convert into REAL or INTEGER values. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-12722-60883-17939-30379-04776-48495-16635-34994
          +

          The P argument is a pointer to the prepared statement and the X argument points to a 64-bit integer which is the estimated of the number of nanosecond that the prepared statement took to run. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-12723-08526-08318-37597-13416-02611-20506-59607
          +

          SQLITE_LIMIT_EXPR_DEPTH The maximum depth of the parse tree on any expression. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-12747-43999-37880-44715-10819-05870-41962-30541
          +

          A VALUES clause cannot be followed by ORDER BY. +(source: lang_select.html, checked-by: th3/req1/select02.test, matrix: context, detail)

          + +
          R-12776-45508-06202-05323-21053-40693-38134-61393
          +

          If the argument to sign(X) is NULL or is a string or blob that cannot be losslessly converted into a number, then sign(X) return NULL. +(source: lang_corefunc.html, matrix: context, detail)

          + +
          R-12782-61841-54063-57500-26369-54791-20214-34360
          +

          To mark a foreign key constraint as deferred, its declaration must include the following clause: DEFERRABLE INITIALLY DEFERRED -- A deferred foreign key constraint +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, matrix: context, detail)

          + +
          R-12786-00766-63482-41386-10445-23868-47532-37384
          +

          The full amount of memory used by the schemas is reported, even if the schema memory is shared with other database connections due to shared cache mode being enabled. +(source: c3ref/c_dbstatus_options.html, checked-by: th3/req1/dbstatus02.test, matrix: context, detail)

          + +
          R-12793-43283-00395-32420-06808-58269-41877-63577
          +

          Every value in SQLite has one of five fundamental datatypes: 64-bit signed integer 64-bit IEEE floating point number string BLOB NULL +(source: c3ref/c_blob.html, checked-by: src/vdbeapi.c, tcl/capi3.test, th3/req1/column01.test, matrix: context, detail)

          + +
          R-12804-26213-16166-58523-53387-54270-64862-30854
          +

          The highest recorded value is returned in *pHighwater. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-12830-59321-61911-43156-38228-08390-44545-62549
          +

          The RELEASE command starts with the most recent addition to the transaction stack and releases savepoints backwards in time until it releases a savepoint with a matching savepoint-name. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-12831-20703-43607-22542-46423-65070-13678-01417
          +

          The query string consists of text following the first "?" character but excluding the optional fragment that begins with "#". +(source: uri.html, matrix: context, detail)

          + +
          R-12881-55998-05997-62769-52407-41437-37652-18188
          +

          When query results are sorted by an ORDER BY clause, values with storage class NULL come first, followed by INTEGER and REAL values interspersed in numeric order, followed by TEXT values in collating sequence order, and finally BLOB values in memcmp() order. +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-12895-64156-28673-05493-20672-24033-21713-05965
          +

          Inner joins to the left and right of the outer join might be reordered if the optimizer thinks that is advantageous but the outer joins are always evaluated in the order in which they occur. +(source: optoverview.html, matrix: context, detail)

          + +
          R-12940-37052-20666-01661-57871-26003-21807-26945
          +

          SQLITE_LIMIT_LIKE_PATTERN_LENGTH The maximum length of the pattern argument to the LIKE or GLOB operators. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-12976-22893-11163-42545-13145-11346-20238-07010
          +

          Value is the integer 0. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-12993-07777-64601-19102-35955-36137-03402-56962
          +

          When multiple implementations of the same function are available, SQLite will pick the one that involves the least amount of data conversion. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-13024-05443-37707-54511-29409-48512-10836-53316
          +

          Unrecognized arguments are silently ignored. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-13053-11096-22952-42489-44628-35475-18449-44243
          +

          The maximum value is the value that would be returned last in an ORDER BY on the same column. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-13057-33448-09671-56974-58075-51862-56508-46386
          +

          The number of columns in an index is limited to the value set by sqlite3_limit(SQLITE_LIMIT_COLUMN,...). +(source: lang_createindex.html, checked-by: th3/req1/createidx03.test, matrix: context, detail)

          + +
          R-13091-00020-15519-35390-14824-01225-60609-32585
          +

          Note that the authorizer callback is invoked only during sqlite3_prepare() or its variants. +(source: c3ref/set_authorizer.html, matrix: context, detail)

          + +
          R-13116-43655-17420-11723-30506-15977-20565-12123
          +

          The RETURNING clause only returns rows that are directly modified by the DELETE, INSERT, or UPDATE statement. +(source: lang_returning.html, checked-by: th3/cov1/returning04.test, matrix: context, detail)

          + +
          R-13160-27901-08319-02808-35967-30729-30833-45529
          +

          A function where the encoding difference is between UTF16le and UTF16be is a closer match than a function where the encoding difference is between UTF8 and UTF16. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-13161-58512-18507-02027-33184-52817-40400-65254
          +

          The subquery and the outer query do not both have ORDER BY clauses. +(source: optoverview.html, matrix: context, detail)

          + +
          R-13164-16564-32961-63761-40355-01269-15862-60679
          +

          Otherwise, if no error occurs, sqlite3_db_cacheflush() returns SQLITE_OK. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-13183-30817-63475-03286-24149-37029-58658-28178
          +

          Parameters of the form "?" without a following integer have no name and are referred to as "nameless" or "anonymous parameters". +(source: c3ref/bind_parameter_name.html, checked-by: th3/req1/bind04.test, matrix: context, detail)

          + +
          R-13199-64588-45721-29417-06985-29231-64898-26576
          +

          No error is returned for uniqueness, NOT NULL, and UNIQUE constraint errors when the IGNORE conflict resolution algorithm is used. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-13210-09522-30167-47682-54328-15503-65010-64185
          +

          Each entry in the table b-tree corresponds to a row of the SQL table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-13245-13613-20612-29669-51853-01593-36495-38547
          +

          SQLITE_BUSY means that the database engine was unable to acquire the database locks it needs to do its job. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-13279-06508-34532-04763-41016-09422-12015-14257
          +

          This interface returns a pointer to the next prepared statement after pStmt associated with the database connection pDb. +(source: c3ref/next_stmt.html, checked-by: th3/cov1/vdbeapi04.test, matrix: context, detail)

          + +
          R-13288-53765-24256-39621-08967-42078-48057-53348
          +

          A false return does not guarantee that the statement will change the database file. +(source: c3ref/stmt_readonly.html, matrix: context, detail)

          + +
          R-13307-42286-48132-20191-27230-43917-16761-31093
          +

          The sqlite3_memory_used() routine returns the number of bytes of memory currently outstanding (malloced but not freed). +(source: c3ref/memory_highwater.html, matrix: context, detail)

          + +
          R-13324-20915-18608-14135-49913-18477-24470-37665
          +

          When two BLOB values are compared, the result is determined using memcmp(). +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-13337-13961-14137-09012-22007-31627-17736-61931
          +

          If Z is negative then the abs(Z) characters preceding the Y-th character are returned. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-13345-31830-42625-35192-25815-10226-10074-63536
          +

          The escape character followed by a percent symbol (%), underscore (_), or a second instance of the escape character itself matches a literal percent symbol, underscore, or a single escape character, respectively. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-13381-51663-43618-16606-57611-35526-29566-64189
          +

          PRAGMA pragma_list; This pragma returns a list of PRAGMA commands known to the database connection. +(source: pragma.html, matrix: context, detail)

          + +
          R-13435-26311-61176-01189-39199-58705-21930-17615
          +

          Usually, the parent key of a foreign key constraint is the primary key of the parent table. If they are not the primary key, then the parent key columns must be collectively subject to a UNIQUE constraint or have a UNIQUE index. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-13439-14752-32196-09382-64767-42844-00603-31803
          +

          The CREATE VIEW command assigns a name to a pre-packaged SELECT statement. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-13480-46087-00976-25355-37821-19976-64055-41594
          +

          The sqlite3_data_count(P) will return non-zero if previous call to sqlite3_step(P) returned SQLITE_ROW, except in the case of the PRAGMA incremental_vacuum where it always returns zero since each step of that multi-step pragma returns 0 columns of data. +(source: c3ref/data_count.html, checked-by: th3/req1/datacnt01.test, matrix: context, detail)

          + +
          R-13512-64012-34604-11605-36367-14798-29892-18682
          +

          In a compound SELECT, only the last or right-most simple SELECT may contain a LIMIT clause. +(source: lang_select.html, checked-by: tcl/limit.test, th3/req1/select02.test, matrix: context, detail)

          + +
          R-13523-04394-10297-34543-39920-38715-25686-62539
          +

          The second integer on a freelist trunk page is the number of leaf page pointers to follow. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-13543-33261-54186-53828-50711-48001-20973-48866
          +

          A new R*Tree index is created as follows: CREATE VIRTUAL TABLE USING rtree(); The is the name your application chooses for the R*Tree index and is a comma separated list of between 3 and 11 columns. The virtual table creates three shadow tables to actually store its content. The names of these shadow tables are: _node _rowid _parent The shadow tables are ordinary SQLite data tables. You can query them directly if you like, though this unlikely to reveal anything particularly useful. And you can UPDATE, DELETE, INSERT or even DROP the shadow tables, though doing so will corrupt your R*Tree index. So it is best to simply ignore the shadow tables. Recognize that they hold your R*Tree index information and let it go as that. As an example, consider creating a two-dimensional R*Tree index for use in spatial queries: CREATE VIRTUAL TABLE demo_index USING rtree( id, -- Integer primary key minX, maxX, -- Minimum and maximum X coordinate minY, maxY -- Minimum and maximum Y coordinate ); 3.1.1. Column naming details In the argments to "rtree" in the CREATE VIRTUAL TABLE statement, the names of the columns are taken from the first token of each argument. All subsequent tokens within each argument are silently ignored. +(source: rtree.html, matrix: context, detail)

          + +
          R-13547-45635-56676-46930-62295-21423-36076-50678
          +

          The default isolation level for SQLite is SERIALIZABLE. +(source: pragma.html, matrix: context, detail)

          + +
          R-13549-01731-45628-33361-33638-05320-24749-58227
          +

          When immutable is set, SQLite assumes that the database file cannot be changed, even by a process with higher privilege, and so the database is opened read-only and all locking and change detection is disabled. +(source: c3ref/open.html, checked-by: th3/cov1/nolock01.test, matrix: context, detail)

          + +
          R-13561-46814-58902-48141-34775-52925-09120-28270
          +

          The sqlite3_result_text(), sqlite3_result_text16(), sqlite3_result_text16le(), and sqlite3_result_text16be() interfaces set the return value of the application-defined function to be a text string which is represented as UTF-8, UTF-16 native byte order, UTF-16 little endian, or UTF-16 big endian, respectively. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-13591-51789-59523-18205-42201-39107-10748-36836
          +

          Newer versions of SQLite use the in-header database size if it is available but fall back to the actual file size if the in-header database size is not valid. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-13595-45863-41975-17982-37007-43143-15451-31635
          +

          Note that SQLite allows the parenthesized list of scalar values on the right-hand side of an IN or NOT IN operator to be an empty list but most other SQL database database engines and the SQL92 standard require the list to contain at least one element. +(source: lang_expr.html, checked-by: tcl/tkt-80e031a00f.test, matrix: context, detail)

          + +
          R-13615-19528-18270-26667-29979-02127-30381-22829
          +

          A 3-dimensional R*Tree has 7 columns. +(source: rtree.html, matrix: context, detail)

          + +
          R-13635-51078-58575-05686-24588-25758-48639-24635
          +

          Missing values at the end of the record are filled in using the default value for the corresponding columns defined in the table schema. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-13680-39071-55665-32597-06847-40698-32535-24028
          +

          The file change counter is a 4-byte big-endian integer at offset 24 that is incremented whenever the database file is unlocked after having been modified. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-13748-40725-63284-41855-27070-22763-27401-30101
          +

          The current value of the requested counter is returned. +(source: c3ref/stmt_status.html, matrix: context, detail)

          + +
          R-13776-21310-53568-57098-48778-28371-47670-31301
          +

          The count(*) function (with no arguments) returns the total number of rows in the group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-13779-07711-12405-44335-29719-17285-28240-52263
          +

          As long as exactly one connection is using a shared-memory wal-index, the locking mode can be changed freely between NORMAL and EXCLUSIVE. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-13793-11620-18643-36656-33877-44501-53404-27731
          +

          For clarity: the values returned by sqlite3_column_bytes() and sqlite3_column_bytes16() are the number of bytes in the string, not the number of characters. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-13829-63101-23800-05196-00308-40723-07917-23521
          +

          The sqlite_schema.sql column stores SQL text that describes the object. This SQL text is a CREATE TABLE, CREATE VIRTUAL TABLE, CREATE INDEX, CREATE VIEW, or CREATE TRIGGER statement that if evaluated against the database file when it is the main database of a database connection would recreate the object. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-13846-35797-43647-43739-38644-55287-36020-16236
          +

          The random() function returns a pseudo-random integer between -9223372036854775808 and +9223372036854775807. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-13861-56665-11866-23865-35263-00368-63176-40609
          +

          PRAGMA schema.cache_size; PRAGMA schema.cache_size = pages; PRAGMA schema.cache_size = -kibibytes; Query or change the suggested maximum number of database disk pages that SQLite will hold in memory at once per open database file. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-13870-45783-04772-14716-53904-46370-14954-15973
          +

          The sqlite3_load_extension() interface attempts to load an SQLite extension library contained in the file zFile. +(source: c3ref/load_extension.html, matrix: context, detail)

          + +
          R-13876-13274-06329-28290-52708-34927-05709-26395
          +

          If foreign key constraints are enabled and a column with a REFERENCES clause is added, the column must have a default value of NULL. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-13877-64542-39833-15687-62784-10394-38782-49019
          +

          For an "ON UPDATE CASCADE" action, it means that the values stored in each dependent child key are modified to match the new parent key values. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-13903-46567-21188-22822-60227-64496-63410-06513
          +

          This means that when VACUUMing a database, as much as twice the size of the original database file is required in free disk space. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-13943-13592-05756-02149-18071-59821-47409-19193
          +

          A NULL result is considered untrue when evaluating WHEN terms. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-13958-53419-49614-06664-47934-29028-23296-04281
          +

          Supported unary prefix operators are these: - + ~ NOT +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-13981-28768-38524-42691-40554-58455-18349-16495
          +

          And a 5-dimensional R*Tree has 11 columns. +(source: rtree.html, matrix: context, detail)

          + +
          R-13991-38016-24642-53092-34129-28214-25020-08984
          +

          A SELECT statement will always have a positive sqlite3_column_count() but depending on the WHERE clause constraints and the table content, it might return no rows. +(source: c3ref/column_count.html, matrix: context, detail)

          + +
          R-14014-59687-26564-37068-45971-48448-09846-38995
          +

          No affinity is applied to comparison operands for the implicit comparisons associated with UNION, INTERSECT, or EXCEPT - the values are compared as is. +(source: datatype3.html, checked-by: th3/req1/datatype3_07.test, matrix: context, detail)

          + +
          R-14034-00929-27099-16044-59671-40921-25544-35067
          +

          If an error code is returned, that error will propagate back up through the SQLite code base to cause the statement that provoked the callback to report an error, though the commit will have still occurred. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-14054-28168-18904-50700-49610-53857-56121-06395
          +

          The special encoding rules for columns with REAL affinity apply to WITHOUT ROWID tables the same as they do with rowid tables. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-14068-49671-08903-14280-45288-40590-58798-59213
          +

          Parameters that are not assigned values using sqlite3_bind() are treated as NULL. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-14099-28081-41654-53120-44875-00301-46355-06140
          +

          If the commit hook returns non-zero, then the COMMIT is converted into a ROLLBACK. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-14168-07579-40145-07578-27946-11279-56601-46509
          +

          If there is no ELSE expression and none of the WHEN expressions are true, then the overall result is NULL. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-14174-63475-36300-18663-27828-32664-44187-42924
          +

          If any other error occurs while flushing dirty pages to disk (for example an IO error or out-of-memory condition), then processing is abandoned and an SQLite error code is returned to the caller immediately. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-14184-13732-63564-17158-02009-26231-20937-39061
          +

          The SQLITE_FCNTL_FILE_POINTER value for the op parameter causes a pointer to the underlying sqlite3_file object to be written into the space pointed to by the 4th parameter. +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-14195-12074-64677-06793-17072-43123-33020-17925
          +

          PRAGMA recursive_triggers; PRAGMA recursive_triggers = boolean; Query, set, or clear the recursive trigger capability. +(source: pragma.html, matrix: context, detail)

          + +
          R-14208-23986-02817-62350-58798-64603-05852-18001
          +

          If foreign key constraints are enabled when it is prepared, the DROP TABLE command performs an implicit DELETE to remove all rows from the table before dropping it. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, th3/req1/foreignkeys22.test, matrix: context, detail)

          + +
          R-14213-41276-38760-54552-34093-20752-64281-40652
          +

          If the function pointer is NULL, the sqlite3_log() interface becomes a no-op. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/log01.test, matrix: context, detail)

          + +
          R-14222-20715-36794-58646-49579-04398-47433-20385
          +

          Any attempt to create a function with a longer name will result in SQLITE_MISUSE being returned. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, matrix: context, detail)

          + +
          R-14302-38934-55936-51388-09326-06316-22131-13547
          +

          The new column may take any of the forms permissible in a CREATE TABLE statement, with the following restrictions: +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-14303-42483-31616-40850-13979-44263-42291-56182
          +

          If database zDb is the name of an attached database that is not in WAL mode, SQLITE_OK is returned and both *pnLog and *pnCkpt set to -1. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-14310-64553-52878-24653-31344-14066-48757-18483
          +

          1 if the index-column is a key column and 0 if the index-column is an auxiliary column. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-14349-34154-22313-18444-03285-54966-26711-64366
          +

          Note that the order of the rules for determining column affinity is important. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-14350-06824-15886-23716-53356-08607-64991-22845
          +

          If write-ahead log mode is disabled, this pragma is a harmless no-op. +(source: pragma.html, checked-by: th3/req1/pragma29.test, matrix: context, detail)

          + +
          R-14350-55458-23472-59439-25847-10170-60896-21467
          +

          If no successful INSERTs into rowid tables have ever occurred on the database connection D, then sqlite3_last_insert_rowid(D) returns zero. +(source: c3ref/last_insert_rowid.html, checked-by: th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-14374-42468-63596-09513-53214-31321-61248-26314
          +

          This option sets the threading mode to Multi-thread. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-14413-31567-12478-15952-22976-18615-46799-38246
          +

          The schema of the sqlite_stat1 table is as follows: CREATE TABLE sqlite_stat1(tbl,idx,stat); +(source: fileformat2.html, matrix: context, detail)

          + +
          R-14428-50133-01194-47236-05116-05687-25228-52456
          +

          The sqlite3_reset(S) interface resets the prepared statement S back to the beginning of its program. +(source: c3ref/reset.html, checked-by: th3/req1/reset01.test, matrix: context, detail)

          + +
          R-14442-41305-19421-12764-11199-11923-26443-20423
          +

          If the simple SELECT is a SELECT DISTINCT, then duplicate rows are removed from the set of result rows before it is returned. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-14450-37597-62750-52193-20411-23547-30776-32199
          +

          If SQLite is compiled with the SQLITE_THREADSAFE=0 compile-time option then the entire mutexing subsystem is omitted from the build and hence calls to sqlite3_config() with the SQLITE_CONFIG_GETMUTEX configuration option will return SQLITE_ERROR. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-14451-19951-27480-60238-09584-48372-64711-58964
          +

          If N is zero then memory mapped I/O is disabled. +(source: pragma.html, matrix: context, detail)

          + +
          R-14480-10586-37418-24498-17324-51005-09457-09815
          +

          All five date and time functions take a time value as an argument. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-14505-63184-58138-52966-27681-02252-30754-64236
          +

          An INTEGER or REAL value is less than any TEXT or BLOB value. +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-14522-26183-36808-38782-13052-12335-19619-11308
          +

          The sqlite3_uint64 and sqlite_uint64 types can store integer values between 0 and +18446744073709551615 inclusive. +(source: c3ref/int64.html, checked-by: th3/req1/int64_01.test, matrix: context, detail)

          + +
          R-14553-34013-61751-37329-34569-35054-62588-04416
          +

          the complete database schema for efficient implementation of the foreign key constraint might be: CREATE TABLE artist( artistid INTEGER PRIMARY KEY, artistname TEXT ); CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER REFERENCES artist ); CREATE INDEX trackindex ON track(trackartist); +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys09.test, matrix: context, detail)

          + +
          R-14560-62209-22846-15269-26800-65188-24586-57276
          +

          The sqlite3_blob_bytes() interface returns the size of the BLOB in bytes. +(source: c3ref/blob.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-14606-31564-30448-03385-20591-46329-55460-01385
          +

          Value is a BLOB that is (N-12)/2 bytes in length. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-14672-19530-25387-57734-27624-49837-27929-41109
          +

          This is the number of rows inserted into transient indices that were created automatically in order to help joins run faster. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-14696-55973-19769-03431-09296-22447-01636-28484
          +

          PRAGMA schema.table_xinfo(table-name); This pragma returns one row for each column in the named table, including hidden columns in virtual tables. +(source: pragma.html, matrix: context, detail)

          + +
          R-14708-27487-63029-62326-38556-29353-26608-43462
          +

          If either X or Y are NULL in instr(X,Y) then the result is NULL. +(source: lang_corefunc.html, checked-by: tcl/instr.test, matrix: context, detail)

          + +
          R-14744-61161-64598-20723-40374-11950-32585-46634
          +

          Bindings are not cleared by the sqlite3_reset() routine. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-14755-58619-21710-46731-49779-58295-52088-49443
          +

          If a schema name is specified, then only that one schema is searched for the named object. +(source: lang_naming.html, checked-by: tcl/e_resolve.test, matrix: context, detail)

          + +
          R-14786-64066-57173-54332-48842-61932-26767-55226
          +

          The fourth parameter to the preupdate callback is the name of the database within the database connection that is being modified. This will be "main" for the main database or "temp" for TEMP tables or the name given after the AS keyword in the ATTACH statement for attached databases. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-14809-12532-29849-37931-55866-36288-34668-62105
          +

          Every column of every table has an associated collating function. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-14816-14138-45914-00386-55030-19688-47427-16370
          +

          The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt to enter a mutex. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-14854-58090-42318-16758-11511-55845-43125-55221
          +

          The xShutdown method is only called from sqlite3_shutdown() so it does not need to be threadsafe either. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-14875-52970-09502-55318-65489-30403-63848-22858
          +

          The last_insert_rowid() function returns the ROWID of the last row insert from the database connection which invoked the function. +(source: lang_corefunc.html, checked-by: th3/req1/func01.test, matrix: context, detail)

          + +
          R-14902-14650-01699-08626-33973-09336-38963-61808
          +

          Generated columns can have a datatype. +(source: gencol.html, matrix: context, detail)

          + +
          R-14926-50129-46614-17358-58969-23562-31943-57141
          +

          For the purposes of grouping rows, NULL values are considered equal. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-14928-00869-49295-06828-40495-44673-44350-58207
          +

          The soft heap limit is automatically enabled whenever the hard heap limit is enabled. +(source: c3ref/hard_heap_limit64.html, matrix: context, detail)

          + +
          R-14939-58295-46667-49876-44919-10267-12133-09440
          +

          For indexes on WITHOUT ROWID tables, N will be the number of columns indexed plus the number of columns in the primary key. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-14970-42377-34844-46496-15895-42662-06341-12505
          +

          If this flag is set, then the F_FULLFSYNC syncing method is used during checkpoint operations on systems that support F_FULLFSYNC. +(source: pragma.html, checked-by: th3/req1/pragma11.test, matrix: context, detail)

          + +
          R-15060-13876-27196-24328-29262-37207-52735-33647
          +

          A 1-dimensional R*Tree thus has 3 columns. +(source: rtree.html, matrix: context, detail)

          + +
          R-15063-51342-39351-23162-57397-34240-32875-44138
          +

          A zero is returned if no matching parameter is found. +(source: c3ref/bind_parameter_index.html, checked-by: th3/req1/bind03.test, matrix: context, detail)

          + +
          R-15067-52851-39310-09608-48928-40262-32010-41531
          +

          The registration remains valid until it is replaced by a different module or until the database connection closes. +(source: c3ref/module.html, matrix: context, detail)

          + +
          R-15078-25200-47597-45134-52626-09709-11803-57181
          +

          However, if an insert fails due to (for example) a uniqueness constraint, the ROWID of the failed insertion attempt might not be reused on subsequent inserts, resulting in gaps in the ROWID sequence. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-15107-48632-28569-47708-49546-63224-06623-07526
          +

          The authorizer callback is invoked as SQL statements are being compiled by sqlite3_prepare() or its variants sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16(), sqlite3_prepare16_v2(), and sqlite3_prepare16_v3(). +(source: c3ref/set_authorizer.html, matrix: context, detail)

          + +
          R-15111-17896-62926-21896-36187-36992-24278-56286
          +

          Numeric values (serial types 1 through 9) sort after NULLs and in numeric order. +(source: fileformat2.html, checked-by: th3/req1/fileformat05.test, matrix: context, detail)

          + +
          R-15162-34851-63939-05950-21084-00823-32030-36120
          +

          If the 5th parameter to sqlite3_exec() is not NULL then any error message is written into memory obtained from sqlite3_malloc() and passed back through the 5th parameter. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-15172-56782-14433-51557-38019-58913-08243-11771
          +

          The returned value is one of SQLITE_INTEGER, SQLITE_FLOAT, SQLITE_TEXT, SQLITE_BLOB, or SQLITE_NULL. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-15179-00775-17006-23705-43111-64529-05716-35122
          +

          The N-th integer (for N>1) is the estimated average number of rows in the index which have the same value for the first N-1 columns. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-15195-28467-04090-15133-31201-08580-44070-48072
          +

          A RETURNING clause for an UPSERT reports both inserted and updated rows. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-15250-32031-29902-43107-55645-15949-41885-09210
          +

          The solution to enforcing one leader per team is to create a unique index on team_id but restricted to those entries for which is_team_leader is true: CREATE UNIQUE INDEX team_leader ON person(team_id) WHERE is_team_leader; +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-15264-45364-33795-29086-26475-46082-16234-09444
          +

          For the purposes of this routine, an INSERT is considered to be successful even if it is subsequently rolled back. +(source: c3ref/last_insert_rowid.html, matrix: context, detail)

          + +
          R-15279-42727-36622-43533-51632-55419-55302-44871
          +

          Virtual tables methods can set an error message by assigning a string obtained from sqlite3_mprintf() to zErrMsg. +(source: c3ref/vtab.html, checked-by: th3/req1/vtab01.test, matrix: context, detail)

          + +
          R-15283-49521-12983-52199-46141-26319-45151-22196
          +

          If the table has never before contained any data, then a ROWID of 1 is used. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-15313-19540-00987-59181-43377-13803-46289-24513
          +

          The name for the collating sequence used to compare values in the index-column. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-15326-32258-55998-27349-46389-10665-40357-65139
          +

          When multiple database connections share the same cache, changing the secure-delete flag on one database connection changes it for them all. +(source: pragma.html, checked-by: th3/cov1/pragma21.test, matrix: context, detail)

          + +
          R-15331-08345-58118-19144-46490-41902-30698-42442
          +

          The second parameter to the logger function is a copy of the first parameter to the corresponding sqlite3_log() call and is intended to be a result code or an extended result code. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/log01.test, matrix: context, detail)

          + +
          R-15334-58407-28961-30248-32119-35017-40136-56612
          +

          A column that uses INTEGER affinity behaves the same as a column with NUMERIC affinity. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-15356-65223-28934-39981-61264-10821-14188-49484
          +

          SQLite does not use the lock-byte page. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-15363-55230-31292-18565-56039-36923-37219-31589
          +

          If the default value of a column is CURRENT_TIME, CURRENT_DATE or CURRENT_TIMESTAMP, then the value used in the new row is a text representation of the current UTC date and/or time. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-15400-09401-11917-03904-29330-15741-54444-34897
          +

          A keyword enclosed in square brackets is an identifier. +(source: lang_keywords.html, checked-by: th3/req1/keyword01.test, matrix: context, detail)

          + +
          R-15402-03103-21390-36962-23389-49198-06887-52060
          +

          PRAGMA schema.foreign_key_check; PRAGMA schema.foreign_key_check(table-name); +(source: pragma.html, checked-by: tcl/fkey5.test, th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-15417-28014-30557-42534-17582-00197-65121-60035
          +

          Indices are not required for child key columns +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-15442-09728-53714-13219-50103-51559-23392-54573
          +

          Furthermore, the data_store_directory pragma always assumes that any string that this variable points to is held in memory obtained from sqlite3_malloc and the pragma may attempt to free that memory using sqlite3_free. +(source: c3ref/data_directory.html, matrix: context, detail)

          + +
          R-15462-52806-17600-54979-17711-21725-52659-40805
          +

          An SQLITE_TRACE_STMT callback is invoked when a prepared statement first begins running and possibly at other times during the execution of the prepared statement, such as at the start of each trigger subprogram. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-15465-20813-03488-35934-00721-06683-61343-58043
          +

          The maximum and minimum embedded payload fractions and the leaf payload fraction values must be 64, 32, and 32. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-15506-57666-56346-10655-27907-33619-59147-37222
          +

          The second callback argument is one of SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE, depending on the operation that caused the callback to be invoked. +(source: c3ref/update_hook.html, checked-by: tcl/hook.test, th3/cov1/main15.test, matrix: context, detail)

          + +
          R-15514-65163-22430-27593-57969-12482-41561-35461
          +

          SQLite understands the following binary operators, in order from highest to lowest precedence: || * / % + - << >> & | < <= > >= = == != <> IS IS NOT IN LIKE GLOB MATCH REGEXP AND OR +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-15522-56042-47189-16162-53355-39499-48752-21999
          +

          For all of these errors, SQLite attempts to undo just the one statement it was working on and leave changes from prior statements within the same transaction intact and continue with the transaction. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-15548-18334-64551-32138-25458-60589-38835-29955
          +

          If the largest root b-tree page value is zero, then the database must not contain ptrmap pages. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-15572-63310-25640-21443-38928-49206-01158-44169
          +

          So just because a column is declared to contain a particular type does not mean that the data stored in that column is of the declared type. +(source: c3ref/column_decltype.html, matrix: context, detail)

          + +
          R-15607-52988-55821-17631-36260-55856-06121-21546
          +

          The added rows contain NULL values in the columns that would normally contain values copied from the right-hand input dataset. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-15610-35227-39836-10138-16838-61419-33727-13478
          +

          Unfinalized SQL statements typically hold a read transaction open, so the VACUUM might fail if there are unfinalized SQL statements on the same connection. +(source: lang_vacuum.html, checked-by: src/vacuum.c, matrix: context, detail)

          + +
          R-15618-12639-40629-36536-35814-47765-39575-62705
          +

          If it is NULL, then all attached databases are searched for the table using the same algorithm used by the database engine to resolve unqualified table references. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-15620-41309-18590-43642-05731-59843-28363-36322
          +

          In this case the call to sqlite3_backup_step() can be retried later. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-15629-60483-22088-30931-50587-36197-35177-56236
          +

          If the locking mode is EXCLUSIVE when first entering WAL journal mode, then the locking mode cannot be changed to NORMAL until after exiting WAL journal mode. +(source: pragma.html, checked-by: th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-15672-33611-05081-27963-61291-19773-24542-63496
          +

          PRAGMA schema.page_count; Return the total number of pages in the database file. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma12.test, matrix: context, detail)

          + +
          R-15704-22093-19659-04811-31747-18777-12777-21799
          +

          If it is set to "ASC" (the default), then the data structures are optimized for returning results in ascending order by docid. +(source: fts3.html, matrix: context, detail)

          + +
          R-15707-53749-16663-50259-17040-65136-59107-02793
          +

          The LIKE optimization will only be attempted if the right-hand side of the GLOB or LIKE operator is either literal string or a parameter that has been bound to a string literal. +(source: optoverview.html, matrix: context, detail)

          + +
          R-15737-42560-39966-60421-02348-13704-23907-48839
          +

          Keyword arguments can optionally appear in quotes. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-15741-50893-04622-59701-05174-07929-61978-12539
          +

          The child key index does not have to be (and usually will not be) a UNIQUE index. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys09.test, matrix: context, detail)

          + +
          R-15796-47513-29721-16055-11683-21050-32207-60873
          +

          When comparing text values, the collating sequence associated with the parent key column is always used. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys03.test, matrix: context, detail)

          + +
          R-15800-25719-02234-49112-58438-56406-07161-16214
          +

          If index-name does not exist or cannot be used for the query, then the preparation of the SQL statement fails. +(source: lang_indexedby.html, checked-by: tcl/indexedby.test, matrix: context, detail)

          + +
          R-15807-22461-03820-63759-43480-30184-16184-55723
          +

          The SQLITE_TRANSIENT value means that the content will likely change in the near future and that SQLite should make its own private copy of the content before returning. +(source: c3ref/c_static.html, checked-by: th3/req1/clearbind01.test, th3/req1/static01.test, matrix: context, detail)

          + +
          R-15810-56691-30500-50989-63977-00699-03712-43349
          +

          The IN and NOT IN operators take an expression on the left and a list of values or a subquery on the right. +(source: lang_expr.html, checked-by: th3/cov1/in01.test, matrix: context, detail)

          + +
          R-15818-17128-00123-39161-32371-64598-56479-09338
          +

          The first parameter is a prepared statement. If this statement is a SELECT statement and the Nth column of the returned result set of that SELECT is a table column (not an expression or subquery) then the declared type of the table column is returned. +(source: c3ref/column_decltype.html, matrix: context, detail)

          + +
          R-15825-58263-40535-43132-40682-17971-55847-38484
          +

          The psow query parameter overrides the powersafe overwrite property of the database file being opened. +(source: uri.html, matrix: context, detail)

          + +
          R-15842-53296-08003-60856-35696-17823-54223-09480
          +

          The WHERE clause on a query is broken up into "terms" where each term is separated from the others by an AND operator. +(source: optoverview.html, matrix: context, detail)

          + +
          R-15867-30493-08974-44645-42836-18647-48672-50550
          +

          The "." character is always used as the decimal point even if the locale setting specifies "," for this role - the use of "," for the decimal point would result in syntactic ambiguity. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-15888-36326-49147-46840-54698-34618-50911-39482
          +

          Similarly, the "DEFAULT VALUES" form of the INSERT statement is supported for top-level INSERT statements only and not for INSERT statements within triggers. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-15909-61171-23810-45611-13574-21954-09176-43834
          +

          In incremental mode, the separate incremental_vacuum pragma must be invoked to cause the auto-vacuum to occur. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-15925-22066-04345-38382-31136-29690-34862-08150
          +

          2. +(source: lang_delete.html, matrix: context, detail)

          + +
          R-15958-50233-58629-08203-04879-28676-03150-11250
          +

          As you would expect, it is not possible to manipulate the database to a state that violates the foreign key constraint by deleting or updating rows in the artist table either: sqlite> -- Attempting to delete the artist record for "Frank Sinatra" fails, since sqlite> -- the track table contains a row that refer to it. sqlite> DELETE FROM artist WHERE artistname = 'Frank Sinatra'; SQL error: foreign key constraint failed sqlite> -- Delete all the records from the track table that refer to the artist sqlite> -- "Frank Sinatra". Only then is it possible to delete the artist. sqlite> DELETE FROM track WHERE trackname = 'My Way'; sqlite> DELETE FROM artist WHERE artistname = 'Frank Sinatra'; sqlite> -- Try to update the artistid of a row in the artist table while there sqlite> -- exists records in the track table that refer to it. sqlite> UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin'; SQL error: foreign key constraint failed sqlite> -- Once all the records that refer to a row in the artist table have sqlite> -- been deleted, it is possible to modify the artistid of the row. sqlite> DELETE FROM track WHERE trackname IN('That''s Amore', 'Christmas Blues'); sqlite> UPDATE artist SET artistid=4 WHERE artistname = 'Dean Martin'; +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys01.test, matrix: context, detail)

          + +
          R-15968-48708-39759-44208-63382-65413-21684-48201
          +

          The other allowed parameters to sqlite3_mutex_alloc() (anything other than SQLITE_MUTEX_FAST and SQLITE_MUTEX_RECURSIVE) each return a pointer to a static preexisting mutex. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-15996-49369-09216-34166-12668-33958-11442-01163
          +

          This function returns the number of rows modified, inserted or deleted by the most recently completed INSERT, UPDATE or DELETE statement on the database connection specified by the only parameter. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-15997-27576-09912-47070-23601-24983-46411-48984
          +

          PRAGMA read_uncommitted; PRAGMA read_uncommitted = boolean; Query, set, or clear READ UNCOMMITTED isolation. +(source: pragma.html, matrix: context, detail)

          + +
          R-16028-39081-19377-46684-10718-53381-04734-64750
          +

          The min() aggregate function returns the minimum non-NULL value of all values in the group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-16040-25925-39944-42727-17957-08154-60392-58357
          +

          If no encoding is first set with this pragma, then the encoding with which the main database will be created defaults to one determined by the API used to open the connection. +(source: pragma.html, matrix: context, detail)

          + +
          R-16046-57096-05363-52910-04894-60844-28556-45944
          +

          If the "unordered" argument is present, then the query planner assumes that the index is unordered and will not use the index for a range query or for sorting. +(source: fileformat2.html, checked-by: th3/cov1/unordered01.test, matrix: context, detail)

          + +
          R-16057-55834-34183-27727-54013-42481-60412-05224
          +

          The extension can add new functions or collating sequences, but cannot modify or delete existing functions or collating sequences because those functions and/or collating sequences might be used elsewhere in the currently running SQL statement. +(source: lang_corefunc.html, checked-by: th3/cov1/func03.test, matrix: context, detail)

          + +
          R-16074-54196-43824-25031-17914-10655-20694-13926
          +

          If the FROM clause is omitted from a simple SELECT statement, then the input data is implicitly a single row zero columns wide +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-16085-53730-63732-38499-15956-61706-03515-37986
          +

          If the optional IF NOT EXISTS clause is present and another index with the same name already exists, then this command becomes a no-op. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-16127-35442-25332-57824-03233-02546-37060-55461
          +

          The following SQLite command-line session illustrates the effect of the foreign key constraint added to the track table: sqlite> SELECT * FROM artist; artistid artistname -------- ----------------- 1 Dean Martin 2 Frank Sinatra sqlite> SELECT * FROM track; trackid trackname trackartist ------- ----------------- ----------- 11 That's Amore 1 12 Christmas Blues 1 13 My Way 2 sqlite> -- This fails because the value inserted into the trackartist column (3) sqlite> -- does not correspond to row in the artist table. sqlite> INSERT INTO track VALUES(14, 'Mr. Bojangles', 3); SQL error: foreign key constraint failed sqlite> -- This succeeds because a NULL is inserted into trackartist. A sqlite> -- corresponding row in the artist table is not required in this case. sqlite> INSERT INTO track VALUES(14, 'Mr. Bojangles', NULL); sqlite> -- Trying to modify the trackartist field of the record after it has sqlite> -- been inserted does not work either, since the new value of trackartist (3) sqlite> -- Still does not correspond to any row in the artist table. sqlite> UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles'; SQL error: foreign key constraint failed sqlite> -- Insert the required row into the artist table. It is then possible to sqlite> -- update the inserted row to set trackartist to 3 (since a corresponding sqlite> -- row in the artist table now exists). sqlite> INSERT INTO artist VALUES(3, 'Sammy Davis Jr.'); sqlite> UPDATE track SET trackartist = 3 WHERE trackname = 'Mr. Bojangles'; sqlite> -- Now that "Sammy Davis Jr." (artistid = 3) has been added to the database, sqlite> -- it is possible to INSERT new tracks using this artist without violating sqlite> -- the foreign key constraint: sqlite> INSERT INTO track VALUES(15, 'Boogie Woogie', 3); +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys01.test, matrix: context, detail)

          + +
          R-16179-57541-27339-65229-35614-47877-55057-18753
          +

          After the error message is delivered up to the client application, the string will be automatically freed by sqlite3_free() and the zErrMsg field will be zeroed. +(source: c3ref/vtab.html, checked-by: th3/req1/vtab01.test, matrix: context, detail)

          + +
          R-16185-00071-09955-21762-46377-47789-41533-03861
          +

          SQLite uses a cost-based query planner that estimates the CPU and disk I/O costs of various competing query plans and chooses the plan that it thinks will be the fastest. +(source: optoverview.html, matrix: context, detail)

          + +
          R-16185-13185-15947-28676-15535-40253-42456-41343
          +

          The sqlite3_str_finish(X) interface will also return a NULL pointer if the string in sqlite3_str object X is zero bytes long. +(source: c3ref/str_finish.html, matrix: context, detail)

          + +
          R-16230-40037-23249-35634-11042-62086-60136-18681
          +

          The LIKE and GLOB optimizations consist of adding two virtual terms like this: column >= x AND column < y +(source: optoverview.html, matrix: context, detail)

          + +
          R-16262-20798-18081-17023-40907-44361-41056-32016
          +

          If X is a string then characters indices refer to actual UTF-8 characters. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-16263-09274-39662-25002-11330-48229-57034-52902
          +

          Whenever the xFilename parameter is NULL it will also be the case that the flags parameter will include SQLITE_OPEN_DELETEONCLOSE. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-16315-56881-31877-40762-35289-40185-03417-40758
          +

          SQLite uses the string pointed to by the 2nd parameter of sqlite3_result_error() or sqlite3_result_error16() as the text of an error message. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-16333-64433-39289-13667-32304-47493-49006-13545
          +

          Checkpoint as many frames as possible without waiting for any database readers or writers to finish, then sync the database file if all frames in the log were checkpointed. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-16335-41477-51529-00085-31320-00976-56017-05968
          +

          The implementation of the new function always causes an exception to be thrown. +(source: c3ref/overload_function.html, matrix: context, detail)

          + +
          R-16338-21766-30824-60129-14672-05861-18786-65530
          +

          The sqlite_schema.sql is NULL for the internal indexes that are automatically created by UNIQUE or PRIMARY KEY constraints. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-16368-45976-00872-58854-24152-50721-64128-13057
          +

          If the specified column is "rowid", "oid" or "_rowid_" and the table is not a WITHOUT ROWID table and an INTEGER PRIMARY KEY column has been explicitly declared, then the output parameters are set for the explicitly declared column. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-16423-47210-04827-18220-00892-21798-11379-58569
          +

          SQLITE_CONFIG_LOOKASIDE sets the default lookaside size. The SQLITE_DBCONFIG_LOOKASIDE option to sqlite3_db_config() can be used to change the lookaside configuration on individual connections. +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-16465-40078-63621-42444-05703-20205-45309-57719
          +

          An error is still returned if the table cannot be created because of an existing index, even if the "IF NOT EXISTS" clause is specified. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-16469-27921-09165-55692-23366-54628-53596-65397
          +

          Let X be ((U-12)*64/255)-23. If the payload size P is less than or equal to X then the entire payload is stored on the b-tree page. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-16484-18454-63901-36936-39837-40548-12508-46006
          +

          This means that if there is a RETURNING clause, the rows returned by the statement probably will not be in the order specified by the ORDER BY clause. +(source: lang_delete.html, matrix: context, detail)

          + +
          R-16560-34565-42127-15402-21393-00583-21014-04940
          +

          When memory allocation statistics are disabled, the following SQLite interfaces become non-operational: sqlite3_hard_heap_limit64() sqlite3_memory_used() sqlite3_memory_highwater() sqlite3_soft_heap_limit64() sqlite3_status64() +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-16566-16123-02807-20883-30772-24192-15588-47043
          +

          If the fourth parameter to sqlite3_bind_text() or sqlite3_bind_text16() is negative, then the length of the string is the number of bytes up to the first zero terminator. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-16584-60189-60940-01835-35282-37415-55139-16536
          +

          The LIKE operator does a pattern matching comparison. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-16618-15294-40098-25515-23421-58217-44729-28455
          +

          The xDestroy callback is not called if the sqlite3_create_collation_v2() function fails. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-16625-30785-18660-34070-49109-22249-51329-26220
          +

          CREATE TABLE t1( t TEXT, -- text affinity by rule 2 nu NUMERIC, -- numeric affinity by rule 5 i INTEGER, -- integer affinity by rule 1 r REAL, -- real affinity by rule 4 no BLOB -- no affinity by rule 3 ); -- Values stored as TEXT, INTEGER, INTEGER, REAL, TEXT. INSERT INTO t1 VALUES('500.0', '500.0', '500.0', '500.0', '500.0'); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; text|integer|integer|real|text -- Values stored as TEXT, INTEGER, INTEGER, REAL, REAL. DELETE FROM t1; INSERT INTO t1 VALUES(500.0, 500.0, 500.0, 500.0, 500.0); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; text|integer|integer|real|real -- Values stored as TEXT, INTEGER, INTEGER, REAL, INTEGER. DELETE FROM t1; INSERT INTO t1 VALUES(500, 500, 500, 500, 500); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; text|integer|integer|real|integer -- BLOBs are always stored as BLOBs regardless of column affinity. DELETE FROM t1; INSERT INTO t1 VALUES(x'0500', x'0500', x'0500', x'0500', x'0500'); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; blob|blob|blob|blob|blob -- NULLs are also unaffected by affinity DELETE FROM t1; INSERT INTO t1 VALUES(NULL,NULL,NULL,NULL,NULL); SELECT typeof(t), typeof(nu), typeof(i), typeof(r), typeof(no) FROM t1; null|null|null|null|null +(source: datatype3.html, checked-by: th3/req1/datatype3_03.test, matrix: context, detail)

          + +
          R-16642-42503-02054-10937-29863-20492-60012-48807
          +

          If pnLog is not NULL, then *pnLog is set to the total number of frames in the log file or to -1 if the checkpoint could not run because of an error or because the database is not in WAL mode. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-16646-21584-46697-05681-31663-32907-36469-00200
          +

          Assuming that customer records are stored in the "customers" table, and that order records are stored in the "orders" table, the following UPDATE trigger ensures that all associated orders are redirected when a customer changes his or her address: CREATE TRIGGER update_customer_address UPDATE OF address ON customers BEGIN UPDATE orders SET address = new.address WHERE customer_name = old.name; END; With this trigger installed, executing the statement: UPDATE customers SET address = '1 Main St.' WHERE name = 'Jack Jones'; causes the following to be automatically executed: UPDATE orders SET address = '1 Main St.' WHERE customer_name = 'Jack Jones'; +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-16667-09772-49719-31383-20699-54843-21151-14987
          +

          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. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-16677-54172-01660-13905-64102-51935-20932-64314
          +

          All spaces following the first two keywords are converted into a single space. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-16711-29980-24951-32335-36937-22599-07259-26262
          +

          The filename in the INTO clause can be an arbitrary SQL expression that evaluates to a string. +(source: lang_vacuum.html, checked-by: th3/cov1/vacuum10.test, matrix: context, detail)

          + +
          R-16717-50504-54717-12200-54209-43488-56382-57633
          +

          Each R*Tree index is a virtual table with an odd number of columns between 3 and 11. +(source: rtree.html, matrix: context, detail)

          + +
          R-16727-13091-18593-02936-45365-35968-45386-40640
          +

          The column may not be GENERATED ALWAYS . +(source: lang_altertable.html, matrix: context, detail)

          + +
          R-16727-30552-59838-52112-19419-11299-04704-42837
          +

          In this case, the object and the provided pointer to it must remain valid until either the prepared statement is finalized or the same SQL parameter is bound to something else, whichever occurs sooner. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-16735-29088-33516-22402-46874-28284-28835-57919
          +

          When two TEXT values are compared an appropriate collating sequence is used to determine the result. +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-16748-44311-29408-30496-47489-38562-34902-17551
          +

          If the specified table is actually a view, an error code is returned. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-16775-34716-48016-59856-43563-01952-64923-08515
          +

          You cannot DELETE, INSERT, or UPDATE a view. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-16776-49985-46642-51355-02020-16796-53995-22275
          +

          The integer return value from the callback is currently ignored, though this may change in future releases. +(source: c3ref/trace_v2.html, matrix: context, detail)

          + +
          R-16824-07538-50218-17384-27705-17061-18390-01878
          +

          Support for the diagnostic functions sqlite3_compileoption_used() and sqlite3_compileoption_get() may be omitted by specifying the SQLITE_OMIT_COMPILEOPTION_DIAGS option at compile time. +(source: c3ref/compileoption_get.html, checked-by: src/ctime.c, matrix: context, detail)

          + +
          R-16876-26469-56495-43773-04643-04870-06914-01150
          +

          However, in many cases you can use an INSTEAD OF trigger on the view to accomplish the same thing. +(source: lang_createview.html, matrix: context, detail)

          + +
          R-16907-50223-28692-47460-07440-02664-00215-50680
          +

          The SQL syntax for custom queries is the same regardless of which interface, sqlite3_rtree_geometry_callback() or sqlite3_rtree_query_callback(), is used to register the SQL function. +(source: rtree.html, matrix: context, detail)

          + +
          R-16960-46772-37295-51769-03234-47143-37776-03273
          +

          The xSetSystemCall(), xGetSystemCall(), and xNestSystemCall() interfaces are not used by the SQLite core. +(source: c3ref/vfs.html, matrix: context, detail)

          + +
          R-17002-27534-60658-04301-02636-10331-43886-13324
          +

          The %z format is interchangeable with %s. +(source: lang_corefunc.html, checked-by: tcl/printf2.test, th3/cov1/printf08.test, matrix: context, detail)

          + +
          R-17004-26469-33978-15550-51185-63234-25288-10208
          +

          Multiple collating functions can be registered using the same name but with different eTextRep parameters and SQLite will use whichever function requires the least amount of data transformation. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-17039-33674-48721-19365-01161-03583-42602-47199
          +

          If this global variable is made to point to a string which is the name of a folder (a.k.a. directory), then all database files specified with a relative pathname and created or accessed by SQLite when using a built-in windows VFS will be assumed to be relative to that directory. +(source: c3ref/data_directory.html, matrix: context, detail)

          + +
          R-17066-08509-20793-46689-03241-48208-02822-18117
          +

          The multi-argument min() function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-17069-05052-11760-32212-31983-21465-64929-00475
          +

          Regardless of whether or not it is successful, this file control takes the file descriptor out of batch write mode so that all subsequent write operations are independent. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-17100-46000-36927-33778-08378-49986-19867-19918
          +

          The sqlite3_column_name() interface returns a pointer to a zero-terminated UTF-8 string and sqlite3_column_name16() returns a pointer to a zero-terminated UTF-16 string. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-17129-39366-12879-37953-16940-52651-36509-01278
          +

          The SQLITE_ENABLE_STAT3 and SQLITE_ENABLE_STAT4 options causes the ANALYZE command to collect a histogram of column content in the sqlite_stat3 or sqlite_stat4 tables and to use this histogram to make a better guess at the best query to use for range constraints such as the above. +(source: optoverview.html, matrix: context, detail)

          + +
          R-17146-37073-08858-03066-53488-24451-10311-22699
          +

          Within a trigger program each INSERT, UPDATE and DELETE statement sets the value returned by sqlite3_changes() upon completion as normal. Of course, this value will not include any changes performed by sub-triggers, as the sqlite3_changes() value will be saved and restored after each sub-trigger has run. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-17151-07205-10894-28299-62821-16887-02117-62221
          +

          The sort order may or may not be ignored depending on the database file format, and in particular the schema format number. +(source: lang_createindex.html, checked-by: th3/req1/createidx02.test, matrix: context, detail)

          + +
          R-17186-50053-08160-14434-65470-31031-28806-57680
          +

          The busy-handler callback is never invoked in this mode. +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-17203-10061-39568-47821-02948-38975-34395-48032
          +

          Calling sqlite3_free() with a pointer previously returned by sqlite3_malloc() or sqlite3_realloc() releases that memory so that it might be reused. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-17228-37124-21945-03605-09770-36410-30558-62639
          +

          If the action code is SQLITE_DELETE and the callback returns SQLITE_IGNORE then the DELETE operation proceeds but the truncate optimization is disabled and all rows are deleted individually. +(source: c3ref/set_authorizer.html, checked-by: src/delete.c, th3/cov1/delete05.test, matrix: context, detail)

          + +
          R-17269-58859-62979-20789-28373-02283-01402-32903
          +

          The pArg argument is passed through to the callback. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-17287-50357-43174-57829-08409-00389-08180-30252
          +

          sqlite> EXPLAIN QUERY PLAN SELECT * FROM (SELECT * FROM t2 WHERE c=1), t1; QUERY PLAN |--SEARCH TABLE t2 USING INDEX i4 (c=?) `--SCAN TABLE t1 +(source: eqp.html, matrix: context, detail)

          + +
          R-17287-60737-33985-12645-22938-14534-06595-16406
          +

          Immediately following the wal-header are zero or more frames. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-17313-07189-19129-06928-03198-35699-51824-58751
          +

          The S and M arguments passed to sqlite3_backup_init(D,N,S,M) identify the database connection and database name of the source database, respectively. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-17329-35644-14084-44573-27599-05498-14002-35742
          +

          If both arguments X and Y to instr(X,Y) are non-NULL and are not BLOBs then both are interpreted as strings. +(source: lang_corefunc.html, checked-by: tcl/instr.test, matrix: context, detail)

          + +
          R-17341-41375-54397-54408-61756-02302-26643-35471
          +

          This is the number of times that SQLite has stepped forward in a table as part of a full table scan. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-17379-32951-58399-57501-33498-60036-41846-10214
          +

          Any attempt to insert a duplicate entry will result in an error. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-17403-41821-06964-23183-41391-40881-28445-64765
          +

          This value is not actually a counter, and so the resetFlg parameter to sqlite3_stmt_status() is ignored when the opcode is SQLITE_STMTSTATUS_MEMUSED. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-17446-42210-34693-14358-63736-15125-50788-14623
          +

          Like other SQL identifiers, schema names are case-insensitive. +(source: lang_naming.html, checked-by: tcl/e_resolve.test, matrix: context, detail)

          + +
          R-17458-15700-03472-60284-42134-49579-06923-34319
          +

          The sqlite3_stmt_busy(S) interface returns false if S is a NULL pointer. +(source: c3ref/stmt_busy.html, checked-by: th3/cov1/vdbeapi03.test, matrix: context, detail)

          + +
          R-17482-00398-10630-63000-62255-53684-56492-08333
          +

          If the authority is not an empty string or "localhost", an error is returned to the caller. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-17495-17419-60080-02439-41171-12294-54829-31710
          +

          The VACUUM command may change the ROWIDs of entries in any tables that do not have an explicit INTEGER PRIMARY KEY. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, th3/cov1/vacuum01.test, matrix: context, detail)

          + +
          R-17497-43474-02755-40707-55508-06941-43855-44277
          +

          Likewise, registering a callback using sqlite3_wal_hook() disables the automatic checkpoint mechanism configured by this function. +(source: c3ref/wal_autocheckpoint.html, checked-by: tcl/e_walauto.test, matrix: context, detail)

          + +
          R-17503-25110-05842-17616-27745-25701-57748-55330
          +

          If the WAL contains no copies of page P that are valid and which are a commit frame or are followed by a commit frame, then page P is read from the database file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-17503-44008-12544-16508-15108-35473-45615-30294
          +

          The default implementation stores all statistics in a single table named "sqlite_stat1". +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-17527-22739-13874-05126-20619-29164-21106-56855
          +

          Parameter OutputType Description 5th const char* Data type 6th const char* Name of default collation sequence 7th int True if column has a NOT NULL constraint 8th int True if column is part of the PRIMARY KEY 9th int True if column is AUTOINCREMENT +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-17535-15185-26123-07430-36338-10169-10447-08966
          +

          If foreign key constraints are enabled, a DROP TABLE command performs an implicit DELETE FROM command before removing the table from the database schema. +(source: lang_droptable.html, checked-by: th3/req1/droptable01.test, matrix: context, detail)

          + +
          R-17537-00183-53931-12298-10408-12793-18687-03447
          +

          A similar effect occurs when the original date is February 29 of a leapyear and the modifier is ±N years where N is not a multiple of four. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-17564-54218-01993-46231-42657-60991-50837-12624
          +

          If the resetFlag is true, then the highest record value is reset after *pHighwater is written. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-17579-15688-44175-34852-39551-28405-28214-64262
          +

          These interfaces are only available if SQLite is compiled using the SQLITE_ENABLE_PREUPDATE_HOOK compile-time option. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-17591-50446-37876-17822-10375-27592-36497-28987
          +

          Boolean values are stored as integers 0 (false) and 1 (true). +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-17596-52174-25214-41225-30917-27450-40075-28590
          +

          A particular database will use either a rollback journal or a WAL, but not both at the same time. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-17615-49737-42602-31197-05538-64484-08202-17390
          +

          A negative number implies no limit. +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-17628-54414-54605-31939-57279-20393-13350-52356
          +

          The next time SQLite attempts to open the database file, the presence of the rollback journal file will be detected and the journal will be automatically played back to restore the database to its state at the start of the incomplete transaction. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-17644-02150-10619-56225-58542-30426-53377-14747
          +

          The sqlite3_create_module_v2() interface has a fifth parameter which is a pointer to a destructor for the pClientData. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-17644-24322-63248-40281-26514-10793-04355-46693
          +

          Notice that all other date and time functions can be expressed in terms of strftime(): FunctionEquivalent strftime() date(...) strftime('%Y-%m-%d', ...) time(...) strftime('%H:%M:%S', ...) datetime(...) strftime('%Y-%m-%d %H:%M:%S', ...) julianday(...) strftime('%J', ...) +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-17683-59594-13579-14757-04762-40863-05270-49270
          +

          At various points during the compilation process, as logic is being created to perform various actions, the authorizer callback is invoked to see if those actions are allowed. +(source: c3ref/set_authorizer.html, matrix: context, detail)

          + +
          R-17684-03275-18018-08876-61159-17187-00685-37913
          +

          Only ROWID values from previous transactions that were committed are considered. ROWID values that were rolled back are ignored and can be reused. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-17719-44813-04835-03337-09891-18871-23593-16128
          +

          An aggregate SQL function requires an implementation of xStep and xFinal and NULL pointer must be passed for xFunc. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc03.test, matrix: context, detail)

          + +
          R-17719-64233-56665-24727-28694-41697-48581-47600
          +

          Each frame consists of a 24-byte frame-header followed by a page-size bytes of page data. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-17746-39108-25168-47884-07203-13722-37711-19749
          +

          Pointers to the right of X refer to pages where all keys are greater than X. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-17759-10613-53810-53402-33339-35108-00085-57750
          +

          Most R*Tree queries use a depth-first search. This is accomplished by setting the rScore equal to iLevel. +(source: rtree.html, matrix: context, detail)

          + +
          R-17768-43126-25682-30166-03658-34000-04918-35023
          +

          The name of a result column is the value of the "AS" clause for that column, if there is an AS clause. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-17784-08205-07510-46755-33017-49924-02897-50961
          +

          The sqlite3_snapshot_open(D,S,P) interface either starts a new read transaction or upgrades an existing one for schema S of database connection D such that the read transaction refers to historical snapshot P, rather than the most recent change to the database. +(source: c3ref/snapshot_open.html, matrix: context, detail)

          + +
          R-17817-00630-38271-37218-33911-49615-48775-23865
          +

          If the largest possible ROWID has previously been inserted, then new INSERTs are not allowed and any attempt to insert a new row will fail with an SQLITE_FULL error. +(source: autoinc.html, checked-by: src/vdbe.c, th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-17817-46062-61072-05424-12542-62157-01447-33721
          +

          If an error occurs within sqlite3_backup_init(D,N,S,M), then NULL is returned and an error code and error message are stored in the destination database connection D. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-17840-50075-33076-39937-50165-09009-15721-26614
          +

          In ordinary indexes, there is exactly one entry in the index for every row in the table. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-17847-41579-08261-19893-13376-57099-17968-14055
          +

          The third parameter (nArg) is the number of arguments that the SQL function or aggregate takes. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc02.test, matrix: context, detail)

          + +
          R-17874-21123-26215-56857-37279-50732-34133-47276
          +

          The first column of an SQLite R*Tree is similar to an integer primary key column of a normal SQLite table. +(source: rtree.html, matrix: context, detail)

          + +
          R-17899-04554-16139-08865-17180-48146-22421-25181
          +

          Table names that begin with "sqlite_" are reserved for internal use. It is an error to attempt to create a table with a name that starts with "sqlite_". +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-17926-09424-52325-52888-31926-01436-23382-42237
          +

          The statistics gathered by this scan are stored in special database tables names shows names all begin with "sqlite_stat". +(source: optoverview.html, matrix: context, detail)

          + +
          R-17939-38828-17695-42161-08728-29310-38414-12197
          +

          The fifth parameter is an arbitrary pointer. The implementation of the function can gain access to this pointer using sqlite3_user_data(). +(source: c3ref/create_function.html, checked-by: th3/req1/userdata01.test, matrix: context, detail)

          + +
          R-18023-38297-26646-57171-09733-60965-00209-38549
          +

          EXTRA synchronous is like FULL with the addition that the directory containing a rollback journal is synced after that journal is unlinked to commit a transaction in DELETE mode. +(source: pragma.html, matrix: context, detail)

          + +
          R-18031-23188-38756-14350-07582-34544-63211-44348
          +

          If there is no metadata associated with the function argument, the sqlite3_get_auxdata(C,N) interface returns a NULL pointer. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-18043-40700-22598-52813-64197-51522-53393-10304
          +

          The psow query parameter works with the default windows and unix VFSes but might be a no-op for other proprietary or non-standard VFSes. +(source: uri.html, matrix: context, detail)

          + +
          R-18085-46797-38544-57069-39269-06542-00638-19188
          +

          numeric arguments in parentheses that following the type name (ex: "VARCHAR(255)") are ignored +(source: datatype3.html, checked-by: th3/req1/datatype3_02.test, matrix: context, detail)

          + +
          R-18088-57186-13089-35997-22868-17352-00310-65503
          +

          For example, let the index be CREATE INDEX ex1 ON tab1(a,b) WHERE a=5 OR b=6; And let the query be: SELECT * FROM tab1 WHERE b=6 AND a=7; -- uses partial index Then the index is usable by the query because the "b=6" term appears in both the index definition and in the query. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-18130-23470-26620-07261-16274-17871-22790-47651
          +

          This interface enables or disables both the C-API sqlite3_load_extension() and the SQL function load_extension(). +(source: c3ref/enable_load_extension.html, matrix: context, detail)

          + +
          R-18143-12121-25249-36193-24562-40889-39176-48672
          +

          Value is the integer 1. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-18160-43138-45730-29033-18368-13452-34551-31953
          +

          PRAGMA foreign_keys; PRAGMA foreign_keys = boolean; Query, set, or clear the enforcement of foreign key constraints. +(source: pragma.html, checked-by: th3/req1/pragma18.test, matrix: context, detail)

          + +
          R-18160-48734-12487-09997-11031-61003-43897-08278
          +

          SQLITE_STATUS_MALLOC_SIZE This parameter records the largest memory allocation request handed to sqlite3_malloc() or sqlite3_realloc() (or their internal equivalents). Only the value returned in the *pHighwater parameter to sqlite3_status() is of interest. The value written into the *pCurrent parameter is undefined. +(source: c3ref/c_status_malloc_count.html, matrix: context, detail)

          + +
          R-18190-43830-34676-47582-56241-44977-21337-20567
          +

          If an error occurs and pzErrMsg is not 0, then the sqlite3_load_extension() interface shall attempt to fill *pzErrMsg with error message text stored in memory obtained from sqlite3_malloc(). +(source: c3ref/load_extension.html, matrix: context, detail)

          + +
          R-18219-48316-63080-50419-00617-04513-48558-33147
          +

          In other words, the values to the right of the IN operator (the "x", "y", and "z" values in this example) are considered to have no affinity, even if they happen to be column values or CAST expressions. +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-18232-39104-31806-20551-06401-15021-42756-14177
          +

          The TEMP or TEMPORARY keyword is removed if it occurs after the initial CREATE keyword. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-18268-44140-34945-14293-33912-32138-63537-31986
          +

          If an application-defined collating sequence and/or like() SQL function are provided, the LIKE optimization described here will never be taken. +(source: optoverview.html, matrix: context, detail)

          + +
          R-18318-14995-07554-10565-41972-64784-37540-10382
          +

          The value of a subquery expression is the first row of the result from the enclosed SELECT statement. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-18321-05872-40763-16666-14015-36142-16508-50881
          +

          The flags parameter to sqlite3_open_v2() must include, at a minimum, one of the following three flag combinations: +(source: c3ref/open.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-18347-31070-03027-11066-56518-02178-55511-27886
          +

          NULL values (serial type 0) sort first. +(source: fileformat2.html, checked-by: th3/req1/fileformat05.test, matrix: context, detail)

          + +
          R-18364-25640-43471-65335-34300-00271-36361-11229
          +

          Some mathematical operators (%, <<, >>, &, and |) expect INTEGER operands. For those operators, REAL operands are converted into INTEGER in the same way as a CAST to INTEGER. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-18369-35089-02774-53882-33695-33553-03042-04730
          +

          In each such row, the sqlite_stat.stat column will be a string consisting of a list of integers followed by zero or more arguments. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-18401-29434-64954-06986-64183-65174-36377-46247
          +

          The ROLLBACK TO command reverts the state of the database back to what it was just after the corresponding SAVEPOINT. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-18404-60208-00331-08583-24532-43133-17599-55121
          +

          For the purposes of this paragraph, hexadecimal integer literals are not considered well-formed and are stored as TEXT. (This is done for historical compatibility with versions of SQLite prior to version 3.8.6 2014-08-15 where hexadecimal integer literals were first introduced into SQLite.) +(source: datatype3.html, matrix: context, detail)

          + +
          R-18439-38548-20374-55698-53430-21042-59445-48532
          +

          In other words, if the left-hand dataset consists of Nleft rows of Mleft columns, and the right-hand dataset of Nright rows of Mright columns, then the cartesian product is a dataset of Nleft×Nright rows, each containing Mleft+Mright columns. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-18444-13968-40811-25945-54439-20224-30854-05072
          +

          If the progress callback returns non-zero, the operation is interrupted. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-18448-33677-24948-48953-25784-65474-15600-00219
          +

          If a schema-name is specified, it must be either "main", "temp", or the name of an attached database. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-18465-63076-46355-46123-39901-27541-22994-57422
          +

          The sqlite3_data_count(P) routine also returns 0 if P is a NULL pointer. +(source: c3ref/data_count.html, checked-by: th3/req1/datacnt01.test, matrix: context, detail)

          + +
          R-18500-08619-10931-07451-20568-56201-09385-55546
          +

          When the auto-vacuum mode is 1 or "full", the freelist pages are moved to the end of the database file and the database file is truncated to remove the freelist pages at every transaction commit. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-18509-21923-06285-21395-08287-44781-54571-62637
          +

          In a well-formed sqlite_stat4 table, the samples for any single index must appear in the same order that they occur in the index. In other words, if entry S1 is earlier in the index b-tree than entry S2, then in the sqlite_stat4 table, sample S1 must have a smaller rowid than sample S2. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-18547-52845-30240-29713-43116-28155-35660-14807
          +

          The nul terminator is not stored. +(source: fileformat2.html, checked-by: th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-18567-63872-28950-34991-21095-45728-61145-64681
          +

          The 4th argument to sqlite3_exec() is relayed through to the 1st argument of each callback invocation. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-18628-11938-58280-60424-32964-58816-64179-48454
          +

          If the LIMIT expression evaluates to non-negative value N and the UPDATE statement has an ORDER BY clause, then all rows that would be updated in the absence of the LIMIT clause are sorted according to the ORDER BY and the first N updated. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-18658-48735-17951-17191-40214-20850-63941-45114
          +

          The third parameter passed to the logger is log message after formatting via sqlite3_snprintf(). +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/log01.test, matrix: context, detail)

          + +
          R-18665-26680-08407-38690-15882-41528-44716-07525
          +

          The in-header database size is only considered to be valid if it is non-zero and if the 4-byte change counter at offset 24 exactly matches the 4-byte version-valid-for number at offset 92. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-18669-12610-19021-20460-56494-30622-24671-33359
          +

          A successful call to sqlite3_backup_init() returns a pointer to an sqlite3_backup object. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-18673-21346-54823-18159-41507-63066-50898-24427
          +

          The view to drop is identified by the view-name and optional schema-name specified as part of the DROP VIEW statement. This reference is resolved using the standard procedure for object resolution. +(source: lang_dropview.html, checked-by: th3/cov1/build13.test, matrix: context, detail)

          + +
          R-18684-41029-50457-11697-46944-61670-11271-59779
          +

          When no rows match an aggregate query, the xStep() callback of the aggregate function implementation is never called and xFinal() is called exactly once. In those cases, sqlite3_aggregate_context() might be called for the first time from within xFinal(). +(source: c3ref/aggregate_context.html, checked-by: th3/req1/aggcntx01.test, matrix: context, detail)

          + +
          R-18692-17694-63404-11739-00590-02418-57066-37741
          +

          If the table being renamed has triggers or indices, then these remain attached to the table after it has been renamed. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-18701-28385-27325-47261-28842-16656-24212-49294
          +

          If sqlite3_realloc(X,N) returns NULL and N is positive, then the prior allocation is not freed. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-18705-33393-57819-41139-38249-59845-61429-28312
          +

          If neither ASC or DESC are specified, rows are sorted in ascending (smaller values first) order by default. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-18711-35549-27220-03897-01638-65186-51204-23198
          +

          The ROLLBACK command without a TO clause rolls backs all transactions and leaves the transaction stack empty. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-18721-11322-01126-64339-40438-59164-27470-15171
          +

          If the SQLITE_FCNTL_PRAGMA file control returns any result code other than SQLITE_OK or SQLITE_NOTFOUND, that means that the VFS encountered an error while handling the PRAGMA and the compilation of the PRAGMA fails with an error. +(source: c3ref/c_fcntl_begin_atomic_write.html, checked-by: th3/cov1/pragma24.test, matrix: context, detail)

          + +
          R-18741-16139-46901-23037-06510-07608-27753-13735
          +

          If the third parameter to sqlite3_result_error() or sqlite3_result_error16() is negative then SQLite takes as the error message all text up through the first zero character. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-18761-36601-52477-41858-50422-48259-26249-60600
          +

          There are three arguments to SQLITE_CONFIG_PAGECACHE: A pointer to 8-byte aligned memory (pMem), the size of each page cache line (sz), and the number of cache lines (N). +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/cov1/main42.test, matrix: context, detail)

          + +
          R-18773-06579-40569-18123-18199-49078-54792-42080
          +

          SQLITE_RANGE is returned if the parameter index is out of range. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-18814-23501-09117-45657-61449-22992-54979-37312
          +

          Each time a row is inserted into the table by an INSERT statement that does not provide explicit values for all table columns the values stored in the new row are determined by their default values +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-18818-06259-05609-26467-03914-52420-50425-49000
          +

          A SAVEPOINT can be started either within or outside of a BEGIN...COMMIT. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-18846-05946-40974-48701-32199-53032-10077-35779
          +

          With synchronous OFF (0), SQLite continues without syncing as soon as it has handed data off to the operating system. +(source: pragma.html, matrix: context, detail)

          + +
          R-18856-64447-32517-13318-33579-07767-23814-56336
          +

          For example, the following CREATE TABLE statements all specify the same table, which will have the exact same representation on disk: CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c)) WITHOUT ROWID); CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,c,a,c)) WITHOUT ROWID); CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,A,a,C)) WITHOUT ROWID); CREATE TABLE t1(a,b,c,d,PRIMARY KEY(a,a,a,a,c)) WITHOUT ROWID); +(source: fileformat2.html, matrix: context, detail)

          + +
          R-18879-47479-26487-44670-60127-29624-08821-22011
          +

          If it is set to "DESC", then FTS4 stores its data in such a way as to optimize returning results in descending order by docid. +(source: fts3.html, matrix: context, detail)

          + +
          R-18885-42713-55126-22349-03815-15805-20030-42091
          +

          A column with REAL affinity behaves like a column with NUMERIC affinity except that it forces integer values into floating point representation. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-18895-27365-20289-12607-60428-18477-59440-44133
          +

          If the "TEMP" or "TEMPORARY" keyword occurs between the "CREATE" and "TABLE" then the new table is created in the temp database. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-18913-19355-04042-04396-26693-02137-35105-64598
          +

          The fourth parameter is the number of pages currently in the write-ahead log file, including those that were just committed. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-18927-01951-35709-41382-23039-58065-29475-65248
          +

          Each column of the new row is populated with its default value, or with a NULL if no default value is specified as part of the column definition in the CREATE TABLE statement. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-18962-08090-15768-27249-44223-08875-09432-04987
          +

          Hence, a cache created with bPurgeable false will never contain any unpinned pages. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-18964-51531-38235-16261-57269-07859-04237-25462
          +

          This function causes any pending database operation to abort and return at its earliest opportunity. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-18968-56672-08189-06837-25504-50513-21713-31862
          +

          The ROWID chosen for the new row is at least one larger than the largest ROWID that has ever before existed in that same table. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-18977-48537-51631-02692-14706-00961-61427-62208
          +

          The sqlite3_txn_state(D,S) interface returns one of these constants in order to describe the transaction state of schema S in database connection D. +(source: c3ref/c_txn_none.html, matrix: context, detail)

          + +
          R-18978-08031-62088-38924-17278-52934-19628-35993
          +

          The memory pointed to by the character pointers returned for the declaration type and collation sequence is valid until the next call to any SQLite API function. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-18981-16292-44177-39464-49712-02547-36593-34843
          +

          When the defer_foreign_keys PRAGMA is on, enforcement of all foreign key constraints is delayed until the outermost transaction is committed. +(source: pragma.html, checked-by: tcl/fkey6.test, th3/cov1/fkey24.test, matrix: context, detail)

          + +
          R-18981-44563-59556-01794-47708-02337-53296-37760
          +

          The OFF journaling mode disables the rollback journal completely. +(source: pragma.html, checked-by: th3/req1/pragma25.test, matrix: context, detail)

          + +
          R-18996-06026-12732-36881-04380-02078-38106-17370
          +

          However, the IGNORE conflict resolution algorithm works like ABORT for foreign key constraint errors. +(source: lang_conflict.html, matrix: context, detail)

          + +
          R-19003-27813-57127-49100-22413-58501-27554-18699
          +

          The SAVEPOINT with the matching name remains on the transaction stack, but all database changes that occurred after that SAVEPOINT was created are rolled back. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-19069-01001-21275-64198-08959-57544-11845-18751
          +

          These routines are used to register a new virtual table module name. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-19114-56113-41752-64271-30879-46460-35912-30160
          +

          Different constraints within the same table may have different default conflict resolution algorithms. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-19120-50787-31629-64944-20395-18225-62762-09460
          +

          The sqlite3_preupdate_old(D,N,P) interface writes into P a pointer to a protected sqlite3_value that contains the value of the Nth column of the table row before it is updated. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-19139-12267-31476-22597-30278-48901-50934-33461
          +

          If sqlite3_unlock_notify() is called with a NULL pointer as its second argument, then any existing unlock-notify callback is canceled. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-19162-55388-28844-29887-54254-48882-22034-22486
          +

          The sqlite3_bind_zeroblob() routine binds a BLOB of length N that is filled with zeroes. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-19178-27645-63083-26050-05481-47319-52943-38968
          +

          Otherwise, no affinity is applied and both operands are compared as is. +(source: datatype3.html, checked-by: th3/cov1/affinity01.test, th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-19186-55658-49729-13397-54658-17694-41016-19836
          +

          The sqlite3_result_value() interface makes a copy of the sqlite3_value so that the sqlite3_value specified in the parameter may change or be deallocated after sqlite3_result_value() returns without harm. +(source: c3ref/result_blob.html, checked-by: th3/req1/result03.test, matrix: context, detail)

          + +
          R-19194-50107-23350-24777-39179-56094-65469-19806
          +

          If this in-header datasize size is not valid (see the next paragraph), then the database size is computed by looking at the actual size of the database file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-19218-01018-34190-29408-05030-57766-08679-20332
          +

          If the column-name list after table-name is omitted then the number of values inserted into each row must be the same as the number of columns in the table. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-19222-28861-33123-00573-15800-37173-53846-06929
          +

          Otherwise, sqlite3_value_pointer(V,Y) returns a NULL. +(source: c3ref/value_blob.html, checked-by: th3/cov1/carray01.test, matrix: context, detail)

          + +
          R-19244-03478-32061-23000-56536-05403-47491-06826
          +

          The leaves have a level of 0. +(source: rtree.html, matrix: context, detail)

          + +
          R-19245-12964-15266-21259-12378-18812-33916-24209
          +

          The DELETE journaling mode is the normal behavior. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-19249-32353-33767-36599-40313-00705-24761-59859
          +

          SQLITE_LIMIT_WORKER_THREADS The maximum number of auxiliary worker threads that a single prepared statement may start. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sort4.test, matrix: context, detail)

          + +
          R-19259-42385-45456-07469-03560-15190-02204-12412
          +

          SQLITE_STATUS_PAGECACHE_SIZE This parameter records the largest memory allocation request handed to the pagecache memory allocator. Only the value returned in the *pHighwater parameter to sqlite3_status() is of interest. The value written into the *pCurrent parameter is undefined. +(source: c3ref/c_status_malloc_count.html, matrix: context, detail)

          + +
          R-19326-44825-19062-24470-23880-46223-50935-31383
          +

          The "PRAGMA data_version" value is a local property of each database connection and so values returned by two concurrent invocations of "PRAGMA data_version" on separate database connections are often different even though the underlying database is identical. +(source: pragma.html, checked-by: tcl/pragma3.test, th3/cov1/pragma26.test, matrix: context, detail)

          + +
          R-19334-12811-52965-43642-11320-54818-13590-65507
          +

          Each group of input dataset rows contributes a single row to the set of result rows. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-19353-19546-22807-46023-33784-34102-06986-46730
          +

          A 2-dimensional R*Tree has 5 columns. +(source: rtree.html, matrix: context, detail)

          + +
          R-19353-43643-11289-35798-30332-46906-60350-15505
          +

          The last bullet above is illustrated by the following: CREATE TABLE parent2(a, b, PRIMARY KEY(a,b)); CREATE TABLE child8(x, y, FOREIGN KEY(x,y) REFERENCES parent2); -- Ok CREATE TABLE child9(x REFERENCES parent2); -- Error! CREATE TABLE child10(x,y,z, FOREIGN KEY(x,y,z) REFERENCES parent2); -- Error! +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-19393-22085-63206-61334-35392-55321-46849-03619
          +

          For a string value X, the length(X) function returns the number of characters (not bytes) in X prior to the first NUL character. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-19404-45868-36670-49387-53766-10214-08555-10559
          +

          When the argument X to sqlite_compileoption_used(X) is a string which is the name of a compile-time option, this routine returns true (1) or false (0) depending on whether or not that option was used during the build. +(source: lang_corefunc.html, checked-by: th3/cov1/ctime02.test, matrix: context, detail)

          + +
          R-19406-19221-39828-63725-16599-34636-45225-33176
          +

          The destructor will also be invoked if the call to sqlite3_create_module_v2() fails. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-19454-21689-24466-55871-29604-18048-60005-14723
          +

          The sqlite3_memory_highwater() routine returns the maximum value of sqlite3_memory_used() since the high-water mark was last reset. +(source: c3ref/memory_highwater.html, matrix: context, detail)

          + +
          R-19480-30968-40912-48323-17771-07927-20882-34034
          +

          It can be applied to strings, numbers, blobs or NULL and it always returns a result with the same value as the operand. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-19486-35828-58507-08873-52072-46615-25523-07720
          +

          If the UPDATE statement has no ORDER BY clause, then all rows that would be updated in the absence of the LIMIT clause are assembled in an arbitrary order before applying the LIMIT and OFFSET clauses to determine which are actually updated. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-19509-40356-60366-52142-26522-07330-31595-37095
          +

          Instead of a separate OFFSET clause, the LIMIT clause may specify two scalar expressions separated by a comma. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-19515-61262-57142-56165-47391-12804-63366-22975
          +

          If there is no match, a NULL pointer is returned. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-19553-64528-24132-56992-22388-20387-05422-50188
          +

          Total() never throws an integer overflow. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-19570-53558-20410-64757-41149-53677-54257-63723
          +

          It is an error to specify a compress function without also specifying an uncompress function. +(source: fts3.html, matrix: context, detail)

          + +
          R-19604-19849-22831-12858-52721-48914-18931-47249
          +

          The sqlite3_str_reset(X) method resets the string under construction inside sqlite3_str object X back to zero bytes in length. +(source: c3ref/str_append.html, matrix: context, detail)

          + +
          R-19619-42762-44736-08897-02902-26192-57996-46412
          +

          The INDEXED BY and NOT INDEXED clauses are not allowed on UPDATE statements within triggers. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-19619-54598-52217-51985-41765-58210-14890-62978
          +

          The first argument to the busy handler is a copy of the void* pointer which is the third argument to sqlite3_busy_handler(). +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-19628-13587-38733-35705-07447-40697-34819-47467
          +

          SQLite holds a write transaction open on the destination database file for the duration of the backup operation. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup01.test, matrix: context, detail)

          + +
          R-19648-30943-40070-65065-35301-05411-03146-42916
          +

          This option takes three additional arguments that determine the lookaside memory allocator configuration for the database connection. +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-19660-56479-36342-33235-14845-36400-09046-33188
          +

          The result of sum() is an integer value if all non-NULL inputs are integers. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-19672-38383-43870-63614-05691-24053-06228-32918
          +

          The BEGIN command only works if the transaction stack is empty, or in other words if there are no pending transactions. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-19673-40972-58319-61162-14300-46572-05681-35590
          +

          If executing the SELECT would return no rows at all, then the EXISTS operator evaluates to 0. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-19696-22724-31246-18328-34316-54250-32558-13544
          +

          If logging is enabled, the zFormat string and subsequent arguments are used with sqlite3_snprintf() to generate the final output string. +(source: c3ref/log.html, checked-by: th3/cov1/log01.test, matrix: context, detail)

          + +
          R-19757-35036-22658-29796-35090-49616-44864-00036
          +

          The current value of the parameter is returned into *pCurrent. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-19785-02834-31233-04888-56980-35561-24739-27802
          +

          This pragma is a wrapper around the sqlite3_wal_autocheckpoint() C interface. +(source: pragma.html, matrix: context, detail)

          + +
          R-19803-45884-64369-17915-53923-43638-05068-02663
          +

          If an action is not explicitly specified, it defaults to "NO ACTION". +(source: foreignkeys.html, checked-by: src/parse.y, tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-19808-29370-64330-18475-42910-48751-21092-02221
          +

          The xDestroy() method is used to delete a cache allocated by xCreate(). +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-19812-36779-26037-25587-55568-01966-51571-26935
          +

          If one operand is NULL and the other is not, then the IS operator evaluates to 0 (false) and the IS NOT operator is 1 (true). +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-19827-62289-58446-52993-02249-28252-12913-58361
          +

          If both virtual terms end up being used as constraints on an index, then the original BETWEEN term is omitted and the corresponding test is not performed on input rows. +(source: optoverview.html, matrix: context, detail)

          + +
          R-19836-11244-52903-63249-46309-23850-25183-00208
          +

          Example: X'53514C697465' +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-19846-48503-04889-44735-07429-55750-55258-63586
          +

          The value returned by sqlite3_msize(X) might be larger than the number of bytes requested when X was allocated. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-19854-42126-27972-10302-08269-22410-63996-33681
          +

          There are three arguments to SQLITE_CONFIG_HEAP: An 8-byte aligned pointer to the memory, the number of bytes in the memory buffer, and the minimum allocation size. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-19878-23484-53576-16359-03133-43197-12770-47752
          +

          Let M be ((U-12)*32/255)-23 and let K be M+((P-M)%(U-4)). If P is greater than X then the number of bytes stored on the table b-tree leaf page is K if K is less or equal to X or M otherwise. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-19879-20948-53153-63685-13139-09400-29655-64256
          +

          VACUUM (but not VACUUM INTO) is a write operation and so if another database connection is holding a lock that prevents writes, then the VACUUM will fail. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-19884-42355-59719-29955-34222-13016-47876-51670
          +

          The sqlite3_preupdate_new(D,N,P) interface writes into P a pointer to a protected sqlite3_value that contains the value of the Nth column of the table row after it is updated. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-19885-09448-58561-44146-11128-00310-35686-58085
          +

          The names of internal schema objects always begin with "sqlite_" and any table, index, view, or trigger whose name begins with "sqlite_" is an internal schema object. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-19920-11576-34548-21403-56992-25102-09000-41133
          +

          However, newer versions of SQLite still avoid using the last six entries in the freelist trunk page array in order that database files created by newer versions of SQLite can be read by older versions of SQLite. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-19971-54976-54556-37696-16686-39038-59563-20085
          +

          Configuring "NO ACTION" means just that: when a parent key is modified or deleted from the database, no special action is taken. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-19982-00724-51550-61529-52295-40817-37605-44623
          +

          If pStmt is NULL then this interface returns a pointer to the first prepared statement associated with the database connection pDb. +(source: c3ref/next_stmt.html, checked-by: th3/cov1/vdbeapi04.test, matrix: context, detail)

          + +
          R-20022-00570-36475-01777-57661-23786-03560-20337
          +

          The byte-order of UTF16 input text is determined by the byte-order mark (BOM, U+FEFF) found in first character, which is removed, or in the absence of a BOM the byte order is the native byte order of the host machine for sqlite3_bind_text16() or the byte order specified in the 6th parameter for sqlite3_bind_text64(). +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-20051-05832-30877-26776-57299-30715-57449-61816
          +

          On windows, the first component of an absolute path is a drive specification (e.g. "C:"). +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-20053-18593-57587-13858-53773-26981-59084-43132
          +

          The X argument is a pointer to a string which is the unexpanded SQL text of the prepared statement or an SQL comment that indicates the invocation of a trigger. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-20111-12873-06694-53393-06638-09093-12890-49161
          +

          In order to succeed, the database connection must not be in autocommit mode when sqlite3_snapshot_open(D,S,P) is called. +(source: c3ref/snapshot_open.html, matrix: context, detail)

          + +
          R-20124-57769-12967-06011-36499-08186-14693-61176
          +

          If a schema-name is specified, then the view is created in the specified database. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-20149-25884-15163-16334-64710-02284-04877-02507
          +

          the following declaration does not result in "x" being an alias for the rowid: CREATE TABLE t(x INTEGER PRIMARY KEY DESC, y, z); +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-20205-17349-17235-26223-03175-26249-31726-44344
          +

          If the WHERE clause is not present, all records in the table are deleted. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-20205-54808-33054-53571-46292-49413-32449-15224
          +

          These expressions are similar to the expressions following the SELECT keyword in a SELECT statement in that they define the values of the columns in the result set. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-20210-23164-18665-04349-57984-05045-09964-53374
          +

          Unregister a VFS with the sqlite3_vfs_unregister() interface. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-20235-14821-33939-37352-02301-46502-25259-56810
          +

          If the subquery uses LIMIT then the outer query may not have a WHERE clause. +(source: optoverview.html, matrix: context, detail)

          + +
          R-20244-07722-17778-50950-32360-26781-61977-13264
          +

          The list of integers in the stat column can optionally be followed by arguments, each of which is a sequence of non-space characters. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-20262-06249-08007-38401-43127-56610-34465-06889
          +

          No rollback journal is ever created and hence there is never a rollback journal to delete. +(source: pragma.html, checked-by: th3/req1/pragma25.test, matrix: context, detail)

          + +
          R-20264-55497-15889-55738-11694-39322-19970-05132
          +

          However, just because this routine returns a positive number does not mean that one or more rows of data will be returned. +(source: c3ref/column_count.html, matrix: context, detail)

          + +
          R-20339-64003-24275-14776-38996-63966-02497-20063
          +

          Format 4 causes SQLite to respect the DESC keyword on index declarations. +(source: fileformat2.html, checked-by: th3/req1/fileformat01.test, matrix: context, detail)

          + +
          R-20409-33051-08329-62436-45384-49643-45094-34288
          +

          The avg() function returns the average value of all non-NULL X within a group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-20413-39093-25878-54576-60732-55561-33363-27302
          +

          The first four bytes of each overflow page are a big-endian integer which is the page number of the next page in the chain, or zero for the final page in the chain. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-20467-43422-30485-36826-60194-40272-32740-00331
          +

          If an expression has an OFFSET clause, then the first M rows are omitted from the result set returned by the SELECT statement and the next N rows are returned, where M and N are the values that the OFFSET and LIMIT clauses evaluate to, respectively. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-20474-44465-10719-25363-46434-31101-34097-17120
          +

          Normally, the database page_size and whether or not the database supports auto_vacuum must be configured before the database file is actually created. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-20486-33667-53440-39666-65031-09323-37959-22013
          +

          The content of the sqlite_sequence table can be modified using ordinary UPDATE, INSERT, and DELETE statements. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-20520-54086-20387-28345-20691-46445-65238-30953
          +

          If SQLite is compiled with the SQLITE_THREADSAFE=0 compile-time option then it is not possible to set the Multi-thread threading mode and sqlite3_config() will return SQLITE_ERROR if called with the SQLITE_CONFIG_MULTITHREAD configuration option. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-20556-35657-32764-17566-55966-02395-47898-45086
          +

          If the 4th parameter to the sqlite3_result_text* interfaces or sqlite3_result_blob is the special constant SQLITE_TRANSIENT then SQLite makes a copy of the result into space obtained from sqlite3_malloc() before it returns. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-20560-39162-53987-29912-13699-13892-53398-21192
          +

          The UNION operator works the same way as UNION ALL, except that duplicate rows are removed from the final result set. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-20568-61871-33672-25407-24732-44471-23157-56477
          +

          . +(source: whynotgit.html, matrix: context, detail)

          + +
          R-20589-01955-18800-07127-42802-30893-02013-32671
          +

          SQLITE_OPEN_URI The filename can be interpreted as a URI if this flag is set. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-20590-08726-45565-50300-40304-23510-62801-34037
          +

          It is an error to specify a value for the mode parameter that is less restrictive than that specified by the flags passed in the third parameter to sqlite3_open_v2(). +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-20609-23860-31620-63775-42539-11534-17004-18607
          +

          The rollback journal file is always located in the same directory as the database file and has the same name as the database file but with the string "-journal" appended. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-20637-43463-07167-46903-44256-61988-15144-63319
          +

          A simple SELECT statement is an aggregate query if it contains either a GROUP BY clause or one or more aggregate functions in the result-set. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-20643-25656-58463-39709-46255-05856-32679-34239
          +

          The sqlite3_data_count(P) interface returns the number of columns in the current row of the result set of prepared statement P. +(source: c3ref/data_count.html, checked-by: th3/th3util.c, matrix: context, detail)

          + +
          R-20665-17792-14135-29123-51100-08894-37624-05824
          +

          The result of any binary operator is either a numeric value or NULL, except for the || concatenation operator which always evaluates to either NULL or a text value. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-20690-50594-54745-63542-12245-05150-52761-00851
          +

          The second field of the b-tree page header is the offset of the first freeblock, or zero if there are no freeblocks on the page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-20707-34919-04305-11410-25646-43791-21158-43878
          +

          If there are many OR terms in the WHERE clause or if some of the indexes on individual OR-clause subterms are not very selective, then SQLite might decide that it is faster to use a different query algorithm, or even a full-table scan. +(source: optoverview.html, matrix: context, detail)

          + +
          R-20728-12013-63789-14843-17871-12981-47663-15474
          +

          Parentheses around the column name are ignored. Hence if X and Y.Z are column names, then (X) and (Y.Z) are also considered column names and have the affinity of the corresponding columns. +(source: datatype3.html, matrix: context, detail)

          + +
          R-20762-60389-11004-15746-05973-23268-57265-62679
          +

          The sqlite_schema table contains one row for each table, index, view, and trigger (collectively "objects") in the database schema, except there is no entry for the sqlite_schema table itself. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-20765-15127-44657-52295-11493-39499-43241-33689
          +

          The time value is followed by zero or more modifiers. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-20784-11852-57325-61888-34040-48421-29147-36386
          +

          Metadata is returned by writing to the memory locations passed as the 5th and subsequent parameters to this function. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-20790-14025-05441-59886-17616-40247-63857-04714
          +

          The sqlite3_threadsafe() function returns zero if and only if SQLite was compiled with mutexing code omitted due to the SQLITE_THREADSAFE compile-time option being set to 0. +(source: c3ref/threadsafe.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-20795-39479-27238-02391-59931-28698-11385-12447
          +

          The column is used in the expression of a generated column. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-20796-14963-19630-14669-08622-46367-39917-03067
          +

          This function causes all database schemas to be read from disk and parsed, if that has not already been done, and returns an error if any errors are encountered while loading the schema. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-20854-17109-31337-20710-58230-10583-22919-16758
          +

          A CAST conversion is similar to the conversion that takes place when a column affinity is applied to a value except that with the CAST operator the conversion always takes place even if the conversion lossy and irreversible, whereas column affinity only changes the data type of a value if the change is lossless and reversible. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-20857-32692-20795-02101-46664-36777-53557-28223
          +

          The sqlite3_int64 and sqlite_int64 types can store integer values between -9223372036854775808 and +9223372036854775807 inclusive. +(source: c3ref/int64.html, checked-by: th3/req1/int64_01.test, matrix: context, detail)

          + +
          R-20915-35810-14572-42507-50726-14071-51730-17527
          +

          The second form of the pragma listed above is used to set a new limit in bytes for the specified database. +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-20958-54138-45241-50664-65336-36333-30654-63832
          +

          An attempt to write to an expired BLOB handle fails with an error code of SQLITE_ABORT. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-20974-45876-55609-02198-26922-65375-59673-02037
          +

          Some systems (for example, Windows 95) do not support the operation implemented by sqlite3_mutex_try(). On those systems, sqlite3_mutex_try() will always return SQLITE_BUSY. The SQLite core only ever uses sqlite3_mutex_try() as an optimization so this is acceptable behavior. +(source: c3ref/mutex_alloc.html, checked-by: th3/th3mutex.c, matrix: context, detail)

          + +
          R-20983-25183-16317-48719-00472-39133-57551-19276
          +

          If sqlite3_config() is called after sqlite3_initialize() and before sqlite3_shutdown() then it will return SQLITE_MISUSE. +(source: c3ref/config.html, matrix: context, detail)

          + +
          R-21003-54221-59589-12513-12600-39825-11085-16301
          +

          The rowid is always available as an undeclared column named ROWID, OID, or _ROWID_ as long as those names are not also used by explicitly declared columns. +(source: c3ref/last_insert_rowid.html, checked-by: th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-21024-07855-27912-21826-13192-43444-47677-34434
          +

          The primary key columns appear in the order they they were declared in the PRIMARY KEY clause and the remaining columns appear in the order they occur in the CREATE TABLE statement. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-21115-58321-25716-23770-11415-21637-17771-56749
          +

          If a column-name list is specified, then the number of values in each term of the VALUE list must match the number of specified columns. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-21148-64834-51953-28586-58289-58298-04009-03354
          +

          The "INSERT INTO table DEFAULT VALUES" form of the INSERT statement is not supported. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-21156-19645-52425-35799-35184-17104-33723-09061
          +

          If the third parameter to sqlite3_bind_text64() is not NULL, then it should be a pointer to a well-formed unicode string that is either UTF8 if the sixth parameter is SQLITE_UTF8, or UTF16 otherwise. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-21171-34919-23602-58467-34631-37001-49601-29313
          +

          The eParentWithin and rParentScore values are copies of the eWithin and rScore values from the containing subtree of the current row. +(source: rtree.html, matrix: context, detail)

          + +
          R-21182-58169-20146-54960-02459-65291-16580-58190
          +

          The replace(X,Y,Z) function returns a string formed by substituting string Z for every occurrence of string Y in string X. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-21205-43338-53386-10621-24475-38034-05751-45938
          +

          When sqlite3_hard_heap_limit64(N) is invoked and the soft heap limit is outside the range of 1. +(source: c3ref/hard_heap_limit64.html, matrix: context, detail)

          + +
          R-21228-24308-16193-26156-01988-42098-33808-34150
          +

          The sqlite3_cancel_auto_extension(X) interface unregisters the initialization routine X that was registered using a prior call to sqlite3_auto_extension(X). +(source: c3ref/cancel_auto_extension.html, matrix: context, detail)

          + +
          R-21228-58399-13607-54712-08787-36573-11741-23051
          +

          If M is greater than zero then after M page records the journal file may be zero padded out to the next multiple of the sector size and another journal header may be inserted. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-21274-02227-62864-03639-07150-27166-13487-20730
          +

          The sqlite3_interrupt(D) call is in effect until all currently running SQL statements on database connection D complete. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-21320-14810-43799-05408-58279-13675-12785-56952
          +

          The wal_checkpoint pragma returns a single row with three integer columns. +(source: pragma.html, checked-by: th3/req1/pragma29.test, matrix: context, detail)

          + +
          R-21426-10262-16472-16411-19241-49098-31695-43338
          +

          The path component of the URI specifies the disk file that is the SQLite database to be opened. +(source: uri.html, matrix: context, detail)

          + +
          R-21490-41092-09920-20398-33812-50363-51367-35594
          +

          The first form (with the "VALUES" keyword) creates one or more new rows in an existing table. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-21508-14355-30725-13403-38836-44113-60272-57161
          +

          The third argument (eTextRep) must be one of the constants: SQLITE_UTF8, SQLITE_UTF16LE, SQLITE_UTF16BE, SQLITE_UTF16, or SQLITE_UTF16_ALIGNED. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-21527-28967-38710-01216-03543-44346-41120-54609
          +

          If, however, all columns that were to be fetched from the table are already available in the index itself, SQLite will use the values contained in the index and will never look up the original table row. +(source: optoverview.html, matrix: context, detail)

          + +
          R-21555-60916-58264-59419-46832-30971-06241-53598
          +

          No storage class conversions occur before the sort. +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-21599-16038-23557-29825-04044-13537-53990-06867
          +

          In SQLite, a foreign key constraint is permanently marked as deferred or immediate when it is created. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys23.test, matrix: context, detail)

          + +
          R-21637-36677-40497-35509-61399-46252-57328-58576
          +

          If a term in X is of the form "z IS NOT NULL" and if a term in W is a comparison operator on "z" other than "IS", then those terms match. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-21674-26855-05967-15589-29302-41964-38112-11067
          +

          The rowid of the SQL table is the 64-bit signed integer key for each entry in the table b-tree. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-21752-26913-20480-58251-45591-43193-62846-17726
          +

          The defer_foreign_keys pragma is automatically switched off at each COMMIT or ROLLBACK. Hence, the defer_foreign_keys pragma must be separately enabled for each transaction. +(source: pragma.html, checked-by: tcl/fkey6.test, th3/cov1/fkey24.test, matrix: context, detail)

          + +
          R-21769-42523-56036-07125-49513-08938-03164-12762
          +

          For example, if an application defines a function "eval()" that calls sqlite3_exec(), then the following SQL statement would change the database file through side-effects: SELECT eval('DELETE FROM t1') FROM t2; But because the SELECT statement does not change the database file directly, sqlite3_stmt_readonly() would still return true. +(source: c3ref/stmt_readonly.html, checked-by: th3/cov1/vdbeapi14.test, matrix: context, detail)

          + +
          R-21806-43221-13311-12534-07273-62377-06740-15345
          +

          The sqlite3_initialize() routine returns SQLITE_OK on success. +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-21827-30701-03148-53639-55860-16366-16292-16032
          +

          The vfs query parameter causes the database connection to be opened using the VFS called NAME. +(source: uri.html, matrix: context, detail)

          + +
          R-21827-60920-49018-16791-65129-33759-13224-63617
          +

          Example: Let the index be CREATE INDEX ex2 ON tab2(b,c) WHERE c IS NOT NULL; Then any query that uses operators =, <, >, <=, >=, <>, IN, LIKE, or GLOB on column "c" would be usable with the partial index because those comparison operators are only true if "c" is not NULL. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-21829-14563-51248-28780-63073-47174-17671-25024
          +

          When casting a BLOB value to INTEGER, the value is first converted to TEXT. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-21869-50933-18898-03814-15794-26050-32013-17586
          +

          The sqlite_stat1.tbl column is the name of the table to which the index belongs. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-21873-57098-57834-11008-20676-08257-29659-57534
          +

          For backwards compatibility, the "0x" hexadecimal integer notation is only understood by the SQL language parser, not by the type conversions routines. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-21898-42697-02847-18633-49907-40744-21589-01331
          +

          The DBSTAT virtual table is an eponymous virtual table, meaning that is not necessary to run CREATE VIRTUAL TABLE to create an instance of the dbstat virtual table before using it. +(source: dbstat.html, matrix: context, detail)

          + +
          R-21926-12440-51056-61142-44683-61094-56845-29582
          +

          A column with TEXT affinity stores all data using storage classes NULL, TEXT or BLOB. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-21999-45122-31048-13446-02528-26470-06317-22169
          +

          The sqlite3_update_hook() interface registers a callback function with the database connection identified by the first argument to be invoked whenever a row is updated, inserted or deleted in a rowid table. +(source: c3ref/update_hook.html, checked-by: tcl/hook.test, th3/cov1/main15.test, matrix: context, detail)

          + +
          R-22035-46182-36006-24131-28314-61788-09848-09790
          +

          The SQLITE_CONFIG_GETPCACHE2 option takes a single argument which is a pointer to an sqlite3_pcache_methods2 object. SQLite copies of the current page cache implementation into that object. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3pcache.c, matrix: context, detail)

          + +
          R-22036-37196-51098-25883-36361-04038-28343-30035
          +

          The sqlite3_result_error_nomem() interface causes SQLite to throw an error indicating that a memory allocation failed. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-22070-59472-34995-42069-63414-37359-02285-11048
          +

          If a term consists of multiple subterms containing a common column name and separated by OR, like this: column = expr1 OR column = expr2 OR column = expr3 OR ... Then that term is rewritten as follows: column IN (expr1,expr2,expr3,...) +(source: optoverview.html, matrix: context, detail)

          + +
          R-22130-30551-62458-54742-21400-01108-16464-06661
          +

          On success, the sqlite3_snapshot_get(D,S,P) interface writes a pointer to the newly created sqlite3_snapshot object into *P and returns SQLITE_OK. +(source: c3ref/snapshot_get.html, matrix: context, detail)

          + +
          R-22138-49689-43749-53930-34571-29718-47006-51402
          +

          The string returned by sqlite_source_id() is the date and time that the source code was checked in followed by the SHA3-256 hash for that check-in. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-22182-18548-50904-36957-63145-12902-60404-23884
          +

          For example, an UPDATE statement might have a WHERE clause that makes it a no-op, but the sqlite3_stmt_readonly() result would still be false. +(source: c3ref/stmt_readonly.html, matrix: context, detail)

          + +
          R-22232-40047-05023-56174-19457-36430-27942-49450
          +

          The particular operator is stored in aConstraint[].op using one of the SQLITE_INDEX_CONSTRAINT_ values. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-22235-47006-02687-15500-56774-48140-19704-63768
          +

          Casting an INTEGER or REAL value into TEXT renders the value as if via sqlite3_snprintf() except that the resulting TEXT uses the encoding of the database connection. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-22239-33740-47135-11952-01366-26065-00899-21193
          +

          A subquery that returns two or more columns is a row value subquery and can only be used as the operand of a comparison operator. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-22283-14179-18327-11516-19708-03741-18136-56509
          +

          Tables are removed using the DROP TABLE statement. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-22304-13691-20726-05433-26877-46116-43863-25024
          +

          In practice, metadata is preserved between function calls for function parameters that are compile-time constants, including literal values and parameters and expressions composed from the same. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-22309-26004-04913-07405-19734-55428-18120-53442
          +

          The profile callback contains the original statement text and an estimate of wall-clock time of how long that statement took to run. +(source: c3ref/profile.html, checked-by: th3/cov1/main16.test, matrix: context, detail)

          + +
          R-22338-33270-38633-54292-24133-20932-49452-38355
          +

          If N is less than one then the progress handler is disabled. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-22347-12719-38657-19900-45791-11174-27141-23723
          +

          When a configuration option is set, sqlite3_config() returns SQLITE_OK. +(source: c3ref/config.html, matrix: context, detail)

          + +
          R-22391-07186-37161-38876-45465-63159-33403-63078
          +

          Note that if one of the dynamic mutex parameters (SQLITE_MUTEX_FAST or SQLITE_MUTEX_RECURSIVE) is used then sqlite3_mutex_alloc() returns a different mutex on every call. +(source: c3ref/mutex_alloc.html, checked-by: th3/cov1/mutex01.test, matrix: context, detail)

          + +
          R-22414-48736-05483-33334-64418-18410-20572-40044
          +

          A COLLATE operator has the same affinity as its left-hand side operand. +(source: datatype3.html, matrix: context, detail)

          + +
          R-22464-05974-13353-12575-31195-54661-61656-32852
          +

          The expression of a generated column can refer to any of the other declared columns in the table, including other generated columns, as long as the expression does not directly or indirectly refer back to itself. +(source: gencol.html, matrix: context, detail)

          + +
          R-22484-49535-05658-48568-12441-17149-15045-25439
          +

          Leading spaces are removed. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-22504-36456-63205-11923-40332-44268-43890-46191
          +

          In first form, if the main database has already been created, then this pragma returns the text encoding used by the main database, one of 'UTF-8', 'UTF-16le' (little-endian UTF-16 encoding) or 'UTF-16be' (big-endian UTF-16 encoding). +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-22511-33242-53982-27627-41881-51518-34601-24400
          +

          This is the number of times that the prepared statement has been run. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-22517-03298-06877-11770-25908-54043-03696-50918
          +

          The FTS4 prefix option causes FTS to index term prefixes of specified lengths in the same way that it always indexes complete terms. +(source: fts3.html, matrix: context, detail)

          + +
          R-22528-31592-23814-33593-53187-04400-51621-15631
          +

          The following two queries are not equivalent: SELECT * FROM tab1 LEFT JOIN tab2 ON tab1.x=tab2.y; SELECT * FROM tab1 LEFT JOIN tab2 WHERE tab1.x=tab2.y; +(source: optoverview.html, matrix: context, detail)

          + +
          R-22564-11647-52151-33857-28940-09855-65445-38014
          +

          The header begins with a single varint which determines the total number of bytes in the header. The varint value is the size of the header in bytes including the size varint itself. +(source: fileformat2.html, checked-by: src/vdbe.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-22567-44039-44321-46904-30045-11816-43845-22039
          +

          The PRAGMA foreign_keys command is a no-op in this configuration. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys05.test, matrix: context, detail)

          + +
          R-22624-19349-43907-49115-55409-14540-64613-59655
          +

          Terms of the WHERE clause can be manually disqualified for use with indexes by prepending a unary + operator to the column name. +(source: optoverview.html, matrix: context, detail)

          + +
          R-22655-13879-23181-45430-34065-63005-59196-64005
          +

          The coalesce() function returns a copy of its first non-NULL argument, or NULL if all arguments are NULL. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-22662-28218-11402-23235-34288-43676-21619-60718
          +

          If there is no prefix that can be interpreted as a real number, the result of the conversion is 0.0. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-22671-22821-00746-11610-44216-38779-63984-03906
          +

          The orderByConsumed means that output from xFilter/xNext will occur in the correct order to satisfy the ORDER BY clause so that no separate sorting step is required. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-22671-54036-59271-48827-17148-12128-60554-20551
          +

          If argvIndex>0 then the right-hand side of the corresponding aConstraint[] is evaluated and becomes the argvIndex-th entry in argv. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-22710-53328-59796-08773-22880-08291-09347-39531
          +

          The third and fourth bytes of each freeblock form a big-endian integer which is the size of the freeblock in bytes, including the 4-byte header. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-22724-45533-32532-12289-36170-43581-26380-53780
          +

          if there is only a single global wildcard to the right of x, then the original LIKE or GLOB test is disabled. +(source: optoverview.html, matrix: context, detail)

          + +
          R-22771-48210-15439-13040-38130-20286-36509-06208
          +

          The number of bytes stored on the leaf page is never less than M. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-22776-52830-07659-57324-38629-30744-28731-31224
          +

          For each pair of named columns, the expression "lhs.X = rhs.X" is evaluated for each row of the cartesian product as a boolean expression. Only rows for which all such expressions evaluates to true are included from the result set. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-22782-22472-63620-46521-58776-65513-25083-63478
          +

          Names are zero-terminated UTF-8 strings. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-22795-48828-40923-07115-03137-30466-52786-33478
          +

          If X is a BLOB then the indices refer to bytes. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-22799-40241-49763-48856-12252-38243-16002-08188
          +

          The sqlite3_status() and sqlite3_status64() routines return SQLITE_OK on success and a non-zero error code on failure. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-22849-20349-24730-37218-10911-22554-30363-05607
          +

          If a floating point value that can be represented exactly as an integer is inserted into a column with NUMERIC affinity, the value is converted into an integer. +(source: datatype3.html, matrix: context, detail)

          + +
          R-22861-02843-39646-61037-38089-35502-27977-11188
          +

          Zero all sqlite3_stmt_scanstatus() related event counters. +(source: c3ref/stmt_scanstatus_reset.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-22868-25880-64801-36236-02118-32586-25357-26503
          +

          The LIKE operator can be made case sensitive using the case_sensitive_like pragma. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-22872-18005-62981-26187-32897-04943-19086-58374
          +

          But the "PRAGMA cache_spill=N" form of this statement only applies to the "main" schema or whatever other schema is specified as part of the statement. +(source: pragma.html, matrix: context, detail)

          + +
          R-22887-63324-57928-49032-58189-23826-57467-19364
          +

          The unlikely(X) function is a no-op that the code generator optimizes away so that it consumes no CPU cycles at run-time (that is, during calls to sqlite3_step()). +(source: lang_corefunc.html, checked-by: tcl/func3.test, matrix: context, detail)

          + +
          R-22934-25134-31918-65183-03263-52759-06599-24509
          +

          Comments are treated as whitespace by the parser. +(source: lang_comment.html, checked-by: src/tokenize.c, matrix: context, detail)

          + +
          R-22956-37754-14278-17642-05627-50863-58555-30245
          +

          Casting to a BLOB consists of first casting the value to TEXT in the encoding of the database connection, then interpreting the resulting byte sequence as a BLOB instead of as TEXT. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-22973-56658-43836-32419-61759-38607-43348-03721
          +

          SQLite will make this determination, but only if it has been compiled with SQLITE_ENABLE_STAT3 or SQLITE_ENABLE_STAT4. +(source: optoverview.html, matrix: context, detail)

          + +
          R-23019-08375-23742-45203-57540-44774-03255-16704
          +

          When case_sensitive_like is enabled, case becomes significant. So, for example, 'a' LIKE 'A' is false but 'a' LIKE 'a' is still true. +(source: pragma.html, checked-by: th3/req1/pragma10.test, matrix: context, detail)

          + +
          R-23025-34321-53440-17551-64635-00032-03474-62946
          +

          The maximum page count cannot be reduced below the current database size. +(source: pragma.html, checked-by: th3/req1/pragma12.test, matrix: context, detail)

          + +
          R-23027-03515-05606-08970-61667-55431-59935-24913
          +

          Setting it to "shared" is equivalent to setting the SQLITE_OPEN_SHAREDCACHE bit in the flags argument passed to sqlite3_open_v2(). +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-23027-35758-08796-19756-16363-24577-05722-25269
          +

          The size of the blob (and hence the maximum value of N+iOffset) can be determined using the sqlite3_blob_bytes() interface. +(source: c3ref/blob_read.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-23038-23996-21339-41009-49120-44197-27486-19934
          +

          If a database connection is operating in exclusive locking mode or in persistent journal mode (PRAGMA journal_mode=persist) then after committing a transaction the rollback journal file may remain in the file-system. +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-23075-39245-36315-44421-23373-63820-24651-07544
          +

          This modifier causes the DDDDDDDDDD to be interpreted not as a Julian day number as it normally would be, but as Unix Time - the number of seconds since 1970. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-23110-47146-52080-06643-60978-41760-17507-36913
          +

          the parser allows the use of the single keyword REPLACE as an alias for "INSERT OR REPLACE". +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-23114-21695-36244-34709-35067-61095-03657-31992
          +

          The auxiliary index-columns are not shown by the index_info pragma, but they are listed by the index_xinfo pragma. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-23120-24122-52717-58793-54182-36500-02638-57419
          +

          After an application receives an SQLITE_LOCKED error, it may call the sqlite3_unlock_notify() method with the blocked connection handle as the first argument to register for a callback that will be invoked when the blocking connections current transaction is concluded. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-23149-10450-31226-11876-31056-64303-42616-45384
          +

          The second parameter is either the name of the database (i.e. "main", "temp", or an attached database) containing the specified table or NULL. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-23153-04437-57288-59301-62447-22408-58278-59491
          +

          A column whose declared type is "CHARINT" will match both rules 1 and 2 but the first rule takes precedence and so the column affinity will be INTEGER. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-23155-55597-19897-49290-61770-15838-04803-37418
          +

          Otherwise, if a simple SELECT contains no aggregate functions or a GROUP BY clause, it is a non-aggregate query. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-23182-54295-50785-24596-08451-02370-06326-41675
          +

          The cache parameter may be set to either "shared" or "private". +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-23205-44230-04357-26544-42483-62148-64483-35199
          +

          Query or change a limit on the approximate ANALYZE setting. This is approximate number of rows examined in each index by the ANALYZE command. +(source: pragma.html, matrix: context, detail)

          + +
          R-23293-62447-32888-51584-58025-47542-61505-16122
          +

          If the OFFSET clause evaluates to a negative value, the results are the same as if it had evaluated to zero. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-23299-15149-12260-14236-54625-56854-20927-10236
          +

          The sqlite3_value_numeric_type() interface attempts to apply numeric affinity to the value. This means that an attempt is made to convert the value to an integer or floating point. If such a conversion is possible without loss of information (in other words, if the value is a string that looks like a number) then the conversion is performed. Otherwise no conversion occurs. The datatype after conversion is returned. +(source: c3ref/value_blob.html, checked-by: th3/req1/value02.test, th3/req1/value03.test, matrix: context, detail)

          + +
          R-23302-30956-02464-62581-38265-62787-52147-51200
          +

          If this SELECT returns any rows at all, then SQLite concludes that deleting the row from the parent table would violate the foreign key constraint and returns an error. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys10.test, matrix: context, detail)

          + +
          R-23313-12651-48093-62761-39865-28601-55555-42424
          +

          Call the second integer on a freelist trunk page L. If L is greater than zero then integers with array indexes between 2 and L+1 inclusive contain page numbers for freelist leaf pages. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-23317-43079-57684-22333-28404-22394-54055-23674
          +

          The rtrim(X,Y) function returns a string formed by removing any and all characters that appear in Y from the right side of X. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-23332-64992-62836-09715-29451-35524-14907-15195
          +

          The sqlite3_stmt_readonly(X) interface returns true (non-zero) if and only if the prepared statement X makes no direct changes to the content of the database file. +(source: c3ref/stmt_readonly.html, checked-by: th3/cov1/vdbeapi14.test, matrix: context, detail)

          + +
          R-23336-07085-33379-01813-11813-48961-61224-20101
          +

          The new column is always appended to the end of the list of existing columns. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-23360-48280-32877-53646-44675-29604-63391-63755
          +

          Rows for which the expression is false or NULL are retained. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-23378-42536-56340-49562-54695-41894-41223-62715
          +

          The second is a copy of the database handle. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-23385-34636-24682-17782-28236-64093-44026-01327
          +

          Applications can update, delete from, insert into or drop the sqlite_stat1 table, but may not create or alter the sqlite_stat1 table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-23388-15416-08272-50703-43179-31884-02828-12043
          +

          SQLITE_DBSTATUS_LOOKASIDE_HIT This parameter returns the number of malloc attempts that were satisfied using lookaside memory. Only the high-water value is meaningful; the current value is always zero. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-23445-46109-37360-43495-15091-19372-04158-40881
          +

          This pragma causes the database connection on which it is invoked to free up as much memory as it can, by calling sqlite3_db_release_memory(). +(source: pragma.html, checked-by: src/pragma.c, matrix: context, detail)

          + +
          R-23458-03780-07133-16857-18321-45188-49595-32402
          +

          Virtual tables can provide alternative implementations of functions using the xFindFunction method of the virtual table module. But global versions of those functions must exist in order to be overloaded. +(source: c3ref/overload_function.html, matrix: context, detail)

          + +
          R-23479-00031-14881-27531-19387-40447-21321-20674
          +

          Alternative collating functions for table columns can be specified in the CREATE TABLE statement using the COLLATE clause on the column definition. +(source: fileformat2.html, checked-by: th3/req1/fileformat05.test, matrix: context, detail)

          + +
          R-23486-28813-15662-33687-07998-38651-35612-02946
          +

          The SQLITE_ prefix is omitted from any strings returned by sqlite3_compileoption_get(). +(source: c3ref/compileoption_get.html, checked-by: th3/cov1/ctime01.test, matrix: context, detail)

          + +
          R-23498-38103-14789-32362-20893-18131-57271-11278
          +

          When the REPLACE conflict resolution strategy deletes rows in order to satisfy a constraint, delete triggers fire if and only if recursive triggers are enabled. +(source: lang_conflict.html, checked-by: th3/req1/conflict02.test, matrix: context, detail)

          + +
          R-23552-22587-27822-03022-61455-36680-30849-34520
          +

          If the MATCH operator is connected to other terms of the WHERE clause via an OR operator, for example, the query will fail with an error. +(source: rtree.html, checked-by: th3/cov1/rtree04.test, matrix: context, detail)

          + +
          R-23569-48727-57101-02184-22731-43304-31733-55704
          +

          UNIQUE and PRIMARY KEY constraints on tables cause SQLite to create internal indexes with names of the form "sqlite_autoindex_TABLE_N" where TABLE is replaced by the name of the table that contains the constraint and N is an integer beginning with 1 and increasing by one with each constraint seen in the table definition. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-23579-05241-28343-33967-00321-51471-16387-08197
          +

          PRAGMA busy_timeout; PRAGMA busy_timeout = milliseconds; Query or change the setting of the busy timeout. +(source: pragma.html, checked-by: tcl/lock.test, th3/cov1/main21.test, matrix: context, detail)

          + +
          R-23588-34450-24473-59625-33708-24256-58306-00821
          +

          The two-byte integer at offset 1 gives the start of the first freeblock on the page, or is zero if there are no freeblocks. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-23595-60076-32539-07407-36536-15376-05711-31213
          +

          The sqlite3_malloc64(N) routine works just like sqlite3_malloc(N) except that N is an unsigned 64-bit integer instead of a signed 32-bit integer. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-23612-42210-08607-14273-01110-55544-62379-11788
          +

          You can access the ROWID of an SQLite table using one of the special column names ROWID, _ROWID_, or OID. Except if you declare an ordinary table column to use one of those special names, then the use of that name will refer to the declared column not to the internal ROWID. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-23640-47263-12341-60168-43783-53275-58204-18225
          +

          The rollback journal file can be truncated to zero length +(source: fileformat2.html, matrix: context, detail)

          + +
          R-23648-58527-04335-61943-03061-32754-63941-35147
          +

          SQLite only understands upper/lower case for ASCII characters by default. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-23682-59820-57074-21944-19735-61329-41044-60872
          +

          By contrast, if foreign key errors can be recognized simply by looking at the definition of the child table and without having to consult the parent table definition, then the CREATE TABLE statement for the child table fails. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys08.test, matrix: context, detail)

          + +
          R-23702-41282-42393-06958-42086-21645-30380-61682
          +

          The path is optional if the authority is present. +(source: uri.html, matrix: context, detail)

          + +
          R-23735-03107-03121-47557-18096-07566-30916-33769
          +

          The likely(X) function returns the argument X unchanged. +(source: lang_corefunc.html, checked-by: tcl/func3.test, matrix: context, detail)

          + +
          R-23774-64117-15302-61921-22939-28381-40174-39816
          +

          The destructor is also invoked if the call to sqlite3_create_function_v2() fails. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc07.test, matrix: context, detail)

          + +
          R-23786-28684-07406-43966-34623-43310-02646-59578
          +

          The "PRAGMA cache_spill=boolean" form of this pragma applies across all databases attached to the database connection. +(source: pragma.html, matrix: context, detail)

          + +
          R-23828-03043-49392-48287-20383-19771-48629-15869
          +

          After at least "ms" milliseconds of sleeping, the handler returns 0 which causes sqlite3_step() to return SQLITE_BUSY. +(source: c3ref/busy_timeout.html, checked-by: th3/cov1/main21.test, matrix: context, detail)

          + +
          R-23882-45353-30604-47614-45882-29623-34325-59956
          +

          The cell pointer array of a b-tree page immediately follows the b-tree page header. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-23914-51476-03843-05689-25158-40099-03729-02958
          +

          A literal value can also be the token "NULL". +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-23927-54081-32743-59723-35169-61192-28393-34691
          +

          Each expression in the result-set is then evaluated once for each group of rows. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-23929-31743-58027-02127-28995-37198-56222-58306
          +

          These routines work just like the corresponding column access functions except that these routines take a single protected sqlite3_value object pointer instead of a sqlite3_stmt* pointer and an integer column number. +(source: c3ref/value_blob.html, checked-by: th3/req1/value02.test, th3/req1/value03.test, matrix: context, detail)

          + +
          R-23935-31469-05351-59076-27167-07827-26621-20596
          +

          If a RELEASE command releases the outermost savepoint, so that the transaction stack becomes empty, then RELEASE is the same as COMMIT. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-23955-02765-61832-08091-33535-52671-43903-30817
          +

          Cache_spill is enabled by default +(source: pragma.html, checked-by: tcl/pragma2.test, matrix: context, detail)

          + +
          R-23976-43329-40116-37521-45580-17979-29083-00221
          +

          It is an error to specify both a schema-name and the TEMP or TEMPORARY keyword, unless the schema-name is "temp". +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-23979-26855-11433-13886-36819-17221-39687-26769
          +

          The abs(X) function returns the absolute value of the numeric argument X. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/func01.test, matrix: context, detail)

          + +
          R-23980-43280-61587-10591-51567-45451-02507-40247
          +

          This interface causes the xEntryPoint() function to be invoked for each new database connection that is created. +(source: c3ref/auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-23980-48859-56951-38852-38346-56715-55568-02993
          +

          There is one exception: if the foreign key column in the track table is NULL, then no corresponding entry in the artist table is required. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys01.test, matrix: context, detail)

          + +
          R-23984-49501-37243-56289-03587-60124-22633-25227
          +

          PRAGMA ignore_check_constraints = boolean; This pragma enables or disables the enforcement of CHECK constraints. +(source: pragma.html, checked-by: th3/req1/pragma20.test, matrix: context, detail)

          + +
          R-23992-39183-25313-23566-64095-36776-23498-04069
          +

          Regardless of the compile-time configuration, any identifier that is not on the following 147 element list is not a keyword to the SQL parser in SQLite: ABORT ACTION ADD AFTER ALL ALTER ALWAYS ANALYZE AND AS ASC ATTACH AUTOINCREMENT BEFORE BEGIN BETWEEN BY CASCADE CASE CAST CHECK COLLATE COLUMN COMMIT CONFLICT CONSTRAINT CREATE CROSS CURRENT CURRENT_DATE CURRENT_TIME CURRENT_TIMESTAMP DATABASE DEFAULT DEFERRABLE DEFERRED DELETE DESC DETACH DISTINCT DO DROP EACH ELSE END ESCAPE EXCEPT EXCLUDE EXCLUSIVE EXISTS EXPLAIN FAIL FILTER FIRST FOLLOWING FOR FOREIGN FROM FULL GENERATED GLOB GROUP GROUPS HAVING IF IGNORE IMMEDIATE IN INDEX INDEXED INITIALLY INNER INSERT INSTEAD INTERSECT INTO IS ISNULL JOIN KEY LAST LEFT LIKE LIMIT MATCH MATERIALIZED NATURAL NO NOT NOTHING NOTNULL NULL NULLS OF OFFSET ON OR ORDER OTHERS OUTER OVER PARTITION PLAN PRAGMA PRECEDING PRIMARY QUERY RAISE RANGE RECURSIVE REFERENCES REGEXP REINDEX RELEASE RENAME REPLACE RESTRICT RETURNING RIGHT ROLLBACK ROW ROWS SAVEPOINT SELECT SET TABLE TEMP TEMPORARY THEN TIES TO TRANSACTION TRIGGER UNBOUNDED UNION UNIQUE UPDATE USING VACUUM VALUES VIEW VIRTUAL WHEN WHERE WINDOW WITH WITHOUT +(source: lang_keywords.html, checked-by: th3/req1/keyword01.test, matrix: context, detail)

          + +
          R-23992-54131-34297-51092-28105-58242-15143-29320
          +

          If the "TEMP" or "TEMPORARY" keyword occurs in between "CREATE" and "VIEW" then the view that is created is only visible to the database connection that created it and is automatically deleted when the database connection is closed. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-24016-17929-42002-59431-23117-37264-43384-47268
          +

          C-style comments can span multiple lines. +(source: lang_comment.html, checked-by: th3/req1/comment01.test, matrix: context, detail)

          + +
          R-24023-61156-56094-16008-29634-01440-59018-40109
          +

          The mode query parameter determines if the new database is opened read-only, read-write, read-write and created if it does not exist, or that the database is a pure in-memory database that never interacts with disk, respectively. +(source: uri.html, matrix: context, detail)

          + +
          R-24078-09375-10188-46060-61284-00703-09304-21721
          +

          Value is a NULL. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-24086-08530-21252-40131-41317-48771-53823-31992
          +

          For example, a partial index might omit entries for which the column being indexed is NULL. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-24089-57979-14928-03351-49983-36558-42407-47450
          +

          If a page contains no cells (which is only possible for a root page of a table that contains no rows) then the offset to the cell content area will equal the page size minus the bytes of reserved space. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-24098-10282-28593-32391-22620-22460-46080-08998
          +

          The DROP COLUMN command only works if the column is not referenced by any other parts of the schema and is not a PRIMARY KEY and does not have a UNIQUE constraint. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, matrix: context, detail)

          + +
          R-24153-28352-05918-29721-55341-26989-15412-17405
          +

          Tables created using CREATE TABLE AS are initially populated with the rows of data returned by the SELECT statement. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-24157-46062-13277-37526-03999-51751-53681-32386
          +

          The 3rd argument to the sqlite3_exec() callback is an array of pointers to strings obtained as if from sqlite3_column_text(), one for each column. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-24161-47822-59915-14251-27754-57973-48969-03751
          +

          The sqlite3_version() function is mostly constant, but it can change when SQLite is upgraded, and so even though it always returns the same answer for any particular session, because it can change answers across sessions it is still considered non-deterministic. +(source: deterministic.html, matrix: context, detail)

          + +
          R-24176-11856-49416-35044-22347-11072-23258-18948
          +

          The length of the name is limited to 255 bytes in a UTF-8 representation, exclusive of the zero-terminator. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, matrix: context, detail)

          + +
          R-24179-60523-60164-40067-19292-39680-45687-45747
          +

          Even if the foreign key constraint it is attached to is deferred, configuring a RESTRICT action causes SQLite to return an error immediately if a parent key with dependent child keys is deleted or modified. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-24188-24349-51458-56364-12806-43304-14352-46380
          +

          The expression attached to the optional OFFSET clause that may follow a LIMIT clause must also evaluate to an integer, or a value that can be losslessly converted to an integer. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-24189-42234-36662-00124-25434-59870-15844-57738
          +

          An SQLITE_TRACE_ROW callback is invoked whenever a prepared statement generates a single row of result. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-24225-46995-38973-17701-37772-12518-00219-22558
          +

          For example, "(CAST '123e+5' AS INTEGER)" results in 123, not in 12300000. +(source: lang_expr.html, checked-by: tcl/cast.test, matrix: context, detail)

          + +
          R-24227-04807-65013-09510-28047-53461-17252-27305
          +

          Or, if none of the WHEN expressions evaluate to true, the result of evaluating the ELSE expression, if any. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-24306-14960-36438-04276-35826-43147-57622-43704
          +

          RESTART This mode works the same way as FULL with the addition that after checkpointing the log file it blocks (calls the busy-handler callback) until all readers are finished with the log file. +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-24334-46836-37699-41209-48952-15160-39885-36508
          +

          The SQLite core will never read or write the lock-byte page, though operating-system specific VFS implementations may choose to read or write bytes on the lock-byte page according to the needs and proclivities of the underlying system. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-24401-52400-49114-60456-18821-28705-54480-01087
          +

          as will attempting to delete a row from the artist table when there exist dependent rows in the track table +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys01.test, matrix: context, detail)

          + +
          R-24408-11841-16708-30331-61955-39086-27640-21297
          +

          An application can tell which course of action SQLite took by using the sqlite3_get_autocommit() C-language interface. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-24411-60193-43052-59187-49935-26782-54329-59494
          +

          The frame-header is six big-endian 32-bit unsigned integer values, as follows: WAL Frame Header Format OffsetSizeDescription 04 Page number 44 For commit records, the size of the database file in pages after the commit. For all other records, zero. 84 Salt-1 copied from the WAL header 124 Salt-2 copied from the WAL header 164 Checksum-1: Cumulative checksum up through and including this page 204 Checksum-2: Second half of the cumulative checksum. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-24420-43338-21659-30217-32361-58749-59788-18529
          +

          In formats 5 through 7, the "T" is a literal character separating the date and the time, as required by ISO-8601. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-24433-42760-21501-54800-20604-32904-26746-52498
          +

          AUTOINCREMENT guarantees that automatically chosen ROWIDs will be increasing but not that they will be sequential. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-24450-46174-44304-25763-63471-62798-12121-54973
          +

          All foreign key constraints in SQLite are handled as if MATCH SIMPLE were specified. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys23.test, matrix: context, detail)

          + +
          R-24454-61742-57320-38040-08939-30630-11445-30109
          +

          The BINARY collating sequence is used for comparisons. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-24470-31136-04101-59681-51092-46521-28491-41459
          +

          This function is an SQL wrapper around the sqlite3_sourceid() C interface. +(source: lang_corefunc.html, checked-by: src/func.c, th3/req1/func04.test, matrix: context, detail)

          + +
          R-24499-57071-23351-26477-16690-35822-52475-36418
          +

          The following example illustrates the effect of using a deferred foreign key constraint. -- Database schema. Both tables are initially empty. CREATE TABLE artist( artistid INTEGER PRIMARY KEY, artistname TEXT ); CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER REFERENCES artist(artistid) DEFERRABLE INITIALLY DEFERRED ); sqlite3> -- If the foreign key constraint were immediate, this INSERT would sqlite3> -- cause an error (since as there is no row in table artist with sqlite3> -- artistid=5). But as the constraint is deferred and there is an sqlite3> -- open transaction, no error occurs. sqlite3> BEGIN; sqlite3> INSERT INTO track VALUES(1, 'White Christmas', 5); sqlite3> -- The following COMMIT fails, as the database is in a state that sqlite3> -- does not satisfy the deferred foreign key constraint. The sqlite3> -- transaction remains open. sqlite3> COMMIT; SQL error: foreign key constraint failed sqlite3> -- After inserting a row into the artist table with artistid=5, the sqlite3> -- deferred foreign key constraint is satisfied. It is then possible sqlite3> -- to commit the transaction without error. sqlite3> INSERT INTO artist VALUES(5, 'Bing Crosby'); sqlite3> COMMIT; +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys13.test, matrix: context, detail)

          + +
          R-24505-23230-57666-22051-56312-29400-20176-42804
          +

          A pointer to an sqlite3_context object is always first parameter to application-defined SQL functions. +(source: c3ref/context.html, checked-by: src/vdbe.c, src/vdbemem.c, th3/req1/aggcntx01.test, th3/req1/func02.test, matrix: context, detail)

          + +
          R-24519-28304-27679-62184-02249-08056-49023-13978
          +

          When the value of auto-vacuum is 2 or "incremental" then the additional information needed to do auto-vacuuming is stored in the database file but auto-vacuuming does not occur automatically at each commit as it does with auto_vacuum=full. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-24531-54682-59565-24630-56412-40369-07306-32819
          +

          The update hook is not invoked when internal system tables are modified (i.e. sqlite_sequence). +(source: c3ref/update_hook.html, checked-by: tcl/hook.test, matrix: context, detail)

          + +
          R-24539-09359-22756-36895-58208-42463-58275-24865
          +

          PRAGMA function_list; This pragma returns a list of SQL functions known to the database connection. +(source: pragma.html, matrix: context, detail)

          + +
          R-24543-02373-21907-00972-51733-48834-36106-39581
          +

          If pzTail is not NULL then *pzTail is made to point to the first byte past the end of the first SQL statement in zSql. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-24550-28707-14750-42136-44607-00507-28775-21401
          +

          An SQLITE_TRACE_CLOSE callback is invoked when a database connection closes. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-24625-56801-43002-50418-06223-19456-53547-53426
          +

          SQLite makes its own private copy of the content of the sqlite3_mem_methods structure before the sqlite3_config() call returns. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/th3oom.c, matrix: context, detail)

          + +
          R-24635-37065-50827-53824-24547-23611-48294-22857
          +

          The <<, >>, &, and | operators always return an INTEGER (or NULL) result, but the % operator returns either INTEGER or REAL (or NULL) depending on the type of its operands. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-24654-22397-54230-45811-61786-44537-26039-50669
          +

          The X callback is invoked whenever any of the events identified by mask M occur. +(source: c3ref/trace_v2.html, matrix: context, detail)

          + +
          R-24663-27339-41709-46831-61109-18753-41935-55210
          +

          SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE The database is opened for reading and writing, and is created if it does not already exist. This is the behavior that is always used for sqlite3_open() and sqlite3_open16(). +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-24676-09859-25258-06679-18327-03281-24955-00264
          +

          For example, consider the following database schema: CREATE TABLE album( albumartist TEXT, albumname TEXT, albumcover BINARY, PRIMARY KEY(albumartist, albumname) ); CREATE TABLE song( songid INTEGER, songartist TEXT, songalbum TEXT, songname TEXT, FOREIGN KEY(songartist, songalbum) REFERENCES album(albumartist, albumname) ); In this system, each entry in the song table is required to map to an entry in the album table with the same combination of artist and album. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys11.test, matrix: context, detail)

          + +
          R-24691-27369-29687-09464-65253-51469-13435-14358
          +

          Memory to hold the error message string is managed internally. The application does not need to worry about freeing the result. However, the error string might be overwritten or deallocated by subsequent calls to other SQLite interface functions. +(source: c3ref/errcode.html, matrix: context, detail)

          + +
          R-24707-22256-10968-61514-58469-45624-50106-41306
          +

          The estimatedRows value is an estimate of the number of rows that will be returned by the strategy. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-24728-13230-17441-17828-27985-11598-34826-53003
          +

          SQLite parses MATCH clauses (i.e. does not report a syntax error if you specify one), but does not enforce them. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys23.test, matrix: context, detail)

          + +
          R-24731-45773-21654-50701-01955-60961-16210-17736
          +

          The IS and IS NOT operators work like = and != except when one or both of the operands are NULL. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-24738-46982-10847-07410-11065-35020-61549-58241
          +

          Otherwise, it is invoked with two arguments only. +(source: lang_corefunc.html, checked-by: th3/req1/func02.test, matrix: context, detail)

          + +
          R-24770-07833-20413-40492-33395-44315-54642-50376
          +

          The expression of a generated column may only reference constant literals and columns within the same row, and may only use scalar deterministic functions. +(source: gencol.html, matrix: context, detail)

          + +
          R-24770-17719-20723-28193-15704-54316-24358-11027
          +

          As with all SQL syntax, the case of the keywords does not matter. One can write "WITHOUT rowid" or "without rowid" or "WiThOuT rOwId" and it will mean the same thing. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-24784-09209-65529-37322-41810-39114-37590-65280
          +

          The authority may be omitted, may be blank, or may be "localhost". Any other authority results in an error. +(source: uri.html, matrix: context, detail)

          + +
          R-24843-55391-00331-31917-58094-58865-54184-39062
          +

          It is permitted to register multiple implementations of the same functions with the same name but with either differing numbers of arguments or differing preferred text encodings. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-24874-01721-30373-30915-48096-44417-56853-33182
          +

          If sqlite3_collation_needed16() is used, the names are passed as UTF-16 in machine native byte order. +(source: c3ref/collation_needed.html, matrix: context, detail)

          + +
          R-24896-34661-16790-51948-60772-09392-38798-62711
          +

          The sqlite_stat4.tbl column holds name of the table that owns the index that the row describes +(source: fileformat2.html, matrix: context, detail)

          + +
          R-24911-36108-02843-41555-24793-65003-42358-61703
          +

          The GLOB operator is always case sensitive. +(source: optoverview.html, checked-by: th3/cov1/pragma02.test, matrix: context, detail)

          + +
          R-24982-11525-35857-44633-64462-64682-47144-54575
          +

          The SQLITE_CONFIG_SMALL_MALLOC option takes single argument of type int, interpreted as a boolean, which if true provides a hint to SQLite that it should avoid large memory allocations if possible. +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-24983-33491-21111-64156-17936-16093-21195-54073
          +

          Because the function inputs are not necessarily known until run-time, the date/time functions will throw an exception if they encounter any of the non-deterministic features in a context where only deterministic functions are allowed. +(source: deterministic.html, matrix: context, detail)

          + +
          R-24984-42113-54448-54138-16961-63127-18743-03855
          +

          Any callback set by a previous call to sqlite3_rollback_hook() for the same database connection is overridden. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-25008-21688-65381-07984-00031-51738-33385-29636
          +

          The size of a page is a power of two between 512 and 65536 inclusive. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-25048-46581-04940-52749-02967-51891-39439-41238
          +

          SQLite will never invoke xInit() more than once without an intervening call to xShutdown(). +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-25063-23286-45841-01783-39001-22838-28482-44286
          +

          The sqlite3_sourceid() function returns a pointer to a string constant whose value is the same as the SQLITE_SOURCE_ID C preprocessor macro. Except if SQLite is built using an edited copy of the amalgamation, then the last four characters of the hash might be different from SQLITE_SOURCE_ID. +(source: c3ref/libversion.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-25071-21202-61916-09187-06401-02826-31838-35119
          +

          The "CROSS JOIN" join operator produces the same result as the "INNER JOIN", "JOIN" and "," operators +(source: lang_select.html, checked-by: tcl/e_select.test, tcl/e_select2.test, matrix: context, detail)

          + +
          R-25072-57278-41815-02342-40750-19788-27895-44607
          +

          The argument to INTO can be a URI filename if URI filenames are enabled. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-25108-07802-40508-32376-19441-31217-21410-63803
          +

          However, if there are pending write operations, the COMMIT command will fail with an error code SQLITE_BUSY. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-25136-65062-60246-57323-36202-59774-22241-57010
          +

          This option is used to enable or disable the enforcement of foreign key constraints. +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/cov1/main34.test, matrix: context, detail)

          + +
          R-25142-32967-13152-03974-64146-30247-48913-62281
          +

          For conversions between TEXT and REAL storage classes, only the first 15 significant decimal digits of the number are preserved. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-25149-16900-02037-62067-08314-01684-52893-04562
          +

          The RETURNING clause may only reference the table being modified. +(source: lang_returning.html, matrix: context, detail)

          + +
          R-25149-22012-48563-28153-37839-65089-07651-08185
          +

          The INSERT ... DEFAULT VALUES statement inserts a single new row into the named table. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-25205-10214-27993-08782-38533-49821-04798-04951
          +

          The sqlite3_str object is destroyed and the string it created is returned using the sqlite3_str_finish() interface. +(source: c3ref/str.html, matrix: context, detail)

          + +
          R-25216-03908-32391-06837-09807-59608-58830-19572
          +

          The term "b=6" does not match "b=3+3" or "b-6=0" or "b BETWEEN 6 AND 6". +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-25288-28061-40828-54827-02140-23541-51097-39397
          +

          If sqlite3_value object V was initialized using sqlite3_bind_pointer(S,I,P,X,D) or sqlite3_result_pointer(C,P,X,D) and if X and Y are strings that compare equal according to strcmp(X,Y), then sqlite3_value_pointer(V,Y) will return the pointer P. +(source: c3ref/value_blob.html, checked-by: th3/cov1/carray01.test, matrix: context, detail)

          + +
          R-25343-19498-17466-42652-61214-37840-16481-55260
          +

          It is not necessary for every column of an index to appear in a WHERE clause term in order for that index to be used. +(source: optoverview.html, matrix: context, detail)

          + +
          R-25359-61571-30835-46993-61423-15847-19094-36045
          +

          If the implicit DELETE FROM causes any deferred foreign key constraints to be violated, and the violations still exist when the transaction is committed, an error is returned at the time of commit. +(source: lang_droptable.html, checked-by: th3/cov1/fkey24.test, matrix: context, detail)

          + +
          R-25361-16150-63678-45550-40472-51042-22441-52100
          +

          This function is omitted from SQLite by default. It is only available if the SQLITE_SOUNDEX compile-time option is used when SQLite is built. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/func07.test, matrix: context, detail)

          + +
          R-25384-39337-58415-17102-37697-27977-14467-00416
          +

          There is nothing stopping the user from creating a foreign key definition that refers to a parent table that does not exist, or to parent key columns that do not exist or are not collectively bound by a PRIMARY KEY or UNIQUE constraint. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys21.test, matrix: context, detail)

          + +
          R-25451-61125-57795-23914-51441-34414-44666-54346
          +

          The SQLITE_CONFIG_URI option takes a single argument of type int. If non-zero, then URI handling is globally enabled. If the parameter is zero, then URI handling is globally disabled. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-25459-18529-03655-35597-46929-35137-47473-63058
          +

          These routines return 0 if the statement is incomplete. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-25460-65232-16560-61859-43199-38232-53443-46120
          +

          The sqlite3_test_control() interface is used to read out internal state of SQLite and to inject faults into SQLite for testing purposes. +(source: c3ref/test_control.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-25473-20557-44472-04975-51987-58936-13072-57785
          +

          The number of columns in a table is limited by the SQLITE_MAX_COLUMN compile-time parameter. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-25540-36848-64613-55100-38595-19137-49959-42593
          +

          So as not to open security holes in older applications that are unprepared to deal with extension loading, and as a means of disabling extension loading while evaluating user-entered SQL, the following API is provided to turn the sqlite3_load_extension() mechanism on and off. +(source: c3ref/enable_load_extension.html, matrix: context, detail)

          + +
          R-25541-17189-03104-63416-46282-42879-07481-01224
          +

          Furthermore, the temp_store_directory pragma always assumes that any string that this variable points to is held in memory obtained from sqlite3_malloc and the pragma may attempt to free that memory using sqlite3_free. +(source: c3ref/temp_directory.html, matrix: context, detail)

          + +
          R-25558-37487-19096-36063-17437-04044-36041-27526
          +

          If the specified view cannot be found and the IF EXISTS clause is not present, it is an error. +(source: lang_dropview.html, checked-by: tcl/e_dropview.test, th3/cov1/build13.test, matrix: context, detail)

          + +
          R-25583-11663-64337-14085-59741-00588-27469-12431
          +

          Compute the last day of the current month. SELECT date('now','start of month','+1 month','-1 day'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-25587-45258-04258-19279-64153-15260-17086-46262
          +

          Additional sqlite3_trace() callbacks might occur as each triggered subprogram is entered. The callbacks for triggers contain a UTF-8 SQL comment that identifies the trigger. +(source: c3ref/profile.html, checked-by: th3/cov1/main16.test, matrix: context, detail)

          + +
          R-25588-27181-18097-02154-44633-08776-21987-21638
          +

          The EXISTS operator always evaluates to one of the integer values 0 and 1. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-25613-37547-39472-02780-29297-59051-40019-17427
          +

          Indexes are removed with the DROP INDEX command. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-25616-08788-18594-15704-08007-00569-12211-26573
          +

          A SELECT statement used as either a scalar subquery or as the right-hand operand of an IN, NOT IN or EXISTS expression may contain references to columns in the outer query. +(source: lang_expr.html, checked-by: th3/req1/select01.test, matrix: context, detail)

          + +
          R-25616-61116-19772-20982-08386-58484-18398-18419
          +

          The database connection can be changed between full and incremental autovacuum mode at any time. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-25638-20415-36003-28189-21007-56161-18481-25600
          +

          The sqlite3_mprintf() and sqlite3_vmprintf() routines write their results into memory obtained from sqlite3_malloc64(). +(source: c3ref/mprintf.html, matrix: context, detail)

          + +
          R-25645-37767-35870-43075-30633-04117-48100-12426
          +

          However, if the 4th parameter to sqlite3_create_function_v2() is OR-ed with SQLITE_DETERMINISTIC, then SQLite will treat that function as if it were deterministic. +(source: deterministic.html, matrix: context, detail)

          + +
          R-25654-38196-54382-29664-57733-52949-37784-40820
          +

          All reads from and writes to the main database file begin at a page boundary and all writes are an integer number of pages in size. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-25715-37072-58552-52856-29858-64366-26989-17165
          +

          Memory allocation statistics are enabled by default unless SQLite is compiled with SQLITE_DEFAULT_MEMSTATUS=0 in which case memory allocation statistics are disabled by default. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/sqliteInt.h, matrix: context, detail)

          + +
          R-25722-54578-39151-48243-45997-39827-22901-27237
          +

          sqlite3_realloc(X,N) returns a pointer to a memory allocation of at least N bytes in size or NULL if insufficient memory is available. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-25726-27770-20459-03461-13607-13171-18925-23787
          +

          SQLite will invoke the destructor function (if it is not NULL) when SQLite no longer needs the pClientData pointer. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-25727-24709-18641-35581-28019-63513-51229-00924
          +

          Each expression defines the value for a single column. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-25787-28949-24920-53948-06133-34727-56080-32939
          +

          The EXCEPT operator returns the subset of rows returned by the left SELECT that are not also returned by the right-hand SELECT. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-25824-45489-43990-02774-35332-28137-18182-24527
          +

          The D and N arguments to sqlite3_backup_init(D,N,S,M) are the database connection associated with the destination database and the database name, respectively. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-25832-43294-06509-06689-56001-36083-00062-63837
          +

          The presence of the "noskipscan" token on the sqlite_stat1.stat field of an index prevents that index from being used with the skip-scan optimization. +(source: fileformat2.html, checked-by: th3/cov1/where43.test, matrix: context, detail)

          + +
          R-25857-01867-51039-59358-11204-13788-02264-02528
          +

          The values of these parameters (also called "host parameter names" or "SQL parameters") can be set using the sqlite3_bind_*() routines defined here. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-25882-51550-16212-06454-16146-64979-21023-53530
          +

          SQLITE_OPEN_MEMORY The database will be opened as an in-memory database. The database is named by the "filename" argument for the purposes of cache-sharing, if shared cache mode is enabled, but the "filename" is otherwise ignored. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-25883-55063-43215-03328-35797-53686-57723-04298
          +

          The expressions in the GROUP BY clause do not have to be expressions that appear in the result. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-25894-51060-18040-53125-15120-62396-36354-30863
          +

          Calling this routine with a null pointer (such as would be returned by a failed call to sqlite3_blob_open()) is a harmless no-op. +(source: c3ref/blob_close.html, checked-by: tcl/e_blobclose.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-25950-00887-26391-00141-61376-60148-41906-53274
          +

          Both the WHEN clause and the trigger actions may access elements of the row being inserted, deleted or updated using references of the form "NEW.column-name" and "OLD.column-name", where column-name is the name of a column from the table that the trigger is associated with. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-25963-03527-53793-34841-03007-31919-23816-21204
          +

          The xInit() method is passed a copy of the sqlite3_pcache_methods2.pArg value. +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-26000-56589-64657-09406-12178-15033-38154-19492
          +

          The xShutdown() method may be NULL. +(source: c3ref/pcache_methods2.html, checked-by: src/pcache.c, matrix: context, detail)

          + +
          R-26018-54615-20076-23782-57324-62216-58815-28451
          +

          In the "vX" interfaces, the prepared statement that is returned (the sqlite3_stmt object) contains a copy of the original SQL text. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-26022-39063-15323-00044-24129-45502-60784-59294
          +

          PRAGMA analysis_limit; PRAGMA analysis_limit = N; +(source: pragma.html, matrix: context, detail)

          + +
          R-26030-41411-57646-19570-38371-36124-26436-49384
          +

          The highwater mark associated with SQLITE_DBSTATUS_CACHE_USED is always 0. +(source: c3ref/c_dbstatus_options.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-26031-07851-20661-23903-48754-42738-42414-42677
          +

          URIs are processed as UTF8 text. +(source: uri.html, matrix: context, detail)

          + +
          R-26078-30979-29806-34785-43846-23819-01793-57552
          +

          The content of these tables is not updated as the database changes so after making significant changes it might be prudent to rerun ANALYZE. +(source: optoverview.html, matrix: context, detail)

          + +
          R-26102-39000-00300-53165-31110-34521-05669-39517
          +

          The mxLevel entry in the sqlite3_rtree_query_info structure is the level value for the root of the R*Tree. +(source: rtree.html, matrix: context, detail)

          + +
          R-26117-01852-15491-47779-25813-50210-15791-48499
          +

          In this latter case, the integer at offset 64 is true for incremental_vacuum and false for auto_vacuum. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-26128-01625-01942-61645-49803-53494-49149-48512
          +

          Calls to sqlite3_close() and sqlite3_close_v2() return SQLITE_OK if the sqlite3 object is successfully destroyed and all associated resources are deallocated. +(source: c3ref/close.html, checked-by: th3/th3util.c, matrix: context, detail)

          + +
          R-26145-35631-18411-10408-27137-14285-36971-04977
          +

          The sqlite3_errmsg() and sqlite3_errmsg16() return English-language text that describes the error, as either UTF-8 or UTF-16 respectively. +(source: c3ref/errcode.html, matrix: context, detail)

          + +
          R-26170-15376-11446-15770-61234-08203-15612-42127
          +

          The sqlite3_str_appendchar(X,N,C) method appends N copies of the single-byte character C onto the end of sqlite3_str object X. +(source: c3ref/str_append.html, matrix: context, detail)

          + +
          R-26177-52471-27779-44415-45290-32639-49511-38944
          +

          The first argument is an integer code for the specific parameter to measure. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-26188-08449-06969-05333-36262-60871-22176-39475
          +

          If the SQLITE_FCNTL_PRAGMA file control returns SQLITE_OK, then the parser assumes that the VFS has handled the PRAGMA itself and the parser generates a no-op prepared statement if result string is NULL, or that returns a copy of the result string if the string is non-NULL. +(source: c3ref/c_fcntl_begin_atomic_write.html, checked-by: tcl/multiplex4.test, th3/cov1/pragma24.test, matrix: context, detail)

          + +
          R-26228-33773-01538-19072-29962-47655-12853-04397
          +

          The 4th argument to the sqlite3_exec() callback is an array of pointers to strings where each entry represents the name of corresponding result column as obtained from sqlite3_column_name(). +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-26234-58592-26686-64458-63937-04823-26518-58770
          +

          Whether or not any conversions are attempted before the comparison takes place depends on the type affinity of the operands. +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-26245-27007-61091-63162-56268-13882-14164-49256
          +

          Comments can begin anywhere whitespace can be found, including inside expressions that span multiple lines. +(source: lang_comment.html, checked-by: th3/req1/comment01.test, matrix: context, detail)

          + +
          R-26266-37313-29476-24640-23484-47513-24426-61925
          +

          If the implicit DELETE FROM executed as part of a DROP TABLE command violates any immediate foreign key constraints, an error is returned and the table is not dropped. +(source: lang_droptable.html, checked-by: th3/cov1/fkey24.test, th3/req1/droptable01.test, matrix: context, detail)

          + +
          R-26267-43414-63813-04870-32404-43287-64705-64465
          +

          In the case of an update, this is the rowid after the update takes place. +(source: c3ref/update_hook.html, checked-by: th3/cov1/main15.test, matrix: context, detail)

          + +
          R-26300-50198-46822-10316-25756-64179-25231-23016
          +

          If a WHERE clause is supplied, then only those rows for which the WHERE clause boolean expression is true are deleted. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-26304-43698-14397-16826-05465-17486-47171-40397
          +

          The sqlite3_errstr() interface returns the English-language text that describes the result code, as UTF-8. +(source: c3ref/errcode.html, matrix: context, detail)

          + +
          R-26335-36429-33832-38639-19447-31976-61151-28783
          +

          The second and third column are -1 if there is no write-ahead log, for example if this pragma is invoked on a database connection that is not in WAL mode. +(source: pragma.html, checked-by: th3/req1/pragma29.test, matrix: context, detail)

          + +
          R-26343-45930-10507-06945-56497-65367-59680-35735
          +

          This pragma invokes the sqlite3_soft_heap_limit64() interface with the argument N, if N is specified and is a non-negative integer. +(source: pragma.html, checked-by: src/pragma.c, tcl/softheap1.test, matrix: context, detail)

          + +
          R-26346-36443-14203-01237-59463-02061-43306-07214
          +

          When casting a BLOB value to a REAL, the value is first converted to TEXT. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-26377-49195-21869-49397-37126-00993-02015-27234
          +

          If the DELETE statement also has an OFFSET clause, then it is similarly evaluated and cast to an integer value. Again, it is an error if the value cannot be losslessly converted to an integer. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-26383-00685-00003-12709-20041-02640-63629-60960
          +

          Note that the journal_mode for an in-memory database is either MEMORY or OFF and can not be changed to a different value. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-26383-51744-00561-00695-36382-45480-37936-10675
          +

          If a CHECK constraint or foreign key constraint violation occurs, the REPLACE conflict resolution algorithm works like ABORT. +(source: lang_conflict.html, checked-by: src/insert.c, th3/req1/conflict02.test, matrix: context, detail)

          + +
          R-26406-03647-33657-03652-13422-62298-62842-50282
          +

          It is possible for the library compile-time C preprocessor symbol SQLITE_TEMP_STORE to override this pragma setting. +(source: pragma.html, matrix: context, detail)

          + +
          R-26427-33659-32322-40327-33016-33915-32615-17849
          +

          Other parameters record only the highwater mark and not the current value. For these latter parameters nothing is written into *pCurrent. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-26456-17544-11737-29192-02704-19416-55152-07326
          +

          The right-hand operand of an IN or NOT IN operator has no affinity if the operand is a list and has the same affinity as the affinity of the result set expression if the operand is a SELECT. +(source: datatype3.html, checked-by: th3/cov1/affinity01.test, th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-26480-31567-01189-11331-40338-43119-64271-54165
          +

          The key for each entry in the WITHOUT ROWID b-tree is a record composed of the columns of the PRIMARY KEY followed by all remaining columns of the table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-26490-64257-21643-35537-33187-49961-28588-55610
          +

          But making modifications to this table will likely perturb the AUTOINCREMENT key generation algorithm. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-26492-45204-29363-38379-65381-14832-32787-08398
          +

          If P>X and K<=X then the first K bytes of P are stored on the btree page and the remaining P-K bytes are stored on overflow pages. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-26501-17306-17113-63025-42217-43181-46541-32131
          +

          If a table contains a user defined column named "rowid", "oid" or "_rowid_", then that name always refers the explicitly declared column and cannot be used to retrieve the integer rowid value. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-26507-47431-65188-24932-00073-09728-32384-65254
          +

          If the N parameter to sqlite3_realloc(X,N) is zero or negative then the behavior is exactly the same as calling sqlite3_free(X). +(source: c3ref/free.html, checked-by: src/malloc.c, th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-26512-02966-03467-49127-26389-10088-58457-04547
          +

          When secure_delete is on, SQLite overwrites deleted content with zeros. +(source: pragma.html, checked-by: th3/cov1/pragma20.test, matrix: context, detail)

          + +
          R-26578-03501-48329-54809-40303-33325-20677-03881
          +

          The load_extension() function raises an exception if the extension fails to load or initialize correctly. +(source: lang_corefunc.html, checked-by: th3/cov1/func03.test, matrix: context, detail)

          + +
          R-26601-01119-55361-00031-26734-63731-65122-53650
          +

          Subject to rules (11), (12) and (13), they may also contain ORDER BY, LIMIT and OFFSET clauses. +(source: optoverview.html, matrix: context, detail)

          + +
          R-26602-05678-16907-15766-43643-13869-48465-09322
          +

          The sqlite3_blob_read() and sqlite3_blob_write() interfaces can be used to read or write small subsections of the BLOB. +(source: c3ref/blob.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-26684-40576-09126-53282-12439-40003-41887-60526
          +

          Each non-aggregate expression in the result-set is evaluated once for an arbitrarily selected row of the dataset. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-26704-30334-42154-41889-16850-21412-27655-04243
          +

          The sqlite3_config(SQLITE_CONFIG_PCACHE2, ...) interface can register an alternative page cache implementation by passing in an instance of the sqlite3_pcache_methods2 structure. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-26801-64137-39079-48164-16524-44855-40563-04540
          +

          If the xInit() method is NULL, then the built-in default page cache is used instead of the application defined page cache. +(source: c3ref/pcache_methods2.html, checked-by: src/pcache.c, matrix: context, detail)

          + +
          R-26810-60950-31083-35442-30714-31340-57644-05934
          +

          If the authority section is present, then the path is always an absolute pathname. +(source: uri.html, matrix: context, detail)

          + +
          R-26835-10964-22323-42888-35777-38355-20607-28933
          +

          The first argument (the third parameter to sqlite3_db_config() is a pointer to a memory buffer to use for lookaside memory. +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-26835-34471-30842-38170-16771-41578-05053-31515
          +

          SQL comments begin with two consecutive "-" characters (ASCII 0x2d) and extend up to and including the next newline character (ASCII 0x0a) or until the end of input, whichever comes first. +(source: lang_comment.html, checked-by: th3/req1/comment01.test, matrix: context, detail)

          + +
          R-26845-32976-14599-31607-31221-37786-17413-24156
          +

          Value "rwc" is equivalent to setting both SQLITE_OPEN_READWRITE and SQLITE_OPEN_CREATE. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-26888-26313-07515-35775-03599-15989-59200-07369
          +

          The default setting is off, meaning that CHECK constraints are enforced by default. +(source: pragma.html, checked-by: th3/req1/pragma20.test, matrix: context, detail)

          + +
          R-26894-41325-01569-09628-52380-05795-22160-61664
          +

          If the TEXT value is not a well-formed integer or real literal, then the value is stored as TEXT. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-26900-09176-20658-03305-09602-45574-02965-13099
          +

          A value of 13 (0x0d) means the page is a leaf table b-tree page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-26917-59594-53851-11147-17067-15964-43582-37189
          +

          For the INSERT and UPDATE commands, the keywords "ON CONFLICT" are replaced by "OR" so that the syntax reads more naturally. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-26947-19317-61341-19233-36872-20864-34826-22893
          +

          If the statement is a COMMIT or occurs outside of an explicit transaction, then you can retry the statement. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-26959-28969-15823-07414-35392-55670-52959-52462
          +

          As of version 3.6.18, without running ANALYZE, SQLite will choose option 2. +(source: optoverview.html, matrix: context, detail)

          + +
          R-26972-25540-17987-13345-11118-49972-58252-62199
          +

          The sqlite3_bind_* routines return SQLITE_OK on success or an error code if anything goes wrong. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-26993-43540-10992-37102-45404-55683-60247-30594
          +

          Passing zero or a negative value as the nFrame parameter disables automatic checkpoints entirely. +(source: c3ref/wal_autocheckpoint.html, checked-by: tcl/e_walauto.test, matrix: context, detail)

          + +
          R-26999-04791-16827-31249-13986-61939-06074-63605
          +

          The sqlite_sequence table is an internal table used to help implement AUTOINCREMENT. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-27002-52307-56024-23951-62365-30891-30149-50327
          +

          The DROP VIEW statement removes a view created by the CREATE VIEW statement. +(source: lang_dropview.html, checked-by: tcl/e_dropview.test, th3/cov1/build13.test, matrix: context, detail)

          + +
          R-27061-43436-37550-51046-04512-17816-21037-16098
          +

          The aConstraintUsage[].omit flag is an optimization hint. When the omit flag is left in its default setting of false, the constraint will always be checked separately in byte code. If the omit flag is change to true, then the constraint may or may not be checked in byte code. In other words, when the omit flag is true there is no guarantee that the constraint will not be checked again using byte code. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-27108-11003-35381-33223-00139-25935-11742-39438
          +

          The name of the database is "main" for the main database or "temp" for the TEMP database, or the name that appears after the AS keyword for databases that are added using the ATTACH SQL command. +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-27192-61982-03758-21332-41239-32834-09507-36997
          +

          The third and fourth parameters to this function are the table and column name of the desired column, respectively. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-27219-49057-63143-35616-48690-21583-47587-41101
          +

          Unlike most SQL databases, SQLite does not restrict the type of data that may be inserted into a column based on the columns declared type. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-27228-35217-15852-02871-02611-58321-58852-42304
          +

          A scalar SQL function requires an implementation of the xFunc callback only; NULL pointers must be passed as the xStep and xFinal parameters. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc03.test, matrix: context, detail)

          + +
          R-27233-06819-06438-56184-33294-63005-30894-40602
          +

          If the TEXT value is a well-formed integer literal that is too large to fit in a 64-bit signed integer, it is converted to REAL. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-27234-05761-29027-01683-12712-48347-06174-19243
          +

          Parameter zDb is not the filename that contains the database, but rather the symbolic name of the database. For attached databases, this is the name that appears after the AS keyword in the ATTACH statement. For the main database file, the database name is "main". For TEMP tables, the database name is "temp". +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-27289-46867-00795-18230-38785-61782-07002-59582
          +

          If N is negative, then the limit reverts to the default value determined by the most recent sqlite3_config(SQLITE_CONFIG_MMAP_SIZE), or to the compile time default determined by SQLITE_DEFAULT_MMAP_SIZE if not start-time limit has been set. +(source: pragma.html, matrix: context, detail)

          + +
          R-27290-56511-04892-59250-62806-15127-45739-19284
          +

          CREATE INDEX po_parent ON purchaseorder(parent_po) WHERE parent_po IS NOT NULL; +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-27301-09658-03082-11591-62753-46064-11323-29821
          +

          Otherwise, if the ORDER BY expression is a column or an alias of an expression that is a column, then the default collation sequence for the column is used. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-27327-54431-40312-06060-63431-19500-57112-52669
          +

          The entry point is zProc. +(source: c3ref/load_extension.html, matrix: context, detail)

          + +
          R-27363-63308-55807-24434-61973-58824-33773-60814
          +

          If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() routine returns the number of bytes in that BLOB or string. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-27380-17544-22852-64378-45230-22316-25696-47821
          +

          All schemas are optimized in the first two forms, and only the specified schema is optimized in the latter two. +(source: pragma.html, matrix: context, detail)

          + +
          R-27383-10246-01655-25271-51755-59417-27078-62241
          +

          An ON UPDATE action is only taken if the values of the parent key are modified so that the new parent key values are not equal to the old. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys20.test, matrix: context, detail)

          + +
          R-27438-53558-39373-64011-10542-64778-48166-54900
          +

          Each column of the subquery has the collation sequence and affinity of the corresponding expression in the subquery statement. +(source: lang_select.html, checked-by: tcl/e_select2.test, matrix: context, detail)

          + +
          R-27458-04043-31882-50848-08148-11623-61104-53512
          +

          URI hexadecimal escape sequences (%HH) are supported within the path and query components of a URI. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-27461-16942-46149-61363-05307-36708-49016-10103
          +

          The TEMP database has a default suggested cache size of 0 pages. +(source: pragma.html, checked-by: th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-27472-62612-19629-13155-08759-40565-10817-64469
          +

          But WITHOUT ROWID tables do follow the standard and will throw an error on any attempt to insert a NULL into a PRIMARY KEY column. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-27484-01467-40660-08782-16756-57898-53117-01697
          +

          For example, CREATE TABLE parent(a PRIMARY KEY, b UNIQUE, c, d, e, f); CREATE UNIQUE INDEX i1 ON parent(c, d); CREATE INDEX i2 ON parent(e); CREATE UNIQUE INDEX i3 ON parent(f COLLATE nocase); CREATE TABLE child1(f, g REFERENCES parent(a)); -- Ok CREATE TABLE child2(h, i REFERENCES parent(b)); -- Ok CREATE TABLE child3(j, k, FOREIGN KEY(j, k) REFERENCES parent(c, d)); -- Ok CREATE TABLE child4(l, m REFERENCES parent(e)); -- Error! CREATE TABLE child5(n, o REFERENCES parent(f)); -- Error! CREATE TABLE child6(p, q, FOREIGN KEY(p, q) REFERENCES parent(b, c)); -- Error! CREATE TABLE child7(r REFERENCES parent(c)); -- Error! The foreign key constraints created as part of tables child1, child2 and child3 are all fine. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-27484-38990-39416-37657-02655-32272-61477-41469
          +

          Reads are also usually an integer number of pages in size, with the one exception that when the database is first opened, the first 100 bytes of the database file (the database file header) are read as a sub-page size unit. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-27525-15031-55320-08912-51889-58390-12207-18026
          +

          The column on the left side of the GLOB operator must always use the built-in BINARY collating sequence or no attempt will be made to optimize that operator with indexes. +(source: optoverview.html, matrix: context, detail)

          + +
          R-27542-08072-33902-06053-42391-63696-60417-63522
          +

          The sqlite3_set_auxdata(C,N,P,X) interface saves P as metadata for the N-th argument of the application-defined function. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-27549-59611-14621-06209-14436-33110-11201-06265
          +

          The instr(X,Y) function finds the first occurrence of string Y within string X and returns the number of prior characters plus 1, or 0 if Y is nowhere found within X. +(source: lang_corefunc.html, checked-by: tcl/instr.test, matrix: context, detail)

          + +
          R-27599-07502-21530-13120-63753-37571-15799-15475
          +

          The callback function registered by sqlite3_trace() is invoked at various times when an SQL statement is being run by sqlite3_step(). +(source: c3ref/profile.html, checked-by: th3/cov1/main16.test, matrix: context, detail)

          + +
          R-27632-24205-25477-34441-62508-04163-16390-61608
          +

          URI filename interpretation is enabled if the SQLITE_OPEN_URI flag is set in the third argument to sqlite3_open_v2(), or if it has been enabled globally using the SQLITE_CONFIG_URI option with the sqlite3_config() method or by the SQLITE_USE_URI compile-time option. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-27649-21314-13870-57957-53735-15830-08405-07126
          +

          However a left outer join is neither commutative nor associative and hence will not be reordered. +(source: optoverview.html, matrix: context, detail)

          + +
          R-27653-00078-33413-45845-06007-29371-61376-52679
          +

          Within an xUpdate method, any value for which sqlite3_value_nochange(X) is true will in all other respects appear to be a NULL value. +(source: c3ref/value_blob.html, matrix: context, detail)

          + +
          R-27690-36184-48459-32575-13610-54533-11397-57376
          +

          The sqlite3_int64 variable pointed to by the V parameter will be set to the total number of times that the X-th loop has run. +(source: c3ref/c_scanstat_est.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-27702-51733-15398-16850-47606-12840-18480-45806
          +

          New VFSes are registered with sqlite3_vfs_register(). +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-27726-60934-44670-59608-21152-24326-11375-20798
          +

          The "PRAGMA data_version" command provides an indication that the database file has been modified. +(source: pragma.html, checked-by: tcl/pragma3.test, th3/cov1/pragma26.test, matrix: context, detail)

          + +
          R-27741-36039-35312-26646-43562-16753-08652-02657
          +

          The remaining seven methods defined by this structure (xMutexAlloc, xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and xMutexNotheld) implement the following interfaces (respectively): sqlite3_mutex_alloc() sqlite3_mutex_free() sqlite3_mutex_enter() sqlite3_mutex_try() sqlite3_mutex_leave() sqlite3_mutex_held() sqlite3_mutex_notheld() +(source: c3ref/mutex_methods.html, matrix: context, detail)

          + +
          R-27753-05999-58187-16156-08992-28399-17856-50930
          +

          The 5th parameter to the authorizer callback is the name of the database ("main", "temp", etc.) if applicable. +(source: c3ref/c_alter_table.html, checked-by: th3/cov1/auth03.test, matrix: context, detail)

          + +
          R-27775-64721-40407-04494-31964-21217-54345-17508
          +

          Both of these limits can be lowered at runtime using the sqlite3_limit() C/C++ interface. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-27800-48033-09479-04735-22303-21367-59255-07249
          +

          For the index above and WHERE clause like this: ... WHERE a=5 AND b IN (1,2,3) AND d='hello' Only columns a and b of the index would be usable. The d column would not be usable because column c is not constrained and there can be no gaps in the set of columns that usable by the index. +(source: optoverview.html, matrix: context, detail)

          + +
          R-27806-26076-28846-24074-00653-42186-57572-51475
          +

          The handler for an SQLITE_FCNTL_PRAGMA file control can optionally make the first element of the char** argument point to a string obtained from sqlite3_mprintf() or the equivalent and that string will become the result of the pragma or the error message if the pragma fails. +(source: c3ref/c_fcntl_begin_atomic_write.html, checked-by: src/test_multiplex.c, th3/cov1/pragma24.test, matrix: context, detail)

          + +
          R-27809-56550-37281-65484-19482-39813-11020-02299
          +

          The VACUUM command works by copying the contents of the database into a temporary database file and then overwriting the original with the contents of the temporary file. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-27819-43026-21380-16418-25214-30821-40612-27368
          +

          The _database_ routines return the database name, the _table_ routines return the table name, and the origin_ routines return the column name. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-27831-00579-12114-42310-13784-00983-37340-32180
          +

          NOT NULL is enforced on every column of the PRIMARY KEY in a WITHOUT ROWID table. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-27847-27229-42495-29063-58716-22268-05238-18530
          +

          The first argument is the database connection object to be interrogated. +(source: c3ref/db_status.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-27875-27272-27361-08539-07716-12839-63715-05434
          +

          The implied type conversion of mathematical operands is slightly different from CAST to NUMERIC in that string and BLOB values that look like real numbers but have no fractional part are kept as REAL instead of being converted into INTEGER as they would be for CAST to NUMERIC. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-27882-15425-11851-57208-29860-19997-13242-33591
          +

          This option is used to enable or disable the sqlite3_load_extension() interface independently of the load_extension() SQL function. +(source: c3ref/c_dbconfig_defensive.html, matrix: context, detail)

          + +
          R-27896-13480-56358-14836-45881-39569-16238-21022
          +

          The sqlite3_result_null() interface sets the return value of the application-defined function to be NULL. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-27910-63456-49633-56474-25927-30250-35983-46521
          +

          If an SQL operation is very nearly finished at the time when sqlite3_interrupt() is called, then it might not have an opportunity to be interrupted and might continue to completion. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-27925-06263-58551-32265-51230-19990-38380-59040
          +

          SQLite strives to keep heap memory utilization below the soft heap limit by reducing the number of pages held in the page cache as heap memory usages approaches the limit. +(source: c3ref/hard_heap_limit64.html, checked-by: th3/req1/softheaplimit02.test, matrix: context, detail)

          + +
          R-27935-58314-00156-50891-26988-61472-07043-33985
          +

          Any prior cache entry associated with newKey is guaranteed not to be pinned. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-27941-57764-10424-18721-07448-14003-34159-15666
          +

          The sqlite3_rollback_hook() interface registers a callback function to be invoked whenever a transaction is rolled back. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-27945-10199-33337-38453-50117-26077-19774-25797
          +

          Each ordinary SQL table in the database schema is represented on-disk by a table b-tree. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-27966-31616-60182-10304-08590-16090-08574-57683
          +

          An attempt to create a WITHOUT ROWID table without a PRIMARY KEY results in an error. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-27985-03553-20917-04804-06476-41235-27520-21131
          +

          These interfaces are used to retrieve runtime status information about the performance of SQLite, and optionally to reset various highwater marks. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-27988-54257-37832-50021-60393-63759-63179-56137
          +

          The RETURNING clause is not supported for triggers. +(source: lang_delete.html, matrix: context, detail)

          + +
          R-27994-60376-08852-47971-54191-53637-09431-08610
          +

          The same arbitrarily selected row is used for each non-aggregate expression. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-28051-48608-28159-47201-29527-20252-33499-18741
          +

          If xGeom returns anything other than SQLITE_OK, then the r-tree query will abort with an error. +(source: rtree.html, matrix: context, detail)

          + +
          R-28060-16686-02484-25378-20168-65175-45888-14189
          +

          So, for example, if sqlite3_result_text16le() is invoked with text that begins with bytes 0xfe, 0xff (a big-endian byte-order mark) then the first two bytes of input are skipped and the remaining input is interpreted as UTF16BE text. +(source: c3ref/result_blob.html, matrix: context, detail)

          + +
          R-28170-10886-01228-38547-37735-16350-02783-15797
          +

          To make an existing VFS into the default VFS, register it again with the makeDflt flag set. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-28176-28813-25399-58317-42934-47980-64589-03329
          +

          The xGeom callback always does a depth-first search of the r-tree. +(source: rtree.html, matrix: context, detail)

          + +
          R-28183-48984-04569-19175-13455-19458-08289-27795
          +

          If the callback returns non-zero, then another attempt is made to access the database and the cycle repeats. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-28207-40885-37612-34994-37916-57388-29422-16350
          +

          The last argument is a pointer into which the callback result should be written. +(source: rtree.html, matrix: context, detail)

          + +
          R-28220-46694-36270-42674-38857-47778-22952-56853
          +

          For example, if an "ON DELETE SET DEFAULT" action is configured, but there is no row in the parent table that corresponds to the default values of the child key columns, deleting a parent key while dependent child keys exist still causes a foreign key violation. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys18.test, matrix: context, detail)

          + +
          R-28258-23166-61617-36220-57922-46020-57990-00363
          +

          Row iRow is not present in the table +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-28262-47447-02372-41671-47406-00862-29752-13937
          +

          If a HAVING clause is a non-aggregate expression, it is evaluated with respect to an arbitrarily selected row from the group. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-28265-37702-63167-40719-28674-33175-26294-56765
          +

          The second argument is a pointer to the function to invoke when a row is updated, inserted or deleted in a rowid table. +(source: c3ref/update_hook.html, checked-by: th3/cov1/main15.test, matrix: context, detail)

          + +
          R-28279-44669-55028-49406-32452-64424-01870-54893
          +

          If nByte is positive, then it is the number of bytes read from zSql. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-28307-32767-23693-57600-42950-25827-15696-21088
          +

          All other databases use the normal locking mode by default and are affected by this pragma. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-28312-64704-30092-58113-01356-46939-35653-28661
          +

          However, the usable size is not allowed to be less than 480. In other words, if the page size is 512, then the reserved space size cannot exceed 32. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-28329-37702-19692-05275-47566-55090-16021-12790
          +

          The string literal must not begin with a wildcard; if the right-hand side begins with a wildcard character then this optimization is not attempted. +(source: optoverview.html, matrix: context, detail)

          + +
          R-28346-31823-44337-58654-12319-45607-22371-22984
          +

          A call to either function replaces the existing collation-needed callback. +(source: c3ref/collation_needed.html, matrix: context, detail)

          + +
          R-28351-07091-05361-50500-02238-36187-02311-00737
          +

          Note that an inner transaction might commit (using the RELEASE command) but then later have its work undone by a ROLLBACK in an outer transaction. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-28355-09804-02024-51679-13656-23007-30178-16776
          +

          If there is more than one table or subquery in FROM clause then the contents of all tables and/or subqueries are joined into a single dataset for the simple SELECT statement to operate on. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-28401-00140-19628-52826-12287-35959-24998-24420
          +

          Value is a string in the text encoding and (N-13)/2 bytes in length. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-28453-47400-61335-60267-59373-07041-42359-06361
          +

          This API may be used to register a callback that SQLite will invoke when the connection currently holding the required lock relinquishes it. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-28465-35432-54989-58142-09664-10793-19950-25889
          +

          When the temp_store setting is changed, all existing temporary tables, indices, triggers, and views are immediately deleted. +(source: pragma.html, matrix: context, detail)

          + +
          R-28518-13457-48277-27328-18424-50932-01795-30236
          +

          The optional "OR action" conflict clause that follows the UPDATE keyword allows the user to nominate a specific constraint conflict resolution algorithm to use during this one UPDATE command. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-28530-22001-17760-49127-38466-18799-32025-16275
          +

          Content is not actually committed on the disk until the outermost transaction commits. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-28535-44631-32814-50468-55427-04715-11501-46204
          +

          The likelihood(X) function is a no-op that the code generator optimizes away so that it consumes no CPU cycles during run-time (that is, during calls to sqlite3_step()). +(source: lang_corefunc.html, checked-by: tcl/func3.test, matrix: context, detail)

          + +
          R-28555-32340-54703-19587-00440-31117-26893-64821
          +

          This function is used to move an existing BLOB handle so that it points to a different row of the same database table. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-28594-02890-08451-24102-07094-48300-54751-43989
          +

          The one-byte flag at offset 0 indicating the b-tree page type. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-28659-11035-10621-07368-12698-03611-12155-24539
          +

          If the path begins with a '/' character, then it is interpreted as an absolute path. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-28676-08005-24857-51856-29072-62693-32404-21796
          +

          Table zTable does not exist within database zDb +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-28676-32830-52785-15539-23546-23390-27594-39349
          +

          The xMutexInit routine is called by SQLite exactly once for each effective call to sqlite3_initialize(). +(source: c3ref/mutex_methods.html, matrix: context, detail)

          + +
          R-28691-49464-13455-34259-09637-44341-17028-46530
          +

          The INDEXED BY and NOT INDEXED clauses are not allowed on DELETE statements within triggers. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-28740-04940-19074-59456-16824-11848-19165-57032
          +

          The time() function returns the time as HH:MM:SS. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-28760-53843-47957-08431-27887-29261-48374-11570
          +

          When more than two tables are joined together as part of a FROM clause, the join operations are processed in order from left to right. In other words, the FROM clause (A join-op-1 B join-op-2 C) is computed as ((A join-op-1 B) join-op-2 C). +(source: lang_select.html, checked-by: tcl/e_select2.test, matrix: context, detail)

          + +
          R-28765-22796-02386-57750-08034-62633-19124-45761
          +

          If the previous call to this routine had an N of 1 or more and a non-NULL P then the pseudo-randomness is generated internally and without recourse to the sqlite3_vfs xRandomness method. +(source: c3ref/randomness.html, checked-by: th3/cov1/random01.test, matrix: context, detail)

          + +
          R-28818-00847-36702-14411-16104-05353-45723-35449
          +

          Otherwise, they return the name of the attached database, table, or column that query result column was extracted from. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-28818-63526-62393-01881-62533-13491-06138-19891
          +

          If the table to which the trigger is attached is not in the temp database, then DELETE statements within the trigger body must operate on tables within the same database as it. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-28853-08147-20510-38197-22369-16459-32849-06937
          +

          However, if the SELECT is a compound SELECT, then ORDER BY expressions that are not aliases to output columns must be exactly the same as an expression used as an output column. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-28861-22117-11804-11458-17489-33951-18363-36356
          +

          The structure of the sqlite_schema table is as if it had been created using the following SQL: CREATE TABLE sqlite_schema( type text, name text, tbl_name text, rootpage integer, sql text ); +(source: fileformat2.html, matrix: context, detail)

          + +
          R-28870-48866-03452-03570-43153-10694-10376-44715
          +

          In SQLite, table rows normally have a 64-bit signed integer ROWID which is unique among all rows in the same table. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-28880-18896-60065-00895-16000-25645-24475-60986
          +

          The ALTER TABLE command does not work on statistics tables. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-28902-17274-01624-42364-46386-62149-20745-43372
          +

          EXPLAIN QUERY PLAN is most useful on a SELECT statement, but may also appear with other statements that read data from database tables (e.g. UPDATE, DELETE, INSERT INTO ... SELECT). +(source: eqp.html, matrix: context, detail)

          + +
          R-28911-57501-45271-30589-18471-43910-24083-24523
          +

          The defer_foreign_keys pragma defaults to OFF so that foreign key constraints are only deferred if they are created as "DEFERRABLE INITIALLY DEFERRED". +(source: pragma.html, checked-by: tcl/fkey6.test, th3/cov1/fkey24.test, matrix: context, detail)

          + +
          R-28989-00211-56037-13079-09434-49891-20969-08914
          +

          sqlite3_config() can be called as part of the implementation of an application-defined sqlite3_os_init(). +(source: c3ref/config.html, matrix: context, detail)

          + +
          R-28995-46979-25570-20018-47836-46368-43472-22663
          +

          The sqlite3_column_type() routine returns the datatype code for the initial data type of the result column. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-29005-40549-62573-61718-07162-40054-58592-42696
          +

          FTS4 uses term prefix indexes to speed up prefix queries. +(source: fts3.html, matrix: context, detail)

          + +
          R-29045-37224-33225-01178-62278-53898-40877-61168
          +

          For example, the sqlite_stat1 table might indicate that an equality constraint on column x reduces the search space to 10 rows on average, whereas an equality constraint on column y reduces the search space to 3 rows on average. In that case, SQLite would prefer to use index ex2i2 since that index is more selective. +(source: optoverview.html, matrix: context, detail)

          + +
          R-29052-00975-25766-49663-50070-52826-19346-28533
          +

          String and BLOB values that do not look like numbers are interpreted as 0. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-29055-19620-57316-63969-08563-57428-43116-59145
          +

          SQLite interprets the string from sqlite3_result_error16() as UTF-16 using the same byte-order determination rules as sqlite3_bind_text16(). +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-29082-45770-21240-41661-14924-48900-49346-30675
          +

          An attempt to read from an expired BLOB handle fails with an error code of SQLITE_ABORT. +(source: c3ref/blob_read.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-29130-21766-34227-41742-24593-26617-14935-23368
          +

          The sqlite3_str_finish(X) interface destroys the sqlite3_str object X and returns a pointer to a memory buffer obtained from sqlite3_malloc64() that contains the constructed string. +(source: c3ref/str_finish.html, matrix: context, detail)

          + +
          R-29137-58191-04727-48044-60255-14464-15278-17646
          +

          SQLITE_STATUS_MALLOC_COUNT This parameter records the number of separate memory allocations currently checked out. +(source: c3ref/c_status_malloc_count.html, matrix: context, detail)

          + +
          R-29144-37270-15316-24457-48532-24353-08508-55125
          +

          The ROLLBACK command with a TO clause rolls back transactions going backwards in time back to the most recent SAVEPOINT with a matching name. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-29161-24939-37010-28632-36605-59202-44014-09658
          +

          This is the number of sort operations that have occurred. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-29161-32953-36932-45614-26636-25376-16033-00724
          +

          If one operand has TEXT affinity and the other has no affinity, then TEXT affinity is applied to the other operand. +(source: datatype3.html, checked-by: th3/cov1/affinity01.test, th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-29177-48281-29998-61012-25413-14806-58383-44850
          +

          It then checkpoints all frames in the log file and syncs the database file. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-29187-47463-37855-25397-01259-03141-56758-63159
          +

          For indexes on an ordinary rowid table, N will be one more than the number of columns indexed. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-29198-50701-28906-62015-01619-10608-18054-51120
          +

          When the commit hook callback routine returns zero, the COMMIT operation is allowed to continue normally. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-29213-61195-54301-03299-01569-39638-01555-01215
          +

          The third and fourth arguments to the callback contain pointers to the database and table name containing the affected row. +(source: c3ref/update_hook.html, checked-by: tcl/hook.test, th3/cov1/main15.test, matrix: context, detail)

          + +
          R-29255-51137-31633-40808-05446-49202-54154-26438
          +

          For "X LIKE P" without the ESCAPE clause, set the E parameter of sqlite3_strlike(P,X,E) to 0. +(source: c3ref/strlike.html, matrix: context, detail)

          + +
          R-29276-00741-11068-20150-45137-35653-26807-40835
          +

          When the locking-mode is set to EXCLUSIVE, the database connection never releases file-locks. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-29283-15561-34387-21673-60506-52883-35719-11898
          +

          Otherwise, the storage class of the result is determined by applying the rules for determining column affinity to the type-name. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-29319-62175-31242-39109-13345-46061-10840-60903
          +

          If the source database connection is being used to write to the source database when sqlite3_backup_step() is called, then SQLITE_LOCKED is returned immediately. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-29353-26294-62114-45133-33417-28665-47147-29185
          +

          PRAGMA fullfsync PRAGMA fullfsync = boolean; Query or change the fullfsync flag. +(source: pragma.html, checked-by: th3/req1/pragma11b.test, matrix: context, detail)

          + +
          R-29353-35916-54935-35443-09756-12894-62191-13348
          +

          Generated columns can occur anywhere in the table definition. +(source: gencol.html, matrix: context, detail)

          + +
          R-29356-02391-20787-31753-20232-32348-21090-16703
          +

          If the database uses a 65536-byte page size and the reserved space is zero (the usual value for reserved space) then the cell content offset of an empty page wants to be 65536. However, that integer is too large to be stored in a 2-byte unsigned integer, so a value of 0 is used in its place. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-29387-20242-08784-06903-03129-29684-27650-40318
          +

          Some virtual table implementations might impose additional restrictions. +(source: lang_createvtab.html, matrix: context, detail)

          + +
          R-29410-53018-13680-36864-38018-28179-51962-01812
          +

          If there are too few arguments in the argument list, missing arguments are assumed to have a NULL value, which is translated into 0 or 0.0 for numeric formats or an empty string for %s. +(source: lang_corefunc.html, checked-by: tcl/printf2.test, th3/cov1/printf08.test, matrix: context, detail)

          + +
          R-29431-39229-16691-57532-51214-42870-42294-30038
          +

          The highwater mark associated with SQLITE_DBSTATUS_CACHE_WRITE is always 0. +(source: c3ref/c_dbstatus_options.html, checked-by: src/status.c, matrix: context, detail)

          + +
          R-29448-60346-55143-08707-47583-53661-32513-61785
          +

          PRAGMA schema.index_info(index-name); This pragma returns one row for each key column in the named index. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-29466-27412-45786-34057-43817-35684-25480-06167
          +

          If a given call to sqlite3_unlock_notify() would put the system in a deadlocked state, then SQLITE_LOCKED is returned and no unlock-notify callback is registered. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-29497-04603-39486-29131-04048-03697-44723-21949
          +

          A subsequent call to sqlite3_result_error() or sqlite3_result_error16() resets the error code to SQLITE_ERROR. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-29512-54644-05780-17564-45452-02840-21704-61078
          +

          If the table to which the trigger is attached is in the TEMP database, then the unqualified name of the table being updated is resolved in the same way as it is for a top-level statement (by searching first the TEMP database, then the main database, then any other databases in the order they were attached). +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-29517-30691-07524-03121-42038-48163-15213-35798
          +

          Hence, when an application changes the statistics tables directly, SQLite will not immediately notice the changes. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-29523-01234-45433-34913-07391-02140-19209-23434
          +

          When a "table-name" is specified, the only foreign key constraints checked are those created by REFERENCES clauses in the CREATE TABLE statement for table-name. +(source: pragma.html, checked-by: th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-29538-34987-07238-64188-64158-06889-50248-62239
          +

          The usual algorithm is to give the newly created row a ROWID that is one larger than the largest ROWID in the table prior to the insert. +(source: autoinc.html, checked-by: src/vdbe.c, th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-29565-52740-53863-51242-23520-28931-17220-09831
          +

          The sqlite3_stmt_isexplain(S) interface returns 1 if the prepared statement S is an EXPLAIN statement, or 2 if the statement S is an EXPLAIN QUERY PLAN. +(source: c3ref/stmt_isexplain.html, matrix: context, detail)

          + +
          R-29575-14878-05474-20512-63309-33241-31866-62624
          +

          Each call to either sqlite3_trace() or sqlite3_trace_v2() overrides (cancels) any prior calls to sqlite3_trace() or sqlite3_trace_v2(). +(source: c3ref/trace_v2.html, matrix: context, detail)

          + +
          R-29588-44058-56045-00722-36389-33824-35706-30523
          +

          An INSERT that fails due to a constraint violation is not a successful INSERT and does not change the value returned by this routine. +(source: c3ref/last_insert_rowid.html, matrix: context, detail)

          + +
          R-29600-32407-54811-33651-22955-26262-16018-30636
          +

          sqlite3_free() is used to free idxPtr if and only if needToFreeIdxPtr is true. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-29604-30395-11418-33165-02079-38209-02467-57208
          +

          However, COMMIT will fail as long as foreign key constraints remain in violation. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, th3/req1/foreignkeys14.test, matrix: context, detail)

          + +
          R-29609-10377-53436-28646-00070-22457-04173-55911
          +

          The right-hand side of an IN or NOT IN operator can be a table name or table-valued function name in which case the right-hand side is understood to be subquery of the form "(SELECT * FROM name)". +(source: lang_expr.html, checked-by: th3/cov1/in01.test, matrix: context, detail)

          + +
          R-29629-55858-55328-41166-17171-44417-01732-51851
          +

          Type is associated with individual values, not with the containers used to hold those values. +(source: c3ref/column_decltype.html, matrix: context, detail)

          + +
          R-29639-16887-16584-30400-13663-34877-64046-50311
          +

          The sqlite3_db_readonly(D,N) interface returns 1 if the database N of connection D is read-only, 0 if it is read/write, or -1 if N is not the name of a database on connection D. +(source: c3ref/db_readonly.html, checked-by: tcl/rdonly.test, matrix: context, detail)

          + +
          R-29639-49338-45805-35258-41039-23584-19093-35749
          +

          The sqlite3_create_function() interface can be used to override the like() function and thereby change the operation of the LIKE operator. +(source: lang_corefunc.html, checked-by: th3/req1/func02.test, matrix: context, detail)

          + +
          R-29649-49812-55856-43048-16547-37449-39759-10169
          +

          The nullif(X,Y) function returns its first argument if the arguments are different and NULL if the arguments are the same. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, th3/req1/func03.test, matrix: context, detail)

          + +
          R-29653-64292-04142-32577-33842-31550-59902-00796
          +

          The second argument to the busy handler callback is the number of times that the busy handler has been invoked previously for the same locking event. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-29691-21352-53312-54436-56868-51235-26976-62729
          +

          For a blob value X, length(X) returns the number of bytes in the blob. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-29701-50711-44772-52633-13865-01358-40998-48117
          +

          The unicode(X) function returns the numeric unicode code point corresponding to the first character of the string X. +(source: lang_corefunc.html, checked-by: tcl/func.test, matrix: context, detail)

          + +
          R-29702-55194-05446-48408-53607-29729-56782-07687
          +

          If either operand has an explicit collating function assignment using the postfix COLLATE operator, then the explicit collating function is used for comparison, with precedence to the collating function of the left operand. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-29704-26647-58862-58935-31533-13851-11315-20283
          +

          Application developers can use the EXPLAIN QUERY PLAN prefix on a statement to get a high-level overview of the chosen query strategy. +(source: optoverview.html, matrix: context, detail)

          + +
          R-29730-42609-05554-56391-51377-12498-20824-07696
          +

          In this case the result of evaluating the left-most expression from each term of the VALUES list is inserted into the left-most column of each new row, and so forth for each subsequent expression. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-29736-23230-43340-15713-20658-37994-08323-17511
          +

          The sqlite3_str_new(D) interface allocates and initializes a new sqlite3_str object. +(source: c3ref/str_new.html, matrix: context, detail)

          + +
          R-29740-29379-09735-48719-34134-53325-08131-24362
          +

          For any key X, pointers to the left of a X refer to b-tree pages on which all keys are less than or equal to X. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-29747-05924-20663-28243-45594-47687-47105-58596
          +

          FULL blocks concurrent writers while it is running, but readers can proceed. +(source: pragma.html, matrix: context, detail)

          + +
          R-29748-45567-07187-24756-39474-12329-09927-01777
          +

          A function where the preferred text encoding matches the database encoding is a better match than a function where the encoding is different. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-29753-05667-59108-06137-58483-55469-25582-30166
          +

          The text of query parameters is appended to the filename argument of the xOpen method of the VFS. +(source: uri.html, matrix: context, detail)

          + +
          R-29765-45832-49120-26582-31576-30942-45829-65039
          +

          When an INTEGER or REAL is compared to another INTEGER or REAL, a numerical comparison is performed. +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-29779-04281-26216-55813-25026-31775-44460-23073
          +

          If the ORDER BY expression is a constant integer K then the expression is considered an alias for the K-th column of the result set (columns are numbered from left to right starting with 1). +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-29781-51289-55954-01701-34718-07402-02199-48708
          +

          So, ordinary rowid tables in SQLite violate the SQL standard and allow NULL values in PRIMARY KEY fields. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-29804-27366-08727-59986-31864-09983-14088-09844
          +

          If offset iOffset is less than N bytes from the end of the BLOB, SQLITE_ERROR is returned and no data is written. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-29830-14325-45586-46074-54512-52450-29043-42603
          +

          If the savepoint-name in a ROLLBACK TO command does not match any SAVEPOINT on the stack, then the ROLLBACK command fails with an error and leaves the state of the database unchanged. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-29851-52272-33233-14067-54274-53843-25272-26823
          +

          Value is a big-endian 64-bit twos-complement integer. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-29855-60809-01544-19871-54336-63942-18466-34966
          +

          The source database connection may be used by the application for other purposes while a backup operation is underway or being initialized. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-29868-13536-10966-03336-45139-07308-57583-25685
          +

          If a NOT NULL constraint is specified, then the column must have a default value other than NULL. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-29872-04040-27270-03833-42234-32060-43929-61511
          +

          If those locks cannot be obtained immediately and there is a busy-handler callback configured, it is invoked in the usual manner. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-29875-31678-61620-24152-15277-25938-13734-04890
          +

          The argument to the SQLITE_FCNTL_PRAGMA file control is an array of pointers to strings (char**) in which the second element of the array is the name of the pragma and the third element is the argument to the pragma or NULL if the pragma has no argument. +(source: c3ref/c_fcntl_begin_atomic_write.html, checked-by: src/pragma.c, src/test_multiplex.c, matrix: context, detail)

          + +
          R-29897-28851-11131-17538-15635-12313-50588-15022
          +

          Such transactions usually persist until the next COMMIT or ROLLBACK command. But a transaction will also ROLLBACK if the database is closed or if an error occurs and the ROLLBACK conflict resolution algorithm is specified. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-29901-08836-51888-40758-53445-49475-03703-08720
          +

          The SQLITE_OPEN_EXCLUSIVE flag is always used in conjunction with the SQLITE_OPEN_CREATE flag, which are both directly analogous to the O_EXCL and O_CREAT flags of the POSIX open() API. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-29907-43640-25763-15861-54141-28138-53381-17065
          +

          This file control takes the file descriptor out of batch write mode so that all subsequent write operations are independent. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-29907-62378-42519-29973-48919-58819-22759-58497
          +

          Calling sqlite3_auto_extension(X) with an entry point X that is already on the list of automatic extensions is a harmless no-op. +(source: c3ref/auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-29924-24161-31191-57990-51475-61688-39790-55251
          +

          EXCLUSIVE is similar to IMMEDIATE in that a write transaction is started immediately. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-29946-11104-19867-16845-18883-10746-06540-64125
          +

          Example Typenames From TheCREATE TABLE Statement or CAST Expression Resulting Affinity Rule Used To Determine Affinity INT INTEGER TINYINT SMALLINT MEDIUMINT BIGINT UNSIGNED BIG INT INT2 INT8 INTEGER 1 CHARACTER(20) VARCHAR(255) VARYING CHARACTER(255) NCHAR(55) NATIVE CHARACTER(70) NVARCHAR(100) TEXT CLOB TEXT 2 BLOB no datatype specified BLOB 3 REAL DOUBLE DOUBLE PRECISION FLOAT REAL 4 NUMERIC DECIMAL(10,5) BOOLEAN DATE DATETIME NUMERIC 5 +(source: datatype3.html, checked-by: th3/req1/datatype3_02.test, matrix: context, detail)

          + +
          R-29987-53326-32227-44761-37373-28199-35279-34751
          +

          The leftmost column of the result set has the index 0. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-29989-03153-00644-12353-52386-44408-44979-16456
          +

          If the argument to sqlite3_mutex_enter(), sqlite3_mutex_try(), or sqlite3_mutex_leave() is a NULL pointer, then all three routines behave as no-ops. +(source: c3ref/mutex_alloc.html, checked-by: th3/cov1/mutex01.test, matrix: context, detail)

          + +
          R-30008-03647-27202-20831-29850-54434-32362-14140
          +

          If the result is a BLOB or UTF-16 string then the sqlite3_column_bytes16() routine returns the number of bytes in that BLOB or string. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-30025-13801-01234-26643-63886-25441-43268-35607
          +

          The psow parameter indicates whether or not the powersafe overwrite property does or does not apply to the storage media on which the database file resides. +(source: c3ref/open.html, checked-by: th3/cov1/psow01.test, matrix: context, detail)

          + +
          R-30082-38996-55894-31210-19025-03289-36793-27218
          +

          The non-equals operator can be either != or <>. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-30083-58938-31645-59750-38554-41419-43937-22175
          +

          The index of the column is stored in aConstraint[].iColumn. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-30104-14201-52849-13140-57489-26582-19257-15267
          +

          Additional application-specific collating functions can be added to SQLite using the sqlite3_create_collation() interface. +(source: fileformat2.html, checked-by: th3/th3util.c, matrix: context, detail)

          + +
          R-30105-58549-25183-38919-44198-38701-12397-38507
          +

          PASSIVE Checkpoint as many frames as possible without waiting for any database readers or writers to finish. Sync the db file if all frames in the log are checkpointed. +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-30135-06439-12622-19657-03902-02051-33050-20191
          +

          The wal_autocheckpoint pragma can be used to invoke this interface from SQL. +(source: c3ref/wal_autocheckpoint.html, checked-by: tcl/e_walauto.test, matrix: context, detail)

          + +
          R-30140-15527-13572-28268-32284-47435-56739-50325
          +

          The compress option is used to specify the compress function. +(source: fts3.html, matrix: context, detail)

          + +
          R-30164-60316-40156-60446-50221-53227-39726-53106
          +

          The number of pages in cache must exceed both the cache_spill threshold and the maximum cache size set by the PRAGMA cache_size statement in order for spilling to occur. +(source: pragma.html, matrix: context, detail)

          + +
          R-30185-15359-41231-64088-51727-20362-49126-10873
          +

          The default suggested cache size is -2000, which means the cache size is limited to 2048000 bytes of memory. +(source: pragma.html, checked-by: src/sqliteLimit.h, th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-30189-54097-58322-43687-36717-28803-52946-09131
          +

          For each limit category SQLITE_LIMIT_NAME there is a hard upper bound set at compile-time by a C preprocessor macro called SQLITE_MAX_NAME. (The "_LIMIT_" in the name is changed to "_MAX_".) +(source: c3ref/limit.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-30195-08968-16924-33658-13499-65099-07965-35563
          +

          All automatic checkpoints are PASSIVE. +(source: pragma.html, matrix: context, detail)

          + +
          R-30224-53949-52765-04057-07963-58169-00243-05425
          +

          The load_extension() function will fail if the extension attempts to modify or delete an SQL function or collating sequence. +(source: lang_corefunc.html, checked-by: th3/cov1/func03.test, matrix: context, detail)

          + +
          R-30243-02494-34522-44043-46462-44113-55048-51587
          +

          The sqlite3_stricmp() and sqlite3_strnicmp() APIs allow applications and extensions to compare the contents of two buffers containing UTF-8 strings in a case-independent fashion, using the same definition of "case independence" that SQLite uses internally when comparing identifiers. +(source: c3ref/stricmp.html, checked-by: src/util.c, matrix: context, detail)

          + +
          R-30264-64343-18676-16200-46556-14505-34639-51509
          +

          All arguments are preceded by a single space. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-30269-25284-41363-48378-16742-02348-00072-11353
          +

          The default value of the fullfsync flag is off. +(source: pragma.html, checked-by: th3/req1/pragma11b.test, matrix: context, detail)

          + +
          R-30311-39793-14973-30919-34186-11921-51287-47112
          +

          The minimum value is the first non-NULL value that would appear in an ORDER BY of the column. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-30323-21917-40561-21411-57538-63013-10240-64875
          +

          Each foreign key constraint in SQLite is classified as either immediate or deferred. +(source: foreignkeys.html, checked-by: src/build.c, src/fkey.c, src/sqliteInt.h, tcl/e_fkey.test, th3/req1/foreignkeys12.test, matrix: context, detail)

          + +
          R-30347-18702-41681-51017-11561-03801-56644-21815
          +

          Casting a REAL or INTEGER value to NUMERIC is a no-op, even if a real value could be losslessly converted to an integer. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-30358-48480-02487-45285-44102-55038-52936-37421
          +

          The SQLITE_SOURCE_ID macro evaluates to a string which identifies a particular check-in of SQLite within its configuration management system. +(source: c3ref/c_source_id.html, checked-by: th3/req1/version01.test, matrix: context, detail)

          + +
          R-30374-63100-15715-29897-06518-00278-46226-59168
          +

          Every call to sqlite3_backup_step() obtains a shared lock on the source database that lasts for the duration of the sqlite3_backup_step() call. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-30391-20943-57014-62404-57876-35219-41861-22105
          +

          There can only be a single busy handler defined for each database connection. Setting a new busy handler clears any previously set handler. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-30433-25443-23879-51033-37593-48703-34224-12115
          +

          An underscore ("_") in the LIKE pattern matches any single character in the string. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-30470-29835-03618-00817-05721-31518-05673-45416
          +

          Any column in an SQLite version 3 database, except an INTEGER PRIMARY KEY column, may be used to store a value of any storage class. +(source: datatype3.html, checked-by: th3/req1/datatype3_11.test, matrix: context, detail)

          + +
          R-30481-56627-22651-35996-10349-58660-54475-15242
          +

          Any scalar expression may be used in the LIMIT clause, so long as it evaluates to an integer or a value that can be losslessly converted to an integer. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-30493-01537-45458-43801-08603-54598-05440-48528
          +

          If this routine has not been previously called or if the previous call had N less than one or a NULL pointer for P, then the PRNG is seeded using randomness obtained from the xRandomness method of the default sqlite3_vfs object. +(source: c3ref/randomness.html, checked-by: th3/cov1/random01.test, matrix: context, detail)

          + +
          R-30526-43432-10994-07089-02178-39041-60976-54446
          +

          The locking mode of temp and in-memory databases cannot be changed. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-30582-29746-05981-37310-62755-30295-44870-62832
          +

          If the callback on a commit hook function returns non-zero, then the commit is converted into a rollback. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-30617-11336-33984-38056-06680-32424-07593-35065
          +

          After calling the xDestroy() method, SQLite considers the sqlite3_pcache* handle invalid, and will not use it with any other sqlite3_pcache_methods2 functions. +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-30638-59954-59281-20323-32142-07020-22821-14638
          +

          In a CASE without a base expression, each WHEN expression is evaluated and the result treated as a boolean, starting with the leftmost and continuing to the right. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-30687-15230-29813-38800-06728-37939-57957-31201
          +

          The WAL header is 32 bytes in size and consists of the following eight big-endian 32-bit unsigned integer values: WAL Header Format OffsetSizeDescription 04 Magic number. 0x377f0682 or 0x377f0683 44 File format version. Currently 3007000. 84 Database page size. Example: 1024 124 Checkpoint sequence number 164 Salt-1: random integer incremented with each checkpoint 204 Salt-2: a different random number for each checkpoint 244 Checksum-1: First part of a checksum on the first 24 bytes of header 284 Checksum-2: Second part of the checksum on the first 24 bytes of header +(source: fileformat2.html, matrix: context, detail)

          + +
          R-30791-11785-26457-12987-43722-30660-26434-24770
          +

          The sqlite3_strlike(P,X,E) function matches Unicode characters, though only ASCII characters are case folded. +(source: c3ref/strlike.html, matrix: context, detail)

          + +
          R-30809-57812-61495-62022-11490-25278-56613-15778
          +

          The final callback parameter is the rowid of the row. +(source: c3ref/update_hook.html, checked-by: tcl/hook.test, th3/cov1/main15.test, matrix: context, detail)

          + +
          R-30842-64597-38059-54199-19748-27245-38788-44472
          +

          If a write-transaction is open on database connection D when the sqlite3_db_cacheflush(D) interface invoked, any dirty pages in the pager-cache that are not currently in use are written out to disk. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-30866-25765-07571-30018-14065-28481-40844-53725
          +

          The callback is invoked from within the sqlite3_step or sqlite3_close call that concludes the blocking connection's transaction. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-30879-62015-53996-61326-18041-63884-46339-47880
          +

          And the declared type of "STRING" has an affinity of NUMERIC, not TEXT. +(source: datatype3.html, checked-by: th3/req1/datatype3_02.test, matrix: context, detail)

          + +
          R-30918-12436-57339-31834-32101-57409-49210-29864
          +

          The sqlite3_result_text64() interface sets the return value of an application-defined function to be a text string in an encoding specified by the fifth (and last) parameter, which must be one of SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16BE, or SQLITE_UTF16LE. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-30955-38324-06638-08685-16466-65436-15533-06365
          +

          If the UPDATE statement also has an OFFSET clause, then it is similarly evaluated and cast to an integer value. If the OFFSET expression evaluates to a non-negative value M, then the first M rows are skipped and the following N rows updated instead. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-30964-04756-41013-33290-38906-18403-44827-12997
          +

          The legacy behavior was that sqlite3_step() would only return a generic SQLITE_ERROR result code and the application would have to make a second call to sqlite3_reset() in order to find the underlying cause of the problem. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare03.test, matrix: context, detail)

          + +
          R-30967-33251-18681-38633-21419-53092-54100-57767
          +

          Memory to hold the error message string is managed internally and must not be freed by the application +(source: c3ref/errcode.html, matrix: context, detail)

          + +
          R-30981-64168-44842-46448-61673-47635-40067-59553
          +

          For each UNIQUE constraint on the table, each row must contain a unique combination of values in the columns identified by the UNIQUE constraint. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-31029-02789-51389-40070-25151-19392-18984-32450
          +

          Root pages are moved to the beginning of the database file by the CREATE TABLE, CREATE INDEX, DROP TABLE, and DROP INDEX operations. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-31035-48105-55236-17512-32062-12366-10110-52557
          +

          If no arguments are given, all attached databases are analyzed. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-31067-37494-56120-35098-11105-54623-54147-27483
          +

          Triggers are removed using the DROP TRIGGER statement. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-31070-13763-03261-14688-14121-11229-57314-08102
          +

          The sqlite3_busy_handler(D,X,P) routine sets a callback function X that might be invoked with argument P whenever an attempt is made to access a database table associated with database connection D when another thread or process has the table locked. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-31074-37730-44024-06868-31899-04779-58492-60283
          +

          Any SELECT statement, including compound SELECTs and SELECT statements with ORDER BY and/or LIMIT clauses, may be used in an INSERT statement of this form. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-31086-35521-56938-30140-08121-54172-49179-57363
          +

          On success, SQLITE_OK is returned and the new BLOB handle is stored in *ppBlob. Otherwise an error code is returned and, unless the error code is SQLITE_MISUSE, *ppBlob is set to NULL. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-31130-45753-58005-22978-58145-31360-08893-12454
          +

          The SQLITE_SOURCE_ID string contains the date and time of the check-in (UTC) and a SHA1 or SHA3-256 hash of the entire source tree. +(source: c3ref/c_source_id.html, checked-by: th3/req1/version01.test, matrix: context, detail)

          + +
          R-31163-29022-10663-19494-01661-06524-11639-30452
          +

          The "E" character that begins the exponentiation clause of a floating point literal can be either upper or lower case. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-31195-28735-28971-60122-53361-51297-04226-18526
          +

          Every table must have at least one non-generated column. +(source: gencol.html, matrix: context, detail)

          + +
          R-31200-13290-19748-06553-12904-19504-15586-34616
          +

          The sqlite3_db_filename(D,N) interface returns a pointer to the filename associated with database N of connection D. +(source: c3ref/db_filename.html, checked-by: th3/cov1/attach04.test, matrix: context, detail)

          + +
          R-31204-44780-48490-01818-36589-33853-37932-09648
          +

          Database zDb does not exist +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-31231-36717-57726-13439-19567-41766-26823-60811
          +

          The new mutex is recursive when SQLITE_MUTEX_RECURSIVE is used but not necessarily so when SQLITE_MUTEX_FAST is used. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-31235-42643-53508-27982-17967-09319-44968-07098
          +

          The fourth column in the output of the foreign_key_check pragma is the same integer as the first column in the output of the foreign_key_list pragma. +(source: pragma.html, checked-by: th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-31246-29731-62646-60277-08521-29245-49284-60874
          +

          The pContext member of the sqlite3_rtree_geometry structure is always set to a copy of the pContext argument passed to sqlite3_rtree_geometry_callback() when the callback is registered. +(source: rtree.html, matrix: context, detail)

          + +
          R-31248-24630-37475-28758-64215-56604-24000-32221
          +

          The 32-bit integers are big-endian if the magic number in the first 4 bytes of the WAL header is 0x377f0683 and the integers are little-endian if the magic number is 0x377f0682. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-31275-44060-31786-28874-63587-64128-53792-58628
          +

          Strings returned by sqlite3_column_text() and sqlite3_column_text16(), even empty strings, are always zero-terminated. +(source: c3ref/column_blob.html, checked-by: src/vdbemem.c, th3/req1/column01.test, matrix: context, detail)

          + +
          R-31305-35170-11464-64098-34506-16219-33057-18056
          +

          After the header and zero padding are zero or more page records. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-31312-33516-05278-47140-12669-18608-41834-55008
          +

          The lower(X) function returns a copy of string X with all ASCII characters converted to lower case. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-31322-10196-14986-33891-01213-47655-00762-39748
          +

          Each trigger must specify that it will fire for one of the following operations: DELETE, INSERT, UPDATE. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-31338-54830-28259-56420-63783-19909-54858-57072
          +

          The error code and message for the failed call to sqlite3_backup_init() can be retrieved using the sqlite3_errcode(), sqlite3_errmsg(), and/or sqlite3_errmsg16() functions. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-31386-03131-57152-48354-62931-03354-07372-50774
          +

          The authorizer callback should return SQLITE_OK to allow the action, SQLITE_IGNORE to disallow the specific action but allow the SQL statement to continue to be compiled, or SQLITE_DENY to cause the entire SQL statement to be rejected with an error. +(source: c3ref/set_authorizer.html, matrix: context, detail)

          + +
          R-31406-45734-45366-20105-37202-23050-60311-59562
          +

          If the 2nd parameter to sqlite3_exec() is a NULL pointer, a pointer to an empty string, or a pointer that contains only whitespace and/or SQL comments, then no SQL statements are evaluated and the database is not changed. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-31407-09838-16507-11461-46420-27815-09445-39948
          +

          The sqlite3_user_data() interface returns a copy of the pointer that was the pUserData parameter (the 5th parameter) of the sqlite3_create_function() and sqlite3_create_function16() routines that originally registered the application defined function. +(source: c3ref/user_data.html, checked-by: th3/req1/userdata01.test, matrix: context, detail)

          + +
          R-31429-36570-40063-15627-34756-54740-34056-60066
          +

          Subverting this mechanism by using "PRAGMA schema_version" may cause SQL statement to run using an obsolete schema, which can lead to incorrect answers and/or database corruption. +(source: pragma.html, checked-by: th3/req1/pragma28.test, matrix: context, detail)

          + +
          R-31442-26915-27818-62289-58213-54460-29931-06977
          +

          The default built-in lower() function works for ASCII characters only. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-31453-41389-40618-59449-38915-45174-40720-02932
          +

          For example, the function "count(distinct X)" will return the number of distinct values of column X instead of the total number of non-null values in column X. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-31509-21858-22614-04075-64482-13479-08451-58532
          +

          The "order" option may be set to either "DESC" or "ASC" (in upper or lower case). +(source: fts3.html, matrix: context, detail)

          + +
          R-31509-40414-28527-23209-39294-56164-06955-51281
          +

          The purpose of the likelihood(X,Y) function is to provide a hint to the query planner that the argument X is a boolean that is true with a probability of approximately Y. +(source: lang_corefunc.html, checked-by: th3/cov1/where42.test, matrix: context, detail)

          + +
          R-31518-37056-56231-07788-10281-54147-06570-65506
          +

          If the destructor argument is SQLITE_STATIC, it means that the content pointer is constant and will never change. +(source: c3ref/c_static.html, checked-by: th3/req1/clearbind01.test, th3/req1/static01.test, matrix: context, detail)

          + +
          R-31520-16302-20553-09634-49353-53000-23080-58537
          +

          When a table is referenced by a SELECT but no column values are extracted from that table (for example in a query like "SELECT count(*) FROM tab") then the SQLITE_READ authorizer callback is invoked once for that table with a column name that is an empty string. +(source: c3ref/set_authorizer.html, checked-by: tcl/auth.test, th3/cov1/auth01.test, matrix: context, detail)

          + +
          R-31536-32008-60945-18932-27030-19997-64437-42960
          +

          Literal values may be integers, floating point numbers, strings, BLOBs, or NULLs. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-31537-00101-65351-40298-33316-64699-39889-60990
          +

          If a HAVING clause is specified, it is evaluated once for each group of rows as a boolean expression. If the result of evaluating the HAVING clause is false, the group is discarded. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-31538-00384-26321-49073-43364-40462-44753-02654
          +

          _. +(source: undoredo.html, matrix: context, detail)

          + +
          R-31559-52189-63274-09210-03777-15240-18014-01548
          +

          Inner joins can be freely reordered. +(source: optoverview.html, matrix: context, detail)

          + +
          R-31567-38587-20789-38106-63049-52268-08688-06103
          +

          If the table to which the trigger is attached is in the TEMP database, then the unqualified name of the table being deleted is resolved in the same way as it is for a top-level statement (by searching first the TEMP database, then the main database, then any other databases in the order they were attached). +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-31579-59686-01381-52027-49305-56500-23555-06857
          +

          To avoid having to register all collation sequences before a database can be used, a single callback function may be registered with the database connection to be invoked whenever an undefined collation sequence is required. +(source: c3ref/collation_needed.html, matrix: context, detail)

          + +
          R-31603-05822-25247-46496-01667-17001-45146-39739
          +

          The sqlite3_trace_v2(D,M,X,P) interface registers a trace callback function X against database connection D, using property mask M and context pointer P. +(source: c3ref/trace_v2.html, matrix: context, detail)

          + +
          R-31603-41906-64593-49135-09537-60740-41731-32155
          +

          The name of the table (as it appears in sqlite_schema.name) is in the sqlite_sequence.main field and the largest INTEGER PRIMARY KEY ever inserted into that table is in the sqlite_sequence.seq field. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-31624-24737-51221-05558-39670-00793-48763-40650
          +

          RTRIM is like BINARY except that extra spaces at the end of either string do not change the result. In other words, strings will compare equal to one another as long as they differ only in the number of spaces at the end. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-31676-45509-42539-51511-07128-62436-51993-36875
          +

          If X is the integer -9223372036854775808 then abs(X) throws an integer overflow error since there is no equivalent positive 64-bit two complement value. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/func01.test, matrix: context, detail)

          + +
          R-31757-07599-53600-28407-17941-01600-55959-20235
          +

          As an internal optimization, small floating point values with no fractional component and stored in columns with REAL affinity are written to disk as integers in order to take up less space and are automatically converted back into floating point as the value is read out. +(source: datatype3.html, checked-by: th3/req1/datatype3_12.test, matrix: context, detail)

          + +
          R-31773-41793-43777-15026-65463-02438-20954-63890
          +

          If sqlite3_open_v2() is used and the "cache" parameter is present in a URI filename, its value overrides any behavior requested by setting SQLITE_OPEN_PRIVATECACHE or SQLITE_OPEN_SHAREDCACHE flag. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-31775-48204-44006-26750-02620-57678-37164-54735
          +

          Or, if a PRIMARY KEY clause is specified as a table-constraint, then the primary key of the table consists of the list of columns specified as part of the PRIMARY KEY clause. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-31795-57643-34892-44323-47602-12322-63634-37934
          +

          a NOT NULL constraint dictates that the associated column may not contain a NULL value. Attempting to set the column value to NULL when inserting a new row or updating an existing one causes a constraint violation. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-31812-49659-31326-36358-44931-00819-19755-27412
          +

          The size of a blob may not be changed by this interface. +(source: c3ref/blob_open.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-31816-13824-03247-24421-35841-11575-32489-23110
          +

          PRAGMA legacy_alter_table; PRAGMA legacy_alter_table = boolean This pragma sets or queries the value of the legacy_alter_table flag. +(source: pragma.html, matrix: context, detail)

          + +
          R-31820-22006-44575-45426-57001-50586-37778-41806
          +

          If the final parameter to sqlite3_create_function_v2() or sqlite3_create_window_function() is not NULL, then it is destructor for the application data pointer. The destructor is invoked when the function is deleted, either by being overloaded or when the database connection closes. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc07.test, matrix: context, detail)

          + +
          R-31826-01813-36062-43919-63231-47318-45635-11887
          +

          An error is raised if more than one PRIMARY KEY clause appears in a CREATE TABLE statement. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-31839-40105-47825-07965-38954-04263-02531-41060
          +

          Both forms of the pragma return the maximum page count. +(source: pragma.html, checked-by: th3/req1/pragma12.test, matrix: context, detail)

          + +
          R-31842-04164-45925-20128-62976-05013-64077-31889
          +

          The zeroblob(N) function returns a BLOB consisting of N bytes of 0x00. +(source: lang_corefunc.html, checked-by: th3/cov1/func04.test, matrix: context, detail)

          + +
          R-31855-18665-44731-17316-60627-29707-46771-04515
          +

          If sqlite3_open_v2() is used and the vfs option is present, then the VFS specified by the option takes precedence over the value passed as the fourth parameter to sqlite3_open_v2(). +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-31877-46991-26033-20819-54780-54256-64426-46176
          +

          In addition to being a result code, the SQLITE_ABORT value is also used as a conflict resolution mode returned from the sqlite3_vtab_on_conflict() interface. +(source: rescode.html, checked-by: th3/cov1/vtab04.test, th3/cov1/vtab07.test, matrix: context, detail)

          + +
          R-31881-13880-39891-17539-21926-06368-53167-38054
          +

          When an applicable constraint violation occurs, the ROLLBACK resolution algorithm aborts the current SQL statement with an SQLITE_CONSTRAINT error and rolls back the current transaction. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-31882-08811-51062-63000-47445-51971-26333-04918
          +

          But the FAIL resolution does not back out prior changes of the SQL statement that failed nor does it end the transaction. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-31883-14373-53297-17557-08649-10879-14648-40339
          +

          If the path component is omitted, then the database is stored in a temporary file that will be automatically deleted when the database connection closes. +(source: uri.html, matrix: context, detail)

          + +
          R-31884-19145-46591-63123-39712-55381-35148-20037
          +

          The syntax for the ON CONFLICT clause is as shown above for the CREATE TABLE command. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-31929-21448-54248-05455-38618-31976-59904-18809
          +

          during the original sqlite3_set_auxdata() call when a memory allocation error occurs. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-31969-57825-42101-14521-32158-26846-01551-49036
          +

          If EXCLUSIVE locking mode is set prior to the first WAL-mode database access, then SQLite never attempts to call any of the shared-memory methods and hence no shared-memory wal-index is ever created. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-31984-08010-07046-54406-16085-56792-07633-10679
          +

          On windows, if the absolute path begins with "/X:/" where X is any single ASCII alphabetic character ("a" through "z" or "A" through "Z") then the "X:" is understood to be the drive letter of the volume containing the file, not the toplevel directory. +(source: uri.html, matrix: context, detail)

          + +
          R-31989-51162-12344-35872-57783-63477-65151-09543
          +

          Text is appended to the sqlite3_str object using various methods, such as sqlite3_str_appendf(). +(source: c3ref/str.html, matrix: context, detail)

          + +
          R-31997-24564-21710-03958-33842-06684-32775-28605
          +

          If no schema name is specified and the TEMP keyword is not present then the table is created in the main database. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-32023-34269-07081-56751-59037-09134-01490-38261
          +

          The second parameter is the name of the SQL function to be created or redefined. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, matrix: context, detail)

          + +
          R-32090-20403-62451-54879-55700-60084-08956-01962
          +

          Autocommit mode is re-enabled by a COMMIT or ROLLBACK. +(source: c3ref/get_autocommit.html, matrix: context, detail)

          + +
          R-32163-18986-58302-09222-31539-08493-63340-58892
          +

          The sqlite3_normalized_sql(P) interface returns a pointer to a UTF-8 string containing the normalized SQL text of prepared statement P. +(source: c3ref/expanded_sql.html, matrix: context, detail)

          + +
          R-32172-42404-39492-45133-11034-45047-00308-58009
          +

          Function sqlite3_backup_step(B,N) will copy up to N pages between the source and destination databases specified by sqlite3_backup object B. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup03.test, matrix: context, detail)

          + +
          R-32181-50629-37005-34302-07700-29801-11487-35180
          +

          Queries that contain a single MIN() or MAX() aggregate function whose argument is the left-most column of an index might be satisfied by doing a single index lookup rather than by scanning the entire table. +(source: optoverview.html, matrix: context, detail)

          + +
          R-32235-53300-57293-28888-55345-58030-49173-41178
          +

          FOR EACH ROW implies that the SQL statements specified in the trigger may be executed (depending on the WHEN clause) for each database row being inserted, updated or deleted by the statement causing the trigger to fire. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-32246-51249-01476-28736-10889-32262-29627-47860
          +

          The preupdate hook is disabled by invoking sqlite3_preupdate_hook() with a NULL pointer as the second parameter. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-32266-59420-04967-20715-46228-25200-01200-16446
          +

          If the second parameter (zDbName) does not match the name of any open database file, then SQLITE_ERROR is returned. +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-32267-31938-07296-47086-37699-20446-18682-32942
          +

          The data_store_directory pragma may modify this variable and cause it to point to memory obtained from sqlite3_malloc. +(source: c3ref/data_directory.html, matrix: context, detail)

          + +
          R-32326-44592-25744-64223-64465-06212-39042-00138
          +

          Unlike normal SQLite columns, an integer primary key or rowid column must contain integer values. Integer primary key or rowid columns are not able to hold floating point values, strings, BLOBs, or NULLs. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-32329-22225-62429-19871-19916-05643-31400-56048
          +

          The sqlite_stat4.idx column holds name of the index that the row describes, or in the case of an sqlite_stat4 entry for a WITHOUT ROWID table, the name of the table itself. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-32333-58476-07670-32465-34848-10846-33271-03352
          +

          Triggers are automatically dropped when the table that they are associated with (the table-name table) is dropped. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-32341-39358-46818-14772-56147-53577-21121-58224
          +

          However if the phrase "WITHOUT ROWID" is added to the end of a CREATE TABLE statement, then the special "rowid" column is omitted. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-32349-39610-03152-29035-33006-19037-05076-08294
          +

          sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; QUERY PLAN `--SCAN TABLE t1 +(source: eqp.html, matrix: context, detail)

          + +
          R-32365-09043-50030-24839-64719-45976-15708-15010
          +

          A "CREATE TABLE ... AS SELECT" statement creates and populates a database table based on the results of a SELECT statement. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-32434-09092-13813-42395-15886-36394-05508-61902
          +

          If the value of expr is NULL, then the result of the CAST expression is also NULL. +(source: lang_expr.html, checked-by: tcl/e_expr.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-32485-24703-27801-29483-21531-11705-09294-53002
          +

          The RENAME TO syntax changes the name of table-name to new-table-name. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-32562-20566-46417-07999-12317-06673-44579-53773
          +

          When three or more simple SELECTs are connected into a compound SELECT, they group from left to right. In other words, if "A", "B" and "C" are all simple SELECT statements, (A op B op C) is processed as ((A op B) op C). +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-32575-52606-04029-38072-09330-12543-11814-27885
          +

          There can be an arbitrary number of sqlite_stat3 entries per index. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-32586-01296-10189-28566-58677-02270-23105-07978
          +

          SELECT statements may be optionally preceded by a single WITH clause that defines one or more common table expressions for use within the SELECT statement. +(source: lang_select.html, checked-by: th3/cov1/with01.test, matrix: context, detail)

          + +
          R-32633-52682-08562-36271-43194-24127-51342-52899
          +

          At least szOsFile bytes of memory are allocated by SQLite to hold the sqlite3_file structure passed as the third argument to xOpen. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-32667-09902-21409-45460-33680-48359-54103-12889
          +

          The built-in date and time functions of SQLite are a special case. These functions are usually considered deterministic. However, if these functions use the string "now" as the date, or if they use the localtime modifier or the utc modifier, then they are considered non-deterministic. +(source: deterministic.html, matrix: context, detail)

          + +
          R-32706-07403-21974-02831-34123-06843-55643-09070
          +

          No affinity transformations are applied to any values when comparing rows as part of a compound SELECT. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-32737-17936-16355-61809-23249-50193-59951-04545
          +

          Comments are not SQL commands, but can occur within the text of SQL queries passed to sqlite3_prepare_v2() and related interfaces. +(source: lang_comment.html, checked-by: th3/req1/comment01.test, matrix: context, detail)

          + +
          R-32768-47925-14881-49153-08372-50935-16619-06911
          +

          If an immediate foreign key constraint is violated, the DROP TABLE statement fails and the table is not dropped. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, th3/req1/foreignkeys22.test, matrix: context, detail)

          + +
          R-32806-65233-63423-39928-44686-28712-07931-12350
          +

          The fourth argument, pArg, is an application data pointer that is passed through as the first argument to the collating function callback. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-32809-14620-63808-12852-40065-57653-46928-34414
          +

          The parent key must be a named column or columns in the parent table, not the rowid. +(source: foreignkeys.html, checked-by: th3/req1/foreignkeys03.test, matrix: context, detail)

          + +
          R-32811-57727-45748-41236-27648-12493-19068-34622
          +

          When the WHERE clause and RETURNING clause are both omitted from a DELETE statement and the table being deleted has no triggers, SQLite uses an optimization to erase the entire table content without having to visit each row of the table individually. +(source: lang_delete.html, matrix: context, detail)

          + +
          R-32857-15826-08814-08217-40160-38064-19925-14488
          +

          Subsequent calls to sqlite3_get_auxdata(C,N) return P from the most recent sqlite3_set_auxdata(C,N,P,X) call if the metadata is still valid or NULL if the metadata has been discarded. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-32918-61474-62391-07743-12159-44767-00770-02393
          +

          Before entering a trigger program the value returned by sqlite3_changes() function is saved. After the trigger program has finished, the original value is restored. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-32925-06786-44484-40389-19544-51015-10010-30515
          +

          Each column name or expression can be followed by one of the "ASC" or "DESC" keywords to indicate sort order. +(source: lang_createindex.html, checked-by: th3/req1/createidx02.test, matrix: context, detail)

          + +
          R-33035-16498-10379-54790-22685-33042-10966-12535
          +

          If a memory allocation fails, then SQLITE_NOMEM is returned. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-33038-09382-52096-22256-12094-15064-07280-37767
          +

          If the second argument to SQLITE_DBCONFIG_LOOKASIDE is not a multiple of 8, it is internally rounded down to the next smaller multiple of 8. +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-33075-33190-25707-00729-29148-31049-04309-45993
          +

          If a keyword in single quotes (ex: 'key' or 'glob') is used in a context where an identifier is allowed but where a string literal is not allowed, then the token is understood to be an identifier instead of a string literal. +(source: lang_keywords.html, checked-by: th3/req1/keyword01.test, matrix: context, detail)

          + +
          R-33080-59193-42664-27310-42541-31106-33090-39782
          +

          Checkpoints initiated by this mechanism are PASSIVE. +(source: c3ref/wal_autocheckpoint.html, checked-by: tcl/e_walauto.test, matrix: context, detail)

          + +
          R-33113-07215-37933-59376-21317-00912-14100-16891
          +

          The iRowid field is the rowid (the first of the 3 to 11 columns in the R*Tree) for the element being considered. iRowid is only valid for leaves. +(source: rtree.html, matrix: context, detail)

          + +
          R-33124-58846-63098-57444-60113-38939-22033-09777
          +

          Note that when the right-hand side of a LIKE or GLOB operator is a parameter and the statement is prepared using sqlite3_prepare_v2() or sqlite3_prepare16_v2() then the statement is automatically reparsed and recompiled on the first sqlite3_step() call of each run if the binding to the right-hand side parameter has changed since the previous run. +(source: optoverview.html, matrix: context, detail)

          + +
          R-33140-21501-29804-63127-48240-59602-40241-17867
          +

          For the LIKE operator, if case_sensitive_like mode is enabled then the column must indexed using BINARY collating sequence, or if case_sensitive_like mode is disabled then the column must indexed using built-in NOCASE collating sequence. +(source: optoverview.html, checked-by: th3/cov1/where03.test, th3/cov1/where03b.test, matrix: context, detail)

          + +
          R-33142-02092-43419-10432-03484-54260-43121-37781
          +

          AUTOINCREMENT does not work on WITHOUT ROWID tables. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-33211-38833-64331-54724-35381-31821-05246-63257
          +

          These routines do not parse the SQL statements thus will not detect syntactically incorrect SQL. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-33257-44249-04384-28673-29527-48027-05174-23036
          +

          The update hook is not invoked when WITHOUT ROWID tables are modified. +(source: c3ref/update_hook.html, checked-by: tcl/hook.test, matrix: context, detail)

          + +
          R-33315-53384-19536-00039-42426-59902-48545-24529
          +

          Thus, the backup may be performed on a live source database without preventing other database connections from reading or writing to the source database while the backup is underway. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup01.test, matrix: context, detail)

          + +
          R-33316-19795-08370-35100-15159-39307-16097-56767
          +

          If the most recent call to sqlite3_step(S) for the prepared statement S indicated an error, then sqlite3_reset(S) returns an appropriate error code. +(source: c3ref/reset.html, checked-by: th3/th3util.c, matrix: context, detail)

          + +
          R-33326-45252-38720-14593-54555-59144-23018-05599
          +

          The ON DELETE and ON UPDATE action associated with each foreign key in an SQLite database is one of "NO ACTION", "RESTRICT", "SET NULL", "SET DEFAULT" or "CASCADE". +(source: foreignkeys.html, checked-by: src/parse.y, tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-33352-16228-19462-25047-13980-23357-27400-59118
          +

          When the EXPLAIN keyword appears by itself it causes the statement to behave as a query that returns the sequence of virtual machine instructions it would have used to execute the command had the EXPLAIN keyword not been present. +(source: lang_explain.html, checked-by: th3/cov1/vdbeaux01.test, matrix: context, detail)

          + +
          R-33368-33178-21159-57347-39405-35254-59100-49447
          +

          The first parameter, szPage, is the size in bytes of the pages that must be allocated by the cache. +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-33393-31741-20908-00667-39287-64680-56276-36828
          +

          Terms of the ORDER BY clause that is part of a SELECT statement may be assigned a collating sequence using the COLLATE operator, in which case the specified collating function is used for sorting. +(source: datatype3.html, checked-by: th3/req1/datatype3_10.test, matrix: context, detail)

          + +
          R-33401-06099-44102-08352-15092-58623-33401-34005
          +

          SQLITE_OPEN_READONLY The database is opened in read-only mode. If the database does not already exist, an error is returned. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-33414-20006-38430-38330-20007-08440-33108-23538
          +

          The SQLITE_UTF16 and SQLITE_UTF16_ALIGNED values for eTextRep force strings to be UTF16 with native byte order. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-33440-07331-05623-12245-41589-49905-51548-00120
          +

          For the purposes of the DEFAULT clause, an expression is considered constant if it contains no sub-queries, column or table references, bound parameters, or string literals enclosed in double-quotes instead of single-quotes. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-33443-64794-37777-63092-51102-53301-52354-10216
          +

          For non-TEMP triggers, the table to be modified or queried must exist in the same database as the table or view to which the trigger is attached. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-33490-49513-63336-09770-17828-12612-45403-52100
          +

          The third column is the number of pages in the write-ahead log file that have been successfully moved back into the database file at the conclusion of the checkpoint. +(source: pragma.html, matrix: context, detail)

          + +
          R-33496-49460-40885-47410-47365-30809-19419-02033
          +

          Module names must be registered before creating a new virtual table using the module and before using a preexisting virtual table for the module. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-33509-39458-36310-35502-14516-21374-43920-49454
          +

          A question mark followed by a number NNN holds a spot for the NNN-th parameter. NNN must be between 1 and SQLITE_MAX_VARIABLE_NUMBER. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-33528-20612-64279-03791-45165-25207-10127-32608
          +

          If no database is specified as part of the object reference, then SQLite searches the main, temp and all attached databases for an object with a matching name. The temp database is searched first, followed by the main database, followed all attached databases in the order that they were attached. The reference resolves to the first match found. +(source: lang_naming.html, checked-by: tcl/e_resolve.test, matrix: context, detail)

          + +
          R-33553-19363-35042-00573-64070-53843-36958-05658
          +

          The subquery does not use OFFSET. +(source: optoverview.html, matrix: context, detail)

          + +
          R-33570-18895-27619-21793-53436-58897-32599-21994
          +

          The following table summarizes the interaction of the SQLITE_TEMP_STORE preprocessor macro and the temp_store pragma: SQLITE_TEMP_STORE PRAGMAtemp_store Storage used forTEMP tables and indices 0 any file 1 0 file 1 1 file 1 2 memory 2 0 memory 2 1 file 2 2 memory 3 any memory +(source: pragma.html, matrix: context, detail)

          + +
          R-33599-53132-08850-48831-58699-38998-10150-06398
          +

          The sqlite_stat4.nEq column holds a list of N integers where the K-th integer is the approximate number of entries in the index whose left-most K columns exactly match the K left-most columns of the sample. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-33626-44500-44579-55445-20026-07899-19169-03498
          +

          There may be at most one unlock-notify callback registered by a blocked connection. If sqlite3_unlock_notify() is called when the blocked connection already has a registered unlock-notify callback, then the new callback replaces the old. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-33626-48418-46855-58211-38849-29467-54588-01790
          +

          In SQLite, if any of the child key columns (in this case songartist and songalbum) are NULL, then there is no requirement for a corresponding row in the parent table. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys11.test, matrix: context, detail)

          + +
          R-33670-36097-38044-00457-34720-22769-46022-27724
          +

          A question mark that is not followed by a number creates a parameter with a number one greater than the largest parameter number already assigned. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-33693-50180-37638-14993-01835-21324-19267-11438
          +

          The REGEXP operator is a special syntax for the regexp() user function. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-33696-20860-22256-33727-50165-31840-30518-14765
          +

          In a WITHOUT ROWID table, there is no sqlite_schema entry for the PRIMARY KEY, but the "sqlite_autoindex_TABLE_N" name is set aside for the PRIMARY KEY as if the sqlite_schema entry did exist. This will affect the numbering of subsequent UNIQUE constraints. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-33708-43819-48693-15112-15003-18731-38490-26979
          +

          The content allows the text being indexed to be stored in a separate table distinct from the FTS4 table, or even outside of SQLite. +(source: fts3.html, matrix: context, detail)

          + +
          R-33710-56344-23353-36559-53018-17291-08260-37097
          +

          In order to use foreign key constraints in SQLite, the library must be compiled with neither SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys05.test, matrix: context, detail)

          + +
          R-33724-43128-37475-21517-54367-56577-55269-13573
          +

          PRAGMA legacy_file_format; This pragma no longer functions. It has become a no-op. +(source: pragma.html, matrix: context, detail)

          + +
          R-33750-29536-47450-45123-25964-11560-21995-55948
          +

          Otherwise, the SELECT returns the first N rows of its result set only, where N is the value that the LIMIT expression evaluates to. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-33788-46243-41692-58767-41171-41314-21464-32804
          +

          In this case, the first expression is used as the OFFSET expression and the second as the LIMIT expression. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-33800-32193-29222-19847-14904-43461-36254-14018
          +

          If the required lock still cannot be obtained, then the database is skipped and an attempt made to flush any dirty pages belonging to the next (if any) database. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-33841-62945-13926-63288-41300-28246-26461-11874
          +

          Thus, for example, the data 2001-03-31 modified by '+1 month' initially yields 2001-04-31, but April only has 30 days so the date is normalized to 2001-05-01. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-33848-17975-36657-57635-49129-43335-29769-30640
          +

          PRAGMA schema.incremental_vacuum(N); PRAGMA schema.incremental_vacuum; The incremental_vacuum pragma causes up to N pages to be removed from the freelist. +(source: pragma.html, checked-by: th3/req1/pragma21.test, matrix: context, detail)

          + +
          R-33883-28833-60318-48575-53923-47015-06615-40154
          +

          Foreign key DDL errors are reported regardless of whether or not foreign key constraints are enabled when the table is created. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys08.test, matrix: context, detail)

          + +
          R-33917-24086-34361-61973-51178-03721-35954-00662
          +

          However, if the "IF NOT EXISTS" clause is specified as part of the CREATE TABLE statement and a table or view of the same name already exists, the CREATE TABLE command simply has no effect (and no error message is returned). +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-33948-22286-15597-10485-25275-41982-01072-17156
          +

          The algorithm specified in the OR clause of an INSERT or UPDATE overrides any algorithm specified in a CREATE TABLE. +(source: lang_conflict.html, checked-by: th3/req1/conflict04.test, matrix: context, detail)

          + +
          R-33950-57093-23380-64554-61801-30987-12746-10574
          +

          All indices and triggers associated with the table are also deleted. +(source: lang_droptable.html, checked-by: th3/req1/droptable01.test, matrix: context, detail)

          + +
          R-33977-57271-59293-02679-37541-34864-44396-22637
          +

          The left-most column is column 0 for these routines. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-33987-04842-11248-14802-44002-26437-03063-21132
          +

          These three options exist: 1) A destructor to dispose of the BLOB or string after SQLite has finished with it may be passed. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-33990-33527-11105-07702-18476-34779-54347-40484
          +

          When casting to INTEGER, if the text looks like a floating point value with an exponent, the exponent will be ignored because it is no part of the integer prefix. +(source: lang_expr.html, checked-by: tcl/cast.test, matrix: context, detail)

          + +
          R-34009-51042-01012-14502-52205-32655-22973-26621
          +

          If Y is negative then the first character of the substring is found by counting from the right rather than the left. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-34021-38482-31030-34652-01469-03047-61601-46080
          +

          The optimizer automatically inverts terms of the form "expr OP column" and makes other simplifications to the WHERE clause in an attempt to get as many WHERE clause terms into the form shown above as possible. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-34023-52929-12261-02515-22772-45177-48508-47679
          +

          The query string is optional. +(source: uri.html, matrix: context, detail)

          + +
          R-34027-00617-24854-21763-47858-39540-20896-63477
          +

          If the blob handle being closed was opened for read-write access, and if the database is in auto-commit mode and there are no other open read-write blob handles or active write statements, the current transaction is committed. +(source: c3ref/blob_close.html, checked-by: tcl/e_blobclose.test, matrix: context, detail)

          + +
          R-34068-60670-00760-36695-36282-03640-02435-26992
          +

          SQLITE_OPEN_PRIVATECACHE The database is opened shared cache disabled, overriding the default shared cache setting provided by sqlite3_enable_shared_cache(). +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-34076-18298-19777-37411-10938-20306-38293-17518
          +

          The RETURNING clause may not contain top-level aggregate functions or window functions. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-34109-39108-27898-16254-24563-58797-32171-17937
          +

          If the CHECK expression evaluates to NULL, or any other non-zero value, it is not a constraint violation. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-34146-30782-53907-40582-61923-47415-21722-12527
          +

          Column zColumn is part of an index, PRIMARY KEY or UNIQUE constraint and the blob is being opened for read/write access +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-34186-52914-35981-17820-54007-24600-55033-63809
          +

          The rank of the column within the index. (0 means left-most.) +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-34230-56049-07873-23044-54462-14755-43207-20479
          +

          SQLite automatically increments the schema-version whenever the schema changes. +(source: pragma.html, checked-by: src/build.c, th3/req1/pragma28.test, matrix: context, detail)

          + +
          R-34234-52126-13891-36855-21265-08475-46071-60317
          +

          The default mode is for LIKE comparisons to be insensitive to differences of case for latin1 characters. +(source: optoverview.html, checked-by: th3/cov1/pragma02.test, th3/cov1/where03.test, th3/cov1/where03b.test, matrix: context, detail)

          + +
          R-34264-15842-51908-27355-58812-13180-15279-38051
          +

          The legacy_file_format pragma can be used to cause SQLite to create new database files using format 1. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-34271-33106-55360-31605-05941-37144-32278-15012
          +

          PRAGMA automatic_index; PRAGMA automatic_index = boolean; Query, set, or clear the automatic indexing capability. +(source: pragma.html, checked-by: tcl/autoindex1.test, th3/req1/pragma08.test, matrix: context, detail)

          + +
          R-34280-42283-63975-25394-58653-47378-35851-53437
          +

          The count(X) function returns a count of the number of times that X is not NULL in a group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-34293-31480-01160-31597-61187-16604-15204-31151
          +

          The sqlite3_extended_errcode() interface is the same except that it always returns the extended result code even when extended result codes are disabled. +(source: c3ref/errcode.html, matrix: context, detail)

          + +
          R-34314-06007-23852-03493-52380-57466-48633-09703
          +

          The sqlite3_sql(P) interface returns a pointer to a copy of the UTF-8 SQL text used to create prepared statement P if P was created by sqlite3_prepare_v2(), sqlite3_prepare_v3(), sqlite3_prepare16_v2(), or sqlite3_prepare16_v3(). +(source: c3ref/expanded_sql.html, checked-by: th3/req1/sql01.test, th3/th3util.c, matrix: context, detail)

          + +
          R-34326-56357-56903-53526-53046-15549-19745-22986
          +

          The sqlite3_result_error_code() function changes the error code returned by SQLite as a result of an error in a function. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-34354-51417-57740-57504-01542-51579-51443-23369
          +

          If the callback pointer to sqlite3_exec() is NULL, then no callback is ever invoked and result rows are ignored. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-34391-24921-52036-19820-43252-56353-24608-07545
          +

          The sqlite3_release_memory() routine is a no-op returning zero if SQLite is not compiled with SQLITE_ENABLE_MEMORY_MANAGEMENT. +(source: c3ref/release_memory.html, checked-by: src/malloc.c, th3/req1/releasemem01.test, matrix: context, detail)

          + +
          R-34400-33772-12568-07085-14602-53889-15876-12187
          +

          Any leading spaces in the TEXT value when converting from TEXT to INTEGER are ignored. +(source: lang_expr.html, checked-by: tcl/e_expr.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-34407-33329-56662-13063-42233-50984-46328-08443
          +

          The sqlite3_vsnprintf() routine is a varargs version of sqlite3_snprintf(). +(source: c3ref/mprintf.html, checked-by: th3/req1/malloc01.test, matrix: context, detail)

          + +
          R-34456-00884-53550-63882-43324-33974-40030-43057
          +

          The first form of this pragma queries the current journaling mode for database. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-34457-09668-37447-61343-26020-24066-28137-60426
          +

          "1" if the index is a partial index and "0" if not. +(source: pragma.html, checked-by: tcl/index7.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-34467-36570-51008-00703-20331-24944-30267-61623
          +

          When the destructor callback is invoked, it is passed a single argument which is a copy of the application data pointer which was the fifth parameter to sqlite3_create_function_v2(). +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc07.test, matrix: context, detail)

          + +
          R-34472-09915-38123-43434-43436-60925-14387-37410
          +

          Note that if a non-deterministic function is tagged with SQLITE_DETERMINISTIC and if that function ends up being used in the WHERE clause of a partial index or in an expression index, then when the function begins to return different answers, the associated index may become corrupt. +(source: deterministic.html, matrix: context, detail)

          + +
          R-34481-43669-25977-57618-65082-36703-04463-10475
          +

          The NOCASE collation is like BINARY except that uppercase ASCII characters ('A' through 'Z') are folded into their lowercase equivalents prior to running the comparison. Only ASCII characters are case-folded. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-34489-53953-36029-13063-60538-08284-18396-26034
          +

          Nine static mutexes are used by the current version of SQLite. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-34494-34867-10904-51436-14050-30444-55567-08867
          +

          That ORDER BY clause will apply across all elements of the compound. +(source: lang_select.html, checked-by: th3/req1/select02.test, matrix: context, detail)

          + +
          R-34519-06271-04461-63947-59293-07505-45589-19404
          +

          SQLITE_BUSY is returned in this case. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-34526-35712-49832-15543-35160-30600-56964-59649
          +

          By default, the error code is SQLITE_ERROR. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-34561-00264-36299-40120-12079-02627-14730-26524
          +

          If an authorizer callback returns SQLITE_IGNORE for an SQLITE_DELETE action code, then the DELETE operation will proceed but the truncate optimization will be bypassed and rows will be deleted one by one. +(source: lang_delete.html, matrix: context, detail)

          + +
          R-34616-57962-62200-63763-25892-01209-38424-05918
          +

          Cache sharing is enabled and disabled for an entire process. +(source: c3ref/enable_shared_cache.html, matrix: context, detail)

          + +
          R-34648-44875-03220-54825-01081-20056-64407-58283
          +

          Or, if the SELECT would return less than M+N rows if it did not have a LIMIT clause, then the first M rows are skipped and the remaining rows (if any) are returned. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-34657-61226-12617-43692-19153-03581-17665-29840
          +

          The "PRAGMA cache_spill=N" form of this pragma sets a minimum cache size threshold required for spilling to occur. +(source: pragma.html, checked-by: tcl/pragma2.test, matrix: context, detail)

          + +
          R-34696-31731-45418-63028-04604-07803-00716-15058
          +

          When a prepared statement runs, it first checks the schema cookie to ensure the value is the same as when the statement was prepared and if the schema cookie has changed, the statement either automatically reprepares and reruns or it aborts with an SQLITE_SCHEMA error. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-34706-05629-19212-06603-14274-22035-31068-37221
          +

          The open attempt fails if NAME is not the name of a VFS that is built into SQLite or that has been previously registered using sqlite3_vfs_register(). +(source: uri.html, matrix: context, detail)

          + +
          R-34730-53445-15838-11944-46041-12438-53750-14468
          +

          The case_sensitive_like pragma installs a new application-defined LIKE function that is either case sensitive or insensitive depending on the value of the case_sensitive_like pragma. +(source: pragma.html, checked-by: th3/req1/pragma10.test, matrix: context, detail)

          + +
          R-34745-08839-34242-42308-04034-17314-18313-24494
          +

          If the xDelUser variable is set to a non-NULL value, then after the query has finished running SQLite automatically invokes it with the value of the pUser variable as the only argument. +(source: rtree.html, matrix: context, detail)

          + +
          R-34751-04246-20772-53163-23654-34620-17677-07511
          +

          So, in the example above, if the query were rewritten as: SELECT z FROM ex2 WHERE +x=5 AND y=6; The + operator on the x column will prevent that term from constraining an index. This would force the use of the ex2i2 index. +(source: optoverview.html, matrix: context, detail)

          + +
          R-34751-18293-04541-58685-13120-57905-41689-08740
          +

          If a single column-name appears more than once in the list of assignment expressions, all but the rightmost occurrence is ignored. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-34773-62253-14389-56183-06695-27653-47306-47953
          +

          The only difference between the following two CASE expressions is that the x expression is evaluated exactly once in the first example but might be evaluated multiple times in the second: CASE x WHEN w1 THEN r1 WHEN w2 THEN r2 ELSE r3 END CASE WHEN x=w1 THEN r1 WHEN x=w2 THEN r2 ELSE r3 END +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-34782-18311-17741-53218-12879-22753-50681-05507
          +

          Unless SQLITE_MISUSE is returned, this function sets the database connection error code and message accessible via sqlite3_errcode() and sqlite3_errmsg() and related functions. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-34789-59934-28389-39071-40559-33528-38029-45906
          +

          The DESC keyword is ignored in indexes for formats 1, 2, and 3. +(source: fileformat2.html, checked-by: th3/req1/fileformat01.test, matrix: context, detail)

          + +
          R-34809-04839-09181-10394-33851-21757-50200-61577
          +

          Let X be U-35. If the payload size P is less than or equal to X then the entire payload is stored on the b-tree leaf page. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-34814-22035-19752-61012-44426-48112-33201-20182
          +

          Values stored in sqlite3_value objects can be integers, floating point values, strings, BLOBs, or NULL. +(source: c3ref/value.html, checked-by: th3/req1/value01.test, matrix: context, detail)

          + +
          R-34816-32505-14191-41651-46944-10844-62255-46096
          +

          The xCreate and xConnect methods of a virtual table module call this interface to declare the format (the names and datatypes of the columns) of the virtual tables they implement. +(source: c3ref/declare_vtab.html, checked-by: th3/req1/vtab01.test, matrix: context, detail)

          + +
          R-34818-13664-64271-58157-25090-18668-59799-37546
          +

          The 'now' argument to date and time functions always returns exactly the same value for multiple invocations within the same sqlite3_step() call. +(source: lang_datefunc.html, checked-by: tcl/date.test, th3/cov1/date4.test, matrix: context, detail)

          + +
          R-34837-12462-62420-33748-07267-00170-63881-53119
          +

          The first argument to the callback is a copy of the third argument to sqlite3_update_hook(). +(source: c3ref/update_hook.html, checked-by: th3/cov1/main15.test, matrix: context, detail)

          + +
          R-34918-27009-22149-14301-56506-15307-06517-16770
          +

          The INDEXED BY and NOT INDEXED clauses are not supported for UPDATE and DELETE statements. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-34926-03360-27843-47752-48355-13649-05844-37285
          +

          SQLITE_CONFIG_WIN32_HEAPSIZE takes a 32-bit unsigned integer value that specifies the maximum size of the created heap. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-34933-01612-63826-59975-42480-58884-65014-06327
          +

          The names returned are the original un-aliased names of the database, table, and column. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-34937-45675-11260-35059-56178-30979-30227-02001
          +

          The sole argument is a pointer to a constant UTF8 string which will become the new schema name in place of "main". +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/cov1/maindbname01.test, matrix: context, detail)

          + +
          R-34963-21048-59232-16607-21091-43824-49294-11066
          +

          If the sqlite_sequence.seq field of an AUTOINCREMENT table is already at the largest integer value (9223372036854775807) then attempts to add new rows to that table with an automatically generated integer primary will fail with an SQLITE_FULL error. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-34979-54336-33279-53576-25867-30233-28350-04331
          +

          If the main database is ":memory:" or if the journal_mode is WAL, then transactions continue to be atomic within each individual database file. But if the host computer crashes in the middle of a COMMIT where two or more database files are updated, some of those files might get the changes where others might not. +(source: lang_attach.html, checked-by: th3/req1/attach02.test, matrix: context, detail)

          + +
          R-34993-45031-36632-60048-51944-50307-62063-53207
          +

          The maximum allowed mmap size will be silently truncated if necessary so that it does not exceed the compile-time maximum mmap size set by the SQLITE_MAX_MMAP_SIZE compile-time option. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-34998-49915-07664-55575-37059-29902-40579-47714
          +

          If the result is a UTF-8 string, then sqlite3_column_bytes16() converts the string to UTF-16 and then returns the number of bytes. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-35002-09502-01413-09334-58784-32407-44903-62982
          +

          If the threading mode is Single-thread or Multi-thread then this routine returns a NULL pointer. +(source: c3ref/db_mutex.html, checked-by: th3/req1/dbmutex01.test, matrix: context, detail)

          + +
          R-35003-32738-64790-42236-58307-21158-57428-12443
          +

          If X is numeric then length(X) returns the length of a string representation of X. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-35033-20570-55146-33091-43588-36289-00669-04528
          +

          The subquery on the right of an IN or NOT IN operator must be a scalar subquery if the left expression is not a row value expression. +(source: lang_expr.html, matrix: context, detail)

          + +
          R-35036-33960-30076-49697-10834-60924-14728-15122
          +

          The sixth, seventh and eighth parameters passed to the three "sqlite3_create_function*" functions, xFunc, xStep and xFinal, are pointers to C-language functions that implement the SQL function or aggregate. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc03.test, matrix: context, detail)

          + +
          R-35036-36587-25670-53930-46391-17517-28623-46452
          +

          For a WITHOUT ROWID table, N will be the number of columns in the primary key. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-35088-43392-22185-31834-16686-27011-41097-22750
          +

          Shared-cache locks are released when a database connection concludes its current transaction, either by committing it or rolling it back. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-35092-12727-62894-63814-26795-55319-59085-22626
          +

          The pointers returned are valid until a type conversion occurs as described above, or until sqlite3_step() or sqlite3_reset() or sqlite3_finalize() is called. +(source: c3ref/column_blob.html, checked-by: th3/req1/column03.test, matrix: context, detail)

          + +
          R-35105-34724-05666-13344-17136-11047-06163-46281
          +

          If pMem is NULL and N is non-zero, then each database connection does an initial bulk allocation for page cache memory from sqlite3_malloc() sufficient for N cache lines if N is positive or of -1024*N bytes if N is negative, . +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-35109-49139-58862-12127-06342-61829-38093-58472
          +

          The number of columns in each row returned by the SELECT statement (if any) and the specific values returned have no effect on the results of the EXISTS operator. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-35111-05628-59609-35925-11859-38596-24754-51119
          +

          If an error occurs while committing the transaction, an error code is returned and the transaction rolled back. +(source: c3ref/blob_close.html, checked-by: tcl/e_blobclose.test, matrix: context, detail)

          + +
          R-35113-43214-56626-24487-53216-55188-49391-33418
          +

          Unless the column is an INTEGER PRIMARY KEY or the table is a WITHOUT ROWID table or the column is declared NOT NULL, SQLite allows NULL values in a PRIMARY KEY column. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-35129-58141-36157-07998-30656-14308-25733-01656
          +

          For example: -- Database schema CREATE TABLE parent(x PRIMARY KEY); CREATE TABLE child(y REFERENCES parent ON UPDATE SET NULL); sqlite> SELECT * FROM parent; x ---- key sqlite> SELECT * FROM child; y ---- key sqlite> -- Since the following UPDATE statement does not actually modify sqlite> -- the parent key value, the ON UPDATE action is not performed and sqlite> -- the child key value is not set to NULL. sqlite> UPDATE parent SET x = 'key'; sqlite> SELECT IFNULL(y, 'null') FROM child; y ---- key sqlite> -- This time, since the UPDATE statement does modify the parent key sqlite> -- value, the ON UPDATE action is performed and the child key is set sqlite> -- to NULL. sqlite> UPDATE parent SET x = 'key2'; sqlite> SELECT IFNULL(y, 'null') FROM child; y ---- null +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys20.test, matrix: context, detail)

          + +
          R-35187-29937-54093-33401-20341-46072-51751-40097
          +

          Unless the flattening optimization is applied, if a subquery appears in the FROM clause of a SELECT statement, SQLite can either run the subquery and stores the results in a temporary table, or it can run the subquery as a co-routine. The following query is an example of the latter. The subquery is run by a co-routine. The outer query blocks whenever it needs another row of input from the subquery. Control switches to the co-routine which produces the desired output row, then control switches back to the main routine which continues processing. sqlite> EXPLAIN QUERY PLAN SELECT count(*) FROM (SELECT max(b) AS x FROM t1 GROUP BY a) GROUP BY x; QUERY PLAN |--CO-ROUTINE 0x20FC3E0 | `--SCAN TABLE t1 USING COVERING INDEX i2 |--SCAN SUBQUERY 0x20FC3E0 `--USE TEMP B-TREE FOR GROUP BY +(source: eqp.html, matrix: context, detail)

          + +
          R-35196-57110-30977-27033-46331-62759-56891-62679
          +

          There is a single row in the sqlite_sequence table for each ordinary table that uses AUTOINCREMENT. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-35210-63508-42678-48683-05229-58965-46588-04293
          +

          The sqlite3_libversion_number() function returns an integer equal to SQLITE_VERSION_NUMBER. +(source: c3ref/libversion.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-35214-06564-22940-62614-38557-57045-54055-01727
          +

          Format 4 also adds two new boolean record type values (serial types 8 and 9). +(source: fileformat2.html, checked-by: th3/req1/fileformat01.test, matrix: context, detail)

          + +
          R-35224-32827-55933-44478-17553-06933-55583-57822
          +

          The table named in the table_info pragma can also be a view. +(source: pragma.html, matrix: context, detail)

          + +
          R-35229-17830-32159-37744-59002-46141-27438-26089
          +

          A string constant is formed by enclosing the string in single quotes ('). +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-35254-48865-63817-52724-57944-24327-24630-05485
          +

          A call to one of the above APIs creates a new SQL function named by the second parameter (zQueryFunc or zGeom). +(source: rtree.html, matrix: context, detail)

          + +
          R-35268-31914-29013-65007-60500-40286-59986-01540
          +

          The value returned by sqlite3_memory_highwater(1) is the high-water mark prior to the reset. +(source: c3ref/memory_highwater.html, matrix: context, detail)

          + +
          R-35272-30329-38196-23593-15037-30954-61861-19508
          +

          Columns in the result set include the column name, data type, whether or not the column can be NULL, and the default value for the column. +(source: pragma.html, checked-by: th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-35290-16460-32571-10958-08768-45451-01146-58774
          +

          Foreign key constraints are immediate by default. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, matrix: context, detail)

          + +
          R-35311-10820-21037-47746-53186-51250-62481-54055
          +

          When the locking_mode pragma specifies a particular database, for example: PRAGMA main.locking_mode=EXCLUSIVE; Then the locking mode applies only to the named database. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-35325-25517-01545-24178-13996-21143-53189-45296
          +

          An uncorrelated subquery is evaluated only once and the result reused as necessary. +(source: lang_expr.html, checked-by: th3/req1/select01.test, matrix: context, detail)

          + +
          R-35340-24525-47723-05351-53509-38292-37828-03543
          +

          The sqlite3_aggregate_context(C,N) routine returns a NULL pointer when first called if N is less than or equal to zero or if a memory allocate error occurs. +(source: c3ref/aggregate_context.html, checked-by: th3/req1/aggcntx01.test, matrix: context, detail)

          + +
          R-35362-38850-39624-46125-42742-24667-28362-39621
          +

          The BEFORE or AFTER keyword determines when the trigger actions will be executed relative to the insertion, modification or removal of the associated row. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-35371-58843-38332-21753-13618-41551-34238-06657
          +

          The ATTACH DATABASE statement adds another database file to the current database connection. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-35443-03595-46720-21224-13105-18323-15585-18563
          +

          Ifnull() must have exactly 2 arguments. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-35454-31058-05961-25112-64343-26549-00069-20498
          +

          If P>X and K>X then the first M bytes of P are stored on the btree page and the remaining P-M bytes are stored on overflow pages. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-35460-03740-02108-04893-51916-60089-58945-40785
          +

          Registering a NULL function disables the callback. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-35496-03635-05800-19681-11567-09775-48933-50480
          +

          The name of the index. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-35503-60218-20246-16465-03448-36808-43658-06556
          +

          When SQLite compares two strings, it uses a collating sequence or collating function (two words for the same thing) to determine which string is greater or if the two strings are equal. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-35553-21226-59052-33659-22709-48132-34010-52118
          +

          The upper(X) function returns a copy of input string X in which all lower-case ASCII characters are converted to their upper-case equivalent. +(source: lang_corefunc.html, checked-by: th3/cov1/func04.test, matrix: context, detail)

          + +
          R-35592-43376-11648-07628-49784-57585-43144-43201
          +

          If pragma integrity_check finds no errors, a single row with the value 'ok' is returned. +(source: pragma.html, checked-by: th3/req1/integrityck01.test, matrix: context, detail)

          + +
          R-35640-30414-24972-23354-27947-42421-53546-27717
          +

          The sqlite3_value_dup(V) interface returns NULL if V is NULL or if a memory allocation fails. +(source: c3ref/value_dup.html, matrix: context, detail)

          + +
          R-35668-58241-09537-53108-57582-24768-01452-25578
          +

          The phrase "VALUES(expr-list)" means the same thing as "SELECT expr-list". +(source: lang_select.html, checked-by: th3/cov1/select30.test, th3/req1/select02.test, matrix: context, detail)

          + +
          R-35698-25375-34264-35367-42002-17994-39861-33131
          +

          C-style comments begin with "/*" and extend up to and including the next "*/" character pair or until the end of input, whichever comes first. +(source: lang_comment.html, checked-by: th3/req1/comment01.test, matrix: context, detail)

          + +
          R-35711-48727-49492-05161-09107-16114-44571-60110
          +

          If N or iOffset is less than zero, SQLITE_ERROR is returned and no data is read. +(source: c3ref/blob_read.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-35739-57436-25800-46947-32358-09819-57778-06393
          +

          The sqlite3_errmsg() or sqlite3_errmsg16() routines can be used to obtain an English language description of the error following a failure of any of the sqlite3_open() routines. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-35763-48267-24179-20441-32559-50420-39179-45580
          +

          Foreign key DML errors are reported if: The parent table does not exist, or The parent key columns named in the foreign key constraint do not exist, or The parent key columns named in the foreign key constraint are not the primary key of the parent table and are not subject to a unique constraint using collating sequence specified in the CREATE TABLE, or The child table references the primary key of the parent without specifying the primary key columns and the number of primary key columns in the parent do not match the number of child key columns. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-35764-01730-42752-16574-48638-21892-06176-19887
          +

          The user_version pragma will to get or set the value of the user-version integer at offset 60 in the database header. +(source: pragma.html, checked-by: th3/req1/pragma28.test, matrix: context, detail)

          + +
          R-35765-61623-59690-19582-04854-45693-22489-08520
          +

          Only a single progress handler may be defined at one time per database connection; setting a new progress handler cancels the old one. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-35802-14059-47020-23527-06222-22948-08783-35470
          +

          Nor is the update hook invoked when rows are deleted using the truncate optimization. +(source: c3ref/update_hook.html, checked-by: th3/cov1/main15.test, matrix: context, detail)

          + +
          R-35812-46755-23531-40873-62145-48640-15024-41940
          +

          The default journal size limit is -1 (no limit). +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-35835-22506-43266-17385-20539-20628-59606-19981
          +

          NOCASE - Similar to binary, except that it uses sqlite3_strnicmp() for the comparison. Hence the 26 upper case characters of ASCII are folded to their lower case equivalents before the comparison is performed. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-35840-33204-13129-04501-28754-46758-55672-28059
          +

          If URI filename interpretation is enabled, and the filename argument begins with "file:", then the filename is interpreted as a URI. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-35856-58769-58714-05667-00872-44195-43278-26599
          +

          However if an ON CONFLICT clause is specified as part of the statement causing the trigger to fire, then conflict handling policy of the outer statement is used instead. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-35865-29619-35015-08784-17694-42068-56782-50747
          +

          This interface is used to retrieve runtime status information about a single database connection. +(source: c3ref/db_status.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-35880-12325-57817-26418-36971-18732-46777-12474
          +

          For the index above and WHERE clause like this: ... WHERE b IN (1,2,3) AND c NOT NULL AND d='hello' The index is not usable at all because the left-most column of the index (column "a") is not constrained. +(source: optoverview.html, matrix: context, detail)

          + +
          R-35892-30289-55875-11491-60713-08800-59610-09295
          +

          For a command of the form "REINDEX name", a match against collation-name takes precedence over a match against index-name or table-name. +(source: lang_reindex.html, checked-by: tcl/e_reindex.test, matrix: context, detail)

          + +
          R-35903-55864-38042-65190-02899-64342-40234-23933
          +

          The P argument is a pointer to the prepared statement. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-35921-30782-30597-38751-45197-16333-41298-65365
          +

          If SQLite has not been initialized using sqlite3_initialize() prior to invoking sqlite3_complete16() then sqlite3_initialize() is invoked automatically by sqlite3_complete16(). If that initialization fails, then the return value from sqlite3_complete16() will be non-zero regardless of whether or not the input SQL is complete. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-35945-11759-33348-59186-12007-55771-30323-25128
          +

          The sqlite3_mutex_alloc() routine returns NULL if it is unable to allocate the requested mutex. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-35968-60209-16507-36689-50525-63369-04471-36400
          +

          By default, application-defined SQL functions are considered to be non-deterministic. +(source: deterministic.html, matrix: context, detail)

          + +
          R-36007-42565-41988-28835-07682-45738-21986-28193
          +

          The sqlite3_realloc64(X,N) interfaces works the same as sqlite3_realloc(X,N) except that N is a 64-bit unsigned integer instead of a 32-bit signed integer. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-36018-21755-34988-08386-62029-36954-65009-29361
          +

          The parent key definitions of foreign key constraints are not checked when a table is created. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys21.test, matrix: context, detail)

          + +
          R-36043-10590-35190-29655-36320-51519-10161-16668
          +

          Changes made as part of foreign key actions are included in the count, but those made as part of REPLACE constraint resolution are not. +(source: c3ref/total_changes.html, checked-by: tcl/e_totalchanges.test, matrix: context, detail)

          + +
          R-36097-50928-12790-61017-20060-26535-57569-32056
          +

          SQLite implements this interface by calling the xSleep() method of the default sqlite3_vfs object. +(source: c3ref/sleep.html, checked-by: th3/req1/sleep01.test, matrix: context, detail)

          + +
          R-36103-43483-56354-57798-31615-25926-09784-32512
          +

          The sqlite_stat3.nLt holds the approximate number of entries in the index whose left-most column is less than the sample. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-36147-61857-54581-58200-55810-07092-59837-08687
          +

          The second parameter to the preupdate callback is a pointer to the database connection that registered the preupdate hook. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-36185-29671-26091-33323-34163-48928-21638-35689
          +

          If the column-name list is omitted, then the names of the columns in the view are derived from the names of the result-set columns in the select-stmt. +(source: lang_createview.html, matrix: context, detail)

          + +
          R-36190-27688-09198-02833-32879-47498-11674-13730
          +

          PRAGMA schema.page_size; PRAGMA schema.page_size = bytes; Query or set the page size of the database. +(source: pragma.html, matrix: context, detail)

          + +
          R-36195-31555-35544-12860-62754-30693-28143-39954
          +

          The usual INSERT, UPDATE, and DELETE commands work on an R*Tree index just like on regular tables. +(source: rtree.html, matrix: context, detail)

          + +
          R-36231-30731-18114-11584-03409-00455-24711-59821
          +

          The COLLATE operator has a higher precedence (binds more tightly) than any binary operator and any unary prefix operator except "~". +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-36239-04077-08470-54931-40517-19628-02448-15955
          +

          The scalar expressions may refer to columns of the row being updated. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-36257-52125-15338-28227-38982-51329-51201-58164
          +

          SQLite does not make a copy of the new main schema name string, so the application must ensure that the argument passed into this DBCONFIG option is unchanged until after the database connection closes. +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, th3/cov1/maindbname01.test, matrix: context, detail)

          + +
          R-36327-17224-30714-13238-62239-10610-34314-51642
          +

          If a result expression is the special expression "*" then all columns in the input data are substituted for that one expression. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-36328-16367-14145-21377-30808-40796-28392-26990
          +

          In that case, the database connection remains in EXCLUSIVE mode as long as the journal mode is WAL; attempts to change the locking mode using "PRAGMA locking_mode=NORMAL;" are no-ops. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-36338-64112-59318-08203-11484-65439-59164-45202
          +

          If one or more ON INSERT, ON DELETE or ON UPDATE triggers are defined on a view, then it is not an error to execute an INSERT, DELETE or UPDATE statement on the view, respectively. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-36357-08369-42604-06511-16723-17506-10955-34539
          +

          If the WHERE clause expression evaluates to NULL or to false for some rows of the table, then those rows are omitted from the index. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-36394-12461-27768-64371-31765-36302-25885-56308
          +

          SQLite will always use the table b-tree key rather than the NULL value when referencing the INTEGER PRIMARY KEY column. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-36399-45840-38419-49366-05932-18953-07682-47549
          +

          SQLITE_STATUS_PAGECACHE_USED This parameter returns the number of pages used out of the pagecache memory allocator that was configured using SQLITE_CONFIG_PAGECACHE. The value returned is in pages, not in bytes. +(source: c3ref/c_status_malloc_count.html, matrix: context, detail)

          + +
          R-36476-47203-56638-47160-44339-35126-05623-44628
          +

          A string might look like a floating-point literal with a decimal point and/or exponent notation but as long as the value can be expressed as an integer, the NUMERIC affinity will convert it into an integer. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-36522-24811-64811-56384-05057-49516-54548-20894
          +

          If the database connection is associated with unfinalized prepared statements, BLOB handlers, and/or unfinished sqlite3_backup objects then sqlite3_close() will leave the database connection open and return SQLITE_BUSY. +(source: c3ref/close.html, checked-by: th3/cov1/main23.test, matrix: context, detail)

          + +
          R-36545-62345-61603-06376-33533-12580-59655-26356
          +

          The value returned by sqlite3_backup_finish is SQLITE_OK if no sqlite3_backup_step() errors occurred, regardless or whether or not sqlite3_backup_step() completed. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-36570-50350-22690-62620-40069-12741-59912-39682
          +

          Transactions can be started manually using the BEGIN command. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-36592-02772-49597-21134-35176-13314-34028-16274
          +

          The SQLITE_CONFIG_COVERING_INDEX_SCAN option takes a single integer argument which is interpreted as a boolean in order to enable or disable the use of covering indices for full table scans in the query optimizer. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-36596-35603-05344-10987-20238-56026-42130-18053
          +

          The sqlite3_last_insert_rowid(D) interface usually returns the rowid of the most recent successful INSERT into a rowid table or virtual table on database connection D. +(source: c3ref/last_insert_rowid.html, matrix: context, detail)

          + +
          R-36598-60500-12425-47640-29499-27621-13512-27511
          +

          Attached databases can be vacuumed by appending the appropriate schema-name to the VACUUM statement. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-36602-21087-51192-25883-57410-35458-57650-49197
          +

          The column is named in the WHERE clause of a partial index. +(source: lang_altertable.html, checked-by: th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-36608-10930-24220-22579-46351-14737-62834-54918
          +

          The arguments can be just about any text as long as it has balanced parentheses. +(source: lang_createvtab.html, matrix: context, detail)

          + +
          R-36609-39554-02465-47159-11232-33677-21086-13785
          +

          "c" if the index was created by a CREATE INDEX statement, "u" if the index was created by a UNIQUE constraint, or "pk" if the index was created by a PRIMARY KEY constraint. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-36610-45292-54097-28024-65527-46641-42678-27744
          +

          The sqlite3_snprintf() routine is similar to "snprintf()" from the standard C library. The result is written into the buffer supplied as the second parameter whose size is given by the first parameter. Note that the order of the first two parameters is reversed from snprintf(). +(source: c3ref/mprintf.html, checked-by: th3/req1/malloc01.test, matrix: context, detail)

          + +
          R-36612-64789-14111-46629-37131-49911-14128-04823
          +

          But the next query can not use the partial index: SELECT * FROM tab2 WHERE b=456; -- cannot use partial index +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-36620-34941-18970-44416-30193-42757-18271-60128
          +

          The secure-delete setting for newly attached databases is the setting of the main database at the time the ATTACH command is evaluated. +(source: pragma.html, checked-by: th3/cov1/pragma20.test, th3/cov1/pragma21.test, matrix: context, detail)

          + +
          R-36651-49821-06866-46556-29729-37304-36967-33618
          +

          Note that the name length limit is in UTF-8 bytes, not characters nor UTF-16 bytes. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, matrix: context, detail)

          + +
          R-36706-10507-15107-19022-47834-34931-59903-48809
          +

          The PRAGMA wal_checkpoint command can be used to invoke this interface from SQL. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-36754-20545-04159-27572-44208-64137-08044-49180
          +

          Strings with embedded NUL characters cannot be represented as string literals in SQL and hence the returned string literal is truncated prior to the first NUL. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-36765-11966-40319-64990-44757-09945-39108-37525
          +

          If the sqlite_stat1.idx column is the same as the sqlite_stat1.tbl column, then the table is a WITHOUT ROWID table and the sqlite_stat1.stat field contains information about the index btree that implements the WITHOUT ROWID table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-36787-21388-40333-56236-13841-04160-18258-18988
          +

          If the STRING or BLOB looks like a real number (if it has a decimal point or an exponent) or if the value is outside the range that can be represented as a 64-bit signed integer, then it converts to REAL. Otherwise the operand converts to INTEGER. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-36822-49898-51267-28801-22242-39926-43860-26511
          +

          In many pragmas, the argument is a boolean. The boolean can be one of: 1 yes true on0 no false off +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-36834-48950-59089-31267-28729-41659-26952-44127
          +

          On the other hand, the virtual terms themselves never causes tests to be performed on input rows. +(source: optoverview.html, matrix: context, detail)

          + +
          R-36850-34127-02357-30625-11793-50017-46803-57751
          +

          The likely(X) function is short-hand for likelihood(X,0.9375). +(source: lang_corefunc.html, checked-by: src/resolve.c, matrix: context, detail)

          + +
          R-36859-05333-15357-38800-46653-01342-64657-49103
          +

          SQLite guarantees that the zFilename parameter to xOpen is either a NULL pointer or string obtained from xFullPathname() with an optional suffix added. +(source: c3ref/vfs.html, checked-by: th3/cov1/pager25.test, th3/th3testvfs.c, matrix: context, detail)

          + +
          R-36882-08642-64574-34445-28855-37148-23559-38229
          +

          The sqlite3_hard_heap_limit64(N) interface is similar to sqlite3_soft_heap_limit64(N) except that memory allocations will fail when the hard heap limit is reached. +(source: c3ref/hard_heap_limit64.html, matrix: context, detail)

          + +
          R-36924-43758-45428-63164-00988-45045-48041-44762
          +

          By default, every row in SQLite has a special column, usually called the "rowid", that uniquely identifies that row within the table. +(source: withoutrowid.html, checked-by: tcl/rowid.test, tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-36947-39582-19332-41522-37066-30341-40007-20770
          +

          A WITHOUT ROWID table uses an index b-tree rather than a table b-tree for storage. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-36961-63052-16205-51009-18443-35672-28780-03927
          +

          The sqlite3_stmt_readonly() interface returns true for BEGIN since BEGIN merely sets internal flags, but the BEGIN IMMEDIATE and BEGIN EXCLUSIVE commands do touch the database and so sqlite3_stmt_readonly() returns false for those commands. +(source: c3ref/stmt_readonly.html, checked-by: th3/cov1/vdbeapi14.test, matrix: context, detail)

          + +
          R-37002-28871-53113-54694-45983-06407-17129-31700
          +

          The "NOT INDEXED" clause specifies that no index shall be used when accessing the preceding table, including implied indices create by UNIQUE and PRIMARY KEY constraints. However, the rowid can still be used to look up entries even when "NOT INDEXED" is specified. +(source: lang_indexedby.html, checked-by: tcl/indexedby.test, matrix: context, detail)

          + +
          R-37002-32774-01005-00409-47681-36421-50128-30923
          +

          The two-byte integer at offset 3 gives the number of cells on the page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-37014-01401-21089-17070-29691-04562-53032-12534
          +

          The ATTACH and DETACH statements also cause sqlite3_stmt_readonly() to return true since, while those statements change the configuration of a database connection, they do not make changes to the content of the database files on disk. +(source: c3ref/stmt_readonly.html, checked-by: th3/cov1/vdbeapi14.test, matrix: context, detail)

          + +
          R-37019-57602-33488-54627-46176-35899-62282-07201
          +

          Nor does REPLACE increment the change counter. +(source: lang_conflict.html, checked-by: th3/req1/conflict02.test, matrix: context, detail)

          + +
          R-37051-49391-21174-04435-43019-60258-26390-24659
          +

          The available modifiers are as follows. NNN days NNN hours NNN minutes NNN.NNNN seconds NNN months NNN years start of month start of year start of day weekday N unixepoch localtime utc +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-37099-37053-38363-03939-37447-24344-49731-34436
          +

          Similarly, if URI filenames are not recognized when the database connection is first opened, they will not be recognized by ATTACH. +(source: uri.html, matrix: context, detail)

          + +
          R-37127-14782-63396-43128-39237-20363-34771-13214
          +

          A call to this routine stores N bytes of randomness into buffer P. +(source: c3ref/randomness.html, checked-by: th3/cov1/random01.test, matrix: context, detail)

          + +
          R-37137-45553-37587-45054-45881-44464-34262-16786
          +

          In some pragmas, the schema name is meaningless and is simply ignored. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-37257-17813-38895-36946-60878-55344-03990-64044
          +

          Note that upon successful completion of an SQLITE_CHECKPOINT_TRUNCATE, the log file will have been truncated to zero bytes and so both *pnLog and *pnCkpt will be set to zero. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-37271-65264-45647-61848-25356-06624-30160-41691
          +

          Compute the current unix timestamp. SELECT strftime('%s','now'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-37283-61388-33413-37250-53520-10226-00265-15596
          +

          All these names are aliases for one another and work equally well in any context. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-37284-06965-27563-13787-56362-60751-57097-13652
          +

          If the DELETE statement has no ORDER BY clause, then all rows that would be deleted in the absence of the LIMIT clause are assembled in an arbitrary order before applying the LIMIT and OFFSET clauses to determine the subset that are actually deleted. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-37286-42536-47612-10625-41273-62615-36449-24349
          +

          /* Add a table named 't1' to the temp, main and an attached database */ ATTACH 'file.db' AS aux; CREATE TABLE t1(x, y); CREATE TEMP TABLE t1(x, y); CREATE TABLE aux.t1(x, y); DROP TABLE t1; /* Drop table in temp database */ DROP TABLE t1; /* Drop table in main database */ DROP TABLE t1; /* Drop table in aux database */ +(source: lang_naming.html, checked-by: tcl/e_resolve.test, matrix: context, detail)

          + +
          R-37287-38238-38896-00540-17030-60706-04523-55035
          +

          The column may not have a default value of CURRENT_TIME, CURRENT_DATE, CURRENT_TIMESTAMP, or an expression in parentheses. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-37304-39405-25413-14317-50314-46541-26352-18136
          +

          If the base expression is NULL then the result of the CASE is always the result of evaluating the ELSE expression if it exists, or NULL if it does not. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-37306-64424-24476-44387-21141-11283-27580-01252
          +

          If an SQL table is created using the "WITHOUT ROWID" clause at the end of its CREATE TABLE statement, then that table is a WITHOUT ROWID table and uses a different on-disk representation. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-37338-25090-02456-18897-36801-31063-06233-22705
          +

          The sqlite3_result_double() interface sets the result from an application-defined function to be a floating point value specified by its 2nd argument. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-37342-04007-10606-64148-39195-51101-42464-04051
          +

          The index value returned is suitable for use as the second parameter to sqlite3_bind(). +(source: c3ref/bind_parameter_index.html, checked-by: th3/req1/bind03.test, matrix: context, detail)

          + +
          R-37367-57340-65398-65389-19439-49960-45341-59090
          +

          In a well-formed sqlite_stat3 table, the samples for any single index must appear in the same order that they occur in the index. In other words, if the entry with left-most column S1 is earlier in the index b-tree than the entry with left-most column S2, then in the sqlite_stat3 table, sample S1 must have a smaller rowid than sample S2. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-37390-56181-43004-09239-55854-05379-58019-03084
          +

          Pending write operations always fail with this error when a rollback occurs. +(source: rescode.html, matrix: context, detail)

          + +
          R-37412-09436-16826-17483-13770-41037-63628-17339
          +

          Either modification causes the SQL statement to behave as a query and to return information about how the SQL statement would have operated if the EXPLAIN keyword or phrase had been omitted. +(source: lang_explain.html, checked-by: th3/cov1/vdbeaux01.test, matrix: context, detail)

          + +
          R-37434-19929-01541-26191-03532-28681-18224-01267
          +

          Abs(X) returns NULL if X is NULL. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/func01.test, matrix: context, detail)

          + +
          R-37497-42412-17450-21022-09662-57031-07761-02196
          +

          The size of the reserved region is determined by the one-byte unsigned integer found at an offset of 20 into the database file header. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-37514-35566-00640-25084-57688-04377-16048-30214
          +

          A value of 1 means UTF-8. +(source: fileformat2.html, checked-by: th3/req1/fileformat03.test, matrix: context, detail)

          + +
          R-37526-53407-04018-28041-58853-34090-01926-44362
          +

          The second integer is the approximate number of rows in the index that have the same value in the first column of the index. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-37639-55938-19671-37883-10811-32762-31289-05215
          +

          This interfaces opens a handle to the BLOB located in row iRow, column zColumn, table zTable in database zDb; in other words, the same BLOB that would be selected by: SELECT zColumn FROM zDb.zTable WHERE rowid = iRow; +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, th3/req1/blob01.test, matrix: context, detail)

          + +
          R-37688-43700-53103-62151-49236-10303-34051-45197
          +

          Use the sqlite3_blob_bytes() interface to determine the size of the opened blob. +(source: c3ref/blob_open.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-37736-42616-04169-53390-00856-45033-53695-63004
          +

          If a COMMIT statement (or the RELEASE of a transaction SAVEPOINT) fails because the database is currently in a state that violates a deferred foreign key constraint and there are currently nested savepoints, the nested savepoints remain open. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys15.test, matrix: context, detail)

          + +
          R-37760-36374-21935-46380-43039-31326-26713-65030
          +

          The sqlite3_table_column_metadata() interface returns SQLITE_OK and fills in the non-NULL pointers in the final five arguments with appropriate values if the specified column exists. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-37773-10272-55463-21527-23891-50096-65319-03368
          +

          For a table or view, the tbl_name column is a copy of the name column. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-37783-42715-27194-59163-53660-14941-49401-50024
          +

          Any %HH escape sequences in the query parameters are resolved prior to being appended to the xOpen filename. +(source: uri.html, matrix: context, detail)

          + +
          R-37795-21752-00915-21672-38602-04515-27824-24579
          +

          The SQLITE_CONFIG_LOG option takes two arguments: a pointer to a function with a call signature of void(*)(void*,int,const char*), and a pointer to void. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/log01.test, th3/th3main.c, matrix: context, detail)

          + +
          R-37801-37633-06717-41084-61304-63724-52548-02844
          +

          The BLOB handle is closed unconditionally. Even if this routine returns an error code, the handle is still closed. +(source: c3ref/blob_close.html, checked-by: tcl/e_blobclose.test, matrix: context, detail)

          + +
          R-37808-62273-24906-47503-60125-44409-00514-33279
          +

          Note that triggers are automatically dropped when the associated table is dropped. +(source: lang_droptrigger.html, checked-by: tcl/e_droptrigger.test, matrix: context, detail)

          + +
          R-37810-60222-47752-18821-24220-18386-52831-63855
          +

          Compute the number of seconds since a particular moment in 2004: SELECT strftime('%s','now') - strftime('%s','2004-01-01 02:34:56'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-37812-47407-44151-24694-62524-58711-37886-57014
          +

          Once an encoding has been set for a database, it cannot be changed. +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-37821-32925-08521-48318-15093-49732-47345-21314
          +

          It is not possible to ALTER TABLE ADD COLUMN a STORED column. +(source: gencol.html, matrix: context, detail)

          + +
          R-37839-54301-54800-59276-61282-21878-13355-00369
          +

          Value is a big-endian 24-bit twos-complement integer. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-37910-23168-39063-40634-50772-23998-34303-02455
          +

          The sqlite_version() function returns the version string for the SQLite library that is running. +(source: lang_corefunc.html, checked-by: th3/req1/func04.test, matrix: context, detail)

          + +
          R-37911-51642-34718-50738-49482-42498-05083-29076
          +

          The LIMIT clause is used to place an upper bound on the number of rows returned by the entire SELECT statement. +(source: lang_select.html, checked-by: th3/req1/select02.test, matrix: context, detail)

          + +
          R-37916-47407-25841-44869-57866-03917-48046-05809
          +

          The MATCH operator is a special syntax for the match() application-defined function. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-37923-12173-52320-03983-04095-34314-35102-35798
          +

          The sqlite3_prepare_v2() interface works exactly the same as sqlite3_prepare_v3() with a zero prepFlags parameter. +(source: c3ref/prepare.html, checked-by: src/prepare.c, matrix: context, detail)

          + +
          R-37936-22853-22443-15784-22618-50674-60606-55303
          +

          If UTF16 input text contains invalid unicode characters, then SQLite might change those invalid characters into the unicode replacement character: U+FFFD. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-37997-42187-51725-59091-37072-50205-56712-26602
          +

          The difference between the effect of a RESTRICT action and normal foreign key constraint enforcement is that the RESTRICT action processing happens as soon as the field is updated - not at the end of the current statement as it would with an immediate constraint, or at the end of the current transaction as it would with a deferred constraint. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-38023-18396-22713-13690-61527-29951-04231-55806
          +

          It is an error to use a "*" or "alias.*" expression in any context other than a result expression list. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-38049-07913-57133-40179-27689-18844-57300-61225
          +

          If any other error occurs while processing an attached database, processing is abandoned and the error code is returned to the caller immediately. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-38049-49177-51808-41050-10295-13822-05309-22802
          +

          The anQueue field is an array of mxLevel+1 unsigned integers that tell the current number of elements in the priority queue at each level. +(source: rtree.html, matrix: context, detail)

          + +
          R-38062-30057-54968-60320-51568-47118-43997-50197
          +

          In partial indexes, only some subset of the rows in the table have corresponding index entries. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-38083-64261-20639-49699-39897-18481-13344-23243
          +

          In other words, calls to xUnpin() on a cache with bPurgeable set to false will always have the "discard" flag set to true. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-38091-32352-01038-12567-23855-46288-57631-62410
          +

          The maximum parameter number is set at compile-time by the SQLITE_MAX_VARIABLE_NUMBER macro. +(source: lang_expr.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-38128-34102-03228-01716-42650-19152-18652-04810
          +

          The sqlite3_wal_autocheckpoint(D,N) is a wrapper around sqlite3_wal_hook() that causes any database on database connection D to automatically checkpoint after committing a transaction if there are N or more frames in the write-ahead log file. +(source: c3ref/wal_autocheckpoint.html, checked-by: tcl/e_walauto.test, matrix: context, detail)

          + +
          R-38176-56274-44779-06953-35503-33902-10868-27976
          +

          In a database with ptrmap pages, the first ptrmap page is page 2. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-38200-45242-44126-59333-52626-62279-09263-45295
          +

          The sqlite3_load_extension() interface returns SQLITE_OK on success and SQLITE_ERROR if something goes wrong. +(source: c3ref/load_extension.html, matrix: context, detail)

          + +
          R-38207-48996-22949-56982-35182-46285-03543-37900
          +

          If zDb is not NULL (or a zero length string) and is not the name of any attached database, SQLITE_ERROR is returned to the caller. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-38219-53002-00313-45584-37253-57007-40981-19888
          +

          If no unused ROWID can be found after a reasonable number of attempts, the insert operation fails with an SQLITE_FULL error. +(source: autoinc.html, checked-by: src/vdbe.c, th3/cov1/vdbe23.test, matrix: context, detail)

          + +
          R-38229-40159-56776-58417-62683-03427-34499-02992
          +

          If the callback function to sqlite3_exec() returns non-zero, then sqlite3_exec() will return SQLITE_ABORT. +(source: rescode.html, checked-by: src/legacy.c, th3/cov1/legacy01.test, matrix: context, detail)

          + +
          R-38242-53217-63508-42050-45799-27349-00700-51305
          +

          "SEARCH" indicates that only a subset of the table rows are visited. +(source: eqp.html, matrix: context, detail)

          + +
          R-38255-01123-17984-58641-36613-29376-16056-55612
          +

          If the filename is ":memory:", then a private, temporary in-memory database is created for the connection. +(source: c3ref/open.html, checked-by: th3/cov1/sharedcache03.test, matrix: context, detail)

          + +
          R-38260-37719-07465-52549-18983-56456-60761-04524
          +

          The VFS is required to either truncate or zero the header of the wal-index when the last connection to it closes. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-38293-42495-20916-29854-03664-36898-47028-10197
          +

          Prior savepoints, even savepoints with matching savepoint-names, are unchanged. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-38308-24406-60432-36844-44723-02085-25022-07693
          +

          SQLite attempts to use an index to satisfy the ORDER BY clause of a query when possible. +(source: optoverview.html, matrix: context, detail)

          + +
          R-38336-05023-13605-39367-03302-30111-01531-40111
          +

          Hence explicitly specifying FOR EACH ROW is optional. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-38392-49970-12862-30349-17432-31139-60846-54763
          +

          If the action code is SQLITE_READ and the callback returns SQLITE_IGNORE then the prepared statement statement is constructed to substitute a NULL value in place of the table column that would have been read if SQLITE_OK had been returned. +(source: c3ref/set_authorizer.html, checked-by: tcl/auth.test, th3/cov1/auth01.test, matrix: context, detail)

          + +
          R-38412-06710-13373-27041-27382-60302-02109-00077
          +

          If the name of the table is unique across all attached databases and the main and temp databases, then the schema-name prefix is not required. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-38422-04402-49671-03749-58225-12387-56102-01352
          +

          The column from the dataset on the left-hand side of the join-operator is considered to be on the left-hand side of the comparison operator (=) for the purposes of collation sequence and affinity precedence. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-38462-47168-00802-29232-37957-12454-50485-62719
          +

          The number of system calls for filesystem operations is reduced, possibly resulting in a small performance increase. +(source: pragma.html, checked-by: th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-38465-03616-05704-04458-16230-08535-12299-37595
          +

          If there is an ON clause then the ON expression is evaluated for each row of the cartesian product as a boolean expression. Only rows for which the expression evaluates to true are included from the dataset. +(source: lang_select.html, checked-by: tcl/e_select.test, tcl/e_select2.test, matrix: context, detail)

          + +
          R-38470-19236-05585-14334-15897-63539-60552-16628
          +

          As with all other SQLite APIs, those whose names end with "16" return UTF-16 encoded strings and the other functions return UTF-8. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-38485-20010-44949-34877-39366-11397-10597-42284
          +

          If a table contains a column of type INTEGER PRIMARY KEY, then that column becomes an alias for the ROWID. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-38493-22774-30789-51088-59525-02333-30794-32184
          +

          when sqlite3_set_auxdata() is invoked again on the same parameter +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-38513-43475-55678-22086-42456-40584-55564-45510
          +

          A call to xRelease(X,M) invalidates all savepoints where N>=M. +(source: vtab.html, matrix: context, detail)

          + +
          R-38515-45264-03335-50980-08297-28344-12265-07348
          +

          An UPDATE statement is used to modify a subset of the values stored in zero or more rows of the database table identified by the qualified-table-name specified as part of the UPDATE statement. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-38536-04510-23157-49681-06132-47285-44686-09674
          +

          The quote(X) function returns the text of an SQL literal which is the value of its argument suitable for inclusion into an SQL statement. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-38545-41243-15928-60739-42424-40199-61520-19344
          +

          If SQLite determines that invoking the busy handler could result in a deadlock, it will go ahead and return SQLITE_BUSY to the application instead of invoking the busy handler. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-38577-07276-49824-55947-21917-12317-50155-56118
          +

          If the query string is present, then all query parameters are passed through into the xOpen method of the underlying VFS. +(source: uri.html, matrix: context, detail)

          + +
          R-38578-34175-46775-59738-25546-18239-05883-23898
          +

          If an SQLITE_BUSY error is encountered when processing one or more of the attached WAL databases, the operation is still attempted on any remaining attached databases and SQLITE_BUSY is returned at the end. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-38590-62769-37174-11350-15307-56847-39156-23447
          +

          The first parameter to the authorizer callback is a copy of the third parameter to the sqlite3_set_authorizer() interface. +(source: c3ref/set_authorizer.html, checked-by: src/tclsqlite.c, th3/th3util.c, matrix: context, detail)

          + +
          R-38595-30726-57286-21229-43510-46199-10154-57516
          +

          If the value N is out of range or if the N-th parameter is nameless, then NULL is returned. +(source: c3ref/bind_parameter_name.html, checked-by: th3/req1/bind04.test, matrix: context, detail)

          + +
          R-38620-19499-44951-35069-39820-53253-57753-11041
          +

          In a CASE with a base expression, the base expression is evaluated just once and the result is compared against the evaluation of each WHEN expression from left to right. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-38640-56094-37919-00442-61763-52765-52692-27177
          +

          The "int" variable pointed to by the V parameter will be set to the "select-id" for the X-th loop. +(source: c3ref/c_scanstat_est.html, matrix: context, detail)

          + +
          R-38644-64912-46499-33348-47960-41753-16072-56504
          +

          If the right-most element of a compound SELECT is a VALUES clause, then no ORDER BY clause is allowed on that statement. +(source: lang_select.html, checked-by: th3/req1/select02.test, matrix: context, detail)

          + +
          R-38650-02327-39862-58764-51816-33051-52085-34596
          +

          The immutable query parameter is a boolean that signals to SQLite that the underlying database file is held on read-only media and cannot be modified, even by another process with elevated privileges. +(source: uri.html, matrix: context, detail)

          + +
          R-38720-18127-00182-16789-56682-25353-36594-39383
          +

          The default setting is determined by the SQLITE_ALLOW_COVERING_INDEX_SCAN compile-time option, or is "on" if that compile-time option is omitted. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/global.c, matrix: context, detail)

          + +
          R-38759-38789-04186-61984-59919-00444-32947-07826
          +

          Operators IS and IS NOT have the same precedence as =. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-38787-59790-48915-64090-33059-22783-12299-30230
          +

          If the SQLITE_FCNTL_PRAGMA file control returns SQLITE_NOTFOUND, then normal PRAGMA processing continues. +(source: c3ref/c_fcntl_begin_atomic_write.html, checked-by: th3/cov1/pragma24.test, matrix: context, detail)

          + +
          R-38799-08373-51877-49685-25873-19436-11233-20221
          +

          URI filenames can be enabled or disabled using the SQLITE_USE_URI=1 or SQLITE_USE_URI=0 compile-time options. +(source: uri.html, checked-by: src/global.c, matrix: context, detail)

          + +
          R-38815-48046-28937-36081-10893-02265-15426-25349
          +

          A frame is considered valid if and only if the following conditions are true: The salt-1 and salt-2 values in the frame-header match salt values in the wal-header The checksum values in the final 8 bytes of the frame-header exactly match the checksum computed consecutively on the first 24 bytes of the WAL header and the first 8 bytes and the content of all frames up to and including the current frame. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-38828-57497-43339-57489-42530-28213-54283-40875
          +

          When a SAVEPOINT is the outer-most savepoint and it is not within a BEGIN...COMMIT then the behavior is the same as BEGIN DEFERRED TRANSACTION. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-38841-33525-61370-32823-20999-44685-25709-53990
          +

          Application code is allowed to modify the sqlite_sequence table, to add new rows, to delete rows, or to modify existing rows. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-38910-65521-60645-02772-59473-48927-46815-22731
          +

          The "const char *" variable pointed to by the V parameter will be set to a zero-terminated UTF-8 string containing the name of the index or table used for the X-th loop. +(source: c3ref/c_scanstat_est.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-38914-26427-29082-17331-29986-21952-39833-10934
          +

          The total_changes() function returns the number of row changes caused by INSERT, UPDATE or DELETE statements since the current database connection was opened. +(source: lang_corefunc.html, checked-by: th3/cov1/func05.test, matrix: context, detail)

          + +
          R-38971-13593-63134-41706-45438-37598-45923-53388
          +

          Note that a declared type of "FLOATING POINT" would give INTEGER affinity, not REAL affinity, due to the "INT" at the end of "POINT". +(source: datatype3.html, checked-by: th3/req1/datatype3_02.test, matrix: context, detail)

          + +
          R-38973-52184-38987-24216-42448-05561-19819-59369
          +

          If the optional ESCAPE clause is present, then the like() function is invoked with three arguments. +(source: lang_corefunc.html, checked-by: th3/req1/func02.test, matrix: context, detail)

          + +
          R-38980-08445-54197-34551-31600-64664-60502-04654
          +

          NOCASE does not implement a general purpose unicode caseless comparison. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-38989-21359-13709-49366-18905-24783-41677-06526
          +

          The szExtra parameter will a number less than 250. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-39000-44986-06007-27676-18826-64674-54503-26539
          +

          If S is NULL, then the highest transaction state of any schema on database connection D is returned. +(source: c3ref/txn_state.html, matrix: context, detail)

          + +
          R-39009-25596-33829-41361-38484-11658-48369-57903
          +

          The result of the CASE expression is the evaluation of the THEN expression that corresponds to the first WHEN expression that evaluates to true. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-39020-65330-19381-32057-25425-01859-32299-49676
          +

          The COLLATE clause of the column definition is used to define alternative collating functions for a column. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-39051-42271-46025-06225-43154-22193-07696-21282
          +

          The second form attempts to modify the maximum page count. +(source: pragma.html, checked-by: th3/req1/pragma12.test, matrix: context, detail)

          + +
          R-39070-64522-51812-62435-11898-58079-59310-06231
          +

          The sqlite3_db_cacheflush(D) interface flushes caches for all schemas - "main", "temp", and any attached databases. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-39073-45389-04336-35554-15796-29115-57398-44032
          +

          If M is -1 in the initial journal header, then the number of page records that follow is computed by computing how many page records will fit in the available space of the remainder of the journal file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-39074-57615-41505-43616-22624-34066-27860-62726
          +

          The SQLITE_OMIT_TRACE compile-time option causes sqlite3_expanded_sql() to always return NULL. +(source: c3ref/expanded_sql.html, checked-by: th3/req1/sql01.test, matrix: context, detail)

          + +
          R-39082-45490-57705-20308-15536-26647-22917-12593
          +

          The query above will use the po_parent index to help find the answer, since the po_parent index contains entries for all rows of interest. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-39084-14613-42485-09805-36660-25752-30462-34243
          +

          The sqlite3_str_errcode(X) method returns SQLITE_NOMEM following any out-of-memory error, or SQLITE_TOOBIG if the size of the dynamic string exceeds SQLITE_MAX_LENGTH, or SQLITE_OK if there have been no errors. +(source: c3ref/str_errcode.html, matrix: context, detail)

          + +
          R-39086-42574-52066-34566-03603-26293-15630-13712
          +

          The third argument to xCreate(), bPurgeable, is true if the cache being created will be used to cache database pages of a file stored on disk, or false if it is used for an in-memory database. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-39088-19376-30403-42071-52241-63734-59003-40185
          +

          The sqlite3_value object returned by sqlite3_column_value() is unprotected. +(source: c3ref/value.html, checked-by: th3/req1/value01.test, matrix: context, detail)

          + +
          R-39089-10219-02970-26628-53332-63736-48500-08755
          +

          The s1 value spans all 32-bit integer terms of the sequence whereas s0 omits the final term. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-39100-27317-10483-05917-57976-22690-13501-50723
          +

          The SQLITE_CONFIG_PCACHE_HDRSZ option takes a single parameter which is a pointer to an integer and writes into that integer the number of extra bytes per page required for each page in SQLITE_CONFIG_PAGECACHE. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/cov1/main42.test, matrix: context, detail)

          + +
          R-39150-60222-54489-42043-19266-00482-07233-17932
          +

          On a cache where bPurgeable is false, SQLite will never invoke xUnpin() except to deliberately delete a page. +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-39210-36906-47474-04238-18863-57364-16133-33806
          +

          "b=6" will match to "6=b" as long as "b=6" is on the index and "6=b" is in the query. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-39221-43493-49031-48260-11050-48204-23096-55403
          +

          The sqlite3_mutex_leave() routine exits a mutex that was previously entered by the same thread. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-39225-16568-52968-30010-37247-11603-25439-49402
          +

          The expression of a generated column may not directly reference the ROWID, though it can reference the INTEGER PRIMARY KEY column, which is often the same thing. +(source: gencol.html, matrix: context, detail)

          + +
          R-39254-55835-64728-03186-59811-05640-07786-15038
          +

          Each entry in the index b-tree corresponds to a single row in the associated SQL table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-39265-04070-30004-05781-22531-14920-64985-48690
          +

          If no matching expression can be found in the result columns of any constituent SELECT, it is an error. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-39279-48828-00404-43812-37996-18739-13104-15317
          +

          The order of values in the record is the same as the order of columns in the SQL table definition. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-39332-27982-27049-48904-10655-02053-00990-04758
          +

          The subquery does not use LIMIT or the outer query does not use aggregates. +(source: optoverview.html, matrix: context, detail)

          + +
          R-39350-14264-06804-50075-43758-39518-52551-62265
          +

          These routines open an SQLite database file as specified by the filename argument. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-39368-64333-53302-20010-22332-46980-48834-46750
          +

          In a compound SELECT, all the constituent SELECTs must return the same number of result columns. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-39412-46882-37101-45160-49245-06434-49198-35151
          +

          An application-defined function is permitted to call other SQLite interfaces. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc06.test, matrix: context, detail)

          + +
          R-39414-35489-25303-10592-22636-36530-45454-18784
          +

          The infix GLOB operator is implemented by calling the function glob(Y,X) and can be modified by overriding that function. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-39448-56079-43024-42660-00434-04264-13777-54050
          +

          The filename argument sqlite3_open16() is converted from UTF16 native byte order into UTF8 prior to processing. +(source: uri.html, matrix: context, detail)

          + +
          R-39464-12723-18801-15682-15503-09131-15880-06935
          +

          The return value from sqlite3_column_blob() for a zero-length BLOB is a NULL pointer. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-39464-36566-10218-24417-22703-07867-12954-27805
          +

          The first time the database is written, an exclusive lock is obtained and held. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-39544-28997-13653-57291-53593-51283-21786-51117
          +

          In other words, the first column is 0 if the equivalent call to sqlite3_wal_checkpoint_v2() would have returned SQLITE_OK or 1 if the equivalent call would have returned SQLITE_BUSY. +(source: pragma.html, matrix: context, detail)

          + +
          R-39556-50570-30565-00761-35102-37425-01790-22325
          +

          The progress handler is also disabled by setting N to a value less than 1. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-39564-36305-13838-22783-16141-24782-64457-11535
          +

          The sqlite_compileoption_used() SQL function is a wrapper around the sqlite3_compileoption_used() C/C++ function. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/ctime02.test, matrix: context, detail)

          + +
          R-39578-54133-12312-25444-39025-43860-65200-11026
          +

          The SQLITE_FCNTL_OVERWRITE opcode is invoked by SQLite after opening a write transaction to indicate that, unless it is rolled back for some reason, the entire database file will be overwritten by the current transaction. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-39608-49000-51968-24842-19070-08094-34539-25072
          +

          This pragma sets or queries the database connection locking-mode. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-39616-20555-02533-15918-45822-50476-08959-13235
          +

          Both GLOB and LIKE may be preceded by the NOT keyword to invert the sense of the test. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-39625-59133-51160-16821-08966-29861-61919-63168
          +

          A USING or ON clause may not be added to a join that specifies the NATURAL keyword. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-39692-12488-54491-44352-04912-13609-39585-46004
          +

          Deferred foreign key constraints are not checked until the transaction tries to COMMIT. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, th3/req1/foreignkeys14.test, matrix: context, detail)

          + +
          R-39719-17021-25795-58953-42832-28593-26146-38577
          +

          The sqlite3_commit_hook(D,C,P) and sqlite3_rollback_hook(D,C,P) functions return the P argument from the previous call of the same function on the same database connection D, or NULL for the first call for each function on D. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-39746-16618-18331-39876-26719-11435-38479-45574
          +

          It is not possible to change the text encoding of a database after it has been created and any attempt to do so will be silently ignored. +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-39763-46240-25727-03918-12212-03992-13820-06726
          +

          PRAGMA schema.journal_mode; PRAGMA schema.journal_mode = DELETE | TRUNCATE | PERSIST | MEMORY | WAL | OFF This pragma queries or sets the journal mode for databases associated with the current database connection. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-39822-07822-55219-05739-15484-26699-12744-24448
          +

          In this case the new table is created in the named database. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-39822-14939-20605-05288-51207-58465-58259-08970
          +

          If the transaction has already been rolled back automatically by the error response, then the ROLLBACK command will fail with an error, but no harm is caused by this. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-39910-14723-21123-44064-38823-12161-58690-10248
          +

          A comma (",") is used as the separator if Y is omitted. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-39930-13329-18334-04678-35004-32482-06305-13006
          +

          The sqlite3_int64 variable pointed to by the V parameter will be set to the total number of rows examined by all iterations of the X-th loop. +(source: c3ref/c_scanstat_est.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-40025-59984-53912-08799-37788-65154-58103-39921
          +

          Expressions in an index may only refer to columns in the table that is being indexed. +(source: lang_createindex.html, matrix: context, detail)

          + +
          R-40026-10531-12029-61961-20483-43769-01249-19476
          +

          If SQLite is compiled with the SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option, then the syntax of the DELETE statement is extended by the addition of optional ORDER BY and LIMIT clauses: +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-40045-04159-18257-36948-62852-01097-02415-08499
          +

          SQLite ensures that *pzErrMsg is NULL before calling the xEntryPoint(). +(source: c3ref/auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-40069-12485-64831-34937-24315-11591-54668-02692
          +

          The RETURNING clause does not report any additional database changes caused by foreign key constraints or triggers. +(source: lang_returning.html, checked-by: th3/cov1/returning04.test, matrix: context, detail)

          + +
          R-40079-54503-52433-22063-65278-03713-13772-01502
          +

          The BETWEEN operator is logically equivalent to a pair of comparisons. "x BETWEEN y AND z" is equivalent to "x>=y AND x<=z" except that with BETWEEN, the x expression is only evaluated once. +(source: lang_expr.html, checked-by: tcl/e_expr.test, th3/cov1/rowvalue04.test, matrix: context, detail)

          + +
          R-40086-60101-35729-43768-42445-10732-59805-35730
          +

          If the FORMAT argument is missing or NULL then the result is NULL. +(source: lang_corefunc.html, checked-by: tcl/printf2.test, th3/cov1/printf08.test, matrix: context, detail)

          + +
          R-40134-30296-44811-22193-40834-03348-00642-51152
          +

          Table zTable is a WITHOUT ROWID table +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, tcl/without_rowid5.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-40137-26050-25715-27051-43009-42599-25608-04347
          +

          If the mode option is set to "rw", then the database is opened for read-write (but not create) access, as if SQLITE_OPEN_READWRITE (but not SQLITE_OPEN_CREATE) had been set. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-40197-14811-29578-36290-28063-57666-21739-57478
          +

          The dropped table is completely removed from the database schema and the disk file. +(source: lang_droptable.html, checked-by: th3/req1/droptable01.test, matrix: context, detail)

          + +
          R-40212-32858-03884-52961-15925-53384-61113-63305
          +

          Therefore, auto-vacuuming must be turned on before any tables are created. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-40219-59128-49321-57557-20784-05955-23042-57460
          +

          The T argument is one of the SQLITE_TRACE constants to indicate why the callback was invoked. +(source: c3ref/trace_v2.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-40233-33496-43567-58551-03815-59938-27256-59385
          +

          The nolock query parameter is a boolean that disables all calls to the xLock, xUnlock, and xCheckReservedLock methods of the VFS when true. +(source: uri.html, matrix: context, detail)

          + +
          R-40235-17052-28075-57665-18059-48204-40601-49682
          +

          The update hook is not invoked for rows that are deleted by the REPLACE conflict resolution strategy. +(source: lang_conflict.html, checked-by: th3/req1/conflict02.test, matrix: context, detail)

          + +
          R-40244-56906-37355-29196-11093-05053-42353-15016
          +

          If the 5th parameter to sqlite3_exec() is not NULL and no errors occur, then sqlite3_exec() sets the pointer in its 5th parameter to NULL before returning. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-40248-50202-39876-24554-56269-52121-36535-08663
          +

          The sqlite3_cancel_auto_extension(X) routine returns 1 if initialization routine X was successfully unregistered and it returns 0 if X was not on the list of initialization routines. +(source: c3ref/cancel_auto_extension.html, matrix: context, detail)

          + +
          R-40260-16838-48833-50335-31686-26847-17814-00082
          +

          The number of coordinates is 2 for a 1-dimensional R*Tree, 4 for a 2-dimensional R*Tree, 6 for a 3-dimensional R*Tree, and so forth. +(source: rtree.html, matrix: context, detail)

          + +
          R-40275-54363-02570-13891-25879-32462-51713-20144
          +

          If no COLLATE clause is specified, the default collation sequence is BINARY. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-40297-14464-07991-25596-41588-39255-21146-34618
          +

          The INDEXED BY phrase forces the SQLite query planner to use a particular named index on a DELETE, SELECT, or UPDATE statement. +(source: lang_indexedby.html, checked-by: tcl/indexedby.test, matrix: context, detail)

          + +
          R-40298-31327-08313-07924-25737-24102-08430-39905
          +

          The LIKE optimization might occur if the column named on the left of the operator is indexed using the built-in BINARY collating sequence and case_sensitive_like is turned on. Or the optimization might occur if the column is indexed using the built-in NOCASE collating sequence and the case_sensitive_like mode is off. These are the only two combinations under which LIKE operators will be optimized. +(source: optoverview.html, checked-by: th3/cov1/where03.test, th3/cov1/where03b.test, matrix: context, detail)

          + +
          R-40318-26723-38949-62709-27455-61275-20452-62962
          +

          BLOB values (even serial types 12 and larger) sort last and in the order determined by memcmp(). +(source: fileformat2.html, checked-by: th3/req1/fileformat05.test, matrix: context, detail)

          + +
          R-40355-56314-02785-21892-27630-10277-00128-03405
          +

          When the callback is invoked, the first argument passed is a copy of the second argument to sqlite3_collation_needed() or sqlite3_collation_needed16(). The second argument is the database connection. The third argument is one of SQLITE_UTF8, SQLITE_UTF16BE, or SQLITE_UTF16LE, indicating the most desirable form of the collation sequence function required. The fourth parameter is the name of the required collation sequence. +(source: c3ref/collation_needed.html, matrix: context, detail)

          + +
          R-40361-64162-53893-43519-22401-31532-23705-29102
          +

          Autocommit mode is on by default. +(source: c3ref/get_autocommit.html, matrix: context, detail)

          + +
          R-40373-33294-50231-39382-53294-24447-44855-24711
          +

          SQLite makes a copy of the sqlite3_pcache_methods2 object. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-40383-06816-10485-50532-53566-05766-27128-48276
          +

          The sqlite3_compileoption_used() function returns 0 or 1 indicating whether the specified option was defined at compile time. +(source: c3ref/compileoption_get.html, checked-by: th3/cov1/ctime01.test, matrix: context, detail)

          + +
          R-40390-09039-54106-21086-56168-24022-18205-41129
          +

          These functions add, remove, or modify a collation associated with the database connection specified as the first argument. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-40460-39888-52540-38305-24333-10191-58577-29064
          +

          A call to sqlite3_snapshot_open(D,S,P) will fail if the database connection D does not know that the database file for schema S is in WAL mode. A database connection might not know that the database file is in WAL mode if there has been no prior I/O on that database connection, or if the database entered WAL mode after the most recent I/O on the database connection. +(source: c3ref/snapshot_open.html, matrix: context, detail)

          + +
          R-40463-24712-34752-07038-54630-26227-29776-31431
          +

          SQLITE_DBSTATUS_CACHE_MISS This parameter returns the number of pager cache misses that have occurred. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-40472-60438-03331-36186-60982-36973-59940-12981
          +

          Columns that do not appear in the list of assignments are left unmodified. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-40482-20265-47732-31040-18704-35090-36000-12311
          +

          The third column is the name of the table that is referred to. +(source: pragma.html, checked-by: tcl/fkey5.test, th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-40490-08523-63255-17373-12821-43863-07916-14588
          +

          The sqlite3_str_length(X) method returns the current length, in bytes, of the dynamic string under construction in sqlite3_str object X. +(source: c3ref/str_errcode.html, matrix: context, detail)

          + +
          R-40502-12262-42819-60807-51435-51687-55446-47633
          +

          If SQLITE_IOERR_XXX, SQLITE_NOMEM, or SQLITE_READONLY is returned, then there is no point in retrying the call to sqlite3_backup_step(). These errors are considered fatal. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-40541-16535-13486-20808-32771-40014-56894-53399
          +

          This pragma returns the names of compile-time options used when building SQLite, one option per row. +(source: pragma.html, checked-by: th3/req1/pragma13.test, matrix: context, detail)

          + +
          R-40541-54897-33607-37262-17474-57290-09312-25628
          +

          For the purposes of this API, a transaction is said to have been rolled back if an explicit "ROLLBACK" statement is executed, or an error or constraint causes an implicit rollback to occur. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-40564-64233-62609-55740-51668-02472-22352-36166
          +

          No affinities are applied to any values as the result of a GROUP by clause. +(source: datatype3.html, checked-by: th3/req1/datatype3_07.test, matrix: context, detail)

          + +
          R-40597-22164-08785-17254-28069-60974-16591-44156
          +

          The result of avg() is NULL if and only if there are no non-NULL inputs. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-40598-36595-56877-54174-64761-50948-11892-46483
          +

          For each affected row, the named columns are set to the values found by evaluating the corresponding scalar expressions. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-40602-24566-60725-06279-09295-25327-26293-64572
          +

          The schema-names 'main' and 'temp' refer to the main database and the database used for temporary tables. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-40630-02268-40288-03121-46855-38283-56768-00095
          +

          If used within a SELECT that uses the "query by rowid" or "linear scan" strategies, then the snippet and offsets both return an empty string, and the matchinfo function returns a blob value zero bytes in size. +(source: fts3.html, checked-by: tcl/fts3snippet.test, matrix: context, detail)

          + +
          R-40641-22898-05833-02924-09975-01966-21919-53888
          +

          The name of the column being indexed, or NULL if the index-column is the rowid of the table being indexed or an expression. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-40676-08516-16968-48123-39083-47673-52246-45004
          +

          Inserts into WITHOUT ROWID tables are not recorded. +(source: c3ref/last_insert_rowid.html, checked-by: th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-40682-45237-21409-00125-10329-07254-01818-58163
          +

          As with the LIKE operator, the sqlite3_strlike(P,X,E) function is case insensitive - equivalent upper and lower case ASCII characters match one another. +(source: c3ref/strlike.html, matrix: context, detail)

          + +
          R-40729-56447-32753-40044-54162-25797-56212-55799
          +

          Duplicate rows are removed from the results of INTERSECT and EXCEPT operators before the result set is returned. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-40745-32628-44360-54833-19873-28133-21062-02308
          +

          However xMutexAlloc() may use SQLite memory allocation for a fast or recursive mutex. +(source: c3ref/mutex_methods.html, matrix: context, detail)

          + +
          R-40779-12285-51949-10144-43789-15381-05710-53892
          +

          The first column is usually 0 but will be 1 if a RESTART or FULL or TRUNCATE checkpoint was blocked from completing, for example because another thread or process was actively using the database. +(source: pragma.html, checked-by: th3/req1/pragma29.test, matrix: context, detail)

          + +
          R-40798-35269-51954-12592-52405-01125-52034-02657
          +

          Warning: misuse of this pragma can easily result in a corrupt database file. +(source: pragma.html, checked-by: th3/req1/pragma30.test, matrix: context, detail)

          + +
          R-40812-03570-58737-26450-04451-50021-12578-43661
          +

          If no negative ROWID values are inserted explicitly, then automatically generated ROWID values will always be greater than zero. +(source: autoinc.html, checked-by: src/vdbe.c, th3/cov1/vdbe23.test, matrix: context, detail)

          + +
          R-40855-36147-31785-54623-27721-28379-48170-05800
          +

          If the SELECT statement is an aggregate query with a GROUP BY clause, then each of the expressions specified as part of the GROUP BY clause is evaluated for each row of the dataset according to the processing rules stated below for ORDER BY expressions. Each row is then assigned to a "group" based on the results; rows for which the results of evaluating the GROUP BY expressions are the same get assigned to the same group. +(source: lang_select.html, matrix: context, detail)

          + +
          R-40858-03003-08666-12472-31051-52566-61637-28947
          +

          The fourth parameter to sqlite3_open_v2() is the name of the sqlite3_vfs object that defines the operating system interface that the new database connection should use. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-40874-07817-64808-61349-14164-22324-19538-25900
          +

          In those routines that have a fourth argument, its value is the number of bytes in the parameter. To be clear: the value is the number of bytes in the value, not the number of characters. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-40892-13487-22632-16999-05016-52970-57179-01588
          +

          An attempt to execute COMMIT might also result in an SQLITE_BUSY return code if an another thread or process has an open read connection. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-40912-17796-52858-33167-65116-31464-10604-52940
          +

          Only an effective call of sqlite3_initialize() does any initialization. All other calls are harmless no-ops. +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-40921-47946-20610-64910-18137-09746-01061-06361
          +

          Another limitation of the histogram data is that it only applies to the left-most column on an index. +(source: optoverview.html, matrix: context, detail)

          + +
          R-40935-37384-47520-54323-57387-46753-55838-11679
          +

          In the following logically equivalent formulation of the same query, the substitution of "CROSS JOIN" for the "," means that the order of tables must be N1, E, N2. SELECT * FROM node AS n1 CROSS JOIN edge AS e CROSS JOIN node AS n2 WHERE n1.name = 'alice' AND n2.name = 'bob' AND e.orig = n1.id AND e.dest = n2.id; +(source: optoverview.html, matrix: context, detail)

          + +
          R-40949-19585-05483-44375-20599-28045-28956-60873
          +

          The fifth byte through the last usable byte are used to hold overflow content. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-40949-22892-24068-33862-21333-32882-13770-09171
          +

          The third integer is the number number of rows in the index that have the same value for the first two columns. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-40975-20399-26495-18141-01831-14670-61544-00270
          +

          If N is a negative number or something other than an integer value, then the pragma behaves as if the N argument was omitted. +(source: pragma.html, matrix: context, detail)

          + +
          R-40979-20331-65132-35120-47137-32709-07069-35596
          +

          The SQLITE_DBCONFIG_ENABLE_QPSG option activates or deactivates the query planner stability guarantee (QPSG). When the QPSG is active, a single SQL query statement will always use the same algorithm regardless of values of bound parameters. +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/cov1/qpsg01.test, th3/cov1/qpsg02.test, matrix: context, detail)

          + +
          R-41004-58299-09133-05321-11963-32065-55865-10893
          +

          The parameter P is passed through as the only parameter to the callback function X. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-41025-56247-28274-26451-36451-44569-58431-11817
          +

          Otherwise, the affinity is NUMERIC. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-41040-47502-07753-07518-58818-60449-29305-32446
          +

          Autocheckpointing is enabled by default with an interval of 1000 or SQLITE_DEFAULT_WAL_AUTOCHECKPOINT. +(source: pragma.html, matrix: context, detail)

          + +
          R-41050-23052-29095-23436-46083-00331-23025-31647
          +

          The first (query) form will return the synchronous setting as an integer. +(source: pragma.html, matrix: context, detail)

          + +
          R-41051-26626-32657-27004-34667-60114-13297-41837
          +

          In more recent versions of SQLite, the ROLLBACK will proceed and pending statements will often be aborted, causing them to return an SQLITE_ABORT or SQLITE_ABORT_ROLLBACK error. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-41062-34431-24503-40012-23472-27163-07838-01416
          +

          Parent and child keys must have the same cardinality. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys11.test, matrix: context, detail)

          + +
          R-41103-34171-63381-59793-03319-04831-02307-39561
          +

          If an error occurs while evaluating the SQL statements passed into sqlite3_exec(), then execution of the current statement stops and subsequent statements are skipped. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-41129-04825-55392-49717-44063-44499-04205-01374
          +

          PRAGMA schema.secure_delete; PRAGMA schema.secure_delete = boolean|FAST Query or change the secure-delete setting. +(source: pragma.html, checked-by: th3/cov1/pragma20.test, th3/cov1/pragma21.test, matrix: context, detail)

          + +
          R-41132-04368-54784-12197-53730-05205-63815-61247
          +

          Comments do not nest. +(source: lang_comment.html, checked-by: th3/req1/comment01.test, matrix: context, detail)

          + +
          R-41134-27890-19387-23998-27179-40954-57167-14106
          +

          When you change the cache size using the cache_size pragma, the change only endures for the current session. +(source: pragma.html, checked-by: th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-41146-12423-20310-63569-37846-41405-23151-59633
          +

          SQLite attempts to transform the result of the generating expression into that datatype using the same affinity rules as for ordinary columns. +(source: gencol.html, matrix: context, detail)

          + +
          R-41161-50390-16822-36301-43678-58977-40657-30512
          +

          If this parameter is -1, then the SQL function or aggregate may take any number of arguments between 0 and the limit set by sqlite3_limit(SQLITE_LIMIT_FUNCTION_ARG). +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc02.test, matrix: context, detail)

          + +
          R-41183-50724-01751-26515-20432-60241-55721-62765
          +

          The returned string is valid until the prepared statement is destroyed using sqlite3_finalize() or until the statement is automatically reprepared by the first call to sqlite3_step() for a particular run or until the same information is requested again in a different encoding. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-41220-51800-40113-04594-39111-44246-00162-60024
          +

          This option sets the threading mode to Serialized. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-41246-06467-15697-52258-02048-61500-49466-56999
          +

          The multi-argument max() function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-41299-52117-33031-60403-48286-21515-32111-27387
          +

          If no error (SQLITE_BUSY or otherwise) is encountered while processing the attached databases, SQLITE_OK is returned. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-41321-43211-53918-03188-33264-03683-46680-13592
          +

          In the following query, the optimizer is free to reorder the tables of FROM clause any way it sees fit: SELECT * FROM node AS n1, edge AS e, node AS n2 WHERE n1.name = 'alice' AND n2.name = 'bob' AND e.orig = n1.id AND e.dest = n2.id; +(source: optoverview.html, matrix: context, detail)

          + +
          R-41332-12947-25232-24036-57064-07925-19702-44154
          +

          Page 1 of a database file is the root page of a table b-tree that holds a special table named "sqlite_schema". +(source: fileformat2.html, matrix: context, detail)

          + +
          R-41357-61664-43525-02491-20290-06673-35745-04652
          +

          The RETURNING clause is followed by a comma-separated list of expressions. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-41361-32452-08540-06268-11369-38463-57924-37597
          +

          The "pk" column in the result set is zero for columns that are not part of the primary key, and is the index of the column in the primary key for columns that are part of the primary key. +(source: pragma.html, matrix: context, detail)

          + +
          R-41381-35999-48332-52888-17487-39096-22671-62741
          +

          If the third parameter to sqlite3_result_error() or sqlite3_result_error16() is non-negative then SQLite takes that many bytes (not characters) from the 2nd parameter as the error message. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-41411-18837-33884-40601-61407-45364-54319-00196
          +

          If the keywords PRIMARY KEY are added to a column definition, then the primary key for the table consists of that single column. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-41417-64456-42642-02544-40631-11378-24048-47614
          +

          The WAL journaling mode uses a write-ahead log instead of a rollback journal to implement transactions. +(source: pragma.html, checked-by: th3/req1/pragma24.test, matrix: context, detail)

          + +
          R-41435-15049-20553-57196-01541-07225-45251-60631
          +

          When temp_store is DEFAULT (0), the compile-time C preprocessor macro SQLITE_TEMP_STORE is used to determine where temporary tables and indices are stored. +(source: pragma.html, matrix: context, detail)

          + +
          R-41438-32603-17646-55492-38195-10504-33475-54382
          +

          This columns is NULL if the column is the rowid or an expression. +(source: pragma.html, matrix: context, detail)

          + +
          R-41438-41245-47933-47570-18885-03208-62677-50789
          +

          This can result in a table that contains data that is in violation of the CHECK constraint. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-41444-49665-13532-29136-56203-03908-49213-31629
          +

          Other integer type names like "INT" or "BIGINT" or "SHORT INTEGER" or "UNSIGNED INTEGER" causes the primary key column to behave as an ordinary table column with integer affinity and a unique index, not as an alias for the rowid. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-41470-32236-05158-07794-46704-63040-13347-49238
          +

          The aConstraint[] array only reports WHERE clause terms that are relevant to the particular virtual table being queried. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-41499-47058-04189-19670-59283-14956-02456-13763
          +

          The leftmost column is number 0. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-41519-43313-49943-13325-32316-49786-47625-55988
          +

          If N is out of range, sqlite3_compileoption_get() returns a NULL pointer. +(source: c3ref/compileoption_get.html, checked-by: th3/cov1/ctime01.test, matrix: context, detail)

          + +
          R-41531-51083-45051-37425-19674-01432-09098-10672
          +

          Every new database connection defaults to having the auto-checkpoint enabled with a threshold of 1000 or SQLITE_DEFAULT_WAL_AUTOCHECKPOINT pages. +(source: c3ref/wal_autocheckpoint.html, checked-by: tcl/e_walauto.test, matrix: context, detail)

          + +
          R-41548-42669-47727-24774-07572-16450-39601-00236
          +

          However, using auto_vacuum can lead to extra database file fragmentation. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-41613-20553-43985-38699-33284-42636-36954-15318
          +

          The sqlite3_wal_checkpoint(D,X) is equivalent to sqlite3_wal_checkpoint_v2(D,X,SQLITE_CHECKPOINT_PASSIVE,0,0). +(source: c3ref/wal_checkpoint.html, checked-by: src/main.c, tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-41621-22586-12548-60539-44942-45128-18412-02664
          +

          As an example, consider the following SQL: CREATE TABLE ex25(a,b,c,d,e,PRIMARY KEY(d,c,a)) WITHOUT rowid; CREATE INDEX ex25ce ON ex25(c,e); CREATE INDEX ex25acde ON ex25(a,c,d,e); CREATE INDEX ex25ae ON ex25(a COLLATE nocase,e); Each row in the ex25ce index is a record with these columns: c, e, d, a. The first two columns are the columns being indexed, c and e. The remaining columns are the primary key of the corresponding table row. Normally, the primary key would be columns d, c, and a, but because column c already appears earlier in the index, it is omitted from the key suffix. +(source: fileformat2.html, checked-by: th3/req1/fileformat04.test, matrix: context, detail)

          + +
          R-41640-10889-37891-53855-47925-09375-30702-30304
          +

          The filename returned by this function is the output of the xFullPathname method of the VFS. +(source: c3ref/db_filename.html, checked-by: th3/cov1/attach04.test, matrix: context, detail)

          + +
          R-41650-20872-58221-16141-48271-22021-38019-62849
          +

          No regexp() user function is defined by default and so use of the REGEXP operator will normally result in an error message. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-41653-15278-35465-27999-04338-56048-26181-52623
          +

          The foreign_key_check pragma checks the database, or the table called "table-name", for foreign key constraints that are violated. The foreign_key_check pragma returns one row output for each foreign key violation. +(source: pragma.html, checked-by: tcl/fkey5.test, th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-41671-45444-43968-05404-57044-18687-11501-21021
          +

          The format string supports the most common substitutions found in the strftime() function from the standard C library plus two new substitutions, %f and %J. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-41719-33203-52232-61281-45744-11728-08852-57887
          +

          The sqlite_stat4.nLt column holds a list of N integers where the K-th integer is the approximate number of entries in the index whose K left-most columns are collectively less than the K left-most columns of the sample. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-41719-58677-16610-62099-11420-34570-29798-59249
          +

          Any SQL statement variables that had values bound to them using the sqlite3_bind_*() API retain their values. +(source: c3ref/reset.html, checked-by: th3/req1/clearbind01.test, matrix: context, detail)

          + +
          R-41778-26203-39333-15071-00697-32758-59991-57440
          +

          SQLITE_LIMIT_ATTACHED The maximum number of attached databases. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-41784-13339-39195-36557-35011-50589-62735-17221
          +

          Tip: If the command "PRAGMA foreign_keys" returns no data instead of a single row containing "0" or "1", then the version of SQLite you are using does not support foreign keys (either because it is older than 3.6.19 or because it was compiled with SQLITE_OMIT_FOREIGN_KEY or SQLITE_OMIT_TRIGGER defined). +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys05.test, matrix: context, detail)

          + +
          R-41795-40039-43827-16838-58364-41518-15809-62342
          +

          These three ways of committing a transaction correspond to the DELETE, TRUNCATE, and PERSIST settings, respectively, of the journal_mode pragma. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-41796-02552-46731-27208-23017-23175-41935-19333
          +

          The columns referenced in the WHERE clause of a partial index can be any of the columns in the table, not just columns that happen to be indexed. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-41837-07814-38752-23130-22847-42887-22849-22070
          +

          If the interrupted SQL operation is an INSERT, UPDATE, or DELETE that is inside an explicit transaction, then the entire transaction will be rolled back automatically. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-41898-15939-51576-48964-07633-48670-39877-19524
          +

          The sqlite3_value_text16be() and sqlite3_value_text16le() interfaces extract UTF-16 strings as big-endian and little-endian respectively. +(source: c3ref/value_blob.html, checked-by: th3/req1/value02.test, th3/req1/value03.test, matrix: context, detail)

          + +
          R-41914-07968-11618-38374-65120-62637-18868-18201
          +

          Pragma integrity_check will return at most N errors before the analysis quits, with N defaulting to 100. +(source: pragma.html, checked-by: th3/req1/integrityck01.test, matrix: context, detail)

          + +
          R-41921-05214-15323-21890-34251-22434-34985-19293
          +

          The likelihood(X,Y) function returns argument X unchanged. +(source: lang_corefunc.html, checked-by: tcl/func3.test, matrix: context, detail)

          + +
          R-41959-38737-02891-22407-44809-18467-12520-20988
          +

          Otherwise, if this function is passed a valid open blob handle, the values returned by the sqlite3_errcode() and sqlite3_errmsg() functions are set before returning. +(source: c3ref/blob_close.html, checked-by: tcl/e_blobclose.test, matrix: context, detail)

          + +
          R-41964-12887-53267-54582-29615-62168-19001-17157
          +

          Create a partial index by adding a WHERE clause to the end of an ordinary CREATE INDEX statement. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-41969-26805-23474-17997-34431-40001-19681-04714
          +

          If the application crashes in the middle of a transaction when the OFF journaling mode is set, then the database file will very likely go corrupt. +(source: pragma.html, checked-by: th3/req1/pragma25.test, matrix: context, detail)

          + +
          R-41970-42722-40683-07259-21331-17616-49232-32709
          +

          This pragma queries or sets the write-ahead log auto-checkpoint interval. +(source: pragma.html, matrix: context, detail)

          + +
          R-41999-52998-34503-61762-41637-15807-51046-53346
          +

          The definition of LIKE pattern matching used in sqlite3_strlike(P,X,E) is the same as for the "X LIKE P ESCAPE E" operator in the SQL dialect understood by SQLite. +(source: c3ref/strlike.html, matrix: context, detail)

          + +
          R-42015-34236-37938-25676-18354-23739-35368-22470
          +

          The sqlite3_value_frombind(X) interface returns non-zero if the value X originated from one of the sqlite3_bind() interfaces. +(source: c3ref/value_blob.html, matrix: context, detail)

          + +
          R-42024-63312-61234-05516-46921-52814-12711-65369
          +

          RESTART blocks concurrent writers while it is running, but allowed readers to proceed. +(source: pragma.html, matrix: context, detail)

          + +
          R-42037-15614-06254-40391-55101-11302-16506-13295
          +

          The DROP INDEX statement removes an index added with the CREATE INDEX statement. +(source: lang_dropindex.html, matrix: context, detail)

          + +
          R-42037-37826-09680-08362-57128-46753-57920-34709
          +

          The default match() function implementation raises an exception and is not really useful for anything. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-42043-38025-54022-62680-37100-38992-27371-65527
          +

          The C argument is a copy of the context pointer passed in as the fourth argument to sqlite3_trace_v2(). +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-42049-24001-08911-07479-20981-30990-05153-14571
          +

          A subsequent call to xRollbackTo(X,R) means that the state of the virtual table should return to what it was when xSavepoint(X,R) was last called. +(source: vtab.html, matrix: context, detail)

          + +
          R-42053-10634-10178-57084-38599-37696-52821-41019
          +

          Setting the heap limits to zero disables the heap limiter mechanism. +(source: c3ref/hard_heap_limit64.html, checked-by: th3/req1/softheaplimit02.test, matrix: context, detail)

          + +
          R-42059-47211-64082-08084-07412-31027-38938-26624
          +

          If the argument N is positive then the suggested cache size is set to N. +(source: pragma.html, checked-by: src/pcache.c, tcl/pragma.test, matrix: context, detail)

          + +
          R-42089-41020-28633-04847-35892-58431-48484-20358
          +

          If no transaction is active (other than the implied transaction that is created on every command) then the ROLLBACK resolution algorithm works the same as the ABORT algorithm. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-42106-50385-56441-15914-62934-29085-54052-00189
          +

          Hexadecimal integer literals are interpreted as 64-bit two's-complement integers and are thus limited to sixteen significant digits of precision. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-42136-40354-42275-03158-50011-22774-46135-65161
          +

          The sqlite3_update_hook(D,C,P) function returns the P argument from the previous call on the same database connection D, or NULL for the first call on D. +(source: c3ref/update_hook.html, checked-by: th3/cov1/main15.test, matrix: context, detail)

          + +
          R-42144-12179-61067-60521-47776-40756-33656-09079
          +

          The third parameter to sqlite3_preupdate_hook() is passed through as the first parameter to callbacks. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-42164-62580-24188-26678-17421-37500-23009-49649
          +

          In addition to the tables, indexes, views, and triggers created by the application and/or the developer using CREATE statements SQL, the sqlite_schema table may contain zero or more entries for internal schema objects that are created by SQLite for its own internal use. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-42168-23975-08359-11434-07624-62565-20004-56753
          +

          Built-in functions may be overloaded by new application-defined functions. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, th3/req1/createfunc05.test, matrix: context, detail)

          + +
          R-42196-45693-64496-49282-35220-26786-47093-56372
          +

          The collating function callback is invoked with a copy of the pArg application data pointer and with two strings in the encoding specified by the eTextRep argument. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-42199-02842-23017-63561-09592-29870-10052-07819
          +

          After a complete checkpoint, if no other connections are in transactions that use the WAL, then subsequent write transactions can overwrite the WAL file from the beginning. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-42207-04347-65478-63733-46803-43649-38770-36227
          +

          In other words, if the pattern is like this: column LIKE x% column GLOB x* then the original LIKE or GLOB tests are disabled when the virtual terms constrain an index because in that case we know that all of the rows selected by the index will pass the LIKE or GLOB test. +(source: optoverview.html, matrix: context, detail)

          + +
          R-42243-62806-04242-02019-64725-25394-01618-23361
          +

          The call to xRollbackTo(X,R) will invalidate all savepoints with N>R; none of the invalided savepoints will be rolled back or released without first being reinitialized by a call to xSavepoint(). +(source: vtab.html, matrix: context, detail)

          + +
          R-42245-25582-08929-62299-62377-14335-00721-06605
          +

          datetime(time-value, modifier, modifier, ...) +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-42264-30503-59734-27182-09604-54439-24686-19729
          +

          The SQLITE_MAX_TRIGGER_DEPTH and SQLITE_LIMIT_TRIGGER_DEPTH settings determine the maximum allowable depth of trigger program recursion. For the purposes of these limits, foreign key actions are considered trigger programs. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys24.test, matrix: context, detail)

          + +
          R-42297-37851-22979-34861-45337-51350-47253-02521
          +

          The parameter name must be given in UTF-8 even if the original statement was prepared from UTF-16 text using sqlite3_prepare16_v2() or sqlite3_prepare16_v3(). +(source: c3ref/bind_parameter_index.html, checked-by: th3/req1/bind03.test, matrix: context, detail)

          + +
          R-42315-53658-63706-40087-63101-17320-03632-52756
          +

          This routine sets a busy handler that sleeps for a specified amount of time when a table is locked. +(source: c3ref/busy_timeout.html, checked-by: th3/cov1/main21.test, matrix: context, detail)

          + +
          R-42316-09582-63519-16650-16131-27933-31807-16513
          +

          If there is no explicit DEFAULT clause attached to a column definition, then the default value of the column is NULL. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-42333-10376-25894-44230-56156-46004-61943-25934
          +

          The incremental_vacuum pragma has no effect if the database is not in auto_vacuum=incremental mode or if there are no pages on the freelist. +(source: pragma.html, checked-by: th3/req1/pragma21.test, matrix: context, detail)

          + +
          R-42353-38420-62893-47772-45609-25296-37398-15241
          +

          If the busy callback returns 0, then no additional attempts are made to access the database and SQLITE_BUSY is returned to the application. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-42363-29104-39854-61131-26966-39533-29446-04460
          +

          SQLITE_LIMIT_VARIABLE_NUMBER The maximum index number of any parameter in an SQL statement. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-42393-33810-20509-47326-15941-02937-41283-04621
          +

          If Z is not initially a string, it is cast to a UTF-8 string prior to processing. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-42401-19613-44791-55246-19167-45900-28933-57755
          +

          If offset iOffset is less than N bytes from the end of the BLOB, SQLITE_ERROR is returned and no data is read. +(source: c3ref/blob_read.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-42412-59321-17229-61863-37154-26359-45547-07737
          +

          Tip: If the application requires a stricter relationship between artist and track, where NULL values are not permitted in the trackartist column, simply add the appropriate "NOT NULL" constraint to the schema. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys02.test, matrix: context, detail)

          + +
          R-42413-48699-18180-28011-52485-52164-16827-39292
          +

          SQLite will also attempt to use indexes to help satisfy GROUP BY clauses and the DISTINCT keyword. +(source: optoverview.html, matrix: context, detail)

          + +
          R-42415-59396-18993-18875-54415-33588-07688-24488
          +

          Or the pragma might run during sqlite3_step() just like normal SQL statements. +(source: pragma.html, checked-by: th3/req1/pragma06.test, matrix: context, detail)

          + +
          R-42420-56072-06217-40848-64970-52103-43558-36371
          +

          The highwater mark associated with SQLITE_DBSTATUS_CACHE_HIT is always 0. +(source: c3ref/c_dbstatus_options.html, checked-by: src/status.c, matrix: context, detail)

          + +
          R-42475-05522-33974-48486-41062-27037-25414-59266
          +

          SQLITE_DBSTATUS_STMT_USED This parameter returns the approximate number of bytes of heap and lookaside memory used by all prepared statements associated with the database connection. +(source: c3ref/c_dbstatus_options.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-42511-39459-28264-29563-43720-13525-46264-32619
          +

          PRIMARY KEY, UNIQUE and NOT NULL constraints may be explicitly assigned a default conflict resolution algorithm by including a conflict-clause in their definitions. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-42511-45809-64803-32183-55869-46108-05938-14656
          +

          If the Y argument is omitted, trim(X) removes spaces from both ends of X. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-42531-52874-22459-56160-55887-19020-25957-01415
          +

          If the join-operator is a "LEFT JOIN" or "LEFT OUTER JOIN", then after the ON or USING filtering clauses have been applied, an extra row is added to the output for each row in the original left-hand input dataset that corresponds to no rows at all in the composite dataset (if any). +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-42555-53392-53053-11662-61855-46471-62332-42985
          +

          A time value can be in any of the following formats shown below. The value is usually a string, though it can be an integer or floating point number in the case of format 12. YYYY-MM-DD YYYY-MM-DD HH:MM YYYY-MM-DD HH:MM:SS YYYY-MM-DD HH:MM:SS.SSS YYYY-MM-DDTHH:MM YYYY-MM-DDTHH:MM:SS YYYY-MM-DDTHH:MM:SS.SSS HH:MM HH:MM:SS HH:MM:SS.SSS now DDDDDDDDDD +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-42556-20460-59163-07637-16181-08925-43211-33857
          +

          There can only be a single busy handler for a particular database connection at any given moment. If another busy handler was defined (using sqlite3_busy_handler()) prior to calling this routine, that other busy handler is cleared. +(source: c3ref/busy_timeout.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-42584-44456-56130-43487-49627-44255-00000-11489
          +

          To always truncate rollback journals and WAL files to their minimum size, set the journal_size_limit to zero. +(source: pragma.html, matrix: context, detail)

          + +
          R-42620-22184-27875-60566-02937-27650-15183-08626
          +

          If this means the parameter would be assigned a number greater than SQLITE_MAX_VARIABLE_NUMBER, it is an error. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-42639-56137-32346-60663-52828-48959-18769-50856
          +

          Each entry in most SQLite tables (except for WITHOUT ROWID tables) has a unique 64-bit signed integer key called the "rowid". +(source: c3ref/last_insert_rowid.html, checked-by: th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-42640-12758-34834-48042-16634-19699-19506-39894
          +

          For example, if the internal representation is FLOAT and a text result is requested, sqlite3_snprintf() is used internally to perform the conversion automatically. +(source: c3ref/column_blob.html, checked-by: th3/req1/column02.test, matrix: context, detail)

          + +
          R-42648-01192-24711-57227-24478-04310-65154-26465
          +

          Notice that the type VARCHAR contains the string "CHAR" and is thus assigned TEXT affinity. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-42657-00400-11552-47738-28049-57819-30867-53665
          +

          If the integer at offset 52 is non-zero then it is the page number of the largest root page in the database file, the database file will contain ptrmap pages, and the mode must be either auto_vacuum or incremental_vacuum. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-42660-47528-56905-42571-24684-45816-05890-54288
          +

          A statement is judged to be complete if it ends with a semicolon token and is not a prefix of a well-formed CREATE TRIGGER statement. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-42670-46183-00438-39556-01982-63614-08671-47686
          +

          If the result is a numeric value then sqlite3_column_bytes16() uses sqlite3_snprintf() to convert that value to a UTF-16 string and returns the number of bytes in that string. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-42680-10017-09402-35540-35488-37864-08326-19321
          +

          The first host parameter has an index of 1, not 0. +(source: c3ref/bind_parameter_name.html, checked-by: th3/req1/bind04.test, matrix: context, detail)

          + +
          R-42714-29052-62793-36764-55594-49553-21277-61265
          +

          If N is greater than zero, then the analysis limit is set to N and subsequent ANALYZE commands will stop analyzing each index after it has examined approximately N rows. +(source: pragma.html, matrix: context, detail)

          + +
          R-42757-24221-43746-48434-02480-64556-26113-38051
          +

          The second parameter szExtra is a number of bytes of extra storage associated with each page cache entry. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-42776-35033-43191-08460-16792-47540-52989-38911
          +

          If an SQL function is nearly deterministic (which is to say, if it only rarely changes, like sqlite_version()) and it is used in an index that becomes corrupt, the corruption can be fixed by running REINDEX. +(source: deterministic.html, matrix: context, detail)

          + +
          R-42790-23372-13524-47335-35146-00064-12684-28505
          +

          The sqlite3_db_config() interface will return a non-zero error code if a discontinued or unsupported configuration option is invoked. +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-42798-04097-62077-21747-11472-32542-49000-45202
          +

          The leftmost SQL parameter has an index of 1. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-42811-40895-19437-55912-12563-37813-52753-07207
          +

          The real tables underlying the view are not modified (except possibly explicitly, by a trigger program). +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-42868-39706-29794-00885-30480-27776-00308-11610
          +

          In other words, the filename will be an absolute pathname, even if the filename used to open the database originally was a URI or relative pathname. +(source: c3ref/db_filename.html, checked-by: th3/cov1/attach04.test, matrix: context, detail)

          + +
          R-42881-44982-56235-44486-35660-20338-31764-62780
          +

          The name of the table to be modified in an UPDATE, DELETE, or INSERT statement must be an unqualified table name. In other words, one must use just "tablename" not "database.tablename" when specifying the table. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-42924-00638-21387-26968-40165-13268-56405-46606
          +

          The current implementation only uses the lower 31 bits of the N value - higher order bits are silently ignored. Future versions of SQLite might begin using higher order bits. +(source: pragma.html, matrix: context, detail)

          + +
          R-42938-07030-34028-51732-04227-55156-04511-38808
          +

          If this means the parameter number is greater than SQLITE_MAX_VARIABLE_NUMBER, it is an error. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-42967-40755-03922-54202-06529-32553-15493-34553
          +

          Each term of aOrderBy records a column of the ORDER BY clause. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-42990-60904-19508-54128-30417-12976-04052-35475
          +

          The void pointer that is the second argument to SQLITE_CONFIG_LOG is passed through as the first parameter to the application-defined logger function whenever that function is invoked. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/log01.test, matrix: context, detail)

          + +
          R-42999-28458-07893-62789-61417-10043-42121-06014
          +

          The sqlite3_strglob(P,X) interface returns zero if and only if string X matches the GLOB pattern P. +(source: c3ref/strglob.html, checked-by: th3/cov1/glob01.test, matrix: context, detail)

          + +
          R-43036-46756-34715-46322-50618-48036-10639-21553
          +

          If "ro" is specified, then the database is opened for read-only access, just as if the SQLITE_OPEN_READONLY flag had been set in the third argument to sqlite3_open_v2(). +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-43040-62530-50072-37699-18765-48451-48404-22344
          +

          The text of the child CREATE TABLE statement or statements stored in the sqlite_schema table are modified to reflect the new parent table name. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys21.test, matrix: context, detail)

          + +
          R-43042-22504-56439-09446-23422-01554-61314-54021
          +

          No error messages are generated if an unknown pragma is issued. +(source: pragma.html, checked-by: th3/req1/pragma03.test, matrix: context, detail)

          + +
          R-43042-25245-03668-43553-25952-57766-42536-13209
          +

          If the mode option is set to "memory" then a pure in-memory database that never reads or writes from disk is used. +(source: c3ref/open.html, checked-by: th3/cov1/sharedcache03.test, matrix: context, detail)

          + +
          R-43058-16959-43788-45364-39792-51782-37660-38644
          +

          The amount of space allocated by sqlite3_aggregate_context(C,N) is determined by the N parameter on first successful call. Changing the value of N in any subsequent call to sqlite3_aggregate_context() within the same aggregate function instance will not resize the memory allocation. +(source: c3ref/aggregate_context.html, checked-by: th3/req1/aggcntx01.test, matrix: context, detail)

          + +
          R-43060-16536-10698-60756-41285-15374-61767-21299
          +

          The profile callback time is in units of nanoseconds, however the current implementation is only capable of millisecond resolution so the six least significant digits in the time are meaningless. +(source: c3ref/profile.html, checked-by: th3/cov1/main16.test, matrix: context, detail)

          + +
          R-43064-28843-60545-11344-25729-47633-22876-03755
          +

          For each table read by the query, the output of EXPLAIN QUERY PLAN includes a record for which the value in the "detail" column begins with either "SCAN" or "SEARCH". +(source: eqp.html, matrix: context, detail)

          + +
          R-43076-48302-39117-06885-40232-30421-32965-23901
          +

          The sqlite3_extended_result_codes() routine enables or disables the extended result codes feature of SQLite. +(source: c3ref/extended_result_codes.html, checked-by: th3/cov1/main06.test, matrix: context, detail)

          + +
          R-43156-15813-49564-25791-10742-05152-48657-05796
          +

          The SQLITE_FCNTL_BUSYHANDLER file-control may be invoked by SQLite on the database file handle shortly after it is opened in order to provide a custom VFS with access to the connection's busy-handler callback. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-43164-44276-05448-08571-37890-01247-49300-00926
          +

          If there is no prefix that can be interpreted as an integer number, the result of the conversion is 0. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-43172-64399-63789-05300-15599-35833-47014-02400
          +

          The 4-byte big-endian integer at offset 68 is an "Application ID" that can be set by the PRAGMA application_id command in order to identify the database as belonging to or associated with a particular application. +(source: fileformat2.html, checked-by: th3/req1/fileformat03.test, matrix: context, detail)

          + +
          R-43190-62442-20010-51227-34344-19852-62865-03762
          +

          In other words, the schema-name. prefix on the table name of the UPDATE is not allowed within triggers. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-43217-29904-47266-41497-40047-57138-51637-14307
          +

          This routine returns the N-th compile-time option used to build SQLite or NULL if N is out of range. +(source: lang_corefunc.html, checked-by: th3/cov1/ctime02.test, matrix: context, detail)

          + +
          R-43230-40115-50366-23982-20450-64068-63336-08552
          +

          Any process or thread can select READ UNCOMMITTED isolation, but SERIALIZABLE will still be used except between connections that share a common page and schema cache. +(source: pragma.html, matrix: context, detail)

          + +
          R-43237-50879-06987-12679-64583-33041-22126-56366
          +

          If the database schema changes, instead of returning SQLITE_SCHEMA as it always used to do, sqlite3_step() will automatically recompile the SQL statement and try to run it again. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare02.test, matrix: context, detail)

          + +
          R-43249-19882-52899-37517-44560-32908-46536-34852
          +

          The third through sixth parameters to the callback are either NULL pointers or zero-terminated strings that contain additional details about the action to be authorized. +(source: c3ref/set_authorizer.html, checked-by: src/auth.c, th3/cov1/auth05.test, matrix: context, detail)

          + +
          R-43263-13491-37815-28347-01820-41692-00359-07852
          +

          The total number of bytes in all fragments is stored in the fifth field of the b-tree page header. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-43273-35828-43292-36541-60340-59124-40866-23243
          +

          Because the source database is not locked between calls to sqlite3_backup_step(), the source database may be modified mid-way through the backup process. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-43309-20049-45767-17244-13943-35472-42649-06268
          +

          If there is no INTEGER PRIMARY KEY column, then the outputs for the rowid are set as follows: data type: "INTEGER" collation sequence: "BINARY" not null: 0 primary key: 1 auto increment: 0 +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-43310-35438-04399-12485-38547-48138-39815-28430
          +

          The ORDER BY and LIMIT clauses on UPDATE and DELETE statements are not supported. ORDER BY and LIMIT are not normally supported for UPDATE or DELETE in any context but can be enabled for top-level statements using the SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option. However, that compile-time option only applies to top-level UPDATE and DELETE statements, not UPDATE and DELETE statements within triggers. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-43316-37308-43115-39313-41984-23156-09755-42929
          +

          A value of 2 (0x02) means the page is an interior index b-tree page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-43323-52188-61316-01603-51862-46847-20290-63862
          +

          The RETURNING clause cannot be used by statements within triggers. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-43328-56724-38269-63059-47788-20047-48832-13506
          +

          If a column has the type INTEGER PRIMARY KEY AUTOINCREMENT then a slightly different ROWID selection algorithm is used. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-43340-55464-08586-38170-34053-21521-23708-51540
          +

          The database header also stores the page number of the first freelist trunk page as a 4-byte big-endian integer at an offset of 32 from the beginning of the file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-43363-59092-12659-08651-39134-62372-15667-15588
          +

          If aConstraintUsage[].omit is true, then the constraint is assumed to be fully handled by the virtual table and might not be checked again by the byte code. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-43366-61198-05845-57681-29417-64282-40524-45626
          +

          SQLite will then manage the lifetime of its private copy. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-43382-54865-31574-52044-42032-61533-34154-44077
          +

          Each SQL index, whether explicitly declared via a CREATE INDEX statement or implied by a UNIQUE or PRIMARY KEY constraint, corresponds to an index b-tree in the database file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-43399-09409-02985-19756-28234-54022-20282-22241
          +

          This means that if the changes() SQL function (or similar) is used by the first INSERT, UPDATE or DELETE statement within a trigger, it returns the value as set when the calling statement began executing. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-43412-05248-04352-15247-64896-14746-56138-24199
          +

          SQLITE_DBSTATUS_LOOKASIDE_USED This parameter returns the number of lookaside memory slots currently checked out. +(source: c3ref/c_dbstatus_options.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-43412-16016-07613-58418-19222-63413-27211-48074
          +

          The column has a UNIQUE constraint. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-43415-05262-05879-65095-11903-46844-51636-40644
          +

          The filename argument is interpreted as UTF-8 for sqlite3_open() and sqlite3_open_v2() and as UTF-16 in the native byte order for sqlite3_open16(). +(source: c3ref/open.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-43433-49136-61285-59919-49849-25550-47556-02276
          +

          Transactions can be DEFERRED, IMMEDIATE, or EXCLUSIVE. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-43442-30789-40705-27465-13407-54814-56874-21617
          +

          SQLITE_STATUS_SCRATCH_OVERFLOW No longer used. SQLITE_STATUS_SCRATCH_SIZE No longer used. SQLITE_STATUS_PARSER_STACK The *pHighwater parameter records the deepest parser stack. The *pCurrent value is undefined. The *pHighwater value is only meaningful if SQLite is compiled with YYTRACKMAXSTACKDEPTH. +(source: c3ref/c_status_malloc_count.html, matrix: context, detail)

          + +
          R-43443-20296-62064-61017-62025-48147-54408-20485
          +

          SQLITE_PREPARE_PERSISTENT The SQLITE_PREPARE_PERSISTENT flag is a hint to the query planner that the prepared statement will be retained for a long time and probably reused many times. +(source: c3ref/c_prepare_normalize.html, matrix: context, detail)

          + +
          R-43448-12354-12620-62746-36446-48855-45456-57112
          +

          When there are attached databases and no database is specified in the pragma, all databases have their secure-delete setting altered. +(source: pragma.html, checked-by: th3/cov1/pragma20.test, th3/cov1/pragma21.test, matrix: context, detail)

          + +
          R-43455-30330-13340-63618-42639-11266-34972-33026
          +

          The main and temp databases cannot be attached or detached. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-43464-09689-21831-49515-17205-20394-62676-59001
          +

          The likely(X) function is a no-op that the code generator optimizes away so that it consumes no CPU cycles at run-time (that is, during calls to sqlite3_step()). +(source: lang_corefunc.html, checked-by: tcl/func3.test, matrix: context, detail)

          + +
          R-43475-58499-15568-06638-27533-08364-56193-27126
          +

          SQLite avoids reading or writing freelist leaf pages in order to reduce disk I/O. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-43482-09713-62461-41415-00231-20987-55224-61145
          +

          In this mode the VACUUM command can be used to rebuild the entire database file and thus reclaim unused disk space. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-43492-30972-07405-10322-20447-24571-17673-28262
          +

          Similarly, index columns will not normally be used (for indexing purposes) if they are to the right of a column that is constrained only by inequalities. +(source: optoverview.html, matrix: context, detail)

          + +
          R-43520-58856-06723-52893-53353-04776-19721-26256
          +

          The MEMORY journaling mode stores the rollback journal in volatile RAM. +(source: pragma.html, checked-by: th3/req1/pragma25.test, matrix: context, detail)

          + +
          R-43521-55927-08457-46227-28920-39349-41728-53227
          +

          If the right-hand side is a parameter that is bound to a string, then this optimization is only attempted if the prepared statement containing the expression was compiled with sqlite3_prepare_v2() or sqlite3_prepare16_v2(). +(source: optoverview.html, matrix: context, detail)

          + +
          R-43522-35548-12073-03111-59330-30466-17240-55087
          +

          Casting a value to a type-name with no affinity causes the value to be converted into a BLOB. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-43573-23448-48051-43416-34138-28993-49586-17736
          +

          A SELECT statement enclosed in parentheses is a subquery. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-43589-15127-43886-39082-32655-09009-64323-07852
          +

          The sqlite3_mutex_free() routine deallocates a previously allocated dynamic mutex. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-43609-64396-32492-00883-25685-46145-60531-30223
          +

          The application wants to prevent other processes from accessing the database file. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-43620-20913-52855-36210-21307-33610-27291-15644
          +

          Only an effective call to sqlite3_shutdown() does any deinitialization. All other valid calls to sqlite3_shutdown() are harmless no-ops. +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-43634-32029-21276-39122-52064-20443-35317-63823
          +

          The "utc" modifier is the opposite of "localtime". "utc" assumes that the time value to its left is in the local timezone and adjusts that time value to be in UTC. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-43641-06233-62582-50959-46555-19334-21762-55443
          +

          Generated columns may not be used as part of the PRIMARY KEY. +(source: gencol.html, matrix: context, detail)

          + +
          R-43642-56306-35814-07631-25075-47179-35702-00473
          +

          By default, URI handling is globally disabled. The default value may be changed by compiling with the SQLITE_USE_URI symbol defined. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/global.c, matrix: context, detail)

          + +
          R-43646-40507-46737-61854-04250-53447-25357-32059
          +

          The checksum is an unsigned 32-bit integer computed as follows: Initialize the checksum to the checksum nonce value found in the journal header at offset 12. Initialize index X to be N-200 (where N is the size of a database page in bytes. Interpret the byte at offset X into the page as an 8-bit unsigned integer and add the value of that integer to the checksum. Subtract 200 from X. If X is greater than or equal to zero, go back to step 3. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-43689-60751-17173-17363-04961-34787-47888-07177
          +

          SQLITE_DBSTATUS_CACHE_SPILL This parameter returns the number of dirty cache entries that have been written to disk in the middle of a transaction due to the page cache overflowing. Transactions are more efficient if they are written to disk all at once. When pages spill mid-transaction, that introduces additional overhead. This parameter can be used help identify inefficiencies that can be resolved by increasing the cache size. SQLITE_DBSTATUS_DEFERRED_FKS This parameter returns zero for the current value if and only if all foreign key constraints (deferred or immediate) have been resolved. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-43693-30522-63226-58235-18305-62021-52549-18888
          +

          If the expression is the alias of a table or subquery in the FROM clause followed by ".*" then all columns from the named table or subquery are substituted for the single expression. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-43696-56835-52509-34515-30380-28351-43291-45019
          +

          If a term of the form "6=b" appears in the index, it will never match anything. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-43700-31930-54080-27091-31266-57199-30903-39458
          +

          The sqlite_sequence table is created and initialized automatically whenever a normal table that contains an AUTOINCREMENT column is created. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-43713-34954-61284-51343-43182-28146-52130-40042
          +

          The xMutexEnd method defined by this structure is invoked as part of system shutdown by the sqlite3_shutdown() function. +(source: c3ref/mutex_methods.html, matrix: context, detail)

          + +
          R-43737-39999-60785-41458-46023-21259-00950-21702
          +

          Every valid SQLite database file begins with the following 16 bytes (in hex): 53 51 4c 69 74 65 20 66 6f 72 6d 61 74 20 33 00. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-43753-41505-35386-09439-04210-20192-61863-65048
          +

          For an index, the tbl_name is the name of the table that is indexed. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-43754-40546-54172-00360-10157-15070-11211-43243
          +

          The SQLITE_TRACE_PROFILE callback is invoked when the statement finishes. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-43797-56749-02967-54481-29642-02482-32480-02233
          +

          In NORMAL locking-mode (the default unless overridden at compile-time using SQLITE_DEFAULT_LOCKING_MODE), a database connection unlocks the database file at the conclusion of each read or write transaction. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-43820-61705-52813-55767-43715-42880-00775-50924
          +

          The purpose of the unlikely(X) function is to provide a hint to the query planner that the argument X is a boolean value that is usually not true. +(source: lang_corefunc.html, checked-by: th3/cov1/where42.test, matrix: context, detail)

          + +
          R-43823-35025-00176-30164-46726-64409-48434-13396
          +

          The schema cookie is a 4-byte big-endian integer at offset 40 that is incremented whenever the database schema changes. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-43833-46001-07535-07747-23355-16276-19014-45982
          +

          If idx is out of range - less than zero or greater than or equal to the total number of loops used to implement the statement - a non-zero value is returned and the variable that pOut points to is unchanged. +(source: c3ref/stmt_scanstatus.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-43879-08025-52526-08970-15750-21422-30684-37873
          +

          Attaching a "REFERENCES " clause to a column definition creates a foreign key constraint that maps the column to the primary key of . +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys09.test, matrix: context, detail)

          + +
          R-43881-23456-20563-20957-51474-28716-20128-57454
          +

          when sqlite3_reset() or sqlite3_finalize() is called for the SQL statement +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-43895-16198-12902-10668-43383-15391-26544-03216
          +

          When coercing a string value in the format of a hexadecimal integer into an integer value, the conversion process stops when the 'x' character is seen so the resulting integer value is always zero. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-43996-29471-48886-45304-51416-12121-07825-19150
          +

          SQLITE_LIMIT_COLUMN The maximum number of columns in a table definition or in the result set of a SELECT or the maximum number of columns in an index or in an ORDER BY or GROUP BY clause. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-44013-13102-10441-32146-65192-28233-37032-42173
          +

          The mode parameter may be set to either "ro", "rw", "rwc", or "memory". Attempting to set it to any other value is an error +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-44028-31666-03936-19748-14191-58058-00871-01668
          +

          The P parameter can be a NULL pointer. +(source: c3ref/randomness.html, checked-by: th3/cov1/random01.test, matrix: context, detail)

          + +
          R-44050-47362-62664-60634-46008-39199-23714-03291
          +

          If the SELECT statement is a non-aggregate query, then each expression in the result expression list is evaluated for each row in the dataset filtered by the WHERE clause. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-44053-64068-31529-32657-44606-24557-47766-35713
          +

          The subquery has a FROM clause. +(source: optoverview.html, matrix: context, detail)

          + +
          R-44062-08550-47406-04162-18234-03785-06690-48010
          +

          If a DELETE statement has a LIMIT clause, the maximum number of rows that will be deleted is found by evaluating the accompanying expression and casting it to an integer value. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-44114-07168-48628-58571-39460-30302-43731-62236
          +

          The first parameter is the database connection to which the SQL function is to be added. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, matrix: context, detail)

          + +
          R-44118-24115-09333-12766-04940-32044-13276-33930
          +

          Generated columns may not have a default value (they may not use the "DEFAULT" clause). +(source: gencol.html, matrix: context, detail)

          + +
          R-44130-32593-50612-23115-00910-25537-42820-39348
          +

          If an ORDER BY expression is not an integer alias, then SQLite searches the left-most SELECT in the compound for a result column that matches either the second or third rules above. If a match is found, the search stops and the expression is handled as an alias for the result column that it has been matched against. Otherwise, the next SELECT to the right is tried, and so on. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-44133-61651-41897-46315-46351-30200-24176-28474
          +

          The value Y in likelihood(X,Y) must be a floating point constant between 0.0 and 1.0, inclusive. +(source: lang_corefunc.html, checked-by: tcl/func3.test, matrix: context, detail)

          + +
          R-44155-30417-12865-55438-14349-49695-29873-16334
          +

          This query would result in a full table scan. +(source: optoverview.html, matrix: context, detail)

          + +
          R-44163-39688-38219-15448-17659-56666-21013-19183
          +

          The expression of a CHECK constraint may not contain a subquery. +(source: lang_createtable.html, matrix: context, detail)

          + +
          R-44190-32878-23725-35704-06982-10932-63377-41592
          +

          The returned string is always in UTF-8 encoding even if the named parameter was originally specified as UTF-16 in sqlite3_prepare16(), sqlite3_prepare16_v2(), or sqlite3_prepare16_v3(). +(source: c3ref/bind_parameter_name.html, checked-by: th3/req1/bind04.test, matrix: context, detail)

          + +
          R-44209-40260-17459-44675-20302-51345-49866-43242
          +

          If and only if the previously described conversion of OR to an IN operator does not work, the second OR-clause optimization is attempted. +(source: optoverview.html, matrix: context, detail)

          + +
          R-44223-43966-50481-12161-32962-54841-33868-44497
          +

          If there are no non-NULL input rows then sum() returns NULL but total() returns 0. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-44241-31306-56883-60998-04220-09447-33322-42012
          +

          Any existing statements prepared using the legacy sqlite3_prepare() interface may fail with an SQLITE_SCHEMA error after the recursive_triggers setting is changed. +(source: pragma.html, matrix: context, detail)

          + +
          R-44252-06035-10062-38462-00454-12973-27157-29991
          +

          The subquery does not use LIMIT or the outer query is not a join. +(source: optoverview.html, matrix: context, detail)

          + +
          R-44261-39702-04875-31790-36524-45169-57836-16173
          +

          Foreign key constraints are disabled by default (for backwards compatibility), so must be enabled separately for each database connection. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys04.test, matrix: context, detail)

          + +
          R-44270-63173-43365-51432-46246-26535-62506-06270
          +

          Both key and value may contain %HH escape sequences. +(source: uri.html, matrix: context, detail)

          + +
          R-44272-02265-45662-49730-44670-47137-63900-27537
          +

          However, SQLite will nest the loops in a different order if doing so will help it to select better indexes. +(source: optoverview.html, matrix: context, detail)

          + +
          R-44289-63209-61315-10942-18523-19279-36717-48244
          +

          If the authority is omitted then the path is required. +(source: uri.html, matrix: context, detail)

          + +
          R-44294-52863-08300-09780-12014-19647-27880-25111
          +

          The third parameter is the name of the database that was written to - either "main" or the name of an ATTACH-ed database. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-44295-13823-09058-27289-44091-57467-52153-35683
          +

          A transaction savepoint (a non-nested savepoint that was opened while there was not currently an open transaction), on the other hand, is subject to the same restrictions as a COMMIT - attempting to RELEASE it while the database is in such a state will fail. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys15.test, matrix: context, detail)

          + +
          R-44324-41166-42942-47705-27184-58566-20473-14339
          +

          It is also an error to use a "*" or "alias.*" expression in a simple SELECT query that does not have a FROM clause. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-44334-22485-53037-21261-43718-31016-47117-27643
          +

          date(time-value, modifier, modifier, ...) +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-44336-03155-46084-50304-15554-44543-05811-18658
          +

          Note also that the journal_mode cannot be changed while a transaction is active. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-44355-00270-30749-42094-52510-11222-59749-40119
          +

          The PRAGMA recursive_triggers setting does not affect the operation of foreign key actions. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys24.test, matrix: context, detail)

          + +
          R-44364-00581-20291-58587-51533-44159-46989-51099
          +

          For example: SELECT t1.a, t2.b FROM t2, (SELECT x+y AS a FROM t1 WHERE z<100) WHERE a>5 Would be rewritten using query flattening as: SELECT t1.x+t1.y AS a, t2.b FROM t2, t1 WHERE z<100 AND a>5 +(source: optoverview.html, matrix: context, detail)

          + +
          R-44381-11669-25586-00441-33187-20695-56764-33989
          +

          the expression 'a' LIKE 'A' is TRUE but 'æ' LIKE 'Æ' is FALSE. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-44382-28097-05870-38154-27344-49810-07099-20883
          +

          The second through fifth forms of this pragma set the encoding that the main database will be created with if it is created by this session. +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-44409-62641-17041-24104-11614-63008-35007-15423
          +

          The || operator is "concatenate" - it joins together the two strings of its operands. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-44414-54710-39878-46703-10464-52029-15490-53304
          +

          There is a row in the cartesian product dataset formed by combining each unique combination of a row from the left-hand and right-hand datasets. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-44424-47897-20192-49943-44571-25334-57312-32558
          +

          If the integer at offset 52 is zero then the integer at offset 64 must also be zero. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-44448-00687-59565-33416-30258-38835-37742-50898
          +

          The pUser and xDelUser members of the sqlite3_rtree_geometry structure are initially set to NULL. +(source: rtree.html, matrix: context, detail)

          + +
          R-44462-37635-62099-13453-38487-62317-50080-33351
          +

          SQLite will never invoke SQLITE_FCNTL_COMMIT_ATOMIC_WRITE without a prior successful call to SQLITE_FCNTL_BEGIN_ATOMIC_WRITE. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-44487-57903-51219-53037-61864-06803-55060-36082
          +

          The sqlite3_stmt_isexplain(S) interface returns 0 if S is an ordinary statement or a NULL pointer. +(source: c3ref/stmt_isexplain.html, matrix: context, detail)

          + +
          R-44492-58344-41928-11727-58799-16717-41714-60827
          +

          The purpose of the likely(X) function is to provide a hint to the query planner that the argument X is a boolean value that is usually true. +(source: lang_corefunc.html, checked-by: th3/cov1/where42.test, matrix: context, detail)

          + +
          R-44512-29500-51400-28317-41248-06688-48400-64915
          +

          If sqlite3_backup_step() has not yet returned SQLITE_DONE, then any active write-transaction on the destination database is rolled back. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-44544-27073-02924-52207-56870-56461-15432-54248
          +

          In cases where there exist loops with no available statistics, this function behaves as if the loop did not exist - it returns non-zero and leave the variable that pOut points to unchanged. +(source: c3ref/stmt_scanstatus.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-44557-40871-19236-56089-26171-47416-20797-60193
          +

          If the most recent evaluation of statement S failed, then sqlite3_finalize(S) returns the appropriate error code or extended error code. +(source: c3ref/finalize.html, checked-by: th3/req1/finalize01.test, matrix: context, detail)

          + +
          R-44582-60138-19271-50465-03257-36624-40089-31260
          +

          SQLite may from time to time reorganize a b-tree page so that there are no freeblocks or fragment bytes, all unused bytes are contained in the unallocated space region, and all cells are packed tightly at the end of the page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-44615-33286-13182-19247-40132-09732-39940-41262
          +

          The special identifiers only refer to the row key if the CREATE TABLE statement does not define a real column with the same name. +(source: lang_expr.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-44617-07829-03757-45608-53499-18988-55260-02741
          +

          The contents of the sqlite3_pcache_methods2 structure are copied to an internal buffer by SQLite within the call to sqlite3_config. Hence the application may discard the parameter after the call to sqlite3_config() returns. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-44624-50921-54896-40195-40598-14115-12715-41655
          +

          The PERSIST journaling mode prevents the rollback journal from being deleted at the end of each transaction. Instead, the header of the journal is overwritten with zeros. +(source: pragma.html, checked-by: th3/req1/pragma24.test, matrix: context, detail)

          + +
          R-44638-50196-46982-43265-31220-24766-09972-56099
          +

          However, some application may prefer a breadth-first search, which can be accomplished by setting rScore to mxLevel-iLevel. +(source: rtree.html, matrix: context, detail)

          + +
          R-44699-55558-27782-01179-44434-54573-03026-09570
          +

          The INDEXED BY clause does not give the optimizer hints about which index to use; it gives the optimizer a requirement of which index to use. +(source: lang_indexedby.html, checked-by: tcl/indexedby.test, matrix: context, detail)

          + +
          R-44699-57140-60647-60895-26603-26594-01750-63577
          +

          This mode works the same way as SQLITE_CHECKPOINT_RESTART with the addition that it also truncates the log file to zero bytes just prior to a successful return. +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/wal.c, tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-44709-33024-54980-17199-17128-51759-15220-29599
          +

          The DROP COLUMN command removes the named column from the table, and rewrites its content to purge the data associated with that column. +(source: lang_altertable.html, checked-by: th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-44743-26048-26164-09256-55055-05174-57916-33189
          +

          Generated columns may have NOT NULL, CHECK, and UNIQUE constraints, and foreign key constraints, just like ordinary columns. +(source: gencol.html, matrix: context, detail)

          + +
          R-44809-60674-55337-11812-63258-27949-26446-49308
          +

          SQLite will use the implementation that most closely matches the way in which the SQL function is used. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-44820-17227-57032-02316-25534-20387-01483-22879
          +

          The third parameter to the preupdate callback is one of the constants SQLITE_INSERT, SQLITE_DELETE, or SQLITE_UPDATE to identify the kind of update operation that is about to occur. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-44830-52899-50578-35713-22195-41858-55847-16818
          +

          *ppStmt is left pointing to a compiled prepared statement that can be executed using sqlite3_step(). +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-44835-24883-49938-43446-56074-23376-41868-21974
          +

          No reads or writes occur except within a transaction. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-44877-05564-55761-20700-41033-29591-21228-47309
          +

          Executing any other type of SQL statement does not modify the value returned by this function. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-44885-25196-65175-63597-64540-27010-19745-60174
          +

          Value is an 8-bit twos-complement integer. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-44890-03323-56789-62483-63880-22591-35189-31774
          +

          The output is the same as for PRAGMA table_info except that hidden columns are shown rather than being omitted. +(source: pragma.html, matrix: context, detail)

          + +
          R-44929-19675-50890-09843-10224-35620-29397-31048
          +

          The database connection returned by sqlite3_db_handle is the same database connection that was the first argument to the sqlite3_prepare_v2() call (or its variants) that was used to create the statement in the first place. +(source: c3ref/db_handle.html, checked-by: th3/req1/dbhandle01.test, matrix: context, detail)

          + +
          R-44931-31853-26224-06306-44467-24966-10617-31779
          +

          Universal Coordinated Time (UTC) is used. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-44988-41064-02279-18587-19747-40125-16068-53673
          +

          Rows are first sorted based on the results of evaluating the left-most expression in the ORDER BY list, then ties are broken by evaluating the second left-most expression and so on. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-44990-49065-20422-08324-27654-16812-49799-14821
          +

          SQLite invokes the xShrink() method when it wants the page cache to free up as much of heap memory as possible. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-44992-52812-59111-17856-46428-55199-28475-08004
          +

          SQLite prohibits applications from creating objects whose names begin with "sqlite_". +(source: fileformat2.html, matrix: context, detail)

          + +
          R-45001-15102-62824-43089-64558-18158-53977-55532
          +

          The first argument to these interfaces is a prepared statement. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-45003-07395-31947-31592-21927-23597-32015-06745
          +

          Autocommit mode is disabled by a BEGIN statement. +(source: c3ref/get_autocommit.html, matrix: context, detail)

          + +
          R-45034-43967-17911-30540-50129-42981-54712-01086
          +

          The following are examples of non-deterministic functions: random() changes() last_insert_rowid() sqlite3_version() +(source: deterministic.html, matrix: context, detail)

          + +
          R-45051-55006-15108-02545-65455-20416-20562-25495
          +

          The sqlite3_release_memory() interface attempts to free N bytes of heap memory by deallocating non-essential memory allocations held by the database library. +(source: c3ref/release_memory.html, checked-by: th3/req1/releasemem01.test, matrix: context, detail)

          + +
          R-45052-47506-16194-46831-63738-43272-24543-14451
          +

          When sqlite3_prepare_v2() is used to prepare a statement, the statement might be re-prepared during sqlite3_step() due to a schema change. +(source: c3ref/set_authorizer.html, matrix: context, detail)

          + +
          R-45058-52483-53751-35980-24819-54487-13131-07028
          +

          If the outer query is part of a compound select, then the subquery may not have a LIMIT clause. +(source: optoverview.html, matrix: context, detail)

          + +
          R-45075-05696-46728-36342-39076-34346-28499-29393
          +

          As an example of the result table format, suppose a query result is as follows: Name | Age ----------------------- Alice | 43 Bob | 28 Cindy | 21 There are two columns (M==2) and three rows (N==3). Thus the result table has 8 entries. Suppose the result table is stored in an array named azResult. Then azResult holds this content: azResult[0] = "Name"; azResult[1] = "Age"; azResult[2] = "Alice"; azResult[3] = "43"; azResult[4] = "Bob"; azResult[5] = "28"; azResult[6] = "Cindy"; azResult[7] = "21"; +(source: c3ref/free_table.html, checked-by: th3/req1/gettable01.test, matrix: context, detail)

          + +
          R-45087-11455-34010-58446-15384-63423-21176-52177
          +

          when the corresponding function parameter changes +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-45092-55768-62322-65360-04224-03075-32666-24560
          +

          If two or more such blocked connections have specified the same callback function, then instead of invoking the callback function multiple times, it is invoked once with the set of void* context pointers specified by the blocked connections bundled together into an array. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-45095-63572-26689-30740-64749-16083-48841-09127
          +

          When an applicable constraint violation occurs, the FAIL resolution algorithm aborts the current SQL statement with an SQLITE_CONSTRAINT error. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-45099-02601-54724-45407-56685-24152-16852-27215
          +

          Each subterm is analyzed as if it were itself the entire WHERE clause in order to see if the subterm is indexable by itself. +(source: optoverview.html, matrix: context, detail)

          + +
          R-45106-55778-23498-47099-45026-10871-39267-61418
          +

          The RELEASE of an inner transaction does not cause any changes to be written to the database file; it merely removes savepoints from the transaction stack such that it is no longer possible to ROLLBACK TO those savepoints. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-45162-11578-30985-60631-31894-17735-12127-52197
          +

          This mode is the same as calling the sqlite3_wal_checkpoint() C interface. +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-45164-23268-36240-53561-39664-08143-25092-01923
          +

          However if the trigger actions reference other tables, the trigger is not dropped or modified if those other tables are dropped or modified. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-45175-37688-08419-23660-35132-45148-11733-21680
          +

          If a WHEN clause is supplied, the SQL statements specified are only executed if the WHEN clause is true. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-45195-19773-08710-22098-44834-37724-61682-21963
          +

          The extended result codes are disabled by default for historical compatibility. +(source: c3ref/extended_result_codes.html, checked-by: th3/cov1/main06.test, matrix: context, detail)

          + +
          R-45200-50363-59708-20315-54778-07324-53392-01839
          +

          If the expression is not a column and has no COLLATE clause, then the BINARY collating sequence is used. +(source: datatype3.html, checked-by: th3/req1/datatype3_10.test, matrix: context, detail)

          + +
          R-45209-39960-61875-37751-41850-04754-65242-24219
          +

          The SQLITE_FCNTL_VFS_POINTER opcode finds a pointer to the top-level VFSes currently in use. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-45221-02523-04020-35318-02486-22619-25012-28682
          +

          This error code is not remembered and will not be recalled by sqlite3_errcode() or sqlite3_errmsg(). +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-45251-44035-31636-37177-08697-29378-39945-28652
          +

          When database is omitted, the "main" database is queried. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-45262-28997-10763-36487-00906-22281-55952-21771
          +

          SQLite will also add one of the following flags to the xOpen() call, depending on the object being opened: SQLITE_OPEN_MAIN_DB SQLITE_OPEN_MAIN_JOURNAL SQLITE_OPEN_TEMP_DB SQLITE_OPEN_TEMP_JOURNAL SQLITE_OPEN_TRANSIENT_DB SQLITE_OPEN_SUBJOURNAL SQLITE_OPEN_SUPER_JOURNAL SQLITE_OPEN_WAL +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-45318-21719-47167-32773-02041-53098-12990-64085
          +

          If any xEntryPoint() returns an error, the sqlite3_open(), sqlite3_open16(), or sqlite3_open_v2() call that provoked the xEntryPoint() will fail. +(source: c3ref/auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-45324-33155-04012-63035-54710-33706-56967-14745
          +

          The sqlite3_result_value() interface sets the result of the application-defined function to be a copy of the unprotected sqlite3_value object specified by the 2nd parameter. +(source: c3ref/result_blob.html, checked-by: th3/req1/result03.test, matrix: context, detail)

          + +
          R-45363-38948-33312-55000-36938-65231-54003-14501
          +

          If the sqlite_sequence.seq value for an AUTOINCREMENT table is manually set to something other than an integer and there is a subsequent attempt to insert the or update the AUTOINCREMENT table, then the behavior is undefined. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-45387-42504-16923-07908-20467-28557-08879-46075
          +

          A call to sqlite3_snapshot_open() will fail to open if the specified snapshot has been overwritten by a checkpoint. +(source: c3ref/snapshot_open.html, matrix: context, detail)

          + +
          R-45408-40694-64054-48639-23979-33510-40886-26968
          +

          Changes written into a BLOB prior to the BLOB expiring are not rolled back by the expiration of the BLOB. Such changes will eventually commit if the transaction continues to completion. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-45416-45177-17165-44236-63392-58604-16012-62044
          +

          The effect of the RETURNING clause is to cause the statement to return one result row for each database row that is deleted, inserted, or updated. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-45424-07352-14354-52803-50663-63365-62375-01898
          +

          If there is only a single table or subquery in the FROM clause, then the input data used by the SELECT statement is the contents of the named table. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-45424-59143-42887-56356-41413-49128-47927-21331
          +

          Modifiers are applied from left to right; order is important. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-45427-27134-18298-64328-24893-59331-19022-41786
          +

          If the third parameter to sqlite3_bind_text() is not NULL, then it should be a pointer to well-formed UTF8 text. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-45428-55355-50147-62692-64807-19630-14135-59274
          +

          In the example above, if column x has TEXT affinity then the comparison "x=5" will be done as text. The + operator removes the affinity. So the comparison "+x=5" will compare the text in column x with the numeric value 5 and will always be false. +(source: optoverview.html, matrix: context, detail)

          + +
          R-45440-25633-60928-38627-51174-16128-58812-25800
          +

          ORDER BY and LIMIT clauses may only occur at the end of the entire compound SELECT, and then only if the final element of the compound is not a VALUES clause. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-45441-43537-47777-63556-12740-30003-58169-32879
          +

          A single WAL can and usually does record multiple transactions. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-45488-08504-64399-03603-60147-65359-06274-60393
          +

          If the database schema contains foreign key errors that require looking at more than one table definition to identify, then those errors are not detected when the tables are created. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-45493-35653-32389-26460-18465-38474-56599-09288
          +

          A CHECK constraint may be attached to a column definition or specified as a table constraint. In practice it makes no difference. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-45509-34933-24347-37380-13828-03412-57306-45781
          +

          The CREATE, TABLE, VIEW, TRIGGER, and INDEX keywords at the beginning of the statement are converted to all upper case letters. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-45540-25505-12705-13417-45651-45483-56013-24623
          +

          To prevent older versions of SQLite (prior to version 3.7.0, 2010-07-22) from trying to recover a WAL-mode database (and making matters worse) the database file format version numbers (bytes 18 and 19 in the database header) are increased from 1 to 2 in WAL mode. +(source: wal.html, checked-by: tcl/e_wal.test, matrix: context, detail)

          + +
          R-45642-41863-02575-26055-57853-43447-11909-01929
          +

          If the optional schema name is omitted, "main" is assumed. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-45667-58607-22220-28108-32382-15512-20537-62688
          +

          If it does, then SQLite requires every entry in the index to be unique. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-45676-18204-05370-40567-50208-38360-04513-21756
          +

          If the sqlite3_create_function() interface is used to override the glob(X,Y) function with an alternative implementation then the GLOB operator will invoke the alternative implementation. +(source: lang_corefunc.html, checked-by: th3/req1/func02.test, matrix: context, detail)

          + +
          R-45725-33143-49569-42045-56416-09972-18063-04229
          +

          Note also that sqlite3_snprintf() returns a pointer to its buffer instead of the number of characters actually written into the buffer. +(source: c3ref/mprintf.html, checked-by: th3/req1/malloc01.test, matrix: context, detail)

          + +
          R-45728-08709-00373-57456-04392-57683-10379-45526
          +

          There are four columns in each result row. +(source: pragma.html, checked-by: tcl/fkey5.test, th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-45735-05060-45707-02597-62787-16150-27278-23647
          +

          The column may not have a PRIMARY KEY or UNIQUE constraint. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-45744-19146-21008-38057-12826-38180-64084-01618
          +

          The suppression of redundant columns in the key suffix of an index entry only occurs in WITHOUT ROWID tables. +(source: fileformat2.html, checked-by: th3/req1/fileformat04.test, matrix: context, detail)

          + +
          R-45764-31737-17057-32264-52283-10533-45215-02214
          +

          The INTERSECT operator returns the intersection of the results of the left and right SELECTs. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-45798-31769-08217-55662-19864-50738-55178-62419
          +

          The exclusive lock is not released until either sqlite3_backup_finish() is called or the backup operation is complete and sqlite3_backup_step() returns SQLITE_DONE. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-45820-61953-03602-28420-59065-19791-09856-58583
          +

          A correlated subquery is reevaluated each time its result is required. +(source: lang_expr.html, checked-by: th3/req1/select01.test, matrix: context, detail)

          + +
          R-45864-01884-48942-09518-31331-15179-06601-52827
          +

          On success, sqlite3_blob_write() returns SQLITE_OK. Otherwise, an error code or an extended error code is returned. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-45878-07697-09901-50980-47387-13868-52582-57913
          +

          If the REINDEX keyword is followed by a collation-sequence name, then all indices in all attached databases that use the named collation sequences are recreated. +(source: lang_reindex.html, checked-by: tcl/e_reindex.test, matrix: context, detail)

          + +
          R-45882-09372-45562-22355-27454-39457-08272-55277
          +

          SQL parameters of the form "?NNN" or ":AAA" or "@AAA" or "$AAA" have a name which is the string "?NNN" or ":AAA" or "@AAA" or "$AAA" respectively. In other words, the initial ":" or "$" or "@" or "?" is included as part of the name. +(source: c3ref/bind_parameter_name.html, checked-by: th3/req1/bind04.test, matrix: context, detail)

          + +
          R-45883-43943-57871-65431-07060-17806-58519-01354
          +

          The second form changes the journaling mode for "database" or for all attached databases if "database" is omitted. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-45889-48790-57472-62779-24530-49470-03633-17983
          +

          The database, table and column on which the blob handle is open remain the same. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-45910-50363-25944-16530-55356-15445-20890-14687
          +

          The default setting can be overridden by each database connection using either the PRAGMA mmap_size command, or by using the SQLITE_FCNTL_MMAP_SIZE file control. +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-45939-02717-13913-16916-47597-06370-47114-21935
          +

          The randomblob(N) function return an N-byte blob containing pseudo-random bytes. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-45951-08347-03834-18503-21973-51666-50988-55652
          +

          if the declaration of a column with declared type "INTEGER" includes an "PRIMARY KEY DESC" clause, it does not become an alias for the rowid and is not classified as an integer primary key. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-45970-35618-54800-59485-17030-46204-37187-33805
          +

          Unlike this index_info pragma, this pragma returns information about every column in the index, not just the key columns. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-45981-25528-39449-05041-45662-56122-46761-09278
          +

          The fragment component of a URI, if present, is ignored. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-46053-13931-52012-22668-02470-26618-35785-45191
          +

          The sqlite3_progress_handler(D,N,X,P) interface causes the callback function X to be invoked periodically during long running calls to sqlite3_exec(), sqlite3_step() and sqlite3_get_table() for database connection D. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-46076-42323-06794-05495-00937-01913-04786-13791
          +

          The sqlite_stat3.nEq column holds the approximate number of entries in the index whose left-most column exactly matches the sample. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-46129-45598-36416-42008-62999-11143-15168-02813
          +

          The rowid can be used anywhere a regular column can be used. +(source: lang_expr.html, matrix: context, detail)

          + +
          R-46130-13641-40955-08660-38234-32467-56742-20127
          +

          However, since SQLite version 3.35.0, TEMP views are still allowed even if this option is off. So, in other words, this option now only disables views in the main database schema or in the schemas of ATTACH-ed databases. +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/cov1/view02.test, matrix: context, detail)

          + +
          R-46155-47219-10347-23082-03363-55795-00922-50884
          +

          If the expression evaluates to a NULL value or any other value that cannot be losslessly converted to an integer, an error is returned. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-46193-28368-58972-00027-31729-34447-02569-47363
          +

          sqlite> CREATE INDEX i2 ON t1(a, b); sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; QUERY PLAN `--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) +(source: eqp.html, matrix: context, detail)

          + +
          R-46197-42811-45122-27334-03540-14095-05781-43695
          +

          This means that the underlying VFS must support the "version 2" shared-memory. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-46199-30249-53951-48405-44359-44625-30943-37142
          +

          SQLite guarantees that the second argument to xRealloc is always a value returned by a prior call to xRoundup. +(source: c3ref/mem_methods.html, checked-by: src/malloc.c, src/mem1.c, src/mem2.c, src/mem5.c, matrix: context, detail)

          + +
          R-46221-33909-22471-18212-13524-55885-62727-63389
          +

          International character sets are case sensitive in SQLite unless an application-defined collating sequence and like() SQL function are provided that take non-ASCII characters into account. +(source: optoverview.html, checked-by: th3/cov1/pragma02.test, matrix: context, detail)

          + +
          R-46234-61323-27035-49381-04828-37598-41286-52895
          +

          If the path does not begin with a '/' (meaning that the authority section is omitted from the URI) then the path is interpreted as a relative path. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-46256-57243-24322-24814-28812-31567-52831-61261
          +

          There is no difference between the "INNER JOIN", "JOIN" and "," join operators. +(source: lang_select.html, checked-by: tcl/e_select.test, tcl/e_select2.test, matrix: context, detail)

          + +
          R-46291-22228-33337-03438-09062-41936-26465-59313
          +

          The UPDATE, DELETE, and INSERT statements within triggers do not support the full syntax for UPDATE, DELETE, and INSERT statements. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-46334-60999-49221-04702-27230-06175-42868-32331
          +

          The file named by the INTO clause must not previously exist, or else it must be an empty file, or the VACUUM INTO command will fail with an error. +(source: lang_vacuum.html, checked-by: th3/cov1/vacuum10.test, matrix: context, detail)

          + +
          R-46380-62105-49403-51977-53564-35485-34919-25717
          +

          This interface allows the size of various constructs to be limited on a connection by connection basis. The first parameter is the database connection whose limit is to be set or queried. The second parameter is one of the limit categories that define a class of constructs to be size limited. The third parameter is the new limit for that construct. +(source: c3ref/limit.html, checked-by: th3/req1/limit01.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-46397-11150-35825-03689-51879-43855-50852-63161
          +

          The second parameter is the column number. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-46413-56591-19010-63234-29028-02870-41994-21141
          +

          The checksum values are always stored in the frame header in a big-endian format regardless of which byte order is used to compute the checksum. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-46421-32541-46392-23903-65246-33066-39018-41515
          +

          Or, if X and Y are both BLOBs, then instr(X,Y) returns one more than the number bytes prior to the first occurrence of Y, or 0 if Y does not occur anywhere within X. +(source: lang_corefunc.html, checked-by: tcl/instr.test, matrix: context, detail)

          + +
          R-46455-06721-25633-38567-39133-09580-16982-03702
          +

          A partial index definition may include the UNIQUE keyword. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-46475-65007-45296-37609-03818-24981-55908-33234
          +

          The expression "a BETWEEN b AND c" is treated as two separate binary comparisons "a >= b AND a <= c", even if that means different affinities are applied to 'a' in each of the comparisons. +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-46487-45214-33132-22408-46065-05189-04922-26668
          +

          The memory-mapped file is in the same directory as the database and has the same name as the database with a "-shm" suffix appended. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-46513-12418-39442-33008-36450-21417-18357-12067
          +

          To delete an existing SQL function or aggregate, pass NULL pointers for all three function callbacks. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc03.test, matrix: context, detail)

          + +
          R-46542-01490-05241-30409-15162-63986-32317-12249
          +

          The SQLITE_FCNTL_WIN32_AV_RETRY opcode is used to configure automatic retry counts and intervals for certain disk I/O operations for the windows VFS in order to provide robustness in the presence of anti-virus programs. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-46605-62546-04930-07815-45981-57271-29937-28077
          +

          The special "*" expression expands into a list of all non-hidden columns of the table being deleted, inserted, or updated. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-46612-63606-63989-00465-43025-33740-12303-63068
          +

          Note that min() is a simple function when it has 2 or more arguments but operates as an aggregate function if given only a single argument. +(source: lang_corefunc.html, checked-by: th3/req1/func05.test, matrix: context, detail)

          + +
          R-46616-26780-52699-16900-61811-04122-03606-62757
          +

          When an error occurs, sqlite3_step() will return one of the detailed error codes or extended error codes. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare03.test, matrix: context, detail)

          + +
          R-46619-65417-10138-19214-14415-00475-28219-65444
          +

          The first column is always a 64-bit signed integer primary key. +(source: rtree.html, matrix: context, detail)

          + +
          R-46643-08949-52505-46852-59994-03587-15582-21793
          +

          Some parameters do not record the highest value. For those parameters nothing is written into *pHighwater and the resetFlag is ignored. +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-46649-58537-03180-36291-48705-13434-30415-43306
          +

          It is not possible to enable or disable foreign key constraints in the middle of a multi-statement transaction (when SQLite is not in autocommit mode). Attempting to do so does not return an error; it simply has no effect. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys06.test, matrix: context, detail)

          + +
          R-46656-45156-45910-65271-53395-31310-28369-14407
          +

          The sqlite3_version[] string constant contains the text of SQLITE_VERSION macro. +(source: c3ref/libversion.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-46672-40841-59774-15416-63280-30428-42891-05941
          +

          When not in shared cache mode, it is possible to have the same database file attached multiple times using different names, and detaching one connection to a file will leave the others intact. +(source: lang_detach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-46677-03283-38607-60635-61745-23618-46045-62138
          +

          If no database name qualifier precedes the "locking_mode" keyword then the locking mode is applied to all databases, including any new databases added by subsequent ATTACH commands. +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-46702-22190-08999-08775-06967-16190-65475-37101
          +

          Databases created by the ATTACH command always use the same encoding as the main database. +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-46709-29000-19476-32067-18840-61551-53618-60985
          +

          Let M be ((U-12)*32/255)-23 and let K be M+((P-M)%(U-4)). If P is greater than X then the number of bytes stored on the index b-tree page is K if K is less than or equal to X or M otherwise. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-46731-08965-36580-59849-15689-59530-23694-02071
          +

          The column is indexed. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-46762-41357-02891-26535-53181-26230-38926-40574
          +

          The schema-name is the name of an ATTACH-ed database or "main" or "temp" for the main and the TEMP databases. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-46765-43362-55332-05088-06369-35446-43155-35174
          +

          For the purposes of determining duplicate rows for the results of compound SELECT operators, NULL values are considered equal to other NULL values and distinct from all non-NULL values. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-46780-34130-42515-13535-26112-08732-08829-27411
          +

          This is the number of virtual machine operations executed by the prepared statement if that number is less than or equal to 2147483647. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-46798-18657-50742-54084-49745-39581-20744-29339
          +

          SQLITE_STATUS_PAGECACHE_OVERFLOW This parameter returns the number of bytes of page cache allocation which could not be satisfied by the SQLITE_CONFIG_PAGECACHE buffer and where forced to overflow to sqlite3_malloc(). The returned value includes allocations that overflowed because they where too large (they were larger than the "sz" parameter to SQLITE_CONFIG_PAGECACHE) and allocations that overflowed because no space was left in the page cache. +(source: c3ref/c_status_malloc_count.html, matrix: context, detail)

          + +
          R-46798-50301-48995-28285-56174-19296-23504-21814
          +

          The sqlite3_context_db_handle() interface returns a copy of the pointer to the database connection (the 1st parameter) of the sqlite3_create_function() and sqlite3_create_function16() routines that originally registered the application defined function. +(source: c3ref/context_db_handle.html, checked-by: src/vdbeapi.c, th3/req1/value01.test, matrix: context, detail)

          + +
          R-46863-28786-21721-60077-48835-05844-55823-37833
          +

          The current value of the requested parameter is written into *pCur and the highest instantaneous value is written into *pHiwtr. +(source: c3ref/db_status.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-46875-36446-38498-63657-23480-31614-51411-31350
          +

          The sqlite3_strlike(P,X,E) interface returns zero if and only if string X matches the LIKE pattern P with escape character E. +(source: c3ref/strlike.html, matrix: context, detail)

          + +
          R-46912-28798-53031-38709-36895-29366-07860-41608
          +

          Any attempt to use AUTOINCREMENT on a WITHOUT ROWID table or on a column other than the INTEGER PRIMARY KEY column results in an error. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-46931-43245-47331-55287-00929-39790-16947-25937
          +

          DEFERRED means that the transaction does not actually start until the database is first accessed. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-46934-63022-13283-12249-18112-11687-53025-24870
          +

          If an INSERT occurs within a trigger then this routine will return the rowid of the inserted row as long as the trigger is running. Once the trigger program ends, the value returned by this routine reverts to what it was before the trigger was fired. +(source: c3ref/last_insert_rowid.html, matrix: context, detail)

          + +
          R-46937-57672-41895-41327-41182-38354-24563-01052
          +

          Objects of this type are created by sqlite3_blob_open() and destroyed by sqlite3_blob_close(). +(source: c3ref/blob.html, checked-by: th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-46991-00459-32284-17616-36879-21143-59661-33845
          +

          Instead, executing an INSERT, DELETE or UPDATE on the view causes the associated triggers to fire. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-47032-28289-44184-46595-09836-48485-53901-64968
          +

          A database connection handle is usually returned in *ppDb, even if an error occurs. The only exception is that if SQLite is unable to allocate memory to hold the sqlite3 object, a NULL will be written into *ppDb instead of a pointer to the sqlite3 object. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-47045-23194-06320-38835-32835-03422-03688-60752
          +

          Input text that looks like floating point (there is a decimal point and/or an exponent) and the text describes a value that can be losslessly converted back and forth between IEEE 754 64-bit float and a 51-bit signed integer, then the result is INTEGER. +(source: lang_expr.html, checked-by: tcl/e_expr.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-47080-02069-19289-28177-02416-33406-46082-01364
          +

          If an "ALTER TABLE ... RENAME TO" command is used to rename a table that is the parent table of one or more foreign key constraints, the definitions of the foreign key constraints are modified to refer to the parent table by its new name +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys21.test, matrix: context, detail)

          + +
          R-47085-17460-48136-50298-50839-31630-41230-33764
          +

          PRAGMA cell_size_check PRAGMA cell_size_check = boolean; The cell_size_check pragma enables or disables additional sanity checking on database b-tree pages as they are initially read from disk. +(source: pragma.html, matrix: context, detail)

          + +
          R-47106-26961-22018-10007-09993-39383-21640-46039
          +

          The sqlite3_backup object may be used with the sqlite3_backup_step() and sqlite3_backup_finish() functions to perform the specified backup operation. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-47112-45289-11795-12854-05038-48584-59127-00440
          +

          Cautious programmers might include assert() statements in their application to verify that values returned by these interfaces match the macros in the header, and thus ensure that the application is compiled with matching library and header files. assert( sqlite3_libversion_number()==SQLITE_VERSION_NUMBER ); assert( strncmp(sqlite3_sourceid(),SQLITE_SOURCE_ID,80)==0 ); assert( strcmp(sqlite3_libversion(),SQLITE_VERSION)==0 ); +(source: c3ref/libversion.html, checked-by: th3/th3main.c, matrix: context, detail)

          + +
          R-47125-14019-06302-35267-43761-08118-47718-40685
          +

          The "start of" modifiers (7 through 9) shift the date backwards to the beginning of the current month, year or day. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-47129-02844-42227-35202-45348-02049-58295-05636
          +

          The sqlite3_value returned is a protected sqlite3_value object even if the input is not. +(source: c3ref/value_dup.html, matrix: context, detail)

          + +
          R-47136-25746-15640-41932-06678-43823-40123-27757
          +

          This method can be used, for example, to add whitespace indentation. +(source: c3ref/str_append.html, matrix: context, detail)

          + +
          R-47175-52442-38801-17858-62181-59243-23138-32376
          +

          Invoking this pragma with an argument is equivalent to calling the sqlite3_wal_checkpoint_v2() C interface with a 3rd parameter corresponding to the argument: +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-47188-50799-37892-57634-15721-61381-60158-50947
          +

          The phrase "VALUES(expr-list-1),...,(expr-list-N)" means the same thing as "SELECT expr-list-1 UNION ALL ... UNION ALL SELECT expr-list-N". +(source: lang_select.html, checked-by: th3/cov1/select30.test, th3/req1/select02.test, matrix: context, detail)

          + +
          R-47208-15314-60187-26132-59357-10692-55881-38588
          +

          And the automatically generated ROWIDs are guaranteed to be monotonically increasing. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-47220-36599-18549-01728-06678-05877-60935-22906
          +

          The sqlite3_result_pointer(C,P,T,D) interface sets the result to an SQL NULL value, just like sqlite3_result_null(C), except that it also associates the host-language pointer P or type T with that NULL value such that the pointer can be retrieved within an application-defined SQL function using sqlite3_value_pointer(). +(source: c3ref/result_blob.html, checked-by: th3/cov1/bindptr01.test, th3/cov1/carray01.test, matrix: context, detail)

          + +
          R-47220-63683-02784-26430-33183-60835-28174-15820
          +

          The sqlite3_last_insert_rowid() function does not work for WITHOUT ROWID tables. +(source: withoutrowid.html, checked-by: tcl/lastinsert.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-47224-48532-62948-64824-54403-32645-39277-62522
          +

          When an applicable constraint violation occurs, the ABORT resolution algorithm aborts the current SQL statement with an SQLITE_CONSTRAINT error and backs out any changes made by the current SQL statement; but changes caused by prior SQL statements within the same transaction are preserved and the transaction remains active. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-47237-20641-51298-30597-19533-32249-45130-16580
          +

          The parameter N is the approximate number of virtual machine instructions that are evaluated between successive invocations of the callback X. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-47257-47871-22083-44604-28744-21660-36470-17217
          +

          Smaller scores are processed first. +(source: rtree.html, matrix: context, detail)

          + +
          R-47276-58266-57990-47507-55397-12547-44122-03404
          +

          Like SQLITE_CHECKPOINT_FULL, this mode blocks new database writer attempts while it is pending, but does not impede readers. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-47301-17448-04122-36354-45464-07871-26388-12045
          +

          String variables that contain text formatted like hexadecimal integers are not interpreted as hexadecimal integers when coercing the string value into an integer due to a CAST expression or for a column affinity transformation or prior to performing a numeric operation or for any other run-time conversions. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-47326-42054-43655-41302-10309-18227-37352-51087
          +

          No entry point will be called more than once for each database connection that is opened. +(source: c3ref/auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-47349-36088-56332-49361-27773-46509-28359-10620
          +

          The ifnull() function is equivalent to coalesce() with two arguments. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-47355-18032-54463-52994-47328-64569-52603-29032
          +

          The column is identified by the second, third and fourth parameters to this function. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-47358-05964-44521-01667-50829-29935-00197-29054
          +

          The sqlite3_data_count(P) routine returns 0 if the previous call to sqlite3_step(P) returned SQLITE_DONE. +(source: c3ref/data_count.html, matrix: context, detail)

          + +
          R-47362-07898-57690-63362-38950-19612-46458-01308
          +

          If the REINDEX keyword is not followed by a collation-sequence or database object identifier, then all indices in all attached databases are rebuilt. +(source: lang_reindex.html, checked-by: tcl/e_reindex.test, matrix: context, detail)

          + +
          R-47366-13741-55802-55490-13630-64665-63412-14686
          +

          If the option is unknown or SQLite is unable to set the option then this routine returns a non-zero error code. +(source: c3ref/config.html, matrix: context, detail)

          + +
          R-47371-54529-47056-05139-21545-30146-30084-29428
          +

          Unlike regular SQLite tables which can store data in a variety of datatypes and formats, the R*Tree rigidly enforce these storage types. +(source: rtree.html, matrix: context, detail)

          + +
          R-47394-08393-08013-46591-44142-56491-27088-03038
          +

          The like() function is used to implement the "Y LIKE X [ESCAPE Z]" expression. +(source: lang_corefunc.html, checked-by: th3/req1/func02.test, matrix: context, detail)

          + +
          R-47421-29468-64946-07771-42048-44217-36224-10277
          +

          If none of the arguments to min() define a collating function, then the BINARY collating function is used. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-47436-38935-17734-42324-42347-43578-49292-42564
          +

          The header of the rollback journal can be overwritten with invalid header text (for example, all zeros). +(source: fileformat2.html, matrix: context, detail)

          + +
          R-47446-42933-31518-33219-37380-53181-26111-02925
          +

          At most one preupdate hook may be registered at a time on a single database connection; each call to sqlite3_preupdate_hook() overrides the previous setting. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-47496-23053-18561-13621-46143-05639-50277-51479
          +

          If any input to sum() is neither an integer or a NULL then sum() returns a floating point value which might be an approximation to the true sum. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-47505-58569-20472-23148-40328-48365-60870-06508
          +

          The "PRAGMA data_version" value is unchanged for commits made on the same database connection. +(source: pragma.html, checked-by: tcl/pragma3.test, th3/cov1/pragma26.test, matrix: context, detail)

          + +
          R-47512-27714-00574-29870-48560-40440-32292-60340
          +

          An individual database connection D can reduce its maximum parameter number below the compile-time maximum using the sqlite3_limit(D, SQLITE_LIMIT_VARIABLE_NUMBER,...) interface. +(source: lang_expr.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-47543-32145-59149-48631-62108-17148-32947-37500
          +

          Or, if none of the WHEN expressions evaluate to a value equal to the base expression, the result of evaluating the ELSE expression, if any. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-47563-44180-26995-52116-57167-46758-14753-28295
          +

          An SQLITE_TRACE_PROFILE callback provides approximately the same information as is provided by the sqlite3_profile() callback. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-47608-56469-23173-27343-55331-44027-52555-65470
          +

          Any other value for the b-tree page type is an error. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-47612-45842-47349-09557-45633-42955-42013-27541
          +

          When casting a TEXT value to INTEGER, the longest possible prefix of the value that can be interpreted as an integer number is extracted from the TEXT value and the remainder ignored. +(source: lang_expr.html, checked-by: tcl/e_expr.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-47666-36489-24359-20436-03208-18550-24058-22275
          +

          To perform a backup operation: sqlite3_backup_init() is called once to initialize the backup, sqlite3_backup_step() is called one or more times to transfer the data between the two databases, and finally sqlite3_backup_finish() is called to release all resources associated with the backup operation. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup01.test, matrix: context, detail)

          + +
          R-47674-04435-43323-49671-63294-37647-53866-33040
          +

          When a database is in WAL mode, all connections to that database must use the WAL. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-47688-18802-24758-22650-17797-24943-61288-58043
          +

          The query string is divided into key/value pairs. +(source: uri.html, matrix: context, detail)

          + +
          R-47709-27231-29719-54015-39691-57688-49858-37109
          +

          The usual rules apply for selecting a collation sequence to compare text values. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-47730-38043-27274-49738-18176-22421-00022-64697
          +

          Recognized integer codes are of the form SQLITE_STATUS_.... +(source: c3ref/status.html, matrix: context, detail)

          + +
          R-47754-42489-63490-59015-30535-62379-17829-51875
          +

          If the main database has not already been created, then the value returned is the text encoding that will be used to create the main database, if it is created by this session. +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-47754-63122-64688-34803-40832-37059-61979-20469
          +

          If the busy callback is not NULL, then the callback might be invoked with two arguments. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-47794-27716-03685-35899-02913-62361-61931-61907
          +

          The right-most column that is used can employ inequalities. +(source: optoverview.html, matrix: context, detail)

          + +
          R-47838-03249-08993-49658-07257-31799-38437-20814
          +

          The column is named in a table or column CHECK constraint not associated with the column being dropped. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-47864-57952-52818-65192-57929-18923-19319-26072
          +

          The 's' character at the end of the modifier names is optional. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-47870-49110-06101-43911-08439-20961-63107-08637
          +

          The parent and sub-query may contain WHERE clauses. +(source: optoverview.html, matrix: context, detail)

          + +
          R-47871-25994-62051-30257-22396-55190-62622-00222
          +

          The second argument is the size of each lookaside buffer slot. +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-47901-33947-04080-30794-42855-09326-15418-05201
          +

          With one exception noted below, if a rowid table has a primary key that consists of a single column and the declared type of that column is "INTEGER" in any mixture of upper and lower case, then the column becomes an alias for the rowid. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-47913-44653-19019-51800-53744-51346-51796-57702
          +

          For example, the max() function with a single argument is an aggregate and the max() function with two or more arguments is a simple function. +(source: lang_expr.html, checked-by: th3/req1/func05.test, matrix: context, detail)

          + +
          R-47936-10044-12721-09990-49763-27309-53307-48514
          +

          Or, more generally: SELECT rowid FROM WHERE = :parent_key_value +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys10.test, matrix: context, detail)

          + +
          R-47952-62498-54054-51429-18050-07399-51898-49231
          +

          It is not possible to use the "ALTER TABLE ... ADD COLUMN" syntax to add a column that includes a REFERENCES clause, unless the default value of the new column is NULL. Attempting to do so returns an error. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys21.test, matrix: context, detail)

          + +
          R-47962-27004-38595-48890-59288-41835-42483-18817
          +

          In an RTREE virtual table, the first column always has a type affinity of INTEGER and all other data columns have a type affinity of NUMERIC. +(source: rtree.html, matrix: context, detail)

          + +
          R-48014-15694-55612-58237-43071-46388-26537-49429
          +

          sqlite> EXPLAIN QUERY PLAN SELECT a FROM t1 UNION SELECT c FROM t2; QUERY PLAN `--COMPOUND QUERY |--LEFT-MOST SUBQUERY | `--SCAN TABLE t1 USING COVERING INDEX i1 `--UNION USING TEMP B-TREE `--SCAN TABLE t2 USING COVERING INDEX i4 +(source: eqp.html, matrix: context, detail)

          + +
          R-48019-29352-09930-00922-22494-19242-19926-63915
          +

          Strings are surrounded by single-quotes with escapes on interior quotes as needed. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-48044-29703-58801-20879-03319-43155-48187-62436
          +

          Any triggers attached to the table are dropped from the database schema before the implicit DELETE FROM is executed, so this cannot cause any triggers to fire. +(source: lang_droptable.html, checked-by: th3/req1/droptable01.test, matrix: context, detail)

          + +
          R-48107-00250-26810-18282-01790-21926-12239-51218
          +

          The busy-handler is also invoked while waiting for database readers as described above. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-48118-34840-54112-17431-20305-06499-24777-65466
          +

          To convert the results of an SQL expression to a boolean value, SQLite first casts the result to a NUMERIC value in the same way as a CAST expression. A numeric zero value (integer value 0 or real value 0.0) is considered to be false. A NULL value is still NULL. All other values are considered true. +(source: lang_expr.html, checked-by: th3/req1/expr03.test, matrix: context, detail)

          + +
          R-48124-63225-09560-63618-32598-12840-01456-15525
          +

          A single foreign key constraint may have different actions configured for ON DELETE and ON UPDATE. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/pragma02.test, matrix: context, detail)

          + +
          R-48126-27717-31293-47858-22865-09722-12158-06374
          +

          The content of the statistics tables can be queried using SELECT and can be changed using the DELETE, INSERT, and UPDATE commands. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-48141-52334-41562-00713-04774-04609-31111-39049
          +

          If the DELETE statement has an ORDER BY clause, then all rows that would be deleted in the absence of the LIMIT clause are sorted according to the ORDER BY. The first M rows, where M is the value found by evaluating the OFFSET clause expression, are skipped, and the following N, where N is the value of the LIMIT expression, are deleted. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-48191-50425-24568-05066-49812-07872-47674-23180
          +

          A rollback journal is only considered to be valid if it exists and contains a valid header. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-48204-18881-64880-60099-58359-33874-53073-00752
          +

          Instead, the built-in Date And Time Functions of SQLite are capable of storing dates and times as TEXT, REAL, or INTEGER values: TEXT as ISO8601 strings ("YYYY-MM-DD HH:MM:SS.SSS"). REAL as Julian day numbers, the number of days since noon in Greenwich on November 24, 4714 B.C. according to the proleptic Gregorian calendar. INTEGER as Unix Time, the number of seconds since 1970-01-01 00:00:00 UTC. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-48205-43578-08481-37323-43342-53439-37471-23722
          +

          The default suggested cache size can be altered using the SQLITE_DEFAULT_CACHE_SIZE compile-time options. +(source: pragma.html, checked-by: src/sqliteLimit.h, matrix: context, detail)

          + +
          R-48230-36247-21230-47058-09870-51505-35285-11048
          +

          The special behaviors associated "INTEGER PRIMARY KEY" do not apply on WITHOUT ROWID tables. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-48245-15045-20041-46563-30518-58270-45669-62749
          +

          A filename that is not a well-formed URI is interpreted as an ordinary filename. +(source: uri.html, matrix: context, detail)

          + +
          R-48254-42943-07993-04131-52492-34370-46050-41806
          +

          This option is used to enable or disable the fts3_tokenizer() function which is part of the FTS3 full-text search engine extension. +(source: c3ref/c_dbconfig_defensive.html, matrix: context, detail)

          + +
          R-48270-44282-22791-02682-41212-30485-35514-10094
          +

          Foreign key ON DELETE and ON UPDATE clauses are used to configure actions that take place when deleting rows from the parent table (ON DELETE), or modifying the parent key values of existing rows (ON UPDATE). +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/pragma02.test, matrix: context, detail)

          + +
          R-48313-35799-57609-24734-64937-33072-43085-04424
          +

          The four-byte page number at offset 8 is the right-most pointer. This value appears in the header of interior b-tree pages only and is omitted from all other pages. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-48331-62427-58525-15123-43794-40933-40016-08024
          +

          The cache size reverts to the default value when the database is closed and reopened. +(source: pragma.html, checked-by: th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-48332-15034-37665-36826-65494-46636-19772-53636
          +

          Overflow pages form a linked list. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-48333-48208-51802-16528-34605-32533-04815-58648
          +

          The page cache implementation may choose to evict unpinned pages at any time. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-48353-58021-05653-25479-47424-12546-41849-50684
          +

          Coalesce() must have at least 2 arguments. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-48365-36308-32644-24714-49385-43742-45411-08326
          +

          Specifying an unknown VFS is an error. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-48367-20048-50643-18297-54370-57109-07198-62808
          +

          Calls to sqlite3_blob_read() and sqlite3_blob_write() for an expired BLOB handle fail with a return code of SQLITE_ABORT. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-48391-38472-46406-48874-31358-29787-61398-48182
          +

          Instead, such errors prevent the application from preparing SQL statements that modify the content of the child or parent tables in ways that use the foreign keys. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-48422-12154-41896-26820-42783-11801-54961-22024
          +

          SQLITE_DONE means that the statement has finished executing successfully. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-48498-17552-64242-05980-09276-07161-21761-29741
          +

          The priority assigned to each node in the search is the lowest priority returned by any of the MATCH operators. +(source: rtree.html, matrix: context, detail)

          + +
          R-48508-22969-00511-42065-43898-18607-20276-53224
          +

          The sqlite3_expanded_sql() interface returns NULL if insufficient memory is available to hold the result, or if the result would exceed the the maximum string length determined by the SQLITE_LIMIT_LENGTH. +(source: c3ref/expanded_sql.html, matrix: context, detail)

          + +
          R-48515-17071-01748-53635-10360-09083-05478-56213
          +

          When there are multiple VFS shims in the stack, this opcode finds the upper-most shim only. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-48521-51450-40029-38325-35476-53863-12365-01087
          +

          When in write-ahead log mode, only the auto_vacuum support property can be changed using VACUUM. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-48560-31808-12822-42502-57159-22070-42910-14910
          +

          The fifth parameter to the preupdate callback is the name of the table that is being modified. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-48563-15053-26384-64007-26863-55213-59220-45966
          +

          If nByte is zero, then no prepared statement is generated. +(source: c3ref/prepare.html, checked-by: th3/cov1/prepare07.test, matrix: context, detail)

          + +
          R-48576-42125-14408-22326-23329-43841-05542-05024
          +

          This pragma only operates on the single database specified prior to the pragma name (or on the "main" database if no database is specified. +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-48584-41074-15154-28473-43969-34090-29401-03268
          +

          For example, if an UPDATE statement encountered a constraint violation on the 100th row that it attempts to update, then the first 99 row changes are preserved but changes to rows 100 and beyond never occur. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-48616-47814-10585-42560-43373-45165-03302-15640
          +

          The COLLATE clause optionally following each column name or expression defines a collating sequence used for text entries in that column. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-48666-10705-60913-59085-01718-56024-53514-10016
          +

          The 4-byte big-endian integer at offset 96 stores the SQLITE_VERSION_NUMBER value for the SQLite library that most recently modified the database file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-48680-34580-07535-36530-00266-23021-14207-17358
          +

          This routine enables or disables the sharing of the database cache and schema data structures between connections to the same database. Sharing is enabled if the argument is true and disabled if the argument is false. +(source: c3ref/enable_shared_cache.html, matrix: context, detail)

          + +
          R-48699-48617-19592-25745-27147-09294-16176-26232
          +

          This function is an SQL wrapper around the sqlite3_libversion() C-interface. +(source: lang_corefunc.html, checked-by: src/func.c, th3/req1/func04.test, matrix: context, detail)

          + +
          R-48711-46457-28354-47973-39166-41669-11371-37006
          +

          The COMMIT command commits all outstanding transactions and leaves the transaction stack empty. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-48725-32206-13295-21825-58953-47648-55693-43130
          +

          If it is globally disabled, filenames are only interpreted as URIs if the SQLITE_OPEN_URI flag is set when the database connection is opened. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-48730-20169-40246-20306-06910-57968-05795-57037
          +

          Setting the auto-checkpoint size to zero or a negative value turns auto-checkpointing off. +(source: pragma.html, matrix: context, detail)

          + +
          R-48741-32454-48845-05465-27210-18049-43593-22824
          +

          If the prefix integer is greater than +9223372036854775807 then the result of the cast is exactly +9223372036854775807. +(source: lang_expr.html, checked-by: tcl/cast.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-48747-10400-04518-40468-05285-19498-18492-16808
          +

          The affinity of a column is determined by the declared type of the column, according to the following rules in the order shown: +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-48764-26733-47009-14023-25431-43800-20632-23039
          +

          SQLITE_LIMIT_VDBE_OP The maximum number of instructions in a virtual machine program used to implement an SQL statement. If sqlite3_prepare_v2() or the equivalent tries to allocate space for more than this many opcodes in a single prepared statement, an SQLITE_NOMEM error is returned. +(source: c3ref/c_limit_attached.html, checked-by: th3/cov1/vdbe43.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-48780-51154-29045-33846-29685-59485-21134-40329
          +

          A rollback journal header is padded with zeros out to the size of a single sector (as defined by the sector size integer at offset 20). +(source: fileformat2.html, matrix: context, detail)

          + +
          R-48887-45097-32252-48133-01081-61153-45933-38095
          +

          When INSERT OR REPLACE encounters a constraint violation, it does not fail. The INSERT continues to completion after deleting rows that caused the constraint problem so INSERT OR REPLACE will always change the return value of this interface. +(source: c3ref/last_insert_rowid.html, matrix: context, detail)

          + +
          R-48924-26514-16091-23967-07299-63684-26291-30704
          +

          SQLite passes the module arguments directly to the xCreate and xConnect methods of the module implementation without any interpretation. +(source: lang_createvtab.html, matrix: context, detail)

          + +
          R-48930-58522-23866-61724-42615-58170-25168-58351
          +

          If the fullfsync flag is set, then the F_FULLFSYNC syncing method is used for all sync operations and the checkpoint_fullfsync setting is irrelevant. +(source: pragma.html, checked-by: th3/req1/pragma11.test, matrix: context, detail)

          + +
          R-48932-13175-31748-44734-45646-26291-63323-36256
          +

          When the auto_vacuum pragma is invoked with no arguments, it returns the current auto_vacuum mode. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-48945-04866-13752-27122-40545-48068-02764-57790
          +

          If the input text looks like an integer (there is no decimal point nor exponent) and the value is small enough to fit in a 64-bit signed integer, then the result will be INTEGER. +(source: lang_expr.html, checked-by: tcl/e_expr.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-48957-47016-25285-15223-13940-44175-60524-56619
          +

          PRAGMA schema.max_page_count; PRAGMA schema.max_page_count = N; Query or set the maximum number of pages in the database file. +(source: pragma.html, checked-by: th3/req1/pragma12.test, matrix: context, detail)

          + +
          R-48969-57179-22710-19682-41342-60747-10784-57811
          +

          The initial columns of the index must be used with the = or IN or IS operators. +(source: optoverview.html, matrix: context, detail)

          + +
          R-48974-49065-61621-06146-19676-25971-04970-57642
          +

          When overwriting the original, a rollback journal or write-ahead log WAL file is used just as it would be for any other database transaction. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-49006-07361-60933-29760-59065-52177-14168-55126
          +

          This interface returns a pointer the sqlite3_mutex object that serializes access to the database connection given in the argument when the threading mode is Serialized. +(source: c3ref/db_mutex.html, checked-by: th3/req1/dbmutex01.test, matrix: context, detail)

          + +
          R-49034-18526-14571-23024-35463-03575-44456-04746
          +

          If sqlite3_close_v2() is called with unfinalized prepared statements, unclosed BLOB handlers, and/or unfinished sqlite3_backups, it returns SQLITE_OK regardless, but instead of deallocating the database connection immediately, it marks the database connection as an unusable "zombie" and makes arrangements to automatically deallocate the database connection after all prepared statements are finalized, all BLOB handles are closed, and all backups have finished. +(source: c3ref/close.html, checked-by: th3/cov1/main39.test, matrix: context, detail)

          + +
          R-49045-42493-00753-52815-20675-33627-44655-32339
          +

          SQLite will use the xCurrentTimeInt64() method to get the current date and time if that method is available (if iVersion is 2 or greater and the function pointer is not NULL) and will fall back to xCurrentTime() if xCurrentTimeInt64() is unavailable. +(source: c3ref/vfs.html, checked-by: src/os.c, matrix: context, detail)

          + +
          R-49053-54554-23954-60675-57503-20600-08222-18852
          +

          The sqlite3_free() routine is a no-op if is called with a NULL pointer. +(source: c3ref/free.html, checked-by: src/malloc.c, th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-49060-02464-24124-01756-13538-48535-01084-34882
          +

          For UTF16 input text to the sqlite3_result_text16(), sqlite3_result_text16be(), sqlite3_result_text16le(), and sqlite3_result_text64() routines, if the text contains invalid UTF16 characters, the invalid characters might be converted into the unicode replacement character, U+FFFD. +(source: c3ref/result_blob.html, matrix: context, detail)

          + +
          R-49065-33371-62807-45806-18659-22955-12642-05474
          +

          you cannot create indices or triggers on a virtual table. +(source: lang_createvtab.html, matrix: context, detail)

          + +
          R-49080-64834-49066-11889-43527-52313-57456-24143
          +

          SQLite further guarantees that the string will be valid and unchanged until xClose() is called. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-49128-31170-23004-04082-05241-62766-17146-48048
          +

          The second column is "main" for the main database file, "temp" for the database file used to store TEMP objects, or the name of the ATTACHed database for other database files. +(source: pragma.html, checked-by: th3/req1/pragma14.test, matrix: context, detail)

          + +
          R-49155-63541-44229-54839-02572-16362-28643-16859
          +

          If the busy-handler returns 0 before the writer lock is obtained or while waiting for database readers, the checkpoint operation proceeds from that point in the same way as SQLITE_CHECKPOINT_PASSIVE - checkpointing as many frames as possible without blocking any further. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-49178-21358-58489-31319-06651-33455-27209-45773
          +

          By contrast, if a statement modifies the contents of the database such that a deferred foreign key constraint is violated, the violation is not reported immediately. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, matrix: context, detail)

          + +
          R-49203-06300-24971-00388-61998-23090-03169-09394
          +

          SQLITE_ERROR means that a run-time error (such as a constraint violation) has occurred. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-49248-49502-37963-38186-54348-07899-11836-10186
          +

          A trace callback has four arguments: xCallback(T,C,P,X). +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-49255-55373-50105-35704-52398-37600-44211-44389
          +

          The "unixepoch" modifier (11) only works if it immediately follows a time value in the DDDDDDDDDD format. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-49314-60109-53910-26284-37294-10072-42169-13875
          +

          The sqlite3_str_new(D) interface always returns a pointer to a valid sqlite3_str object, though in the event of an out-of-memory error the returned object might be a special singleton that will silently reject new text, always return SQLITE_NOMEM from sqlite3_str_errcode(), always return 0 for sqlite3_str_length(), and always return NULL from sqlite3_str_finish(X). +(source: c3ref/str_new.html, matrix: context, detail)

          + +
          R-49321-63177-63913-58265-32915-52148-26230-28252
          +

          At the start of the first new write transaction, the WAL header salt-1 value is incremented and the salt-2 value is randomized. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-49341-60912-32956-53217-17617-26256-31299-20924
          +

          The schema for the sqlite_sequence table is: CREATE TABLE sqlite_sequence(name,seq); +(source: fileformat2.html, matrix: context, detail)

          + +
          R-49389-26640-51376-48756-08197-40049-61248-27840
          +

          And auto_vacuum does not compact partially filled pages of the database as VACUUM does. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-49438-33626-11664-14261-26905-24626-16262-08666
          +

          The second argument is the index of the SQL parameter to be set. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-49475-10767-10056-16287-22604-26853-09642-54500
          +

          Triggers are database operations that are automatically performed when a specified database event occurs. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-49482-28255-11165-16969-19865-58468-07547-43545
          +

          strftime(format, time-value, modifier, modifier, ...) +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-49566-01570-19269-51029-21052-63278-54120-39261
          +

          If the left and right-hand input datasets feature no common column names, then the NATURAL keyword has no effect on the results of the join. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-49616-30196-22472-11090-21986-31770-01648-15576
          +

          Or, if the argument attached to the REINDEX identifies a specific database table, then all indices attached to the database table are rebuilt. +(source: lang_reindex.html, checked-by: tcl/e_reindex.test, matrix: context, detail)

          + +
          R-49703-40061-17137-59156-45965-30575-53076-21589
          +

          Note that you must use the keyword "CROSS" in order to disable the table reordering optimization; INNER JOIN, NATURAL JOIN, JOIN, and other similar combinations work just like a comma join in that the optimizer is free to reorder tables as it sees fit. +(source: optoverview.html, matrix: context, detail)

          + +
          R-49709-12803-31814-26348-47423-57692-52617-09726
          +

          If this variable is a NULL pointer, then SQLite assumes that all database files specified with a relative pathname are relative to the current directory for the process. +(source: c3ref/data_directory.html, matrix: context, detail)

          + +
          R-49713-24018-00307-59185-08643-49847-38156-16208
          +

          PRAGMA optimize; PRAGMA optimize(MASK); PRAGMA schema.optimize; PRAGMA schema.optimize(MASK); Attempt to optimize the database. +(source: pragma.html, matrix: context, detail)

          + +
          R-49718-44437-53178-33073-48551-60632-45231-61036
          +

          If sqlite3_backup_step(B,N) successfully copies N pages and there are still more pages to be copied, then the function returns SQLITE_OK. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup03.test, matrix: context, detail)

          + +
          R-49744-28344-63399-17680-56251-18260-15622-25179
          +

          Return the number of columns in the result set returned by the prepared statement. +(source: c3ref/column_count.html, checked-by: th3/req1/datacnt01.test, th3/th3util.c, matrix: context, detail)

          + +
          R-49752-52776-47662-23975-09882-64912-61393-46932
          +

          Unless deadlock is detected (see below), sqlite3_unlock_notify() always returns SQLITE_OK. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-49755-52305-50585-21714-21268-35296-20673-02389
          +

          Hence, to find the current value of a limit without changing it, simply invoke this interface with the third parameter set to -1. +(source: c3ref/limit.html, checked-by: th3/req1/limit01.test, matrix: context, detail)

          + +
          R-49759-12456-29059-02912-58446-28690-22652-14283
          +

          None of the xSavepoint(), xRelease(), or xRollbackTo() methods will ever be called except in between calls to xBegin() and either xCommit() or xRollback(). +(source: vtab.html, matrix: context, detail)

          + +
          R-49770-47130-58542-44165-02097-09691-62108-60186
          +

          Thus with SQLite, there is no computational advantage to use the newer SQL92 join syntax over the older SQL89 comma-join syntax. They both end up accomplishing exactly the same thing on inner joins. +(source: optoverview.html, matrix: context, detail)

          + +
          R-49783-61279-16242-54630-23858-13201-42746-50539
          +

          An "at" sign works exactly like a colon, except that the name of the parameter created is @AAAA. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-49787-09095-59828-21873-59722-58007-44874-49615
          +

          The sqlite3_wal_checkpoint_v2(D,X,M,L,C) interface runs a checkpoint operation on database X of database connection D in mode M. Status information is written back into integers pointed to by L and C. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-49789-16524-33222-15346-50158-11030-19428-38711
          +

          For an inner join, the two queries above would be identical. +(source: optoverview.html, matrix: context, detail)

          + +
          R-49793-28525-19299-21644-21029-37441-20100-31652
          +

          Setting the cache parameter to "private" is equivalent to setting the SQLITE_OPEN_PRIVATECACHE bit. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-49794-35026-38918-00907-30383-35141-38655-30488
          +

          Value is a big-endian 16-bit twos-complement integer. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-49846-38160-32658-53011-14500-27650-55616-46897
          +

          If the argument is a table name, then only that table and the indices associated with that table are analyzed. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-49851-43011-30572-52632-23403-60290-47065-63539
          +

          When this flag is on, the ALTER TABLE RENAME command (for changing the name of a table) works as it did in SQLite 3.24.0 (2018-06-04) and earlier. +(source: pragma.html, matrix: context, detail)

          + +
          R-49858-53293-55345-56898-28930-13121-51128-08876
          +

          If a column-name list follows the view-name, then that list determines the names of the columns for the view. +(source: lang_createview.html, matrix: context, detail)

          + +
          R-49872-03192-58704-53251-31114-19723-47133-57999
          +

          If the join-operator is "CROSS JOIN", "INNER JOIN", "JOIN" or a comma (",") and there is no ON or USING clause, then the result of the join is simply the cartesian product of the left and right-hand datasets. +(source: lang_select.html, checked-by: tcl/e_select.test, tcl/e_select2.test, matrix: context, detail)

          + +
          R-49876-15090-54531-12360-51762-42464-27372-16242
          +

          SQLite makes a copy of the content of the sqlite3_mutex_methods structure before the call to sqlite3_config() returns. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/th3main.c, matrix: context, detail)

          + +
          R-49920-60189-48669-35973-51094-40513-29191-34461
          +

          If the first pointer (the memory pointer) is NULL, then SQLite reverts to using its default memory allocator (the system malloc() implementation), undoing any prior invocation of SQLITE_CONFIG_MALLOC. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3oom.c, matrix: context, detail)

          + +
          R-49925-55905-53634-34425-17507-41771-04127-21905
          +

          Otherwise, the BINARY collation sequence is used. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-49931-19798-23474-09370-36216-10511-05923-60825
          +

          After each call to sqlite3_set_auxdata(C,N,P,X) where X is not NULL, SQLite will invoke the destructor function X with parameter P exactly once, when the metadata is discarded. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-49933-05137-11348-33836-49788-49818-47982-53945
          +

          If there is a USING clause then each of the column names specified must exist in the datasets to both the left and right of the join-operator. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-49956-53465-03282-32441-61380-45245-38103-26687
          +

          A protected sqlite3_value object may always be used where an unprotected sqlite3_value object is required, so either kind of sqlite3_value object can be used with this interface. +(source: c3ref/result_blob.html, checked-by: th3/req1/result03.test, matrix: context, detail)

          + +
          R-49959-19447-21859-18883-29920-55804-31442-61320
          +

          The xMutexInit method defined by this structure is invoked as part of system initialization by the sqlite3_initialize() function. +(source: c3ref/mutex_methods.html, matrix: context, detail)

          + +
          R-49983-40731-31772-48546-63558-64382-07908-41217
          +

          There is normally one row per index, with the index identified by the name in the sqlite_stat1.idx column. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-49991-12716-30919-42596-27111-39963-53414-21739
          +

          A keyword in double-quotes is an identifier. +(source: lang_keywords.html, checked-by: th3/req1/keyword01.test, matrix: context, detail)

          + +
          R-50036-02772-43008-32720-05728-55771-24380-32183
          +

          The definition of GLOB pattern matching used in sqlite3_strglob(P,X) is the same as for the "X GLOB P" operator in the SQL dialect understood by SQLite. +(source: c3ref/strglob.html, checked-by: th3/cov1/glob01.test, matrix: context, detail)

          + +
          R-50083-49187-63509-30877-07462-63628-48341-23744
          +

          Both routines return a NULL pointer if sqlite3_malloc64() is unable to allocate enough memory to hold the resulting string. +(source: c3ref/mprintf.html, matrix: context, detail)

          + +
          R-50083-60579-41416-11234-29660-46304-14804-18223
          +

          The second argument is an integer constant, taken from the set of SQLITE_DBSTATUS options, that determines the parameter to interrogate. +(source: c3ref/db_status.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-50109-18895-48987-07545-37480-53059-10212-16515
          +

          Hexadecimal integer literals follow the C-language notation of "0x" or "0X" followed by hexadecimal digits. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-50117-55204-45597-46380-14331-21746-62351-54085
          +

          Foreign key constraints are enabled, column zColumn is part of a child key definition and the blob is being opened for read/write access +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, th3/cov1/vdbeblob06.test, matrix: context, detail)

          + +
          R-50141-17598-64848-16921-53866-52555-58777-52662
          +

          The legacy_file_format pragma can be used to change set the specific behavior for any version of SQLite. +(source: lang_createindex.html, matrix: context, detail)

          + +
          R-50173-30557-65428-54259-43210-11188-24430-56909
          +

          The integrity_check pragma look for: Table or index entries that are out of sequence Misformatted records Missing pages Missing or surplus index entries UNIQUE, CHECK, and NOT NULL constraint errors Integrity of the freelist Sections of the database that are used more than once, or not at all +(source: pragma.html, matrix: context, detail)

          + +
          R-50185-15050-31039-59683-34271-57411-13572-34990
          +

          sqlite3_initialize() will invoke sqlite3_os_init(). +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-50194-36439-38643-58258-08094-53618-19496-51516
          +

          The right-hand side of the LIKE or GLOB must be either a string literal or a parameter bound to a string literal that does not begin with a wildcard character. +(source: optoverview.html, matrix: context, detail)

          + +
          R-50221-42915-63366-22900-20330-11785-03020-07712
          +

          The result of an IN or NOT IN operator is determined by the following matrix: Left operand is NULL Right operand contains NULL Right operand is an empty set Left operand found within right operand Result of IN operator Result of NOT IN operator no no no no false true does not matter no yes no false true no does not matter no yes true false no yes no no NULL NULL yes does not matter no does not matter NULL NULL +(source: lang_expr.html, checked-by: tcl/tkt-80e031a00f.test, matrix: context, detail)

          + +
          R-50227-03668-59884-25860-05974-05725-11856-44463
          +

          The descending index schema format (4) takes index sort order into account. +(source: lang_createindex.html, checked-by: th3/req1/createidx02.test, matrix: context, detail)

          + +
          R-50230-26466-58809-52102-21271-42089-25495-26496
          +

          Without this flag, sqlite3_prepare_v3() and sqlite3_prepare16_v3() assume that the prepared statement will be used just once or at most a few times and then destroyed using sqlite3_finalize() relatively soon. +(source: c3ref/c_prepare_normalize.html, matrix: context, detail)

          + +
          R-50253-50589-37477-41446-40449-16495-32904-62089
          +

          The subquery may not be a recursive CTE. +(source: optoverview.html, matrix: context, detail)

          + +
          R-50295-28419-15389-14310-31711-65097-63451-02333
          +

          Thus if the BETWEEN term ends up being used as an index constraint no tests are ever performed on that term. +(source: optoverview.html, matrix: context, detail)

          + +
          R-50299-05307-25514-21202-52371-12958-26129-48124
          +

          When an applicable constraint violation occurs, the IGNORE resolution algorithm skips the one row that contains the constraint violation and continues processing subsequent rows of the SQL statement as if nothing went wrong. +(source: lang_conflict.html, checked-by: th3/req1/conflict01.test, matrix: context, detail)

          + +
          R-50300-26941-55863-56023-43928-35657-09281-24931
          +

          Any text input that describes a value outside the range of a 64-bit signed integer yields a REAL result. +(source: lang_expr.html, checked-by: tcl/e_expr.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-50324-49641-07188-15996-37030-30300-11878-30571
          +

          When an SQL table includes an INTEGER PRIMARY KEY column (which aliases the rowid) then that column appears in the record as a NULL value. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-50327-55469-41680-02730-23455-56699-46254-12208
          +

          The sqlite_schema.type column will be one of the following text strings: 'table', 'index', 'view', or 'trigger' according to the type of object defined. The 'table' string is used for both ordinary and virtual tables. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-50385-09674-49008-33764-60842-63141-30629-37607
          +

          Value is a big-endian 48-bit twos-complement integer. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-50436-30597-52741-48231-49256-06993-48572-34850
          +

          The list of query parameters appended to the xOpen filename is terminated by a single zero-length key. +(source: uri.html, matrix: context, detail)

          + +
          R-50437-53270-64199-48076-12233-35385-13777-56267
          +

          The first argument is a pointer to an sqlite3_rtree_geometry structure which provides information about how the SQL function was invoked. +(source: rtree.html, matrix: context, detail)

          + +
          R-50442-34254-35455-58700-58965-62142-32020-28485
          +

          For nested transactions, use the SAVEPOINT and RELEASE commands. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-50479-29416-05730-38331-50823-03190-30140-42480
          +

          Invoking sqlite3_soft_heap_limit64(0) when the hard heap limit is enabled makes the soft heap limit equal to the hard heap limit. +(source: c3ref/hard_heap_limit64.html, matrix: context, detail)

          + +
          R-50479-38141-17486-25121-60764-22579-08326-61073
          +

          The sqlite3_strglob(P,X) function is case sensitive. +(source: c3ref/strglob.html, checked-by: th3/cov1/glob01.test, matrix: context, detail)

          + +
          R-50485-58274-46639-28890-19306-28119-49534-14014
          +

          The first time the sqlite3_aggregate_context(C,N) routine is called for a particular aggregate function, SQLite allocates N bytes of memory, zeroes out that memory, and returns a pointer to the new memory. +(source: c3ref/aggregate_context.html, checked-by: th3/req1/aggcntx01.test, matrix: context, detail)

          + +
          R-50503-22862-13388-40598-38770-05008-28550-22955
          +

          It is harmless, apart from the wasted memory, for the sz parameter to be larger than necessary. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/main42.test, matrix: context, detail)

          + +
          R-50542-62589-12148-25496-57313-35082-62636-01906
          +

          If the row that a BLOB handle points to is modified by an UPDATE, DELETE, or by ON CONFLICT side-effects then the BLOB handle is marked as "expired". This is true if any column of the row is changed, even a column other than the one the BLOB handle is open on. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-50551-20166-10060-53242-13172-15723-06354-52489
          +

          In any database file that contains ptrmap pages, all b-tree root pages must come before any non-root b-tree page, cell payload overflow page, or freelist page. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-50561-21716-49344-62594-61737-43195-59179-37313
          +

          SQLITE_NOMEM is returned if malloc() fails. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-50578-26484-60015-06758-51752-02916-33934-51751
          +

          The default setting for auto-vacuum is 0 or "none", unless the SQLITE_DEFAULT_AUTOVACUUM compile-time option is used. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-50603-48655-15152-53727-63260-31520-08001-01619
          +

          The sqlite3_preupdate_hook() interface registers a callback function that is invoked prior to each INSERT, UPDATE, and DELETE operation on a database table. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-50610-58991-40013-53389-28738-38932-29911-53900
          +

          Database locks obtained by a connection in EXCLUSIVE mode may be released either by closing the database connection, or by setting the locking-mode back to NORMAL using this pragma and then accessing the database file (for read or write). +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-50620-43692-22262-08233-20574-62920-57833-55280
          +

          The value will be valid until the database N is DETACH-ed or until the database connection closes. +(source: c3ref/db_filename.html, matrix: context, detail)

          + +
          R-50629-09283-02529-31024-03182-51396-04180-35688
          +

          The trim(X,Y) function returns a string formed by removing any and all characters that appear in Y from both ends of X. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-50658-17415-26867-64238-49618-34933-22371-53108
          +

          One is the usual increment. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-50676-09860-46242-55530-65292-55859-31075-59958
          +

          The callback can compute the same text that would have been returned by the legacy sqlite3_trace() interface by using the X argument when X begins with "--" and invoking sqlite3_expanded_sql(P) otherwise. +(source: c3ref/c_trace.html, checked-by: src/vdbe.c, matrix: context, detail)

          + +
          R-50678-57776-62798-21946-06580-60998-12542-16606
          +

          If Y is an empty string then return X unchanged. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-50747-49923-21483-58514-27398-43836-46861-05011
          +

          In WAL mode when synchronous is NORMAL (1), the WAL file is synchronized before each checkpoint and the database file is synchronized after each completed checkpoint and the WAL file header is synchronized when a WAL file begins to be reused after a checkpoint, but no sync operations occur during most transactions. +(source: pragma.html, matrix: context, detail)

          + +
          R-50761-32325-45623-21011-38075-29398-65285-24375
          +

          If the SQL statement being executed returns any data, then SQLITE_ROW is returned each time a new row of data is ready for processing by the caller. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-50775-16353-43388-35823-42786-57944-23203-27410
          +

          Aggregate max() returns NULL if and only if there are no non-NULL values in the group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-50779-31451-02741-56798-14558-26402-32929-36548
          +

          Regardless of the compile-time or start-time settings, URI filenames can be enabled for individual database connections by including the SQLITE_OPEN_URI bit in the set of bits passed as the F parameter to sqlite3_open_v2(N,P,F,V). +(source: uri.html, checked-by: th3/th3script.c, th3/th3scriptDemo.c, matrix: context, detail)

          + +
          R-50786-24793-54635-21021-11581-63558-51983-08230
          +

          The sqlite3_backup_finish() interfaces releases all resources associated with the sqlite3_backup object. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-50811-36721-38303-45762-44578-12408-00845-45536
          +

          Return the index of an SQL parameter given its name. +(source: c3ref/bind_parameter_index.html, checked-by: th3/req1/bind03.test, matrix: context, detail)

          + +
          R-50848-12841-20813-56140-49872-26884-10100-43197
          +

          The sqlite3_realloc(X,N) interface attempts to resize a prior memory allocation X to be at least N bytes. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-50854-53979-53797-24039-01336-17260-53892-24252
          +

          If the flags parameter is non-zero, then the BLOB is opened for read and write access. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-50943-18433-57597-04082-04676-55042-26161-32461
          +

          Frequent inserts, updates, and deletes can cause the database file to become fragmented - where data for a single table or index is scattered around the database file. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-50949-63870-33866-03179-22330-03090-53959-18896
          +

          The sqlite3_preupdate_depth(D) interface returns 0 if the preupdate callback was invoked as a result of a direct insert, update, or delete operation; or 1 for inserts, updates, or deletes invoked by top-level triggers; or 2 for changes resulting from triggers called by top-level triggers; and so forth. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-50991-36730-61115-19569-38902-10025-13040-27195
          +

          The julianday() function returns the Julian day - the number of days since noon in Greenwich on November 24, 4714 B.C. (Proleptic Gregorian calendar). +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-50998-48593-15923-36152-59159-51921-46950-43599
          +

          Similarly, a CREATE TABLE IF NOT EXISTS statement is a read-only no-op if the table already exists, but sqlite3_stmt_readonly() still returns false for such a statement. +(source: c3ref/stmt_readonly.html, matrix: context, detail)

          + +
          R-51001-58728-23268-57802-19223-01595-20066-01281
          +

          If sqlite3_malloc() fails during the processing of either routine (for example during a conversion from UTF-8 to UTF-16) then a NULL pointer is returned. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-51011-20077-64132-12410-55765-38017-02998-57581
          +

          The results of an ANALYZE command are only available to database connections that are opened after the ANALYZE command completes. +(source: optoverview.html, matrix: context, detail)

          + +
          R-51014-28024-42085-28455-54203-21971-27731-22448
          +

          The preupdate hook only fires for changes to real database tables; the preupdate hook is not invoked for changes to virtual tables or to system tables like sqlite_sequence or sqlite_stat1. +(source: c3ref/preupdate_blobwrite.html, matrix: context, detail)

          + +
          R-51039-44840-65130-09775-42940-11077-05048-04287
          +

          The foreign key declared as part of table child4 is an error because even though the parent key column is indexed, the index is not UNIQUE. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-51077-27219-05589-60630-09467-24342-14957-57780
          +

          The sqlite3_bind_parameter_name(P,N) interface returns the name of the N-th SQL parameter in the prepared statement P. +(source: c3ref/bind_parameter_name.html, checked-by: th3/req1/bind04.test, matrix: context, detail)

          + +
          R-51090-01319-14064-12731-11996-25271-12036-18507
          +

          To specify a ROWID manually, just include it in the list of values to be inserted. For example: CREATE TABLE test1(a INT, b TEXT); INSERT INTO test1(rowid, a, b) VALUES(123, 5, 'hello'); +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-51132-22354-55296-53634-47929-60689-49370-19301
          +

          The fragment is optional. If present, it is ignored. +(source: uri.html, matrix: context, detail)

          + +
          R-51136-58806-61234-62019-55007-59360-42389-06217
          +

          The SQLITE_CONFIG_GETMUTEX option takes a single argument which is a pointer to an instance of the sqlite3_mutex_methods structure. The sqlite3_mutex_methods structure is filled with the currently defined mutex routines. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/th3main.c, matrix: context, detail)

          + +
          R-51188-10511-53486-13467-33183-09537-36166-58492
          +

          In a well-formed database, all children of an interior b-tree have the same depth. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-51202-43754-48199-60556-57882-64692-40949-61434
          +

          The last transaction started will be the first transaction committed or rolled back. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-51206-57397-04624-50040-55912-00290-07116-44966
          +

          The sqlite3_result_int() interface sets the return value of the application-defined function to be the 32-bit signed integer value given in the 2nd argument. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-51213-46414-44836-21808-03706-65472-27222-00802
          +

          The SQLITE_CONFIG_GETMALLOC option takes a single argument which is a pointer to an instance of the sqlite3_mem_methods structure. The sqlite3_mem_methods structure is filled with the currently defined memory allocation routines. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3oom.c, matrix: context, detail)

          + +
          R-51232-50224-58506-40920-61688-18757-44131-05457
          +

          The collation sequence used to compare two text values is determined as if the columns of the left and right-hand SELECT statements were the left and right-hand operands of the equals (=) operator, except that greater precedence is not assigned to a collation sequence specified with the postfix COLLATE operator. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-51243-03259-14628-62602-22056-51212-17455-10922
          +

          Otherwise, the BINARY collating function is used for comparison. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-51247-30732-42040-45560-24413-23058-07649-15585
          +

          The subquery is not DISTINCT. +(source: optoverview.html, matrix: context, detail)

          + +
          R-51255-43746-15106-11095-25505-08076-41908-14797
          +

          For example, given the database schema: CREATE TABLE t1(c1 VARIANT); and the following statement to be compiled: SELECT c1 + 1, c1 FROM t1; this routine would return the string "VARIANT" for the second result column (i==1), and a NULL pointer for the first result column (i==0). +(source: c3ref/column_decltype.html, matrix: context, detail)

          + +
          R-51278-32108-12212-46077-36246-55134-53199-48747
          +

          SQLite interprets the error message string from sqlite3_result_error() as UTF-8. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-51288-13280-04102-45116-03468-31022-16818-18887
          +

          PRAGMA schema.synchronous; PRAGMA schema.synchronous = 0 | OFF | 1 | NORMAL | 2 | FULL | 3 | EXTRA; Query or change the setting of the "synchronous" flag. +(source: pragma.html, matrix: context, detail)

          + +
          R-51332-60960-52674-22540-45151-35167-25354-18137
          +

          Zero or more escape sequences of the form "%HH" (where H represents any hexadecimal digit) can occur in the path, query string, or fragment. +(source: uri.html, matrix: context, detail)

          + +
          R-51343-23764-31964-03774-37293-59817-59078-38155
          +

          This technique allows multiple concurrent readers to view different versions of the database content simultaneously. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-51358-63229-53880-11808-10105-25877-37226-63676
          +

          If the default VFS is unregistered, another VFS is chosen as the default. The choice for the new VFS is arbitrary. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-51359-17496-64791-11531-01433-14001-31199-61206
          +

          The infix LIKE operator is implemented by calling the application-defined SQL functions like(Y,X) or like(Y,X,Z). +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-51370-13632-41258-48157-25813-10718-36175-44493
          +

          If the integer at offset 52 is zero then pointer-map (ptrmap) pages are omitted from the database file and neither auto_vacuum nor incremental_vacuum are supported. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-51414-32910-11625-05562-19787-23325-64160-35214
          +

          Except for WITHOUT ROWID tables, all rows within SQLite tables have a 64-bit signed integer key that uniquely identifies the row within its table. +(source: lang_createtable.html, checked-by: src/resolve.c, matrix: context, detail)

          + +
          R-51415-29417-45054-21593-06367-21314-00949-64320
          +

          Within a single database connection X, a SELECT statement always sees all changes to the database that are completed prior to the start of the SELECT statement, whether committed or uncommitted. +(source: isolation.html, matrix: context, detail)

          + +
          R-51445-09984-56297-19281-17742-25631-52037-59978
          +

          The return value of the sqlite3_threadsafe() function shows only the compile-time setting of thread safety, not any run-time changes to that setting made by sqlite3_config(). In other words, the return value from sqlite3_threadsafe() is unchanged by calls to sqlite3_config(). +(source: c3ref/threadsafe.html, checked-by: th3/th3main.c, matrix: context, detail)

          + +
          R-51463-25634-03361-45717-43677-30720-21925-17287
          +

          Attempts to increase a limit above its hard upper bound are silently truncated to the hard upper bound. +(source: c3ref/limit.html, checked-by: src/main.c, th3/req1/limit01.test, matrix: context, detail)

          + +
          R-51469-36013-06451-37309-14378-27141-44520-41230
          +

          Unless SQLite is running in "auto_vacuum=FULL" mode, when a large amount of data is deleted from the database file it leaves behind empty space, or "free" database pages. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-51513-12026-58956-15151-33280-52344-26081-14635
          +

          The last_insert_rowid() SQL function is a wrapper around the sqlite3_last_insert_rowid() C/C++ interface function. +(source: lang_corefunc.html, checked-by: src/func.c, matrix: context, detail)

          + +
          R-51517-40824-40012-37469-09201-20241-42443-20040
          +

          If a REAL is greater than the greatest possible signed integer (+9223372036854775807) then the result is the greatest possible signed integer and if the REAL is less than the least possible signed integer (-9223372036854775808) then the result is the least possible signed integer. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-51594-01886-40324-04229-65116-14684-49683-32490
          +

          The blocked connections unlock-notify callback may also be canceled by closing the blocked connection using sqlite3_close(). +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-51608-43497-31902-60107-31973-18527-41260-25807
          +

          However, if SQLite is compiled with the SQLITE_OMIT_AUTOINIT compile-time option, then the automatic calls to sqlite3_initialize() are omitted and the application must call sqlite3_initialize() directly prior to using any other SQLite interface. +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-51689-46548-01385-34358-38620-06240-42232-09514
          +

          If URI handling is globally enabled, all filenames passed to sqlite3_open(), sqlite3_open_v2(), sqlite3_open16() or specified as part of ATTACH commands are interpreted as URIs, regardless of whether or not the SQLITE_OPEN_URI flag is set when the database connection is opened. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-51717-16874-57746-23780-03416-60181-48500-48749
          +

          The sqlite3_value objects that are passed as parameters into the implementation of application-defined SQL functions are protected. +(source: c3ref/value.html, checked-by: th3/req1/value01.test, matrix: context, detail)

          + +
          R-51733-58667-21298-61463-51769-00827-24918-26200
          +

          The sqlite_schema.name column will hold the name of the object. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-51848-06142-00211-08018-28076-33620-42817-53867
          +

          When grouping values with the GROUP BY clause values with different storage classes are considered distinct, except for INTEGER and REAL values which are considered equal if they are numerically equal. +(source: datatype3.html, checked-by: th3/req1/datatype3_07.test, matrix: context, detail)

          + +
          R-51849-15852-01721-49206-07191-28976-11047-33073
          +

          This routine can be used to find the number of SQL parameters in a prepared statement. +(source: c3ref/bind_parameter_count.html, checked-by: th3/req1/bindparamcnt01.test, matrix: context, detail)

          + +
          R-51867-44713-01499-65438-22037-17014-32940-19082
          +

          This mode blocks new database writers while it is pending, but new database readers are allowed to continue unimpeded. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-51873-39618-36887-07740-29910-44227-64994-45614
          +

          The page size for a database file is determined by the 2-byte integer located at an offset of 16 bytes from the beginning of the database file. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-51885-22945-13735-45717-24021-29019-43116-06433
          +

          If the fourth parameter is a NULL pointer then the default sqlite3_vfs object is used. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-51885-42713-13450-15041-37294-08802-56652-50878
          +

          If an sqlite3 object is destroyed while a transaction is open, the transaction is automatically rolled back. +(source: c3ref/close.html, checked-by: th3/cov1/main23.test, matrix: context, detail)

          + +
          R-51928-56409-25580-29954-36146-50977-06316-16623
          +

          If the Y argument is omitted, it is assumed to be 0. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-51971-34154-03806-52008-63597-27653-22801-35864
          +

          A value of 3 means UTF-16be. +(source: fileformat2.html, checked-by: th3/req1/fileformat03.test, matrix: context, detail)

          + +
          R-51988-01124-61073-07192-64442-28469-58291-20254
          +

          The single row of result-set data created by evaluating the aggregate and non-aggregate expressions in the result-set forms the result of an aggregate query without a GROUP BY clause. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-52009-56800-02876-38410-52331-04439-27959-64251
          +

          When the same named SQL parameter is used more than once, second and subsequent occurrences have the same index as the first occurrence. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-52058-53560-05683-08265-32399-18917-51840-34472
          +

          The difference between this pragma and cache_size is that the value set here persists across database connections. +(source: pragma.html, checked-by: th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-52064-29026-64235-14547-56898-38639-53411-40731
          +

          Then valid content of the WAL is transferred into the database file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-52075-50256-20099-08079-26279-42286-42612-03538
          +

          WAL databases can be accessed in EXCLUSIVE mode without the use of shared memory. +(source: pragma.html, checked-by: th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-52087-12043-18539-27674-65294-02537-52169-03316
          +

          The GLOB operator is similar to LIKE but uses the Unix file globbing syntax for its wildcards. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-52095-61560-15875-18075-33970-20286-17473-17110
          +

          Compute the time since the unix epoch in seconds (like strftime('%s','now') except includes fractional part): SELECT (julianday('now') - 2440587.5)*86400.0; +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-52112-44167-29557-32082-32253-19519-12143-63610
          +

          Disable the authorizer by installing a NULL callback. +(source: c3ref/set_authorizer.html, checked-by: tcl/auth.test, th3/cov1/auth01.test, matrix: context, detail)

          + +
          R-52129-08912-02677-16711-14942-51135-37066-54539
          +

          Otherwise the two pragmas are the same. +(source: pragma.html, matrix: context, detail)

          + +
          R-52155-58082-26086-07987-14656-12581-61413-44017
          +

          The database file is truncated by the same amount. +(source: pragma.html, checked-by: th3/req1/pragma21.test, matrix: context, detail)

          + +
          R-52173-30215-53600-04024-57111-07523-42614-02715
          +

          A new entry is inserted into the table for each row of data returned by executing the SELECT statement. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-52173-44778-34853-40579-46358-28940-10008-53316
          +

          The REINDEX command is used to delete and recreate indices from scratch. +(source: lang_reindex.html, checked-by: tcl/e_reindex.test, matrix: context, detail)

          + +
          R-52186-13726-13182-41140-39915-38956-00015-42302
          +

          When temp_store is MEMORY (2) temporary tables and indices are kept in as if they were pure in-memory databases memory. +(source: pragma.html, matrix: context, detail)

          + +
          R-52219-37966-04646-12994-22275-64637-40649-18825
          +

          The "const char *" variable pointed to by the V parameter will be set to a zero-terminated UTF-8 string containing the EXPLAIN QUERY PLAN description for the X-th loop. +(source: c3ref/c_scanstat_est.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-52227-24890-51100-17044-40956-25330-61806-31356
          +

          At this time SQLite supports only FOR EACH ROW triggers, not FOR EACH STATEMENT triggers. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-52275-20321-01403-45171-16511-11521-16103-23832
          +

          However, special processing applies to the ON and USING clauses of an OUTER join: specifically, the constraints in an ON or USING clause do not apply if the right table of the join is on a null row, but the constraints do apply in the WHERE clause. +(source: optoverview.html, matrix: context, detail)

          + +
          R-52275-55503-36173-27620-56866-61017-01277-04274
          +

          When the right operand is an empty set, the result of IN is false and the result of NOT IN is true, regardless of the left operand and even if the left operand is NULL. +(source: lang_expr.html, checked-by: tcl/tkt-80e031a00f.test, matrix: context, detail)

          + +
          R-52293-58497-02008-48685-44667-03336-29126-34066
          +

          If this option is set to an empty string the default VFS object is used. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-52324-13814-42283-42747-08778-19058-01136-41555
          +

          If the resetFlg is true, then the counter is reset to zero after this interface call returns. +(source: c3ref/stmt_status.html, matrix: context, detail)

          + +
          R-52325-25449-60499-51336-30088-24450-41754-02274
          +

          The value of a subquery expression is NULL if the enclosed SELECT statement returns no rows. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-52382-54248-22062-55622-65270-38332-60427-10536
          +

          Each table in SQLite may have at most one PRIMARY KEY. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-52422-13996-14748-65406-33477-57912-42976-47996
          +

          This optimization is completely invisible at the SQL level and can only be detected by examining the raw bits of the database file. +(source: datatype3.html, checked-by: th3/req1/datatype3_12.test, matrix: context, detail)

          + +
          R-52436-31752-34647-62444-09688-32062-53340-29522
          +

          The column is a PRIMARY KEY or part of one. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-52476-28732-49113-60930-43191-11602-63829-33469
          +

          If the new limit is a negative number, the limit is unchanged. +(source: c3ref/limit.html, checked-by: src/main.c, th3/req1/limit01.test, matrix: context, detail)

          + +
          R-52479-14335-30324-56170-28904-55659-58035-31825
          +

          If the sqlite_sequence row for an AUTOINCREMENT table does not exist when the AUTOINCREMENT table is updated, then a new sqlite_sequence row is created. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-52486-21352-15520-42418-18389-29845-28843-27004
          +

          Expressed in SQL, this means that for every row in the track table, the following expression evaluates to true: trackartist IS NULL OR EXISTS(SELECT 1 FROM artist WHERE artistid=trackartist) +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys01.test, matrix: context, detail)

          + +
          R-52494-36749-63981-51564-54926-02873-46485-09219
          +

          SQLITE_DBSTATUS_CACHE_WRITE This parameter returns the number of dirty cache entries that have been written to disk. Specifically, the number of pages written to the wal file in wal mode databases, or the number of pages written to the database file in rollback mode databases. Any pages written as part of transaction rollback or database recovery operations are not included. If an IO or other error occurs while writing a page to disk, the effect on subsequent SQLITE_DBSTATUS_CACHE_WRITE requests is undefined. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-52502-32617-59424-01442-19182-34788-24122-07279
          +

          If a suffix is added to the zFilename parameter, it will consist of a single "-" character followed by no more than 11 alphanumeric and/or "-" characters. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-52566-22867-38000-46800-13895-09420-20056-05293
          +

          So to insert some data into our sample R*Tree index, we can do something like this: INSERT INTO demo_index VALUES( 1, -- Primary key -- SQLite.org headquarters -80.7749, -80.7747, -- Longitude range 35.3776, 35.3778 -- Latitude range ); INSERT INTO demo_index VALUES( 2, -- NC 12th Congressional District in 2010 -81.0, -79.6, 35.0, 36.2 ); The entries above might represent (for example) a bounding box around the main office for SQLite.org and bounding box around the 12th Congressional District of North Carolina (prior to the 2011 redistricting) in which SQLite.org was located. 3.3. Querying An R*Tree Index Any valid query will work against an R*Tree index. But the R*Tree implementation is designed to make two kinds of queries especially efficient. First, queries against the primary key are efficient: SELECT * FROM demo_index WHERE id=1; Of course, an ordinary SQLite table will also do a query against its integer primary key efficiently, so the previous is no big deal. The real reason for using an R*Tree is so that you can efficiently do inequality queries against the coordinate ranges. To find all elements of the index that are contained within the vicinity of Charlotte, North Carolina, one might do: SELECT id FROM demo_index WHERE minX>=-81.08 AND maxX<=-80.58 AND minY>=35.00 AND maxY<=35.44; The query above would very quickly locate the id of 1 even if the R*Tree contained millions of entries. The previous is an example of a "contained-within" query. The R*Tree also supports "overlapping" queries. For example, to find all bounding boxes that overlap the Charlotte area: SELECT id FROM demo_index WHERE maxX>=-81.08 AND minX<=-80.58 AND maxY>=35.00 AND minY<=35.44; This second query would find both entry 1 (the SQLite.org office) which is entirely contained within the query box and also the 12th Congressional District which extends well outside the query box but still overlaps the query box. +(source: rtree.html, matrix: context, detail)

          + +
          R-52572-02078-29727-01284-61421-00978-11983-52043
          +

          For the purposes of determining the uniqueness of primary key values, NULL values are considered distinct from all other values, including other NULLs. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-52584-04009-09183-39351-22068-55932-63814-54169
          +

          The rowid value can be accessed using one of the special case-independent names "rowid", "oid", or "_rowid_" in place of a column name. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-52585-35928-11217-60344-47086-04619-13740-01929
          +

          The max() aggregate function returns the maximum value of all values in the group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-52629-38967-65267-07230-17348-21667-50787-63164
          +

          The first parameter passed to the callback function when it is invoked is a copy of the third parameter passed to sqlite3_wal_hook() when registering the callback. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-52653-05256-00101-41227-35426-26812-44795-06520
          +

          These functions only work for dates between 0000-01-01 00:00:00 and 9999-12-31 23:59:59 (julian day numbers 1721059.5 through 5373484.5). +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-52668-48601-43859-11032-33191-58876-15768-53065
          +

          The default transaction behavior is DEFERRED. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-52669-16467-62181-15890-38253-37577-17953-50258
          +

          The first parameter is the prepared statement that implements the SELECT statement. +(source: c3ref/column_name.html, matrix: context, detail)

          + +
          R-52722-37312-59730-59343-41826-18723-03600-14255
          +

          The third parameter is a pointer to the implementation of the virtual table module. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-52747-41357-44885-51166-33553-21008-38098-18892
          +

          In some cases, VACUUM may also reduce the number of partially filled pages in the database, reducing the size of the database file further. +(source: lang_vacuum.html, matrix: context, detail)

          + +
          R-52756-41993-17034-10899-10921-49986-45271-10557
          +

          This function is a wrapper around the sqlite3_total_changes() C/C++ interface. +(source: lang_corefunc.html, checked-by: src/func.c, matrix: context, detail)

          + +
          R-52765-50368-61769-61482-53990-53504-23409-31144
          +

          Before the path or query components of a URI filename are interpreted, they are encoded using UTF-8 and all hexadecimal escape sequences replaced by a single byte containing the corresponding octet. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-52786-44878-02459-51231-59841-41905-39578-10951
          +

          SQLite defines three built-in collating functions: +(source: fileformat2.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-52799-16320-39840-10926-00511-08842-62770-55110
          +

          N is zero for the left-most function argument. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-52830-19955-18632-16869-37447-04753-28772-23279
          +

          A URI filename can optionally be followed by a query string. +(source: uri.html, matrix: context, detail)

          + +
          R-52843-09507-00185-40399-22075-19673-59320-05443
          +

          The sqlite_schema table contains entries for internal schema objects in addition to application- and programmer-defined objects. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-52858-40376-16050-37055-60638-11562-16087-23807
          +

          The soft heap limit may not be greater than the hard heap limit. +(source: c3ref/hard_heap_limit64.html, matrix: context, detail)

          + +
          R-52864-57317-33695-37364-46935-23221-38785-50224
          +

          For rows that define views, triggers, and virtual tables, the rootpage column is 0 or NULL. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-52874-10360-37775-63380-13039-47698-21027-19281
          +

          If the locking mode is NORMAL when first entering WAL journal mode, then the locking mode can be changed between NORMAL and EXCLUSIVE and back again at any time and without needing to exit WAL journal mode. +(source: pragma.html, checked-by: th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-52885-58365-34589-60224-33569-54251-15646-22637
          +

          The highwater mark associated with SQLITE_DBSTATUS_SCHEMA_USED is always 0. +(source: c3ref/c_dbstatus_options.html, checked-by: th3/req1/dbstatus01.test, th3/req1/dbstatus02.test, matrix: context, detail)

          + +
          R-52892-55360-15524-03344-29674-00712-56313-40382
          +

          This routine registers an authorizer callback with a particular database connection, supplied in the first argument. +(source: c3ref/set_authorizer.html, checked-by: th3/cov1/auth01.test, matrix: context, detail)

          + +
          R-52918-29603-61249-39870-15213-51167-58462-10808
          +

          Names are case sensitive. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-52940-53106-43126-08219-27163-02651-42624-21494
          +

          SQLITE_DBSTATUS_LOOKASIDE_MISS_FULL This parameter returns the number malloc attempts that might have been satisfied using lookaside memory but failed due to all lookaside memory already being in use. Only the high-water value is meaningful; the current value is always zero. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-52944-64228-64118-58952-09671-12918-63425-40021
          +

          The following is a complete list of valid strftime() substitutions: %d day of month: 00 %f fractional seconds: SS.SSS %H hour: 00-24 %j day of year: 001-366 %J Julian day number %m month: 01-12 %M minute: 00-59 %s seconds since 1970-01-01 %S seconds: 00-59 %w day of week 0-6 with Sunday==0 %W week of year: 00-53 %Y year: 0000-9999 %% % +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-52949-04679-63640-64673-56558-51308-22602-53102
          +

          When synchronous is FULL (2), the SQLite database engine will use the xSync method of the VFS to ensure that all content is safely written to the disk surface prior to continuing. +(source: pragma.html, matrix: context, detail)

          + +
          R-52975-24025-19782-48078-21253-08318-64480-41617
          +

          D is either a NULL pointer or a pointer to a destructor function for P. +(source: c3ref/bind_blob.html, checked-by: th3/cov1/carray01.test, matrix: context, detail)

          + +
          R-52979-05948-62253-13959-08616-19782-00231-65048
          +

          The sqlite3_create_module() interface is equivalent to sqlite3_create_module_v2() with a NULL destructor. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-53010-63100-48596-37758-55156-50818-27273-22273
          +

          SQLITE_DBSTATUS_SCHEMA_USED This parameter returns the approximate number of bytes of heap memory used to store the schema for all databases associated with the connection - main, temp, and any ATTACH-ed databases. +(source: c3ref/c_dbstatus_options.html, checked-by: th3/req1/dbstatus02.test, matrix: context, detail)

          + +
          R-53084-07740-56303-11732-40527-47126-44561-51023
          +

          An error is raised if the "AUTOINCREMENT" keyword is used in the CREATE TABLE statement for a WITHOUT ROWID table. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-53088-19343-27677-16808-20266-14528-30816-49365
          +

          The incremental blob I/O routines can only read or overwriting existing blob content; they cannot change the size of a blob. +(source: c3ref/blob_bytes.html, checked-by: tcl/e_blobbytes.test, th3/cov1/vdbeblob01.test, matrix: context, detail)

          + +
          R-53099-14426-29346-17813-35365-40265-31413-38800
          +

          A special SQL function RAISE() may be used within a trigger-program, +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-53139-25371-00097-20894-04129-08497-32476-32210
          +

          SQLite will never invoke SQLITE_FCNTL_ROLLBACK_ATOMIC_WRITE without a prior successful call to SQLITE_FCNTL_BEGIN_ATOMIC_WRITE. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-53195-24238-49524-21833-03175-16230-23443-12553
          +

          If sqlite3_backup_step(B,N) successfully finishes copying all pages from source to destination, then it returns SQLITE_DONE. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup03.test, matrix: context, detail)

          + +
          R-53201-01290-50295-51716-63557-40807-32035-47874
          +

          The content of each SQL table row is stored in the database file by first combining the values in the various columns into a byte array in the record format, then storing that byte array as the payload in an entry in the table b-tree. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-53201-15548-30250-52937-65049-09366-55722-10298
          +

          sqlite> EXPLAIN QUERY PLAN SELECT a FROM t1 EXCEPT SELECT d FROM t2 ORDER BY 1; QUERY PLAN `--MERGE (EXCEPT) |--LEFT | `--SCAN TABLE t1 USING COVERING INDEX i1 `--RIGHT |--SCAN TABLE t2 `--USE TEMP B-TREE FOR ORDER BY +(source: eqp.html, matrix: context, detail)

          + +
          R-53205-22341-54375-46881-03757-15307-06901-24042
          +

          The fourth parameter, eTextRep, specifies what text encoding this SQL function prefers for its parameters. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-53215-27584-18525-51882-25660-37940-21919-06094
          +

          If it is used by the second or subsequent such statement within a trigger program, the value returned reflects the number of rows modified by the previous INSERT, UPDATE or DELETE statement within the same trigger. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-53264-40062-38571-39514-17235-18477-59967-25878
          +

          If the Nth column returned by the statement is an expression or subquery and is not a column value, then all of these functions return NULL. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-53273-52304-57192-35830-05219-48039-41857-59674
          +

          Virtual terms are used for analysis only and do not cause any byte-code to be generated. +(source: optoverview.html, matrix: context, detail)

          + +
          R-53334-49168-61696-52419-22788-21864-59883-48546
          +

          For the index above and WHERE clause like this: ... WHERE a=5 AND b IN (1,2,3) AND c>12 AND d='hello' Only columns a, b, and c of the index would be usable. The d column would not be usable because it occurs to the right of c and c is constrained only by inequalities. +(source: optoverview.html, matrix: context, detail)

          + +
          R-53341-35419-60805-00614-53630-15165-00520-17900
          +

          Regardless of whether or not the limit was changed, the sqlite3_limit() interface returns the prior value of the limit. +(source: c3ref/limit.html, checked-by: src/main.c, th3/req1/limit01.test, matrix: context, detail)

          + +
          R-53354-47195-06587-01867-57045-45178-06835-07822
          +

          CREATE TABLE t1( x INTEGER PRIMARY KEY, a, /* collating sequence BINARY */ b COLLATE BINARY, /* collating sequence BINARY */ c COLLATE RTRIM, /* collating sequence RTRIM */ d COLLATE NOCASE /* collating sequence NOCASE */ ); /* x a b c d */ INSERT INTO t1 VALUES(1,'abc','abc', 'abc ','abc'); INSERT INTO t1 VALUES(2,'abc','abc', 'abc', 'ABC'); INSERT INTO t1 VALUES(3,'abc','abc', 'abc ', 'Abc'); INSERT INTO t1 VALUES(4,'abc','abc ','ABC', 'abc'); /* Text comparison a=b is performed using the BINARY collating sequence. */ SELECT x FROM t1 WHERE a = b ORDER BY x; --result 1 2 3 /* Text comparison a=b is performed using the RTRIM collating sequence. */ SELECT x FROM t1 WHERE a = b COLLATE RTRIM ORDER BY x; --result 1 2 3 4 /* Text comparison d=a is performed using the NOCASE collating sequence. */ SELECT x FROM t1 WHERE d = a ORDER BY x; --result 1 2 3 4 /* Text comparison a=d is performed using the BINARY collating sequence. */ SELECT x FROM t1 WHERE a = d ORDER BY x; --result 1 4 /* Text comparison 'abc'=c is performed using the RTRIM collating sequence. */ SELECT x FROM t1 WHERE 'abc' = c ORDER BY x; --result 1 2 3 /* Text comparison c='abc' is performed using the RTRIM collating sequence. */ SELECT x FROM t1 WHERE c = 'abc' ORDER BY x; --result 1 2 3 /* Grouping is performed using the NOCASE collating sequence (Values ** 'abc', 'ABC', and 'Abc' are placed in the same group). */ SELECT count(*) FROM t1 GROUP BY d ORDER BY 1; --result 4 /* Grouping is performed using the BINARY collating sequence. 'abc' and ** 'ABC' and 'Abc' form different groups */ SELECT count(*) FROM t1 GROUP BY (d || '') ORDER BY 1; --result 1 1 2 /* Sorting or column c is performed using the RTRIM collating sequence. */ SELECT x FROM t1 ORDER BY c, x; --result 4 1 2 3 /* Sorting of (c||'') is performed using the BINARY collating sequence. */ SELECT x FROM t1 ORDER BY (c||''), x; --result 4 2 3 1 /* Sorting of column c is performed using the NOCASE collating sequence. */ SELECT x FROM t1 ORDER BY c COLLATE NOCASE, x; --result 2 4 3 1 +(source: datatype3.html, checked-by: th3/req1/datatype3_08.test, matrix: context, detail)

          + +
          R-53361-24419-19828-49263-36591-42427-29848-60757
          +

          PRAGMA schema.locking_mode; PRAGMA schema.locking_mode = NORMAL | EXCLUSIVE +(source: pragma.html, checked-by: th3/req1/pragma04.test, matrix: context, detail)

          + +
          R-53367-43190-16013-34482-35638-20487-30911-18864
          +

          If either argument to this option is negative, then that argument is changed to its compile-time default. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-53367-44371-39189-42145-26716-53190-00022-58526
          +

          An expression of the form "CAST(expr AS type)" has an affinity that is the same as a column with a declared type of "type". +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-53378-00429-63656-00839-65291-28098-14033-06508
          +

          If this variable is a NULL pointer, then SQLite performs a search for an appropriate temporary file directory. +(source: c3ref/temp_directory.html, matrix: context, detail)

          + +
          R-53431-59159-09911-22042-14613-41147-21418-31229
          +

          The % operator casts both of its operands to type INTEGER and then computes the remainder after dividing the left integer by the right integer. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-53436-40973-13105-02748-62500-49771-13394-01786
          +

          The likely(X) function is equivalent to likelihood(X,0.9375). +(source: lang_corefunc.html, checked-by: src/resolve.c, matrix: context, detail)

          + +
          R-53473-04519-45856-48059-38257-59187-05509-43871
          +

          If the Nth column of the result set is an expression or subquery, then a NULL pointer is returned. +(source: c3ref/column_decltype.html, matrix: context, detail)

          + +
          R-53478-59161-12237-18673-01094-03147-04077-16034
          +

          The flags argument to xAccess() may be SQLITE_ACCESS_EXISTS to test for the existence of a file, or SQLITE_ACCESS_READWRITE to test whether a file is readable and writable, or SQLITE_ACCESS_READ to test whether a file is at least readable. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-53479-41922-39952-24779-27153-12886-60849-40367
          +

          A 4-dimensional R*Tree has 9 columns. +(source: rtree.html, matrix: context, detail)

          + +
          R-53505-01828-44329-62678-22950-03794-01329-32376
          +

          The lookaside memory configuration for a database connection can only be changed when that connection is not currently using lookaside memory, or in other words when the "current value" returned by sqlite3_db_status(D,SQLITE_CONFIG_LOOKASIDE,...) is zero. Any attempt to change the lookaside memory configuration when lookaside memory is in use leaves the configuration unchanged and returns SQLITE_BUSY. +(source: c3ref/c_dbconfig_defensive.html, checked-by: th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-53520-01610-10679-40002-23178-34440-17674-23927
          +

          The sqlite3_backup_step() might return SQLITE_READONLY if the destination database was opened read-only, or the destination database is using write-ahead-log journaling and the destination and source page sizes differ, or the destination database is an in-memory database and the destination and source page sizes differ. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-53528-47027-65277-23622-06185-25684-15860-07330
          +

          BINARY - Compares string data using memcmp(), regardless of text encoding. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-53536-42575-40544-57743-11521-12112-01903-53371
          +

          The sqlite3_libversion() function returns a pointer to the to the sqlite3_version[] string constant. +(source: c3ref/libversion.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-53547-37067-09638-20252-03189-64013-38251-09094
          +

          This pragma is a no-op within a transaction; foreign key constraint enforcement may only be enabled or disabled when there is no pending BEGIN or SAVEPOINT. +(source: pragma.html, checked-by: th3/req1/pragma18.test, matrix: context, detail)

          + +
          R-53666-61329-49768-59983-34751-33356-35133-56080
          +

          The values returned by these functions are only updated by sqlite3_backup_step(). If the source database is modified in a way that changes the size of the source database or the number of pages remaining, those changes are not reflected in the output of sqlite3_backup_pagecount() and sqlite3_backup_remaining() until after the next sqlite3_backup_step(). +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-53670-03373-29503-41803-42706-56849-33971-45159
          +

          The unary operator + is a no-op. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-53672-30929-36842-16986-17417-33321-43631-35859
          +

          If X comes from an SQL literal value, or a table column, or an expression, then sqlite3_value_frombind(X) returns zero. +(source: c3ref/value_blob.html, matrix: context, detail)

          + +
          R-53717-22688-52875-42885-33071-58467-09778-10973
          +

          The string value returned by this routine is owned and managed by the database connection. +(source: c3ref/db_filename.html, matrix: context, detail)

          + +
          R-53735-47017-47286-05670-21598-63500-17525-58856
          +

          If the expression is an aggregate expression, it is evaluated across all rows in the group. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-53739-41794-61362-55314-61050-59238-26275-11948
          +

          If this global variable is made to point to a string which is the name of a folder (a.k.a. directory), then all temporary files created by SQLite when using a built-in VFS will be placed in that directory. +(source: c3ref/temp_directory.html, matrix: context, detail)

          + +
          R-53739-48047-10287-11519-42885-23496-56458-39764
          +

          The new row must meet the same criteria as for sqlite3_blob_open() - it must exist and there must be either a blob or text value stored in the nominated column. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-53759-57366-14099-11673-51182-17816-42165-23586
          +

          The exact same sqlite3_rtree_geometry structure is used for every callback for same MATCH operator in the same query. +(source: rtree.html, matrix: context, detail)

          + +
          R-53782-41596-18711-17394-59679-49399-55234-36791
          +

          The argument N is the maximum number of bytes of the database file that will be accessed using memory-mapped I/O. +(source: pragma.html, matrix: context, detail)

          + +
          R-53820-33897-43817-17457-29508-48288-48051-25287
          +

          Even if there is a busy-handler configured, it will not be invoked in this case. +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/wal.c, tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-53882-48160-21334-05882-20873-26881-20436-15030
          +

          It not necessary to put generated columns at the end of the list of columns in the table definition, as is shown in the examples above. +(source: gencol.html, matrix: context, detail)

          + +
          R-53900-18983-14254-27441-52776-55824-16298-22482
          +

          SQLite will invoke the xMutexEnd() method when sqlite3_shutdown() is called, but only if the prior call to xMutexInit returned SQLITE_OK. +(source: c3ref/mutex_methods.html, matrix: context, detail)

          + +
          R-53924-08809-36668-27423-20589-58335-57366-25050
          +

          If there is more than one non-aggregate expression in the result-set, then all such expressions are evaluated for the same row. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-53924-42297-60529-07660-45668-52976-46184-14405
          +

          The sqlite3_hard_heap_limit64(N) interface sets a hard upper bound of N bytes on the amount of memory that will be allocated. +(source: c3ref/hard_heap_limit64.html, matrix: context, detail)

          + +
          R-53938-27527-43335-12056-46528-12200-49434-41509
          +

          Only changes made directly by the INSERT, UPDATE or DELETE statement are considered - auxiliary changes caused by triggers, foreign key actions or REPLACE constraint resolution are not counted. +(source: c3ref/changes.html, checked-by: tcl/e_changes.test, matrix: context, detail)

          + +
          R-53946-02894-03994-04896-49185-13086-04703-60466
          +

          These routines return information about a single column of the current result row of a query. +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, th3/req1/column02.test, th3/req1/column03.test, matrix: context, detail)

          + +
          R-53968-51642-29002-32833-59790-62444-61146-02233
          +

          Configuring an ON UPDATE or ON DELETE action does not mean that the foreign key constraint does not need to be satisfied. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys18.test, matrix: context, detail)

          + +
          R-53994-11873-49794-19921-48320-57211-64823-29959
          +

          The 4-byte big-endian integer at offset 60 is the user version which is set and queried by the user_version pragma. +(source: fileformat2.html, checked-by: th3/req1/fileformat03.test, matrix: context, detail)

          + +
          R-53994-49363-33213-19869-13324-28404-40753-33810
          +

          If the authority section is omitted, then the path is an absolute pathname if it begins with the "/" character (ASCII code 0x2f) and is a relative pathname otherwise. +(source: uri.html, matrix: context, detail)

          + +
          R-54020-18969-35305-43404-58494-09530-16898-08730
          +

          The minimum key value is 1. +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-54034-37639-41781-11443-11424-21021-61180-47109
          +

          If the 3rd parameter to the sqlite3_result_text* interfaces is negative, then SQLite takes result text from the 2nd parameter through the first zero character. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-54035-60779-28299-56700-44695-40391-47008-32723
          +

          The soft heap limit is "soft" because even though SQLite strives to stay below the limit, it will exceed the limit rather than generate an SQLITE_NOMEM error. +(source: c3ref/hard_heap_limit64.html, checked-by: th3/req1/softheaplimit02.test, matrix: context, detail)

          + +
          R-54043-63736-37256-25763-10275-07807-60527-63818
          +

          SQLITE_DBSTATUS_LOOKASIDE_MISS_SIZE This parameter returns the number malloc attempts that might have been satisfied using lookaside memory but failed due to the amount of memory requested being larger than the lookaside slot size. Only the high-water value is meaningful; the current value is always zero. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-54046-48600-47086-52711-24230-00638-25946-34111
          +

          When comparing values as a result of a USING clause, the normal rules for handling affinities, collation sequences and NULL values in comparisons apply. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-54056-32692-17641-45055-32204-64266-46866-10760
          +

          An operand of a comparison is considered to have an explicit collating function assignment (rule 1 above) if any subexpression of the operand uses the postfix COLLATE operator. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-54100-20147-64333-16407-13054-37480-42962-25139
          +

          The highwater mark associated with SQLITE_DBSTATUS_CACHE_MISS is always 0. +(source: c3ref/c_dbstatus_options.html, checked-by: src/status.c, matrix: context, detail)

          + +
          R-54105-45069-36894-51687-59300-29186-60662-50296
          +

          Changing the foreign_keys setting affects the execution of all statements prepared using the database connection, including those prepared before the setting was changed. +(source: pragma.html, checked-by: th3/req1/pragma18.test, matrix: context, detail)

          + +
          R-54138-14726-01342-01077-27366-45054-60392-40592
          +

          The sixth, seventh, eighth and ninth parameters (xStep, xFinal, xValue and xInverse) passed to sqlite3_create_window_function are pointers to C-language callbacks that implement the new function. +(source: c3ref/create_function.html, matrix: context, detail)

          + +
          R-54142-41346-32014-56293-25636-63110-30822-28140
          +

          The properties of the DROP TABLE and ALTER TABLE commands described above only apply if foreign keys are enabled. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys22.test, matrix: context, detail)

          + +
          R-54172-54170-29331-23732-60109-43479-50710-53922
          +

          The sqlite3_snapshot_free(P) interface destroys sqlite3_snapshot P. +(source: c3ref/snapshot_free.html, matrix: context, detail)

          + +
          R-54218-24562-17509-58575-21096-25882-18026-33588
          +

          The NNN value must be between 1 and the sqlite3_limit() parameter SQLITE_LIMIT_VARIABLE_NUMBER (default value: 32766). +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-54219-22147-53235-46719-19479-08650-29878-29792
          +

          The sqlite3_str_value(X) method returns a pointer to the current content of the dynamic string under construction in X. +(source: c3ref/str_errcode.html, matrix: context, detail)

          + +
          R-54260-17937-27956-02792-29631-43521-06975-25593
          +

          When a new row is inserted into an SQLite table, the ROWID can either be specified as part of the INSERT statement or it can be assigned automatically by the database engine. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-54272-29032-18669-23400-04748-20753-02544-31833
          +

          If N is negative, all remaining source pages are copied. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup03.test, matrix: context, detail)

          + +
          R-54275-45098-32061-17354-31139-20112-21246-15357
          +

          These routines might also return NULL if a memory allocation error occurs. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-54293-07495-13048-34845-43688-00379-35800-25394
          +

          The first six modifiers (1 through 6) simply add the specified amount of time to the date and time specified by the arguments to the left. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-54349-27488-43340-32008-63380-57974-11339-53896
          +

          This pragma uses sqlite3_create_function() to overload the LIKE and GLOB functions, which may override previous implementations of LIKE and GLOB registered by the application. +(source: pragma.html, checked-by: th3/req1/pragma10.test, matrix: context, detail)

          + +
          R-54378-38553-30727-53168-14484-58684-10446-07107
          +

          If numerical data is inserted into a column with TEXT affinity it is converted into text form before being stored. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-54405-49237-08494-43030-09178-29005-00449-25094
          +

          The sqlite3_str_appendall(X,S) method appends the complete content of zero-terminated string S onto the end of sqlite3_str object X. +(source: c3ref/str_append.html, matrix: context, detail)

          + +
          R-54466-46756-05959-55829-53224-11229-48614-30148
          +

          If SQLite is compiled with the SQLITE_THREADSAFE=0 compile-time option then it is not possible to change the threading mode from its default value of Single-thread and so sqlite3_config() will return SQLITE_ERROR if called with the SQLITE_CONFIG_SINGLETHREAD configuration option. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-54493-30181-37798-05514-46235-61023-30019-39106
          +

          The sqlite3_soft_heap_limit64() interface sets and/or queries the soft limit on the amount of heap memory that may be allocated by SQLite. +(source: c3ref/hard_heap_limit64.html, checked-by: th3/req1/softheaplimit01.test, matrix: context, detail)

          + +
          R-54562-06892-25259-07703-54157-59355-38292-12890
          +

          The behavior of "PRAGMA data_version" is the same for all database connections, including database connections in separate processes and shared cache database connections. +(source: pragma.html, checked-by: tcl/pragma3.test, matrix: context, detail)

          + +
          R-54577-32145-57305-62671-23422-08381-26358-15334
          +

          Compute the date and time given a unix timestamp 1092941466. SELECT datetime(1092941466, 'unixepoch'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-54592-23151-09328-60476-49284-22460-04291-25126
          +

          This function does not set the database handle error code or message returned by the sqlite3_errcode() and sqlite3_errmsg() functions. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-54611-06855-62690-60121-09688-57757-21462-60136
          +

          The expression following the WHERE clause may contain operators, literal values, and names of columns in the table being indexed. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-54614-40903-43648-00840-19083-45681-47455-60151
          +

          The rules for determining which collating function to use for a binary comparison operator (=, <, >, <=, >=, !=, IS, and IS NOT) are as follows: +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-54671-04027-22136-36062-14023-39261-02732-05176
          +

          The ifnull() function returns a copy of its first non-NULL argument, or NULL if both arguments are NULL. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-54702-17780-20915-24655-06816-59842-01536-54593
          +

          When a UNIQUE or PRIMARY KEY constraint violation occurs, the REPLACE algorithm deletes pre-existing rows that are causing the constraint violation prior to inserting or updating the current row and the command continues executing normally. +(source: lang_conflict.html, checked-by: th3/req1/conflict02.test, matrix: context, detail)

          + +
          R-54721-48557-63407-03546-07641-33336-53635-34168
          +

          If there is no ELSE expression and none of the WHEN expressions produce a result equal to the base expression, the overall result is NULL. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-54737-49034-36463-44594-64965-25751-29163-41666
          +

          The cell pointers are arranged in key order with left-most cell (the cell with the smallest key) first and the right-most cell (the cell with the largest key) last. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-54755-39291-22328-03349-12952-06333-56270-04082
          +

          The PRIMARY KEY is optional for ordinary tables but is required for WITHOUT ROWID tables. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-54780-55967-39790-26433-61749-36346-50867-30615
          +

          The datetime() function returns "YYYY-MM-DD HH:MM:SS". +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-54781-23071-09729-07904-20031-27691-48494-39961
          +

          The DROP TABLE command works on statistics tables as of SQLite version 3.7.9. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-54814-00088-09992-08072-08455-19266-24087-41023
          +

          A trace callback is invoked with four arguments: callback(T,C,P,X). +(source: c3ref/trace_v2.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-54872-08741-62719-64632-51902-03049-34462-47837
          +

          Changes to a view that are intercepted by INSTEAD OF triggers are not counted. +(source: c3ref/total_changes.html, checked-by: tcl/e_totalchanges.test, matrix: context, detail)

          + +
          R-54898-34554-42956-11210-21105-01944-03178-39152
          +

          When casting a TEXT value to REAL, the longest possible prefix of the value that can be interpreted as a real number is extracted from the TEXT value and the remainder ignored. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-54913-41491-50260-09040-49829-18676-09673-35147
          +

          This is the number of times that the prepare statement has been automatically regenerated due to schema changes or changes to bound parameters that might affect the query plan. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-54914-35280-25250-15027-11750-01727-31556-09932
          +

          The checksum algorithm is as follows: s0 = s1 = 0 for i from 0 to n-1 step 2: s0 += x(i) + s1; s1 += x(i+1) + s0; endfor # result in s0 and s1 +(source: fileformat2.html, matrix: context, detail)

          + +
          R-54918-11103-44275-41655-39625-25925-11501-45553
          +

          If zVfsName is NULL then the default VFS is returned. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-54925-42075-28504-27777-13871-37665-20055-23123
          +

          In a normal index, there is a one-to-one mapping between rows in a table and entries in each index associated with that table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-54935-19057-55411-14278-34768-16661-27190-25243
          +

          Or, if the SELECT statement would return less than N rows without a LIMIT clause, then the entire result set is returned. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-54961-28617-11438-13073-24028-16766-12231-36247
          +

          "SCAN" is used for a full-table scan, including cases where SQLite iterates through all records in a table in an order defined by an index. +(source: eqp.html, matrix: context, detail)

          + +
          R-54967-64139-35056-57094-27190-32604-29267-26110
          +

          If any databases are skipped because locks cannot be obtained, but no other error occurs, this function returns SQLITE_BUSY. +(source: c3ref/db_cacheflush.html, matrix: context, detail)

          + +
          R-54971-39725-56830-50400-02582-07563-61018-15429
          +

          The xCachesize() method may be called at any time by SQLite to set the suggested maximum cache-size (number of pages stored by) the cache instance passed as the first argument. This is the value configured using the SQLite "PRAGMA cache_size" command. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-55025-21042-57260-24001-55816-18376-64535-50045
          +

          The identifier name in this case can include one or more occurrences of "::" and a suffix enclosed in "(...)" containing any text at all. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-55061-47754-54391-02401-15466-20656-29553-32154
          +

          The COLLATE clause specifies the name of a collating sequence to use as the default collation sequence for the column. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-55069-12282-57104-06256-56752-59196-49409-09981
          +

          The default conflict resolution algorithm is ABORT. +(source: lang_conflict.html, checked-by: th3/req1/conflict03.test, matrix: context, detail)

          + +
          R-55072-00299-56529-46464-12562-60725-23596-59611
          +

          As with PRIMARY KEYs, a UNIQUE table-constraint clause must contain only column names — the use of expressions in an indexed-column of a UNIQUE table-constraint is not supported. +(source: lang_createtable.html, matrix: context, detail)

          + +
          R-55084-10555-33415-01077-58327-07092-00273-30693
          +

          Casting a TEXT or BLOB value into NUMERIC yields either an INTEGER or a REAL result. +(source: lang_expr.html, checked-by: tcl/cast.test, tcl/e_expr.test, th3/cov1/cast01.test, matrix: context, detail)

          + +
          R-55089-42193-42390-08039-05012-03378-63784-16707
          +

          If the argument N is omitted, then the analysis limit is unchanged. +(source: pragma.html, matrix: context, detail)

          + +
          R-55119-57913-09912-49020-08762-55611-23100-00371
          +

          By default, VACUUM only works only on the main database. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-55130-30724-57761-34999-45544-53302-25388-55825
          +

          The sqlite3_table_column_metadata() interface returns SQLITE_ERROR if the specified column does not exist. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-55137-26834-36059-41974-16460-01927-24032-61978
          +

          For the purposes of unique indices, all NULL values are considered different from all other NULL values and are thus unique. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-55138-13241-38479-09846-46068-29398-26502-36438
          +

          An alternative to using the VACUUM command to reclaim space after data has been deleted is auto-vacuum mode, enabled using the auto_vacuum pragma. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-55147-47664-01653-03142-36497-30903-54815-06427
          +

          For as long as the user has an open transaction, the database is allowed to exist in a state that violates any number of deferred foreign key constraints. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, th3/req1/foreignkeys14.test, matrix: context, detail)

          + +
          R-55189-15164-61309-44787-48881-65424-27276-43718
          +

          The sqlite3_initialize() routine is called internally by many other SQLite interfaces so that an application usually does not need to invoke sqlite3_initialize() directly. +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-55246-25452-29787-15226-62317-06868-45565-21162
          +

          There are some contexts in SQLite that do not allow the use of non-deterministic functions: In the expression of a CHECK constraint. In the WHERE clause of a partial index. In an expression used as part of an expression index. In the expression of a generated column. +(source: deterministic.html, matrix: context, detail)

          + +
          R-55258-32329-20179-17327-29048-20222-48155-64370
          +

          Any command that accesses the database (basically, any SQL command, except a few PRAGMA statements) will automatically start a transaction if one is not already in effect. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-55269-29598-22145-31317-31671-53288-42244-17124
          +

          The localtime_r() C function normally only works for years between 1970 and 2037. For dates outside this range, SQLite attempts to map the year into an equivalent year within this range, do the calculation, then map the year back. +(source: lang_datefunc.html, checked-by: src/date.c, matrix: context, detail)

          + +
          R-55292-54599-58036-06496-23806-16073-05204-14716
          +

          The first integer in this list is the approximate number of rows in the index. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-55312-58443-27187-57557-21962-11397-57143-02839
          +

          The SQLITE_VERSION_NUMBER C preprocessor macro resolves to an integer with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z are the same numbers used in SQLITE_VERSION. +(source: c3ref/c_source_id.html, checked-by: th3/req1/version01.test, matrix: context, detail)

          + +
          R-55316-21772-61172-01789-50748-54713-63157-59070
          +

          If the VFS does not support shared-memory methods, then the attempt to open a database that is already in WAL mode, or the attempt convert a database into WAL mode, will fail. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-55351-62604-52448-54183-29592-46679-39320-37048
          +

          A single row of a table cannot store more than SQLITE_MAX_LENGTH bytes of data. +(source: lang_createtable.html, matrix: context, detail)

          + +
          R-55352-50321-25777-65350-51066-10256-38308-17470
          +

          The number of columns in the result can be determined using sqlite3_column_count(). +(source: c3ref/column_blob.html, checked-by: th3/req1/column01.test, matrix: context, detail)

          + +
          R-55381-29093-22266-09255-42316-49532-06927-42379
          +

          IMMEDIATE cause the database connection to start a new write immediately, without waiting for a write statement. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-55392-56277-35725-48242-28273-14685-15840-32650
          +

          If the third parameter to sqlite3_bind_text() or sqlite3_bind_text16() or sqlite3_bind_blob() is a NULL pointer then the fourth parameter is ignored and the end result is the same as sqlite3_bind_null(). +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-55398-57340-09635-03247-16694-08409-20914-48585
          +

          Setting parameter X to NULL disables the progress handler. +(source: c3ref/progress_handler.html, checked-by: th3/req1/progress01.test, matrix: context, detail)

          + +
          R-55403-13450-43666-61222-09717-03349-14429-52085
          +

          The HAVING expression may refer to values, even aggregate functions, that are not in the result. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-55406-38524-31149-09087-45874-46813-10331-17259
          +

          A percent symbol ("%") in the LIKE pattern matches any sequence of zero or more characters in the string. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-55407-45319-53851-58560-05892-08992-42854-39100
          +

          The declared type of each column is determined by the expression affinity of the corresponding expression in the result set of the SELECT statement, as follows: Expression Affinity Column Declared Type TEXT "TEXT" NUMERIC "NUM" INTEGER "INT" REAL "REAL" BLOB (a.k.a "NONE") "" (empty string) +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-55422-28457-57897-11786-10838-58259-25547-52567
          +

          Changing the recursive_triggers setting affects the execution of all statements prepared using the database connection, including those prepared before the setting was changed. +(source: pragma.html, matrix: context, detail)

          + +
          R-55435-14303-03333-49029-22084-10936-61067-18432
          +

          Each time a new row is inserted into the table or an existing row is updated, the expression associated with each CHECK constraint is evaluated and cast to a NUMERIC value in the same way as a CAST expression. If the result is zero (integer value 0 or real value 0.0), then a constraint violation has occurred. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-55438-03590-29197-39620-12271-07480-54322-54101
          +

          The same VFS can be registered multiple times without injury. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-55460-47820-18774-52597-12272-16306-23027-62332
          +

          If there is a blocking connection, then the extended error code is set to SQLITE_LOCKED_SHAREDCACHE. Otherwise, in the special "DROP TABLE/INDEX" case, the extended error code is just SQLITE_LOCKED. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-55469-62130-44621-63602-01605-63421-57069-12544
          +

          The char(X1,X2,...,XN) function returns a string composed of characters having the unicode code point values of integers X1 through XN, respectively. +(source: lang_corefunc.html, checked-by: tcl/func.test, matrix: context, detail)

          + +
          R-55478-19008-07990-22880-24783-58740-20121-48079
          +

          The "localtime" modifier (12) assumes the time value to its left is in Universal Coordinated Time (UTC) and adjusts that time value so that it is in localtime. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-55530-52930-45065-40235-10917-28940-04210-09538
          +

          In a well-formed b-tree page, there will always be at least one cell before the first freeblock. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-55532-10108-63513-58109-24698-43338-62703-39415
          +

          Values 1, 1.0, 0.1, -0.1 and '1english' are considered to be true. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-55548-33817-29284-24020-20403-44127-42701-15933
          +

          The compile-time setting for URI filenames can be changed at start-time using the sqlite3_config(SQLITE_CONFIG_URI,1) or sqlite3_config(SQLITE_CONFIG_URI,0) configuration calls. +(source: uri.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-55594-21030-55644-51033-26913-03312-40389-27101
          +

          The SQLITE_CONFIG_MALLOC option takes a single argument which is a pointer to an instance of the sqlite3_mem_methods structure. The argument specifies alternative low-level memory allocation routines to be used in place of the memory allocation routines built into SQLite. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3oom.c, matrix: context, detail)

          + +
          R-55595-13513-43287-07115-18907-23748-32560-50080
          +

          The strftime() function also takes a format string as its first argument. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-55606-57227-21877-64681-10447-20017-21356-32881
          +

          If the RELEASE command causes the transaction stack to become empty (if the RELEASE command releases the outermost transaction from the stack) then the transaction commits. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-55636-16561-36868-23956-09727-21947-00276-50271
          +

          If two or more tables in different databases have the same name and the schema-name prefix is not used on a table reference, then the table chosen is the one in the database that was least recently attached. +(source: lang_attach.html, checked-by: th3/req1/attach01.test, matrix: context, detail)

          + +
          R-55638-04244-14117-31927-31561-07826-29267-09174
          +

          The sqlite3_reset(S) interface does not change the values of any bindings on the prepared statement S. +(source: c3ref/reset.html, checked-by: th3/req1/clearbind01.test, matrix: context, detail)

          + +
          R-55640-01652-03650-49788-46468-05074-56971-00383
          +

          The column is used in a foreign key constraint. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-55672-01620-31109-43050-24330-12239-06929-55084
          +

          The first column is the name of the table that contains the REFERENCES clause. +(source: pragma.html, checked-by: tcl/fkey5.test, th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-55673-47845-33764-15957-40467-43694-47305-60720
          +

          The memory high-water mark is reset to the current value of sqlite3_memory_used() if and only if the parameter to sqlite3_memory_highwater() is true. +(source: c3ref/memory_highwater.html, matrix: context, detail)

          + +
          R-55700-34343-49028-33969-14549-05550-41139-48792
          +

          This pragma does a low-level formatting and consistency check of the database. +(source: pragma.html, matrix: context, detail)

          + +
          R-55708-49653-17675-07799-20555-47879-27152-48993
          +

          When COMMIT fails in this way, the transaction remains active and the COMMIT can be retried later after the reader has had a chance to clear. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-55733-20912-49393-01361-02084-05970-17120-19612
          +

          If the callback function of the 3rd argument to sqlite3_exec() is not NULL, then it is invoked for each result row coming out of the evaluated SQL statements. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-55814-22637-16882-39129-49686-50158-19394-50709
          +

          The "SET DEFAULT" actions are similar to "SET NULL", except that each of the child key columns is set to contain the column's default value instead of NULL. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-55820-29984-60455-07962-21616-40941-09415-50372
          +

          In most cases, UNIQUE and PRIMARY KEY constraints are implemented by creating a unique index in the database. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-55837-00155-61561-08494-32854-35753-30155-49706
          +

          The pUser variable may be set by the callback implementation to any arbitrary value that may be useful to subsequent invocations of the callback within the same query (for example, a pointer to a complicated data structure used to test for region intersection). +(source: rtree.html, matrix: context, detail)

          + +
          R-55869-30521-47622-53163-51064-21445-33319-34731
          +

          If the UPDATE statement does not have a WHERE clause, all rows in the table are modified by the UPDATE. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-55888-39002-08567-49374-03343-41740-10082-36394
          +

          Extension loading is off by default. +(source: c3ref/enable_load_extension.html, matrix: context, detail)

          + +
          R-55903-20082-12808-10678-61421-17044-64440-32605
          +

          The idxNum and idxPtr values are recorded and passed into the xFilter method. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-55970-49067-15919-18439-36628-50905-05103-43155
          +

          If the new row is not present in the table, or if it does not contain a blob or text value, or if another error occurs, an SQLite error code is returned and the blob handle is considered aborted. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-55989-34690-53025-39227-28195-61827-56491-03494
          +

          If an index is created using a statement like this: CREATE INDEX idx_ex1 ON ex1(a,b,c,d,e,...,y,z); Then the index might be used if the initial columns of the index (columns a, b, and so forth) appear in WHERE clause terms. +(source: optoverview.html, matrix: context, detail)

          + +
          R-56020-12355-36965-55890-52401-50899-40834-02969
          +

          To overcome this problem, a separate data structure called the wal-index is maintained to expedite the search for frames of a particular page. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-56032-24923-44084-62651-61742-23069-00366-25575
          +

          The foreign key constraint is satisfied if for each row in the child table either one or more of the child key columns are NULL, or there exists a row in the parent table for which each parent key column contains a value equal to the value in its associated child key column. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys03.test, matrix: context, detail)

          + +
          R-56045-57163-57243-01717-21782-41584-31182-16126
          +

          If the third parameter (the pointer to the sqlite3_module object) is NULL then no new module is create and any existing modules with the same name are dropped. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-56064-04001-25559-63693-43897-15444-07346-25115
          +

          The %p format is an alias for %X. +(source: lang_corefunc.html, checked-by: tcl/printf2.test, th3/cov1/printf08.test, matrix: context, detail)

          + +
          R-56075-46525-28921-54400-33560-07294-24655-01890
          +

          The source and destination database connections (parameters S and D) must be different or else sqlite3_backup_init(D,N,S,M) will fail with an error. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup02.test, matrix: context, detail)

          + +
          R-56088-25150-58914-01692-09523-48299-30387-32306
          +

          The group_concat() function returns a string which is the concatenation of all non-NULL values of X. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-56094-57830-57463-55156-04028-13498-23873-32141
          +

          the following three table declarations all cause the column "x" to be an alias for the rowid (an integer primary key): CREATE TABLE t(x INTEGER PRIMARY KEY ASC, y, z); CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x ASC)); CREATE TABLE t(x INTEGER, y, z, PRIMARY KEY(x DESC)); +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-56101-50212-09292-39432-28945-47695-30385-48702
          +

          For the purposes of the previous sentence, a column name preceded by one or more unary "+" operators and/or CAST operators is still considered a column name. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-56132-15700-29603-38264-36933-60961-45364-58760
          +

          This is the only difference between a USING clause and its equivalent ON constraint. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-56143-29319-15474-25022-04217-21901-07164-36607
          +

          PRAGMA schema.index_xinfo(index-name); This pragma returns information about every column in an index. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15x.test, matrix: context, detail)

          + +
          R-56168-33548-13029-39450-16925-62002-00954-18437
          +

          The aConstraint[] array records WHERE clause constraints of the form: column OP expr where OP is =, <, <=, >, or >=. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-56208-64576-63593-38076-41294-48177-09207-06182
          +

          If this routine returns 0, that means the prepared statement returns no data (for example an UPDATE). +(source: c3ref/column_count.html, matrix: context, detail)

          + +
          R-56236-11699-62098-20167-23584-50570-40984-46383
          +

          The string 'UTF-16' is interpreted as "UTF-16 encoding using native machine byte-ordering". +(source: pragma.html, checked-by: th3/req1/pragma16.test, matrix: context, detail)

          + +
          R-56249-28265-13438-15861-43462-53554-35799-32319
          +

          Compute the current date. SELECT date('now'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-56255-17851-46934-55657-46753-27526-25250-09423
          +

          The C argument is a copy of the context pointer. +(source: c3ref/trace_v2.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-56256-08578-55482-47155-20535-53157-53389-52654
          +

          In the "v2" interface, the more specific error code is returned directly by sqlite3_step(). +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-56280-17369-11717-14525-09241-09664-14556-20621
          +

          Both forms of the CASE expression use lazy, or short-circuit, evaluation. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-56294-03966-08864-53339-51473-44924-63281-58418
          +

          All types of SELECT statement, including aggregate and compound SELECT queries (queries with keywords like UNION or EXCEPT) are allowed as scalar subqueries. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-56352-62404-53777-34179-15915-63338-07108-44476
          +

          However, since SQLite version 3.35.0, TEMP triggers are still allowed even if this option is off. So, in other words, this option now only disables triggers in the main database schema or in the schemas of ATTACH-ed databases. +(source: c3ref/c_dbconfig_defensive.html, matrix: context, detail)

          + +
          R-56368-08028-57945-39505-32022-20213-21801-17605
          +

          The iif(X,Y,Z) function is logically equivalent to and generates the same bytecode as the CASE expression "CASE WHEN X THEN Y ELSE Z END". +(source: lang_corefunc.html, matrix: context, detail)

          + +
          R-56376-21261-47968-49600-56386-05495-27914-63410
          +

          Column zColumn does not exist +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-56419-60514-06155-63301-38811-42368-46598-13480
          +

          However, in a partial index, the index b-tree only contains entries corresponding to table rows for which the WHERE clause expression on the CREATE INDEX statement is true. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-56424-18878-13584-40742-26912-14341-05618-57860
          +

          The first parameter is an operation code that determines the number, meaning, and operation of all subsequent parameters. +(source: c3ref/test_control.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-56469-26825-44365-22627-52974-52312-09458-38219
          +

          Within the xUpdate method of a virtual table, the sqlite3_value_nochange(X) interface returns true if and only if the column corresponding to X is unchanged by the UPDATE operation that the xUpdate method call was invoked to implement and if and the prior xColumn method call that was invoked to extracted the value for that column returned without setting a result (probably because it queried sqlite3_vtab_nochange() and found that the column was unchanging). +(source: c3ref/value_blob.html, matrix: context, detail)

          + +
          R-56511-46089-40273-37812-64837-44245-01436-05433
          +

          When the write-ahead log is enabled (via the journal_mode pragma) a checkpoint will be run automatically whenever the write-ahead log equals or exceeds N pages in length. +(source: pragma.html, matrix: context, detail)

          + +
          R-56518-44310-03576-50973-10041-44259-32136-55602
          +

          The second parameter to the callback is an integer action code that specifies the particular action to be authorized. +(source: c3ref/set_authorizer.html, checked-by: src/tclsqlite.c, th3/th3util.c, matrix: context, detail)

          + +
          R-56522-34239-18790-35664-56574-22774-39070-01307
          +

          an implicit DELETE FROM does cause any configured foreign key actions to take place. +(source: lang_droptable.html, checked-by: th3/req1/droptable01.test, matrix: context, detail)

          + +
          R-56593-29586-46477-05582-12262-16741-07169-41199
          +

          The default encoding for databases created using sqlite3_open16() will be UTF-16 in the native byte order. +(source: c3ref/open.html, checked-by: th3/cov1/main12.test, matrix: context, detail)

          + +
          R-56683-13731-54307-64156-42285-19581-37676-29217
          +

          If the optional ESCAPE clause is present, then the expression following the ESCAPE keyword must evaluate to a string consisting of a single character. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-56692-55226-52354-63477-50727-27057-22841-42848
          +

          If sqlite3_malloc() is unable to obtain sufficient free memory, it returns a NULL pointer. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-56743-17266-53373-09142-21068-04228-42328-23175
          +

          The conversion from STRING or BLOB into REAL or INTEGER is performed even if it is lossy and irreversible. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-56805-28429-09038-27116-20961-52646-32004-47216
          +

          Note that "monotonically increasing" does not imply that the ROWID always increases by exactly one. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-56841-45734-29539-09781-39505-27779-01471-37796
          +

          If the argument is an index name, then only that one index is analyzed. +(source: lang_analyze.html, checked-by: th3/req1/analyze01.test, matrix: context, detail)

          + +
          R-56844-61705-36939-38835-21077-60167-01566-10120
          +

          If the current statement is not inside an explicit transaction (a BEGIN/COMMIT/ROLLBACK block), then an implicit transaction is committed as soon as the statement has finished executing. In this case deferred constraints behave the same as immediate constraints. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys12.test, matrix: context, detail)

          + +
          R-56861-42673-10667-36418-55159-59166-26000-55286
          +

          sqlite3_prepare_v3() differs from sqlite3_prepare_v2() only in having the extra prepFlags parameter, which is a bit array consisting of zero or more of the SQLITE_PREPARE_* flags. +(source: c3ref/prepare.html, checked-by: src/prepare.c, matrix: context, detail)

          + +
          R-56899-62057-33576-54227-58668-21470-57671-19997
          +

          Use this routine to reset all host parameters to NULL. +(source: c3ref/clear_bindings.html, checked-by: th3/req1/clearbind01.test, matrix: context, detail)

          + +
          R-56910-04118-27168-31313-21595-13844-47285-28502
          +

          The reverse_unordered_selects pragma works for most SELECT statements, however the query planner may sometimes choose an algorithm that is not easily reversed, in which case the output will appear in the same order regardless of the reverse_unordered_selects setting. +(source: pragma.html, checked-by: th3/req1/pragma27.test, matrix: context, detail)

          + +
          R-56921-36726-52234-49163-41445-49849-43983-14131
          +

          The module takes zero or more comma-separated arguments. +(source: lang_createvtab.html, matrix: context, detail)

          + +
          R-56922-36205-22482-11354-54881-45664-41752-42246
          +

          The sqlite3_str_appendf(X,F,. +(source: c3ref/str_append.html, matrix: context, detail)

          + +
          R-56934-42700-38980-08605-33652-52881-52643-23900
          +

          A trigger normally exists in the same database as the table named after the "ON" keyword in the CREATE TRIGGER statement. Except, it is possible to create a TEMP TRIGGER on a table in another database. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-56960-03061-20836-21931-13129-13661-26943-05315
          +

          The sqlite_sequence row for an AUTOINCREMENT table is automatically deleted when the table is dropped. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-57019-29874-21566-05710-22141-45725-52460-50437
          +

          Attempt to return the underlying operating system error code or error number that caused the most recent I/O error or failure to open a file. +(source: c3ref/system_errno.html, matrix: context, detail)

          + +
          R-57025-62168-38373-42436-38968-34840-50734-33391
          +

          The CREATE INDEX command consists of the keywords "CREATE INDEX" followed by the name of the new index, the keyword "ON", the name of a previously created table that is to be indexed, and a parenthesized list of table column names and/or expressions that are used for the index key. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-57047-10461-09824-05395-44122-51121-43183-19652
          +

          For each pair of columns identified by a USING clause, the column from the right-hand dataset is omitted from the joined dataset. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-57051-20322-05054-14581-57313-02803-59746-15019
          +

          TEMP triggers are not subject to the same-database rule. A TEMP trigger is allowed to query or modify any table in any ATTACH-ed database. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-57064-52104-64431-17226-40317-39085-08319-65218
          +

          A keyword enclosed in grave accents (ASCII code 96) is an identifier. +(source: lang_keywords.html, checked-by: th3/req1/keyword01.test, matrix: context, detail)

          + +
          R-57089-01510-52711-12029-01843-57322-48096-53622
          +

          The optional IF EXISTS clause suppresses the error that would normally result if the table does not exist. +(source: lang_droptable.html, checked-by: th3/req1/droptable01.test, matrix: context, detail)

          + +
          R-57089-20897-11493-55029-43412-10473-15914-29086
          +

          The hex() function interprets its argument as a BLOB and returns a string which is the upper-case hexadecimal rendering of the content of that blob. +(source: lang_corefunc.html, checked-by: th3/cov1/func01.test, matrix: context, detail)

          + +
          R-57132-64688-04338-28404-47453-24973-03948-35534
          +

          For a K-column index, there will be K+1 integers in the stat column. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-57148-27043-24197-50864-17789-27068-60020-34476
          +

          If a term of the WHERE clause is of the following form: expr1 BETWEEN expr2 AND expr3 Then two "virtual" terms are added as follows: expr1 >= expr2 AND expr1 <= expr3 +(source: optoverview.html, matrix: context, detail)

          + +
          R-57180-61125-28109-34818-16201-30872-33443-40704
          +

          If the D parameter is not NULL, then it is a pointer to a destructor for the P parameter. +(source: c3ref/result_blob.html, checked-by: th3/cov1/bindptr01.test, matrix: context, detail)

          + +
          R-57195-25932-26146-45143-15236-49265-31478-06435
          +

          When a column is indexed, the same collating function specified in the CREATE TABLE statement is used for the column in the index, by default, though this can be overridden using a COLLATE clause in the CREATE INDEX statement. +(source: fileformat2.html, checked-by: th3/req1/fileformat05.test, matrix: context, detail)

          + +
          R-57201-47694-05778-38752-41584-16986-28240-11084
          +

          SQLITE_OPEN_NOFOLLOW The database filename is not allowed to be a symbolic link +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-57216-60803-31079-31964-02291-43639-29753-51457
          +

          The default behavior of the LIKE operator is to ignore case for ASCII characters. Hence, by default 'a' LIKE 'A' is true. +(source: pragma.html, checked-by: th3/req1/pragma10.test, matrix: context, detail)

          + +
          R-57228-12904-01956-10826-41205-44004-37932-17124
          +

          Invoking sqlite3_finalize() on a NULL pointer is a harmless no-op. +(source: c3ref/finalize.html, checked-by: src/vdbeapi.c, th3/req1/finalize01.test, matrix: context, detail)

          + +
          R-57239-11845-16463-18106-13303-34365-12787-00637
          +

          If NORMAL locking mode is in effect for the first WAL-mode database access, then the shared-memory wal-index is created. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-57242-37005-56028-08872-40154-45403-20109-09312
          +

          Any "foreign key mismatch" errors encountered as part of an implicit DELETE are ignored. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys22.test, matrix: context, detail)

          + +
          R-57255-33789-60728-42833-30002-01027-59947-48122
          +

          However, depending on the statement being evaluated and the point at which the error occurs, it might be necessary for SQLite to rollback and cancel the entire transaction. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-57259-65459-47411-32536-55813-09226-48634-58743
          +

          SQLITE_OPEN_NOMUTEX The new database connection will use the "multi-thread" threading mode. +(source: c3ref/open.html, checked-by: th3/cov1/main12.test, matrix: context, detail)

          + +
          R-57301-64506-10586-49672-48759-26432-01783-64495
          +

          "1" if the index is UNIQUE and "0" if not. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-57313-56280-52259-04296-10229-37412-19300-33360
          +

          If URI filenames are recognized when the database connection is originally opened, then URI filenames will also be recognized on ATTACH statements. +(source: uri.html, matrix: context, detail)

          + +
          R-57343-49114-15055-13437-46054-52631-22669-49552
          +

          Value is a big-endian IEEE 754-2008 64-bit floating point number. +(source: fileformat2.html, checked-by: src/vdbeaux.c, th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-57347-36071-40541-19557-35566-60658-39421-45937
          +

          PRAGMA schema.mmap_size; PRAGMA schema.mmap_size=N Query or change the maximum number of bytes that are set aside for memory-mapped I/O on a single database. +(source: pragma.html, matrix: context, detail)

          + +
          R-57359-59558-63770-19476-57809-18440-47111-21364
          +

          The LIMIT and ORDER BY clauses for UPDATE are unsupported within triggers, regardless of the compilation options used to build SQLite. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-57360-40691-20822-63524-22530-36364-65033-34134
          +

          If a keyword in double quotes (ex: "key" or "glob") is used in a context where it cannot be resolved to an identifier but where a string literal is allowed, then the token is understood to be a string literal instead of an identifier. +(source: lang_keywords.html, checked-by: th3/req1/keyword01.test, matrix: context, detail)

          + +
          R-57360-51191-61413-24528-10483-08494-62999-37912
          +

          If the index is unique, then the last integer will be 1. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-57418-53232-55931-28438-08361-10672-24315-12899
          +

          Thus, if a COLLATE operator is used anywhere in a comparision expression, the collating function defined by that operator is used for string comparison regardless of what table columns might be a part of that expression. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-57428-63758-17863-58074-13884-12302-03924-53063
          +

          The same page may not appear more than once within a single rollback journal. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-57445-43425-22232-12533-21797-53023-32757-29365
          +

          Note that the sqlite3_wal_autocheckpoint() interface and the wal_autocheckpoint pragma both invoke sqlite3_wal_hook() and will overwrite any prior sqlite3_wal_hook() settings. +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-57464-30285-51678-51682-55772-21804-29928-17163
          +

          PRAGMA database_list; This pragma works like a query to return one row for each database attached to the current database connection. +(source: pragma.html, checked-by: th3/req1/pragma14.test, matrix: context, detail)

          + +
          R-57479-00042-18825-57289-32505-64353-45358-46844
          +

          These functions (collectively known as "function creation routines") are used to add SQL functions or aggregates or to redefine the behavior of existing SQL functions or aggregates. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, matrix: context, detail)

          + +
          R-57495-24088-42518-44895-31255-64313-21113-39817
          +

          There are two fundamental forms of the CASE expression: those with a base expression and those without. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-57496-20354-59878-60624-45550-42577-49186-19120
          +

          If the specific value bound to a host parameter in the WHERE clause might influence the choice of query plan for a statement, then the statement will be automatically recompiled, as if there had been a schema change, on the first sqlite3_step() call following any change to the bindings of that parameter. +(source: c3ref/prepare.html, checked-by: src/vdbeapi.c, th3/req1/prepare04.test, matrix: context, detail)

          + +
          R-57594-65522-56996-47204-62238-07875-00187-41859
          +

          In all cases, the value returned is the new analysis limit used for subsequent ANALYZE commands. +(source: pragma.html, matrix: context, detail)

          + +
          R-57611-29319-52424-65046-25950-44814-17641-61305
          +

          The return value from both sqlite3_soft_heap_limit64() and sqlite3_hard_heap_limit64() is the size of the heap limit prior to the call, or negative in the case of an error. +(source: c3ref/hard_heap_limit64.html, checked-by: th3/req1/softheaplimit01.test, matrix: context, detail)

          + +
          R-57629-25253-01540-58314-47057-32967-17520-58138
          +

          If the SELECT statement is an aggregate query without a GROUP BY clause, then each aggregate expression in the result-set is evaluated once across the entire dataset. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-57724-31954-10264-24402-01814-32974-35251-10420
          +

          The filename of the database follows the same semantics as the filename argument to sqlite3_open() and sqlite3_open_v2(); the special name ":memory:" results in an in-memory database and an empty string results in a new temporary database. +(source: lang_attach.html, checked-by: th3/req1/attach03.test, matrix: context, detail)

          + +
          R-57724-61571-01377-08004-10226-53040-57398-43203
          +

          An ON CONFLICT clause may be specified as part of an UPDATE or INSERT action within the body of the trigger. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-57765-12380-65473-27490-60483-53059-23435-27202
          +

          In the above paragraph, the term "equal" means equal when values are compared using the rules specified here. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys03.test, matrix: context, detail)

          + +
          R-57773-31134-13859-63861-60262-03843-19674-02031
          +

          With AUTOINCREMENT, rows with automatically selected ROWIDs are guaranteed to have ROWIDs that have never been used before by the same table in the same database. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-57803-30267-35390-49714-00774-40493-44920-28706
          +

          Note, however, that auto-vacuum only truncates the freelist pages from the file. Auto-vacuum does not defragment the database nor repack individual database pages the way that the VACUUM command does. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-57806-53405-06044-47761-50906-57249-23424-06357
          +

          All of the result in the example are the same if the comparisons are commuted - if expressions of the form "a<40" are rewritten as "40>a". +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-57876-22123-39728-45816-26959-17516-32294-11302
          +

          The default collating sequence is the collating sequence defined for that column in the CREATE TABLE statement. +(source: lang_createindex.html, checked-by: th3/req1/createidx01.test, matrix: context, detail)

          + +
          R-57884-37496-29952-23489-26945-21299-05103-05410
          +

          The scheme of the URI must be "file:". Any other scheme results in the input being treated as an ordinary filename. +(source: uri.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-57928-57565-35172-43517-28321-39002-52243-13899
          +

          The expression "x IN (SELECT y ...)" is handled in the same way as the expression "x = y" for the purposes of determining the collating sequence. +(source: datatype3.html, checked-by: th3/req1/datatype3_10.test, matrix: context, detail)

          + +
          R-57963-05936-27484-31794-06157-35153-01891-09927
          +

          The SAVEPOINT command starts a new transaction with a name. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-57967-31673-02324-15134-55427-47426-59271-07487
          +

          The SQLITE_FCNTL_PERSIST_WAL opcode is used to set or query the persistent Write Ahead Log setting. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-58015-48175-59968-51702-38590-12098-63778-58558
          +

          The two-byte integer at offset 5 designates the start of the cell content area. A zero value for this integer is interpreted as 65536. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-58033-17334-23176-58899-39205-34616-00819-09634
          +

          An error is raised if a CREATE TABLE statement with the WITHOUT ROWID clause lacks a PRIMARY KEY. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-58057-33391-03509-33043-33345-56148-13534-20501
          +

          The fourth parameter may also optionally include the SQLITE_DIRECTONLY flag, which if present prevents the function from being invoked from within VIEWs, TRIGGERs, CHECK constraints, generated column expressions, index expressions, or the WHERE clause of partial indexes. +(source: c3ref/create_function.html, matrix: context, detail)

          + +
          R-58063-38258-54804-43004-10220-55460-06574-61060
          +

          SQLITE_CONFIG_MMAP_SIZE takes two 64-bit integer (sqlite3_int64) values that are the default mmap size limit (the default setting for PRAGMA mmap_size) and the maximum allowed mmap size limit. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-58080-31767-64590-28365-48177-49869-42154-18790
          +

          Note that the sqlite3_changes() and sqlite3_total_changes() interfaces do not count INSTEAD OF trigger firings, but the count_changes pragma does count INSTEAD OF trigger firing. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-58089-05908-32254-07731-27981-33321-41774-40378
          +

          If the table has a column of type INTEGER PRIMARY KEY then that column is another alias for the rowid. +(source: c3ref/last_insert_rowid.html, matrix: context, detail)

          + +
          R-58095-46013-00121-55474-24418-20779-51878-39971
          +

          Otherwise, the UPDATE affects only those rows for which the WHERE clause boolean expression is true. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-58101-01610-39291-65519-22714-56029-10662-40806
          +

          The "SQLITE_" prefix is omitted from the returned option names. +(source: pragma.html, checked-by: th3/req1/pragma13.test, matrix: context, detail)

          + +
          R-58129-20729-43334-45037-61775-65105-23500-10551
          +

          It is not an error if the WHERE clause does not evaluate to true for any row in the table - this just means that the UPDATE statement affects zero rows. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-58133-32721-60366-63441-61614-07001-53385-02322
          +

          A keyword in single quotes is a string literal. +(source: lang_keywords.html, checked-by: th3/req1/keyword01.test, matrix: context, detail)

          + +
          R-58160-63457-25230-02228-13087-65392-10512-19880
          +

          The nolock parameter is a boolean query parameter which if set disables file locking in rollback journal modes. +(source: c3ref/open.html, checked-by: th3/cov1/nolock01.test, matrix: context, detail)

          + +
          R-58208-19414-39381-39843-31272-22359-33296-08793
          +

          The first 2 bytes of a freeblock are a big-endian integer which is the offset in the b-tree page of the next freeblock in the chain, or zero if the freeblock is the last on the chain. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-58230-57098-08245-26579-57280-54560-29149-45335
          +

          The "INDEXED BY index-name" phrase specifies that the named index must be used in order to look up values on the preceding table. +(source: lang_indexedby.html, checked-by: tcl/indexedby.test, matrix: context, detail)

          + +
          R-58261-63259-31112-34122-01382-46669-15924-59329
          +

          The sum() and total() aggregate functions return sum of all non-NULL values in the group. +(source: lang_aggfunc.html, checked-by: th3/req1/aggfunc01.test, matrix: context, detail)

          + +
          R-58293-02725-64867-56851-12538-45360-38316-49543
          +

          Each time a transaction is committed or a WAL file resets, SQLite compares the size of the rollback journal file or WAL file left in the file-system to the size limit set by this pragma and if the journal or WAL file is larger it is truncated to the limit. +(source: pragma.html, checked-by: th3/req1/pragma26.test, matrix: context, detail)

          + +
          R-58297-14483-40146-32998-13341-07144-06303-13895
          +

          WAL databases can be created, read, and written even if shared memory is unavailable as long as the locking_mode is set to EXCLUSIVE before the first attempted access. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-58299-29950-41859-14969-07677-61632-11301-17744
          +

          The sqlite3_txn_state(D,S) interface returns the current transaction state of schema S in database connection D. +(source: c3ref/txn_state.html, matrix: context, detail)

          + +
          R-58312-28618-40592-62073-31662-38591-25433-11093
          +

          If the Y argument is omitted, rtrim(X) removes spaces from the right side of X. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-58318-35349-04006-21440-04924-16231-32271-20333
          +

          The DROP COLUMN syntax is used to remove an existing column from a table. +(source: lang_altertable.html, checked-by: tcl/alterdropcol2.test, th3/cov1/altertable25.test, matrix: context, detail)

          + +
          R-58344-62489-38049-32085-64337-15515-50489-64181
          +

          Thus, by default, the following expression is true: 'a' LIKE 'A' +(source: optoverview.html, matrix: context, detail)

          + +
          R-58361-29089-54084-23122-22641-61380-38258-02749
          +

          The changes() function returns the number of database rows that were changed or inserted or deleted by the most recently completed INSERT, DELETE, or UPDATE statement, exclusive of statements in lower-level triggers. +(source: lang_corefunc.html, checked-by: th3/req1/func01.test, matrix: context, detail)

          + +
          R-58393-10545-21271-47622-25351-02846-49007-50648
          +

          Specifying a new page size does not change the page size immediately. Instead, the new page size is remembered and is used to set the page size when the database is first created, if it does not already exist when the page_size pragma is issued, or at the next VACUUM command that is run on the same database connection while not in WAL mode. +(source: pragma.html, matrix: context, detail)

          + +
          R-58421-05800-43557-56576-34931-38170-06768-38707
          +

          If the Y argument is omitted, ltrim(X) removes spaces from the left side of X. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-58424-53543-49718-27899-29509-07852-05490-25692
          +

          The page size must be a power of two between 512 and 65536 inclusive. +(source: pragma.html, matrix: context, detail)

          + +
          R-58428-36660-63931-61833-12651-58158-26648-39835
          +

          If OMIT_FOREIGN_KEY is defined, then foreign key definitions cannot even be parsed (attempting to specify a foreign key definition is a syntax error). +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys05.test, matrix: context, detail)

          + +
          R-58433-37187-52219-35155-40508-43189-02693-26384
          +

          The COMMIT command and the ROLLBACK command without the TO clause work the same on SAVEPOINT transactions as they do with transactions started by BEGIN. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-58477-34656-38121-25387-55134-41708-03146-13097
          +

          sqlite> CREATE INDEX i1 ON t1(a); sqlite> EXPLAIN QUERY PLAN SELECT a, b FROM t1 WHERE a=1; QUERY PLAN `--SEARCH TABLE t1 USING INDEX i1 (a=?) +(source: eqp.html, matrix: context, detail)

          + +
          R-58546-22075-08471-42930-58515-49649-00646-41652
          +

          The random() function is obviously non-deterministic because it gives a different answer every time it is invoked. +(source: deterministic.html, matrix: context, detail)

          + +
          R-58553-63740-12454-47627-42438-52862-15434-40396
          +

          If executing the SELECT statement specified as the right-hand operand of the EXISTS operator would return one or more rows, then the EXISTS operator evaluates to 1. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-58560-23968-28537-53654-45621-13227-05416-28279
          +

          The default value of the checkpoint_fullfsync flag is off. +(source: pragma.html, checked-by: th3/req1/pragma11.test, matrix: context, detail)

          + +
          R-58570-38916-64955-51139-26033-08534-02981-10292
          +

          If N or iOffset are less than zero SQLITE_ERROR is returned and no data is written. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-58594-33195-20436-37240-14115-17823-15221-34183
          +

          One might, for example, want to query all objects that overlap with the 35th parallel: SELECT id FROM demo_index WHERE maxY>=35.0 AND minY<=35.0; But, generally speaking, the more constraints that the R*Tree module has to work with, and the smaller the bounding box, the faster the results will come back. 3.4. Roundoff Error By default, coordinates are stored in an R*Tree using 32-bit floating point values. When a coordinate cannot be exactly represented by a 32-bit floating point number, the lower-bound coordinates are rounded down and the upper-bound coordinates are rounded up. Thus, bounding boxes might be slightly larger than specified, but will never be any smaller. This is exactly what is desired for doing the more common "overlapping" queries where the application wants to find every entry in the R*Tree that overlaps a query bounding box. Rounding the entry bounding boxes outward might cause a few extra entries to appears in an overlapping query if the edge of the entry bounding box corresponds to an edge of the query bounding box. But the overlapping query will never miss a valid table entry. However, for a "contained-within" style query, rounding the bounding boxes outward might cause some entries to be excluded from the result set if the edge of the entry bounding box corresponds to the edge of the query bounding box. To guard against this, applications should expand their contained-within query boxes slightly (by 0.000012%) by rounding down the lower coordinates and rounding up the top coordinates, in each dimension. 3.5. Reading And Writing At The Same Time It is the nature of the Guttman R-Tree algorithm that any write might radically restructure the tree, and in the process change the scan order of the nodes. For this reason, it is not generally possible to modify the R-Tree in the middle of a query of the R-Tree. Attempts to do so will fail with a SQLITE_LOCKED "database table is locked" error. So, for example, suppose an application runs one query against an R-Tree like this: SELECT id FROM demo_index WHERE maxY>=35.0 AND minY<=35.0; Then for each "id" value returned, suppose the application creates an UPDATE statement like the following and binds the "id" value returned against the "?1" parameter: UPDATE demo_index SET maxY=maxY+0.5 WHERE id=?1; Then the UPDATE might fail with an SQLITE_LOCKED error. The reason is that the initial query has not run to completion. It is remembering its place in the middle of a scan of the R-Tree. So an update to the R-Tree cannot be tolerated as this would disrupt the scan. It is also possible to express this kind of simultaneous read and write on an R-Tree within a single query, for example if an UPDATE statement tries to change the value of one row of the R-Tree based on a complicated query from another row of the same R-Tree, perhaps something like this: UPDATE demo_index SET maxY = (SELECT max(maxX) FROM demo_index AS x2 WHERE x2.maxY>demo_index.x2) WHERE maxY>=35.0 AND minY<=35.0; This is a limitation of the R-Tree extension only. Ordinary tables in SQLite are able to read and write at the same time. Other virtual tables might (or might not) also that capability. And R-Tree can appear to read and write at the same time in some circumstances, if it can figure out how to reliably run the query to completion before starting the update. But you shouldn't count on that for every query. Generally speaking, it is best to avoid running queries and updates to the same R-Tree at the same time. If you really need to update an R-Tree based on complex queries against the same R-Tree, it is best to run the complex queries first and store the results in a temporary table, then update the R-Tree based on the values stored in the temporary table. 4. Using R*Trees Effectively For SQLite versions prior to 3.24.0 (2018-06-04), the only information that an R*Tree index stores about an object is its integer ID and its bounding box. Additional information needs to be stored in separate tables and related to the R*Tree index using the primary key. For the example above, one might create an auxiliary table as follows: CREATE TABLE demo_data( id INTEGER PRIMARY KEY, -- primary key objname TEXT, -- name of the object objtype TEXT, -- object type boundary BLOB -- detailed boundary of object ); In this example, the demo_data.boundary field is intended to hold some kind of binary representation of the precise boundaries of the object. The R*Tree index only holds an axis-aligned rectangular boundary for the object. The R*Tree boundary is just an approximation of the true object boundary. So what typically happens is that the R*Tree index is used to narrow a search down to a list of candidate objects and then more detailed and expensive computations are done on each candidate to find if the candidate truly meets the search criteria. Key Point: An R*Tree index does not normally provide the exact answer but merely reduces the set of potential answers from millions to dozens. Suppose the demo_data.boundary field holds some proprietary data description of a complex two-dimensional boundary for an object and suppose that the application has used the sqlite3_create_function() interface to created application-defined functions "contained_in" and "overlaps" accepting two demo_data.boundary objects and return true or false. One may assume that "contained_in" and "overlaps" are relatively slow functions that we do not want to invoke too frequently. Then an efficient way to find the name of all objects located within the North Carolina 12th District, one may be to run a query like this: SELECT objname FROM demo_data, demo_index WHERE demo_data.id=demo_index.id AND contained_in(demo_data.boundary, :boundary) AND minX>=-81.0 AND maxX<=-79.6 AND minY>=35.0 AND maxY<=36.2; In the query above, one would presumably bind the binary BLOB description of the precise boundary of the 12th district to the ":boundary" parameter. Notice how the query above works: The R*Tree index runs in the outer loop to find entries that are contained within the bounding box of longitude -81..-79.6 and latitude 35.0..36.2. For each object identifier found, SQLite looks up the corresponding entry in the demo_data table. It then uses the boundary field from the demo_data table as a parameter to the contained_in() function and if that function returns true, the objname field from the demo_data table is returned as the next row of query result. One would get the same answer without the use of the R*Tree index using the following simpler query: SELECT objname FROM demo_data WHERE contained_in(demo_data.boundary, :boundary); The problem with this latter query is that it must apply the contained_in() function to millions of entries in the demo_data table. The use of the R*Tree in the penultimate query reduces the number of calls to contained_in() function to a small subset of the entire table. The R*Tree index did not find the exact answer itself, it merely limited the search space. 4.1. Auxiliary Columns Beginning with SQLite version 3.24.0 (2018-06-04), r-tree tables can have auxiliary columns that store arbitrary data. Auxiliary columns can be used in place of secondary tables such as "demo_data". Auxiliary columns are marked with a "+" symbol before the column name. Auxiliary columns must come after all of the coordinate boundary columns. There is a limit of no more than 100 auxiliary columns. The following example shows an r-tree table with auxiliary columns that is equivalent to the two tables "demo_index" and "demo_data" above: CREATE VIRTUAL TABLE demo_index2 USING rtree( id, -- Integer primary key minX, maxX, -- Minimum and maximum X coordinate minY, maxY, -- Minimum and maximum Y coordinate +objname TEXT, -- name of the object +objtype TEXT, -- object type +boundary BLOB -- detailed boundary of object ); +(source: rtree.html, matrix: context, detail)

          + +
          R-58640-02877-59661-28558-18785-36384-52815-36823
          +

          RTRIM - The same as binary, except that trailing space characters are ignored. +(source: datatype3.html, checked-by: th3/req1/datatype3_09.test, matrix: context, detail)

          + +
          R-58706-14229-29588-03178-14400-15818-06936-07358
          +

          Similarly, an INSERT statement may provide a value to use as the rowid for each row inserted. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-58714-09943-11922-47128-02386-08518-39517-24120
          +

          SQLITE_DBSTATUS_CACHE_USED This parameter returns the approximate number of bytes of heap memory used by all pager caches associated with the database connection. +(source: c3ref/c_dbstatus_options.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-58729-25290-19710-37718-46636-04940-09423-21381
          +

          The SQLITE_FCNTL_PRAGMA file control occurs at the beginning of pragma statement analysis and so it is able to override built-in PRAGMA statements. +(source: c3ref/c_fcntl_begin_atomic_write.html, checked-by: th3/cov1/pragma24.test, matrix: context, detail)

          + +
          R-58731-25439-21347-45819-04127-12492-10479-51386
          +

          The collating sequence set by the COLLATE operator overrides the collating sequence determined by the COLLATE clause in a table column definition. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-58769-41706-35801-04154-17384-12039-24513-64456
          +

          The in-header database size is always valid when the database is only modified using recent versions of SQLite, versions 3.7.0 (2010-07-21) and later. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-58777-16499-45201-64788-11957-29416-62683-55566
          +

          Statistics might not be available for all loops in all statements. +(source: c3ref/stmt_scanstatus.html, checked-by: th3/cov1/status02.test, matrix: context, detail)

          + +
          R-58778-10776-22890-25642-31473-47803-35763-23177
          +

          The xInit() method is called once for each effective call to sqlite3_initialize() +(source: c3ref/pcache_methods2.html, checked-by: th3/th3pcache.c, matrix: context, detail)

          + +
          R-58779-36112-07505-12911-48532-31696-16411-64279
          +

          Once created, the sqlite_sequence table exists in the sqlite_schema table forever; it cannot be dropped. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-58813-55036-01417-02412-42813-08467-49473-05345
          +

          The sqlite3_bind_zeroblob() and sqlite3_result_zeroblob() interfaces and the built-in zeroblob SQL function may be used to create a zero-filled blob to read or write using the incremental-blob interface. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-58814-63508-14637-55727-60663-34396-08543-07836
          +

          The sqlite3_db_release_memory(D) interface attempts to free as much heap memory as possible from database connection D. +(source: c3ref/db_release_memory.html, checked-by: tcl/shrink.test, matrix: context, detail)

          + +
          R-58823-28748-40734-32181-06103-05121-55072-03563
          +

          If it identifies a specific database index, then just that index is recreated. +(source: lang_reindex.html, checked-by: tcl/e_reindex.test, matrix: context, detail)

          + +
          R-58827-57434-27367-43621-07290-05598-35918-65407
          +

          SQLite invokes D with P as its only argument when SQLite is finished with P. +(source: c3ref/result_blob.html, matrix: context, detail)

          + +
          R-58835-30946-01453-54095-45782-49033-61690-21172
          +

          The SQLITE_FCNTL_POWERSAFE_OVERWRITE opcode is used to set or query the persistent "powersafe-overwrite" or "PSOW" setting. +(source: c3ref/c_fcntl_begin_atomic_write.html, matrix: context, detail)

          + +
          R-58838-55911-33120-57542-55492-25177-48727-11020
          +

          If the nByte argument is negative, then zSql is read up to the first zero terminator. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-58862-44169-03141-46737-61496-44954-25565-37290
          +

          If an UPDATE statement has a LIMIT clause, the maximum number of rows that will be updated is found by evaluating the accompanying expression and casting it to an integer value. +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-58951-07798-10781-33185-41283-52563-14350-38026
          +

          Otherwise, if no column-list is specified, the number of columns in the result of the SELECT must be the same as the number of columns in the table. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-59001-45278-16450-29510-31593-00362-58308-30623
          +

          SQLITE_LIMIT_FUNCTION_ARG The maximum number of arguments on a function. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit02.test, matrix: context, detail)

          + +
          R-59007-20454-04815-57542-48714-11187-47465-31544
          +

          Any other character matches itself or its lower/upper case equivalent (i.e. case-insensitive matching). +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-59051-35706-17689-00291-19799-28494-42695-25135
          +

          The PRIMARY KEY clause must contain only column names — the use of expressions in an indexed-column of a PRIMARY KEY is not supported. +(source: lang_createtable.html, matrix: context, detail)

          + +
          R-59089-25828-47807-24089-43105-44116-25711-61833
          +

          The columns of the cartesian product dataset are, in order, all the columns of the left-hand dataset followed by all the columns of the right-hand dataset. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-59103-42685-29407-49454-53607-22042-22472-58911
          +

          When pMem is not NULL, SQLite will strive to use the memory provided to satisfy page cache needs, falling back to sqlite3_malloc() if a page cache line is larger than sz bytes or if all of the pMem buffer is exhausted. +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-59114-58431-38576-59945-01836-64391-41431-21894
          +

          The sqlite3_log() interface writes a message into the error log established by the SQLITE_CONFIG_LOG option to sqlite3_config(). +(source: c3ref/log.html, checked-by: th3/cov1/log01.test, matrix: context, detail)

          + +
          R-59124-61339-46915-41859-25282-43163-13207-41482
          +

          Each row in a table with a primary key must have a unique combination of values in its primary key columns. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-59140-43269-17105-04578-09488-50490-51630-23162
          +

          The following table details the conversions that are applied: InternalType RequestedType Conversion NULL INTEGER Result is 0 NULL FLOAT Result is 0.0 NULL TEXT Result is a NULL pointer NULL BLOB Result is a NULL pointer INTEGER FLOAT Convert from integer to float INTEGER TEXT ASCII rendering of the integer INTEGER BLOB Same as INTEGER->TEXT FLOAT INTEGER CAST to INTEGER FLOAT TEXT ASCII rendering of the float FLOAT BLOB CAST to BLOB TEXT INTEGER CAST to INTEGER TEXT FLOAT CAST to REAL TEXT BLOB No change BLOB INTEGER CAST to INTEGER BLOB FLOAT CAST to REAL BLOB TEXT Add a zero terminator if needed +(source: c3ref/column_blob.html, checked-by: th3/req1/column02.test, matrix: context, detail)

          + +
          R-59153-45869-47799-39794-18343-43894-28184-56568
          +

          If the declared type for a column contains any of the strings "REAL", "FLOA", or "DOUB" then the column has REAL affinity. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-59165-19659-62655-08442-22877-21520-01156-02106
          +

          If a numeric literal has a decimal point or an exponentiation clause or if its magnitude is less than -9223372036854775808 or greater than 9223372036854775807, then it is a floating point literal. Otherwise is it is an integer literal. +(source: lang_expr.html, checked-by: th3/req1/expr01.test, matrix: context, detail)

          + +
          R-59171-47567-19370-12985-34134-25393-49439-38591
          +

          This mode blocks (it invokes the busy-handler callback) until there is no database writer and all readers are reading from the most recent database snapshot. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-59172-51198-22956-23364-43321-06820-15140-44023
          +

          If the transaction stack is not empty when the BEGIN command is invoked, then the command fails with an error. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-59177-30964-27370-56053-61429-49243-22831-00049
          +

          If the date is already on the desired weekday, the "weekday" modifier leaves the date unchanged. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-59182-40522-06703-03529-14405-50301-30896-08116
          +

          The SQLITE_VERSION C preprocessor macro in the sqlite3.h header evaluates to a string literal that is the SQLite version in the format "X.Y.Z" where X is the major version number (always 3 for SQLite3) and Y is the minor version number and Z is the release number. +(source: c3ref/c_source_id.html, checked-by: th3/req1/version01.test, matrix: context, detail)

          + +
          R-59218-44473-40361-49593-50972-37596-39041-04578
          +

          The sqlite_sequence table is created automatically whenever any ordinary table with an AUTOINCREMENT integer primary key is created. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-59237-46742-53933-54312-09951-05866-00248-19595
          +

          A subquery specified in the table-or-subquery following the FROM clause in a simple SELECT statement is handled as if it was a table containing the data returned by executing the subquery statement. +(source: lang_select.html, checked-by: tcl/e_select2.test, matrix: context, detail)

          + +
          R-59246-48037-03158-25675-60102-33879-46651-46804
          +

          Any callback set by a previous call to this function for the same database connection is overridden. +(source: c3ref/update_hook.html, checked-by: th3/cov1/main15.test, matrix: context, detail)

          + +
          R-59271-29405-40736-18253-27684-60508-27772-33156
          +

          If the L parameter is NULL, then all virtual table modules are removed. +(source: c3ref/drop_modules.html, matrix: context, detail)

          + +
          R-59275-48655-09864-05329-36519-41537-00645-39530
          +

          The new row is identified by the rowid value passed as the second argument. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-59294-22119-53141-34603-32613-50931-06947-25796
          +

          If additional page cache memory is needed beyond what is provided by the initial allocation, then SQLite goes to sqlite3_malloc() separately for each additional cache line. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/main42.test, matrix: context, detail)

          + +
          R-59310-51205-15407-41555-00888-38389-12336-63259
          +

          The "reserved space" size in the 1-byte integer at offset 20 is the number of bytes of space at the end of each page to reserve for extensions. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-59344-06440-62952-57613-16293-38554-64918-31058
          +

          It is possible to have an aggregate function with the same name as a simple function, as long as the number of arguments for the two forms of the function are different. +(source: lang_expr.html, checked-by: th3/req1/func05.test, matrix: context, detail)

          + +
          R-59391-62387-22553-12077-41502-35655-02982-42889
          +

          Conversions between UTF-16be and UTF-16le are always done in place and do not invalidate a prior pointer, though of course the content of the buffer that the prior pointer references will have been modified. +(source: c3ref/column_blob.html, checked-by: th3/req1/column03.test, matrix: context, detail)

          + +
          R-59400-47238-48120-20066-59137-27524-23883-51047
          +

          The "weekday" modifier advances the date forward, if necessary, to the next date where the weekday number is N. Sunday is 0, Monday is 1, and so forth. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-59451-39147-41115-01514-52343-04781-09357-36534
          +

          A ROLLBACK will cause a pending read operation to fail only if the schema was changed within the transaction being rolled back. +(source: rescode.html, matrix: context, detail)

          + +
          R-59498-62062-55834-19518-04943-47390-59895-15219
          +

          If prepared statement P does not have results ready to return (via calls to the sqlite3_column() family of interfaces) then sqlite3_data_count(P) returns 0. +(source: c3ref/data_count.html, checked-by: th3/req1/datacnt01.test, matrix: context, detail)

          + +
          R-59544-00330-10007-23710-00944-16891-38828-33861
          +

          If the affinity of a column is REAL and that column contains a value that can be converted to an integer without loss of information (if the value contains no fractional part and is not too large to be represented as an integer) then the column may be stored in the record as an integer. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-59553-21705-43899-06784-22214-40480-29104-54159
          +

          Collating functions are deleted when they are overridden by later calls to the collation creation functions or when the database connection is closed using sqlite3_close(). +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-59577-33471-39346-45414-34609-60012-12077-11853
          +

          The COLLATE operator is a unary postfix operator that assigns a collating sequence to an expression. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-59581-44104-07622-44169-35142-09947-54214-52613
          +

          If SQLite is built with the SQLITE_ENABLE_UPDATE_DELETE_LIMIT compile-time option then the syntax of the UPDATE statement is extended with optional ORDER BY and LIMIT clauses +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-59593-21810-38757-57312-51798-28270-65217-02509
          +

          If SQLite is compiled with the SQLITE_THREADSAFE=0 compile-time option then it is not possible to set the Serialized threading mode and sqlite3_config() will return SQLITE_ERROR if called with the SQLITE_CONFIG_SERIALIZED configuration option. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-59615-42828-32025-62941-63094-03389-26549-04394
          +

          A value of 10 (0x0a) means the page is a leaf index b-tree page. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-59626-52827-57662-05724-48441-25095-54534-18435
          +

          The name of the collation is a UTF-8 string for sqlite3_create_collation() and sqlite3_create_collation_v2() and a UTF-16 string in native byte order for sqlite3_create_collation16(). +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-59634-51678-29795-22623-60513-10487-06107-08719
          +

          When that SQL function appears on the right-hand side of the MATCH operator and the left-hand side of the MATCH operator is any column in the R*Tree virtual table, then the callback defined by the third argument (xQueryFunc or xGeom) is invoked to determine if a particular object or subtree overlaps the desired region. +(source: rtree.html, matrix: context, detail)

          + +
          R-59665-46340-25157-22824-10328-32934-42335-25570
          +

          This routine actually returns the index of the largest (rightmost) parameter. For all forms except ?NNN, this will correspond to the number of unique parameters. If parameters of the ?NNN form are used, there may be gaps in the list. +(source: c3ref/bind_parameter_count.html, checked-by: th3/req1/bindparamcnt01.test, matrix: context, detail)

          + +
          R-59712-18547-02212-00843-63183-21822-46730-58410
          +

          The source database is read-locked only while it is being read; it is not locked continuously for the entire backup operation. +(source: c3ref/backup_finish.html, checked-by: th3/req1/backup01.test, matrix: context, detail)

          + +
          R-59738-58751-51247-06625-33593-39630-09372-24907
          +

          The routines sqlite3_prepare_v2(), sqlite3_prepare(), sqlite3_prepare16(), sqlite3_prepare16_v2(), sqlite3_exec(), and sqlite3_get_table() accept an SQL statement list (sql-stmt-list) which is a semicolon-separated list of statements. +(source: lang.html, checked-by: th3/req1/lang01.test, matrix: context, detail)

          + +
          R-59741-51383-54306-63308-23594-36785-40026-55929
          +

          However, application code cannot create the sqlite_sequence table if it does not already exist. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-59782-00072-08374-56821-09554-43453-45852-13316
          +

          The soundex(X) function returns a string that is the soundex encoding of the string X. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/func07.test, matrix: context, detail)

          + +
          R-59782-36818-22157-37925-40398-63566-64063-39784
          +

          The SQLITE_CHECKPOINT_FULL, RESTART and TRUNCATE modes also obtain the exclusive "writer" lock on the database file. +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/wal.c, tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-59829-49719-48760-25089-64787-41616-07778-57513
          +

          The optional "schema-name." prefix on the table-name is supported for top-level INSERT statements only. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-59841-13798-58267-43160-49390-53360-57337-63082
          +

          The 4-byte big-endian integer at offset 32 stores the page number of the first page of the freelist, or zero if the freelist is empty. +(source: fileformat2.html, checked-by: src/btree.c, matrix: context, detail)

          + +
          R-59843-56897-36550-00278-28044-49330-04836-60246
          +

          The name of the module is given by the second parameter. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-59847-53574-49799-21344-47903-30927-18789-48641
          +

          If sqlite3_unlock_notify() is called in a multi-threaded application, there is a chance that the blocking connection will have already concluded its transaction by the time sqlite3_unlock_notify() is invoked. If this happens, then the specified callback is invoked immediately, from within the call to sqlite3_unlock_notify(). +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-59858-46238-55910-38218-36749-39219-09135-02336
          +

          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. +(source: pragma.html, matrix: context, detail)

          + +
          R-59866-40673-09200-10625-43441-33703-34788-06531
          +

          The first call to sqlite3_backup_step() obtains an exclusive lock on the destination file. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-59880-60857-20339-39242-03952-30243-41004-50875
          +

          If no prepared statement satisfies the conditions of this routine, it returns NULL. +(source: c3ref/next_stmt.html, checked-by: th3/cov1/vdbeapi04.test, matrix: context, detail)

          + +
          R-59903-02736-29653-35997-33194-50062-38797-30798
          +

          If M is the size of the prior allocation, then min(N,M) bytes of the prior allocation are copied into the beginning of buffer returned by sqlite3_realloc(X,N) and the prior allocation is freed. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-59941-62933-38106-18791-02770-37169-39632-35636
          +

          PRAGMA checkpoint_fullfsync PRAGMA checkpoint_fullfsync = boolean; Query or change the fullfsync flag for checkpoint operations. +(source: pragma.html, checked-by: th3/req1/pragma11.test, matrix: context, detail)

          + +
          R-59958-37183-05497-01446-42261-31297-62677-47395
          +

          Only rows of the table for which the WHERE clause evaluates to true are included in the index. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-59963-05629-44099-52431-63560-45782-35835-08059
          +

          Even though the function prototype shows that xEntryPoint() takes no arguments and returns void, SQLite invokes xEntryPoint() with three arguments and expects an integer result as if the signature of the entry point where as follows:   int xEntryPoint(   sqlite3 *db,   const char **pzErrMsg,   const struct sqlite3_api_routines *pThunk   ); +(source: c3ref/auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-59964-54038-02693-18271-12639-43179-21789-28572
          +

          SQLITE_OPEN_FULLMUTEX The new database connection will use the "serialized" threading mode. +(source: c3ref/open.html, checked-by: th3/cov1/main12.test, matrix: context, detail)

          + +
          R-59967-13104-62273-50017-33648-63119-25172-21301
          +

          Hence, the histogram data which is collected no left-most column of indexes is useless in helping to choose between the range constraints on columns x and y. +(source: optoverview.html, matrix: context, detail)

          + +
          R-59999-34429-08748-48712-52487-44530-24268-48005
          +

          Generated columns can be interspersed among ordinary columns. +(source: gencol.html, matrix: context, detail)

          + +
          R-60001-20170-36140-08740-00799-64790-64751-11735
          +

          The rollback callback is not invoked if a transaction is automatically rolled back because the database connection is closed. +(source: c3ref/commit_hook.html, matrix: context, detail)

          + +
          R-60007-46407-64450-37762-55294-24345-19762-56932
          +

          For serial types 0, 8, 9, 12, and 13, the value is zero bytes in length. If all columns are of these types then the body section of the record is empty. +(source: fileformat2.html, checked-by: th3/req1/fileformat02.test, matrix: context, detail)

          + +
          R-60014-23402-36895-53889-00518-21066-14301-55859
          +

          When no indexes are available to aid the evaluation of a query, SQLite might create an automatic index that lasts only for the duration of a single SQL statement. +(source: optoverview.html, matrix: context, detail)

          + +
          R-60090-27861-59192-20728-19782-37127-56669-48134
          +

          This interface loads an SQLite extension library from the named file. +(source: c3ref/load_extension.html, matrix: context, detail)

          + +
          R-60099-10331-60202-18303-15072-02692-09131-64001
          +

          The multi-argument max() function returns the argument with the maximum value, or return NULL if any argument is NULL. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, th3/req1/func03.test, matrix: context, detail)

          + +
          R-60116-07512-58915-34357-51591-00163-63646-47672
          +

          The parent key of a foreign key constraint is not allowed to use the rowid. The parent key must used named columns only. +(source: lang_createtable.html, checked-by: th3/req1/foreignkeys03.test, matrix: context, detail)

          + +
          R-60116-58305-35895-50546-31025-26877-37972-30944
          +

          A NULL operand on a mathematical operator yields a NULL result. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-60153-11078-48235-52964-41144-31908-11477-07860
          +

          If the most recent call to sqlite3_step(S) for the prepared statement S returned SQLITE_ROW or SQLITE_DONE, or if sqlite3_step(S) has never before been called on S, then sqlite3_reset(S) returns SQLITE_OK. +(source: c3ref/reset.html, checked-by: th3/th3util.c, matrix: context, detail)

          + +
          R-60175-02388-07986-54483-25650-07763-57471-09194
          +

          Deliberately changing out of WAL mode changes the database file format version numbers back to 1 so that older versions of SQLite can once again access the database file. +(source: wal.html, checked-by: tcl/e_wal.test, matrix: context, detail)

          + +
          R-60235-46489-17538-30450-39189-57367-12631-34674
          +

          The handler will sleep multiple times until at least "ms" milliseconds of sleeping have accumulated. +(source: c3ref/busy_timeout.html, checked-by: th3/cov1/main21.test, matrix: context, detail)

          + +
          R-60247-35692-05586-10115-22101-12155-14694-19352
          +

          The contents of the sqlite3_rtree_geometry structure are initialized by SQLite but are not subsequently modified. +(source: rtree.html, matrix: context, detail)

          + +
          R-60292-04128-28566-07483-18233-58006-62395-18068
          +

          When temp_store is FILE (1) temporary tables and indices are stored in a file. +(source: pragma.html, matrix: context, detail)

          + +
          R-60317-50382-07246-28388-21909-63634-29963-03313
          +

          The sqlite3_table_column_metadata(X,D,T,C,....) routine returns information about column C of table T in database D on database connection X. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-60324-39271-63103-21591-25385-29112-09183-41163
          +

          Key/value pairs are separated by a single "&" character. +(source: uri.html, matrix: context, detail)

          + +
          R-60334-12880-45954-16548-05057-35188-10924-38811
          +

          If the most recent evaluation of the statement encountered no errors or if the statement is never been evaluated, then sqlite3_finalize() returns SQLITE_OK. +(source: c3ref/finalize.html, checked-by: th3/req1/finalize01.test, matrix: context, detail)

          + +
          R-60344-21573-43141-53224-31246-51025-51087-34354
          +

          The SQLite query planner might use the estimated row size information provided by the "sz=NNN" token to help it choose smaller tables and indexes that require less disk I/O. +(source: fileformat2.html, checked-by: th3/cov1/index02.test, matrix: context, detail)

          + +
          R-60349-29862-22141-07811-21559-44331-23137-45760
          +

          This API is only available if the library was compiled with the SQLITE_ENABLE_UNLOCK_NOTIFY C-preprocessor symbol defined. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-60354-20889-08595-48824-21285-36723-22073-47056
          +

          The sqlite3_get_auxdata(C,N) interface returns a pointer to the metadata associated by the sqlite3_set_auxdata(C,N,P,X) function with the Nth argument value to the application-defined function. +(source: c3ref/get_auxdata.html, matrix: context, detail)

          + +
          R-60355-64447-23225-33179-21170-11020-20743-59440
          +

          On success, the sqlite3_prepare() family of routines return SQLITE_OK; otherwise an error code is returned. +(source: c3ref/prepare.html, checked-by: th3/req1/prepare01.test, matrix: context, detail)

          + +
          R-60364-48303-16474-64960-19278-15379-28844-42689
          +

          The sqlite3_mutex_try() interface returns SQLITE_OK upon successful entry. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-60371-22228-63292-43045-55610-34824-26426-18643
          +

          However, there cannot be gaps in the columns of the index that are used. +(source: optoverview.html, matrix: context, detail)

          + +
          R-60470-29837-23817-60993-08685-62249-11012-03852
          +

          The normal ROWID selection algorithm described above will generate monotonically increasing unique ROWIDs as long as you never use the maximum ROWID value and you never delete the entry in the table with the largest ROWID. +(source: autoinc.html, checked-by: th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-60541-63059-13982-01066-19481-07947-17056-17575
          +

          Running VACUUM to rebuild the database reclaims this space and reduces the size of the database file. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-60567-47780-15259-20158-13854-20870-19515-07838
          +

          Unless it returns SQLITE_MISUSE, the sqlite3_wal_checkpoint_v2() interface sets the error information that is queried by sqlite3_errcode() and sqlite3_errmsg(). +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-60616-50251-50131-13271-23159-13048-15084-43797
          +

          If the default value of a column is an expression in parentheses, then the expression is evaluated once for each row inserted and the results used in the new row. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-60626-59740-27448-56337-63939-00650-38940-26585
          +

          All query parameters are always passed through into the xOpen method of the VFS even if they are previously read and interpreted by the SQLite core. +(source: uri.html, matrix: context, detail)

          + +
          R-60642-04082-57988-56847-11396-02756-59286-18214
          +

          If the writer lock cannot be obtained immediately, and a busy-handler is configured, it is invoked and the writer lock retried until either the busy-handler returns 0 or the lock is successfully obtained. +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/wal.c, tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-60722-16865-19617-65256-11278-03266-08396-03886
          +

          sqlite> CREATE INDEX i3 ON t1(b); sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 OR b=2; QUERY PLAN `--MULTI-INDEX OR |--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) `--SEARCH TABLE t1 USING INDEX i3 (b=?) +(source: eqp.html, matrix: context, detail)

          + +
          R-60735-46752-55529-42699-37701-47683-08130-22396
          +

          BLOBs are encoded as hexadecimal literals. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-60748-56514-55459-48719-62733-56255-26618-29581
          +

          If the hard heap limit is enabled and if sqlite3_soft_heap_limit(N) is invoked with a value of N that is greater than the hard heap limit, the the soft heap limit is set to the value of the hard heap limit. +(source: c3ref/hard_heap_limit64.html, matrix: context, detail)

          + +
          R-60755-45226-57184-35002-64218-27799-00922-32350
          +

          The application_id PRAGMA is used to query or set the 32-bit signed big-endian "Application ID" integer located at offset 68 into the database header. +(source: pragma.html, checked-by: th3/cov1/pragma20.test, matrix: context, detail)

          + +
          R-60758-29241-24503-58415-42517-14147-34293-65020
          +

          The RELEASE command causes all savepoints back to and including the most recent savepoint with a matching name to be removed from the transaction stack. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-60770-10612-35184-24244-53222-19878-52254-20031
          +

          One of the ALL or DISTINCT keywords may follow the SELECT keyword in a simple SELECT statement. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-60775-64916-04549-62415-27709-55207-27671-06558
          +

          If a WHERE clause is specified, the WHERE expression is evaluated for each row in the input data as a boolean expression. Only rows for which the WHERE clause expression evaluates to true are included from the dataset before continuing. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-60806-29331-56214-63587-21345-27818-10618-50452
          +

          The answers from changes() and last_insert_rowid() depend on prior SQL statements, and so they are also non-deterministic. +(source: deterministic.html, matrix: context, detail)

          + +
          R-60813-08986-02359-37993-40551-24945-25887-06253
          +

          If another thread is already within the mutex, sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return SQLITE_BUSY. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-60831-05341-23362-01720-38236-12013-65294-04816
          +

          The argument is may be either in parentheses or it may be separated from the pragma name by an equal sign. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-60876-64599-55796-06816-32195-01348-28462-53334
          +

          The sqlite3_value_text16() interface extracts a UTF-16 string in the native byte-order of the host machine. +(source: c3ref/value_blob.html, checked-by: th3/req1/value02.test, th3/req1/value03.test, matrix: context, detail)

          + +
          R-60908-02162-62695-08898-00608-41143-47614-24139
          +

          In the current implementation, the update hook is not invoked when conflicting rows are deleted because of an ON CONFLICT REPLACE clause. +(source: c3ref/update_hook.html, checked-by: th3/cov1/main15.test, matrix: context, detail)

          + +
          R-60985-57662-04483-59248-10439-16937-18279-52954
          +

          SQLite will convert the value back to floating point when extracting it from the record. +(source: fileformat2.html, checked-by: src/expr.c, matrix: context, detail)

          + +
          R-61005-38009-10424-51044-09118-00847-38862-56166
          +

          The third column is the name of the database file itself, or an empty string if the database is not associated with a file. +(source: pragma.html, checked-by: th3/req1/pragma14.test, matrix: context, detail)

          + +
          R-61006-08918-45261-48717-64220-57830-55931-08839
          +

          If the memory pointer is not NULL then the alternative memory allocator is engaged to handle all of SQLites memory allocation needs. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-61011-49942-02510-58821-51919-09145-23706-24617
          +

          If an sqlite3_exec() callback returns non-zero, the sqlite3_exec() routine returns SQLITE_ABORT without invoking the callback again and without running any subsequent SQL statements. +(source: c3ref/exec.html, checked-by: th3/req1/exec01.test, matrix: context, detail)

          + +
          R-61057-06282-34752-62385-16178-37477-62681-46915
          +

          When selecting the order of tables in a join, SQLite uses an efficient polynomial-time algorithm. +(source: optoverview.html, matrix: context, detail)

          + +
          R-61141-39803-04912-41496-05961-04473-04345-36188
          +

          The value of the default cache size is stored in the 4-byte big-endian integer located at offset 48 in the header of the database file. +(source: pragma.html, checked-by: th3/req1/pragma09.test, matrix: context, detail)

          + +
          R-61158-57305-03105-25357-56020-55639-01161-13829
          +

          If the third parameter to sqlite3_bind_text16() is not NULL, then it should be a pointer to well-formed UTF16 text. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-61172-15671-64149-04052-46334-28337-33946-53778
          +

          The DROP TRIGGER statement removes a trigger created by the CREATE TRIGGER statement. +(source: lang_droptrigger.html, checked-by: tcl/e_droptrigger.test, matrix: context, detail)

          + +
          R-61177-47713-20456-53383-60828-21202-49535-63505
          +

          The sqlite3_vfs_find() interface returns a pointer to a VFS given its name. +(source: c3ref/vfs_find.html, checked-by: th3/req1/vfs01.test, matrix: context, detail)

          + +
          R-61189-52809-58613-48789-49594-50841-42659-38002
          +

          If the function pointer is not NULL, it is invoked by sqlite3_log() to process each logging event. +(source: c3ref/c_config_covering_index_scan.html, checked-by: th3/cov1/log01.test, matrix: context, detail)

          + +
          R-61209-06413-51781-11352-22820-24005-55507-30248
          +

          SQLite will always allocate at least mxPathname+1 bytes for the output buffer xFullPathname. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-61241-11973-05308-06384-59636-46330-32526-49143
          +

          A zeroblob uses a fixed amount of memory (just an integer to hold its size) while it is being processed. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind02.test, matrix: context, detail)

          + +
          R-61275-35157-49893-43294-29165-05746-06508-08638
          +

          The SQLITE_CONFIG_MEMSTATUS option takes single argument of type int, interpreted as a boolean, which enables or disables the collection of memory allocation statistics. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-61304-29449-15087-21131-58882-51770-33861-39357
          +

          The unlikely(X) function is equivalent to likelihood(X, 0.0625). +(source: lang_corefunc.html, checked-by: src/resolve.c, matrix: context, detail)

          + +
          R-61362-32087-29784-51692-52137-61704-15338-45644
          +

          Attempting to insert a row into the track table that does not correspond to any row in the artist table will fail, +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys01.test, matrix: context, detail)

          + +
          R-61376-43478-41054-59749-08806-37073-25549-48326
          +

          The glob(X,Y) function is equivalent to the expression "Y GLOB X". +(source: lang_corefunc.html, checked-by: th3/req1/func01.test, matrix: context, detail)

          + +
          R-61376-57267-60176-57380-17573-65142-26150-27865
          +

          A "CASCADE" action propagates the delete or update operation on the parent key to each dependent child key. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-61413-50265-52071-27114-12254-11492-58681-53001
          +

          The SQLITE_CONFIG_STMTJRNL_SPILL option takes a single parameter which becomes the statement journal spill-to-disk threshold. +(source: c3ref/c_config_covering_index_scan.html, matrix: context, detail)

          + +
          R-61427-46983-18669-51894-26690-07828-25787-33323
          +

          For example, a query like the following might be used to find all R*Tree entries that overlap with a circle centered a 45.3,22.9 with a radius of 5.0: SELECT id FROM demo_index WHERE id MATCH circle(45.3, 22.9, 5.0) +(source: rtree.html, matrix: context, detail)

          + +
          R-61430-55629-14606-55181-61950-28043-41747-60450
          +

          If an out-of-memory condition or IO error occurred during any prior sqlite3_backup_step() call on the same sqlite3_backup object, then sqlite3_backup_finish() returns the corresponding error code. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-61435-31567-58098-41334-50609-21089-31560-63690
          +

          The returned string is always UTF-8 encoded. +(source: c3ref/column_decltype.html, matrix: context, detail)

          + +
          R-61444-46004-20245-30772-61521-38434-38855-21947
          +

          If the X callback is NULL or if the M mask is zero, then tracing is disabled. +(source: c3ref/trace_v2.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-61449-07528-25918-54581-50691-46240-35761-07017
          +

          If the 4th parameter to the sqlite3_result_text* interfaces or to sqlite3_result_blob is the special constant SQLITE_STATIC, then SQLite assumes that the text or BLOB result is in constant space and does not copy the content of the parameter nor call a destructor on the content when it has finished using that result. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-61480-49358-44699-35274-34938-16016-20585-63326
          +

          It is called to dispose of the BLOB or string even if the call to the bind API fails, except the destructor is not called if the third parameter is a NULL pointer or the fourth parameter is negative. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-61533-25862-33162-64388-19135-16857-63238-64063
          +

          The SQLite R*Tree implementation does not support R*Trees wider than 5 dimensions. +(source: rtree.html, matrix: context, detail)

          + +
          R-61533-26777-10805-19639-06010-35256-55057-28233
          +

          The sqlite3_result_int64() interface sets the return value of the application-defined function to be the 64-bit signed integer value given in the 2nd argument. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-61561-09244-64416-20951-61914-64570-44208-64280
          +

          SQLITE_OPEN_READWRITE The database is opened for reading and writing if possible, or reading only if the file is write protected by the operating system. In either case the database must already exist, otherwise an error is returned. +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-61562-13487-33758-31073-47966-53384-12179-59162
          +

          The xCurrentTime() method returns a Julian Day Number for the current date and time as a floating point value. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-61616-46700-48571-17878-11289-09346-32706-45031
          +

          Similar queries may be run if the content of the parent key is modified or a new row is inserted into the parent table. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys10.test, matrix: context, detail)

          + +
          R-61726-11117-39197-35640-53612-54106-15944-36516
          +

          SQLITE_LIMIT_TRIGGER_DEPTH The maximum depth of recursion for triggers. +(source: c3ref/c_limit_attached.html, checked-by: th3/req1/limit02.test, matrix: context, detail)

          + +
          R-61766-15253-61535-09888-08438-64512-26902-02870
          +

          Executing any other type of SQL statement does not affect the value returned by sqlite3_total_changes(). +(source: c3ref/total_changes.html, checked-by: tcl/e_totalchanges.test, matrix: context, detail)

          + +
          R-61808-14344-47257-03994-26724-50964-10589-13190
          +

          The sqlite3_update_hook() interface does not fire callbacks for changes to a WITHOUT ROWID table. +(source: withoutrowid.html, checked-by: tcl/hook.test, th3/cov1/main15.test, matrix: context, detail)

          + +
          R-61809-62207-01008-46404-05799-53014-10578-37094
          +

          For an "ON DELETE CASCADE" action, this means that each row in the child table that was associated with the deleted parent row is also deleted. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys16.test, matrix: context, detail)

          + +
          R-61815-26679-56101-35658-51912-28874-35291-46177
          +

          SQLite will invoke sqlite3_free() on *pzErrMsg after xEntryPoint() returns. +(source: c3ref/auto_extension.html, checked-by: th3/req1/autoext01.test, matrix: context, detail)

          + +
          R-61839-52333-58577-62900-39033-24200-06973-14092
          +

          This interface is used to retrieve and reset counter values from a prepared statement. The first argument is the prepared statement object to be interrogated. The second argument is an integer code for a specific SQLITE_STMTSTATUS counter to be interrogated. +(source: c3ref/stmt_status.html, matrix: context, detail)

          + +
          R-61854-19914-11596-34735-37969-17089-57602-12373
          +

          The sqlite3_finalize(S) routine can be called at any point during the life cycle of prepared statement S: before statement S is ever evaluated, after one or more calls to sqlite3_reset(), or after any call to sqlite3_step() regardless of whether or not the statement has completed execution. +(source: c3ref/finalize.html, checked-by: th3/req1/finalize01.test, matrix: context, detail)

          + +
          R-61862-04293-61183-46877-49121-08671-06264-56801
          +

          This is the approximate number of bytes of heap memory used to store the prepared statement. +(source: c3ref/c_stmtstatus_counter.html, matrix: context, detail)

          + +
          R-61888-49680-38370-22600-14954-58148-33546-00932
          +

          SQLite invokes the xCreate() method to construct a new cache instance. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-61914-48074-43351-14056-51344-34537-46858-37537
          +

          If the table is initially empty, then a ROWID of 1 is used. +(source: autoinc.html, checked-by: src/vdbe.c, th3/req1/autoinc01.test, matrix: context, detail)

          + +
          R-61915-31690-21946-53304-13926-27111-60628-08373
          +

          The sqlite3_file_control() interface makes a direct call to the xFileControl method for the sqlite3_io_methods object associated with a particular database identified by the second argument. +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-61939-33480-39091-09989-20555-53712-51566-46990
          +

          All terms of the WHERE clause are analyzed to see if they can be satisfied using indexes. +(source: optoverview.html, matrix: context, detail)

          + +
          R-61942-17018-62236-02362-42701-24808-41313-47258
          +

          An SQL statement can be preceded by the keyword "EXPLAIN" or by the phrase "EXPLAIN QUERY PLAN". +(source: lang_explain.html, checked-by: th3/cov1/vdbeaux01.test, matrix: context, detail)

          + +
          R-61949-35727-14867-12999-21207-20215-20581-25391
          +

          The first argument after the SQLITE_DBCONFIG_LOOKASIDE verb may be NULL in which case SQLite will allocate the lookaside buffer itself using sqlite3_malloc(). +(source: c3ref/c_dbconfig_defensive.html, checked-by: src/main.c, th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-61972-47750-14652-28694-02794-16402-15502-30377
          +

          If SQLite is compiled and configured to support threadsafe database connections, then the source database connection may be used concurrently from within other threads. +(source: c3ref/backup_finish.html, matrix: context, detail)

          + +
          R-61975-13410-23961-36433-37989-49063-55179-53550
          +

          It is not possible for an IS or IS NOT expression to evaluate to NULL. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-61981-08185-11399-27946-15257-51226-00201-31403
          +

          In an index on a WITHOUT ROWID table, if a column of the PRIMARY KEY is also a column in the index and has a matching collating sequence, then the indexed column is not repeated in the table-key suffix on the end of the index record. +(source: fileformat2.html, checked-by: th3/req1/fileformat04.test, matrix: context, detail)

          + +
          R-61987-00541-30628-29518-50059-37734-56753-06843
          +

          SQLITE_LIMIT_LENGTH The maximum size of any string or BLOB or table row, in bytes. +(source: c3ref/c_limit_attached.html, checked-by: tcl/sqllimits1.test, th3/req1/limit01.test, matrix: context, detail)

          + +
          R-62028-47212-10324-26388-32955-09019-38502-43412
          +

          All calls obtain an exclusive "checkpoint" lock on the database file. +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/wal.c, tcl/e_walckpt.test, matrix: context, detail)

          + +
          R-62039-61571-24368-30333-11201-30520-56861-22686
          +

          Semicolons that are embedded within string literals or quoted identifier names or comments are not independent tokens (they are part of the token in which they are embedded) and thus do not count as a statement terminator. +(source: c3ref/complete.html, checked-by: th3/cov1/complete01.test, matrix: context, detail)

          + +
          R-62073-11209-24210-38287-05077-10013-43316-09914
          +

          The changes() SQL function is a wrapper around the sqlite3_changes() C/C++ function and hence follows the same rules for counting changes. +(source: lang_corefunc.html, checked-by: src/func.c, matrix: context, detail)

          + +
          R-62084-05956-21371-24273-03009-23026-15537-48661
          +

          The typeof(X) function returns a string that indicates the datatype of the expression X: "null", "integer", "real", "text", or "blob". +(source: lang_corefunc.html, checked-by: th3/cov1/func04.test, matrix: context, detail)

          + +
          R-62098-31964-50805-21241-10330-01586-45989-63464
          +

          The date() function returns the date in this format: YYYY-MM-DD. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-62101-33764-02885-01676-40188-04354-35995-63967
          +

          The transaction names need not be unique. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-62103-54815-14934-53724-30869-15955-58646-34076
          +

          If the busy callback is NULL, then SQLITE_BUSY is returned immediately upon encountering the lock. +(source: c3ref/busy_handler.html, checked-by: th3/req1/busy01.test, matrix: context, detail)

          + +
          R-62128-24425-59419-24092-37826-34939-18827-33006
          +

          The number of bytes stored on the index page is never less than M. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-62139-20964-30258-06406-62558-17842-12310-23723
          +

          The sqlite3_mutex_alloc() routine allocates a new mutex and returns a pointer to it. +(source: c3ref/mutex_alloc.html, matrix: context, detail)

          + +
          R-62157-11346-38405-02312-46550-08471-09631-26487
          +

          Automatically started transactions are committed when the last SQL statement finishes. +(source: lang_transaction.html, matrix: context, detail)

          + +
          R-62172-00036-57834-47035-33859-45076-31922-24757
          +

          In this implementation, the standard C library function localtime_r() is used to assist in the calculation of local time. +(source: lang_datefunc.html, checked-by: src/date.c, matrix: context, detail)

          + +
          R-62267-62884-09796-14012-16099-39965-57946-58351
          +

          New automatically generated integer primary keys for AUTOINCREMENT tables are guaranteed to be larger than the sqlite_sequence. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-62291-37402-63159-44375-18587-14784-42471-08644
          +

          The SQLITE_UTF16_ALIGNED value for eTextRep forces strings to begin on an even byte address. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-62291-48401-09187-39181-50628-35603-55893-32208
          +

          In the extreme case where the columns being indexed cover all columns of the PRIMARY KEY, the index will consist of only the columns being indexed. The ex25acde example above demonstrates this. +(source: fileformat2.html, checked-by: th3/req1/fileformat04.test, matrix: context, detail)

          + +
          R-62308-64553-46829-46708-05864-23145-57136-36663
          +

          When one of RAISE(ROLLBACK,...), RAISE(ABORT,...) or RAISE(FAIL,...) is called during trigger-program execution, the specified ON CONFLICT processing is performed and the current query terminates. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-62327-53843-00789-05763-27259-51867-41833-27488
          +

          For CURRENT_TIME, the format of the value is "HH:MM:SS". +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-62338-03151-32833-50529-63145-58374-11729-12446
          +

          Comments can appear anywhere whitespace can occur, including inside expressions and in the middle of other SQL statements. +(source: lang_comment.html, checked-by: th3/req1/comment01.test, matrix: context, detail)

          + +
          R-62380-26708-45604-24232-06189-26790-29124-54464
          +

          For any given query, the fact that the OR-clause optimization described here can be used does not guarantee that it will be used. +(source: optoverview.html, matrix: context, detail)

          + +
          R-62406-19374-15611-19215-61037-24367-51028-27326
          +

          The SQLITE_OPEN_DELETEONCLOSE will be set for TEMP databases and their journals, transient databases, and subjournals. +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-62434-33746-54785-17605-60783-47230-32024-49540
          +

          Thus, if the database includes AFTER triggers that modifies some of the values of each row inserted or updated, the RETURNING clause emits the original values that are computed before those triggers run. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-62450-40032-48633-16143-21492-49055-31149-65125
          +

          The sqlite3_result_error_toobig() interface causes SQLite to throw an error indicating that a string or BLOB is too long to represent. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-62469-05091-48869-23817-54734-43619-45624-64340
          +

          New SQL statements that are started after the running statement count reaches zero are not effected by the sqlite3_interrupt(). +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-62477-06476-47005-06861-24657-48512-17530-06708
          +

          For example, the values NULL, 0.0, 0, 'english' and '0' are all considered to be false. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-62529-02872-42080-52891-13443-54286-42392-42073
          +

          The sqlite_offset(X) function returns the byte offset in the database file for the beginning of the record from which value would be read. +(source: lang_corefunc.html, matrix: context, detail)

          + +
          R-62557-09390-19199-07054-57696-39577-58389-44787
          +

          SQLite uses the path component of the URI as the name of the disk file which contains the database. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-62598-50665-64934-51801-32415-41213-44232-38622
          +

          If an error occurs while running sqlite3_backup_step(B,N), then an error code is returned. +(source: c3ref/backup_finish.html, checked-by: th3/cov1/backup01.test, matrix: context, detail)

          + +
          R-62610-51329-57761-33466-25437-21860-03475-27712
          +

          A dollar-sign followed by an identifier name also holds a spot for a named parameter with the name $AAAA. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-62671-45936-15699-15939-47274-39312-22685-45097
          +

          Coincidentally, that same index is useful for locating the team leader of a particular team: SELECT person_id FROM person WHERE is_team_leader AND team_id=?1; +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-62702-40333-38179-40885-41988-22128-55744-38762
          +

          If for some reason, sqlite3_initialize() is unable to initialize the library (perhaps it is unable to allocate a needed resource such as a mutex) it returns an error code other than SQLITE_OK. +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-62740-39384-05078-12157-18759-37018-24032-16854
          +

          To change from "full" or "incremental" back to "none" always requires running VACUUM even on an empty database. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-62773-63407-48411-60588-32030-64322-40065-55617
          +

          time(time-value, modifier, modifier, ...) +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-62782-27113-42237-60058-30893-13916-02478-23717
          +

          The module name is registered on the database connection specified by the first parameter. +(source: c3ref/create_module.html, matrix: context, detail)

          + +
          R-62787-27093-28776-07696-30673-33201-48142-02108
          +

          The new journal mode is returned. +(source: pragma.html, checked-by: th3/req1/pragma23.test, matrix: context, detail)

          + +
          R-62792-33996-11773-03176-05046-17928-37966-25264
          +

          Note that "±NNN months" works by rendering the original date into the YYYY-MM-DD format, adding the ±NNN to the MM month value, then normalizing the result. +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-62804-28221-24652-30727-46370-42129-23035-01106
          +

          The "legacy" schema format (1) ignores index sort order. +(source: lang_createindex.html, checked-by: th3/req1/createidx02.test, matrix: context, detail)

          + +
          R-62839-07969-20835-12393-10949-34728-00422-57830
          +

          The fourth column is the index of the specific foreign key constraint that failed. +(source: pragma.html, checked-by: tcl/fkey5.test, th3/cov1/fkey23.test, matrix: context, detail)

          + +
          R-62860-04741-41366-30406-60752-17856-14374-30516
          +

          If the blocked connection is attempting to obtain a write-lock on a shared-cache table, and more than one other connection currently holds a read-lock on the same table, then SQLite arbitrarily selects one of the other connections to use as the blocking connection. +(source: c3ref/unlock_notify.html, matrix: context, detail)

          + +
          R-62898-22698-26165-43256-00813-48770-03104-06155
          +

          This function is used to write data into an open BLOB handle from a caller-supplied buffer. N bytes of data are copied from the buffer Z into the open BLOB, starting at offset iOffset. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-62902-41226-55424-31114-14414-20606-40238-02650
          +

          In an UPDATE FROM statement, the auxiliary tables named in the FROM clause may not participate in the RETURNING clause. +(source: lang_returning.html, matrix: context, detail)

          + +
          R-62913-19830-16030-42655-41174-29116-40982-36331
          +

          Otherwise, it is evaluated against a single arbitrarily chosen row from within the group. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-62920-36411-37604-08296-13654-34819-36636-51244
          +

          The sqlite3_stmt_busy(S) interface returns true (non-zero) if the prepared statement S has been stepped at least once using sqlite3_step(S) but has neither run to completion (returned SQLITE_DONE from sqlite3_step(S)) nor been reset using sqlite3_reset(S). +(source: c3ref/stmt_busy.html, checked-by: th3/cov1/vdbeapi03.test, matrix: context, detail)

          + +
          R-62920-47450-51194-26975-01851-13117-37430-41623
          +

          The busy-handler callback is never invoked in the SQLITE_CHECKPOINT_PASSIVE mode. +(source: c3ref/wal_checkpoint_v2.html, checked-by: src/wal.c, tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-62953-16283-60973-36600-59526-31076-28505-32788
          +

          The sqlite3_result_error() and sqlite3_result_error16() functions cause the implemented SQL function to throw an exception. +(source: c3ref/result_blob.html, checked-by: th3/req1/result01.test, matrix: context, detail)

          + +
          R-62976-44398-18342-24138-35824-24327-06786-34486
          +

          sqlite> EXPLAIN QUERY PLAN SELECT t1.*, t2.* FROM t1, t2 WHERE t1.a=1 AND t1.b>2; QUERY PLAN |--SEARCH TABLE t1 USING INDEX i2 (a=? AND b>?) `--SCAN TABLE t2 +(source: eqp.html, matrix: context, detail)

          + +
          R-62978-45795-36249-12857-49090-15958-00681-53876
          +

          SQLITE_OPEN_SHAREDCACHE The database is opened shared cache enabled, overriding the default shared cache setting provided by sqlite3_enable_shared_cache(). +(source: c3ref/open.html, matrix: context, detail)

          + +
          R-63005-41812-25626-08915-56924-18701-34240-17116
          +

          The integer values returned by two invocations of "PRAGMA data_version" from the same connection will be different if changes were committed to the database by any other connection in the interim. +(source: pragma.html, checked-by: tcl/pragma3.test, th3/cov1/pragma26.test, matrix: context, detail)

          + +
          R-63007-00158-07444-30400-48022-49637-62807-30158
          +

          The object and pointer to it must remain valid until then. +(source: c3ref/bind_blob.html, matrix: context, detail)

          + +
          R-63043-31985-03147-25743-35105-56824-27105-53861
          +

          A pragma may have an optional schema-name before the pragma name. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-63048-43246-17135-38740-38774-19406-60211-40776
          +

          The number of freelist pages is stored as a 4-byte big-endian integer in the database header at an offset of 36 from the beginning of the file. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-63057-40065-06939-62026-28343-23740-17584-22706
          +

          The printf(FORMAT,...) SQL function works like the sqlite3_mprintf() C-language function and the printf() function from the standard C library. +(source: lang_corefunc.html, checked-by: tcl/printf2.test, th3/cov1/printf08.test, matrix: context, detail)

          + +
          R-63063-00748-16445-34795-46686-39617-28312-04661
          +

          If the declared type for a column contains the string "BLOB" or if no type is specified then the column has affinity BLOB. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-63075-15970-39501-22460-58793-43455-08281-02350
          +

          Once the view is created, it can be used in the FROM clause of another SELECT in place of a table name. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-63084-42258-54235-44279-08664-11821-33988-63457
          +

          Calling sqlite3_blob_bytes() on an aborted blob handle always returns zero. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-63088-37469-41348-62985-35702-04852-27256-05198
          +

          Tables child6 and child7 are incorrect because while both have UNIQUE indices on their parent keys, the keys are not an exact match to the columns of a single UNIQUE index. +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys07.test, matrix: context, detail)

          + +
          R-63107-29542-42038-49029-17221-49854-37760-53513
          +

          The sixth argument to sqlite3_bind_text64() must be one of SQLITE_UTF8, SQLITE_UTF16, SQLITE_UTF16BE, or SQLITE_UTF16LE to specify the encoding of the text in the third parameter. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-63119-53774-25938-08953-42086-26261-27933-12483
          +

          New database files created by SQLite use format 4 by default. +(source: fileformat2.html, checked-by: th3/req1/fileformat01.test, matrix: context, detail)

          + +
          R-63124-28591-54682-33320-59572-27756-28507-16643
          +

          The pragma is like integrity_check except that it does not verify UNIQUE constraints and does not verify that index content matches table content. +(source: pragma.html, matrix: context, detail)

          + +
          R-63138-42446-16317-19373-58144-17163-01725-20742
          +

          If none of the arguments to max() define a collating function, then the BINARY collating function is used. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-63158-42531-36923-32686-05307-30173-57746-45416
          +

          These APIs are only available if the library was compiled with the SQLITE_ENABLE_COLUMN_METADATA C-preprocessor symbol. +(source: c3ref/column_database_name.html, matrix: context, detail)

          + +
          R-63159-49573-46616-00271-21180-18293-63861-41327
          +

          If no schema name is specified, and the TEMP keyword is not present, the VIEW is created in the main database. +(source: lang_createview.html, checked-by: th3/req1/view01.test, matrix: context, detail)

          + +
          R-63167-05205-45599-43338-46949-25227-48175-10749
          +

          A virtual table is destroyed using the ordinary DROP TABLE statement. +(source: lang_createvtab.html, matrix: context, detail)

          + +
          R-63234-56981-14437-01927-09804-62801-28815-37860
          +

          A value of -1 means rowid and a value of -2 means that an expression is being used. +(source: pragma.html, matrix: context, detail)

          + +
          R-63235-50818-32083-65430-57291-26103-11022-63065
          +

          When the payload of a b-tree cell is too large for the b-tree page, the surplus is spilled onto overflow pages. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-63244-23082-15887-51901-20973-26143-20960-26958
          +

          When an expression is a simple reference to a column of a real table (not a VIEW or subquery) then the expression has the same affinity as the table column. +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-63257-11740-13370-40315-30257-30447-50403-36483
          +

          Calling sqlite3_close() or sqlite3_close_v2() with a NULL pointer argument is a harmless no-op. +(source: c3ref/close.html, checked-by: src/main.c, th3/cov1/main23.test, matrix: context, detail)

          + +
          R-63260-45699-31431-11817-19083-14661-24808-60223
          +

          The default encoding will be UTF-8 for databases created using sqlite3_open() or sqlite3_open_v2(). +(source: c3ref/open.html, checked-by: th3/cov1/main12.test, matrix: context, detail)

          + +
          R-63285-37134-15488-58217-13163-52553-20689-06808
          +

          In the SQL statement text input to sqlite3_prepare_v2() and its variants, literals may be replaced by a parameter that matches one of following templates: ? ?NNN :VVV @VVV $VVV In the templates above, NNN represents an integer literal, and VVV represents an alphanumeric identifier. +(source: c3ref/bind_blob.html, checked-by: th3/req1/bind01.test, matrix: context, detail)

          + +
          R-63286-51977-31491-11604-12483-48115-04561-38158
          +

          If the ORDER BY expression is an identifier that corresponds to the alias of one of the output columns, then the expression is considered an alias for that column. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-63294-00538-51136-33751-00245-32067-21028-12625
          +

          When all collating functions having the same name are deleted, that collation is no longer usable. +(source: c3ref/create_collation.html, checked-by: th3/req1/createcoll01.test, matrix: context, detail)

          + +
          R-63298-27030-17109-21513-26476-43157-51997-36280
          +

          Triggers may be created on views, as well as ordinary tables, by specifying INSTEAD OF in the CREATE TRIGGER statement. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-63299-18573-32017-29403-14917-35510-40700-49799
          +

          The values emitted by the RETURNING clause are the values as seen by the top-level DELETE, INSERT, or UPDATE statement and do not reflect any subsequent value changes made by triggers. +(source: lang_returning.html, checked-by: th3/cov1/returning01.test, matrix: context, detail)

          + +
          R-63304-47938-37544-24083-32523-59339-12063-04475
          +

          Applications may change the content of the string returned by sqlite3_str_value(X) as long as they do not write into any bytes outside the range of 0 to sqlite3_str_length(X) and do not read or write any byte after any subsequent sqlite3_str method call. +(source: c3ref/str_errcode.html, matrix: context, detail)

          + +
          R-63325-48378-49771-42071-13733-04560-14136-48632
          +

          The SQLITE_CONFIG_PCACHE2 option takes a single argument which is a pointer to an sqlite3_pcache_methods2 object. This object specifies the interface to a custom page cache implementation. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3pcache.c, matrix: context, detail)

          + +
          R-63341-57517-64693-29591-34989-59774-15075-48148
          +

          If the BLOB handle passed as the first argument was not opened for writing (the flags parameter to sqlite3_blob_open() was zero), this function returns SQLITE_READONLY. +(source: c3ref/blob_write.html, checked-by: tcl/e_blobwrite.test, matrix: context, detail)

          + +
          R-63404-48526-63691-02356-01054-10642-53789-36126
          +

          The P argument is a pointer to the prepared statement and the X argument is unused. +(source: c3ref/c_trace.html, checked-by: th3/cov1/trace01.test, matrix: context, detail)

          + +
          R-63408-55464-37825-38820-53279-17116-24066-22476
          +

          All subsequent calls to sqlite3_blob_read(), sqlite3_blob_write() or sqlite3_blob_reopen() on an aborted blob handle immediately return SQLITE_ABORT. +(source: c3ref/blob_reopen.html, checked-by: th3/req1/blob01.test, matrix: context, detail)

          + +
          R-63421-15521-37250-06535-51349-22995-65191-63992
          +

          This means that, provided the API is not misused, it is always safe to call sqlite3_blob_close() on *ppBlob after this function it returns. +(source: c3ref/blob_open.html, checked-by: tcl/e_blobopen.test, matrix: context, detail)

          + +
          R-63435-12225-33829-37402-17211-27130-05815-22642
          +

          The sqlite3_get_autocommit() interface returns non-zero or zero if the given database connection is or is not in autocommit mode, respectively. +(source: c3ref/get_autocommit.html, matrix: context, detail)

          + +
          R-63443-09418-01239-16017-27553-21198-10588-27536
          +

          Every WITHOUT ROWID table must have a PRIMARY KEY. +(source: withoutrowid.html, checked-by: tcl/without_rowid5.test, th3/cov1/withoutrowid01.test, matrix: context, detail)

          + +
          R-63464-64949-61376-49766-27105-42623-27880-27478
          +

          If an application uses more than one database connection then application-defined SQL functions must be added to each database connection separately. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc01.test, matrix: context, detail)

          + +
          R-63472-46769-27275-37406-54575-06040-42542-11572
          +

          Specifying an unknown parameter in the query component of a URI is not an error. +(source: c3ref/open.html, checked-by: tcl/e_uri.test, matrix: context, detail)

          + +
          R-63519-36751-50402-28921-52304-51801-25208-52249
          +

          The load_extension(X,Y) function loads SQLite extensions out of the shared library file named X using the entry point Y. +(source: lang_corefunc.html, checked-by: th3/cov1/func03.test, matrix: context, detail)

          + +
          R-63522-46088-33895-54497-03733-53184-07098-33228
          +

          The only way to change out of EXCLUSIVE locking mode is to first change out of WAL journal mode. +(source: wal.html, checked-by: tcl/e_wal.test, th3/req1/pragma05.test, matrix: context, detail)

          + +
          R-63549-59887-30432-35575-09108-37055-29466-09817
          +

          PRAGMA cache_spill; PRAGMA cache_spill=boolean; PRAGMA schema.cache_spill=N; +(source: pragma.html, checked-by: tcl/pragma2.test, matrix: context, detail)

          + +
          R-63565-54156-07796-04437-54657-38631-57442-48844
          +

          The sqlite3_str_append(X,S,N) method appends exactly N bytes from string S onto the end of the sqlite3_str object X. +(source: c3ref/str_append.html, matrix: context, detail)

          + +
          R-63573-50730-47689-26625-21808-11120-05729-38640
          +

          The expressions in a GROUP BY clause may not be aggregate expressions. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-63582-45120-10136-38887-13737-27800-47314-58816
          +

          A negative value is interpreted as "no limit". +(source: lang_update.html, checked-by: tcl/e_update.test, matrix: context, detail)

          + +
          R-63614-47421-34077-31697-65388-09052-31073-41571
          +

          If a column-list is specified, the number of columns in the result of the SELECT must be the same as the number of items in the column-list. +(source: lang_insert.html, checked-by: tcl/e_insert.test, matrix: context, detail)

          + +
          R-63656-25792-13227-10920-63493-08567-09592-14766
          +

          The sqlite3_db_handle interface returns the database connection handle to which a prepared statement belongs. +(source: c3ref/db_handle.html, checked-by: th3/req1/dbhandle01.test, matrix: context, detail)

          + +
          R-63660-13730-40361-36600-49819-61310-05389-38402
          +

          OLD and NEW references may only be used in triggers on events for which they are relevant, as follows: INSERT NEW references are valid UPDATE NEW and OLD references are valid DELETE OLD references are valid +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-63666-48755-16443-16891-11864-30751-29625-02647
          +

          If SQLite is compiled with the SQLITE_THREADSAFE=0 compile-time option then the entire mutexing subsystem is omitted from the build and hence calls to sqlite3_config() with the SQLITE_CONFIG_MUTEX configuration option will return SQLITE_ERROR. +(source: c3ref/c_config_covering_index_scan.html, checked-by: src/main.c, th3/th3main.c, matrix: context, detail)

          + +
          R-63672-25227-17465-07864-20680-40543-20473-50716
          +

          The outputs s0 and s1 are both weighted checksums using Fibonacci weights in reverse order. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-63674-39978-56596-19929-61687-32380-54180-59144
          +

          A call to sqlite3_backup_init() will fail, returning NULL, if there is already a read or read-write transaction open on the destination database. +(source: c3ref/backup_finish.html, checked-by: th3/cov1/backup01.test, matrix: context, detail)

          + +
          R-63684-00056-12744-41513-44383-51179-47104-18458
          +

          If there are fewer than N pages on the freelist, or if N is less than 1, or if the "(N)" argument is omitted, then the entire freelist is cleared. +(source: pragma.html, checked-by: th3/req1/pragma21.test, matrix: context, detail)

          + +
          R-63697-19365-62485-52298-29987-32888-31412-50224
          +

          Calls to sqlite3_db_config() return SQLITE_OK if and only if the call is considered successful. +(source: c3ref/db_config.html, checked-by: th3/req1/dbconfig01.test, matrix: context, detail)

          + +
          R-63721-11986-01337-51273-44360-30402-45045-08949
          +

          With the "v2" interface, any of the other result codes or extended result codes might be returned as well. +(source: c3ref/step.html, matrix: context, detail)

          + +
          R-63725-33821-44537-37255-59793-46389-19158-48724
          +

          Compute the date of the first Tuesday in October for the current year. SELECT date('now','start of year','+9 months','weekday 2'); +(source: lang_datefunc.html, checked-by: th3/req1/date01.test, matrix: context, detail)

          + +
          R-63742-65009-14401-02244-32779-40518-14763-45993
          +

          The LIKE optimization is not attempted if the right-hand side is a parameter and the statement was prepared using sqlite3_prepare() or sqlite3_prepare16(). +(source: optoverview.html, matrix: context, detail)

          + +
          R-63748-42498-08000-42048-14533-30815-48804-51551
          +

          The sqlite3_shutdown() routine deallocates any resources that were allocated by sqlite3_initialize(). +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-63806-59621-53713-38948-48550-43673-56726-15716
          +

          If the resetFlg is true, then the highest instantaneous value is reset back down to the current value. +(source: c3ref/db_status.html, checked-by: th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-63822-07193-39399-57145-23201-47133-55148-33056
          +

          If the column-name parameter to sqlite3_table_column_metadata() is a NULL pointer, then this routine simply checks for the existence of the table and returns SQLITE_OK if the table exists and SQLITE_ERROR if it does not. +(source: c3ref/table_column_metadata.html, checked-by: th3/cov1/metadata01.test, matrix: context, detail)

          + +
          R-63827-07147-50106-23079-54369-23240-21585-39525
          +

          To read a page from the database (call it page number P), a reader first checks the WAL to see if it contains page P. If so, then the last valid instance of page P that is followed by a commit frame or is a commit frame itself becomes the value read. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-63827-58581-51732-64119-62268-23504-01315-64410
          +

          Generated columns can participate in indexes, just like ordinary columns. +(source: gencol.html, matrix: context, detail)

          + +
          R-63860-02697-07339-29588-22030-08918-47419-18368
          +

          On second and subsequent calls to sqlite3_aggregate_context() for the same aggregate function instance, the same buffer is returned. +(source: c3ref/aggregate_context.html, checked-by: th3/req1/aggcntx01.test, matrix: context, detail)

          + +
          R-63920-18609-57046-60110-46900-57278-33644-19241
          +

          If there is no attached database N on the database connection D, or if database N is a temporary or in-memory database, then this function will return either a NULL pointer or an empty string. +(source: c3ref/db_filename.html, matrix: context, detail)

          + +
          R-63967-10740-31078-31148-41041-55599-05562-25747
          +

          The unary + is a no-op and will not generate any byte code in the prepared statement. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64004-53814-05259-60925-08012-55166-06006-38537
          +

          If there is no OFFSET clause, or the calculated integer value is negative, the effective OFFSET value is zero. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-64016-22984-52243-31154-04159-15253-33575-11293
          +

          A column with NUMERIC affinity may contain values using all five storage classes. +(source: datatype3.html, checked-by: th3/req1/datatype3_01.test, matrix: context, detail)

          + +
          R-64017-26165-55276-08272-52106-53519-03640-42248
          +

          The sqlite3_finalize() function is called to delete a prepared statement. +(source: c3ref/finalize.html, checked-by: th3/req1/finalize01.test, matrix: context, detail)

          + +
          R-64021-07698-52025-10986-56394-35084-34302-37940
          +

          If the write-ahead log is enabled (via the journal_mode pragma), this pragma causes a checkpoint operation to run on database database, or on all attached databases if database is omitted. +(source: pragma.html, matrix: context, detail)

          + +
          R-64032-17389-14849-50560-10397-51267-05389-65161
          +

          If the sqlite_stat1.idx column is NULL, then the sqlite_stat1.stat column contains a single integer which is the approximate number of rows in the table identified by sqlite_stat1.tbl. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-64049-08691-55124-50671-44406-19697-22475-30547
          +

          The expression "a IN (x, y, z, ...)" is equivalent to "a = +x OR a = +y OR a = +z OR ...". +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-64082-04685-34430-02984-31872-50387-26964-32862
          +

          No database changes are rolled back. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-64097-24821-08867-43816-57174-45858-42283-08645
          +

          However, if three additional indexes where added that contained columns b, c, and d as their left-most columns, then the OR-clause optimization might apply. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64103-17776-35606-10153-57490-26630-22697-19436
          +

          PRAGMA schema.index_list(table-name); This pragma returns one row for each index associated with the given table. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-64107-03133-60846-38260-58078-31674-53966-09002
          +

          The nullif(X,Y) function searches its arguments from left to right for an argument that defines a collating function and uses that collating function for all string comparisons. +(source: lang_corefunc.html, checked-by: th3/req1/func03.test, matrix: context, detail)

          + +
          R-64113-45477-15405-35111-28772-22089-43281-64875
          +

          Use sqlite3_db_config(db,SQLITE_DBCONFIG_ENABLE_LOAD_EXTENSION,..) to enable or disable only the C-API. +(source: c3ref/enable_load_extension.html, matrix: context, detail)

          + +
          R-64130-24369-52120-61237-04539-27042-01288-33957
          +

          The substr(X,Y,Z) function returns a substring of input string X that begins with the Y-th character and which is Z characters long. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-64138-28774-62367-40797-31143-24203-38235-49085
          +

          An aggregate query without a GROUP BY clause always returns exactly one row of data, even if there are zero rows of input data. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-64182-49733-18009-45461-02192-56112-34061-30398
          +

          The sqlite3_expanded_sql(P) interface returns a pointer to a UTF-8 string containing the SQL text of prepared statement P with bound parameters expanded. +(source: c3ref/expanded_sql.html, checked-by: th3/req1/sql01.test, matrix: context, detail)

          + +
          R-64199-22471-28685-05688-45410-48917-35278-06379
          +

          If the ORDER BY expression is assigned a collation sequence using the postfix COLLATE operator, then the specified collation sequence is used. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-64203-64297-25977-44727-61905-56050-52768-56293
          +

          The same SQL function may be registered multiple times using different preferred text encodings, with different implementations for each encoding. +(source: c3ref/create_function.html, checked-by: th3/req1/createfunc04.test, matrix: context, detail)

          + +
          R-64208-53052-48559-48683-00395-47002-65177-30547
          +

          The SQLITE_DEFAULT_PAGE_SIZE compile-time option can be used to change the default page size assigned to new databases. +(source: pragma.html, matrix: context, detail)

          + +
          R-64224-62578-03972-01663-15299-36598-00230-00133
          +

          If an UPDATE statement attempts to set an integer primary key or rowid column to a NULL or blob value, or to a string or real value that cannot be losslessly converted to an integer, a "datatype mismatch" error occurs and the statement is aborted. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-64249-42392-53555-26523-38701-52551-63844-05212
          +

          The ltrim(X,Y) function returns a string formed by removing any and all characters that appear in Y from the left side of X. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-64254-06275-15717-61317-29135-17923-39276-44642
          +

          The string returned by sqlite3_expanded_sql(P), on the other hand, is obtained from sqlite3_malloc() and must be free by the application by passing it to sqlite3_free(). +(source: c3ref/expanded_sql.html, checked-by: th3/req1/sql01.test, matrix: context, detail)

          + +
          R-64276-00534-35608-51878-49907-08473-11116-64004
          +

          Any existing statements prepared using the legacy sqlite3_prepare() interface may fail with an SQLITE_SCHEMA error after the foreign_keys setting is changed. +(source: pragma.html, checked-by: th3/req1/pragma19.test, matrix: context, detail)

          + +
          R-64317-38978-24132-13511-50003-08766-02219-42213
          +

          The other columns are pairs, one pair per dimension, containing the minimum and maximum values for that dimension, respectively. +(source: rtree.html, matrix: context, detail)

          + +
          R-64324-28127-56247-07957-53732-02733-48072-24920
          +

          A TEXT value is less than a BLOB value. +(source: datatype3.html, checked-by: th3/req1/datatype3_04.test, matrix: context, detail)

          + +
          R-64351-21396-30235-21975-23610-30773-00421-25207
          +

          sqlite> SELECT * FROM > (SELECT * FROM t1 WHERE a=1 ORDER BY b LIMIT 2) AS x, > (SELECT * FROM t2 WHERE c=1 ORDER BY d LIMIT 2) AS y; QUERY PLAN |--MATERIALIZE 0x18F06F0 | `--SEARCH TABLE t1 USING COVERING INDEX i2 (a=?) |--MATERIALIZE 0x18F80D0 | |--SEARCH TABLE t2 USING INDEX i4 (c=?) | `--USE TEMP B-TREE FOR ORDER BY |--SCAN SUBQUERY 0x18F06F0 AS x `--SCAN SUBQUERY 0x18F80D0 AS y +(source: eqp.html, matrix: context, detail)

          + +
          R-64365-33714-02196-49679-58449-42596-39965-50249
          +

          SQLITE_DBSTATUS_CACHE_HIT This parameter returns the number of pager cache hits that have occurred. +(source: c3ref/c_dbstatus_options.html, matrix: context, detail)

          + +
          R-64415-18962-49048-16298-22605-23771-20510-46620
          +

          A record might have fewer values than the number of columns in the corresponding table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-64444-28602-34432-27879-08826-07495-40207-13752
          +

          If the limit is zero, then the analysis limit is disabled and the ANALYZE command will examine all rows of each index. +(source: pragma.html, matrix: context, detail)

          + +
          R-64451-07163-52994-32419-24914-21127-60728-58807
          +

          The soft_heap_limit pragma always returns the same integer that would be returned by the sqlite3_soft_heap_limit64(-1) C-language function. +(source: pragma.html, checked-by: src/pragma.c, tcl/softheap1.test, matrix: context, detail)

          + +
          R-64470-55820-31502-18212-19924-05102-35790-30152
          +

          Calling this routine with an argument less than or equal to zero turns off all busy handlers. +(source: c3ref/busy_timeout.html, checked-by: th3/cov1/main21.test, matrix: context, detail)

          + +
          R-64479-57858-30969-38404-45379-17984-36095-58502
          +

          The highwater mark associated with SQLITE_DBSTATUS_STMT_USED is always 0. +(source: c3ref/c_dbstatus_options.html, checked-by: src/status.c, th3/req1/dbstatus01.test, matrix: context, detail)

          + +
          R-64488-01207-41542-36370-36584-38548-35733-59275
          +

          The temp_store_directory pragma can be used to specify the directory containing temporary files when FILE is specified. +(source: pragma.html, matrix: context, detail)

          + +
          R-64528-42778-02888-51810-06932-64442-58390-22409
          +

          If the 3rd parameter to the sqlite3_result_text* interfaces is non-negative, then as many bytes (not characters) of the text pointed to by the 2nd parameter are taken as the application-defined function result. +(source: c3ref/result_blob.html, checked-by: th3/req1/result02.test, matrix: context, detail)

          + +
          R-64531-59395-59522-15917-19627-46695-59010-51244
          +

          Invoking this pragma without an argument is equivalent to calling the sqlite3_wal_checkpoint() C interface. +(source: pragma.html, checked-by: th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-64535-08414-56299-20863-17793-59913-52096-13773
          +

          If there are less than N rows remaining after taking the OFFSET clause into account, or if the LIMIT clause evaluated to a negative value, then all remaining rows are deleted. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-64536-51728-48624-04422-11602-40097-21490-13878
          +

          The values for each column in the record immediately follow the header. +(source: fileformat2.html, checked-by: src/vdbe.c, matrix: context, detail)

          + +
          R-64550-29191-54086-24811-00443-47986-21003-27772
          +

          Note that the result from casting any non-BLOB value into a BLOB and the result from casting any BLOB value into a non-BLOB value may be different depending on whether the database encoding is UTF-8, UTF-16be, or UTF-16le. +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          + +
          R-64586-34038-50551-35162-29949-64214-50082-35974
          +

          On a checkpoint, the WAL is first flushed to persistent storage using the xSync method of the VFS. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-64600-17320-28497-51655-11610-39748-50206-04089
          +

          The first ptrmap page will contain back pointer information for pages 3 through J+2, inclusive. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-64601-24454-22641-31955-15642-29153-65084-11267
          +

          If X is a memory allocation previously obtained from sqlite3_malloc(), sqlite3_malloc64(), sqlite3_realloc(), or sqlite3_realloc64(), then sqlite3_msize(X) returns the size of that memory allocation in bytes. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-64618-48771-56077-37095-41787-03212-44585-24877
          +

          If the outer query is an aggregate, then the subquery may not contain ORDER BY. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64621-04411-33319-49745-15596-29150-62306-56215
          +

          For the sqlite3_result_text16(), sqlite3_result_text16le(), and sqlite3_result_text16be() routines, and for sqlite3_result_text64() when the encoding is not UTF8, if the input UTF16 begins with a byte-order mark (BOM, U+FEFF) then the BOM is removed from the string and the rest of the string is interpreted according to the byte-order specified by the BOM. +(source: c3ref/result_blob.html, matrix: context, detail)

          + +
          R-64625-44339-60095-18400-35169-15526-52031-11800
          +

          The 6th parameter to the authorizer callback is the name of the inner-most trigger or view that is responsible for the access attempt or NULL if this access attempt is directly from top-level SQL code. +(source: c3ref/c_alter_table.html, checked-by: th3/cov1/auth03.test, matrix: context, detail)

          + +
          R-64629-22390-19344-37404-07828-61811-57666-02667
          +

          Unused database file pages are added to a "freelist" and reused for subsequent inserts. +(source: pragma.html, checked-by: th3/req1/pragma07.test, matrix: context, detail)

          + +
          R-64629-41035-41356-60925-45960-54046-62030-03939
          +

          The sqlite3_trace() callback is invoked with a UTF-8 rendering of the SQL statement text as the statement first begins executing. +(source: c3ref/profile.html, checked-by: th3/cov1/main16.test, matrix: context, detail)

          + +
          R-64634-29359-61184-64182-15828-53059-45249-47923
          +

          Note also that when adding a CHECK constraint, the CHECK constraint is not tested against preexisting rows of the table. +(source: lang_altertable.html, checked-by: th3/req1/altertable01.test, matrix: context, detail)

          + +
          R-64672-26627-33717-56839-41110-28928-46204-47104
          +

          The ON and USING clauses of an inner join are converted into additional terms of the WHERE clause prior to WHERE clause analysis described above in paragraph 2. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64707-05329-18384-25236-31190-36839-36915-56468
          +

          The left-most character of X is number 1. +(source: lang_corefunc.html, checked-by: th3/cov1/func02.test, matrix: context, detail)

          + +
          R-64770-29120-59115-58521-20051-37065-45923-19746
          +

          The rewritten term then might go on to constrain an index using the normal rules for IN operators. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64781-29425-02417-13736-38225-42517-23683-29387
          +

          Some pragmas take effect during the SQL compilation stage, not the execution stage. +(source: pragma.html, checked-by: th3/req1/pragma06.test, matrix: context, detail)

          + +
          R-64797-45496-20081-43950-39002-36712-47915-33301
          +

          The expression may not use subqueries, aggregate functions, window functions, or table-valued functions. +(source: gencol.html, matrix: context, detail)

          + +
          R-64809-29224-33309-48329-38874-47326-32566-40643
          +

          An SQL operation that is interrupted will return SQLITE_INTERRUPT. +(source: c3ref/interrupt.html, matrix: context, detail)

          + +
          R-64812-56077-47875-43117-23188-46780-09721-28568
          +

          If every subterm of an OR clause is separately indexable then the OR clause might be coded such that a separate index is used to evaluate each term of the OR clause. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64813-58505-03479-11903-29047-19194-00816-28075
          +

          The WAL is always located in the same directory as the database file and has the same name as the database file but with the string "-wal" appended. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-64828-59568-61067-60898-36143-56429-01681-45331
          +

          The table has the same number of columns as the rows returned by the SELECT statement. The name of each column is the same as the name of the corresponding column in the result set of the SELECT statement. +(source: lang_createtable.html, checked-by: tcl/e_createtable.test, matrix: context, detail)

          + +
          R-64839-61120-28231-56530-41272-62247-43805-43738
          +

          SQLite may attempt to convert values between the storage classes INTEGER, REAL, and/or TEXT before performing a comparison. +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-64844-34873-54978-44161-37358-50690-61472-16160
          +

          When auto_vacuum is enabled for a database free pages may be reclaimed after deleting data, causing the file to shrink, without rebuilding the entire database using VACUUM. +(source: lang_vacuum.html, checked-by: tcl/e_vacuum.test, matrix: context, detail)

          + +
          R-64852-21591-48845-17571-26387-46542-15231-04527
          +

          The sqlite3_backup object is created by a call to sqlite3_backup_init() and is destroyed by a call to sqlite3_backup_finish(). +(source: c3ref/backup.html, checked-by: src/backup.c, th3/cov1/backup01.test, matrix: context, detail)

          + +
          R-64894-16593-62452-43919-42251-52509-45292-14622
          +

          Thus if the BETWEEN term is not used as an index constraint and instead must be used to test input rows, the expr1 expression is only evaluated once. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64894-50321-17583-62706-45487-44187-46471-34655
          +

          The string "?000" is returned if the argument is NULL or contains no ASCII alphabetic characters. +(source: lang_corefunc.html, checked-by: src/func.c, th3/cov1/func07.test, matrix: context, detail)

          + +
          R-64895-14776-45323-12456-17492-01351-20079-09519
          +

          The truncate optimization can be permanently disabled for all queries by recompiling SQLite with the SQLITE_OMIT_TRUNCATE_OPTIMIZATION compile-time switch. +(source: lang_delete.html, matrix: context, detail)

          + +
          R-64942-06615-59529-33377-22531-50938-02982-04631
          +

          The LIMIT and ORDER BY clauses (described below) are unsupported for DELETE statements within triggers. +(source: lang_delete.html, checked-by: tcl/e_delete.test, matrix: context, detail)

          + +
          R-64951-20071-29590-30713-07634-57943-17719-34762
          +

          If the subquery uses LIMIT, then the outer query may not be DISTINCT. +(source: optoverview.html, matrix: context, detail)

          + +
          R-64962-17428-03573-42931-48456-26794-13581-20203
          +

          Each column in an SQLite 3 database is assigned one of the following type affinities: TEXT NUMERIC INTEGER REAL BLOB +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-64962-58611-23755-17940-51440-03163-56069-63868
          +

          If the authorizer callback returns any value other than SQLITE_IGNORE, SQLITE_OK, or SQLITE_DENY then the sqlite3_prepare_v2() or equivalent call that triggered the authorizer will fail with an error message. +(source: c3ref/set_authorizer.html, checked-by: tcl/auth3.test, th3/cov1/auth01.test, matrix: context, detail)

          + +
          R-64967-62742-25252-37896-34522-17857-15899-52885
          +

          The WAL journaling mode is persistent; after being set it stays in effect across multiple database connections and after closing and reopening the database. +(source: pragma.html, checked-by: th3/req1/pragma24.test, matrix: context, detail)

          + +
          R-64973-09381-20072-06844-08666-32916-49559-16306
          +

          A pragma can take either zero or one argument. +(source: pragma.html, checked-by: th3/req1/pragma01.test, matrix: context, detail)

          + +
          R-65019-08383-37218-08161-37100-03292-58035-06860
          +

          The rank of the column within the table being indexed. +(source: pragma.html, checked-by: tcl/pragma.test, th3/req1/pragma15.test, matrix: context, detail)

          + +
          R-65033-28449-21866-26015-44447-32158-58356-59086
          +

          The built-in BINARY collation compares strings byte by byte using the memcmp() function from the standard C library. +(source: fileformat2.html, checked-by: src/main.c, matrix: context, detail)

          + +
          R-65058-57158-61886-52055-64360-05204-52569-52918
          +

          For example, adding an "ON UPDATE CASCADE" clause to the foreign key as shown below enhances the example schema from section 1 to allow the user to update the artistid (the parent key of the foreign key constraint) column without breaking referential integrity: -- Database schema CREATE TABLE artist( artistid INTEGER PRIMARY KEY, artistname TEXT ); CREATE TABLE track( trackid INTEGER, trackname TEXT, trackartist INTEGER REFERENCES artist(artistid) ON UPDATE CASCADE ); sqlite> SELECT * FROM artist; artistid artistname -------- ----------------- 1 Dean Martin 2 Frank Sinatra sqlite> SELECT * FROM track; trackid trackname trackartist ------- ----------------- ----------- 11 That's Amore 1 12 Christmas Blues 1 13 My Way 2 sqlite> -- Update the artistid column of the artist record for "Dean Martin". sqlite> -- Normally, this would raise a constraint, as it would orphan the two sqlite> -- dependent records in the track table. However, the ON UPDATE CASCADE clause sqlite> -- attached to the foreign key definition causes the update to "cascade" sqlite> -- to the child table, preventing the foreign key constraint violation. sqlite> UPDATE artist SET artistid = 100 WHERE artistname = 'Dean Martin'; sqlite> SELECT * FROM artist; artistid artistname -------- ----------------- 2 Frank Sinatra 100 Dean Martin sqlite> SELECT * FROM track; trackid trackname trackartist ------- ----------------- ----------- 11 That's Amore 100 12 Christmas Blues 100 13 My Way 2 +(source: foreignkeys.html, checked-by: tcl/e_fkey.test, th3/req1/foreignkeys17.test, matrix: context, detail)

          + +
          R-65068-25814-18099-09241-35748-05178-29106-53953
          +

          If the savepoint-name in a RELEASE command does not match any savepoint currently in the transaction stack, then no savepoints are released, the database is unchanged, and the RELEASE command returns an error. +(source: lang_savepoint.html, matrix: context, detail)

          + +
          R-65068-27207-32171-32439-07967-23118-62780-22376
          +

          Otherwise, if the ORDER BY expression is any other expression, it is evaluated and the returned value used to order the output rows. +(source: lang_select.html, checked-by: tcl/e_select.test, matrix: context, detail)

          + +
          R-65080-38137-04546-49301-16311-04630-53630-13035
          +

          The default setting for secure_delete is determined by the SQLITE_SECURE_DELETE compile-time option and is normally off. +(source: pragma.html, checked-by: th3/cov1/pragma20.test, th3/cov1/pragma21.test, matrix: context, detail)

          + +
          R-65084-00602-21133-41951-43387-02500-18887-33247
          +

          sqlite3_shutdown() will invoke sqlite3_os_end(). +(source: c3ref/initialize.html, matrix: context, detail)

          + +
          R-65114-09470-57981-35509-40409-30231-64456-31746
          +

          The sqlite_stat4.sample column holds a BLOB in the record format that encodes the indexed columns followed by the rowid for a rowid table or by the columns of the primary key for a WITHOUT ROWID table. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-65124-17715-29002-58648-01842-29148-18346-40549
          +

          The estimatedCost value is an estimate of the cost of a particular strategy. +(source: c3ref/index_info.html, matrix: context, detail)

          + +
          R-65161-60989-13939-65119-57772-34659-43488-10354
          +

          The WHERE clause may not contain subqueries, references to other tables, non-deterministic functions, or bound parameters. +(source: partialindex.html, checked-by: th3/cov1/index01.test, matrix: context, detail)

          + +
          R-65170-37686-46750-59741-09929-07769-53734-56917
          +

          Each prepared statement maintains various SQLITE_STMTSTATUS counters that measure the number of times it has performed specific operations. +(source: c3ref/stmt_status.html, matrix: context, detail)

          + +
          R-65300-64550-00463-55023-40104-43666-12951-02448
          +

          An operand on a mathematical operator that does not look in any way numeric and is not NULL is converted to 0 or 0.0. +(source: datatype3.html, checked-by: th3/req1/datatype3_06.test, matrix: context, detail)

          + +
          R-65304-57881-32228-09146-30017-59454-39464-18055
          +

          CREATE TABLE t1( a TEXT, -- text affinity b NUMERIC, -- numeric affinity c BLOB, -- no affinity d -- no affinity ); -- Values will be stored as TEXT, INTEGER, TEXT, and INTEGER respectively INSERT INTO t1 VALUES('500', '500', '500', 500); SELECT typeof(a), typeof(b), typeof(c), typeof(d) FROM t1; text|integer|text|integer -- Because column "a" has text affinity, numeric values on the -- right-hand side of the comparisons are converted to text before -- the comparison occurs. SELECT a < 40, a < 60, a < 600 FROM t1; 0|1|1 -- Text affinity is applied to the right-hand operands but since -- they are already TEXT this is a no-op; no conversions occur. SELECT a < '40', a < '60', a < '600' FROM t1; 0|1|1 -- Column "b" has numeric affinity and so numeric affinity is applied -- to the operands on the right. Since the operands are already numeric, -- the application of affinity is a no-op; no conversions occur. All -- values are compared numerically. SELECT b < 40, b < 60, b < 600 FROM t1; 0|0|1 -- Numeric affinity is applied to operands on the right, converting them -- from text to integers. Then a numeric comparison occurs. SELECT b < '40', b < '60', b < '600' FROM t1; 0|0|1 -- No affinity conversions occur. Right-hand side values all have -- storage class INTEGER which are always less than the TEXT values -- on the left. SELECT c < 40, c < 60, c < 600 FROM t1; 0|0|0 -- No affinity conversions occur. Values are compared as TEXT. SELECT c < '40', c < '60', c < '600' FROM t1; 0|1|1 -- No affinity conversions occur. Right-hand side values all have -- storage class INTEGER which compare numerically with the INTEGER -- values on the left. SELECT d < 40, d < 60, d < 600 FROM t1; 0|0|1 -- No affinity conversions occur. INTEGER values on the left are -- always less than TEXT values on the right. SELECT d < '40', d < '60', d < '600' FROM t1; 1|1|1 +(source: datatype3.html, checked-by: th3/req1/datatype3_05.test, matrix: context, detail)

          + +
          R-65312-04917-64079-24281-62446-41326-63748-51040
          +

          If the parameter N to sqlite3_malloc() is zero or negative then sqlite3_malloc() returns a NULL pointer. +(source: c3ref/free.html, checked-by: th3/req1/malloc02.test, matrix: context, detail)

          + +
          R-65343-41028-54070-29515-00373-53952-30391-17078
          +

          SQLite will normally invoke xFetch() with a createFlag of 0 or 1. SQLite will only use a createFlag of 2 after a prior call with a createFlag of 1 failed. +(source: c3ref/pcache_methods2.html, matrix: context, detail)

          + +
          R-65347-63411-45850-56512-24851-44706-34523-61535
          +

          In other words, the WAL can fill up with frames and then be checkpointed and then new frames can overwrite the old ones. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-65366-15139-04842-55947-24968-22096-64628-38309
          +

          The callback is invoked by SQLite after the commit has taken place and the associated write-lock on the database released +(source: c3ref/wal_hook.html, checked-by: tcl/e_walhook.test, matrix: context, detail)

          + +
          R-65380-53022-62704-42379-02430-24457-15703-19233
          +

          If the right-most simple SELECT is a VALUES clause then no LIMIT clause is allowed. +(source: lang_select.html, checked-by: th3/req1/select02.test, matrix: context, detail)

          + +
          R-65388-41786-00092-02077-09568-05356-17956-02801
          +

          The SQLITE_ prefix may be omitted from the option name passed to sqlite3_compileoption_used(). +(source: c3ref/compileoption_get.html, checked-by: th3/cov1/ctime01.test, matrix: context, detail)

          + +
          R-65413-22646-29156-64725-36805-48680-56286-58533
          +

          The expression of a generated column may refer to other generated columns in the same row, but no generated column can depend upon itself, either directly or indirectly. +(source: gencol.html, matrix: context, detail)

          + +
          R-65415-14215-28340-46015-14060-32761-36485-26152
          +

          The xCurrentTimeInt64() method returns, as an integer, the Julian Day Number multiplied by 86400000 (the number of milliseconds in a 24-hour day). +(source: c3ref/vfs.html, checked-by: th3/th3testvfs.c, matrix: context, detail)

          + +
          R-65428-21389-17979-34707-50338-54767-57809-35123
          +

          The return value of the xFileControl method becomes the return value of this routine. +(source: c3ref/file_control.html, matrix: context, detail)

          + +
          R-65438-26258-44776-08221-02933-16071-14773-52455
          +

          This function returns the total number of rows inserted, modified or deleted by all INSERT, UPDATE or DELETE statements completed since the database connection was opened, including those executed as part of trigger programs. +(source: c3ref/total_changes.html, checked-by: tcl/e_totalchanges.test, matrix: context, detail)

          + +
          R-65463-62993-22311-50014-58341-59872-02270-20667
          +

          Any database name qualifier that occurs prior to the name of the object being created is removed. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-65489-09702-43837-30882-04138-20719-06311-14611
          +

          BEFORE is the default when neither keyword is present. +(source: lang_createtrigger.html, matrix: context, detail)

          + +
          R-65499-53765-60887-64265-16155-35530-39670-45020
          +

          On the other hand, passive mode might leave the checkpoint unfinished if there are concurrent readers or writers. +(source: c3ref/wal_checkpoint_v2.html, checked-by: tcl/e_walckpt.test, th3/req1/checkpoint01.test, matrix: context, detail)

          + +
          R-65507-55649-05448-07822-60967-65270-42964-52514
          +

          The sqlite_stat1 is an internal table created by the ANALYZE command and used to hold supplemental information about tables and indexes that the query planner can use to help it find better ways of performing queries. +(source: fileformat2.html, matrix: context, detail)

          + +
          R-65524-61849-43329-61953-54493-09890-31645-08912
          +

          If an application-defined SQL function named "regexp" is added at run-time, then the "X REGEXP Y" operator will be implemented as a call to "regexp(Y,X)". +(source: lang_expr.html, checked-by: tcl/e_expr.test, matrix: context, detail)

          +
          -

          This page last modified on 2022-01-08 05:02:57 UTC

          diff -Nru sqlite3-3.42.0/www/rescode.html sqlite3-3.44.0-0/www/rescode.html --- sqlite3-3.42.0/www/rescode.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/rescode.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
          @@ -222,9 +198,9 @@

          4. Primary Result Code List

          -

          The 31 result codes are +

          The 31 result codes are defined in sqlite3.h and are listed in - alphabetical order below: + alphabetical order below:

          • SQLITE_ABORT (4)
          • @@ -263,13 +239,12 @@

            5. Extended Result Code List

            -

            The 74 extended result codes +

            The 71 extended result codes are defined in sqlite3.h and are listed in alphabetical order below:

            Rowid Tables

            @@ -188,5 +164,4 @@ Unfortunately, life is messy. The designer of SQLite offers his sincere apology for the current mess.
          -

          This page last modified on 2022-01-08 05:02:57 UTC

          diff -Nru sqlite3-3.42.0/www/rowvalue.html sqlite3-3.44.0-0/www/rowvalue.html --- sqlite3-3.42.0/www/rowvalue.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/rowvalue.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
          @@ -128,8 +104,7 @@ - - -

          2.2. Row Value IN Operators

          -

          For a row-value IN operator, the left-hand side (hereafter "LHS") can be either a parenthesized list of values or a subquery with multiple columns. But the right-hand side (hereafter "RHS") must be a subquery expression. @@ -245,7 +216,7 @@ (1,3,5) IN (SELECT * FROM t2); -- NULL

          -

          2.3. Row Values In UPDATE Statements

          +

          2.2. Row Values In UPDATE Statements

          Row values can also be used in the SET clause of an UPDATE statement. The LHS must be a list of column names. The RHS can be any row value. @@ -445,5 +416,4 @@

          Row values were added to SQLite version 3.15.0 (2016-10-14). Attempts to use row values in prior versions of SQLite will generate syntax errors. -

          This page last modified on 2022-04-18 02:55:50 UTC

          - +

          diff -Nru sqlite3-3.42.0/www/rtree.html sqlite3-3.44.0-0/www/rtree.html --- sqlite3-3.42.0/www/rtree.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/rtree.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
          @@ -184,8 +160,8 @@

          -The R-Tree concept originated with -Toni Guttman: +The R-Tree concept originated with +Toni Guttman: R-Trees: A Dynamic Index Structure for Spatial Searching, Proc. 1984 ACM SIGMOD International Conference on Management of Data, pp. 47-57. @@ -200,10 +176,8 @@

          The source code to the SQLite R*Tree module is included as part -of the amalgamation. However, depending on configuration options -and the particular version of SQLite you are using, it may or may not -be enabled by default. To ensure that the R*Tree module is enabled, -simply compile with the SQLITE_ENABLE_RTREE +of the amalgamation but is disabled by default. To enable the +R*Tree module, simply compile with the SQLITE_ENABLE_RTREE C-preprocessor macro defined. With many compilers, this is accomplished by adding the option "-DSQLITE_ENABLE_RTREE=1" to the compiler command-line. @@ -218,7 +192,7 @@ The first column is always a 64-bit signed integer primary key. The other columns are pairs, one pair per dimension, containing the minimum and maximum values for that dimension, respectively. -A 1-dimensional R*Tree thus has 3 columns. +A 1-dimensional R*Tree thus has 3 columns. A 2-dimensional R*Tree has 5 columns. A 3-dimensional R*Tree has 7 columns. A 4-dimensional R*Tree has 9 columns. @@ -227,7 +201,7 @@

          -The first column of an SQLite R*Tree is similar to an integer primary +The first column of an SQLite R*Tree is similar to an integer primary key column of a normal SQLite table. It may only store a 64-bit signed integer value. Inserting a NULL value into this column causes SQLite to automatically generate a new unique primary key value. If an attempt @@ -238,7 +212,7 @@ The min/max-value pair columns are stored as 32-bit floating point values for "rtree" virtual tables or as 32-bit signed integers in "rtree_i32" virtual tables. Unlike regular SQLite tables which can store data in a variety of -datatypes and formats, the R*Tree rigidly enforce these storage types. +datatypes and formats, the R*Tree rigidly enforce these storage types. If any other type of value is inserted into such a column, the r-tree module silently converts it to the required type before writing the new record to the database. @@ -265,19 +239,18 @@ <name>_parent

          -

          -The shadow tables are ordinary SQLite data tables. You can query them +The shadow tables are ordinary SQLite data tables. You can query them directly if you like, though this unlikely to reveal anything particularly -useful. -And you can UPDATE, DELETE, INSERT or even DROP +useful. +And you can UPDATE, DELETE, INSERT or even DROP the shadow tables, though doing so will corrupt your R*Tree index. So it is best to simply ignore the shadow tables. Recognize that they hold your R*Tree index information and let it go as that.

          -As an example, consider creating a two-dimensional R*Tree index for use in +As an example, consider creating a two-dimensional R*Tree index for use in spatial queries:

          @@ -288,7 +261,6 @@ );
          -

          3.1.1. Column naming details

          @@ -301,8 +273,7 @@ the behavior of the rtree. In an RTREE virtual table, the first column always has a type affinity of INTEGER and all other data columns have a -type affinity of REAL. -In an RTREE_I32 virtual table, all columns have type affinity of INTEGER. +type affinity of NUMERIC.

          Recommended practice is to omit any extra tokens in the rtree specification. @@ -317,79 +288,68 @@ R*Tree index, we can do something like this:

          -
          INSERT INTO demo_index VALUES
          -  (28215, -80.781227, -80.604706, 35.208813, 35.297367),
          -  (28216, -80.957283, -80.840599, 35.235920, 35.367825),
          -  (28217, -80.960869, -80.869431, 35.133682, 35.208233),
          -  (28226, -80.878983, -80.778275, 35.060287, 35.154446),
          -  (28227, -80.745544, -80.555382, 35.130215, 35.236916),
          -  (28244, -80.844208, -80.841988, 35.223728, 35.225471),
          -  (28262, -80.809074, -80.682938, 35.276207, 35.377747),
          -  (28269, -80.851471, -80.735718, 35.272560, 35.407925),
          -  (28270, -80.794983, -80.728966, 35.059872, 35.161823),
          -  (28273, -80.994766, -80.875259, 35.074734, 35.172836),
          -  (28277, -80.876793, -80.767586, 35.001709, 35.101063),
          -  (28278, -81.058029, -80.956375, 35.044701, 35.223812),
          -  (28280, -80.844208, -80.841972, 35.225468, 35.227203),
          -  (28282, -80.846382, -80.844193, 35.223972, 35.225655);
          +
          INSERT INTO demo_index VALUES(
          +    1,                   -- Primary key -- SQLite.org headquarters
          +    -80.7749, -80.7747,  -- Longitude range
          +    35.3776, 35.3778     -- Latitude range
          +);
          +INSERT INTO demo_index VALUES(
          +    2,                   -- NC 12th Congressional District in 2010
          +    -81.0, -79.6,
          +    35.0, 36.2
          +);
           
          -

          -The entries above are bounding boxes (longitude and latitude) for 14 -zipcodes near Charlotte, NC. A real database would have many thousands, -millions, or billions of such entries, but this small 14-row sample will -be sufficient to illustrate the ideas. +The entries above might represent (for example) a bounding box around +the main office for SQLite.org and bounding box around the +12th Congressional District of North Carolina (prior to the 2011 +redistricting) in which SQLite.org was located.

          3.3. Querying An R*Tree Index

          -Any valid query will work against an R*Tree index. The R*Tree -implementation just makes some kinds of queries especially -efficient. Queries against the primary key are efficient: +Any valid query will work against an R*Tree index. But the R*Tree +implementation is designed to make two kinds of queries especially +efficient. First, queries against the primary key are efficient:

          -
          SELECT * FROM demo_index WHERE id=28269;
          +
          SELECT * FROM demo_index WHERE id=1;
           
          -

          Of course, an ordinary SQLite table will also do a query against its -integer primary key efficiently, so the previous is not important. -The big reason for using an R*Tree is so that -you can efficiently do range queries against the coordinate -ranges. For example, the main office of the SQLite project is -located at 35.37785, -80.77470. -To find which zipcodes might service that office, one could right: +integer primary key efficiently, so the previous is no big deal. +The real reason for using an R*Tree is so that +you can efficiently do inequality queries against the coordinate +ranges. To find all elements of the index that are contained within +the vicinity of Charlotte, North Carolina, one might do:

          SELECT id FROM demo_index
          - WHERE minX<=-80.77470 AND maxX>=-80.77470
          -   AND minY<=35.37785  AND maxY>=35.37785;
          + WHERE minX>=-81.08 AND maxX<=-80.58
          +   AND minY>=35.00  AND maxY<=35.44;
           
          -

          -The query above will quickly locate all zipcodes that contain -the SQLite main office in their bounding box, even if the -R*Tree contains many entries. The previous is an example +The query above would very quickly locate the id of 1 even if the +R*Tree contained millions of entries. The previous is an example of a "contained-within" query. The R*Tree also supports "overlapping" -queries. For example, to find all zipcode bounding boxes that overlap -with the 28269 zipcode: +queries. For example, to find all bounding boxes that overlap the +Charlotte area:

          -
          SELECT A.id FROM demo_index AS A, demo_index AS B
          - WHERE A.maxX>=B.minX AND A.minX<=B.maxX
          -   AND A.maxY>=B.minY AND A.minY<=B.maxY
          -   AND B.id=28269;
          +
          SELECT id FROM demo_index
          + WHERE maxX>=-81.08 AND minX<=-80.58
          +   AND maxY>=35.00  AND minY<=35.44;
           
          -

          -This second query will find both 28269 entry (since every bounding box -overlaps with itself) and also other zipcode that is close enough to -28269 that their bounding boxes overlap. +This second query would find both entry 1 (the SQLite.org office) which +is entirely contained within the query box and also +the 12th Congressional District which extends well outside the +query box but still overlaps the query box.

          @@ -403,7 +363,6 @@ WHERE maxY>=35.0 AND minY<=35.0;

          -

          But, generally speaking, the more constraints that the R*Tree module has to work with, and the smaller the bounding box, the faster the @@ -423,7 +382,7 @@ a query bounding box. Rounding the entry bounding boxes outward might cause a few extra entries to appears in an overlapping query if the edge of the entry bounding box corresponds to an edge of the query bounding box. But -the overlapping query will never miss a valid table entry. +the overlapping query will never miss a valid table entry.

          However, for a "contained-within" style query, rounding the bounding boxes outward might cause some entries to be excluded from the result set @@ -452,7 +411,7 @@

          -Then for each "id" value returned, suppose the application creates an +Then for each "id" value returned, suppose the application creates an UPDATE statement like the following and binds the "id" value returned against the "?1" parameter: @@ -466,6 +425,18 @@ be tolerated as this would disrupt the scan.

          +It is also possible to express this kind of simultaneous read and write +on an R-Tree within a single query, for example if an UPDATE statement +tries to change the value of one row of the R-Tree based on a complicated +query from another row of the same R-Tree, perhaps something like this: + +

          UPDATE demo_index 
          +   SET maxY = (SELECT max(maxX) FROM demo_index AS x2
          +                WHERE x2.maxY>demo_index.x2)
          + WHERE maxY>=35.0  AND minY<=35.0;
          +
          + +

          This is a limitation of the R-Tree extension only. Ordinary tables in SQLite are able to read and write at the same time. Other virtual tables might (or might not) also that capability. And R-Tree can appear to read @@ -519,44 +490,46 @@

          Suppose the demo_data.boundary field holds some proprietary data description -of a complex two-dimensional boundary for a zipcode and suppose that the +of a complex two-dimensional boundary for an object and suppose that the application has used the sqlite3_create_function() interface to -created an application-defined function "contained_in(boundary,lat,long)" -that accepts the demo_data.boundary object and a latitute and longitude -and returns return true or false if the lat/long is contained within -the boundary. -One may assume that "contained_in()" is a relatively slow +created application-defined functions "contained_in" and +"overlaps" accepting two demo_data.boundary objects and return true or false. +One may assume that "contained_in" and "overlaps" are relatively slow functions that we do not want to invoke too frequently. -Then an efficient way to find the specific ZIP code for the main -SQLite office would be to run a query like this: +Then an efficient way to find the name of all objects located within +the North Carolina 12th District, one may be to run a query like this:

          SELECT objname FROM demo_data, demo_index
            WHERE demo_data.id=demo_index.id
          -   AND contained_in(demo_data.boundary, 35.37785, -80.77470)
          -   AND minX<=-80.77470 AND maxX>=-80.77470
          -   AND minY<=35.37785  AND maxY>=35.37785;
          +   AND contained_in(demo_data.boundary, :boundary)
          +   AND minX>=-81.0 AND maxX<=-79.6
          +   AND minY>=35.0 AND maxY<=36.2;
           
          +

          In the query above, one would presumably bind the binary BLOB +description of the precise boundary of the 12th district to the +":boundary" parameter.

          +

          Notice how the query above works: The R*Tree index runs in the outer -loop to find entries that contain the SQLite main office in their -boundary box. -For each row found, SQLite looks up +loop to find entries that are contained within the bounding box +of longitude -81..-79.6 and latitude 35.0..36.2. +For each object identifier found, SQLite looks up the corresponding entry in the demo_data table. It then uses the boundary field from the demo_data table as a parameter to the contained_in() -function and if that function returns true, then we know the sought after -coordinate is in that ZIP code boundary.

          +function and if that function returns true, the objname field from +the demo_data table is returned as the next row of query result.

          One would get the same answer without the use of the R*Tree index using the following simpler query:

          SELECT objname FROM demo_data
          - WHERE contained_in(demo_data.boundary, 35.37785, -80.77470);
          + WHERE contained_in(demo_data.boundary, :boundary);
           

          The problem with this latter query is that it must apply the -contained_in() function to all entries in the demo_data table. +contained_in() function to millions of entries in the demo_data table. The use of the R*Tree in the penultimate query reduces the number of calls to contained_in() function to a small subset of the entire table. The R*Tree index did not find the exact answer itself, it merely @@ -575,9 +548,7 @@

          Auxiliary columns are marked with a "+" symbol before the column name. Auxiliary columns must come after all of the coordinate boundary columns. -An RTREE table can have no more than 100 columns total. In other words, -the count of columns including the integer primary key column, -the coordinate boundary columns, and all auxiliary columns must be 100 or less. +There is a limit of no more than 100 auxiliary columns. The following example shows an r-tree table with auxiliary columns that is equivalent to the two tables "demo_index" and "demo_data" above: @@ -600,9 +571,9 @@ be written as a simple query, like this:

          SELECT objname FROM demo_index2
          - WHERE contained_in(boundary, 35.37785, -80.77470)
          -   AND minX<=-80.77470 AND maxX>=-80.77470
          -   AND minY<=35.37785  AND maxY>=35.37785;
          + WHERE contained_in(boundary, :boundary)
          +   AND minX>=-81.0 AND maxX<=-79.6
          +   AND minY>=35.0 AND maxY>=36.2;
           

          4.1.1. Limitations

          @@ -621,7 +592,7 @@

          5. Integer-Valued R-Trees

          -The default virtual table ("rtree") stores coordinates as +The default virtual table ("rtree") normally stores coordinates as single-precision (4-byte) floating point numbers. If integer coordinates are desired, declare the table using "rtree_i32" instead: @@ -629,23 +600,21 @@

          -An rtree_i32 stores coordinates as 32-bit signed integers. -Even though it stores values using integer, the rtree_i32 virtual -table still uses floating point computations internally as part of -the r-tree algorithm. +An rtree_i32 stores coordinates as 32-bit signed integers. But it still +using floating point computations internally as part of the r-tree algorithm.

          6. Custom R-Tree Queries

          By using standard SQL expressions in the WHERE clause of a SELECT query, -a programmer can query for all R*Tree entries that +a programmer can query for all R*Tree entries that intersect with or are contained within a particular bounding-box. Custom R*Tree queries, using the MATCH -operator in the WHERE clause of a SELECT, allow the programmer to query for -the set of R*Tree entries that intersect any arbitrary region or shape, not -just a box. This capability is useful, for example, in computing the -subset of objects in the R*Tree that are visible from a camera positioned +operator in the WHERE clause of a SELECT, allow the programmer to query for +the set of R*Tree entries that intersect any arbitrary region or shape, not +just a box. This capability is useful, for example, in computing the +subset of objects in the R*Tree that are visible from a camera positioned in 3-D space.

          Regions for custom R*Tree queries are defined by R*Tree geometry callbacks @@ -675,7 +644,7 @@

          A call to one of the above APIs creates a new SQL function named by the second parameter (zQueryFunc or zGeom). When that SQL function appears on the right-hand side of the MATCH operator and the left-hand side of the -MATCH operator is any column in the R*Tree virtual table, then the callback +MATCH operator is any column in the R*Tree virtual table, then the callback defined by the third argument (xQueryFunc or xGeom) is invoked to determine if a particular object or subtree overlaps the desired region. @@ -700,7 +669,7 @@ for any given R*Tree. The number of coordinates is 2 for a 1-dimensional R*Tree, 4 for a 2-dimensional R*Tree, 6 for a 3-dimensional R*Tree, and so forth. The third argument, aCoord[], is an array of nCoord coordinates that defines -a bounding box to be tested. The last argument is a pointer into which +a bounding box to be tested. The last argument is a pointer into which the callback result should be written. The result is zero if the bounding-box defined by aCoord[] is completely outside the region defined by the xGeom callback and the result is non-zero if @@ -781,7 +750,7 @@

          The first five fields of the sqlite3_rtree_query_info structure are identical to the sqlite3_rtree_geometry structure, and have exactly the same meaning. -The sqlite3_rtree_query_info structure also contains nCoord and aCoord fields +The sqlite3_rtree_query_info structure also contains nCoord and aCoord fields which have the same meaning as the parameter of the same name in the xGeom callback.

          The xQueryFunc must set the eWithin field of sqlite3_rtree_query_info to @@ -805,15 +774,13 @@ The query proceeds by extracting the entry from the priority queue that has the lowest score. If that entry is a leaf (meaning that it is an actual R*Tree entry and not a subtree) then that entry -is returned as one row of the query result. +is returned as one row of the query result. If the extracted priority queue entry is a node (a subtree), -then the next child of that node is passed to the xQueryFunc callback. -If the node has more children then it is returned to the priority queue. -Otherwise it is discarded. Those subelements for which the xQueryFunc -callback sets eWithin to PARTLY_WITHIN or FULLY_WITHIN are added to the -priority queue using the score supplied by the callback. Subelements that -return NOT_WITHIN are discarded. The query runs until the priority queue is -empty. +then sub-subtrees or leaves contained within that entry are passed to the +xQueryFunc callback, one by one. Those subelements for which the xQueryFunc +callback sets eWithin to PARTLY_WITHIN or FULLY_WITHIN are added to the priority +queue using the score supplied by the callback. Subelements that return +NOT_WITHIN are discarded. The query runs until the priority queue is empty.

          Every leaf entry and node (subtree) within the R*Tree has an integer "level". The leaves have a level of 0. The first containing subtree of the leaves has @@ -850,7 +817,7 @@ The MATCH operator of a custom R*Tree query function must be a top-level AND-connected term of the WHERE clause, or else it will not be usable by the R*Tree query optimizer and the query will not be runnable. -If the MATCH operator is connected to other terms of the WHERE clause +If the MATCH operator is connected to other terms of the WHERE clause via an OR operator, for example, the query will fail with an error.

          @@ -874,9 +841,9 @@ SQLite tables with names derived from the name of the R*Tree. These three tables are called "shadow tables". This is their schema: -

          CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data)
          -CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode)
          -CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno)
          +

          CREATE TABLE %_node(nodeno INTEGER PRIMARY KEY, data BLOB)
          +CREATE TABLE %_parent(nodeno INTEGER PRIMARY KEY, parentnode INTEGER)
          +CREATE TABLE %_rowid(rowid INTEGER PRIMARY KEY, nodeno INTEGER)
           

          The "%" in the name of each shadow table is replaced by the name of the @@ -890,11 +857,6 @@ Each entry in an R*Tree has a rowid. The %_rowid shadow table maps entry rowids to the node that contains that entry. -

          Extra columns appended to the %_rowid table hold the -content of auxiliary columns. The names of these extra -%_rowid columns are probably not the same as the -actual auxiliary column names. -

          7.2. Integrity Check using the rtreecheck() SQL function

          @@ -921,10 +883,10 @@
        15. for each dimension, (coord1 <= coord2).

        16. unless the cell is on the root node, that the cell is bounded by the parent cell on the parent node. -

        17. for leaf nodes, that there is an entry in the %_rowid - table corresponding to the cell's rowid value that +

        18. for leaf nodes, that there is an entry in the %_rowid + table corresponding to the cell's rowid value that points to the correct node. -

        19. for cells on non-leaf nodes, that there is an entry in the +

        20. for cells on non-leaf nodes, that there is an entry in the %_parent table mapping from the cell's child node to the node that it resides on.

        @@ -934,9 +896,8 @@ is a leaf cell that corresponds to each entry in the %_rowid table.

      3. That there are the same number of entries in the %_parent table -as there are non-leaf cells in the r-tree structure, and that -there is a non-leaf cell that corresponds to each entry in the +as there are non-leaf cells in the r-tree structure, and that +there is a non-leaf cell that corresponds to each entry in the %_parent table.

      -

      This page last modified on 2023-02-20 00:00:42 UTC

      diff -Nru sqlite3-3.42.0/www/schematab.html sqlite3-3.44.0-0/www/schematab.html --- sqlite3-3.42.0/www/schematab.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/schematab.html 2023-11-04 14:24:19.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      +
      } } diff -Nru sqlite3-3.42.0/www/search.d/admin sqlite3-3.44.0-0/www/search.d/admin --- sqlite3-3.42.0/www/search.d/admin 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/search.d/admin 2023-11-04 14:24:19.000000000 +0000 @@ -1106,32 +1106,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      } } Binary files /tmp/tmpzdm9j_aj/x_36KoQHlP/sqlite3-3.42.0/www/search.d/search.db and /tmp/tmpzdm9j_aj/4OSJ1hZg2o/sqlite3-3.44.0-0/www/search.d/search.db differ diff -Nru sqlite3-3.42.0/www/security.html sqlite3-3.44.0-0/www/security.html --- sqlite3-3.42.0/www/security.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/security.html 2023-11-04 14:24:20.000000000 +0000 @@ -3,7 +3,7 @@ -Defense Against The Dark Arts +Defense Against Dark Arts @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      -Defense Against The Dark Arts +Defense Against Dark Arts
      @@ -213,12 +189,6 @@ to the maximum observed instantaneous memory usage plus some margin.

    4. -Consider setting the SQLITE_MAX_ALLOCATION_SIZE compile-time option -to something smaller than its default value of 2147483391 (0x7ffffeff). -A value of 100000000 (100 million) or even smaller would not be unreasonable, -depending on the application. - -

    5. For embedded systems, consider compiling SQLite with the -DSQLITE_ENABLE_MEMSYS5 option and then providing SQLite with a fixed chunk of memory to use as its heap via the @@ -252,8 +222,6 @@

    - -

    1.2. Untrusted SQLite Database Files

    Applications that read or write SQLite database files of uncertain @@ -326,5 +294,4 @@ However, they do provide an extra layer of defense against zero-day exploits and are encouraged for applications that pass data from untrusted sources into SQLite. -

    This page last modified on 2022-11-07 14:28:05 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/selfcontained.html sqlite3-3.44.0-0/www/selfcontained.html --- sqlite3-3.42.0/www/selfcontained.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/selfcontained.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -155,7 +131,7 @@
  • realloc()
  • free()
  • -

    But those routines are optional and can be omitted +

    But those routines are optional can can be omitted using a compile-time option.

    @@ -165,5 +141,4 @@ so forth. All of these interfaces are readily available on most platforms, and custom VFSes can be designed to run SQLite on even the most austere embedded devices. -

    This page last modified on 2022-08-10 18:45:48 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/series.html sqlite3-3.44.0-0/www/series.html --- sqlite3-3.42.0/www/series.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/series.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -151,32 +127,21 @@

    1. Overview

    -

    The generate_series(START,STOP,STEP) table-valued function is a +

    The generate_series(START,END,STEP) table-valued function is a loadable extension included in the SQLite source tree, and compiled into -the command-line shell. The generate_series() table has one visible +the command-line shell. The generate_series() table has a single result column named "value" holding integer values and a number of rows determined by the -parameters START, STOP, and STEP. The first row of the table has -a value of START. Subsequent rows increment by STEP to a value -not exceeding STOP. - -

    The generate_series() table has additional, hidden columns -named "start", "stop", and "step" whose values are the effective -values of START, STOP and STEP as provided or defaulted. -It also has a rowid, accessible by its usual names. +parameters START, END, and STEP. The first row of the table has +a value of START. Subsequent rows increase by STEP up to END.

    Omitted parameters take on default values. STEP defaults to 1. -STOP defaults to 4294967295. The START parameter is required -as of version 3.37.0 (2021-11-27) and later and an error will -be raised if START is omitted or has a self-referential or otherwise -uncomputable value. Older versions used a default of 0 for START. -The legacy behavior can be obtained from recent code by compiling -with -DZERO_ARGUMENT_GENERATE_SERIES. +END defaults to 9223372036854775807. START defaults to 0.

    1.1. Equivalent Recursive Common Table Expression

    -

    The generate_series table can be simulated for positive step values -using a recursive common table expression. If the three parameters +

    The generate_series table can be simulated using a +recursive common table expression. If the three parameters are $start, $end, and $step, then the equivalent common table expression is: @@ -201,7 +166,7 @@

    Generate the 20 random integer values: -

    SELECT random() FROM generate_series(1,20);
    +

    SELECT random() FROM generate_series LIMIT 20;
     

    Find the name of every customer whose account number @@ -215,5 +180,4 @@ WHERE id IN (SELECT value FROM generate_series(10000,20000,200));

    -

    This page last modified on 2023-05-01 21:49:55 UTC

    diff -Nru sqlite3-3.42.0/www/serverless.html sqlite3-3.44.0-0/www/serverless.html --- sqlite3-3.42.0/www/serverless.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/serverless.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -220,5 +196,4 @@ When a database claims to be "serverless", be sure to discern whether they mean "classic serverless" or "neo-serverless". -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/session/c_changeset_abort.html sqlite3-3.44.0-0/www/session/c_changeset_abort.html --- sqlite3-3.42.0/www/session/c_changeset_abort.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/c_changeset_abort.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Constants Returned By The Conflict Handler

    #define SQLITE_CHANGESET_OMIT       0
    +
    +

    Session Module C Interface

    Constants Returned By The Conflict Handler

    #define SQLITE_CHANGESET_OMIT       0
     #define SQLITE_CHANGESET_REPLACE    1
     #define SQLITE_CHANGESET_ABORT      2
     

    @@ -147,7 +123,6 @@ and the call to sqlite3changeset_apply() returns SQLITE_ABORT.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/c_changesetapply_ignorenoop.html sqlite3-3.44.0-0/www/session/c_changesetapply_ignorenoop.html --- sqlite3-3.42.0/www/session/c_changesetapply_ignorenoop.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/c_changesetapply_ignorenoop.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,156 +0,0 @@ - - - - - -Flags for sqlite3changeset_apply_v2 - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -

    Session Module C Interface

    Flags for sqlite3changeset_apply_v2

    #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
    -#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
    -#define SQLITE_CHANGESETAPPLY_IGNORENOOP    0x0004
    -

    -The following flags may passed via the 9th parameter to -sqlite3changeset_apply_v2 and sqlite3changeset_apply_v2_strm:

    - -

    -
    SQLITE_CHANGESETAPPLY_NOSAVEPOINT
    - Usually, the sessions module encloses all operations performed by - a single call to apply_v2() or apply_v2_strm() in a SAVEPOINT. The - SAVEPOINT is committed if the changeset or patchset is successfully - applied, or rolled back if an error occurs. Specifying this flag - causes the sessions module to omit this savepoint. In this case, if the - caller has an open transaction or savepoint when apply_v2() is called, - it may revert the partially applied changeset by rolling it back.

    - -

    SQLITE_CHANGESETAPPLY_INVERT
    - Invert the changeset before applying it. This is equivalent to inverting - a changeset using sqlite3changeset_invert() before applying it. It is - an error to specify this flag with a patchset.

    - -

    SQLITE_CHANGESETAPPLY_IGNORENOOP
    - Do not invoke the conflict handler callback for any changes that - would not actually modify the database even if they were applied. - Specifically, this means that the conflict handler is not invoked - for: -
      -
    • a delete change if the row being deleted cannot be found, -
    • an update change if the modified fields are already set to - their new values in the conflicting row, or -
    • an insert change if all fields of the conflicting row match - the row being inserted. -
    -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/session/c_changesetapply_invert.html sqlite3-3.44.0-0/www/session/c_changesetapply_invert.html --- sqlite3-3.42.0/www/session/c_changesetapply_invert.html 1970-01-01 00:00:00.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/c_changesetapply_invert.html 2023-11-04 14:24:20.000000000 +0000 @@ -0,0 +1,117 @@ + + + + + +Flags for sqlite3changeset_apply_v2 + + + +
    + + + +
    +
    +Small. Fast. Reliable.
    Choose any three. +
    + + +
    +
    + + + +
    +
    +
    + +
    +

    Session Module C Interface

    Flags for sqlite3changeset_apply_v2

    #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
    +#define SQLITE_CHANGESETAPPLY_INVERT        0x0002
    +

    +The following flags may passed via the 9th parameter to +sqlite3changeset_apply_v2 and sqlite3changeset_apply_v2_strm:

    + +

    +
    SQLITE_CHANGESETAPPLY_NOSAVEPOINT
    + Usually, the sessions module encloses all operations performed by + a single call to apply_v2() or apply_v2_strm() in a SAVEPOINT. The + SAVEPOINT is committed if the changeset or patchset is successfully + applied, or rolled back if an error occurs. Specifying this flag + causes the sessions module to omit this savepoint. In this case, if the + caller has an open transaction or savepoint when apply_v2() is called, + it may revert the partially applied changeset by rolling it back.

    + +

    SQLITE_CHANGESETAPPLY_INVERT
    + Invert the changeset before applying it. This is equivalent to inverting + a changeset using sqlite3changeset_invert() before applying it. It is + an error to specify this flag with a patchset. +

    See also lists of + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/c_changeset_conflict.html sqlite3-3.44.0-0/www/session/c_changeset_conflict.html --- sqlite3-3.42.0/www/session/c_changeset_conflict.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/c_changeset_conflict.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Constants Passed To The Conflict Handler

    #define SQLITE_CHANGESET_DATA        1
    +
    +

    Session Module C Interface

    Constants Passed To The Conflict Handler

    #define SQLITE_CHANGESET_DATA        1
     #define SQLITE_CHANGESET_NOTFOUND    2
     #define SQLITE_CHANGESET_CONFLICT    3
     #define SQLITE_CHANGESET_CONSTRAINT  4
    @@ -173,7 +149,6 @@
     
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/c_changesetstart_invert.html sqlite3-3.44.0-0/www/session/c_changesetstart_invert.html --- sqlite3-3.42.0/www/session/c_changesetstart_invert.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/c_changesetstart_invert.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Flags for sqlite3changeset_start_v2

    #define SQLITE_CHANGESETSTART_INVERT        0x0002
    +
    +

    Session Module C Interface

    Flags for sqlite3changeset_start_v2

    #define SQLITE_CHANGESETSTART_INVERT        0x0002
     

    The following flags may passed via the 4th parameter to sqlite3changeset_start_v2 and sqlite3changeset_start_v2_strm:

    @@ -125,7 +101,6 @@ inverting a changeset using sqlite3changeset_invert() before applying it. It is an error to specify this flag with a patchset.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/changegroup.html sqlite3-3.44.0-0/www/session/changegroup.html --- sqlite3-3.42.0/www/session/changegroup.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/changegroup.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Changegroup Handle

    typedef struct sqlite3_changegroup sqlite3_changegroup;
    +
    +

    Session Module C Interface

    Changegroup Handle

    typedef struct sqlite3_changegroup sqlite3_changegroup;
     

    A changegroup is an object used to combine two or more changesets or patchsets @@ -125,7 +101,6 @@ sqlite3changegroup_add(), sqlite3changegroup_output()

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/changeset_iter.html sqlite3-3.44.0-0/www/session/changeset_iter.html --- sqlite3-3.42.0/www/session/changeset_iter.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/changeset_iter.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Changeset Iterator Handle

    typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
    +
    +

    Session Module C Interface

    Changeset Iterator Handle

    typedef struct sqlite3_changeset_iter sqlite3_changeset_iter;
     

    An instance of this object acts as a cursor for iterating over the elements of a changeset or patchset. @@ -136,7 +112,6 @@

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/constlist.html sqlite3-3.44.0-0/www/session/constlist.html --- sqlite3-3.42.0/www/session/constlist.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/constlist.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,40 +89,15 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    + +

    Session Module C Interface

    Constants:

    Other lists: -Objects and -Functions.

    - +Objects and +Functions.

    diff -Nru sqlite3-3.42.0/www/session/c_session_config_strmsize.html sqlite3-3.44.0-0/www/session/c_session_config_strmsize.html --- sqlite3-3.42.0/www/session/c_session_config_strmsize.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/c_session_config_strmsize.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,35 +89,10 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Values for sqlite3session_config().

    #define SQLITE_SESSION_CONFIG_STRMSIZE 1
    +
    +

    Session Module C Interface

    Values for sqlite3session_config().

    #define SQLITE_SESSION_CONFIG_STRMSIZE 1
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/c_session_objconfig_rowid.html sqlite3-3.44.0-0/www/session/c_session_objconfig_rowid.html --- sqlite3-3.42.0/www/session/c_session_objconfig_rowid.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/c_session_objconfig_rowid.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ - - - - - -Options for sqlite3session_object_config - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -

    Session Module C Interface

    Options for sqlite3session_object_config

    #define SQLITE_SESSION_OBJCONFIG_SIZE  1
    -#define SQLITE_SESSION_OBJCONFIG_ROWID 2
    -

    -The following values may passed as the the 2nd parameter to -sqlite3session_object_config().

    - -

    SQLITE_SESSION_OBJCONFIG_SIZE
    - This option is used to set, clear or query the flag that enables - the sqlite3session_changeset_size() API. Because it imposes some - computational overhead, this API is disabled by default. Argument - pArg must point to a value of type (int). If the value is initially - 0, then the sqlite3session_changeset_size() API is disabled. If it - is greater than 0, then the same API is enabled. Or, if the initial - value is less than zero, no change is made. In all cases the (int) - variable is set to 1 if the sqlite3session_changeset_size() API is - enabled following the current call, or 0 otherwise.

    - -

    It is an error (SQLITE_MISUSE) to attempt to modify this setting after - the first table has been attached to the session object.

    - -

    SQLITE_SESSION_OBJCONFIG_ROWID
    - This option is used to set, clear or query the flag that enables - collection of data for tables with no explicit PRIMARY KEY.

    - -

    Normally, tables with no explicit PRIMARY KEY are simply ignored - by the sessions module. However, if this flag is set, it behaves - as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted - as their leftmost columns.

    - -

    It is an error (SQLITE_MISUSE) to attempt to modify this setting after - the first table has been attached to the session object. -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/session/funclist.html sqlite3-3.44.0-0/www/session/funclist.html --- sqlite3-3.42.0/www/session/funclist.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/funclist.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    + +

    Session Module C Interface

    Functions:

    Other lists: -Constants and -Objects.

    - +Constants and +Objects.

    diff -Nru sqlite3-3.42.0/www/session/intro.html sqlite3-3.44.0-0/www/session/intro.html --- sqlite3-3.42.0/www/session/intro.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/intro.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + -

    These pages define the C-language interface for the SQLite +

    These pages define the C-language interface for the SQLite session extension. This is not a tutorial. These pages are designed to be precise, not easy to read. A tutorial is available separately. @@ -134,21 +110,21 @@

    The interface is broken down into three categories:

      -
    1. List Of Objects. +

    2. List Of Objects. This is a list of the three abstract objects used by the SQLite session module. + -

    3. List Of Constants. +

    4. List Of Constants. This is a list of numeric constants used by the SQLite session module and represented by #defines in the sqlite3session.h header file. There are constants passed to conflict handler callbacks to indicate the type of conflict, and constants returned by the conflict handler to indicate how the conflict should be resolved. -

    5. List Of Functions. - This is a list of all SQLite session module functions. +

    6. List Of Functions. + This is a list of all SQLite session module functions.

    - diff -Nru sqlite3-3.42.0/www/session/objlist.html sqlite3-3.44.0-0/www/session/objlist.html --- sqlite3-3.42.0/www/session/objlist.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/objlist.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    + +

    Session Module C Interface

    Objects:

    @@ -127,7 +103,6 @@

    Other lists: -Constants and -Functions. - +Constants and +Functions. diff -Nru sqlite3-3.42.0/www/session/rebaser.html sqlite3-3.44.0-0/www/session/rebaser.html --- sqlite3-3.42.0/www/session/rebaser.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/rebaser.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Rebasing changesets

    typedef struct sqlite3_rebaser sqlite3_rebaser;
    +
    +

    Session Module C Interface

    Rebasing changesets

    typedef struct sqlite3_rebaser sqlite3_rebaser;
     

    Important: This interface is experimental and is subject to change without notice.

    Suppose there is a site hosting a database in state S0. And that modifications are made that move that database to state S1 and a @@ -211,7 +187,6 @@ sqlite3rebaser_delete().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/session.html sqlite3-3.44.0-0/www/session/session.html --- sqlite3-3.42.0/www/session/session.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/session.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Session Object Handle

    typedef struct sqlite3_session sqlite3_session;
    +
    +

    Session Module C Interface

    Session Object Handle

    typedef struct sqlite3_session sqlite3_session;
     

    An instance of this object is a session that can be used to record changes to a database. @@ -129,14 +105,12 @@

  • sqlite3session_diff
  • sqlite3session_enable
  • sqlite3session_indirect
  • -
  • sqlite3session_object_config
  • sqlite3session_patchset
  • sqlite3session_table_filter
  • See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changegroup_add.html sqlite3-3.44.0-0/www/session/sqlite3changegroup_add.html --- sqlite3-3.42.0/www/session/sqlite3changegroup_add.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changegroup_add.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Add A Changeset To A Changegroup

    int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
    +
    +

    Session Module C Interface

    Add A Changeset To A Changegroup

    int sqlite3changegroup_add(sqlite3_changegroup*, int nData, void *pData);
     

    Add all changes within the changeset (or patchset) in buffer pData (size nData bytes) to the changegroup.

    @@ -189,7 +165,6 @@

    If no error occurs, SQLITE_OK is returned.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changegroup_add_strm.html sqlite3-3.44.0-0/www/session/sqlite3changegroup_add_strm.html --- sqlite3-3.42.0/www/session/sqlite3changegroup_add_strm.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changegroup_add_strm.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Streaming Versions of API functions.

    int sqlite3changeset_apply_strm(
    +
    +

    Session Module C Interface

    Streaming Versions of API functions.

    int sqlite3changeset_apply_strm(
       sqlite3 *db,                    /* Apply change to "main" db of this handle */
       int (*xInput)(void *pIn, void *pData, int *pnData), /* Input function */
       void *pIn,                                          /* First arg for xInput */
    @@ -285,7 +261,6 @@
     parameter set to a value less than or equal to zero. Other than this,
     no guarantees are made as to the size of the chunks of data returned.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changegroup_delete.html sqlite3-3.44.0-0/www/session/sqlite3changegroup_delete.html --- sqlite3-3.42.0/www/session/sqlite3changegroup_delete.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changegroup_delete.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,35 +89,10 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Delete A Changegroup Object

    void sqlite3changegroup_delete(sqlite3_changegroup*);
    +
    +

    Session Module C Interface

    Delete A Changegroup Object

    void sqlite3changegroup_delete(sqlite3_changegroup*);
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changegroup_new.html sqlite3-3.44.0-0/www/session/sqlite3changegroup_new.html --- sqlite3-3.42.0/www/session/sqlite3changegroup_new.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changegroup_new.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Create A New Changegroup Object

    int sqlite3changegroup_new(sqlite3_changegroup **pp);
    +
    +

    Session Module C Interface

    Create A New Changegroup Object

    int sqlite3changegroup_new(sqlite3_changegroup **pp);
     

    An sqlite3_changegroup object is used to combine two or more changesets (or patchsets) into a single changeset (or patchset). A single changegroup @@ -149,7 +125,6 @@ sqlite3changegroup_output() functions, also available are the streaming versions sqlite3changegroup_add_strm() and sqlite3changegroup_output_strm().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changegroup_output.html sqlite3-3.44.0-0/www/session/sqlite3changegroup_output.html --- sqlite3-3.42.0/www/session/sqlite3changegroup_output.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changegroup_output.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Obtain A Composite Changeset From A Changegroup

    int sqlite3changegroup_output(
    +
    +

    Session Module C Interface

    Obtain A Composite Changeset From A Changegroup

    int sqlite3changegroup_output(
       sqlite3_changegroup*,
       int *pnData,                    /* OUT: Size of output buffer in bytes */
       void **ppData                   /* OUT: Pointer to output buffer */
    @@ -142,7 +118,6 @@
     responsibility of the caller to eventually free the buffer using a
     call to sqlite3_free().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_apply.html sqlite3-3.44.0-0/www/session/sqlite3changeset_apply.html --- sqlite3-3.42.0/www/session/sqlite3changeset_apply.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_apply.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Apply A Changeset To A Database

    int sqlite3changeset_apply(
    +
    +

    Session Module C Interface

    Apply A Changeset To A Database

    int sqlite3changeset_apply(
       sqlite3 *db,                    /* Apply change to "main" db of this handle */
       int nChangeset,                 /* Size of changeset in bytes */
       void *pChangeset,               /* Changeset blob */
    @@ -298,12 +274,11 @@
     
     

    The behavior of sqlite3changeset_apply_v2() and its streaming equivalent may be modified by passing a combination of -supported flags as the 9th parameter.

    +supported flags as the 9th parameter.

    Note that the sqlite3changeset_apply_v2() API is still experimental and therefore subject to change.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_concat.html sqlite3-3.44.0-0/www/session/sqlite3changeset_concat.html --- sqlite3-3.42.0/www/session/sqlite3changeset_concat.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_concat.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Concatenate Two Changeset Objects

    int sqlite3changeset_concat(
    +
    +

    Session Module C Interface

    Concatenate Two Changeset Objects

    int sqlite3changeset_concat(
       int nA,                         /* Number of bytes in buffer pA */
       void *pA,                       /* Pointer to buffer containing changeset A */
       int nB,                         /* Number of bytes in buffer pB */
    @@ -147,7 +123,6 @@
     
     

    Refer to the sqlite3_changegroup documentation below for details.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_conflict.html sqlite3-3.44.0-0/www/session/sqlite3changeset_conflict.html --- sqlite3-3.42.0/www/session/sqlite3changeset_conflict.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_conflict.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Obtain Conflicting Row Values From A Changeset Iterator

    int sqlite3changeset_conflict(
    +
    +

    Session Module C Interface

    Obtain Conflicting Row Values From A Changeset Iterator

    int sqlite3changeset_conflict(
       sqlite3_changeset_iter *pIter,  /* Changeset iterator */
       int iVal,                       /* Column number */
       sqlite3_value **ppValue         /* OUT: Value from conflicting row */
    @@ -139,7 +115,6 @@
     

    If some other error occurs (e.g. an OOM condition), an SQLite error code is returned and *ppValue is set to NULL.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_finalize.html sqlite3-3.44.0-0/www/session/sqlite3changeset_finalize.html --- sqlite3-3.42.0/www/session/sqlite3changeset_finalize.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_finalize.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Finalize A Changeset Iterator

    int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
    +
    +

    Session Module C Interface

    Finalize A Changeset Iterator

    int sqlite3changeset_finalize(sqlite3_changeset_iter *pIter);
     

    This function is used to finalize an iterator allocated with sqlite3changeset_start().

    @@ -143,7 +119,6 @@ }

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_fk_conflicts.html sqlite3-3.44.0-0/www/session/sqlite3changeset_fk_conflicts.html --- sqlite3-3.42.0/www/session/sqlite3changeset_fk_conflicts.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_fk_conflicts.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Determine The Number Of Foreign Key Constraint Violations

    int sqlite3changeset_fk_conflicts(
    +
    +

    Session Module C Interface

    Determine The Number Of Foreign Key Constraint Violations

    int sqlite3changeset_fk_conflicts(
       sqlite3_changeset_iter *pIter,  /* Changeset iterator */
       int *pnOut                      /* OUT: Number of FK violations */
     );
    @@ -127,7 +103,6 @@
     
     

    In all other cases this function returns SQLITE_MISUSE.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_invert.html sqlite3-3.44.0-0/www/session/sqlite3changeset_invert.html --- sqlite3-3.42.0/www/session/sqlite3changeset_invert.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_invert.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Invert A Changeset

    int sqlite3changeset_invert(
    +
    +

    Session Module C Interface

    Invert A Changeset

    int sqlite3changeset_invert(
       int nIn, const void *pIn,       /* Input changeset */
       int *pnOut, void **ppOut        /* OUT: Inverse of input */
     );
    @@ -145,7 +121,6 @@
     

    WARNING/TODO: This function currently assumes that the input is a valid changeset. If it is not, the results are undefined.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_new.html sqlite3-3.44.0-0/www/session/sqlite3changeset_new.html --- sqlite3-3.42.0/www/session/sqlite3changeset_new.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_new.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Obtain new.* Values From A Changeset Iterator

    int sqlite3changeset_new(
    +
    +

    Session Module C Interface

    Obtain new.* Values From A Changeset Iterator

    int sqlite3changeset_new(
       sqlite3_changeset_iter *pIter,  /* Changeset iterator */
       int iVal,                       /* Column number */
       sqlite3_value **ppValue         /* OUT: New value (or NULL pointer) */
    @@ -145,7 +121,6 @@
     

    If some other error occurs (e.g. an OOM condition), an SQLite error code is returned and *ppValue is set to NULL.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_next.html sqlite3-3.44.0-0/www/session/sqlite3changeset_next.html --- sqlite3-3.42.0/www/session/sqlite3changeset_next.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_next.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Advance A Changeset Iterator

    int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
    +
    +

    Session Module C Interface

    Advance A Changeset Iterator

    int sqlite3changeset_next(sqlite3_changeset_iter *pIter);
     

    This function may only be used with iterators created by the function sqlite3changeset_start(). If it is called on an iterator passed to @@ -136,7 +112,6 @@ codes include SQLITE_CORRUPT (if the changeset buffer is corrupt) or SQLITE_NOMEM.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_old.html sqlite3-3.44.0-0/www/session/sqlite3changeset_old.html --- sqlite3-3.42.0/www/session/sqlite3changeset_old.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_old.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Obtain old.* Values From A Changeset Iterator

    int sqlite3changeset_old(
    +
    +

    Session Module C Interface

    Obtain old.* Values From A Changeset Iterator

    int sqlite3changeset_old(
       sqlite3_changeset_iter *pIter,  /* Changeset iterator */
       int iVal,                       /* Column number */
       sqlite3_value **ppValue         /* OUT: Old value (or NULL pointer) */
    @@ -142,7 +118,6 @@
     

    If some other error occurs (e.g. an OOM condition), an SQLite error code is returned and *ppValue is set to NULL.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_op.html sqlite3-3.44.0-0/www/session/sqlite3changeset_op.html --- sqlite3-3.42.0/www/session/sqlite3changeset_op.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_op.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Obtain The Current Operation From A Changeset Iterator

    int sqlite3changeset_op(
    +
    +

    Session Module C Interface

    Obtain The Current Operation From A Changeset Iterator

    int sqlite3changeset_op(
       sqlite3_changeset_iter *pIter,  /* Iterator object */
       const char **pzTab,             /* OUT: Pointer to table name */
       int *pnCol,                     /* OUT: Number of columns in table */
    @@ -151,7 +127,6 @@
     SQLite error code is returned. The values of the output variables may not
     be trusted in this case.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_pk.html sqlite3-3.44.0-0/www/session/sqlite3changeset_pk.html --- sqlite3-3.42.0/www/session/sqlite3changeset_pk.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_pk.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Obtain The Primary Key Definition Of A Table

    int sqlite3changeset_pk(
    +
    +

    Session Module C Interface

    Obtain The Primary Key Definition Of A Table

    int sqlite3changeset_pk(
       sqlite3_changeset_iter *pIter,  /* Iterator object */
       unsigned char **pabPK,          /* OUT: Array of boolean - true for PK cols */
       int *pnCol                      /* OUT: Number of entries in output array */
    @@ -143,7 +119,6 @@
     SQLITE_OK is returned and the output variables populated as described
     above.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3changeset_start.html sqlite3-3.44.0-0/www/session/sqlite3changeset_start.html --- sqlite3-3.42.0/www/session/sqlite3changeset_start.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3changeset_start.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Create An Iterator To Traverse A Changeset

    int sqlite3changeset_start(
    +
    +

    Session Module C Interface

    Create An Iterator To Traverse A Changeset

    int sqlite3changeset_start(
       sqlite3_changeset_iter **pp,    /* OUT: New changeset iterator handle */
       int nChangeset,                 /* Size of changeset blob in bytes */
       void *pChangeset                /* Pointer to blob containing changeset */
    @@ -164,7 +140,6 @@
     

    Note that the sqlite3changeset_start_v2() API is still experimental and therefore subject to change.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3rebaser_configure.html sqlite3-3.44.0-0/www/session/sqlite3rebaser_configure.html --- sqlite3-3.42.0/www/session/sqlite3rebaser_configure.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3rebaser_configure.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Configure a changeset rebaser object.

    int sqlite3rebaser_configure(
    +
    +

    Session Module C Interface

    Configure a changeset rebaser object.

    int sqlite3rebaser_configure(
       sqlite3_rebaser*, 
       int nRebase, const void *pRebase
     ); 
    @@ -125,7 +101,6 @@
     bytes), which must have been obtained from a previous call to
     sqlite3changeset_apply_v2().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3rebaser_create.html sqlite3-3.44.0-0/www/session/sqlite3rebaser_create.html --- sqlite3-3.42.0/www/session/sqlite3rebaser_create.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3rebaser_create.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,40 +89,15 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Create a changeset rebaser object.

    int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
    +
    +

    Session Module C Interface

    Create a changeset rebaser object.

    int sqlite3rebaser_create(sqlite3_rebaser **ppNew);
     

    Important: This interface is experimental and is subject to change without notice.

    Allocate a new changeset rebaser object. If successful, set (*ppNew) to point to the new object and return SQLITE_OK. Otherwise, if an error occurs, return an SQLite error code (e.g. SQLITE_NOMEM) and set (*ppNew) to NULL.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3rebaser_delete.html sqlite3-3.44.0-0/www/session/sqlite3rebaser_delete.html --- sqlite3-3.42.0/www/session/sqlite3rebaser_delete.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3rebaser_delete.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,39 +89,14 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Delete a changeset rebaser object.

    void sqlite3rebaser_delete(sqlite3_rebaser *p); 
    +
    +

    Session Module C Interface

    Delete a changeset rebaser object.

    void sqlite3rebaser_delete(sqlite3_rebaser *p); 
     

    Important: This interface is experimental and is subject to change without notice.

    Delete the changeset rebaser object and all associated resources. There should be one call to this function for each successful invocation of sqlite3rebaser_create().

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3rebaser_rebase.html sqlite3-3.44.0-0/www/session/sqlite3rebaser_rebase.html --- sqlite3-3.42.0/www/session/sqlite3rebaser_rebase.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3rebaser_rebase.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Rebase a changeset

    int sqlite3rebaser_rebase(
    +
    +

    Session Module C Interface

    Rebase a changeset

    int sqlite3rebaser_rebase(
       sqlite3_rebaser*,
       int nIn, const void *pIn, 
       int *pnOut, void **ppOut 
    @@ -131,7 +107,6 @@
     sqlite3_free(). Otherwise, if an error occurs, (*ppOut) and (*pnOut)
     are set to zero and an SQLite error code returned.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_attach.html sqlite3-3.44.0-0/www/session/sqlite3session_attach.html --- sqlite3-3.42.0/www/session/sqlite3session_attach.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_attach.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Attach A Table To A Session Object

    int sqlite3session_attach(
    +
    +

    Session Module C Interface

    Attach A Table To A Session Object

    int sqlite3session_attach(
       sqlite3_session *pSession,      /* Session object */
       const char *zTab                /* Table name */
     );
    @@ -174,7 +150,6 @@
     sqlite3changeset_apply() function silently ignore any modifications to the
     sqlite_stat1 table that are part of a changeset or patchset.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_changeset.html sqlite3-3.44.0-0/www/session/sqlite3session_changeset.html --- sqlite3-3.42.0/www/session/sqlite3session_changeset.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_changeset.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Generate A Changeset From A Session Object

    int sqlite3session_changeset(
    +
    +

    Session Module C Interface

    Generate A Changeset From A Session Object

    int sqlite3session_changeset(
       sqlite3_session *pSession,      /* Session object */
       int *pnChangeset,               /* OUT: Size of buffer at *ppChangeset */
       void **ppChangeset              /* OUT: Buffer containing changeset */
    @@ -222,7 +198,6 @@
     another field of the same row is updated while the session is enabled, the
     resulting changeset will contain an UPDATE change that updates both fields.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_changeset_size.html sqlite3-3.44.0-0/www/session/sqlite3session_changeset_size.html --- sqlite3-3.42.0/www/session/sqlite3session_changeset_size.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_changeset_size.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Return An Upper-limit For The Size Of The Changeset

    sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession);
    +
    +

    Session Module C Interface

    Return An Upper-limit For The Size Of The Changeset

    sqlite3_int64 sqlite3session_changeset_size(sqlite3_session *pSession);
     

    By default, this function always returns 0. For it to return a useful result, the sqlite3_session object must have been configured @@ -127,7 +103,6 @@ called. The final changeset size might be equal to or smaller than the size in bytes returned by this function.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_config.html sqlite3-3.44.0-0/www/session/sqlite3session_config.html --- sqlite3-3.42.0/www/session/sqlite3session_config.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_config.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Configure global parameters

    int sqlite3session_config(int op, void *pArg);
    +
    +

    Session Module C Interface

    Configure global parameters

    int sqlite3session_config(int op, void *pArg);
     

    The sqlite3session_config() interface is used to make global configuration changes to the sessions module in order to tune it to the specific needs @@ -147,7 +123,6 @@

    This function returns SQLITE_OK if successful, or an SQLite error code otherwise.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_create.html sqlite3-3.44.0-0/www/session/sqlite3session_create.html --- sqlite3-3.42.0/www/session/sqlite3session_create.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_create.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Create A New Session Object

    int sqlite3session_create(
    +
    +

    Session Module C Interface

    Create A New Session Object

    int sqlite3session_create(
       sqlite3 *db,                    /* Database handle */
       const char *zDb,                /* Name of db (e.g. "main") */
       sqlite3_session **ppSession     /* OUT: New session object */
    @@ -148,7 +124,6 @@
     attached database. It is not an error if database zDb is not attached
     to the database when the session object is created.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_delete.html sqlite3-3.44.0-0/www/session/sqlite3session_delete.html --- sqlite3-3.42.0/www/session/sqlite3session_delete.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_delete.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Delete A Session Object

    void sqlite3session_delete(sqlite3_session *pSession);
    +
    +

    Session Module C Interface

    Delete A Session Object

    void sqlite3session_delete(sqlite3_session *pSession);
     

    Delete a session object previously allocated using sqlite3session_create(). Once a session object has been deleted, the @@ -126,7 +102,6 @@ are attached is closed. Refer to the documentation for sqlite3session_create() for details.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_diff.html sqlite3-3.44.0-0/www/session/sqlite3session_diff.html --- sqlite3-3.42.0/www/session/sqlite3session_diff.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_diff.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Load The Difference Between Tables Into A Session

    int sqlite3session_diff(
    +
    +

    Session Module C Interface

    Load The Difference Between Tables Into A Session

    int sqlite3session_diff(
       sqlite3_session *pSession,
       const char *zFromDb,
       const char *zTbl,
    @@ -175,7 +151,6 @@
     message. It is the responsibility of the caller to free this buffer using
     sqlite3_free().
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_enable.html sqlite3-3.44.0-0/www/session/sqlite3session_enable.html --- sqlite3-3.42.0/www/session/sqlite3session_enable.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_enable.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Enable Or Disable A Session Object

    int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
    +
    +

    Session Module C Interface

    Enable Or Disable A Session Object

    int sqlite3session_enable(sqlite3_session *pSession, int bEnable);
     

    Enable or disable the recording of changes by a session object. When enabled, a session object records changes made to the database. When @@ -131,7 +107,6 @@

    The return value indicates the final state of the session object: 0 if the session is disabled, or 1 if it is enabled.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_indirect.html sqlite3-3.44.0-0/www/session/sqlite3session_indirect.html --- sqlite3-3.42.0/www/session/sqlite3session_indirect.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_indirect.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Set Or Clear the Indirect Change Flag

    int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
    +
    +

    Session Module C Interface

    Set Or Clear the Indirect Change Flag

    int sqlite3session_indirect(sqlite3_session *pSession, int bIndirect);
     

    Each change recorded by a session object is marked as either direct or indirect. A change is marked as indirect if either:

    @@ -141,7 +117,6 @@

    The return value indicates the final state of the indirect flag: 0 if it is clear, or 1 if it is set.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_isempty.html sqlite3-3.44.0-0/www/session/sqlite3session_isempty.html --- sqlite3-3.42.0/www/session/sqlite3session_isempty.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_isempty.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Test if a changeset has recorded any changes.

    int sqlite3session_isempty(sqlite3_session *pSession);
    +
    +

    Session Module C Interface

    Test if a changeset has recorded any changes.

    int sqlite3session_isempty(sqlite3_session *pSession);
     

    Return non-zero if no changes to attached tables have been recorded by the session object passed as the first argument. Otherwise, if one or @@ -129,7 +105,6 @@ guaranteed that a call to sqlite3session_changeset() will return a changeset containing zero changes.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_memory_used.html sqlite3-3.44.0-0/www/session/sqlite3session_memory_used.html --- sqlite3-3.42.0/www/session/sqlite3session_memory_used.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_memory_used.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,38 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Query for the amount of heap memory used by a session object.

    sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);
    +
    +

    Session Module C Interface

    Query for the amount of heap memory used by a session object.

    sqlite3_int64 sqlite3session_memory_used(sqlite3_session *pSession);
     

    This API returns the total amount of heap memory in bytes currently used by the session object passed as the only argument.

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_object_config.html sqlite3-3.44.0-0/www/session/sqlite3session_object_config.html --- sqlite3-3.42.0/www/session/sqlite3session_object_config.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_object_config.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,128 +0,0 @@ - - - - - -Configure a Session Object - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -

    Session Module C Interface

    Configure a Session Object

    int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
    -

    -This method is used to configure a session object after it has been -created. At present the only valid values for the second parameter are -SQLITE_SESSION_OBJCONFIG_SIZE and SQLITE_SESSION_OBJCONFIG_ROWID.

    - -

    See also lists of - Objects, - Constants, and - Functions.

    - diff -Nru sqlite3-3.42.0/www/session/sqlite3session_patchset.html sqlite3-3.44.0-0/www/session/sqlite3session_patchset.html --- sqlite3-3.42.0/www/session/sqlite3session_patchset.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_patchset.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Generate A Patchset From A Session Object

    int sqlite3session_patchset(
    +
    +

    Session Module C Interface

    Generate A Patchset From A Session Object

    int sqlite3session_patchset(
       sqlite3_session *pSession,      /* Session object */
       int *pnPatchset,                /* OUT: Size of buffer at *ppPatchset */
       void **ppPatchset               /* OUT: Buffer containing patchset */
    @@ -146,7 +122,6 @@
     a single table are grouped together, tables appear in the order in which
     they were attached to the session object).
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session/sqlite3session_table_filter.html sqlite3-3.44.0-0/www/session/sqlite3session_table_filter.html --- sqlite3-3.42.0/www/session/sqlite3session_table_filter.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session/sqlite3session_table_filter.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,33 +89,9 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); -

    Session Module C Interface

    Set a table filter on a Session Object.

    void sqlite3session_table_filter(
    +
    +

    Session Module C Interface

    Set a table filter on a Session Object.

    void sqlite3session_table_filter(
       sqlite3_session *pSession,      /* Session object */
       int(*xFilter)(
         void *pCtx,                   /* Copy of third arg to _filter_table() */
    @@ -130,7 +106,6 @@
     If xFilter returns 0, changes are not tracked. Note that once a table is 
     attached, xFilter will not be called again.
     

    See also lists of - Objects, - Constants, and - Functions.

    - + Objects, + Constants, and + Functions.

    diff -Nru sqlite3-3.42.0/www/session.html sqlite3-3.44.0-0/www/session.html --- sqlite3-3.42.0/www/session.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/session.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,49 +89,25 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    SQLite Session Module C/C++ Interface

    -

    This page defines the C-language interface to the SQLite +

    This page defines the C-language interface to the SQLite session extension. - This is not a tutorial. These pages are designed to be precise, not easy + This is not a tutorial. These pages are designed to be precise, not easy to read. A tutorial is available separately.

    This page contains all C-language interface information -in a single HTML file. The same information is also available -broken out into some smaller pages +in a single HTML file. The same information is also +available broken out into lots of small pages for easier viewing, if you prefer.

    -

    This document is created by a script which scans comments in the source +

    This document is created by a script which scans comments in the source code file sqlite3session.h.


    @@ -151,9 +127,8 @@

    Constants:


    @@ -216,7 +189,6 @@
  • sqlite3session_indirect
  • sqlite3session_isempty
  • sqlite3session_memory_used
  • -
  • sqlite3session_object_config
  • sqlite3session_patchset
  • sqlite3session_patchset_strm
  • sqlite3session_table_filter
  • @@ -377,7 +349,6 @@
  • sqlite3session_diff
  • sqlite3session_enable
  • sqlite3session_indirect
  • -
  • sqlite3session_object_config
  • sqlite3session_patchset
  • sqlite3session_table_filter
  • @@ -1202,14 +1173,7 @@

    This API returns the total amount of heap memory in bytes currently used by the session object passed as the only argument. -


    -

    Configure a Session Object

    int sqlite3session_object_config(sqlite3_session*, int op, void *pArg);
    -

    -This method is used to configure a session object after it has been -created. At present the only valid values for the second parameter are -SQLITE_SESSION_OBJCONFIG_SIZE and SQLITE_SESSION_OBJCONFIG_ROWID.

    - -


    +


    Generate A Patchset From A Session Object

    int sqlite3session_patchset(
       sqlite3_session *pSession,      /* Session object */
       int *pnPatchset,                /* OUT: Size of buffer at *ppPatchset */
    @@ -1255,10 +1219,9 @@
     to determine whether changes to the table's rows should be tracked or not. 
     If xFilter returns 0, changes are not tracked. Note that once a table is 
     attached, xFilter will not be called again.
    -


    +


    Flags for sqlite3changeset_apply_v2

    #define SQLITE_CHANGESETAPPLY_NOSAVEPOINT   0x0001
     #define SQLITE_CHANGESETAPPLY_INVERT        0x0002
    -#define SQLITE_CHANGESETAPPLY_IGNORENOOP    0x0004
     

    The following flags may passed via the 9th parameter to sqlite3changeset_apply_v2 and sqlite3changeset_apply_v2_strm:

    @@ -1276,20 +1239,7 @@

    SQLITE_CHANGESETAPPLY_INVERT
    Invert the changeset before applying it. This is equivalent to inverting a changeset using sqlite3changeset_invert() before applying it. It is - an error to specify this flag with a patchset.

    - -

    SQLITE_CHANGESETAPPLY_IGNORENOOP
    - Do not invoke the conflict handler callback for any changes that - would not actually modify the database even if they were applied. - Specifically, this means that the conflict handler is not invoked - for: -
      -
    • a delete change if the row being deleted cannot be found, -
    • an update change if the modified fields are already set to - their new values in the conflicting row, or -
    • an insert change if all fields of the conflicting row match - the row being inserted. -
    + an error to specify this flag with a patchset.


    Constants Returned By The Conflict Handler

    #define SQLITE_CHANGESET_OMIT       0
     #define SQLITE_CHANGESET_REPLACE    1
    @@ -1380,38 +1330,6 @@
       sqlite3changeset_conflict() API are undefined.

    -


    -

    Options for sqlite3session_object_config

    #define SQLITE_SESSION_OBJCONFIG_SIZE  1
    -#define SQLITE_SESSION_OBJCONFIG_ROWID 2
    -

    -The following values may passed as the the 2nd parameter to -sqlite3session_object_config().

    - -

    SQLITE_SESSION_OBJCONFIG_SIZE
    - This option is used to set, clear or query the flag that enables - the sqlite3session_changeset_size() API. Because it imposes some - computational overhead, this API is disabled by default. Argument - pArg must point to a value of type (int). If the value is initially - 0, then the sqlite3session_changeset_size() API is disabled. If it - is greater than 0, then the same API is enabled. Or, if the initial - value is less than zero, no change is made. In all cases the (int) - variable is set to 1 if the sqlite3session_changeset_size() API is - enabled following the current call, or 0 otherwise.

    - -

    It is an error (SQLITE_MISUSE) to attempt to modify this setting after - the first table has been attached to the session object.

    - -

    SQLITE_SESSION_OBJCONFIG_ROWID
    - This option is used to set, clear or query the flag that enables - collection of data for tables with no explicit PRIMARY KEY.

    - -

    Normally, tables with no explicit PRIMARY KEY are simply ignored - by the sessions module. However, if this flag is set, it behaves - as if such tables have a column "_rowid_ INTEGER PRIMARY KEY" inserted - as their leftmost columns.

    - -

    It is an error (SQLITE_MISUSE) to attempt to modify this setting after - the first table has been attached to the session object.


    Streaming Versions of API functions.

    int sqlite3changeset_apply_strm(
       sqlite3 *db,                    /* Apply change to "main" db of this handle */
    @@ -1766,7 +1684,7 @@
     
     

    The behavior of sqlite3changeset_apply_v2() and its streaming equivalent may be modified by passing a combination of -supported flags as the 9th parameter.

    +supported flags as the 9th parameter.

    Note that the sqlite3changeset_apply_v2() API is still experimental and therefore subject to change. @@ -1821,4 +1739,3 @@ and therefore subject to change.


    - diff -Nru sqlite3-3.42.0/www/sessionintro.html sqlite3-3.44.0-0/www/sessionintro.html --- sqlite3-3.42.0/www/sessionintro.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/sessionintro.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -161,10 +137,10 @@

    1. Introduction

    -

    The session extension provide a mechanism for conviently recording -changes to some or all of certain tables in an SQLite database, and -packaging those changes into a "changeset" or "patchset" file that can -later be used to apply the same set of changes to another database with +

    The session extension provide a mechanism for recording changes +to some or all of the rowid tables in an SQLite database, and packaging +those changes into a "changeset" or "patchset" file that can later +be used to apply the same set of changes to another database with the same schema and compatible starting data. A "changeset" may also be inverted and used to "undo" a session. @@ -193,21 +169,20 @@ SQLite database files that is similar to the unix patch utility program, or to the "merge" capabilities of version control systems such -as Fossil, Git, +as Fossil, Git, or Mercurial.

    1.2. Obtaining the Session Extension

    -

    Since version 3.13.0 (2016-05-18), +

    Since version 3.13.0 (2016-05-18), the session extension has been included in the SQLite -amalgamation source distribution. By default, the session extension is +amalgamation source distribution. By default, the session extension is disabled. To enable it, build with the following compiler switches:

    -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK
     
    -

    Or, if using the autoconf build system, -pass the --enable-session option to the configure script. +

    Or, if using the autoconf build system, pass the --enable-session option to the configure script.

    1.3. Limitations

    @@ -215,8 +190,7 @@
  • Prior to SQLite version 3.17.0, the session extension only worked with rowid tables, not WITHOUT ROWID tables. As of 3.17.0, both - rowid and WITHOUT ROWID tables are supported. However, extra steps are - needed to record primary keys for WITHOUT ROWID table changes. + rowid and WITHOUT ROWID tables are supported.

  • There is no support for virtual tables. Changes to virtual tables are not captured. @@ -236,69 +210,69 @@

    2.1. Changesets and Patchsets

    -

    The sessions module revolves around creating and manipulating -changesets. A changeset is a blob of data that encodes a series of -changes to a database. Each change in a changeset is one of the +

    The sessions module revolves around creating and manipulating +changesets. A changeset is a blob of data that encodes a series of +changes to a database. Each change in a changeset is one of the following:

      -
    • An INSERT. An INSERT change contains a single row to add to +

    • An INSERT. An INSERT change contains a single row to add to a database table. The payload of the INSERT change consists of the values for each field of the new row.

    • A DELETE. A DELETE change represents a row, identified by its primary key values, to remove from a database table. The payload - of a DELETE change consists of the values for all fields of the + of a DELETE change consists of the values for all fields of the deleted row.

    • An UPDATE. An UPDATE change represents the modification of - one or more non-PRIMARY KEY fields of a single row within a database + one or more non-PRIMARY KEY fields of a single row within a database table, identified by its PRIMARY KEY fields. The payload for an UPDATE change consists of:

        -
      • The PRIMARY KEY values identifying the modified row, +
      • The PRIMARY KEY values identifying the modified row,
      • The new values for each modified field of the row, and
      • The original values for each modified field of the row.

      An UPDATE change does not contain any information regarding non-PRIMARY KEY fields that are not modified by the change. It is not - possible for an UPDATE change to specify modifications to PRIMARY - KEY fields. + possible for an UPDATE change to specify modifications to PRIMARY + KEY fields.

    -

    A single changeset may contain changes that apply to more than one +

    A single changeset may contain changes that apply to more than one database table. For each table that the changeset includes at least one change for, it also encodes the following data:

      -
    • The name of the database table, +
    • The name of the database table,
    • The number of columns the table has, and
    • Which of those columns are PRIMARY KEY columns.
    -

    Changesets may only be applied to databases that contain tables +

    Changesets may only be applied to databases that contain tables matching the above three criteria as stored in the changeset.

    A patchset is similar to a changeset. It is slightly more compact than a changeset, but provides more limited conflict detection and resolution -options (see the next section for details). The differences between a +options (see the next section for details). The differences between a patchset and a changeset are that:

      -
    • For a DELETE change, the payload consists of the PRIMARY KEY +

    • For a DELETE change, the payload consists of the PRIMARY KEY fields only. The original values of other fields are not stored as part of a patchset. -

    • For an UPDATE change, the payload consists of the PRIMARY KEY +

    • For an UPDATE change, the payload consists of the PRIMARY KEY fields and the new values of modified fields only. The original values of modified fields are not stored as part of a patchset.

    2.2. Conflicts

    -

    When a changeset or patchset is applied to a database, an attempt is +

    When a changeset or patchset is applied to a database, an attempt is made to insert a new row for each INSERT change, remove a row for each -DELETE change and modify a row for each UPDATE change. If the target +DELETE change and modify a row for each UPDATE change. If the target database is in the same state as the original database that the changeset was recorded on, this is a simple matter. However, if the contents of the target database is not in exactly this state, conflicts can occur when @@ -311,7 +285,7 @@

  • The target database may already contain a row with the same PRIMARY KEY values as specified by the INSERT change. -
  • Some other database constraint, for example a UNIQUE or CHECK +
  • Some other database constraint, for example a UNIQUE or CHECK constraint, may be violated when the new row is inserted.
  • @@ -319,7 +293,7 @@ detected:

      -
    • The target database may contain no row with the specified PRIMARY +
    • The target database may contain no row with the specified PRIMARY KEY values to delete.
    • The target database may contain a row with the specified PRIMARY @@ -332,7 +306,7 @@ detected:

        -
      • The target database may contain no row with the specified PRIMARY +
      • The target database may contain no row with the specified PRIMARY KEY values to modify.
      • The target database may contain a row with the specified PRIMARY @@ -340,7 +314,7 @@ by the change may not match the original values stored within the changeset. This type of conflict is not detected when using a patchset. -
      • Some other database constraint, for example a UNIQUE or CHECK +
      • Some other database constraint, for example a UNIQUE or CHECK constraint, may be violated when the row is updated.
      @@ -352,11 +326,11 @@

      2.3. Changeset Construction

      -

      After a session object has been configured, it begins monitoring for +

      After a session object has been configured, it begins monitoring for changes to its configured tables. However, it does not record an entire change each time a row within the database is modified. Instead, it records -just the PRIMARY KEY fields for each inserted row, and just the PRIMARY KEY -and all original row values for any updated or deleted rows. If a row is +just the PRIMARY KEY fields for each inserted row, and just the PRIMARY KEY +and all original row values for any updated or deleted rows. If a row is modified more than once by a single session, no new information is recorded.

      The other information required to create a changeset or patchset is @@ -364,9 +338,9 @@ sqlite3session_patchset() is called. Specifically,

        -
      • For each primary key recorded as a result of an INSERT operation, +

      • For each primary key recorded as a result of an INSERT operation, the sessions module checks if there is a row with a matching primary - key still in the table. If so, an INSERT change is added to the + key still in the table. If so, an INSERT change is added to the changeset.

      • For each primary key recorded as a result of an UPDATE or DELETE @@ -374,12 +348,12 @@ primary key within the table. If one can be found, but one or more of the non-PRIMARY KEY fields does not match the original recorded value, an UPDATE is added to the changeset. Or, if there is no row - at all with the specified primary key, a DELETE is added to the + at all with the specified primary key, a DELETE is added to the changeset. If the row does exist but none of the non-PRIMARY KEY fields have been modified, no change is added to the changeset.

      -

      One implication of the above is that if a change is made and then +

      One implication of the above is that if a change is made and then unmade within a single session (for example if a row is inserted and then deleted again), the sessions module does not report any change at all. Or if a row is updated multiple times within the same session, all updates @@ -396,18 +370,18 @@ changeset while executing SQL commands. In summary:

        -
      1. A session object (type sqlite3_session*) is created by making a +

      2. A session object (type sqlite3_session*) is created by making a call to the sqlite3session_create() API function. -

        A single session object monitors changes made to a single database - (i.e. "main", "temp" or an attached database) via a single +

        A single session object monitors changes made to a single database + (i.e. "main", "temp" or an attached database) via a single sqlite3* database handle.

      3. The session object is configured with a set of tables to monitor changes on. -

        By default a session object does not monitor changes on any - database table. Before it does so it must be configured. There +

        By default a session object does not monitor changes on any + database table. Before it does so it must be configured. There are three ways to configure the set of tables to monitor changes on:

          @@ -432,13 +406,13 @@ to sqlite3session_changeset() (or, if using patchsets, a call to the sqlite3session_patchset() function). -

        • The session object is deleted using a call to the +

        • The session object is deleted using a call to the sqlite3session_delete() API function.

          It is not necessary to delete a session object after extracting a changeset or patchset from it. It can be left attached to the database handle and will continue monitoring for changes on the - configured tables as before. However, if + configured tables as before. However, if sqlite3session_changeset() or sqlite3session_patchset() is called a second time on a session object, the changeset or patchset will contain all changes that have taken place on the connection @@ -449,7 +423,7 @@

      /*
      -** Argument zSql points to a buffer containing an SQL script to execute
      +** Argument zSql points to a buffer containing an SQL script to execute 
       ** against the database handle passed as the first argument. As well as
       ** executing the SQL script, this function collects a changeset recording
       ** all changes made to the "main" database file. Assuming no error occurs,
      @@ -498,7 +472,7 @@
       Usually, a single call to sqlite3changeset_apply(), as depicted in the
       example code below, suffices.
       
      -

      In cases where it is complicated, the complications in applying a +

      In cases where it is complicated, the complications in applying a changeset lie in conflict resolution. Refer to the API documentation linked above for details. @@ -516,7 +490,7 @@ ** Return SQLITE_OK if successful, or an SQLite error code if an error ** occurs. ** -** If parameter bIgnoreConflicts is true, then any conflicting changes +** If parameter bIgnoreConflicts is true, then any conflicting changes ** within the changeset are simply ignored. Or, if bIgnoreConflicts is ** false, then this call fails with an SQLTIE_ABORT error if a changeset ** conflict is encountered. @@ -528,9 +502,9 @@ void *pChangeset /* Pointer to changeset blob */ ){ return sqlite3changeset_apply( - db, - nChangeset, pChangeset, - 0, xConflict, + db, + nChangeset, pChangeset, + 0, xConflict, (void*)bIgnoreConflicts ); } @@ -538,7 +512,7 @@

      3.3. Inspecting the Contents of a Changeset

      -

      The example code below demonstrates the techniques used to iterate +

      The example code below demonstrates the techniques used to iterate through and extract the data related to all changes in a changeset. To summarize: @@ -548,7 +522,7 @@ changeset. Initially, the iterator points to no element at all.

    • The first call to sqlite3changeset_next() on the iterator moves - it to point to the first change in the changeset (or to EOF, if + it to point to the first change in the changeset (or to EOF, if the changeset is completely empty). sqlite3changeset_next() returns SQLITE_ROW if it moves the iterator to point to a valid entry, SQLITE_DONE if it moves the iterator to EOF, or an SQLite error @@ -556,7 +530,7 @@

    • If the iterator points to a valid entry, the sqlite3changeset_op() API may be used to determine the type of change (INSERT, UPDATE or - DELETE) that the iterator points to. Additionally, the same API + DELETE) that the iterator points to. Additionally, the same API can be used to obtain the name of the table the change applies to and its expected number of columns and primary key columns. @@ -568,7 +542,7 @@ sqlite3changeset_old() API may be used to obtain the old.* values within the change payload. -

    • An iterator is deleted using a call to the +

    • An iterator is deleted using a call to the sqlite3changeset_finalize() API. If an error occured while iterating, an SQLite error code is returned (even if the same error code has already been returned by sqlite3changeset_next()). Or, @@ -639,7 +613,7 @@ available for the use and manipulation of changeset and patchset blobs:

        -
      • Two or more changeset/patchsets may be combined using the +

      • Two or more changeset/patchsets may be combined using the sqlite3changeset_concat() or sqlite3_changegroup interfaces.

      • A changeset may be "inverted" using the sqlite3changeset_invert() @@ -647,5 +621,4 @@ original. If changeset C+ is the inverse of changeset C, then applying C and then C+ to a database should leave the database unchanged. -

      This page last modified on 2023-01-07 01:13:01 UTC

      - +

    diff -Nru sqlite3-3.42.0/www/sharedcache.html sqlite3-3.44.0-0/www/sharedcache.html --- sqlite3-3.42.0/www/sharedcache.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/sharedcache.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -126,7 +102,6 @@ Table Of Contents
    - @@ -157,11 +132,9 @@ - -

    1. SQLite Shared-Cache Mode

    -

    Starting with version 3.3.0 (2006-01-11), +

    Starting with version 3.3.0 (2006-01-11), SQLite includes a special "shared-cache" mode (disabled by default) intended for use in embedded servers. If shared-cache mode is enabled and a thread establishes multiple connections @@ -169,7 +142,7 @@ This can significantly reduce the quantity of memory and IO required by the system.

    -

    In version 3.5.0 (2007-09-04), +

    In version 3.5.0 (2007-09-04), shared-cache mode was modified so that the same cache can be shared across an entire process rather than just within a single thread. Prior to this change, there were restrictions on @@ -183,37 +156,11 @@ File Locking And Concurrency In SQLite Version 3 for details) is assumed.

    - - -

    1.1. Use of shared-cache is discouraged

    - -

    Shared-cache mode is an obsolete feature. The use of shared-cache mode -is discouraged. Most use cases for shared-cache are better served by -WAL mode. - -

    Shared-cache mode was invented in 2006 at the request of developers -of Symbian. Their problem was that -if the contacts database on the phone was being synced, that would lock the -database file. Then if a call came in, the database lock would prevent them -from querying the contacts database in order to find the appropriate -ring-tone for the incoming call, or a photo of the caller to show on screen, -and so forth. -WAL mode (circa 2010) is a better solution to this problem as it permits -simultaneous access without breaking transaction isolation. - -

    Applications that build their own copy of SQLite from source code -are encouraged to use the -DSQLITE_OMIT_SHARED_CACHE compile-time option, -as the resulting binary will be both smaller and faster. - -

    The shared-cache interfaces described here will continue to be supported -in SQLite, to insure full backwards compatibility. However, the use of -shared-cache is discouraged. - -

    2. Shared-Cache Locking Model

    +

    2. Shared-Cache Locking Model

    Externally, from the point of view of another process or thread, two -or more database connections using a shared-cache appear as a single -connection. The locking protocol used to arbitrate between multiple +or more database connections using a shared-cache appear as a single +connection. The locking protocol used to arbitrate between multiple shared-caches or regular database users is described elsewhere.

    @@ -224,9 +171,9 @@

    Figure 1

    -

    Figure 1 depicts an example runtime configuration where three +

    Figure 1 depicts an example runtime configuration where three database connections have been established. Connection 1 is a normal -SQLite database connection. Connections 2 and 3 share a cache +SQLite database connection. Connections 2 and 3 share a cache The normal locking protocol is used to serialize database access between connection 1 and the shared cache. The internal protocol used to serialize (or not, see @@ -234,8 +181,8 @@ connections 2 and 3 is described in the remainder of this section.

    -

    There are three levels to the shared-cache locking model, -transaction level locking, table level locking and schema level locking. +

    There are three levels to the shared-cache locking model, +transaction level locking, table level locking and schema level locking. They are described in the following three sub-sections.

    2.1. Transaction Level Locking

    @@ -245,26 +192,26 @@ read-transaction until it first writes to a database table, at which point it becomes a write-transaction.

    -

    At most one connection to a single shared cache may open a -write transaction at any one time. This may co-exist with any number of read -transactions. +

    At most one connection to a single shared cache may open a +write transaction at any one time. This may co-exist with any number of read +transactions.

    2.2. Table Level Locking

    -

    When two or more connections use a shared-cache, locks are used to -serialize concurrent access attempts on a per-table basis. Tables support +

    When two or more connections use a shared-cache, locks are used to +serialize concurrent access attempts on a per-table basis. Tables support two types of locks, "read-locks" and "write-locks". Locks are granted to connections - at any one time, each database connection has either a read-lock, write-lock or no lock on each database table.

    At any one time, a single table may have any number of active read-locks -or a single active write lock. To read data from a table, a connection must -first obtain a read-lock. To write to a table, a connection must obtain a +or a single active write lock. To read data from a table, a connection must +first obtain a read-lock. To write to a table, a connection must obtain a write-lock on that table. If a required table lock cannot be obtained, the query fails and SQLITE_LOCKED is returned to the caller. -

    +

    Once a connection obtains a table lock, it is not released until the current transaction (read or write) is concluded. @@ -272,22 +219,22 @@

    2.2.1. Read-Uncommitted Isolation Mode

    -

    The behaviour described above may be modified slightly by using the -read_uncommitted pragma to change the isolation level from serialized +

    The behaviour described above may be modified slightly by using the +read_uncommitted pragma to change the isolation level from serialized (the default), to read-uncommitted.

    -

    A database connection in read-uncommitted mode does not attempt -to obtain read-locks before reading from database tables as described +

    A database connection in read-uncommitted mode does not attempt +to obtain read-locks before reading from database tables as described above. This can lead to inconsistent query results if another database connection modifies a table while it is being read, but it also means that a read-transaction opened by a connection in read-uncommitted mode can neither block nor be blocked by any other connection.

    Read-uncommitted mode has no effect on the locks required to write to -database tables (i.e. read-uncommitted connections must still obtain -write-locks and hence database writes may still block or be blocked). +database tables (i.e. read-uncommitted connections must still obtain +write-locks and hence database writes may still block or be blocked). Also, read-uncommitted mode has no effect on the sqlite_schema -locks required by the rules enumerated below (see section +locks required by the rules enumerated below (see section "Schema (sqlite_schema) Level Locking").

    @@ -305,32 +252,32 @@

    2.3. Schema (sqlite_schema) Level Locking

    -

    The sqlite_schema table supports shared-cache read and write -locks in the same way as all other database tables (see description +

    The sqlite_schema table supports shared-cache read and write +locks in the same way as all other database tables (see description above). The following special rules also apply:

      -
    • A connection must obtain a read-lock on sqlite_schema before +
    • A connection must obtain a read-lock on sqlite_schema before accessing any database tables or obtaining any other read or write locks.
    • -
    • Before executing a statement that modifies the database schema (i.e. -a CREATE or DROP TABLE statement), a connection must obtain a write-lock on +
    • Before executing a statement that modifies the database schema (i.e. +a CREATE or DROP TABLE statement), a connection must obtain a write-lock on sqlite_schema.
    • A connection may not compile an SQL statement if any other connection is holding a write-lock on the sqlite_schema table of any attached -database (including the default database, "main"). +database (including the default database, "main").

    3. Thread Related Issues

    -

    In SQLite versions 3.3.0 through 3.4.2 when shared-cache mode is enabled, +

    In SQLite versions 3.3.0 through 3.4.2 when shared-cache mode is enabled, a database connection may only be used by the thread that called sqlite3_open() to create it. And a connection could only share cache with another connection in the same thread. -These restrictions were dropped beginning with SQLite +These restrictions were dropped beginning with SQLite version 3.5.0 (2007-09-04).

    @@ -343,7 +290,7 @@

    5. Enabling Shared-Cache Mode

    -

    Shared-cache mode is enabled on a per-process basis. Using the C +

    Shared-cache mode is enabled on a per-process basis. Using the C interface, the following API can be used to globally enable or disable shared-cache mode:

    @@ -384,7 +331,7 @@

    6. Shared Cache And In-Memory Databases

    -Beginning with SQLite version 3.7.13 (2012-06-11), +Beginning with SQLite version 3.7.13 (2012-06-11), shared cache can be used on in-memory databases, provided that the database is created using a URI filename. For backwards compatibility, shared cache is always @@ -402,5 +349,4 @@ deleted and memory is reclaimed when the last connection to that database closes.

    -

    This page last modified on 2023-01-02 14:22:42 UTC

    diff -Nru sqlite3-3.42.0/www/shortnames.html sqlite3-3.44.0-0/www/shortnames.html --- sqlite3-3.42.0/www/shortnames.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/shortnames.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -237,5 +213,4 @@ other cases using long filenames is equivalent to deleting a hot journal.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/sitemap.html sqlite3-3.44.0-0/www/sitemap.html --- sqlite3-3.42.0/www/sitemap.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/sitemap.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -136,8 +112,7 @@
  • 8+3 Filenames
  • About SQLite
  • About SQLite — Books
  • -
  • Advantages Of Flexible Typing — The
  • -
  • Against The Dark Arts — Defense
  • +
  • Against Dark Arts — Defense
  • Aggregate Functions — Built in
  • Ahead Logging — Write
  • Allocation In SQLite — Dynamic Memory
  • @@ -152,7 +127,6 @@
  • and Error Codes — Result
  • and FTS4 Extensions — SQLite FTS3
  • and Gotchas In SQLite — Quirks, Caveats,
  • -
  • And Operators — JSON Functions
  • and Reducing CPU Usage in SQLite — Measuring
  • And Tables_Used() Table Valued Functions — The Bytecode()
  • and the WITHOUT ROWID Optimization — Clustered Indexes
  • @@ -170,7 +144,7 @@
  • Archive Files — SQLite
  • Archiver (sqlar.exe) — SQLite
  • Are Efficient In SQLite — Many Small Queries
  • -
  • Arts — Defense Against The Dark
  • +
  • Arts — Defense Against Dark
  • Asked Questions — SQLite Frequently
  • assert() In SQLite — The Use Of
  • Asynchronous I/O Module For SQLite — An
  • @@ -234,7 +208,6 @@
  • Control System — The Fossil Version
  • Copyright — SQLite
  • Corrupt An SQLite Database File — How To
  • -
  • Corrupt SQLite Database — Recovering Data From A
  • CPU Usage in SQLite — Measuring and Reducing
  • CREATE INDEX
  • CREATE TABLE
  • @@ -243,10 +216,8 @@
  • CREATE VIRTUAL TABLE
  • CSV Virtual Table — The
  • Custom Builds Of SQLite
  • -
  • Dark Arts — Defense Against The
  • -
  • Data From A Corrupt SQLite Database — Recovering
  • +
  • Dark Arts — Defense Against
  • DATABASE — ATTACH
  • -
  • Database — Recovering Data From A Corrupt SQLite
  • Database — SQLite: Single File
  • Database Difference Utility — sqldiff.exe:
  • Database Engine — Most Widely Deployed SQL
  • @@ -256,14 +227,14 @@
  • Database Object Name Resolution
  • Database Speed Comparison — SQLite
  • Databases — In Memory
  • -
  • Datatypes In SQLite
  • Datatypes In SQLite version 2
  • +
  • Datatypes In SQLite Version 3
  • Date And Time Functions
  • dbhash.exe Utility Program — The
  • DBSTAT Virtual Table — The
  • Debugging SQLite — Hints for
  • Default Page Size in SQLite Version 3.12.0 — Change in
  • -
  • Defense Against The Dark Arts
  • +
  • Defense Against Dark Arts
  • Defined SQL Functions — Application
  • DELETE
  • Deployed SQL Database Engine — Most Widely
  • @@ -297,6 +268,7 @@
  • Expressions — Indexes On
  • Expressions — SQL Language
  • Extension — SQLite FTS5
  • +
  • Extension — The JSON1
  • Extension — The RBU
  • Extension — The Session
  • Extensions — Run Time Loadable
  • @@ -319,7 +291,6 @@
  • Files — SQLite Archive
  • Files Used By SQLite — Temporary
  • Filesystem — 35% Faster Than The
  • -
  • Flexible Typing — The Advantages Of
  • Floating Point Numbers
  • Footprint — SQLite Library
  • Foreign Key Support — SQLite
  • @@ -332,7 +303,6 @@
  • Format Changes in SQLite — File
  • Fossil Version Control System — The
  • Frequently Asked Questions — SQLite
  • -
  • From A Corrupt SQLite Database — Recovering Data
  • From Version 3.4.2 To 3.5.0 — SQLite Changes
  • From Version 3.5.9 To 3.6.0 — SQLite Changes
  • FTS3 and FTS4 Extensions — SQLite
  • @@ -350,7 +320,6 @@
  • Functions — Deterministic SQL
  • Functions — The Bytecode() And Tables_Used() Table Valued
  • Functions — Window
  • -
  • Functions And Operators — JSON
  • generate_series Table Valued Function — The
  • Generated Columns
  • Generation Query Planner — The Next
  • @@ -397,10 +366,9 @@
  • Interfaces — Pointer Passing
  • Internal Versus External BLOBs
  • Introduction To The SQLite C/C++ Interface — An
  • -
  • Invalid UTF Policy
  • Isolation In SQLite
  • Javascript Required
  • -
  • JSON Functions And Operators
  • +
  • JSON1 Extension — The
  • Key Support — SQLite Foreign
  • Keyword Index — Website
  • Keywords — SQLite
  • @@ -461,7 +429,6 @@
  • Older News — SQLite
  • On Disk Format
  • OpenDocument Used SQLite? — What If
  • -
  • Operators — JSON Functions And
  • Optimization — Clustered Indexes and the WITHOUT ROWID
  • Optimizer Overview — The SQLite Query
  • Options — Compile time
  • @@ -481,17 +448,14 @@
  • Planning — Query
  • Point Numbers — Floating
  • Pointer Passing Interfaces
  • -
  • Policy — Invalid UTF
  • Powersafe Overwrite
  • Pragma statements supported by SQLite
  • printf() — SQLite's Built in
  • Private Branches Of SQLite — Maintaining
  • Pro Support — SQLite
  • -
  • Profiling SQL Queries
  • Program — The dbhash.exe Utility
  • Program — The sqlite3_analyzer.exe Utility
  • Quality Management
  • -
  • Queries — Profiling SQL
  • Queries Are Efficient In SQLite — Many Small
  • Query Language Understood by SQLite
  • Query Optimizer Overview — The SQLite
  • @@ -505,7 +469,6 @@
  • RBU Extension — The
  • Recent SQLite News
  • Recommended Storage Format — LoC
  • -
  • Recovering Data From A Corrupt SQLite Database
  • Reducing CPU Usage in SQLite — Measuring and
  • Reference — C/C++ API
  • REINDEX
  • @@ -552,7 +515,6 @@
  • SQL Functions — Built In Scalar
  • SQL Functions — Deterministic
  • SQL Language Expressions
  • -
  • SQL Queries — Profiling
  • sqldiff.exe: Database Difference Utility
  • SQLite Archive Files
  • SQLite Archiver (sqlar.exe)
  • @@ -597,7 +559,6 @@
  • SQLITE_STMT Virtual Table — The
  • statements supported by SQLite — Pragma
  • Storage Format — LoC Recommended
  • -
  • STRICT Tables
  • Strings — NUL Characters In
  • Support — Long Term
  • Support — SQLite Foreign Key
  • @@ -632,7 +593,6 @@
  • Tables — Imposter
  • Tables — List Of Virtual
  • Tables — Rowid
  • -
  • Tables — STRICT
  • Tables_Used() Table Valued Functions — The Bytecode() And
  • Tcl interface to the SQLite library — The
  • Temporary Files Used By SQLite
  • @@ -641,7 +601,6 @@
  • TH3
  • Than The Filesystem — 35% Faster
  • That SQLite Does Not Implement — SQL Features
  • -
  • The Advantages Of Flexible Typing
  • The Bytecode() And Tables_Used() Table Valued Functions
  • The C language interface to SQLite Version 2
  • The Carray() Table Valued Function
  • @@ -655,6 +614,7 @@
  • The generate_series Table Valued Function
  • The Geopoly Interface To The SQLite R*Tree Module
  • The INDEXED BY Clause
  • +
  • The JSON1 Extension
  • The Lemon LALR(1) Parser Generator
  • The Next Generation Query Planner
  • The ON CONFLICT Clause
  • @@ -687,7 +647,6 @@
  • Transactional — SQLite Is
  • TRIGGER — CREATE
  • TRIGGER — DROP
  • -
  • Typing — The Advantages Of Flexible
  • UINT Collating Sequence — The
  • Understood by SQLite — Query Language
  • Undo/Redo With SQLite — Automatic
  • @@ -704,7 +663,6 @@
  • Users Of SQLite — Well Known
  • Uses For SQLite — Appropriate
  • Using SQLite In Multi Threaded Applications
  • -
  • UTF Policy — Invalid
  • Utility — sqldiff.exe: Database Difference
  • Utility Program — The dbhash.exe
  • Utility Program — The sqlite3_analyzer.exe
  • @@ -717,6 +675,7 @@
  • version 2 — Datatypes In SQLite
  • Version 2 — The C language interface to SQLite
  • Version 3 — C/C++ Interface For SQLite
  • +
  • Version 3 — Datatypes In SQLite
  • Version 3 — File Locking And Concurrency In SQLite
  • Version 3 (old) — C/C++ Interface For SQLite
  • Version 3 Overview — SQLite
  • @@ -763,4 +722,3 @@ - diff -Nru sqlite3-3.42.0/www/speed.html sqlite3-3.44.0-0/www/speed.html --- sqlite3-3.42.0/www/speed.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/speed.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,42 +89,18 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    Database Speed Comparison

    Note: This document is very very old. It describes a speed comparison between -archaic versions of SQLite, MySQL and PostgreSQL. +archaic versions of SQLite, MySQL and PostgreSQL.

    The numbers here have become meaningless. This page has been retained only -as an historical artifact. +as an historical artifact.

    Executive Summary

    @@ -139,7 +115,7 @@
  • SQLite 2.7.6 is significantly faster (sometimes as much as 10 or 20 times faster) than the default PostgreSQL 7.1.3 installation - on RedHat 7.2 for most common operations. + on RedHat 7.2 for most common operations.

  • SQLite 2.7.6 is often faster (sometimes @@ -203,7 +179,7 @@

    -Obsolete URL: http://www.sergeant.org/sqlite_vs_pgsync.html +http://www.sergeant.org/sqlite_vs_pgsync.html

    @@ -222,13 +198,13 @@

    -The times reported on all tests represent wall-clock time +The times reported on all tests represent wall-clock time in seconds. Two separate time values are reported for SQLite. The first value is for SQLite in its default configuration with full disk synchronization turned on. With synchronization turned on, SQLite executes an fsync() system call (or the equivalent) at key points -to make certain that critical data has +to make certain that critical data has actually been written to the disk drive surface. Synchronization is necessary to guarantee the integrity of the database if the operating system crashes or the computer powers down unexpectedly @@ -238,7 +214,7 @@ operating system crash or an unexpected power failure could damage the database. Generally speaking, the synchronous SQLite times are for comparison against PostgreSQL (which is also -synchronous) and the asynchronous SQLite times are for +synchronous) and the asynchronous SQLite times are for comparison against the asynchronous MySQL engine.

    @@ -266,7 +242,7 @@ is a separate transaction so the database file must be opened and closed and the cache must be flushed 1000 times. In spite of this, the asynchronous version of SQLite is still nearly as fast as MySQL. Notice how much slower -the synchronous version is, however. SQLite calls fsync() after +the synchronous version is, however. SQLite calls fsync() after each synchronous transaction to make sure that all data is safely on the disk surface before continuing. For most of the 13 seconds in the synchronous test, SQLite was sitting idle waiting on disk I/O to complete.

    @@ -516,7 +492,7 @@

    The synchronous version of SQLite is the slowest of the group in this test, -but the asynchronous version is the fastest. +but the asynchronous version is the fastest. The difference is the extra time needed to execute fsync().

    @@ -594,8 +570,7 @@

    -On the other hand, dropping tables is not a very common operation +On the other hand, dropping tables is not a very common operation so if SQLite takes a little longer, that is not seen as a big problem.

    -

    This page last modified on 2023-01-02 14:22:42 UTC

    diff -Nru sqlite3-3.42.0/www/spellfix1.html sqlite3-3.44.0-0/www/spellfix1.html --- sqlite3-3.42.0/www/spellfix1.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/spellfix1.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
  • @@ -750,5 +726,4 @@

    The second and third forms return the computed edit distance between strings 'string1' and "string2'. In the second form, a language id of 0 is used. The language id is specified in the third form. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/sqlanalyze.html sqlite3-3.44.0-0/www/sqlanalyze.html --- sqlite3-3.42.0/www/sqlanalyze.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/sqlanalyze.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -1534,5 +1510,4 @@ INSERT INTO space_used VALUES('moz_keywords_placepostdata_uniqueindex','moz_keywords',1,0,0,1,0,0,0,0,0,1,0,0,32760,0,0,32768); COMMIT;
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/sqlar.html sqlite3-3.44.0-0/www/sqlar.html --- sqlite3-3.42.0/www/sqlar.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/sqlar.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -156,7 +132,7 @@

    1. Introduction

    -An "SQLite Archive" is a file container similar to a +An "SQLite Archive" is a file container similar to a ZIP archive or Tarball but based on an SQLite database. @@ -273,7 +249,7 @@

  • An SQLite Archive can work around firewall-imposed censorship. -For example, certain file types that are considered "dangerous" +For example, certain file types that are considered "dangerous" (examples: DLLs) will be blocked by Gmail and probably many other email services and firewalls, even if the @@ -324,7 +300,7 @@

    The recommended way of creating, updating, listing, and extracting -an SQLite Archive is to use the sqlite3.exe command-line shell +an SQLite Archive is to use the sqlite3.exe command-line shell for SQLite version 3.23.0 (2018-04-02) or later. This CLI supports the -A command-line option that allows easy management of SQLite Archives. @@ -374,7 +350,7 @@

    Just as there is the "zip" program to manage ZIP Archives, and the -"tar" program to manage Tarballs, the +"tar" program to manage Tarballs, the "sqlar" program exists to manage SQL Archives. The "sqlar" program is able to create a new SQLite Archive, list the content of an existing archive, add or remove files from the archive, @@ -386,7 +362,7 @@

    Applications can easily read or write SQLite Archives by linking against -SQLite and including the +SQLite and including the ext/misc/sqlar.c extension to handle the compression and decompression. The sqlar.c extension creates two new SQL functions. @@ -395,8 +371,8 @@

    sqlar_compress(X)

    The sqlar_compress(X) function attempts to compress a copy of the -blob X using the Default algorithm and returns the -result as a blob. If the input X is not a compressible blob, then +string or blob X using the Default algorithm and +returns the result as a blob. If the input X is incompressible, then a copy of X is returned. This routine is used when inserting content into an SQLite Archive.

    sqlar_uncompress(Y,SZ)
    @@ -439,4 +415,3 @@ and sqlar_uncompress() functions, and the sqlar.c extension is not required.

    - diff -Nru sqlite3-3.42.0/www/sqldiff.html sqlite3-3.44.0-0/www/sqldiff.html --- sqlite3-3.42.0/www/sqldiff.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/sqldiff.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
  • @@ -152,7 +128,7 @@

    The sqldiff.exe binary is a command-line utility program that -displays content differences between SQLite databases. Example +displays the differences between SQLite databases. Example usage:

    sqldiff [options] database1.sqlite database2.sqlite
    @@ -179,8 +155,7 @@
            pair rows in the source and destination database.  (See additional
            explanation below.)

    --schema
    -

    Show only column name and table differences in the schema, - not the table content

    +

    Show only differences in the schema not the table content

    --summary

    Show how many rows have changed on each table, but do not show the actual changes

    @@ -190,8 +165,8 @@
    --transaction

    Wrap SQL output in a single large transaction

    --vtab
    -

    Add support for handling FTS3, FTS5 and rtree virtual tables. - See below for details. +

    Add support for handling FTS3, FTS5 and rtree virtual tables. + See below for details.

    @@ -249,27 +224,14 @@
    sqldiff --changeset CHANGESET_OUT --table NilChangeset db1.sdb db2.sdb
     
    -will be to produce an empty file named "CHANGESET_OUT". See session limitations for details. +will be to produce an empty file named "CHANGESET_OUT". See session limitations for details.
  • The sqldiff.exe utility does not (currently) display differences in TRIGGERs or VIEWs. -

  • -The sqldiff utility is not designed to support schema migrations -and is forgiving with respect to differing column definitions. -Normally, only the column names and their order are compared -for like-named tables before content comparison proceeds. - -

    However, the single-table comparison option, with "sqlite_schema" -named, can be used to show or detect detailed schema differences -between a pair of databases. -When doing this, the output should not be used directly to modify a database. - - -

  • By default, differences in the schema or content of virtual tables are -not reported on. +not reported on.

    However, if a virtual table implementation creates real tables (sometimes referred to as "shadow" tables) within the database to store its data in, then @@ -279,10 +241,9 @@ bundled virtual tables (FTS3, FTS5, rtree and others), the surprising effects may include corruption of the virtual table content. -

    If the --vtab option is passed to sqldiff.exe, then it ignores all +

    If the --vtab option is passed to sqldiff.exe, then it ignores all underlying shadow tables belonging to an FTS3, FTS5 or rtree virtual table and instead includes the virtual table differences directly.

  • -

    This page last modified on 2023-01-06 00:45:39 UTC

    diff -Nru sqlite3-3.42.0/www/sqlite.css sqlite3-3.44.0-0/www/sqlite.css --- sqlite3-3.42.0/www/sqlite.css 2023-05-16 13:43:06.000000000 +0000 +++ sqlite3-3.44.0-0/www/sqlite.css 2023-11-04 14:24:20.000000000 +0000 @@ -240,9 +240,6 @@ max-width: 100%; } -/* Default fill and stroke for SVG paths */ -polygon { fill: black; stroke:#111111; stroke-width:1 } -path { fill: none; stroke:#111111; stroke-width:1 } .doccat a { color: #044a64 ; diff -Nru sqlite3-3.42.0/www/sqlite.css~ sqlite3-3.44.0-0/www/sqlite.css~ --- sqlite3-3.42.0/www/sqlite.css~ 2023-05-16 13:43:06.000000000 +0000 +++ sqlite3-3.44.0-0/www/sqlite.css~ 1970-01-01 00:00:00.000000000 +0000 @@ -1,281 +0,0 @@ -/* Style sheet for the SQLite Website and Documentation */ -* {box-sizing:border-box;} -@media screen and (max-width: 800px){ - body {margin: 2px;} -} -body { - margin-top: 0; - font-family: Verdana, sans-serif; -} - -/* Horizonal rules */ -.xhr { - color: #044a64; - height: 2px; -} - -/* Hyperlinks that look like buttons */ -.button { - background-color: #ddd; - border: 2px solid #aaa; - text-decoration: none; - border-radius: 4px; - padding: 0 1ex 0 1ex; - white-space: nowrap; - font-size: 90%; - line-height: 150%; - color: black; -} -.button:visited { - color: black; -} - -/* Sidebars on the right-hand side of the screen */ -.rightsidebar { - padding-right: 1ex; - margin: 1ex; - float: right; -} - -/* Border box */ -.border2px { - border: 2px solid #044a64; -} - -.hdrfont { - font-weight:bold; - font-size:115%; -} -.nounderline a { text-decoration: none } - -a { color: #044a64 } -a:visited { color: #734559 } - -.logo { float: left; margin:1px; } -.tagline { - float:right; - text-align:right; - font-style:italic; - width:300px; - margin:12px; - margin-top:58px; -} - -/* Style common to both the main and submenu */ -.menu::before { - content: ""; - clear: both; /* Clear the Logo and TagLine */ - display: block; -} -.menu ul { - margin: 0; - list-style-type: none; - padding: 0; - overflow: hidden; -} -.menu ul li { - color: white; -} -.menu ul li a { - display: block; - color: white; - text-align: center; - padding: 0.7ex 1.4ex; - text-decoration: none; -} - -/* Styling specific to the main menu */ -.mainmenu ul { - background-color: #044a64; - border-radius: 8px; -} -.mainmenu ul li { - float: left; -} -.mainmenu ul li.search { - float: right; -} - -/* Styling specific to the submenu */ -.submenu { - display: none; -} -.submenu ul { - color: white; -} -.submenu ul li { - float: none; - border-radius: 8px; - background-color: #0482c4; - border-top: 2px solid white; -} - -/* Styling for the search menu */ -.searchmenu { - width: 100%; - text-align: right; - display: none; - float: none; - padding: 1ex; - background-color: #0482c4; - border-radius: 8px; -} - -/* Add the "mobileonly" class to any elements that should be visible -** on narrow-screen mobile devices only */ -@media screen and (min-width: 600px){ - /* Settings for wide desktop screens */ - .mobileonly {display: none;} -} -/* Add the "desktoponly" class to any elements that should be visible -** on desktops with at least 600 pixels of horizontal space. */ -@media screen and (max-width: 600px){ - /* Settings for narrow mobile screens */ - .desktoponly {display: none;} -} -/* Add the "wideonly" class to any elements that should be visible -** on wide-screen desktops with */ -@media screen and (max-width: 800px){ - /* Settings for screens that are less than 800px wide */ - .wideonly {display: none;} -} - -.content { margin: 5%; } -.content dt { font-weight:bold; } -.content dd { margin-bottom: 25px; margin-left:20%; } -.content ul { padding:0px; padding-left: 15px; margin:0px; } - -/* Things for "fancyformat" documents start here. */ -.fancy img+p {font-style:italic} -.fancy .codeblock { - display: table; - border: 1px solid #80a796; - padding: 1ex; - background-color: #eee; -} -.fancy .codeblock pre { - display: table-cell; - font-size: 1em; -} -.fancy .codeblock i { color: darkblue; } -.fancy h1,.fancy h2,.fancy h3,.fancy h4 {font-weight:normal;color:#044a64} -.fancy th {text-align:left;border-bottom:solid 1px #444} -.fancy th, .fancy td {padding: 0.2em 1ex; vertical-align:top} -.toct { color: #044a64 ! important; } -#toc_sub a { color: #044a64; text-decoration: none } -#toc_sub { display: none; margin-top: 1em; } -.fancy .todo { color: #AA3333 ; font-style : italic } -.fancy .todo:before { content: 'TODO:' } -.fancy p.todo { border: solid #AA3333 1px; padding: 1ex } -.fancy img { display:block; } -.fancy :link:hover, .fancy :visited:hover { background: wheat } -.fancy_title { - font-size: 2em; - text-align: center; - color: #044a64; -} -.fancy_toc { - margin-top: 1em; -} -.fancy_toc > a { - margin: 1em; - margin-left: 0; - font-size: 1.5em; - color: #044a64; - text-decoration: none; - cursor: pointer; -} -@media screen and (min-width: 600px){ - /* Indentation amounts for non-mobile screens, 600 pixels or wider */ - .fancy p,.fancy ul,.fancy ol,.fancy dl { margin: 1em 5ex } - .fancy li p { margin: 1em 0 } - .fancy blockquote { margin-left : 10ex } - .toct {margin-left:4ex;} - .fancy-toc1 {margin-left:6ex;} - .fancy-toc2 {margin-left:12ex;} - .fancy-toc3 {margin-left:18ex;} - .fancy-toc4 {margin-left:24ex;} - .fancy-toc5 {margin-left:30ex;} - .fancy-toc6 {margin-left:36ex;} - .fancy .codeblock {margin:0 10ex;} - .fancy ol .codeblock {margin:0 5ex;} - .fancy .imgcontainer {margin: 1em 5ex} -} -@media screen and (max-width: 600px){ - /* Indentation amounts for narrow mobile screens */ - .toct {margin-left:0;} - .fancy-toc1 {padding-left:4ex;text-indent:-2ex;} - .fancy-toc2 {padding-left:8ex;text-indent:-4ex;} - .fancy-toc3 {padding-left:12ex;text-indent:-6ex;} - .fancy-toc4 {padding-left:16ex;text-indent:-8ex;} - .fancy-toc5 {padding-left:20ex;text-indent:-10ex;} - .fancy-toc6 {padding-left:24ex;text-indent:-12ex;} - .lessindent {padding-left: 1em; margin-left: 0;} - .fancy .codeblock {margin:0 1ex;} -} -/* End of "fancyformat" specific rules. */ - -/*
      elements used for multi-column lists */ -.multicol_list {padding-left:1em;margin-left:0;} - -.yyterm { - background: #fff; - border: 1px solid #000; - border-radius: 11px; - padding-left: 4px; - padding-right: 4px; - line-height: 125%; -} - -/* Container for an image */ -.imgcontainer img { - max-height: 100%; - max-width: 100%; -} - - -.doccat a { - color: #044a64 ; - text-decoration: none; -} -.doccat h { - font-weight: bold; -} -.doccat h a { - font-size: smaller; - color: black; -} -.doccat { - padding-left: 2ex; - padding-right: 2ex; - white-space:nowrap; -} -.doccat li { - list-style-type: none; - font-size: smaller; - line-height: 150%; -} -.doccat ul { - margin-top: 0.5em; -} - -.footer { - padding-top: 2px; - padding-bottom: 1px; - border-top: 2px solid #044a64; -} - -th.sort:after { - margin-left: .4em; - cursor: pointer; - text-shadow: 0 0 0 #000; /* Makes arrow darker */ -} -th.sort.none:after { - content: '\2666'; -} -th.sort.asc:after { - content: '\2193'; -} -th.sort.desc:after { - content: '\2191' -} diff -Nru sqlite3-3.42.0/www/stmt.html sqlite3-3.44.0-0/www/stmt.html --- sqlite3-3.42.0/www/stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -262,5 +238,4 @@ prepared statement. This field is equivalent to the SQLITE_STMTSTATUS_MEMUSED value.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/stricttables.html sqlite3-3.44.0-0/www/stricttables.html --- sqlite3-3.42.0/www/stricttables.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/stricttables.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,320 +0,0 @@ - - - - - -STRICT Tables - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -
    -
    -
    -STRICT Tables -
    -
    - - - - -

    1. Introduction

    - -

    SQLite strives to be flexible regarding the datatype of -the content that it stores. For example, if a table column has a type of -"INTEGER", then SQLite tries to convert anything inserted into that column -into an integer. So an attempt to insert the string '123' results -in an integer 123 being inserted. But if the content cannot be losslessly -converted into an integer, for example if the input is 'xyz', then -the original string is inserted instead. -See the Datatypes In SQLite document for additional information. - -

    Some developers appreciate the freedom that SQLite's flexible typing -rules provide and use that freedom to advantage. -But other developers are aghast at SQLite's -flagrant rule-breaking and prefer the traditional rigid type -system found in all other SQL database engines and in the -SQL standard. For this latter group, SQLite supports a strict typing -mode, as of version 3.37.0 (2021-11-27), that is enabled -separately for each table. - -

    2. STRICT Tables

    - -

    In a CREATE TABLE statement, if the "STRICT" table-option keyword is -added to the end, after the closing ")", then strict typing rules apply -to that table. -The STRICT keyword causes the following differences: - -

      -
    1. -Every column definition must specify a datatype for that column. -The freedom to specify a column without a datatype is removed. - -

    2. -The datatype must be one of following: -

        -
      • INT -
      • INTEGER -
      • REAL -
      • TEXT -
      • BLOB -
      • ANY -
      -

      No other datatype names are allowed, though new types might be added in -future releases of SQLite. - -

    3. -Content inserted into the column with a datatype other than ANY -must be either a NULL (assuming there -is no NOT NULL constraint on the column) or the type specified. -SQLite attempts to coerce the data into the appropriate type using the usual -affinity rules, as PostgreSQL, MySQL, SQL Server, -and Oracle all do. If the value cannot be -losslessly converted in the specified datatype, then an -SQLITE_CONSTRAINT_DATATYPE error is raised. - -

    4. -Columns with datatype ANY can accept any kind of data (except they will -reject NULL values if they have a NOT NULL constraint, of course). No -type coercion occurs for a column of type ANY in a STRICT table. - -

    5. -Columns that are part of the PRIMARY KEY are implicitly NOT NULL. -However, even though the PRIMARY KEY has an implicit NOT NULL constraint, -when a NULL value is inserted into an INTEGER PRIMARY KEY column, the -NULL is automatically converted into a unique integer, using the same -rules for INTEGER PRIMARY KEY on ordinary, non-strict tables. - -

    6. -The PRAGMA integrity_check and PRAGMA quick_check commands check the -type of the content of all columns in STRICT tables and show errors if -anything is amiss. -

    - -

    -Everything else about a STRICT table works the same as it does in an -ordinary non-strict table: - -

    - -

    3. The ANY datatype

    - -

    The ability to host any type of data in a single column has proven to -be remarkably useful over the years. In order to continue supporting this -ability, even in STRICT tables, the new ANY datatype name is introduced. -When the datatype of a column is "ANY", that means that any kind of data - -integers, floating point values, strings, or binary blobs, can be inserted -into that table and its value and datatype will be preserved exactly as -it is inserted. As far as we know, SQLite is the only SQL database engine -that supports this advanced capability. - -

    The behavior of ANY is slightly different in a -STRICT table versus an ordinary non-strict table. In a STRICT table, -a column of type ANY always preserves the data exactly as it is received. -For an ordinary non-strict table, a column of type ANY will attempt to -convert strings that look like numbers into a numeric value, and if -successful will store the numeric value rather than the original string. -For example: - -

    - -
    STRICTordinary non-strict -
    CREATE TABLE t1(a ANY) STRICT;
    -INSERT INTO t1 VALUES('000123');
    -SELECT typeof(a), quote(a) FROM t1;
    --- result: text '000123'
    -
    -CREATE TABLE t1(a ANY);
    -INSERT INTO t1 VALUES('000123');
    -SELECT typeof(a), quote(a) FROM t1;
    --- result: integer 123
    -
    -
    - -

    4. Backwards Compatibility

    - -

    The STRICT keyword at the end of a CREATE TABLE statement is only -recognized by SQLite version 3.37.0 (2021-11-27) and later. If -you try to open a database containing the STRICT keyword in an earlier -version of SQLite, it will not recognize the keyword and will report -an error (except as noted below). But apart from the extra STRICT keyword, -the underlying file format of the database is identical. - -

    Thus, in general, a database file that contains one or more STRICT -tables can only be read and written by SQLite version 3.37.0 or later. -However, a database created by SQLite 3.37.0 or later can still be -read and written by earlier versions of SQLite, going all the way back -to version 3.0.0 (2004-06-18) as long as the database does not contain -any STRICT tables or other features that were introduced after the older -version of SQLite. - -

    The STRICT keyword may still be used as an identifier. -(It is only treated as a keyword in a certain part of the syntax, -and sqlite3_keyword_check(..) does not recognize it as a regular keyword.) - -

    4.1. Accessing STRICT tables in earlier versions of SQLite

    - -

    Because of a quirk in the SQL language parser, versions of SQLite prior -to 3.37.0 can still read and write STRICT tables if they set -"PRAGMA writable_schema=ON" immediately after opening the database -file, prior to doing anything else that requires knowing the schema. -One of the features of PRAGMA writable_schema=ON is that it disables -errors in the schema parser. This is intentional, because a big reason for -having PRAGMA writable_schema=ON is to facilitate recovery of database files -with corrupt schemas. So with writable_schema=ON, when the schema -parser reaches the STRICT keyword, it says to itself "I don't know what -to do with this, but everything up to this point seems like a valid -table definition so I'll just use what I have." Hence, the STRICT -keyword is effectively ignored. Because nothing else about the file -format changes for STRICT tables, everything else will work normally. -Of course, rigid type enforcement will not occur because the earlier -versions of SQLite do not know how to do that. - -

    The .dump command in the CLI sets PRAGMA writable_schema=ON, because -.dump is designed to extract as much content as it can even from a corrupt -database file. Hence, if you are using an older version of SQLite and -you open a database with STRICT tables in the CLI and issue the ".dump" -command before doing anything else, you will be able to read and write -to the STRICT tables without rigid type enforcement. This could, potentially, -corrupt the database, by allowing incorrect types into STRICT tables. -Reopening the database with a newer version of SQLite and running -"PRAGMA quick_check" will detect and report all such corruption. - -

    5. Other Table Options

    - -

    The SQLite parser accepts a comma-separated list of table options after -the final close parenthesis in a CREATE TABLE statement. As of this -writing (2021-08-23) only two options are recognized: - -

    - -

    If there are multiple options, they can be specified in any order. -To keep things simple, the current parser accepts duplicate options without -complaining, but that might change in future releases, so applications -should not rely on it. -

    This page last modified on 2022-04-18 02:55:50 UTC

    - diff -Nru sqlite3-3.42.0/www/support.html sqlite3-3.44.0-0/www/support.html --- sqlite3-3.42.0/www/support.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/support.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -188,5 +164,4 @@

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/swarmvtab.html sqlite3-3.44.0-0/www/swarmvtab.html --- sqlite3-3.42.0/www/swarmvtab.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/swarmvtab.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -425,5 +401,4 @@

    as required. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/syntax/aggregate-function-invocation.html sqlite3-3.44.0-0/www/syntax/aggregate-function-invocation.html --- sqlite3-3.42.0/www/syntax/aggregate-function-invocation.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/aggregate-function-invocation.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    aggregate-function-invocation

    @@ -184,4 +160,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/alter-table-stmt.html sqlite3-3.44.0-0/www/syntax/alter-table-stmt.html --- sqlite3-3.42.0/www/syntax/alter-table-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/alter-table-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    alter-table-stmt

    @@ -246,4 +222,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/analyze-stmt.html sqlite3-3.44.0-0/www/syntax/analyze-stmt.html --- sqlite3-3.42.0/www/syntax/analyze-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/analyze-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    analyze-stmt

    @@ -167,4 +143,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/attach-stmt.html sqlite3-3.44.0-0/www/syntax/attach-stmt.html --- sqlite3-3.42.0/www/syntax/attach-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/attach-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    attach-stmt

    @@ -156,4 +132,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/begin-stmt.html sqlite3-3.44.0-0/www/syntax/begin-stmt.html --- sqlite3-3.42.0/www/syntax/begin-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/begin-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    begin-stmt

    @@ -166,4 +142,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/column-constraint.html sqlite3-3.44.0-0/www/syntax/column-constraint.html --- sqlite3-3.42.0/www/syntax/column-constraint.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/column-constraint.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    column-constraint

    @@ -327,4 +303,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/column-def.html sqlite3-3.44.0-0/www/syntax/column-def.html --- sqlite3-3.42.0/www/syntax/column-def.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/column-def.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    column-def

    @@ -154,4 +130,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/column-name-list.html sqlite3-3.44.0-0/www/syntax/column-name-list.html --- sqlite3-3.42.0/www/syntax/column-name-list.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/column-name-list.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    column-name-list

    @@ -150,4 +126,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/comment-syntax.html sqlite3-3.44.0-0/www/syntax/comment-syntax.html --- sqlite3-3.42.0/www/syntax/comment-syntax.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/comment-syntax.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    comment-syntax

    @@ -175,4 +151,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/commit-stmt.html sqlite3-3.44.0-0/www/syntax/commit-stmt.html --- sqlite3-3.42.0/www/syntax/commit-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/commit-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    commit-stmt

    @@ -151,4 +127,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/common-table-expression.html sqlite3-3.44.0-0/www/syntax/common-table-expression.html --- sqlite3-3.42.0/www/syntax/common-table-expression.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/common-table-expression.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    common-table-expression

    @@ -191,4 +167,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/compound-operator.html sqlite3-3.44.0-0/www/syntax/compound-operator.html --- sqlite3-3.42.0/www/syntax/compound-operator.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/compound-operator.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    compound-operator

    @@ -161,4 +137,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/compound-select-stmt.html sqlite3-3.44.0-0/www/syntax/compound-select-stmt.html --- sqlite3-3.42.0/www/syntax/compound-select-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/compound-select-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    compound-select-stmt

    @@ -260,4 +236,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/conflict-clause.html sqlite3-3.44.0-0/www/syntax/conflict-clause.html --- sqlite3-3.42.0/www/syntax/conflict-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/conflict-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    conflict-clause

    @@ -177,4 +153,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/create-index-stmt.html sqlite3-3.44.0-0/www/syntax/create-index-stmt.html --- sqlite3-3.42.0/www/syntax/create-index-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/create-index-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    create-index-stmt

    @@ -216,4 +192,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/create-table-stmt.html sqlite3-3.44.0-0/www/syntax/create-table-stmt.html --- sqlite3-3.42.0/www/syntax/create-table-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/create-table-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    create-table-stmt

    -
    +
    @@ -189,10 +165,14 @@ , ) - - - -table-options + + + +WITHOUT + + + +ROWID , @@ -205,13 +185,12 @@ - - - - - - - + + + + + + @@ -222,14 +201,13 @@ select-stmt - +

    Used by:   sql-stmt

    -References:   column-def   select-stmt   table-constraint   table-options

    +References:   column-def   select-stmt   table-constraint

    See also:   lang_createtable.html
    - diff -Nru sqlite3-3.42.0/www/syntax/create-trigger-stmt.html sqlite3-3.44.0-0/www/syntax/create-trigger-stmt.html --- sqlite3-3.42.0/www/syntax/create-trigger-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/create-trigger-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    create-trigger-stmt

    @@ -324,4 +300,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/create-view-stmt.html sqlite3-3.44.0-0/www/syntax/create-view-stmt.html --- sqlite3-3.42.0/www/syntax/create-view-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/create-view-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    create-view-stmt

    @@ -211,4 +187,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/create-virtual-table-stmt.html sqlite3-3.44.0-0/www/syntax/create-virtual-table-stmt.html --- sqlite3-3.42.0/www/syntax/create-virtual-table-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/create-virtual-table-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    create-virtual-table-stmt

    @@ -204,4 +180,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/cte-table-name.html sqlite3-3.44.0-0/www/syntax/cte-table-name.html --- sqlite3-3.42.0/www/syntax/cte-table-name.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/cte-table-name.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    cte-table-name

    @@ -154,4 +130,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/delete-stmt.html sqlite3-3.44.0-0/www/syntax/delete-stmt.html --- sqlite3-3.42.0/www/syntax/delete-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/delete-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    delete-stmt

    @@ -189,4 +165,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/delete-stmt-limited.html sqlite3-3.44.0-0/www/syntax/delete-stmt-limited.html --- sqlite3-3.42.0/www/syntax/delete-stmt-limited.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/delete-stmt-limited.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    delete-stmt-limited

    @@ -224,6 +200,9 @@ + + + @@ -246,4 +225,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/detach-stmt.html sqlite3-3.44.0-0/www/syntax/detach-stmt.html --- sqlite3-3.42.0/www/syntax/detach-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/detach-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    detach-stmt

    @@ -145,4 +121,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/drop-index-stmt.html sqlite3-3.44.0-0/www/syntax/drop-index-stmt.html --- sqlite3-3.42.0/www/syntax/drop-index-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/drop-index-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    drop-index-stmt

    @@ -164,4 +140,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/drop-table-stmt.html sqlite3-3.44.0-0/www/syntax/drop-table-stmt.html --- sqlite3-3.42.0/www/syntax/drop-table-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/drop-table-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    drop-table-stmt

    @@ -164,4 +140,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/drop-trigger-stmt.html sqlite3-3.44.0-0/www/syntax/drop-trigger-stmt.html --- sqlite3-3.42.0/www/syntax/drop-trigger-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/drop-trigger-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    drop-trigger-stmt

    @@ -164,4 +140,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/drop-view-stmt.html sqlite3-3.44.0-0/www/syntax/drop-view-stmt.html --- sqlite3-3.42.0/www/syntax/drop-view-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/drop-view-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    drop-view-stmt

    @@ -164,4 +140,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/expr.html sqlite3-3.44.0-0/www/syntax/expr.html --- sqlite3-3.42.0/www/syntax/expr.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/expr.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    expr

    @@ -326,8 +302,6 @@ REGEXP MATCH - -expr expr @@ -352,24 +326,20 @@ - - - - + + - + - + + - - - expr @@ -412,25 +382,14 @@ NOT - - - -DISTINCT - - - -FROM - - - -expr + +expr - + - expr @@ -628,4 +587,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/factored-select-stmt.html sqlite3-3.44.0-0/www/syntax/factored-select-stmt.html --- sqlite3-3.42.0/www/syntax/factored-select-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/factored-select-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    factored-select-stmt

    @@ -227,4 +203,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/filter-clause.html sqlite3-3.44.0-0/www/syntax/filter-clause.html --- sqlite3-3.42.0/www/syntax/filter-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/filter-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    filter-clause

    @@ -151,4 +127,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/foreign-key-clause.html sqlite3-3.44.0-0/www/syntax/foreign-key-clause.html --- sqlite3-3.42.0/www/syntax/foreign-key-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/foreign-key-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    foreign-key-clause

    @@ -264,4 +240,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/frame-spec.html sqlite3-3.44.0-0/www/syntax/frame-spec.html --- sqlite3-3.42.0/www/syntax/frame-spec.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/frame-spec.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    frame-spec

    @@ -330,4 +306,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/indexed-column.html sqlite3-3.44.0-0/www/syntax/indexed-column.html --- sqlite3-3.42.0/www/syntax/indexed-column.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/indexed-column.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    indexed-column

    @@ -170,4 +146,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/insert-stmt.html sqlite3-3.44.0-0/www/syntax/insert-stmt.html --- sqlite3-3.42.0/www/syntax/insert-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/insert-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    insert-stmt

    @@ -330,4 +306,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/join-clause.html sqlite3-3.44.0-0/www/syntax/join-clause.html --- sqlite3-3.42.0/www/syntax/join-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/join-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    join-clause

    @@ -153,4 +129,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/join-constraint.html sqlite3-3.44.0-0/www/syntax/join-constraint.html --- sqlite3-3.42.0/www/syntax/join-constraint.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/join-constraint.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    join-constraint

    @@ -168,4 +144,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/join-operator.html sqlite3-3.44.0-0/www/syntax/join-operator.html --- sqlite3-3.42.0/www/syntax/join-operator.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/join-operator.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    join-operator

    -
    +
    @@ -129,55 +105,49 @@ LEFT - - - -OUTER - - - - - -JOIN - - - - -, - - - + + + +OUTER + + + + + +JOIN + + + + +, + + + - - - - - - -RIGHT - - - - - -FULL - - - - -INNER - - - - - - -CROSS - - - + + + + + + + + + + + +INNER + + + + + + +CROSS + + +

    @@ -186,4 +156,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/literal-value.html sqlite3-3.44.0-0/www/syntax/literal-value.html --- sqlite3-3.42.0/www/syntax/literal-value.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/literal-value.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    literal-value

    @@ -190,4 +166,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/numeric-literal.html sqlite3-3.44.0-0/www/syntax/numeric-literal.html --- sqlite3-3.42.0/www/syntax/numeric-literal.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/numeric-literal.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    numeric-literal

    @@ -217,4 +193,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/ordering-term.html sqlite3-3.44.0-0/www/syntax/ordering-term.html --- sqlite3-3.42.0/www/syntax/ordering-term.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/ordering-term.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    ordering-term

    @@ -181,4 +157,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/over-clause.html sqlite3-3.44.0-0/www/syntax/over-clause.html --- sqlite3-3.42.0/www/syntax/over-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/over-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    over-clause

    @@ -213,4 +189,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/pragma-stmt.html sqlite3-3.44.0-0/www/syntax/pragma-stmt.html --- sqlite3-3.42.0/www/syntax/pragma-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/pragma-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    pragma-stmt

    @@ -176,4 +152,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/pragma-value.html sqlite3-3.44.0-0/www/syntax/pragma-value.html --- sqlite3-3.42.0/www/syntax/pragma-value.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/pragma-value.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    pragma-value

    @@ -149,4 +125,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/qualified-table-name.html sqlite3-3.44.0-0/www/syntax/qualified-table-name.html --- sqlite3-3.42.0/www/syntax/qualified-table-name.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/qualified-table-name.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    qualified-table-name

    @@ -188,4 +164,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/raise-function.html sqlite3-3.44.0-0/www/syntax/raise-function.html --- sqlite3-3.42.0/www/syntax/raise-function.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/raise-function.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    raise-function

    @@ -175,4 +151,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/recursive-cte.html sqlite3-3.44.0-0/www/syntax/recursive-cte.html --- sqlite3-3.42.0/www/syntax/recursive-cte.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/recursive-cte.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    recursive-cte

    @@ -167,4 +143,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/reindex-stmt.html sqlite3-3.44.0-0/www/syntax/reindex-stmt.html --- sqlite3-3.42.0/www/syntax/reindex-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/reindex-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    reindex-stmt

    @@ -170,4 +146,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/release-stmt.html sqlite3-3.44.0-0/www/syntax/release-stmt.html --- sqlite3-3.42.0/www/syntax/release-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/release-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    release-stmt

    @@ -145,4 +121,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/result-column.html sqlite3-3.44.0-0/www/syntax/result-column.html --- sqlite3-3.42.0/www/syntax/result-column.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/result-column.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    result-column

    @@ -173,4 +149,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/returning-clause.html sqlite3-3.44.0-0/www/syntax/returning-clause.html --- sqlite3-3.42.0/www/syntax/returning-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/returning-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    returning-clause

    @@ -170,4 +146,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/rollback-stmt.html sqlite3-3.44.0-0/www/syntax/rollback-stmt.html --- sqlite3-3.42.0/www/syntax/rollback-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/rollback-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    rollback-stmt

    @@ -159,4 +135,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/savepoint-stmt.html sqlite3-3.44.0-0/www/syntax/savepoint-stmt.html --- sqlite3-3.42.0/www/syntax/savepoint-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/savepoint-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    savepoint-stmt

    @@ -138,4 +114,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/select-core.html sqlite3-3.44.0-0/www/syntax/select-core.html --- sqlite3-3.42.0/www/syntax/select-core.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/select-core.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,35 +89,11 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    select-core

    -
    +
    @@ -187,109 +163,105 @@ - -GROUP - - - -BY - - - -expr - - - -HAVING - - - -expr - -, - - - - - - - - - - + +GROUP + + + +BY + + + +expr + + + +HAVING + + + +expr + +, + + + + + + - - + + - - -WINDOW - - - -window-name - - - -AS - - - -window-defn - -, - - - - - - - - - - - - - - - - - - - - -VALUES - - - -( - - - -expr - - - -) - - - - - - -, - -, - - - - - - - - + + +WINDOW + + + +window-name + + + +AS + + + +window-defn + +, + + + + + + + + + + + + + + + + + + + + +VALUES + + + +( + + + +expr + + + +) + + + + + + +, + +, + + + + + + + +

    @@ -299,4 +271,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/select-stmt.html sqlite3-3.44.0-0/www/syntax/select-stmt.html --- sqlite3-3.42.0/www/syntax/select-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/select-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,36 +89,12 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    select-stmt

    -
    - +
    + @@ -217,180 +193,176 @@ - -GROUP - - - -BY - - - -expr - - - -HAVING - - - -expr - -, - - - - - - - - - - + +GROUP + + + +BY + + + +expr + + + +HAVING + + + +expr + +, + + + + + + - - + + - - -WINDOW - - - -window-name - - - -AS - - - -window-defn - -, - - - - - - - - - - - - - - - - - - - -VALUES - - - -( - - - -expr - - - -) - - - - -, - -, - - - - - - - - - -compound-operator - - + + +WINDOW + + + +window-name + + + +AS + + + +window-defn + +, + + + + + + + + + + + + + + + + + + + +VALUES + + + +( + + + +expr + + + +) + + + + +, + +, + + + + + + + + + +compound-operator + + - + -select-core - -ORDER - - - -BY - -LIMIT - - - -expr - - - -ordering-term - -, - - - - - - - - - - - - - - - - - -OFFSET - - - -expr - - - -, - - - -expr - - - - - - - - - - - - - - - - - - +select-core + +ORDER + + + +BY + +LIMIT + + + +expr + + + +ordering-term + +, + + + + + + + + + + + + + + + + + +OFFSET + + + +expr + + + +, + + + +expr + + + + + + + + + + + + + + + + + +

    @@ -400,4 +372,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/signed-number.html sqlite3-3.44.0-0/www/syntax/signed-number.html --- sqlite3-3.42.0/www/syntax/signed-number.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/signed-number.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    signed-number

    @@ -146,4 +122,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/simple-function-invocation.html sqlite3-3.44.0-0/www/syntax/simple-function-invocation.html --- sqlite3-3.42.0/www/syntax/simple-function-invocation.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/simple-function-invocation.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    simple-function-invocation

    @@ -159,4 +135,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/simple-select-stmt.html sqlite3-3.44.0-0/www/syntax/simple-select-stmt.html --- sqlite3-3.42.0/www/syntax/simple-select-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/simple-select-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    simple-select-stmt

    @@ -220,4 +196,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/sql-stmt.html sqlite3-3.44.0-0/www/syntax/sql-stmt.html --- sqlite3-3.42.0/www/syntax/sql-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/sql-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    sql-stmt

    @@ -337,4 +313,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/sql-stmt-list.html sqlite3-3.44.0-0/www/syntax/sql-stmt-list.html --- sqlite3-3.42.0/www/syntax/sql-stmt-list.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/sql-stmt-list.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    sql-stmt-list

    @@ -144,4 +120,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/table-constraint.html sqlite3-3.44.0-0/www/syntax/table-constraint.html --- sqlite3-3.42.0/www/syntax/table-constraint.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/table-constraint.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    table-constraint

    @@ -229,4 +205,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/table-options.html sqlite3-3.44.0-0/www/syntax/table-options.html --- sqlite3-3.42.0/www/syntax/table-options.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/table-options.html 1970-01-01 00:00:00.000000000 +0000 @@ -1,153 +0,0 @@ - - - - - -SQLite Syntax: table-options - - - -
    - - - -
    -
    -Small. Fast. Reliable.
    Choose any three. -
    - - -
    -
    - - - -
    -
    -
    - -

    table-options

    -
    -
    - - - - -WITHOUT - - - -ROWID - - - - - -STRICT - - - - - -, - - - - -

    - -Used by:   create-table-stmt

    -See also:   lang_createtable.html -
    - - - diff -Nru sqlite3-3.42.0/www/syntax/table-or-subquery.html sqlite3-3.44.0-0/www/syntax/table-or-subquery.html --- sqlite3-3.42.0/www/syntax/table-or-subquery.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/table-or-subquery.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    table-or-subquery

    @@ -265,4 +241,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/type-name.html sqlite3-3.44.0-0/www/syntax/type-name.html --- sqlite3-3.42.0/www/syntax/type-name.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/type-name.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    type-name

    @@ -176,4 +152,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/update-stmt.html sqlite3-3.44.0-0/www/syntax/update-stmt.html --- sqlite3-3.42.0/www/syntax/update-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/update-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    update-stmt

    @@ -291,4 +267,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/update-stmt-limited.html sqlite3-3.44.0-0/www/syntax/update-stmt-limited.html --- sqlite3-3.42.0/www/syntax/update-stmt-limited.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/update-stmt-limited.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    update-stmt-limited

    @@ -350,4 +326,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/upsert-clause.html sqlite3-3.44.0-0/www/syntax/upsert-clause.html --- sqlite3-3.42.0/www/syntax/upsert-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/upsert-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    upsert-clause

    @@ -230,4 +206,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/vacuum-stmt.html sqlite3-3.44.0-0/www/syntax/vacuum-stmt.html --- sqlite3-3.42.0/www/syntax/vacuum-stmt.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/vacuum-stmt.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    vacuum-stmt

    @@ -149,4 +125,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/window-defn.html sqlite3-3.44.0-0/www/syntax/window-defn.html --- sqlite3-3.42.0/www/syntax/window-defn.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/window-defn.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    window-defn

    @@ -202,4 +178,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/window-function-invocation.html sqlite3-3.44.0-0/www/syntax/window-function-invocation.html --- sqlite3-3.42.0/www/syntax/window-function-invocation.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/window-function-invocation.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    window-function-invocation

    @@ -177,4 +153,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntax/with-clause.html sqlite3-3.44.0-0/www/syntax/with-clause.html --- sqlite3-3.42.0/www/syntax/with-clause.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax/with-clause.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    with-clause

    @@ -183,4 +159,3 @@
    - diff -Nru sqlite3-3.42.0/www/syntaxdiagrams.html sqlite3-3.44.0-0/www/syntaxdiagrams.html --- sqlite3-3.42.0/www/syntaxdiagrams.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntaxdiagrams.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -1247,7 +1223,7 @@

    create-table-stmt:

    -
    +
    @@ -1319,10 +1295,14 @@ , ) - - - -table-options + + + +WITHOUT + + + +ROWID , @@ -1335,13 +1315,12 @@ - - - - - - - + + + + + + @@ -1352,12 +1331,12 @@ select-stmt - +
    Used by:   sql-stmt

    -References:   column-def   select-stmt   table-constraint   table-options

    +References:   column-def   select-stmt   table-constraint

    See also:   lang_createtable.html
    @@ -1966,6 +1945,9 @@ + + + @@ -2413,8 +2395,6 @@ REGEXP MATCH - -expr expr @@ -2439,24 +2419,20 @@ - - - - + + - + - + + - - - expr @@ -2499,25 +2475,14 @@ NOT - - - -DISTINCT - - - -FROM - - - -expr + +expr - + - expr @@ -3572,7 +3537,7 @@

    join-operator:

    -
    +
    @@ -3584,60 +3549,54 @@ LEFT - - - -OUTER - - - - - -JOIN - - - - -, - - - + + + +OUTER + + + + + +JOIN + + + + +, + + + - - - - - - -RIGHT - - - - - -FULL - - - - -INNER - - - - - - -CROSS - - - + + + + + + + + + + + +INNER + + + + + + +CROSS + + +
    Used by:   join-clause

    -See also:   lang_aggfunc.html   lang_altertable.html   lang_attach.html   lang_createindex.html   lang_createtable.html   lang_createtrigger.html   lang_createview.html   lang_delete.html   lang_expr.html   lang_insert.html   lang_returning.html   lang_select.html   lang_select.html#compound   lang_select.html#fromclause   lang_select.html#nonstd   lang_select.html#simpleselect   lang_update.html   lang_upsert.html   lang_with.html   partialindex.html +See also:   lang_aggfunc.html   lang_altertable.html   lang_attach.html   lang_createindex.html   lang_createtable.html   lang_createtrigger.html   lang_createview.html   lang_delete.html   lang_expr.html   lang_insert.html   lang_returning.html   lang_select.html   lang_select.html#compound   lang_select.html#fromclause   lang_select.html#simpleselect   lang_update.html   lang_upsert.html   lang_with.html   partialindex.html

    literal-value:

    @@ -4497,7 +4456,7 @@

    select-core:

    -
    +
    @@ -4567,109 +4526,105 @@ - -GROUP - - - -BY - - - -expr - - - -HAVING - - - -expr - -, - - - - - - - - - - + +GROUP + + + +BY + + + +expr + + + +HAVING + + + +expr + +, + + + + + + - - + + - - -WINDOW - - - -window-name - - - -AS - - - -window-defn - -, - - - - - - - - - - - - - - - - - - - - -VALUES - - - -( - - - -expr - - - -) - - - - - - -, - -, - - - - - - - - + + +WINDOW + + + +window-name + + + +AS + + + +window-defn + +, + + + + + + + + + + + + + + + + + + + + +VALUES + + + +( + + + +expr + + + +) + + + + + + +, + +, + + + + + + + +
    @@ -4679,8 +4634,8 @@

    select-stmt:

    -
    - +
    + @@ -4779,180 +4734,176 @@ - -GROUP - - - -BY - - - -expr - - - -HAVING - - - -expr - -, - - - - - - - - - - + +GROUP + + + +BY + + + +expr + + + +HAVING + + + +expr + +, + + + + + + - - + + - - -WINDOW - - - -window-name - - - -AS - - - -window-defn - -, - - - - - - - - - - - - - - - - - - - -VALUES - - - -( - - - -expr - - - -) - - - - -, - -, - - - - - - - - - -compound-operator - - + + +WINDOW + + + +window-name + + + +AS + + + +window-defn + +, + + + + + + + + + + + + + + + + + + + +VALUES + + + +( + + + +expr + + + +) + + + + +, + +, + + + + + + + + + +compound-operator + + - + -select-core - -ORDER - - - -BY - -LIMIT - - - -expr - - - -ordering-term - -, - - - - - - - - - - - - - - - - - -OFFSET - - - -expr - - - -, - - - -expr - - - - - - - - - - - - - - - - - - +select-core + +ORDER + + + +BY + +LIMIT + + + +expr + + + +ordering-term + +, + + + + + + + + + + + + + + + + + +OFFSET + + + +expr + + + +, + + + +expr + + + + + + + + + + + + + + + + + +
    @@ -5494,39 +5445,6 @@ See also:   lang_createtable.html   lang_createtable.html#primkeyconst   lang_createtable.html#tablecoldef   lang_createtable.html#uniqueconst
    -

    table-options:

    -
    - - - - -WITHOUT - - - -ROWID - - - - - -STRICT - - - - - -, - - - - -
    - -Used by:   create-table-stmt

    -See also:   lang_createtable.html -
    -

    table-or-subquery:

    @@ -6497,5 +6415,4 @@ See also:   lang_with.html
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/syntax.html sqlite3-3.44.0-0/www/syntax.html --- sqlite3-3.42.0/www/syntax.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/syntax.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    List of SQLite Syntax Diagrams

    @@ -181,7 +157,6 @@
  • sql-stmt
  • sql-stmt-list
  • table-constraint
  • -
  • table-options
  • table-or-subquery
  • type-name
  • update-stmt
  • @@ -195,4 +170,3 @@
    - diff -Nru sqlite3-3.42.0/www/tclsqlite.html sqlite3-3.44.0-0/www/tclsqlite.html --- sqlite3-3.42.0/www/tclsqlite.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/tclsqlite.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -138,35 +114,27 @@ one command, the interface is not placed in a separate namespace.

    -

    The sqlite3 command is mostly used as follows -to open or create a database:

    +

    The sqlite3 command is used as follows:

    -sqlite3  dbcmd  ?database-name?  ?options? +sqlite3  dbcmd  database-name  ?options?
    -

    To get information only, the sqlite3 command may be given exactly -one argument, either "-version", "-sourceid" or "-has-codec", which will -return the specified datum with no other effect. -

    - -

    With other arguments, the sqlite3 command opens the database -named in the second non-option argument, or named "" if there is no such. -If the open succeeds, a new Tcl command named by the first argument is created -and "" is returned. -(This approach is similar to the way widgets are created in Tk.) -If the open fails, an error is raised without creating a Tcl command -and an error message string is returned. -

    -

    If the database does not already exist, the default behavior +

    +The sqlite3 command opens the database named in the second +argument. If the database does not already exist, the default behavior is for it to be created automatically (though this can be changed by -using the "-create false" option). +using the "-create false" option). +The sqlite3 command always creates a new Tcl +command to control the database. The name of the new Tcl command +is given by the first argument. This approach is similar to the +way widgets are created in Tk.

    The name of the database is usually just the name of a disk file in which -the database is stored. If the name of the database is -the special name ":memory:", then a new database is created +the database is stored. If the name of the database is +the special name ":memory:" then a new database is created in memory. If the name of the database is an empty string, then the database is created in an empty file that is automatically deleted when the database connection closes. URI filenames can be used if @@ -217,28 +185,13 @@ Use an alternative VFS named by the argument.

    -
    -fullmutex BOOLEAN
    -

    -If true, multiple threads can safely attempt to use the database. -If false, such attempts are unsafe. The default value depends upon -how the extension is built. -

    - -
    -nofollow BOOLEAN
    -

    -If true, and the database name refers to a symbolic link, -it will not be followed to open the true database file. -If false, symbolic links will be followed. -The default is "false". -

    -

    -Once an SQLite database is open, it can be controlled using +Once an SQLite database is open, it can be controlled using methods of the dbcmd. There are currently 40 methods defined.

    @@ -307,7 +260,7 @@ like this:

    -dbcmd  eval  ?-withoutnulls?  sql +dbcmd  eval  ?options?  sql   ?array-name?  ?script?
    @@ -451,14 +404,14 @@ db1 eval {INSERT INTO t1 VALUES(5,:bigstring)}
    -

    The use of ":" instead of "$" before the name of a variable can +

    The use of ":" instead of "$" before the name of a variable can sometimes be useful if the SQL text is enclosed in double-quotes "..." -instead of curly-braces {...}. +instead of curly-braces {...}. When the SQL is contained within double-quotes "..." then TCL will do the substitution of $-variables, which can lead to SQL injection if extreme care is not used. But TCL will never substitute a :-variable -regardless of whether double-quotes "..." or curly-braces {...} are -used to enclose the SQL, so the use of :-variables adds an extra +regardless of whether double-quotes "..." or curly-braces {...} are +used to enclose the SQL, so the use of :-variables adds an extra measure of defense against SQL injection.

    @@ -532,7 +485,7 @@

    The "eval" method described above keeps a cache of prepared statements -for recently evaluated SQL commands. +for recently evaluated SQL commands. The "cache" method is used to control this cache. The first form of this command is:

    @@ -551,7 +504,7 @@ dbcmd  cache flush
    -

    The cache-flush method +

    The cache-flush method finalizes all prepared statements currently in the cache.

    @@ -567,7 +520,7 @@

    The "complete" method is useful when building interactive applications in order to know when the user has finished entering a line of SQL code. -This is really just an interface to the +This is really just an interface to the sqlite3_complete() C function. @@ -598,7 +551,7 @@ application security. Turning off the trust_schema setting prevents virtual tables and dodgy SQL functions from being used inside of triggers, views, CHECK constraints, generated columns, and expression indexes. -Turning off the dqs_dml and dqs_ddl settings prevents the use of +Turning off the dqs_dml and dqs_ddl settings prevents the use of double-quoted strings. Turning on defensive prevents direct writes to shadow tables. @@ -627,8 +580,8 @@

    Conflict-algorithm must be one of the SQLite conflict algorithms for the INSERT statement: rollback, abort, fail,ignore, or replace. See the SQLite Language -section for ON CONFLICT for -more information. The conflict-algorithm must be specified in lower case. +section for ON CONFLICT for more information. +The conflict-algorithm must be specified in lower case.

    Table-name must already exists as a table. File-name must exist, and @@ -646,7 +599,7 @@ precede the null-indicator argument.

    The copy method implements similar functionality to the .import -SQLite shell command. +SQLite shell command.

    The "timeout" method

    @@ -686,7 +639,7 @@ database. A single integer argument is appended to the callback before it is invoke. The argument is the number of prior calls to the busy callback for the current locking event. It is intended that -the callback will do some other useful work for a short while +the callback will do some other useful work for a short while (such as service GUI events) then return so that the lock can be tried again. The callback procedure should return "0" if it wants SQLite to try again to open the database and @@ -708,7 +661,7 @@

    This method takes a single boolean argument which will turn the extension loading functionality on or off.

    -

    For best security, do not use this method unless truly needed, +

    For best security, do not use this method unless truly needed, and run PRAGMA trusted_schema=OFF or the "db config trusted_schema 0" method before invoking this method. @@ -752,20 +705,9 @@

    For security reasons, it is recommended that applications first set -PRAGMA trusted_schema=OFF or run the +PRAGMA trusted_schema=OFF or run the "db config trusted_schema 0" -method before using this method.

    - -

    -The syntax looks like this: -

    - -
    -dbcmd  function -  sql-name -  ?options? -  script -
    +method before using this method.

    The following example creates a new SQL function named "hex" that converts @@ -789,7 +731,7 @@

    This option indicates that the function will always return the same answer given the same argument values. The SQLite query optimizer -uses this information to cache answers from function calls with +uses this information to cache answers from function calls with constant inputs and reuse the result rather than invoke the function repeatedly.

    @@ -862,7 +804,7 @@

    The "onecolumn" method

    -

    The "onecolumn" method works like +

    The "onecolumn" method works like "eval" in that it evaluates the SQL query statement given as its argument. The difference is that "onecolumn" returns a single element which is the first column of the @@ -889,7 +831,7 @@

    The "authorizer" method

    -

    The "authorizer" method provides access to the +

    The "authorizer" method provides access to the sqlite3_set_authorizer C/C++ interface. The argument to authorizer is the name of a procedure that is called when SQL statements are being compiled in order to authorize @@ -924,8 +866,8 @@

    The "bind_fallback" method has a single optional argument. If the argument is an empty string, then the bind_fallback is cancelled and the default behavior is restored. If the argument is a non-empty string, then the argument is a -TCL command (usually the name of a proc) to invoke whenever an SQL parameter -is seen that does not match any TCL variable. If the "bind_fallback" method +TCL command (usually the name of a proc) to invoke whenever an SQL parameter +is seen that does not match any TCL variable. If the "bind_fallback" method is given no arguments, then the current bind_fallback command is returned.

    As an example, the following setup causes TCL to throw an error if @@ -1009,7 +951,7 @@

    The "update_hook" method

    -

    This method registers a callback routine that is invoked just after +

    This method registers a callback routine that is invoked just before each row is modified by an UPDATE, INSERT, or DELETE statement. Four arguments are appended to the callback before it is invoked:

    @@ -1019,56 +961,6 @@
  • The table that is being changed
  • The rowid of the row in the table being changed
  • - -

    The callback must not do anything that will modify the database connection -that invoked the update hook such as running queries.

    - -

    The "preupdate" method

    - - -

    This method either registers a callback routine that is invoked just -before each row is modified by an UPDATE, INSERT, or DELETE statement, -or may perform certain operations related to the impending update.

    - -

    To register or remove a preupdate callback, use this syntax: -

    -dbcmd  preupdate  hook  ?SCRIPT? -
    -When a preupdate callback is registered, then prior to each row modification, -the callback is run with these arguments: -
      -
    • The keyword "INSERT", "UPDATE", or "DELETE", as appropriate
    • -
    • The name of the database which is being changed
    • -
    • The table that is being changed
    • -
    • The original rowid of the row in the table being changed
    • -
    • The new rowid (if any) of the row in the table being changed
    • -
    -The callback must not do anything that will modify the database connection -that invoked the preupdate hook such as running queries.

    - -

    When the callback is executing, and only then, these preupdate operations -may be performed by use of the indicated syntax: -

    -dbcmd  preupdate  count
    -dbcmd  preupdate  depth
    -dbcmd  preupdate  new  INDEX
    -dbcmd  preupdate  old  INDEX
    -
    -

    - -

    The count submethod returns the number of columns in the row that is -being inserted, updated, or deleted.

    -

    The depth submethod returns the update nesting depth. This will be -0 for a direct insert, update, or delete operation; -1 for inserts, updates, or deletes invoked by top-level triggers; -or higher values for changes resulting from trigger-invoked triggers.

    - -

    The old and new submethods return the selected original -or changed column value respectively of the row being updated.

    - -

    Note that the Tcl interface (and underlying SQLite library) must have -been built with the preprocessor symbol SQLITE_ENABLE_PREUPDATE_HOOK -defined for the preupdate method to be available.

    The "wal_hook" method

    @@ -1088,7 +980,7 @@ set up an explicit WAL hook, then that one WAL hook must ensure that checkpoints are occurring since the auto-checkpointing mechanism will be disabled.

    -

    This method should return an integer value that is equivalent to an +

    This method should return an integer value that is equivalent to an SQLite error code (usually 0 for SQLITE_OK in the case of success or 1 for SQLITE_ERROR if some error occurs). As in sqlite3_wal_hook(), the results of returning an integer that does not correspond to an SQLite error code are @@ -1109,7 +1001,7 @@

    The command returns a new TCL channel for reading or writing to the BLOB. -The channel is opened using the underlying +The channel is opened using the underlying sqlite3_blob_open() C-language interface. Close the channel using the close command of TCL.

    @@ -1208,7 +1100,7 @@

    The "restore" method

    -

    The "restore" method copies the content from a separate database file +

    The "restore" method copies the content from a separate database file into the current database connection, overwriting any preexisting content. The command syntax is like this:

    @@ -1217,8 +1109,8 @@

    The optional target-database argument tells which database in -the current connection should be overwritten with new content. -The default value is main +the current connection should be overwritten with new content. +The default value is main (or, in other words, the primary database file). To repopulate the TEMP tables use temp. To overwrite an auxiliary database added to the connection using the ATTACH command, use the name of that database as it was assigned @@ -1294,8 +1186,8 @@

    A database handle may only have a single profile script registered at any time. If there is already a script registered when the profile method -is invoked, the previous profile script is replaced by the new one. If the -script argument is an empty string, any previously registered +is invoked, the previous profile script is replaced by the new one. If the +script argument is an empty string, any previously registered profile callback is canceled but no new profile script is registered.

    @@ -1307,4 +1199,3 @@

    - diff -Nru sqlite3-3.42.0/www/tempfiles.html sqlite3-3.44.0-0/www/tempfiles.html --- sqlite3-3.42.0/www/tempfiles.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/tempfiles.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -876,5 +852,4 @@ in this case, though presumably the GetTempPath() system call does. The search algorithm is different for CYGWIN builds. Check the source code for details. -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/testing.html sqlite3-3.44.0-0/www/testing.html --- sqlite3-3.42.0/www/testing.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/testing.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -192,15 +168,15 @@

    The reliability and robustness of SQLite is achieved in part by thorough and careful testing.

    -

    As of version 3.42.0 (2023-05-16), +

    As of version 3.33.0 (2020-08-14), the SQLite library consists of approximately -155.8 KSLOC of C code. +143.4 KSLOC of C code. (KSLOC means thousands of "Source Lines Of Code" or, in other words, lines of code excluding blank lines and comments.) By comparison, the project has -590 times as much -test code and test scripts - -92053.1 KSLOC.

    +640 times as much +test code and test scripts - +91911.0 KSLOC.

    1.1. Executive Summary

    @@ -226,7 +202,7 @@

    2. Test Harnesses

    -

    There are four independent test harnesses used for testing the +

    There are four independent test harnesses used for testing the core SQLite library. Each test harness is designed, maintained, and managed separately from the others. @@ -236,17 +212,17 @@

  • -The TCL Tests are the original tests for SQLite. +The TCL Tests are the oldest set of tests for SQLite. They are contained in the same source tree as the SQLite core and like the SQLite core are in the public domain. The TCL tests are the primary tests used during development. -The TCL tests are written using the +The TCL tests are written using the TCL scripting language. -The TCL test harness itself consists of 27.2 KSLOC +The TCL test harness itself consists of 27.0 KSLOC of C code used to create the TCL interface. The test scripts are contained -in 1390 files totaling -23.2MB in size. There are -51445 distinct test cases, but many of the test +in 1272 files totaling +21.1MB in size. There are +46363 distinct test cases, but many of the test cases are parameterized and run multiple times (with different parameters) so that on a full test run millions of separate tests are performed. @@ -255,21 +231,19 @@

  • The TH3 test harness is a set of proprietary tests, written in -C that provide 100% branch test coverage +C that provide 100% branch test coverage (and 100% MC/DC test coverage) to the core SQLite library. The TH3 tests are designed to run on embedded and specialized platforms that would not easily support -TCL or other workstation services. TH3 tests use only the published +TCL or other workstation services. TH3 tests use only the published SQLite interfaces. TH3 consists of about -76.9 MB or 1055.4 KSLOC -of C code implementing 50362 distinct test cases. +71.5 MB or 978.3 KSLOC +of C code implementing 46622 distinct test cases. TH3 tests are heavily parameterized, though, so a full-coverage test runs -about 2.4 million different test -instances. -The cases that provide 100% branch test coverage constitute +about 1.9 million different test +instances. The cases that provide 100% branch test coverage constitute a subset of the total TH3 test suite. A soak test -prior to release does about -248.5 million tests. +prior to release does hundreds of millions of tests. Additional information on TH3 is available separately.

  • @@ -286,15 +260,16 @@

  • The dbsqlfuzz engine is a -proprietary fuzz tester. Other fuzzers for SQLite +proprietary fuzz tester. Other fuzzers for SQLite mutate either the SQL inputs or the database file. Dbsqlfuzz mutates both the SQL and the database file at the same time, and is thus able to reach new error states. Dbsqlfuzz is built using the libFuzzer framework of LLVM -with a custom mutator. There are -336 seed files. The dbsqlfuzz fuzzer -runs about one billion test mutations per day. -Dbsqlfuzz helps ensure +with a custom mutator. Starting from +252 seed files, the dbsqlfuzz fuzzer +has tried literally billions of mutations, resulting in +58497 distinct test cases that form +the basis of each new fuzzing session. Dbsqlfuzz helps ensure that SQLite is robust against attack via malicious SQL or database inputs.

  • @@ -302,12 +277,12 @@

    In addition to the four main test harnesses, there several other small programs that implement specialized tests.

      -
    1. The "speedtest1.c" program -estimates the performance of SQLite under a typical workload. -
    2. The "mptester.c" program is a stress test for multiple processes +
    3. The "speedtest1.c" program +estimates the performance of SQLite under a typical workload. +
    4. The "mptester.c" program is a stress test for multiple processes concurrently reading and writing a single database.
    5. The "threadtest3.c" program is a stress test for multiple threads using -SQLite simultaneously. +SQLite simultaneously.
    6. The "fuzzershell.c" program is used to run some fuzz tests.
    @@ -319,9 +294,9 @@

    Prior to each check-in to the SQLite source tree, developers typically run a subset (called "veryquick") of the Tcl tests -consisting of about -304.7 thousand test cases. -The veryquick tests include most tests other than the anomaly, fuzz, and +consisting of about +248.5 thousand test cases. +The veryquick tests include most tests other than the anomaly, fuzz, and soak tests. The idea behind the veryquick tests are that they are sufficient to catch most errors, but also run in only a few minutes instead of a few hours.

    @@ -356,7 +331,7 @@ SQLite allows an application to substitute an alternative malloc() implementation using the sqlite3_config(SQLITE_CONFIG_MALLOC,...) interface. The TCL and TH3 test harnesses are both capable of -inserting a modified version of malloc() that can be rigged to fail +inserting a modified version of malloc() that can be rigged to fail after a certain number of allocations. These instrumented mallocs can be set to fail only once and then start working again, or to continue failing after the first failure. OOM tests are done in a @@ -378,8 +353,8 @@

    I/O error testing seeks to verify that SQLite responds sanely to failed I/O operations. I/O errors might result from a full disk drive, malfunctioning disk hardware, network outages when using a network -file system, system configuration or permission changes that occur in the -middle of an SQL operation, or other hardware or operating system +file system, system configuration or permission changes that occur in the +middle of an SQL operation, or other hardware or operating system malfunctions. Whatever the cause, it is important that SQLite be able to respond correctly to these errors and I/O error testing seeks to verify that it does.

    @@ -496,7 +471,7 @@

    AFL proved adept at finding arcane bugs in SQLite. Most of the findings have been assert() statements where the conditional was false under obscure circumstances. But AFL has also found -a fair number of crash bugs in SQLite, and even a few cases where SQLite +a fair number of crash bugs in SQLite, and even a few cases where SQLite computed incorrect results.

    Because of its past success, AFL became a standard part of the testing @@ -508,7 +483,7 @@

    4.1.2. Google OSS Fuzz

    Beginning in 2016, a team of engineers at Google started the -OSS Fuzz project. +OSS Fuzz project. OSS Fuzz uses a AFL-style guided fuzzer running on Google's infrastructure. The Fuzzer automatically downloads the latest check-ins for participating projects, fuzzes them, and sends email to the developers reporting any @@ -531,7 +506,7 @@

    4.1.3. The dbsqlfuzz fuzzer

    Beginning in late 2018, SQLite has been fuzzed using a proprietary -fuzzer called "dbsqlfuzz". Dbsqlfuzz is built using the +fuzzer called "dbsqlfuzz". Dbsqlfuzz is built using the libFuzzer framework of LLVM.

    The dbsqlfuzz fuzzer mutates both the SQL input and the database file @@ -542,15 +517,13 @@ database and the input SQL at the same time, dbsqlfuzz has been able to find some obscure faults in SQLite that were missed by prior fuzzers that mutated only SQL inputs or only the database file. -The SQLite developers keep dbsqlfuzz running against trunk in about -16 cores at all times. Each instance of dbsqlfuzz program is able to -evalutes about 400 test cases per second, meaning that about 500 million -cases are checked every day.

    - -

    The dbsqlfuzz fuzzer has been very successful at hardening the -SQLite code base against malicious attack. Since dbsqlfuzz has been -added to the SQLite internal test suite, bug reports from external -fuzzers such as OSSFuzz have all but stopped. +The SQLite developers usually leave an instance or two of dbsqlfuzz +running on the latest trunk code of SQLite whenever they are away from +the office for an extended period, such as overnight.

    + +

    The dbsqlfuzz fuzzer has been so successful at hardening the +SQLite code base against malicious attack that it is now considered +one of the four primary test harnesses for SQLite.

    Note that dbsqlfuzz is not the Protobuf-based structure-aware fuzzer for SQLite that is used by Chromium and described in the @@ -575,7 +548,7 @@ Linus's law: "given enough eyeballs, all bugs are shallow". -

    One fuzzing researcher of particular note is +

    One fuzzing researcher of particular note is Manuel Rigger, currently (as this paragraph is written on 2019-12-21) at ETH Zurich. @@ -605,7 +578,7 @@ examined over the years. "Interesting" cases are cases that exhibit previously unseen behavior. Actual bugs found by fuzzers are always included among the interesting test cases, but most of the cases run -by fuzzcheck were never actual bugs. +by fuzzcheck were never actual bugs. @@ -615,7 +588,7 @@ one another. That is to say, code tested to 100% MC/DC will tend to be more vulnerable to problems found by fuzzing and code that performs -well during fuzz testing will tend to have (much) less than +well during fuzz testing will tend to have (much) less than 100% MC/DC. This is because MC/DC testing discourages defensive code with unreachable branches, but without defensive code, a fuzzer is @@ -627,14 +600,14 @@

    Of course, users would prefer code that is both robust in normal use and resistant to malicious attack. The SQLite developers are dedicated to providing that. The purpose of this section is merely -to point out that doing both at the same time is difficult. +to point out that doing both at the same time is hard.

    For much of its history SQLite has been focused on 100% MC/DC testing. Resistance to fuzzing attacks only became a concern with the introduction of AFL in 2014. For a while there, fuzzers were finding many problems in SQLite. In more recent years, the testing strategy of SQLite has evolved to place more emphasis on fuzz testing. We still maintain -100% MC/DC of the core SQLite code, but most testing CPU cycles are +100% MC/DC of the core SQLite code, but most testing CPU cycles are now devoted to fuzzing.

    While fuzz testing and 100% MC/DC testing are in tension, they @@ -668,7 +641,7 @@

    4.3. Boundary Value Tests

    SQLite defines certain limits on its operation, such as the -maximum number of columns in a table, the maximum length of an +maximum number of columns in a table, the maximum length of an SQL statement, or the maximum value of an integer. The TCL and TH3 test suites both contains numerous tests that push SQLite right to the edge of its defined limits and verify that it performs correctly for @@ -682,7 +655,7 @@

    5. Regression Testing

    Whenever a bug is reported against SQLite, that bug is not considered -fixed until new test cases that would exhibit the bug have been added +fixed until new test cases that would exhibit the bug have been added to either the TCL or TH3 test suites. Over the years, this has resulted in thousands and thousands of new tests. @@ -773,7 +746,7 @@

    A well-written C program will typically contain some defensive conditionals which in practice are always true or always false. -This leads to a +This leads to a programming dilemma: Does one remove defensive code in order to obtain 100% branch coverage?

    @@ -828,7 +801,7 @@

    But in a coverage measuring build, the testcase() macro -generates code that evaluates the conditional expression in its argument. +generates code that evaluates the conditional expression in its argument. Then during analysis, a check is made to ensure tests exist that evaluate the conditional to both true and false. Testcase() macros are used, for example, to help verify @@ -858,7 +831,7 @@

    For bitmask tests, testcase() macros are used to verify that every bit of the bitmask affects the outcome. For example, in the following block of code, the condition is true if the mask contains either of two bits -indicating either a MAIN_DB or a TEMP_DB is being opened. +indicating either a MAIN_DB or a TEMP_DB is being opened. The testcase() macros that precede the if statement verify that both cases are tested:

    @@ -867,7 +840,7 @@ if( (mask & (SQLITE_OPEN_MAIN_DB|SQLITE_OPEN_TEMP_DB))!=0 ){ ... }
    -

    The SQLite source code contains 1184 +

    The SQLite source code contains 1084 uses of the testcase() macro.

    @@ -877,7 +850,7 @@

    Two methods of measuring test coverage were described above: "statement" and "branch" coverage. There are many other test coverage metrics besides these two. Another popular metric is "Modified -Condition/Decision Coverage" or MC/DC. +Condition/Decision Coverage" or MC/DC. Wikipedia defines MC/DC as follows:

    @@ -889,7 +862,7 @@ affect the outcome of the decision. -

    In the C programming language +

    In the C programming language where && and || are "short-circuit" operators, MC/DC and branch coverage are very nearly the same thing. The primary difference is in boolean vector tests. @@ -910,15 +883,15 @@ option. First the test program is compiled using options "-g -fprofile-arcs -ftest-coverage" and then the test program is run. Then "gcov -b" is run to generate a coverage report. -The coverage report is verbose and inconvenient to read, +The coverage report is verbose and inconvenient to read, so the gcov-generated report is processed using some simple scripts to put it into a more human-friendly format. This entire process is automated using scripts, of course.

    Note that running SQLite with gcov is not a test of SQLite — it is a test of the test suite. The gcov run does not test SQLite because -the -fprofile-args and -ftest-coverage options cause the compiler to -generate different code. +the -fprofile-args and -ftest-coverage options cause the compiler to +generate different code. The gcov run merely verifies that the test suite provides 100% branch test coverage. The gcov run is a test of the test - a meta-test. @@ -928,10 +901,10 @@ and the test program is rerun. This second run is the actual test of SQLite. -

    It is important to verify that the gcov test run +

    It is important to verify that the gcov test run and the second real test run both give the same output. Any differences in output indicate either the use of undefined or -indeterminate behavior in the SQLite code (and hence a bug), +indeterminate behavior in the SQLite code (and hence a bug), or a bug in the compiler. Note that SQLite has, over the previous decade, encountered bugs in each of GCC, Clang, and MSVC. Compiler bugs, while rare, do happen, @@ -945,11 +918,11 @@

    Using gcov (or similar) to show that every branch instruction is taken at least once in both directions is good measure of test suite quality. But even better is showing that every branch instruction makes -a difference in the output. In other words, we want to show +a difference in the output. In other words, we want to show not only that every branch instruction both jumps and falls through but also that every branch is doing useful work and that the test suite is able to detect and verify that work. When a branch is found that does not -make a difference in the output, that suggests that code associated with +make a difference in the output, that suggests that the code associated the branch can be removed (reducing the size of the library and perhaps making it run faster) or that the test suite is inadequately testing the feature that the branch implements. @@ -959,15 +932,15 @@ A script first compiles the SQLite source code into assembly language (using, for example, the -S option to gcc). Then the script steps through -the generated assembly language and, one by one, changes each branch -instruction into either an unconditional jump or a no-op, compiles the +the generated assembly language and, one by one, changes each branch +instruction into either an unconditional jump or a no-op, compiles the result, and verifies that the test suite catches the mutation.

    Unfortunately, SQLite contains many branch instructions that help the code run faster without changing the output. Such branches generate false-positives during mutation testing. -As an example, consider the following +As an example, consider the following hash function used to accelerate table-name lookup: @@ -989,7 +962,7 @@ The problem is that 0 is a valid hash. A hash function that always returns 0 still works in the sense that SQLite still always gets the correct answer. The table-name hash table degenerates into a linked-list -and so the table-name lookups that occur while parsing SQL statements +and so the table-name lookups that occur while parsing SQL statements might be a little slower, but the end result will be the same.

    @@ -1011,7 +984,7 @@ do not have unintended consequences in other parts of the code. The many new features and performance improvements that have been added to SQLite in recent years would not have been possible without -the availability of full-coverage testing.

    +the availability full-coverage testing.

    Maintaining 100% MC/DC is laborious and time-consuming. The level of effort needed to maintain full-coverage testing @@ -1035,7 +1008,7 @@

    8.1. Assert

    -

    The SQLite core contains 6754 assert() +

    The SQLite core contains 5855 assert() statements that verify function preconditions and postconditions and loop invariants. Assert() is a macro which is a standard part of ANSI-C. The argument is a boolean value that is assumed to always be @@ -1046,7 +1019,7 @@ In most systems, asserts are enabled by default. But in SQLite, the asserts are so numerous and are in such performance critical places, that the database engine runs about three times slower when asserts are enabled. -Hence, the default (production) build of SQLite disables asserts. +Hence, the default (production) build of SQLite disables asserts. Assert statements are only enabled when SQLite is compiled with the SQLITE_DEBUG preprocessor macro defined.

    @@ -1061,7 +1034,7 @@ and useful developer tool in the world. Valgrind is a simulator - it simulates an x86 running a Linux binary. (Ports of Valgrind for platforms other than Linux are in development, but as of this writing, Valgrind only -works reliably on Linux, which in the opinion of the SQLite developers +works reliably on Linux, which in the opinion of the SQLite developers means that Linux should be the preferred platform for all software development.) As Valgrind runs a Linux binary, it looks for all kinds of interesting errors such as array overruns, reading from uninitialized memory, @@ -1071,7 +1044,7 @@ into a symbolic debugger at the exact point where the error occur, to facilitate a quick fix.

    -

    Because it is a simulator, running a binary in Valgrind is slower than +

    Because it is a simulator, running a binary in Valgrind is slower than running it on native hardware. (To a first approximation, an application running in Valgrind on a workstation will perform about the same as it would running natively on a smartphone.) So it is impractical to run the full @@ -1085,7 +1058,7 @@

    SQLite contains a pluggable memory allocation subsystem. -The default implementation uses system malloc() and free(). +The default implementation uses system malloc() and free(). However, if SQLite is compiled with SQLITE_MEMDEBUG, an alternative memory allocation wrapper (memsys2) is inserted that looks for memory allocation @@ -1100,7 +1073,7 @@

    8.4. Mutex Asserts

    -

    SQLite contains a pluggable mutex subsystem. Depending on +

    SQLite contains a pluggable mutex subsystem. Depending on compile-time options, the default mutex system contains interfaces sqlite3_mutex_held() and sqlite3_mutex_notheld() that detect whether or not a particular mutex is held by the calling thread. @@ -1136,7 +1109,7 @@ has "undefined" or "implementation defined" behavior. That means that the code might work during development, but then give a different answer on a different system, or when recompiled using different -compiler options. +compiler options. Examples of undefined and implementation-defined behavior in ANSI C include:

      @@ -1192,7 +1165,7 @@

      Not all test cases can be handled this way. Some test cases check to verify that the optimizations really are reducing the amount of -computation by counting the number of disk accesses, sort operations, +computation by counting the number of disk accesses, sort operations, full-scan steps, or other processing steps that occur during queries. Those test cases will appear to fail when optimizations are disabled. But the majority of test cases simply check that the correct answer @@ -1244,20 +1217,20 @@ check for correctness. Static analysis includes compiler warning messages and more in-depth analysis engines such as the Clang Static Analyzer. -SQLite compiles without warnings on GCC and Clang using +SQLite compiles without warnings on GCC and Clang using the -Wall and -Wextra flags on Linux and Mac and on MSVC on Windows. No valid warnings are generated by the Clang Static Analyzer tool "scan-build" either (though recent versions of clang seem to generate many false-positives.) Nevertheless, some warnings might be generated by other static analyzers. Users are encouraged not to stress over these warnings and to instead take solace in the intense testing of SQLite -described above. +described above.

      Static analysis has not been helpful in finding bugs in SQLite. Static analysis has found a few bugs in SQLite, but those are the exceptions. More bugs have been -introduced into SQLite while trying to get it to compile without +introduced into SQLite while trying to get it to compile without warnings than have been found by static analysis.

      @@ -1266,7 +1239,7 @@

      SQLite is open source. This gives many people the idea that it is not well tested as commercial software and is perhaps unreliable. -But that impression is false. +But that impression is false. SQLite has exhibited very high reliability in the field and a very low defect rate, especially considering how rapidly it is evolving. The quality of SQLite is achieved in part by careful code design and @@ -1275,5 +1248,4 @@ summarized the testing procedures that every release of SQLite undergoes with the hope of inspiring confidence that SQLite is suitable for use in mission-critical applications.

      -

      This page last modified on 2023-05-10 20:21:02 UTC

      diff -Nru sqlite3-3.42.0/www/th3.html sqlite3-3.44.0-0/www/th3.html --- sqlite3-3.42.0/www/th3.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/th3.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -566,5 +542,4 @@ of SQLite can deploy their application with the confidence of knowing that it has been tested using TH3. They simply cannot rerun those tests themselves without purchasing a TH3 license.

      -

      This page last modified on 2022-01-08 05:02:57 UTC

      diff -Nru sqlite3-3.42.0/www/threadsafe.html sqlite3-3.44.0-0/www/threadsafe.html --- sqlite3-3.42.0/www/threadsafe.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/threadsafe.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -162,7 +138,7 @@

      2. Compile-time selection of threading mode

      -Use the SQLITE_THREADSAFE compile-time parameter to select the +Use the SQLITE_THREADSAFE compile-time parameter to selected the threading mode. If no SQLITE_THREADSAFE compile-time parameter is present, then serialized mode is used. This can be made explicit with @@ -175,10 +151,15 @@

      -The return value of the sqlite3_threadsafe() interface is the value -of SQLITE_THREADSAFE set at compile-time. It does not reflect changes -to the threading mode made at runtime via the sqlite3_config() -interface or by flags given as the third argument to sqlite3_open_v2(). +The return value of the sqlite3_threadsafe() interface is determined +by the compile-time threading mode selection. If single-thread mode +is selected at compile-time, then sqlite3_threadsafe() returns false. +If either the multi-thread or serialized modes are selected, then +sqlite3_threadsafe() returns true. The sqlite3_threadsafe() +interface predates the multi-thread mode and start-time and run-time +mode selection and so is unable to distinguish +between multi-thread and serialized mode nor is it able to report start-time +or run-time mode changes.

      @@ -217,5 +198,4 @@ sqlite3_open_v2(), then the default mode determined by the compile-time and start-time settings is used.

      -

      This page last modified on 2022-04-18 02:55:50 UTC

      Binary files /tmp/tmpzdm9j_aj/x_36KoQHlP/sqlite3-3.42.0/www/toc.db and /tmp/tmpzdm9j_aj/4OSJ1hZg2o/sqlite3-3.44.0-0/www/toc.db differ diff -Nru sqlite3-3.42.0/www/transactional.html sqlite3-3.44.0-0/www/transactional.html --- sqlite3-3.42.0/www/transactional.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/transactional.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -153,5 +129,4 @@

      Additional information

      -

      This page last modified on 2022-01-08 05:02:57 UTC

      diff -Nru sqlite3-3.42.0/www/uintcseq.html sqlite3-3.44.0-0/www/uintcseq.html --- sqlite3-3.42.0/www/uintcseq.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/uintcseq.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
      @@ -189,5 +165,4 @@ 'abc674xyz'
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/undoredo.html sqlite3-3.44.0-0/www/undoredo.html --- sqlite3-3.42.0/www/undoredo.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/undoredo.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -253,7 +229,6 @@

    Example Code

    -
     # Everything goes in a private namespace
     namespace eval ::undo {
    @@ -297,9 +272,9 @@
     #
     proc freeze {} {
       variable _undo
    -  if {![info exists _undo(freeze)]} return
    +  if {!}; hd_resolve_one {info exists _undo(freeze)}; hd_puts {} return
       if {$_undo(freeze)>=0} {error "recursive call to ::undo::freeze"}
    -  set _undo(freeze) [db one {SELECT coalesce(max(seq),0) FROM undolog}]
    +  set _undo(freeze) }; hd_resolve_one {db one {SELECT coalesce(max(seq),0) FROM undolog}}; hd_puts {
     }
     
     # proc:  ::undo::unfreeze
    @@ -307,7 +282,7 @@
     #
     proc unfreeze {} {
       variable _undo
    -  if {![info exists _undo(freeze)]} return
    +  if {!}; hd_resolve_one {info exists _undo(freeze)}; hd_puts {} return
       if {$_undo(freeze)<0} {error "called ::undo::unfreeze while not frozen"}
       db eval "DELETE FROM undolog WHERE seq>$_undo(freeze)"
       set _undo(freeze) -1
    @@ -322,7 +297,7 @@
     proc event {} {
       variable _undo
       if {$_undo(pending)==""} {
    -    set _undo(pending) [after idle ::undo::barrier]
    +    set _undo(pending) }; hd_resolve_one {after idle ::undo::barrier}; hd_puts {
       }
     }
     
    @@ -337,7 +312,7 @@
         refresh
         return
       }
    -  set end [db one {SELECT coalesce(max(seq),0) FROM undolog}]
    +  set end }; hd_resolve_one {db one {SELECT coalesce(max(seq),0) FROM undolog}}; hd_puts {
       if {$_undo(freeze)>=0 && $end>$_undo(freeze)} {set end $_undo(freeze)}
       set begin $_undo(firstlog)
       _start_interval
    @@ -345,7 +320,7 @@
         refresh
         return
       }
    -  lappend _undo(undostack) [list $begin $end]
    +  lappend _undo(undostack) }; hd_resolve_one {list $begin $end}; hd_puts {
       set _undo(redostack) {}
       refresh
     }
    @@ -374,8 +349,8 @@
     #
     proc refresh {} {
       set body {}
    -  foreach ns [namespace children ::] {
    -    if {[info proc ${ns}::status_refresh]==""} continue
    +  foreach ns }; hd_resolve_one {namespace children ::}; hd_puts { {
    +    if {}; hd_resolve_one {info proc ${ns}::status_refresh}; hd_puts {==""} continue
         append body ${ns}::status_refresh\n
       }
       proc ::undo::refresh {} $body
    @@ -392,8 +367,8 @@
     #
     proc reload_all {} {
       set body {}
    -  foreach ns [namespace children ::] {
    -    if {[info proc ${ns}::reload]==""} continue
    +  foreach ns }; hd_resolve_one {namespace children ::}; hd_puts { {
    +    if {}; hd_resolve_one {info proc ${ns}::reload}; hd_puts {==""} continue
         append body ${ns}::reload\n
       }
       proc ::undo::reload_all {} $body
    @@ -420,14 +395,14 @@
     #
     proc status_refresh {} {
       variable _undo
    -  if {!$_undo(active) || [llength $_undo(undostack)]==0} {
    +  if {!$_undo(active) || }; hd_resolve_one {llength $_undo(undostack)}; hd_puts {==0} {
         .mb.edit entryconfig Undo -state disabled
         .bb.undo config -state disabled
       } else {
         .mb.edit entryconfig Undo -state normal
         .bb.undo config -state normal
       }
    -  if {!$_undo(active) || [llength $_undo(redostack)]==0} {
    +  if {!$_undo(active) || }; hd_resolve_one {llength $_undo(redostack)}; hd_puts {==0} {
         .mb.edit entryconfig Redo -state disabled
         .bb.redo config -state disabled
       } else {
    @@ -448,7 +423,7 @@
       catch {$db eval {DROP TABLE undolog}}
       $db eval {CREATE TEMP TABLE undolog(seq integer primary key, sql text)}
       foreach tbl $args {
    -    set collist [$db eval "pragma table_info($tbl)"]
    +    set collist }; hd_resolve_one {$db eval "pragma table_info($tbl)"}; hd_puts {
         set sql "CREATE TEMP TRIGGER _${tbl}_it AFTER INSERT ON $tbl BEGIN\n"
         append sql "  INSERT INTO undolog VALUES(NULL,"
         append sql "'DELETE FROM $tbl WHERE rowid='||new.rowid);\nEND;\n"
    @@ -479,10 +454,10 @@
     # title:  Drop all of the triggers that _create_triggers created
     #
     proc _drop_triggers {db} {
    -  set tlist [$db eval {SELECT name FROM sqlite_temp_schema
    -                       WHERE type='trigger'}]
    +  set tlist }; hd_resolve_one {$db eval {SELECT name FROM sqlite_temp_schema
    +                       WHERE type='trigger'}}; hd_puts {
       foreach trigger $tlist {
    -    if {![regexp {_.*_(i|u|d)t$} $trigger]} continue
    +    if {!}; hd_resolve_one {regexp {_.*_(i|u|d)t$} $trigger}; hd_puts {} continue
         $db eval "DROP TRIGGER $trigger;"
       }
       catch {$db eval {DROP TABLE undolog}}
    @@ -493,7 +468,7 @@
     #
     proc _start_interval {} {
       variable _undo
    -  set _undo(firstlog) [db one {SELECT coalesce(max(seq),0)+1 FROM undolog}]
    +  set _undo(firstlog) }; hd_resolve_one {db one {SELECT coalesce(max(seq),0)+1 FROM undolog}}; hd_puts {
     }
     
     # xproc: ::undo::_step V1 V2
    @@ -504,24 +479,24 @@
     #
     proc _step {v1 v2} {
       variable _undo
    -  set op [lindex $_undo($v1) end]
    -  set _undo($v1) [lrange $_undo($v1) 0 end-1]
    +  set op }; hd_resolve_one {lindex $_undo($v1) end}; hd_puts {
    +  set _undo($v1) }; hd_resolve_one {lrange $_undo($v1) 0 end-1}; hd_puts {
       foreach {begin end} $op break
       db eval BEGIN
       set q1 "SELECT sql FROM undolog WHERE seq>=$begin AND seq<=$end
               ORDER BY seq DESC"
    -  set sqllist [db eval $q1]
    +  set sqllist }; hd_resolve_one {db eval $q1}; hd_puts {
       db eval "DELETE FROM undolog WHERE seq>=$begin AND seq<=$end"
    -  set _undo(firstlog) [db one {SELECT coalesce(max(seq),0)+1 FROM undolog}]
    +  set _undo(firstlog) }; hd_resolve_one {db one {SELECT coalesce(max(seq),0)+1 FROM undolog}}; hd_puts {
       foreach sql $sqllist {
         db eval $sql
       }
       db eval COMMIT
       reload_all
     
    -  set end [db one {SELECT coalesce(max(seq),0) FROM undolog}]
    +  set end }; hd_resolve_one {db one {SELECT coalesce(max(seq),0) FROM undolog}}; hd_puts {
       set begin $_undo(firstlog)
    -  lappend _undo($v2) [list $begin $end]
    +  lappend _undo($v2) }; hd_resolve_one {list $begin $end}; hd_puts {
       _start_interval
       refresh
     }
    @@ -530,5 +505,4 @@
     # End of the ::undo namespace
     }
     
    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/unionvtab.html sqlite3-3.44.0-0/www/unionvtab.html --- sqlite3-3.42.0/www/unionvtab.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/unionvtab.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -234,5 +210,4 @@ The sqlite3_blob_open() interface does not work for a union-vtab. BLOB content must be read from the union-vtab using ordinary SQL statements.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/unlock_notify.html sqlite3-3.44.0-0/www/unlock_notify.html --- sqlite3-3.42.0/www/unlock_notify.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/unlock_notify.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -488,5 +464,4 @@ situation in question is not likely to occur often.
    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/uri.html sqlite3-3.44.0-0/www/uri.html --- sqlite3-3.42.0/www/uri.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/uri.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -136,7 +112,7 @@ either as an ordinary filename or as a Uniform Resource Identifier or URI. The advantage of using a URI filename is that query parameters on the URI can be used to control details of the newly created database connection. -For example, an alternative VFS can be specified using a +For example, an alternative VFS can be specified using a "vfs=" query parameter. Or the database can be opened read-only by using "mode=ro" as a query parameter. @@ -169,8 +145,8 @@ Since SQLite always interprets any filename that does not begin with "file:" as an ordinary filename regardless of the URI setting, and because it is -very unusual to have an actual file begin with "file:", -it is safe for most applications to enable URI processing even if URI +very unusual to have an actual file begin with "file:", +it is safe for most applications to enable URI processing even if URI filenames are not currently being used.

    @@ -186,17 +162,15 @@

    SQLite uses the "file:" URI syntax to identify database files. SQLite strives to interpret file: URIs in exactly the same way as -popular web-browsers such as -Firefox, -Chrome, -Safari, +popular web-browsers such as +Firefox, +Chrome, +Safari, Internet Explorer, and Opera, -and command-line programs such as Windows -"cmd start" -or -"powershell start", -or the macOS "open" or Linux "xdg-open" commands. +and command-line programs such as +Windows "start" and the Mac OS-X +"open" command. A succinct summary of the URI parsing rules follows:

    @@ -206,25 +180,25 @@
  • The authority may be omitted, may be blank, or may be "localhost". Any other authority results in an error. Exception: If SQLite is compiled with SQLITE_ALLOW_URI_AUTHORITY - then any authority value other than "localhost" is passed through to the + then any authority value other than "localhost" is passed through to the underlying operating system as a UNC filename.
  • The path is optional if the authority is present. If the authority - is omitted then the path is required. + is omitted then the path is required.
  • The query string is optional. If the query string is present, then all query parameters are passed through into the xOpen method of - the underlying VFS. + the underlying VFS.
  • The fragment is optional. If present, it is ignored.
  • -

    Zero or more escape sequences of the form "%HH" -(where H represents any hexadecimal digit) can occur +

    Zero or more escape sequences of the form "%HH" +(where H represents any hexadecimal digit) can occur in the path, query string, or fragment.

    A filename that is not a well-formed URI is interpreted as an ordinary filename.

    URIs are processed as UTF8 text. -The filename argument sqlite3_open16() is converted from UTF16 +The filename argument sqlite3_open16() is converted from UTF16 native byte order into UTF8 prior to processing.

    3.1. The URI Path

    @@ -233,7 +207,7 @@ SQLite database to be opened. If the path component is omitted, then the database is stored in a temporary file that will be automatically deleted when the database connection closes. If the authority section -is present, then the path is always an absolute pathname. If the +is present, then the path is always an absolute pathname. If the authority section is omitted, then the path is an absolute pathname if it begins with the "/" character (ASCII code 0x2f) and is a relative pathname otherwise. On windows, if the absolute path begins with @@ -242,7 +216,7 @@ is understood to be the drive letter of the volume containing the file, not the toplevel directory. -

    An ordinary filename can usually be converted into an equivalent URI +

    An ordinary filename can usually be converted into an equivalent URI by the steps shown below. The one exception is that a relative windows pathname with a drive letter cannot be converted directly into a URI; it must be changed into an absolute pathname first.

    @@ -288,14 +262,14 @@

    3.3. Recognized Query Parameters

    -Some query parameters are interpreted by the SQLite core and used to +Some query parameters are interpreted by the SQLite core and used to modify the characteristics of the new connection. All query parameters are always passed through into the xOpen method of the VFS even if they are previously read and interpreted by the SQLite core.

    -The following query parameters are recognized by SQLite as of +The following query parameters are recognized by SQLite as of version 3.15.0 (2016-10-14). New query parameters might be added in the future.

    @@ -313,13 +287,13 @@
    immutable=1

    The immutable query parameter is a boolean that signals to SQLite that the underlying database file is held on read-only media -and cannot be modified, even by another process with elevated +and cannot be modified, even by another process with elevated privileges. SQLite always opens immutable database files read-only and it skips all file locking and change detection -on immutable database files. If this query parameter (or +on immutable database files. If these query parameter (or the SQLITE_IOCAP_IMMUTABLE bit in xDeviceCharacteristics) -asserts that a database file is immutable and that file -changes anyhow, then SQLite might return incorrect query +asserts that a database file is immutable and that file +changes anyhow, then SQLite might return incorrect query results and/or SQLITE_CORRUPT errors.

    @@ -347,7 +321,7 @@ to the xLock, xUnlock, and xCheckReservedLock methods of the VFS when true. The nolock query parameter might be used, for example, when trying to access a file on a filesystem that does not support file locking. -Caution: If two or more database connections try to interact with +Caution: If two or more database connections try to interact with the same SQLite database and one or more of those connections has enabled "nolock", then database corruption can result. The "nolock" query parameter should only be used if the application can guarantee @@ -378,5 +352,4 @@
  • URI filenames in sqlite3_open()
  • URI filename examples
  • -

    This page last modified on 2023-01-02 14:22:42 UTC

    diff -Nru sqlite3-3.42.0/www/useovernet.html sqlite3-3.44.0-0/www/useovernet.html --- sqlite3-3.42.0/www/useovernet.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/useovernet.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -259,15 +235,8 @@ is hard, and safeguards are sometimes relaxed in favor of performance.

    - A similar hazard arises with file locking in network filesystems. - SQLite relies on exclusive locks for write operations, and those have - been known to operate incorrectly for some network filesystems. This - has led to database corruption. That may happen again as the designers - of such change their implementation to suit more common use cases. -

    -

    - The bottom line is that network filesystem sync and locking reliability - vary among implementations and installations. The design + The bottom line is that network filesystem sync reliability + varies among implementations and installations. The design assumptions upon which it relies may hold more true where an application is tested than where it is relied upon. Rely upon it at your (and your customers') peril. @@ -361,5 +330,4 @@ situations, but a client/server solution will usually work better in that scenario.

    -

    This page last modified on 2022-06-22 21:14:29 UTC

    diff -Nru sqlite3-3.42.0/www/vdbe.html sqlite3-3.44.0-0/www/vdbe.html --- sqlite3-3.42.0/www/vdbe.html 2023-05-16 13:43:14.000000000 +0000 +++ sqlite3-3.44.0-0/www/vdbe.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    The Virtual Database Engine of SQLite

    @@ -1809,5 +1785,4 @@ drh@hwaci.com. Your bug fixes or suggestions are always welcomed.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/version3.html sqlite3-3.44.0-0/www/version3.html --- sqlite3-3.42.0/www/version3.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/version3.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +

    @@ -414,5 +390,4 @@ SQLite version 3.0 is made possible in part by AOL developers supporting and embracing great Open-Source Software.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/versionnumbers.html sqlite3-3.44.0-0/www/versionnumbers.html --- sqlite3-3.42.0/www/versionnumbers.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/versionnumbers.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -213,5 +189,4 @@
  • Chronology
  • Change log
  • -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/vfs.html sqlite3-3.44.0-0/www/vfs.html --- sqlite3-3.42.0/www/vfs.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/vfs.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -361,10 +337,10 @@ appendvfs.c - This VFS allows an SQLite database to be appended to the end of some other file. This can be used, for example, to append an SQLite database -onto the end of an executable such that, when run, it can easily -locate the appended database. The command-line shell will use this -VFS if launched with the --append option, and its .archive command -will use it given the --append flag. +onto the end of an executable such that the executable where it can +then be easily located by the executable when needed. The +command-line shell will use this VFS if launched with the --append +option.

  • test_demovfs.c - @@ -489,5 +465,4 @@ sqlite3_vfs and the sqlite3_file object points to an instance of the sqlite3_io_methods object.

    -

    This page last modified on 2022-04-18 02:55:50 UTC

    diff -Nru sqlite3-3.42.0/www/vtab.html sqlite3-3.44.0-0/www/vtab.html --- sqlite3-3.42.0/www/vtab.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/vtab.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
  • @@ -142,13 +118,8 @@ - - - - - @@ -248,8 +219,8 @@

    A virtual table is created using a CREATE VIRTUAL TABLE statement.

    create-virtual-table-stmt: -

    -
    +

    +
    @@ -336,7 +307,7 @@

    The CREATE VIRTUAL TABLE statement creates a new table called table-name derived from the class -module-name. The module-name +class module-name. The module-name is the name that is registered for the virtual table by the sqlite3_create_module() interface. @@ -552,7 +523,7 @@ int (*xFindFunction)(sqlite3_vtab *pVtab, int nArg, const char *zName, void (**pxFunc)(sqlite3_context*,int,sqlite3_value**), void **ppArg); - int (*xRename)(sqlite3_vtab *pVtab, const char *zNew); + int (*Rename)(sqlite3_vtab *pVtab, const char *zNew); /* The methods above are in version 1 of the sqlite_module object. Those ** below are for version 2 and greater. */ int (*xSavepoint)(sqlite3_vtab *pVTab, int); @@ -616,7 +587,7 @@ other custom virtual tables.

  • series.c → Implementation of the generate_series() table-valued function. -
  • json.c → +
  • json1.c → Contains the sources for the json_each() and json_tree() table-valued functions.
  • csv.c → @@ -663,8 +634,7 @@ module name is the name provided as the second argument to sqlite3_create_module() and as the argument to the USING clause of the CREATE VIRTUAL TABLE statement that is running. -The second, argv[1], is the name of the database in which the new virtual -table is being created. The database name is "main" for the primary database, or +The second, argv[1], is the name of the database in which the new virtual table is being created. The database name is "main" for the primary database, or "temp" for TEMP database, or the name given at the end of the ATTACH statement for attached databases. The third element of the array, argv[2], is the name of the new virtual table, as specified following the TABLE @@ -695,18 +665,6 @@ deallocated and/or reused as soon as the sqlite3_declare_vtab() routine returns. -

    The xConnect method can also optionally request special features -for the virtual table by making one or more calls to -the sqlite3_vtab_config() interface: - -

    int sqlite3_vtab_config(sqlite3 *db, int op, ...);
    -
    - -

    Calls to sqlite3_vtab_config() are optional. But for maximum -security, it is recommended that virtual table implementations -invoke "sqlite3_vtab_config(db, SQLITE_VTAB_DIRECTONLY)" if the -virtual table will not be used from inside of triggers or views. -

    The xCreate method need not initialize the pModule, nRef, and zErrMsg fields of the sqlite3_vtab object. The SQLite core will take care of that chore. @@ -854,9 +812,7 @@

    The xConnect method is very similar to xCreate. It has the same parameters and constructs a new sqlite3_vtab structure just like xCreate. -And it must also call sqlite3_declare_vtab() like xCreate. It -should also make all of the same sqlite3_vtab_config() calls as -xCreate. +And it must also call sqlite3_declare_vtab() like xCreate.

    The difference is that xConnect is called to establish a new connection to an existing virtual table whereas xCreate is called @@ -974,19 +930,10 @@ #define SQLITE_INDEX_CONSTRAINT_ISNOTNULL 70 /* 3.21.0 and later */ #define SQLITE_INDEX_CONSTRAINT_ISNULL 71 /* 3.21.0 and later */ #define SQLITE_INDEX_CONSTRAINT_IS 72 /* 3.21.0 and later */ -#define SQLITE_INDEX_CONSTRAINT_LIMIT 73 /* 3.38.0 and later */ -#define SQLITE_INDEX_CONSTRAINT_OFFSET 74 /* 3.38.0 and later */ #define SQLITE_INDEX_CONSTRAINT_FUNCTION 150 /* 3.25.0 and later */ #define SQLITE_INDEX_SCAN_UNIQUE 1 /* Scan visits at most 1 row */

  • -

    Use the sqlite3_vtab_collation() interface to find the name of -the collating sequence that should be used when evaluating the i-th -constraint: - -

    const char *sqlite3_vtab_collation(sqlite3_index_info*, int i);
    -
    -

    The SQLite core calls the xBestIndex method when it is compiling a query that involves a virtual table. In other words, SQLite calls this method when it is running sqlite3_prepare() or the equivalent. @@ -1151,33 +1098,6 @@ LIKE, GLOB, REGEXP, or MATCH operator but off of the first argument to function-call equivalents of those operators. -

    2.3.1.2. LIMIT and OFFSET

    - -

    When aConstraint[].op is one of SQLITE_INDEX_CONSTRAINT_LIMIT or -SQLITE_INDEX_CONSTRAINT_OFFSET, that indicates that there is a -LIMIT or OFFSET clause on the SQL query statement that is using -the virtual table. The LIMIT and OFFSET operators have no -left operand, and so when aConstraint[].op is one of -SQLITE_INDEX_CONSTRAINT_LIMIT or SQLITE_INDEX_CONSTRAINT_OFFSET -then the aConstraint[].iColumn value is meaningless and should -not be used. - -

    2.3.1.3. Right-hand side values of constraints

    - -

    The sqlite3_vtab_rhs_value() interface can be used to try to -access the right-hand operand of a constraint. However, the value -of a right-hand operator might not be known at the time that -the xBestIndex method is run, so the sqlite3_vtab_rhs_value() -call might not be successful. Usually the right operand of a -constraint is only available to xBestIndex if it is coded as -a literal value in the input SQL. If the right operand is -coded as an expression or a host parameter, it probably will -not be accessible to xBestIndex. Some operators, such as -SQLITE_INDEX_CONSTRAINT_ISNULL and -SQLITE_INDEX_CONSTRAINT_ISNOTNULL have no right-hand operand. -The sqlite3_vtab_rhs_value() interface always returns -SQLITE_NOTFOUND for such operators. -

    2.3.2. Outputs

    Given all of the information above, the job of the xBestIndex @@ -1199,6 +1119,12 @@ The idxStr value may also be a static constant string, in which case the needToFreeIdxStr boolean should remain false. +

    If the virtual table will output rows in the order specified by +the ORDER BY clause, then the orderByConsumed flag may be set to +true. If the output is not automatically in the correct order +then orderByConsumed must be left in its default false setting. +This will indicate to the SQLite core that it will need to do a +separate sorting pass over the data after it comes out of the virtual table.

    The estimatedCost field should be set to the estimated number of disk access operations required to execute this query against @@ -1237,66 +1163,10 @@ when xFilter is called, the argv[0] passed to xFilter will have the EXPR value of the aConstraint[3] constraint. -

    2.3.2.1. Omit constraint checking in bytecode

    - -

    By default, the SQLite generates bytecode that will double -checks all constraints on each row of the virtual table to verify -that they are satisfied. If the virtual table can guarantee -that a constraint will always be satisfied, it can try to -suppress that double-check by setting aConstraintUsage[].omit. -However, with some exceptions, this is only a hint and -there is no guarantee that the redundant check of the constraint -will be suppressed. Key points: - -

      -
    • -The omit flag is only honored if the argvIndex value for the -constraint is greater than 0 and less than or equal to 16. -Constraint checking is never suppressed for constraints -that do not pass their right operand into the xFilter method. -The current implementation is only able to suppress redundant -constraint checking for the first 16 values passed to xFilter, -though that limitation might be increased in future releases. - -

    • -The omit flag is always honored for SQLITE_INDEX_CONSTRAINT_OFFSET -constraints as long as argvIndex is greater than 0. Setting the -omit flag on an SQLITE_INDEX_CONSTRAINT_OFFSET constraint indicates -to SQLite that the virtual table will itself suppress the first N -rows of output, where N is the right operand of the OFFSET operator. -If the virtual table implementation sets omit on an -SQLITE_INDEX_CONSTRAINT_OFFSET constraint but then fails to suppress -the first N rows of output, an incorrect answer will result from -the overall query. -

    - - - -

    2.3.2.2. ORDER BY and orderByConsumed

    - -

    If the virtual table will output rows in the order specified by -the ORDER BY clause, then the orderByConsumed flag may be set to -true. If the output is not automatically in the correct order -then orderByConsumed must be left in its default false setting. -This will indicate to the SQLite core that it will need to do a -separate sorting pass over the data after it comes out of the virtual table. -Setting orderByConsumed is an optimization. A query will always -get the correct answer if orderByConsumed is left at its default -value (0). Unnecessary sort operations might be avoided resulting -in a faster query if orderByConsumed is set, but setting -orderByConsumed incorrectly can result in an incorrect answer. -It is suggested that new virtual table implementations leave -the orderByConsumed value unset initially, and then after everything -else is known to be working correctly, go back and attempt to -optimize by setting orderByConsumed where appropriate. - -

    Sometimes the orderByConsumed flag can be safely set even if -the outputs from the virtual table are not strictly in the order -specified by nOrderBy and aOrderBy. If the -sqlite3_vtab_distinct() interface returns 1 or 2, that indicates -that the ordering can be relaxed. See the documentation on -sqlite3_vtab_distinct() for further information. - +

    By default, the SQLite core double checks all constraints on +each row of the virtual table that it receives. If such a check +is redundant, the xBestFilter method can suppress that double-check by +setting aConstraintUsage[].omit.

    2.3.3. Return Value

    @@ -1306,38 +1176,13 @@

    If xBestIndex returns SQLITE_CONSTRAINT, that does not indicate an error. Rather, SQLITE_CONSTRAINT indicates that the particular combination -of input parameters specified is insufficient for the virtual table -to do its job. -This is logically the same as setting the estimatedCost to infinity. -If every call to xBestIndex for a particular query plan returns -SQLITE_CONSTRAINT, that means there is no way for the virtual table -to be safely used, and the sqlite3_prepare() call will fail with -a "no query solution" error. - -

    2.3.4. Enforcing Required Parameters On Table-Valued Functions

    - -

    The SQLITE_CONSTRAINT return from xBestIndex -is useful for table-valued functions that +of input parameters specified should not be used in the query plan. +The SQLITE_CONSTRAINT return is useful for table-valued functions that have required parameters. If the aConstraint[].usable field is false for one of the required parameter, then the xBestIndex method should -return SQLITE_CONSTRAINT. If a required field does not appear in -the aConstraint[] array at all, that means that the corresponding -parameter is omitted from the input SQL. In that case, xBestIndex -should set an error message in pVTab->zErrMsg and return -SQLITE_ERROR. To summarize: +return SQLITE_CONSTRAINT. -

      -
    1. -The aConstraint[].usable value for a required parameter is -false return SQLITE_CONSTRAINT. -

    2. -A required parameter does not appears anywhere in -the aConstraint[] array -Set an error message in pVTab->zErrMsg and return -SQLITE_ERROR -

    - -

    The following example will better illustrate the use of SQLITE_CONSTRAINT +

    The following example will better illustrate the use of SQLITE_CONSTRAINT as a return value from xBestIndex:

    SELECT * FROM realtab, tablevaluedfunc(realtab.x);
    @@ -1363,7 +1208,7 @@
     

    The xBestIndex method will be invoked once for each of the potential -plans above. For plan 1, the aConstraint[].usable flag for the +plans above. For plan 1, the aConstraint[].usable flag for for the SQLITE_CONSTRAINT_EQ constraint on the param1 column will be true because the right-hand side value for the "param1 = ?" constraint will be known, since it is determined by the outer realtab loop. @@ -1748,24 +1593,22 @@ can be used as a boolean in the WHERE clause of a query and that the virtual table is able to exploit that function to speed up the query result. When xFindFunction returns SQLITE_INDEX_CONSTRAINT_FUNCTION or -larger, the value returned becomes the sqlite3_index_info.aConstraint.op -value for one of the constraints passed into xBestIndex(). The first -argument to the function is the column identified by -aConstraint[].iColumn field of the constraint and the second argument to the -function is the value that will be passed into xFilter() (if the -aConstraintUsage[].argvIndex value is set) or the value returned from -sqlite3_vtab_rhs_value(). - -

    The Geopoly module is an example of a virtual table that makes use -of SQLITE_INDEX_CONSTRAINT_FUNCTION to improve performance. -The xFindFunction() method for Geopoly returns +larger, the value returned becomes the sqlite3_index_info.aConstraint.op +value for one of the constraints passed into xBestIndex() and the second +argument becomes the value corresponding to that constraint that is passed +to xFilter(). This enables the +xBestIndex()/xFilter implementations to use the function to speed +its search. + +

    The technique of having xFindFunction() return values of +SQLITE_INDEX_CONSTRAINT_FUNCTION was initially used in the implementation +of the Geopoly module. The xFindFunction() method of that module returns SQLITE_INDEX_CONSTRAINT_FUNCTION for the geopoly_overlap() SQL function and it returns SQLITE_INDEX_CONSTRAINT_FUNCTION+1 for the geopoly_within() SQL function. This permits search optimizations for queries such as:

    SELECT * FROM geopolytab WHERE geopoly_overlap(_shape, $query_polygon);
    -SELECT * FROM geopolytab WHERE geopoly_within(_shape, $query_polygon);
     

    Note that infix functions (LIKE, GLOB, REGEXP, and MATCH) reverse @@ -1920,7 +1763,7 @@ auxiliary real tables that store content for a virtual table are called "shadow tables". See (1), -(2), and +(2), and (3) for additional information.

    The xShadowName method exists to allow SQLite to determine whether a @@ -1965,5 +1808,4 @@ backwards compatibility. For example, the SQL text generated by the .dump command of the CLI writes directly into shadow tables. -

    This page last modified on 2022-12-08 22:00:16 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/vtablist.html sqlite3-3.44.0-0/www/vtablist.html --- sqlite3-3.42.0/www/vtablist.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/vtablist.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -180,48 +156,45 @@ approximate_match A demonstration of how to use a virtual table to implement approximate string matching. -bytecode -A table-valued function that shows the bytecodes of a prepared - statement. -carray +carray A table-valued function that allows a C-language array of integers, doubles, or strings to be used as table in a query. -closure +closure Compute the transitive closure of a set. -completion +completion Suggests completions for partially-entered words during interactive SQL input. Used by the CLI to help implement tab-completion. -csv +csv A virtual table that represents a comma-separated-value or CSV file (RFC 4180) as a read-only table so that it can be used as part of a larger query. -dbstat +dbstat Provides information about the purpose and use of each page in a database file. Used in the implementation of the sqlite3_analyzer utility program. -files_of_checkin +files_of_checkin Provides information about all files in a single check-in in the Fossil version control system. This virtual table is not part of the SQLite project but is included because it provides an example of how to use virtual tables and because it is used to help version control the SQLite sources. -fsdir +fsdir A table-valued function returning one row for each file in a selected file hierarchy of the host computer. Used by the CLI to help implement the .archive command. -FTS3 +FTS3 A high-performance full-text search index. -FTS5 +FTS5 A higher-performance full-text search index -generate_series -A table-valued function returning a sequence of +generate_series +A table-valued function returning a sequence of increasing integers, modeled after the table-valued function by the same name in PostgreSQL. -json_each +json_each A table-valued function for decomposing a JSON string. -json_tree +json_tree A table-valued function for decomposing a JSON string. -OsQuery +OsQuery Hundreds of virtual tables that publish various aspects of the host computer, such as the process table, user lists, active network connections, and so forth. @@ -233,33 +206,30 @@ SQLite virtual table mechanism can be leveraged to provide elegant solutions to important real-world problems. -pragma +pragma Built-in table-valued functions that return the results of PRAGMA statements for use within ordinary SQL queries. -RTree +RTree An implementation of the Guttmann R*Tree spatial index idea. -spellfix1 +spellfix1 A virtual table that implements a spelling correction engine. -sqlite_btreeinfo +sqlite_btreeinfo This experimental table-valued function provides information about a single B-tree in a database file, such as the depth, and estimated number of pages and number of entries, and so forth. -sqlite_dbpage +sqlite_dbpage Key/value store for the raw database file content. The key is the page number and the value is binary page content. -sqlite_memstat +sqlite_memstat Provides SQL access to the sqlite3_status64() and sqlite3_db_status() interfaces. -sqlite_stmt +sqlite_stmt A table-valued function containing one row for each prepared statement associated with an open database connection. -swarmvtab +swarmvtab An experimental module providing on-demand read-only access to multiple tables spread across multiple databases, via a single virtual table abstraction. -tables_used -A table-valued function that shows the tables and indexes that - are accessed by a prepared statement. tclvar Represents the global variables of a TCL Interpreter as an SQL @@ -288,5 +258,4 @@ the CLI to implement the ability to read and write ZIP Archives. -

    This page last modified on 2023-05-01 21:49:55 UTC

    diff -Nru sqlite3-3.42.0/www/walformat.html sqlite3-3.44.0-0/www/walformat.html --- sqlite3-3.42.0/www/walformat.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/walformat.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -637,11 +613,11 @@ lock for a single database connection can be in exactly one of the following states:

      -
    1. SQLITE_LOCK_NONE (unlocked) -
    2. SQLITE_LOCK_SHARED (reading) -
    3. SQLITE_LOCK_RESERVED (reading, waiting to write) -
    4. SQLITE_LOCK_PENDING (new readers blocked, waiting to write) -
    5. SQLITE_LOCK_EXCLUSIVE (writing) +
    6. SQLITE_LOCK_NONE (unlocked) +
    7. SQLITE_LOCK_SHARED (reading) +
    8. SQLITE_LOCK_RESERVED (reading, waiting to write) +
    9. SQLITE_LOCK_PENDING (new readers blocked, waiting to write) +
    10. SQLITE_LOCK_EXCLUSIVE (writing)

    The DELETE-mode locks are stored on the lock-byte page of the main database file. @@ -889,5 +865,4 @@ WAL-index except for WAL_READ_LOCK(0) are held exclusively. This prevents any other thread from writing the database and from reading any transactions that are held in the WAL, until the recovery is complete. -

    This page last modified on 2022-01-08 05:02:57 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/wal.html sqlite3-3.44.0-0/www/wal.html --- sqlite3-3.42.0/www/wal.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/wal.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -752,5 +728,4 @@

    Deliberately changing out of WAL mode changes the database file format version numbers back to 1 so that older versions of SQLite can once again access the database file.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/whentouse.html sqlite3-3.44.0-0/www/whentouse.html --- sqlite3-3.42.0/www/whentouse.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/whentouse.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -211,8 +187,6 @@ the database. Dynamic content uses about 200 SQL statements per webpage. This setup runs on a single VM that shares a physical server with 23 others and yet still keeps the load average below 0.1 most of the time. - -

    See also: Hacker New discussion from 2022-12-13.

  • Data analysis

    @@ -506,7 +480,7 @@

    SQLite only supports one writer at a time per database file. But in most cases, a write transaction only takes milliseconds and so multiple writers can simply take turns. SQLite will handle -more write concurrency than many people suspect. Nevertheless, +more write concurrency that many people suspect. Nevertheless, client/server database systems, because they have a long-running server process at hand to coordinate access, can usually handle far more write concurrency than SQLite ever will. @@ -532,4 +506,3 @@

  • - diff -Nru sqlite3-3.42.0/www/whyc.html sqlite3-3.44.0-0/www/whyc.html --- sqlite3-3.42.0/www/whyc.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/whyc.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -154,7 +130,7 @@

    1. C Is Best

    -
    +
    Note: Sections 2.0 and 3.0 of this article were added in response to comments on Hacker News and @@ -308,6 +284,33 @@ seems also likely to result in slower code.

  • +Safe programming languages solve the easy problems: memory leaks, +use-after-free errors, array overruns, etc. Safe languages provide +no help beyond ordinary C code in solving the rather more difficult +problem of computing a correct answer to an SQL statement. + +

  • +Safe languages are often touted for helping to prevent +security vulnerabilities. True enough, but SQLite is +not a particularly security-sensitive library. If an application is +running untrusted and unverified SQL, then it already has much bigger +security issues (SQL injection) that no "safe" language will fix. +

    +It is true that applications sometimes import complete binary SQLite +database files from untrusted sources, and such imports could present a +possible attack vector. However, those code paths in SQLite are +limited and are extremely well tested. And pre-validation routines +are available to applications that want to read untrusted databases +that can help detect possible attacks prior to use. + +

  • +Some "safe" languages (ex: Go) dislike the use of assert(). But +the use of assert() is a vital part of keeping SQLite maintainable. +The lack of assert() in Go is a show-stopper as far as the developers +of SQLite are concerned. See the The Use Of assert() In SQLite +article for additional information. + +

  • Safe languages insert additional machine branches to do things like verify that array accesses are in-bounds. In correct code, those branches are never taken. That means that the machine code cannot @@ -324,7 +327,7 @@ All of the existing safe languages are new. The developers of SQLite applaud the efforts of computer language researchers in trying to develop languages that are easier to program safely. We encourage these -efforts to continue. But we ourselves are more interested in old and +efforts to continue. Be we ourselves are more interested in old and boring languages when it comes to implementing SQLite.

  • @@ -357,5 +360,4 @@ Rust, then you are welcomed and encouraged to contact the SQLite developers privately and argue your case. -

    This page last modified on 2022-07-29 00:41:26 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/whynotgit.html sqlite3-3.44.0-0/www/whynotgit.html --- sqlite3-3.42.0/www/whynotgit.html 2023-05-16 13:43:18.000000000 +0000 +++ sqlite3-3.44.0-0/www/whynotgit.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -129,7 +105,7 @@ -
    2.2. Git makes it difficult to find successors (descendants) + @@ -176,7 +152,7 @@ Git version control system like everybody else. This article attempts to answer that question. Also, -in section 3, +in section 3, this article provides hints to Git users about how they can easily access the SQLite source code. @@ -184,14 +160,14 @@ This article is not a comparison between Fossil and Git. See https://fossil-scm.org/fossil/doc/trunk/www/fossil-v-git.wiki -for one comparison of the two systems. Other third-party +for one comparison of the two systems. Other third-party comparisons are available as well - use a search engine to find them.

    This article is not advocating that you switch your projects away from Git. You can use whatever version control system you want. If you are perfectly happy with Git, then by all means keep using -Git. But, if Git is not working well for you or you are wondering +Git. But, if Git is not working well for you or you are wondering if it can be improved or if there is something better, then maybe try to understand the perspectives presented below. Use the insights thus obtained to find or write a different and @@ -224,7 +200,7 @@

    GitHub and GitLab offer nothing comparable. The closest I have found is the network, -which is slow to render (unless it is already cached), does not +which is slow to render (unless it is already cached), does not offer nearly as much details, and scarcely works at all on mobile. The commits view of GitHub provides more detail, renders quickly, @@ -236,18 +212,18 @@

    I am told that Git users commonly install third-party graphical -viewers for Git, many of which do a better job of showing recent +viewers for Git, many of which do a better job of showing recent activity on the project. That is great, but these are still more third-party applications that must be installed and managed separately. Many are platform-specific. (One of the better ones, GitUp, only works on Mac, for example.) All require that you first sync your local repository then bring up their graphical interface on your desktop. And -even with all that, I still cannot see what I typically want to +even with all that, I still cannot see what I typically want to see without multiple clicks. Checking on project status from a phone while away from the office is not an option. -

    2.2. Git makes it difficult to find successors (descendants) +

    2.2. Git makes it difficult to find successors (descendents) of a check-in

    @@ -269,11 +245,11 @@ -

    It is not impossible to find the descendants of a check-in +

    It is not impossible to find the descendents of a check-in in Git. It is merely difficult. For example, -there is a +there is a stackoverflow page -showing the command sequence for finding the descendants of a check-in +showing the command sequence for finding the descendents of a check-in in unix:

    git rev-list --all --parents | grep ".\{40\}.*.*" | awk '{print $1}'
    @@ -282,22 +258,22 @@
     
     

    But this is not the same thing. The command above gives -a list of descendants without showing the branching structure, which +a list of descendents without showing the branching structure, which is important for understanding what happened. And the command only works -if you have a local clone of the repository; finding the descendants of +if you have a local clone of the repository; finding the descendents of a check-in is not something you can do with web interfaces such as GitHub or GitLab.

    -This is not really about just finding the descendants of a check-in -from time to time. The fact that descendants are readily available in +This is not really about just finding the descendents of a check-in +from time to time. The fact that descendents are readily available in Fossil means that the information pervades the web pages provided by Fossil. One example: Every Fossil check-in information page (example) shows -a small "Context" graph of the immediate predecessor and successors +a small "Context" graph of the immediate predecessor and successors to that check-in. This helps the user maintain better situational awareness, and it provides useful capabilities, such as the ability -to click forward to the next check-in within a sequence. Another example: +click forward to the next check-in in sequence. Another example: Fossil easily shows the context around a specific check-in (example) which again helps to promote situational awareness and a deeper @@ -317,7 +293,7 @@ The complexity of Git distracts attention from the software under development. A user of Git needs to keep all of the following in mind: -

      +

      1. The working directory
      2. The "index" or staging area
      3. The local head @@ -326,20 +302,20 @@

      Git has commands (and/or options on commands) for moving and -comparing content between all of these locations. +comparing content between all of these locations.

      In contrast, Fossil users only need to think about their working directory and the check-in they are working on. That is 60% less distraction. Every developer has a finite number of brain-cycles. Fossil -requires fewer brain-cycles to operate, thus freeing up +requires fewer brain-cycles to operate, thus freeing up intellectual resources to focus on the software under development.

      One user of both Git and Fossil writes in HN:

      -Fossil gives me peace of mind that I have everything ... synced to +Fossil gives me peace of mind that I have everything ... synced to the server with a single command.... I never get this peace of mind with git.
      @@ -394,8 +370,8 @@ In contrast, Fossil is a single standalone binary which is installed by putting it on $PATH. That one binary contains all the functionality of core Git and also GitHub and/or GitLab. It -manages a community server with wiki, bug tracking, and forums, -provides packaged downloads for consumers, login managements, +manages a community server with wiki, bug tracking, and forums, +provides packaged downloads for consumers, login managements, and so forth, with no extra software required. Standing up a community server for Fossil takes minutes. And Fossil is efficient. A Fossil server will run fine on a $5/month VPS or a Raspberry Pi, @@ -415,7 +391,7 @@

      Let's be real. Few people dispute that Git provides -a suboptimal user experience. A lot of +a suboptimal user experience. A lot of the underlying implementation shows through into the user interface. The interface is so bad that there is even a parody site that generates @@ -430,20 +406,20 @@

      3. A Git-User's Guide To Accessing SQLite Source Code

      -If you are a devoted Git user, you can still easily access SQLite. +If you are a devoted Git user, you can still easily access SQLite. This section gives some hints on how to do so.

      3.1. The Official GitHub Mirror

      -As of 2019-03-20, there is now an +As of 2019-03-20, there is now an official Git mirror of the SQLite sources on GitHub. -

      The mirror is an incremental export of the +

      The mirror is an incremental export of the canonical Fossil repository for SQLite. A cron-job updates the GitHub repository once an hour. -This is a one-way, read-only code mirror. No pull requests or +This is a one-way, read-only code mirror. No pull requests or changes are accepted via GitHub. The GitHub repository merely copies the content from the Fossil repository. All changes are input via Fossil. @@ -555,15 +531,14 @@

      If you need to verify that the SQLite source code that you have is authentic and has not been modified in any way (perhaps by an adversary) -that can be done using a few simple command-line tools. At the root -of the SQLite source tree is a file named "manifest". The manifest -file contains the name of every other file in the source tree together +that can be done using a few simple command-line tools. At the root +of the SQLite source tree is a file named "manifest". The manifest +file contains the name of every other file in the source tree together with either a SHA1 or SHA3-256 hash for that file. (SHA1 is used for older files and SHA3-256 for newer files.) You can write a -script to extract these hashes and verify them against the source code +script to extract these hashes and verify them against the source code files. The hash name for the check-in is just the SHA3-256 hash of the -"manifest" file itself, possibly with the last line omitted if the -last line begins with "# Remove this line..." +"manifest" file itself.

      4. See Also

      @@ -572,5 +547,4 @@
    1. Fossil vs. Git

    2. What others say about Fossil and Git

    3. -

      This page last modified on 2023-02-27 02:07:35 UTC

      diff -Nru sqlite3-3.42.0/www/windowfunctions.html sqlite3-3.44.0-0/www/windowfunctions.html --- sqlite3-3.42.0/www/windowfunctions.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/windowfunctions.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -174,8 +150,8 @@

    window-function-invocation: -

    -
    +

    +
    @@ -231,8 +207,8 @@

    expr: -

    -
    xValue - This method is only required for window aggregate functions. The presence - of this method is what distinguishes a window aggregate function from a - legacy aggregate function. This method is invoked to return the current + This method is only required window aggregate functions, not legacy + aggregate function implementations. It is invoked to return the current value of the aggregate. Unlike xFinal, the implementation should not delete any context.
    xInverse - This method is only required for window aggregate functions, not legacy - aggregate function implementations. It is invoked to remove the oldest - presently aggregated result of xStep from the current window. - The function arguments, if any, are those - passed to xStep for the row being removed. + This method is only required window aggregate functions, not legacy + aggregate function implementations. It is invoked to remove a row + from the current window. The function arguments, if any, correspond + to the row being removed.

    The C code below implements a simple window aggregate function named @@ -7475,8 +7366,8 @@ ** Add the value of the argument to the aggregate context (an integer). */ static void sumintStep( - sqlite3_context *ctx, - int nArg, + sqlite3_context *ctx, + int nArg, sqlite3_value *apArg[] ){ sqlite3_int64 *pInt; @@ -7502,8 +7393,8 @@ ** been passed to xStep() without error (so it must be an integer). */ static void sumintInverse( - sqlite3_context *ctx, - int nArg, + sqlite3_context *ctx, + int nArg, sqlite3_value *apArg[] ){ sqlite3_int64 *pInt; @@ -7543,7 +7434,7 @@ } /* -** Register sumint() window aggregate with database handle db. +** Register sumint() window aggregate with database handle db. */ int register_sumint(sqlite3 *db){ return sqlite3_create_window_function(db, "sumint", 1, SQLITE_UTF8, 0, @@ -7589,13 +7480,13 @@

  • xStep(4) - add "4" to the current window.
  • xStep(5) - add "5" to the current window.
  • xValue() - invoke xValue() to obtain the value of sumint() for - the row with (x='a'). The window currently consists of values 4 and 5, + the row with (x='a'). The window currently consists of values 4 and 5, and so the result is 9.
  • xStep(3) - add "3" to the current window.
  • xValue() - invoke xValue() to obtain the value of sumint() for the row with (x='b'). The window currently consists of values 4, 5 and 3, and so the result is 12. -
  • xInverse(4) - remove "4" from the window. +
  • xInverse(4) - remove "4" from the window.
  • xStep(8) - add "8" to the current window. The window now consists of values 5, 3 and 8.
  • xValue() - invoked to obtain the value for the row with (x='c'). @@ -7605,18 +7496,11 @@
  • xValue() - invoked to obtain the value for row (x='d').
  • xInverse(3) - remove value "3" from the window. The window now contains values 8 and 1 only. -
  • xFinal() - invoked to reclaim any allocated resources and to - obtain the value for row (x='e'). 9. . +
  • xValue() - invoked to obtain the value for row (x='e'). 9. +
  • xFinal() - invoked to reclaim any allocated resources.
  • -

    If the user were to abandon query execution by calling sqlite3_reset() or -sqlite3_finalize() on the statement handle before SQLite has called xFinal(), -then xFinal() is called automatically from within the sqlite3_reset() or -sqlite3_finalize() call in order to reclaim any allocated resources, even -though the value is not required. In this case any error returned by the xFinal -implementation is silently discarded. - -

    6. History

    +

    6. History

    Window function support was first added to SQLite with release version 3.25.0 (2018-09-15). The SQLite developers used @@ -7631,5 +7515,4 @@ GROUPS frame types, window chaining, and support for "<expr> PRECEDING" and "<expr> FOLLOWING" boundaries in RANGE frames. -

    This page last modified on 2023-02-27 02:07:35 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/withoutrowid.html sqlite3-3.44.0-0/www/withoutrowid.html --- sqlite3-3.42.0/www/withoutrowid.html 2023-05-16 13:43:17.000000000 +0000 +++ sqlite3-3.44.0-0/www/withoutrowid.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,65 +89,13 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    Clustered Indexes and the WITHOUT ROWID Optimization
    - -
    @@ -161,7 +109,7 @@ then the special "rowid" column is omitted. There are sometimes space and performance advantages to omitting the rowid.

    -

    A WITHOUT ROWID table is a table that uses a +

    A WITHOUT ROWID table is a table that uses a Clustered Index as the primary key.

    @@ -177,20 +125,20 @@ ) WITHOUT ROWID;
    -

    As with all SQL syntax, the case of the keywords does not matter. +

    As with all SQL syntax, the case of the keywords does not matter. One can write "WITHOUT rowid" or "without rowid" or "WiThOuT rOwId" and it will mean the same thing.

    Every WITHOUT ROWID table must have a PRIMARY KEY. An error is raised if a CREATE TABLE statement with the WITHOUT ROWID clause lacks a PRIMARY KEY. -

    In most contexts, the special "rowid" column of normal tables can -also be called "oid" or "_rowid_". However, only "rowid" works as +

    In most contexts, the special "rowid" column of normal tables can +also be called "oid" or "_rowid_". However, only "rowid" works as the keyword in the CREATE TABLE statement.

    1.2. Compatibility

    -

    SQLite version 3.8.2 (2013-12-06) or later +

    SQLite version 3.8.2 (2013-12-06) or later is necessary in order to use a WITHOUT ROWID table. An attempt to open a database that contains one or more WITHOUT ROWID tables using an earlier version of SQLite will result in a @@ -202,7 +150,7 @@ with any other SQL database engine, as far as we know. In an elegant system, all tables would behave as WITHOUT ROWID tables even without the WITHOUT ROWID keyword. However, when SQLite was -first designed, it used only integer rowids for row keys +first designed, it used only integer rowids for row keys to simplify the implementation. This approach worked well for many years. But as the demands on SQLite grew, the need for tables in which the PRIMARY KEY really did @@ -236,7 +184,7 @@ on WITHOUT ROWID tables. In an ordinary table, "INTEGER PRIMARY KEY" means that the column is an alias for the rowid. But since there is no rowid in a WITHOUT ROWID -table, that special meaning no longer applies. An "INTEGER PRIMARY KEY" +table, that special meaning no longer applies. An "INTEGER PRIMARY KEY" column in a WITHOUT ROWID table works like an "INT PRIMARY KEY" column in an ordinary table: It is a PRIMARY KEY that has integer affinity. @@ -292,10 +240,10 @@

    A WITHOUT ROWID table is an optimization that can reduce storage and processing requirements. -

    In an ordinary SQLite table, the PRIMARY KEY is really just a +

    In an ordinary SQLite table, the PRIMARY KEY is really just a UNIQUE index. The key used to look up records on disk is the rowid. -The special "INTEGER PRIMARY KEY" column type in ordinary SQLite tables +The special "INTEGER PRIMARY KEY" column type in ordinary SQLite tables causes the column to be an alias for the rowid, and so an INTEGER PRIMARY KEY is a true PRIMARY KEY. But any other kind of PRIMARY KEYs, including "INT PRIMARY KEY" are just unique indexes in an ordinary rowid table.

    @@ -321,10 +269,10 @@ once in the main table and again in the index.

    Consider querying this table to find the number of occurrences of the -word "xsync".: +word "xyzzy".:

    -SELECT cnt FROM wordcount WHERE word='xsync';
    +SELECT cnt FROM wordcount WHERE word='xyzzy';
     

    This query first has to search the index B-Tree looking for any entry @@ -355,7 +303,7 @@ and without the need to do a second binary search on the rowid.

    Thus, in some cases, a WITHOUT ROWID table can use about half the amount -of disk space and can operate nearly twice as fast. Of course, in a +of disk space and can operate nearly twice as fast. Of course, in a real-world schema, there will typically be secondary indices and/or UNIQUE constraints, and the situation is more complicated. But even then, there can often be space and performance advantages to using WITHOUT ROWID @@ -370,25 +318,25 @@ not store large strings or BLOBs.

    WITHOUT ROWID tables will work correctly (that is to say, they -provide the correct answer) for tables with a single INTEGER PRIMARY KEY. -However, ordinary rowid tables will run faster in that case. +provide the correct answer) for tables with a single INTEGER PRIMARY KEY. +However, ordinary rowid tables will run faster in that case. Hence, it is good design -to avoid creating WITHOUT ROWID tables with single-column PRIMARY KEYs +to avoid creating WITHOUT ROWID tables with single-column PRIMARY KEYs of type INTEGER.

    WITHOUT ROWID tables work best when individual rows are not too large. A good rule-of-thumb is that the average size of a single row in a -WITHOUT ROWID table should be less than about 1/20th the size of +WITHOUT ROWID table should be less than about 1/20th the size of a database page. That means that rows should not contain more than about 50 bytes each for a 1KiB page size or about 200 bytes each for 4KiB page size. WITHOUT ROWID tables will work (in the sense that they get the correct answer) for arbitrarily large rows - up to 2GB in size - but traditional rowid tables tend to work faster for large row sizes. This is because rowid tables are implemented as B*-Trees where -all content is stored in the leaves of the tree, whereas WITHOUT ROWID +all content is stored in the leaves of the tree, whereas WITHOUT ROWID tables are implemented using ordinary B-Trees with content stored on both -leaves and intermediate nodes. Storing content in -intermediate nodes causes each intermediate node entry to take up more +leaves and intermediate nodes. Storing content in +intermediate nodes mean that each intermediate node entry takes up more space on the page and thus reduces the fan-out, increasing the search cost.

    The "sqlite3_analyzer.exe" utility program, available as source code @@ -407,18 +355,4 @@ if adding WITHOUT ROWID to tables with non-integer PRIMARY KEYs helps or hurts performance, and retaining the WITHOUT ROWID only in those cases where it helps. - -

    5. Determining If An Existing Table Is WITHOUT ROWID

    - -

    A WITHOUT ROWID table returns the same content for -PRAGMA table_info and PRAGMA table_xinfo as does an ordinary -table. But unlike an ordinary table, a WITHOUT ROWID also -responds to the PRAGMA index_info command. The PRAGMA index_info -on a WITHOUT ROWID table returns information about the PRIMARY KEY -for the table. In this way, the PRAGMA index_info command can be -used to unambiguously determine whether a particular table is a -WITHOUT ROWID table or an ordinary table - an ordinary table will -always return no rows but a WITHOUT ROWID table will always return -one or more rows. -

    This page last modified on 2023-02-27 02:07:35 UTC

    - +

    diff -Nru sqlite3-3.42.0/www/zeroconf.html sqlite3-3.44.0-0/www/zeroconf.html --- sqlite3-3.42.0/www/zeroconf.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/zeroconf.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); + @@ -143,5 +119,4 @@ But doing the initial installation and configuration can often be intimidating.

    -

    This page last modified on 2022-01-08 05:02:57 UTC

    diff -Nru sqlite3-3.42.0/www/zipfile.html sqlite3-3.44.0-0/www/zipfile.html --- sqlite3-3.42.0/www/zipfile.html 2023-05-16 13:43:15.000000000 +0000 +++ sqlite3-3.44.0-0/www/zipfile.html 2023-11-04 14:24:20.000000000 +0000 @@ -89,32 +89,8 @@ } return false; } -var antiRobot = 0; -function antiRobotGo(){ -if( antiRobot!=3 ) return; -antiRobot = 7; -var j = document.getElementById("mtimelink"); -if(j && j.hasAttribute("data-href")) j.href=j.getAttribute("data-href"); -} -function antiRobotDefense(){ -document.body.onmousedown=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousedown=null; -} -document.body.onmousemove=function(){ -antiRobot |= 2; -antiRobotGo(); -document.body.onmousemove=null; -} -setTimeout(function(){ -antiRobot |= 1; -antiRobotGo(); -}, 100) -antiRobotGo(); -} -antiRobotDefense(); +
    @@ -450,5 +426,4 @@ ) SELECT zipfile(name, data) FROM contents;
    -

    This page last modified on 2022-01-08 05:02:57 UTC