git: d9d03b5409f3 - stable/11 - sqlite3: import sqlite3 3.35.5
Cy Schubert
cy at FreeBSD.org
Sun Jun 6 21:55:32 UTC 2021
The branch stable/11 has been updated by cy:
URL: https://cgit.FreeBSD.org/src/commit/?id=d9d03b5409f32668a71468975d944ac1015e878b
commit d9d03b5409f32668a71468975d944ac1015e878b
Author: Cy Schubert <cy at FreeBSD.org>
AuthorDate: 2021-05-07 01:01:44 +0000
Commit: Cy Schubert <cy at FreeBSD.org>
CommitDate: 2021-06-06 01:05:50 +0000
sqlite3: import sqlite3 3.35.5
Merge commit '0511e356f5e2106928ee352ee974d1470c860a9a' into new_merge
Changes at https://www.sqlite.org/releaselog/3_35_5.html.
MFC after: 1 month
(cherry picked from commit ce9de47260d4edc963a94140789e4a52642c28e6)
---
contrib/sqlite3/Makefile.msc | 3 +
contrib/sqlite3/configure | 153 +-
contrib/sqlite3/configure.ac | 50 +-
contrib/sqlite3/shell.c | 501 +-
contrib/sqlite3/sqlite3.c | 11777 ++++++++++++++++++++++---------------
contrib/sqlite3/sqlite3.h | 59 +-
contrib/sqlite3/sqlite3rc.h | 2 +-
contrib/sqlite3/tea/configure | 18 +-
contrib/sqlite3/tea/configure.ac | 2 +-
9 files changed, 7708 insertions(+), 4857 deletions(-)
diff --git a/contrib/sqlite3/Makefile.msc b/contrib/sqlite3/Makefile.msc
index 746162a00c04..1f177557a25a 100644
--- a/contrib/sqlite3/Makefile.msc
+++ b/contrib/sqlite3/Makefile.msc
@@ -303,6 +303,9 @@ OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_SESSION=1
OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_PREUPDATE_HOOK=1
!ENDIF
+# Always enable math functions on Windows
+OPT_FEATURE_FLAGS = $(OPT_FEATURE_FLAGS) -DSQLITE_ENABLE_MATH_FUNCTIONS
+
# Should the rbu extension be enabled? If so, add compilation options
# to enable it.
#
diff --git a/contrib/sqlite3/configure b/contrib/sqlite3/configure
index 0eedad3467dd..4a16edbb6e02 100755
--- a/contrib/sqlite3/configure
+++ b/contrib/sqlite3/configure
@@ -1,6 +1,6 @@
#! /bin/sh
# Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.69 for sqlite 3.34.1.
+# Generated by GNU Autoconf 2.69 for sqlite 3.35.5.
#
# Report bugs to <http://www.sqlite.org>.
#
@@ -590,8 +590,8 @@ MAKEFLAGS=
# Identity of this package.
PACKAGE_NAME='sqlite'
PACKAGE_TARNAME='sqlite'
-PACKAGE_VERSION='3.34.1'
-PACKAGE_STRING='sqlite 3.34.1'
+PACKAGE_VERSION='3.35.5'
+PACKAGE_STRING='sqlite 3.35.5'
PACKAGE_BUGREPORT='http://www.sqlite.org'
PACKAGE_URL=''
@@ -772,6 +772,7 @@ enable_editline
enable_readline
enable_threadsafe
enable_dynamic_extensions
+enable_math
enable_fts4
enable_fts3
enable_fts5
@@ -1341,7 +1342,7 @@ if test "$ac_init_help" = "long"; then
# Omit some internal or obsolete options to make the list less imposing.
# This message is too long to be a string in the A/UX 3.1 sh.
cat <<_ACEOF
-\`configure' configures sqlite 3.34.1 to adapt to many kinds of systems.
+\`configure' configures sqlite 3.35.5 to adapt to many kinds of systems.
Usage: $0 [OPTION]... [VAR=VALUE]...
@@ -1412,7 +1413,7 @@ fi
if test -n "$ac_init_help"; then
case $ac_init_help in
- short | recursive ) echo "Configuration of sqlite 3.34.1:";;
+ short | recursive ) echo "Configuration of sqlite 3.35.5:";;
esac
cat <<\_ACEOF
@@ -1437,6 +1438,7 @@ Optional Features:
--enable-threadsafe build a thread-safe library [default=yes]
--enable-dynamic-extensions
support loadable extensions [default=yes]
+ --enable-math SQL math functions [default=yes]
--enable-fts4 include fts4 support [default=yes]
--enable-fts3 include fts3 support [default=no]
--enable-fts5 include fts5 support [default=yes]
@@ -1537,7 +1539,7 @@ fi
test -n "$ac_init_help" && exit $ac_status
if $ac_init_version; then
cat <<\_ACEOF
-sqlite configure 3.34.1
+sqlite configure 3.35.5
generated by GNU Autoconf 2.69
Copyright (C) 2012 Free Software Foundation, Inc.
@@ -1952,7 +1954,7 @@ cat >config.log <<_ACEOF
This file contains any messages produced by compilers while
running configure, to aid debugging if configure makes a mistake.
-It was created by sqlite $as_me 3.34.1, which was
+It was created by sqlite $as_me 3.35.5, which was
generated by GNU Autoconf 2.69. Invocation command line was
$ $0 $@
@@ -2818,7 +2820,7 @@ fi
# Define the identity of the package.
PACKAGE='sqlite'
- VERSION='3.34.1'
+ VERSION='3.35.5'
cat >>confdefs.h <<_ACEOF
@@ -13335,7 +13337,9 @@ else
enable_threadsafe=yes
fi
-if test x"$enable_threadsafe" != "xno"; then
+if test x"$enable_threadsafe" == "xno"; then
+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_THREADSAFE=0"
+else
BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for library containing pthread_create" >&5
$as_echo_n "checking for library containing pthread_create... " >&6; }
@@ -13528,6 +13532,84 @@ $as_echo_n "checking for whether to support dynamic extensions... " >&6; }
$as_echo "$enable_dynamic_extensions" >&6; }
#-----------------------------------------------------------------------
+#-----------------------------------------------------------------------
+# --enable-math
+#
+# Check whether --enable-math was given.
+if test "${enable_math+set}" = set; then :
+ enableval=$enable_math;
+else
+ enable_math=yes
+fi
+
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking SQL math functions" >&5
+$as_echo_n "checking SQL math functions... " >&6; }
+if test x"$enable_math" = "xyes"; then
+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_MATH_FUNCTIONS"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5
+$as_echo "enabled" >&6; }
+ { $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
+
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
+fi
+#-----------------------------------------------------------------------
+
#-----------------------------------------------------------------------
# --enable-fts4
#
@@ -13538,8 +13620,15 @@ else
enable_fts4=yes
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking FTS4 extension" >&5
+$as_echo_n "checking FTS4 extension... " >&6; }
if test x"$enable_fts4" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5
+$as_echo "enabled" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
fi
#-----------------------------------------------------------------------
@@ -13551,8 +13640,15 @@ if test "${enable_fts3+set}" = set; then :
enableval=$enable_fts3;
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking FTS3 extension" >&5
+$as_echo_n "checking FTS3 extension... " >&6; }
if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5
+$as_echo "enabled" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
fi
#-----------------------------------------------------------------------
@@ -13566,7 +13662,11 @@ else
enable_fts5=yes
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking FTS5 extension" >&5
+$as_echo_n "checking FTS5 extension... " >&6; }
if test x"$enable_fts5" = "xyes"; then
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5
+$as_echo "enabled" >&6; }
{ $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 :
@@ -13624,6 +13724,9 @@ if test "$ac_res" != no; then :
fi
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
fi
#-----------------------------------------------------------------------
@@ -13637,8 +13740,15 @@ else
enable_json1=yes
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking JSON functions" >&5
+$as_echo_n "checking JSON functions... " >&6; }
if test x"$enable_json1" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5
+$as_echo "enabled" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
fi
#-----------------------------------------------------------------------
@@ -13652,8 +13762,15 @@ else
enable_rtree=yes
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking RTREE extension" >&5
+$as_echo_n "checking RTREE extension... " >&6; }
if test x"$enable_rtree" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5
+$as_echo "enabled" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
fi
#-----------------------------------------------------------------------
@@ -13665,8 +13782,15 @@ if test "${enable_session+set}" = set; then :
enableval=$enable_session;
fi
+{ $as_echo "$as_me:${as_lineno-$LINENO}: checking Session extension" >&5
+$as_echo_n "checking Session extension... " >&6; }
if test x"$enable_session" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: enabled" >&5
+$as_echo "enabled" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: disabled" >&5
+$as_echo "disabled" >&6; }
fi
#-----------------------------------------------------------------------
@@ -13678,9 +13802,16 @@ 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 x"$enable_debug" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
CFLAGS="-g -O0"
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: debug" >&5
+$as_echo "debug" >&6; }
+else
+ { $as_echo "$as_me:${as_lineno-$LINENO}: result: release" >&5
+$as_echo "release" >&6; }
fi
#-----------------------------------------------------------------------
@@ -14438,7 +14569,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1
# report actual input values of CONFIG_FILES etc. instead of their
# values after options handling.
ac_log="
-This file was extended by sqlite $as_me 3.34.1, which was
+This file was extended by sqlite $as_me 3.35.5, which was
generated by GNU Autoconf 2.69. Invocation command line was
CONFIG_FILES = $CONFIG_FILES
@@ -14495,7 +14626,7 @@ _ACEOF
cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1
ac_cs_config="`$as_echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`"
ac_cs_version="\\
-sqlite config.status 3.34.1
+sqlite config.status 3.35.5
configured by $0, generated by GNU Autoconf 2.69,
with options \\"\$ac_cs_config\\"
diff --git a/contrib/sqlite3/configure.ac b/contrib/sqlite3/configure.ac
index 72472467d5b7..166f7019cd5c 100644
--- a/contrib/sqlite3/configure.ac
+++ b/contrib/sqlite3/configure.ac
@@ -10,7 +10,7 @@
#
AC_PREREQ(2.61)
-AC_INIT(sqlite, 3.34.1, http://www.sqlite.org)
+AC_INIT(sqlite, 3.35.5, http://www.sqlite.org)
AC_CONFIG_SRCDIR([sqlite3.c])
AC_CONFIG_AUX_DIR([.])
@@ -87,7 +87,9 @@ AC_SUBST(READLINE_LIBS)
AC_ARG_ENABLE(threadsafe, [AS_HELP_STRING(
[--enable-threadsafe], [build a thread-safe library [default=yes]])],
[], [enable_threadsafe=yes])
-if test x"$enable_threadsafe" != "xno"; then
+if test x"$enable_threadsafe" == "xno"; then
+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_THREADSAFE=0"
+else
BUILD_CFLAGS="$BUILD_CFLAGS -D_REENTRANT=1 -DSQLITE_THREADSAFE=1"
AC_SEARCH_LIBS(pthread_create, pthread)
AC_SEARCH_LIBS(pthread_mutexattr_init, pthread)
@@ -109,14 +111,34 @@ AC_MSG_CHECKING([for whether to support dynamic extensions])
AC_MSG_RESULT($enable_dynamic_extensions)
#-----------------------------------------------------------------------
+#-----------------------------------------------------------------------
+# --enable-math
+#
+AC_ARG_ENABLE(math, [AS_HELP_STRING(
+ [--enable-math], [SQL math functions [default=yes]])],
+ [], [enable_math=yes])
+AC_MSG_CHECKING([SQL math functions])
+if test x"$enable_math" = "xyes"; then
+ BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_MATH_FUNCTIONS"
+ AC_MSG_RESULT([enabled])
+ AC_SEARCH_LIBS(ceil, m)
+else
+ AC_MSG_RESULT([disabled])
+fi
+#-----------------------------------------------------------------------
+
#-----------------------------------------------------------------------
# --enable-fts4
#
AC_ARG_ENABLE(fts4, [AS_HELP_STRING(
[--enable-fts4], [include fts4 support [default=yes]])],
[], [enable_fts4=yes])
+AC_MSG_CHECKING([FTS4 extension])
if test x"$enable_fts4" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS4"
+ AC_MSG_RESULT([enabled])
+else
+ AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------
@@ -126,8 +148,12 @@ fi
AC_ARG_ENABLE(fts3, [AS_HELP_STRING(
[--enable-fts3], [include fts3 support [default=no]])],
[], [])
+AC_MSG_CHECKING([FTS3 extension])
if test x"$enable_fts3" = "xyes" -a x"$enable_fts4" = "xno"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS3"
+ AC_MSG_RESULT([enabled])
+else
+ AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------
@@ -137,9 +163,13 @@ fi
AC_ARG_ENABLE(fts5, [AS_HELP_STRING(
[--enable-fts5], [include fts5 support [default=yes]])],
[], [enable_fts5=yes])
+AC_MSG_CHECKING([FTS5 extension])
if test x"$enable_fts5" = "xyes"; then
+ AC_MSG_RESULT([enabled])
AC_SEARCH_LIBS(log, m)
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_FTS5"
+else
+ AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------
@@ -149,8 +179,12 @@ fi
AC_ARG_ENABLE(json1, [AS_HELP_STRING(
[--enable-json1], [include json1 support [default=yes]])],
[],[enable_json1=yes])
+AC_MSG_CHECKING([JSON functions])
if test x"$enable_json1" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_JSON1"
+ AC_MSG_RESULT([enabled])
+else
+ AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------
@@ -160,8 +194,12 @@ fi
AC_ARG_ENABLE(rtree, [AS_HELP_STRING(
[--enable-rtree], [include rtree support [default=yes]])],
[], [enable_rtree=yes])
+AC_MSG_CHECKING([RTREE extension])
if test x"$enable_rtree" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_RTREE -DSQLITE_ENABLE_GEOPOLY"
+ AC_MSG_RESULT([enabled])
+else
+ AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------
@@ -171,8 +209,12 @@ fi
AC_ARG_ENABLE(session, [AS_HELP_STRING(
[--enable-session], [enable the session extension [default=no]])],
[], [])
+AC_MSG_CHECKING([Session extension])
if test x"$enable_session" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_ENABLE_SESSION -DSQLITE_ENABLE_PREUPDATE_HOOK"
+ AC_MSG_RESULT([enabled])
+else
+ AC_MSG_RESULT([disabled])
fi
#-----------------------------------------------------------------------
@@ -182,9 +224,13 @@ fi
AC_ARG_ENABLE(debug, [AS_HELP_STRING(
[--enable-debug], [build with debugging features enabled [default=no]])],
[], [])
+AC_MSG_CHECKING([Build type])
if test x"$enable_debug" = "xyes"; then
BUILD_CFLAGS="$BUILD_CFLAGS -DSQLITE_DEBUG -DSQLITE_ENABLE_SELECTTRACE -DSQLITE_ENABLE_WHERETRACE"
CFLAGS="-g -O0"
+ AC_MSG_RESULT([debug])
+else
+ AC_MSG_RESULT([release])
fi
#-----------------------------------------------------------------------
diff --git a/contrib/sqlite3/shell.c b/contrib/sqlite3/shell.c
index 6f4fee80dc1c..27de22a3819b 100644
--- a/contrib/sqlite3/shell.c
+++ b/contrib/sqlite3/shell.c
@@ -1424,7 +1424,10 @@ SQLITE_EXTENSION_INIT1
#include <assert.h>
#include <string.h>
#include <stdarg.h>
+
+#ifndef SQLITE_AMALGAMATION
/* typedef sqlite3_uint64 u64; */
+#endif /* SQLITE_AMALGAMATION */
/******************************************************************************
** The Hash Engine
@@ -3637,24 +3640,23 @@ int sqlite3_completion_init(
** appended onto the end of some other file, such as an executable.
**
** A special record must appear at the end of the file that identifies the
-** file as an appended database and provides an offset to page 1. For
-** best performance page 1 should be located at a disk page boundary, though
-** that is not required.
+** file as an appended database and provides the offset to the first page
+** of the exposed content. (Or, it is the length of the content prefix.)
+** For best performance page 1 should be located at a disk page boundary,
+** though that is not required.
**
** When opening a database using this VFS, the connection might treat
-** the file as an ordinary SQLite database, or it might treat is as a
-** database appended onto some other file. Here are the rules:
+** the file as an ordinary SQLite database, or it might treat it as a
+** database appended onto some other file. The decision is made by
+** applying the following rules in order:
**
-** (1) When opening a new empty file, that file is treated as an ordinary
-** database.
+** (1) An empty file is an ordinary database.
**
-** (2) When opening a file that begins with the standard SQLite prefix
-** string "SQLite format 3", that file is treated as an ordinary
-** database.
+** (2) If the file ends with the appendvfs trailer string
+** "Start-Of-SQLite3-NNNNNNNN" that file is an appended database.
**
-** (3) When opening a file that ends with the appendvfs trailer string
-** "Start-Of-SQLite3-NNNNNNNN" that file is treated as an appended
-** database.
+** (3) If the file begins with the standard SQLite prefix string
+** "SQLite format 3", that file is an ordinary database.
**
** (4) If none of the above apply and the SQLITE_OPEN_CREATE flag is
** set, then a new database is appended to the already existing file.
@@ -3662,13 +3664,13 @@ int sqlite3_completion_init(
** (5) Otherwise, SQLITE_CANTOPEN is returned.
**
** To avoid unnecessary complications with the PENDING_BYTE, the size of
-** the file containing the database is limited to 1GB. This VFS will refuse
-** to read or write past the 1GB mark. This restriction might be lifted in
-** future versions. For now, if you need a large database, then keep the
-** database in a separate file.
+** the file containing the database is limited to 1GiB. (1073741824 bytes)
+** This VFS will not read or write past the 1GiB mark. This restriction
+** might be lifted in future versions. For now, if you need a larger
+** database, then keep it in a separate file.
**
-** If the file being opened is not an appended database, then this shim is
-** a pass-through into the default underlying VFS.
+** If the file being opened is a plain database (not an appended one), then
+** this shim is a pass-through into the default underlying VFS. (rule 3)
**/
/* #include "sqlite3ext.h" */
SQLITE_EXTENSION_INIT1
@@ -3681,17 +3683,27 @@ SQLITE_EXTENSION_INIT1
** 123456789 123456789 12345
**
** The NNNNNNNN represents a 64-bit big-endian unsigned integer which is
-** the offset to page 1.
+** the offset to page 1, and also the length of the prefix content.
*/
#define APND_MARK_PREFIX "Start-Of-SQLite3-"
#define APND_MARK_PREFIX_SZ 17
-#define APND_MARK_SIZE 25
+#define APND_MARK_FOS_SZ 8
+#define APND_MARK_SIZE (APND_MARK_PREFIX_SZ+APND_MARK_FOS_SZ)
/*
** Maximum size of the combined prefix + database + append-mark. This
** must be less than 0x40000000 to avoid locking issues on Windows.
*/
-#define APND_MAX_SIZE (65536*15259)
+#define APND_MAX_SIZE (0x40000000)
+
+/*
+** Try to align the database to an even multiple of APND_ROUNDUP bytes.
+*/
+#ifndef APND_ROUNDUP
+#define APND_ROUNDUP 4096
+#endif
+#define APND_ALIGN_MASK ((sqlite3_int64)(APND_ROUNDUP-1))
+#define APND_START_ROUNDUP(fsz) (((fsz)+APND_ALIGN_MASK) & ~APND_ALIGN_MASK)
/*
** Forward declaration of objects used by this utility
@@ -3705,11 +3717,45 @@ typedef struct ApndFile ApndFile;
#define ORIGVFS(p) ((sqlite3_vfs*)((p)->pAppData))
#define ORIGFILE(p) ((sqlite3_file*)(((ApndFile*)(p))+1))
-/* An open file */
+/* An open appendvfs file
+**
+** An instance of this structure describes the appended database file.
+** A separate sqlite3_file object is always appended. The appended
+** sqlite3_file object (which can be accessed using ORIGFILE()) describes
+** the entire file, including the prefix, the database, and the
+** append-mark.
+**
+** The structure of an AppendVFS database is like this:
+**
+** +-------------+---------+----------+-------------+
+** | prefix-file | padding | database | append-mark |
+** +-------------+---------+----------+-------------+
+** ^ ^
+** | |
+** iPgOne iMark
+**
+**
+** "prefix file" - file onto which the database has been appended.
+** "padding" - zero or more bytes inserted so that "database"
+** starts on an APND_ROUNDUP boundary
+** "database" - The SQLite database file
+** "append-mark" - The 25-byte "Start-Of-SQLite3-NNNNNNNN" that indicates
+** the offset from the start of prefix-file to the start
+** of "database".
+**
+** The size of the database is iMark - iPgOne.
+**
+** The NNNNNNNN in the "Start-Of-SQLite3-NNNNNNNN" suffix is the value
+** of iPgOne stored as a big-ending 64-bit integer.
+**
+** iMark will be the size of the underlying file minus 25 (APND_MARKSIZE).
+** Or, iMark is -1 to indicate that it has not yet been written.
+*/
struct ApndFile {
- sqlite3_file base; /* IO methods */
- sqlite3_int64 iPgOne; /* File offset to page 1 */
- sqlite3_int64 iMark; /* Start of the append-mark */
+ sqlite3_file base; /* Subclass. MUST BE FIRST! */
+ sqlite3_int64 iPgOne; /* Offset to the start of the database */
+ sqlite3_int64 iMark; /* Offset of the append mark. -1 if unwritten */
+ /* Always followed by another sqlite3_file that describes the whole file */
};
/*
@@ -3801,8 +3847,6 @@ static const sqlite3_io_methods apnd_io_methods = {
apndUnfetch /* xUnfetch */
};
-
-
/*
** Close an apnd-file.
*/
@@ -3820,22 +3864,37 @@ static int apndRead(
int iAmt,
sqlite_int64 iOfst
){
- ApndFile *p = (ApndFile *)pFile;
+ ApndFile *paf = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
- return pFile->pMethods->xRead(pFile, zBuf, iAmt, iOfst+p->iPgOne);
+ return pFile->pMethods->xRead(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}
/*
-** Add the append-mark onto the end of the file.
+** Add the append-mark onto what should become the end of the file.
+* If and only if this succeeds, internal ApndFile.iMark is updated.
+* Parameter iWriteEnd is the appendvfs-relative offset of the new mark.
*/
-static int apndWriteMark(ApndFile *p, sqlite3_file *pFile){
- int i;
+static int apndWriteMark(
+ ApndFile *paf,
+ sqlite3_file *pFile,
+ sqlite_int64 iWriteEnd
+){
+ sqlite_int64 iPgOne = paf->iPgOne;
unsigned char a[APND_MARK_SIZE];
+ int i = APND_MARK_FOS_SZ;
+ int rc;
+ assert(pFile == ORIGFILE(paf));
memcpy(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ);
- for(i=0; i<8; i++){
- a[APND_MARK_PREFIX_SZ+i] = (p->iPgOne >> (56 - i*8)) & 0xff;
+ while( --i >= 0 ){
+ a[APND_MARK_PREFIX_SZ+i] = (unsigned char)(iPgOne & 0xff);
+ iPgOne >>= 8;
+ }
+ iWriteEnd += paf->iPgOne;
+ if( SQLITE_OK==(rc = pFile->pMethods->xWrite
+ (pFile, a, APND_MARK_SIZE, iWriteEnd)) ){
+ paf->iMark = iWriteEnd;
}
- return pFile->pMethods->xWrite(pFile, a, APND_MARK_SIZE, p->iMark);
+ return rc;
}
/*
@@ -3847,38 +3906,28 @@ static int apndWrite(
int iAmt,
sqlite_int64 iOfst
){
- int rc;
- ApndFile *p = (ApndFile *)pFile;
+ ApndFile *paf = (ApndFile *)pFile;
+ sqlite_int64 iWriteEnd = iOfst + iAmt;
+ if( iWriteEnd>=APND_MAX_SIZE ) return SQLITE_FULL;
pFile = ORIGFILE(pFile);
- if( iOfst+iAmt>=APND_MAX_SIZE ) return SQLITE_FULL;
- rc = pFile->pMethods->xWrite(pFile, zBuf, iAmt, iOfst+p->iPgOne);
- if( rc==SQLITE_OK && iOfst + iAmt + p->iPgOne > p->iMark ){
- sqlite3_int64 sz = 0;
- rc = pFile->pMethods->xFileSize(pFile, &sz);
- if( rc==SQLITE_OK ){
- p->iMark = sz - APND_MARK_SIZE;
- if( iOfst + iAmt + p->iPgOne > p->iMark ){
- p->iMark = p->iPgOne + iOfst + iAmt;
- rc = apndWriteMark(p, pFile);
- }
- }
+ /* If append-mark is absent or will be overwritten, write it. */
+ if( paf->iMark < 0 || paf->iPgOne + iWriteEnd > paf->iMark ){
+ int rc = apndWriteMark(paf, pFile, iWriteEnd);
+ if( SQLITE_OK!=rc ) return rc;
}
- return rc;
+ return pFile->pMethods->xWrite(pFile, zBuf, iAmt, paf->iPgOne+iOfst);
}
/*
** Truncate an apnd-file.
*/
static int apndTruncate(sqlite3_file *pFile, sqlite_int64 size){
- int rc;
- ApndFile *p = (ApndFile *)pFile;
+ ApndFile *paf = (ApndFile *)pFile;
pFile = ORIGFILE(pFile);
- rc = pFile->pMethods->xTruncate(pFile, size+p->iPgOne+APND_MARK_SIZE);
- if( rc==SQLITE_OK ){
- p->iMark = p->iPgOne+size;
- rc = apndWriteMark(p, pFile);
- }
- return rc;
+ /* The append mark goes out first so truncate failure does not lose it. */
+ if( SQLITE_OK!=apndWriteMark(paf, pFile, size) ) return SQLITE_IOERR;
+ /* Truncate underlying file just past append mark */
+ return pFile->pMethods->xTruncate(pFile, paf->iMark+APND_MARK_SIZE);
}
/*
@@ -3891,16 +3940,12 @@ static int apndSync(sqlite3_file *pFile, int flags){
/*
** Return the current file-size of an apnd-file.
+** If the append mark is not yet there, the file-size is 0.
*/
static int apndFileSize(sqlite3_file *pFile, sqlite_int64 *pSize){
- ApndFile *p = (ApndFile *)pFile;
- int rc;
- pFile = ORIGFILE(p);
- rc = pFile->pMethods->xFileSize(pFile, pSize);
- if( rc==SQLITE_OK && p->iPgOne ){
- *pSize -= p->iPgOne + APND_MARK_SIZE;
- }
- return rc;
+ ApndFile *paf = (ApndFile *)pFile;
+ *pSize = ( paf->iMark >= 0 )? (paf->iMark - paf->iPgOne) : 0;
+ return SQLITE_OK;
}
/*
@@ -3931,12 +3976,13 @@ static int apndCheckReservedLock(sqlite3_file *pFile, int *pResOut){
** File control method. For custom operations on an apnd-file.
*/
static int apndFileControl(sqlite3_file *pFile, int op, void *pArg){
- ApndFile *p = (ApndFile *)pFile;
+ ApndFile *paf = (ApndFile *)pFile;
int rc;
pFile = ORIGFILE(pFile);
+ if( op==SQLITE_FCNTL_SIZE_HINT ) *(sqlite3_int64*)pArg += paf->iPgOne;
rc = pFile->pMethods->xFileControl(pFile, op, pArg);
if( rc==SQLITE_OK && op==SQLITE_FCNTL_VFSNAME ){
- *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", p->iPgOne, *(char**)pArg);
+ *(char**)pArg = sqlite3_mprintf("apnd(%lld)/%z", paf->iPgOne,*(char**)pArg);
}
return rc;
}
@@ -3995,6 +4041,9 @@ static int apndFetch(
void **pp
){
ApndFile *p = (ApndFile *)pFile;
+ if( p->iMark < 0 || iOfst+iAmt > p->iMark ){
+ return SQLITE_IOERR; /* Cannot read what is not yet there. */
+ }
pFile = ORIGFILE(pFile);
return pFile->pMethods->xFetch(pFile, iOfst+p->iPgOne, iAmt, pp);
}
@@ -4006,95 +4055,153 @@ static int apndUnfetch(sqlite3_file *pFile, sqlite3_int64 iOfst, void *pPage){
return pFile->pMethods->xUnfetch(pFile, iOfst+p->iPgOne, pPage);
}
-/*
-** Check to see if the file is an ordinary SQLite database file.
-*/
-static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
- int rc;
- char zHdr[16];
- static const char aSqliteHdr[] = "SQLite format 3";
- if( sz<512 ) return 0;
- rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0);
- if( rc ) return 0;
- return memcmp(zHdr, aSqliteHdr, sizeof(zHdr))==0;
-}
-
/*
** Try to read the append-mark off the end of a file. Return the
-** start of the appended database if the append-mark is present. If
-** there is no append-mark, return -1;
+** start of the appended database if the append-mark is present.
+** If there is no valid append-mark, return -1;
+**
+** An append-mark is only valid if the NNNNNNNN start-of-database offset
+** indicates that the appended database contains at least one page. The
+** start-of-database value must be a multiple of 512.
*/
static sqlite3_int64 apndReadMark(sqlite3_int64 sz, sqlite3_file *pFile){
int rc, i;
sqlite3_int64 iMark;
+ int msbs = 8 * (APND_MARK_FOS_SZ-1);
unsigned char a[APND_MARK_SIZE];
- if( sz<=APND_MARK_SIZE ) return -1;
+ if( APND_MARK_SIZE!=(sz & 0x1ff) ) return -1;
rc = pFile->pMethods->xRead(pFile, a, APND_MARK_SIZE, sz-APND_MARK_SIZE);
if( rc ) return -1;
if( memcmp(a, APND_MARK_PREFIX, APND_MARK_PREFIX_SZ)!=0 ) return -1;
- iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ]&0x7f))<<56;
- for(i=1; i<8; i++){
- iMark += (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<(56-8*i);
+ iMark = ((sqlite3_int64)(a[APND_MARK_PREFIX_SZ] & 0x7f)) << msbs;
+ for(i=1; i<8; i++){
+ msbs -= 8;
+ iMark |= (sqlite3_int64)a[APND_MARK_PREFIX_SZ+i]<<msbs;
}
+ if( iMark > (sz - APND_MARK_SIZE - 512) ) return -1;
+ if( iMark & 0x1ff ) return -1;
return iMark;
}
+static const char apvfsSqliteHdr[] = "SQLite format 3";
+/*
+** Check to see if the file is an appendvfs SQLite database file.
+** Return true iff it is such. Parameter sz is the file's size.
+*/
+static int apndIsAppendvfsDatabase(sqlite3_int64 sz, sqlite3_file *pFile){
+ int rc;
+ char zHdr[16];
+ sqlite3_int64 iMark = apndReadMark(sz, pFile);
+ if( iMark>=0 ){
+ /* If file has the correct end-marker, the expected odd size, and the
+ ** SQLite DB type marker where the end-marker puts it, then it
+ ** is an appendvfs database.
+ */
+ rc = pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), iMark);
+ if( SQLITE_OK==rc
+ && memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))==0
+ && (sz & 0x1ff) == APND_MARK_SIZE
+ && sz>=512+APND_MARK_SIZE
+ ){
+ return 1; /* It's an appendvfs database */
+ }
+ }
+ return 0;
+}
+
+/*
+** Check to see if the file is an ordinary SQLite database file.
+** Return true iff so. Parameter sz is the file's size.
+*/
+static int apndIsOrdinaryDatabaseFile(sqlite3_int64 sz, sqlite3_file *pFile){
+ char zHdr[16];
+ if( apndIsAppendvfsDatabase(sz, pFile) /* rule 2 */
+ || (sz & 0x1ff) != 0
+ || SQLITE_OK!=pFile->pMethods->xRead(pFile, zHdr, sizeof(zHdr), 0)
+ || memcmp(zHdr, apvfsSqliteHdr, sizeof(zHdr))!=0
+ ){
+ return 0;
+ }else{
+ return 1;
+ }
+}
+
/*
** Open an apnd file handle.
*/
static int apndOpen(
- sqlite3_vfs *pVfs,
+ sqlite3_vfs *pApndVfs,
const char *zName,
sqlite3_file *pFile,
int flags,
int *pOutFlags
){
- ApndFile *p;
- sqlite3_file *pSubFile;
- sqlite3_vfs *pSubVfs;
+ ApndFile *pApndFile = (ApndFile*)pFile;
+ sqlite3_file *pBaseFile = ORIGFILE(pFile);
+ sqlite3_vfs *pBaseVfs = ORIGVFS(pApndVfs);
int rc;
- sqlite3_int64 sz;
- pSubVfs = ORIGVFS(pVfs);
+ sqlite3_int64 sz = 0;
if( (flags & SQLITE_OPEN_MAIN_DB)==0 ){
- return pSubVfs->xOpen(pSubVfs, zName, pFile, flags, pOutFlags);
+ /* The appendvfs is not to be used for transient or temporary databases.
+ ** Just use the base VFS open to initialize the given file object and
+ ** open the underlying file. (Appendvfs is then unused for this file.)
+ */
+ return pBaseVfs->xOpen(pBaseVfs, zName, pFile, flags, pOutFlags);
}
- p = (ApndFile*)pFile;
- memset(p, 0, sizeof(*p));
- pSubFile = ORIGFILE(pFile);
+ memset(pApndFile, 0, sizeof(ApndFile));
pFile->pMethods = &apnd_io_methods;
- rc = pSubVfs->xOpen(pSubVfs, zName, pSubFile, flags, pOutFlags);
- if( rc ) goto apnd_open_done;
- rc = pSubFile->pMethods->xFileSize(pSubFile, &sz);
+ pApndFile->iMark = -1; /* Append mark not yet written */
+
+ rc = pBaseVfs->xOpen(pBaseVfs, zName, pBaseFile, flags, pOutFlags);
+ if( rc==SQLITE_OK ){
+ rc = pBaseFile->pMethods->xFileSize(pBaseFile, &sz);
+ }
if( rc ){
- pSubFile->pMethods->xClose(pSubFile);
- goto apnd_open_done;
+ pBaseFile->pMethods->xClose(pBaseFile);
+ pFile->pMethods = 0;
+ return rc;
}
- if( apndIsOrdinaryDatabaseFile(sz, pSubFile) ){
- memmove(pFile, pSubFile, pSubVfs->szOsFile);
+ if( apndIsOrdinaryDatabaseFile(sz, pBaseFile) ){
+ /* The file being opened appears to be just an ordinary DB. Copy
+ ** the base dispatch-table so this instance mimics the base VFS.
+ */
+ memmove(pApndFile, pBaseFile, pBaseVfs->szOsFile);
return SQLITE_OK;
}
- p->iMark = 0;
- p->iPgOne = apndReadMark(sz, pFile);
- if( p->iPgOne>0 ){
+ pApndFile->iPgOne = apndReadMark(sz, pFile);
+ if( pApndFile->iPgOne>=0 ){
+ pApndFile->iMark = sz - APND_MARK_SIZE; /* Append mark found */
return SQLITE_OK;
}
if( (flags & SQLITE_OPEN_CREATE)==0 ){
- pSubFile->pMethods->xClose(pSubFile);
+ pBaseFile->pMethods->xClose(pBaseFile);
rc = SQLITE_CANTOPEN;
+ pFile->pMethods = 0;
+ }else{
+ /* Round newly added appendvfs location to #define'd page boundary.
+ ** Note that nothing has yet been written to the underlying file.
+ ** The append mark will be written along with first content write.
+ ** Until then, paf->iMark value indicates it is not yet written.
+ */
+ pApndFile->iPgOne = APND_START_ROUNDUP(sz);
}
- p->iPgOne = (sz+0xfff) & ~(sqlite3_int64)0xfff;
-apnd_open_done:
- if( rc ) pFile->pMethods = 0;
return rc;
*** 17973 LINES SKIPPED ***
More information about the dev-commits-src-all
mailing list