libgda r3184 - in trunk: . WixInstaller doc/C doc/C/tmpl libgda libgda/sqlite libgda/sqlite/sqlite-src libgda/sqlite/virtual po providers/mdb providers/postgres providers/skel-implementation/capi samples/Report samples/Virtual tests tests/data-models tests/multi-threading tests/providers tools



Author: vivien
Date: Sun Jul 27 19:25:27 2008
New Revision: 3184
URL: http://svn.gnome.org/viewvc/libgda?rev=3184&view=rev

Log:
2008-07-27  Vivien Malerba <malerba gnome-db org>

	* WixInstaller/make-zip-exe.sh: new script to create a .ZIP file containing
	the minimum files required to execute gda-sql
	* libgda/gda-data-model-import.c: fixed a crasher bug when the XML file being imported
	has the wrong XML structure
	* libgda/sqlite/sqlite-src/: up to version 3.6.0
	* tests/: multiple improvements and corrections
	* libgda/sqlite/gda-sqlite-recordset.c: correctly handle time and data values, and corrected
	a bug related to NULL values
	* libgda/gda-util.[ch]: new functions: gda_parse_iso8601_date(),
	gda_parse_iso8601_time() and gda_parse_iso8601_timestamp(), implementation is very simple at
	the moment
	* libgda/gda-value.c: use the new gda_parse_iso8601*() functions in gda_value_set_from_string()
	and the static set_from_string() function, and better explicit documentation
	* libgda/sqlite/virtual/gda-vconnection-data-model.c: fixed the gda_vconnection_data_model_foreach()
	function where it would not call the provided function if no data model had been associated
	to the table
	* libgda/sqlite/virtual/gda-vprovider-data-model.c: better data type mapping
	* tools/gda-sql.c: query buffer (the one which stores the last executed query) is now per
	connection and not global anymore, and initial meta data retreival is done
	in background (sub thread) if possible
	* libgda/sqlite/utils.c:
	* libgda/sqlite/gda-sqlite.h: new utility function
	* libgda/sqlite/gda-sql-meta.c:
	* providers/postgres/gda-postgres-meta.c: finished implementing meta data extraction
	* libgda/sqlite/gda-sql-provider.c: minor bug fixes, explicitely enable multi
	threading support and better support for date, time and timestamp data types
	* libgda/gda-server-provider.h: new error code
	* libgda/information_schema.xml: documented some fields, and added an "nb_args"
	attributes to the "_routines" table
	* providers/mdb/gda-mdb-provider.c: better date handling, assume "." for DIR_NAME in
	a connection string if not provided
	* doc/C: new gda-sql command manual, and minor other improvements
	* other files: bug fixes, or debug code desacivated


Added:
   trunk/WixInstaller/make-zip-exe.sh   (contents, props changed)
   trunk/doc/C/gda-sql-manual.xml
   trunk/tests/providers/prov_dbstruct.xml
   trunk/tests/test-cnc-utils.c
   trunk/tests/test-cnc-utils.h
Removed:
   trunk/samples/Report/.gdb_history
   trunk/samples/Virtual/.gdb_history
Modified:
   trunk/ChangeLog
   trunk/configure.in
   trunk/doc/C/Makefile.am
   trunk/doc/C/i_s_doc.xml
   trunk/doc/C/libgda-4.0-docs.sgml
   trunk/doc/C/libgda-4.0-sections.txt
   trunk/doc/C/limitations.xml
   trunk/doc/C/tmpl/gda-server-provider.sgml
   trunk/doc/C/tmpl/gda-util.sgml
   trunk/libgda/gda-connection.c
   trunk/libgda/gda-data-comparator.c
   trunk/libgda/gda-data-model-import.c
   trunk/libgda/gda-data-model.c
   trunk/libgda/gda-meta-struct-io.c
   trunk/libgda/gda-meta-struct.c
   trunk/libgda/gda-server-provider.h
   trunk/libgda/gda-util.c
   trunk/libgda/gda-util.h
   trunk/libgda/gda-value.c
   trunk/libgda/information_schema.xml
   trunk/libgda/sqlite/gda-sqlite-meta.c
   trunk/libgda/sqlite/gda-sqlite-provider.c
   trunk/libgda/sqlite/gda-sqlite-recordset.c
   trunk/libgda/sqlite/gda-sqlite.h
   trunk/libgda/sqlite/sqlite-src/Makefile.am
   trunk/libgda/sqlite/sqlite-src/PragmasPatch
   trunk/libgda/sqlite/sqlite-src/sqlite3.c
   trunk/libgda/sqlite/sqlite-src/sqlite3.h
   trunk/libgda/sqlite/utils.c
   trunk/libgda/sqlite/virtual/gda-vconnection-data-model.c
   trunk/libgda/sqlite/virtual/gda-vprovider-data-model.c
   trunk/po/POTFILES.in
   trunk/po/POTFILES.skip
   trunk/providers/mdb/gda-mdb-provider.c
   trunk/providers/postgres/gda-postgres-meta.c
   trunk/providers/postgres/gda-postgres-provider.c
   trunk/providers/postgres/gda-postgres-recordset.c
   trunk/providers/skel-implementation/capi/gda-capi-provider.c
   trunk/tests/Makefile.am
   trunk/tests/data-models/check_model_copy.c
   trunk/tests/data-models/check_model_import.c
   trunk/tests/gda-ddl-creator.c
   trunk/tests/gda-ddl-creator.h
   trunk/tests/multi-threading/Makefile.am
   trunk/tests/multi-threading/check_cnc_lock.c
   trunk/tests/providers/Makefile.am
   trunk/tests/providers/TYPES_SCHEMA_PostgreSQL.xml
   trunk/tests/providers/check_mysql.c
   trunk/tests/providers/check_oracle.c
   trunk/tests/providers/check_postgres.c
   trunk/tests/providers/check_sqlite.c
   trunk/tests/providers/gda_check_db.mdb
   trunk/tests/providers/prov-test-common.c
   trunk/tests/providers/prov-test-common.h
   trunk/tests/providers/prov-test-util.c
   trunk/tests/providers/prov-test-util.h
   trunk/tests/test-ddl-creator.c
   trunk/tools/gda-sql.c

Added: trunk/WixInstaller/make-zip-exe.sh
==============================================================================
--- (empty file)
+++ trunk/WixInstaller/make-zip-exe.sh	Sun Jul 27 19:25:27 2008
@@ -0,0 +1,104 @@
+#!/bin/sh
+
+#
+#
+# This script creates a .ZIP file containing a minimum set of files required
+# to execute the GDA SQL console.
+#
+# It is made to be used when cross compiling
+#
+# Variables to set are:
+# $cross_path is the location of the cross-compilation environment
+# $depend_path is the location of the dependencies (GLib, DBMS client libraries, etc)
+# $prefix is the location of the compiled and installed Libgda's sources
+# $version is the current Libgda's version
+#
+
+cross_path=/fillme
+depend_path=/local/Win32
+prefix=/fillme
+version=3.99.4
+
+
+
+#
+# no modification below
+#
+current_dir=`pwd`
+archive=${current_dir}/gda-exe-${version}.zip
+
+
+# remove current archive if it exists
+rm -f $archive
+
+#
+# Takes 3 arguments:
+# $1 = the prefix directory where files are located
+# $2 = the prefix under $1 where all the files are
+# $3 = a list of files physically in $1/$2/
+#
+function add_files_to_zip
+{
+    dir=$1
+    subdir=$2
+    files=$3
+    pushd $dir >& /dev/null
+    for item in ${files[*]}
+    do
+	echo "Adding file $dir/$subdir/$item"
+	zip ${archive} $subdir/$item >& /dev/null
+	if [ $? -ne 0 ]
+	then
+	    echo "Error (file may noy exist)"
+	    exit 1
+	fi
+    done
+    popd >& /dev/null
+}
+
+#
+# dependencies DLLs
+#
+files=(charset.dll iconv.dll intl.dll libgio-2.0-0.dll libglib-2.0-0.dll libgmodule-2.0-0.dll libgobject-2.0-0.dll libgthread-2.0-0.dll libxml2.dll zlib1.dll)
+add_files_to_zip ${depend_path}/gtk bin $files
+
+files=(libdb47.dll msvcp80.dll msvcr80.dll)
+add_files_to_zip ${depend_path}/bdb bin $files
+
+files=(libmdb-0.dll)
+add_files_to_zip ${depend_path}/mdb bin $files
+
+files=(libmySQL.dll)
+add_files_to_zip ${depend_path}/mysql bin $files
+
+files=(libpq.dll comerr32.dll gssapi32.dll k5sprt32.dll krb5_32.dll libeay32.dll libiconv2.dll libintl3.dll msvcr71.dll pgaevent.dll ssleay32.dll)
+add_files_to_zip ${depend_path}/pgsql bin $files
+
+#
+# dependencies from the cross compilation environment
+#
+files=(readline5.dll)
+add_files_to_zip $cross_path bin $files
+
+#
+# Libgda's files
+#
+files=(bdb_specs_dsn.xml information_schema.xml mdb_specs_dsn.xml mysql_specs_add_column.xml mysql_specs_create_db.xml mysql_specs_create_index.xml mysql_specs_create_table.xml mysql_specs_create_view.xml mysql_specs_drop_column.xml mysql_specs_drop_db.xml mysql_specs_drop_index.xml mysql_specs_drop_table.xml mysql_specs_drop_view.xml mysql_specs_dsn.xml mysql_specs_rename_table.xml postgres_specs_add_column.xml postgres_specs_create_db.xml postgres_specs_create_index.xml postgres_specs_create_table.xml postgres_specs_create_view.xml postgres_specs_drop_column.xml postgres_specs_drop_db.xml postgres_specs_drop_index.xml postgres_specs_drop_table.xml postgres_specs_drop_view.xml postgres_specs_dsn.xml postgres_specs_rename_table.xml sqlite_specs_add_column.xml sqlite_specs_create_db.xml sqlite_specs_create_index.xml sqlite_specs_create_table.xml sqlite_specs_create_view.xml sqlite_specs_drop_db.xml sqlite_specs_drop_index.xml sqlite_specs_drop_table.xml sqlite_specs_drop_view
 .xml sqlite_specs_dsn.xml sqlite_specs_rename_table.xml)
+add_files_to_zip $prefix share/libgda-4.0 $files
+
+files=(libgda-paramlist.dtd libgda-array.dtd libgda-server-operation.dtd)
+add_files_to_zip $prefix share/libgda-4.0/dtd $files
+
+files=(config sales_test.db)
+add_files_to_zip $prefix etc/libgda-4.0 $files
+
+files=(gda-sql-4.0.exe gda-test-connection-4.0.exe libgda-4.0-4.dll)
+add_files_to_zip $prefix bin $files
+
+files=(libgda-sqlite.dll libgda-postgres.dll libgda-mysql.dll libgda-mdb.dll libgda-bdb.dll)
+add_files_to_zip $prefix lib/libgda-4.0/providers $files
+
+#
+# The End
+#
+echo "Archive written to ${archive}"
\ No newline at end of file

Modified: trunk/configure.in
==============================================================================
--- trunk/configure.in	(original)
+++ trunk/configure.in	Sun Jul 27 19:25:27 2008
@@ -1085,7 +1085,7 @@
 then
         AM_CONDITIONAL(HAVE_SQLITE, 0)
 else
-	SQLITE_MODULES="sqlite3 >= 3.3"
+	SQLITE_MODULES="sqlite3 >= 3.6.0"
 	PKG_CHECK_MODULES(SQLITE, $SQLITE_MODULES, have_sqlite=yes, have_sqlite=no)
 	if test x"$have_sqlite" = "xyes"
 	then

Modified: trunk/doc/C/Makefile.am
==============================================================================
--- trunk/doc/C/Makefile.am	(original)
+++ trunk/doc/C/Makefile.am	Sun Jul 27 19:25:27 2008
@@ -59,7 +59,7 @@
 # Other files to distribute
 EXTRA_DIST += examples/full_example.c installation.xml limitations.xml migration.xml migration2.xml \
 	server-operation.xml gettingstarted.xml virtual.xml virtual-notice.xml store-meta-type.xml \
-	prov-writing.xml i_s_doc.xml howto.xml \
+	prov-writing.xml i_s_doc.xml howto.xml gda-sql-manual.xml \
 	DataModels.svg \
 	architecture.svg parts.svg stmt-unknown.svg stmt-select.svg stmt-insert1.svg stmt-insert2.svg \
 	stmt-update.svg stmt-compound.svg information_schema.svg

Added: trunk/doc/C/gda-sql-manual.xml
==============================================================================
--- (empty file)
+++ trunk/doc/C/gda-sql-manual.xml	Sun Jul 27 19:25:27 2008
@@ -0,0 +1,150 @@
+<para>
+  The &LIBGDA;'s console tool allow one to send SQL commands to a database server, and
+  to easily browse the meta data associated to the database (ie. get information about
+  tables and their columns, functions, triggers, etc). This tool has a usage similar to
+  PostgreSQL's <application>psql</application>, MySQL's <application>mysql</application>, Oracle's
+  <application>sqlplus</application> or SQLite's <application>sqlite3</application> programs.
+</para>
+
+<para>
+  However, contrary to the programmed mentionned above, The &LIBGDA;'s console tool
+  offers the same features and usage for any of the databases supported by &LIBGDA;.
+</para>
+
+
+<chapter id="gda-sql-manual-run">
+  <title>Getting started</title>
+
+  <sect1>
+    <title>Features</title>
+    <para>
+      The &LIBGDA;'s console tool' main features are:
+      <itemizedlist>
+	<listitem><para>Can handle more than one connection at the same time</para></listitem>
+	<listitem><para>Reports meta data in a similar way, whatever the real type of database
+	    accessed</para></listitem>
+	<listitem><para>Can create <emphasis>virtual</emphasis> connections binding 
+	    several already opened connections (to run SQL commands across multiple 
+	    connections)</para></listitem>
+	<listitem><para>Allows one to define variables which can be referenced in any
+	    SQL statement (using a common syntax)</para></listitem>
+	<listitem><para>Has one query buffer per connection to edit complex queries (uses a
+	    parametrable external editor)</para></listitem>
+	<listitem><para>Easy command line editing and output using the Readline library and a
+	    (parametrable) pager</para></listitem>
+	<listitem><para>Works on any platform on which &LIBGDA; has been ported to.</para></listitem>
+      </itemizedlist>
+    </para>
+  </sect1>
+
+  <sect1>
+    <title>Execution</title>
+    <para>
+      The &LIBGDA;'s SQL console tool runs is a terminal emulator, and can be launched using
+      the <command>gda-sql-4.0</command>:
+      <cmdsynopsis>
+	<command>gda-sql-4.0</command>
+	<arg>--help</arg>
+	<arg>-l</arg>
+	<arg>-L</arg>
+	<arg>-C <replaceable>command</replaceable></arg>
+	<arg>-f <replaceable>commands file</replaceable></arg>
+	<arg>-o <replaceable>output file</replaceable></arg>
+	<arg>-p</arg>
+	<arg rep="repeat"><replaceable>connection specification</replaceable></arg>
+      </cmdsynopsis>
+      The options are the following ones:
+      <itemizedlist>
+	<listitem><para>the <option>--help</option> option gives a short help summary</para></listitem>
+	<listitem><para>the <option>-l</option> and <option>-L</option> options respectively
+	output a list of the defined data sources (DSN) and of the installed database adaptaters
+	(database providers):
+	    <programlisting>
+[prompt]> gda-sql-4.0 -l
+List of defined data sources
+DSN       | Provider | Description                          | Connection string     | Username | Global
+----------+----------+--------------------------------------+-----------------------+----------+-------
+SalesTest | SQLite   | Test database for a sales department | DB_NAME=sales_test.db |          | FALSE 
+(1 row)
+	    </programlisting>
+	    <programlisting>
+[prompt]> gda-sql-4.0 -L
+                                                        List of installed providers
+Provider    | Description                         | DSN parameters     | Authentication | File 
+                                     
+------------+-------------------------------------+--------------------+----------------+----------------------
+-------------------------------------
+PostgreSQL  | Provider for PostgreSQL databases   | DB_NAME,           | USERNAME,      | [...]libgda-postgres.so
+                                                    SEARCHPATH,          PASSWORD               
+                                                    HOST,                
+                                                    PORT,                    
+                                                    OPTIONS,                             
+                                                    USE_SSL          
+MSAccess    | Provider for Microsoft Access files | DB_NAME,           |                | [...]libgda-mdb.so     
+                                                    DB_DIR 
+[...]            
+	    </programlisting>
+	</para></listitem>
+	<listitem><para>the <option>-C</option> and <option>-f</option> options repectively allow
+	    one to specify a single command to be run or a filename containing the commands to run
+	    before the tool exits</para></listitem>
+	<listitem><para>the <option>-o</option> option allows to specify a file to write the 
+	    output to</para></listitem>
+	<listitem><para>the <option>-p</option> speficies that the tool should not ask for
+	    passwords when a username has been specified for a connection but no password has
+	    been specified.</para></listitem>
+      </itemizedlist>
+    </para>
+    <para>
+      Connections to be opened can be specified on the command line using either defined data 
+      sources (the ones listed using the <option>-l</option> option), or using connection strings
+      which have the following format: "[&lt;provider&gt;://][&lt;username&gt;[:&lt;password&gt;] ]&lt;connection_params&gt;". Note that if provided, &lt;username&gt;, &lt;password&gt; and &lt;provider&gt; must be encoded as per RFC 1738.
+    </para>
+    <para>
+      Connections can also be opened while the tool is running using the <command>.c</command> 
+      internal command.
+    </para>
+    <para>
+      Examples:
+      <programlisting>
+[prompt]> gda-sql-4.0 Sales
+[prompt]> gda-sql-4.0 Postgresql://username DB_NAME=mydb SQLite://DB_NAME=fspot Sales	
+      </programlisting>
+    </para>
+  </sect1>
+
+</chapter>
+
+<chapter id="gda-sql-manual-open">
+  <title>Connections management</title>
+  <para>
+    Blah.
+  </para>
+
+  <sect1>
+    <title>Connection string's format</title>
+  </sect1>
+
+  <sect1>
+    <title>Meta data</title>
+  </sect1>
+
+</chapter>
+
+<chapter id="gda-sql-manual-commands">
+  <title>Executing commands</title>
+  <para>
+    Blah.
+  </para>
+
+  <sect1>
+    <title>SQL comands</title>
+  </sect1>
+
+  <sect1>
+    <title>Internal commands</title>
+  </sect1>
+
+</chapter>
+
+

Modified: trunk/doc/C/i_s_doc.xml
==============================================================================
--- trunk/doc/C/i_s_doc.xml	(original)
+++ trunk/doc/C/i_s_doc.xml	Sun Jul 27 19:25:27 2008
@@ -1,5 +1,5 @@
 <sect2>
-  <!--File generated by the tools/information-schema-doc program from the
+<!--File generated by the tools/information-schema-doc program from the
 libgda/information-schema.xml file,
 do not modify-->
   <title>Individual table description</title>
@@ -73,7 +73,7 @@
   <sect3 id="is:_element_types">
     <title>_element_types table</title>
     <para>Array specific attributes for array data types</para>
-    <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>specific_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry>No specific meaning, used as a primary key, and for joining</entry></row><row><entry>object_catalog</entry><entry>string</entry><entry></entry><entry>No</entry><entry>Name of the catalog that contains the object that uses the array being described</entry></row><row><entry>object_schema</entry><entry>string</entry><entry></entry><entry>No</entry><entry>Name of the schema that contains the object that uses the array being described</entry></row><row><entry>object_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry>Name of the object that uses the array being described</entry></row><row>
 <entry>object_type</entry><entry>string</entry><entry></entry><entry>No</entry><entry>The type of the object that uses the array being described TABLE_COL, DOMAIN, UDT_COL, ROUTINE_COL or ROUTINE_PAR</entry></row><row><entry>data_type</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Base data type of the array (if the base data type is an array, then 'array_spec' is set, and this may be NULL)</entry></row><row><entry>array_spec</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Array description if the base data type is an array</entry></row><row><entry>min_cardinality</entry><entry>gint</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>max_cardinality</entry><entry>gint</entry><entry></entry><entry>Yes</entry><entry></entry></row></tbody></tgroup></informaltable></para>
+    <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>specific_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry>No specific meaning, used as a primary key, and for joining</entry></row><row><entry>object_catalog</entry><entry>string</entry><entry></entry><entry>No</entry><entry>Name of the catalog that contains the object that uses the array being described</entry></row><row><entry>object_schema</entry><entry>string</entry><entry></entry><entry>No</entry><entry>Name of the schema that contains the object that uses the array being described</entry></row><row><entry>object_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry>Name of the object that uses the array being described</entry></row><row>
 <entry>object_type</entry><entry>string</entry><entry></entry><entry>No</entry><entry>The type of the object that uses the array being described TABLE_COL, DOMAIN, UDT_COL, ROUTINE_COL, ROUTINE_PAR</entry></row><row><entry>data_type</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Base data type of the array (if the base data type is an array, then 'array_spec' is set, and this may be NULL)</entry></row><row><entry>array_spec</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Array description if the base data type is an array</entry></row><row><entry>min_cardinality</entry><entry>gint</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>max_cardinality</entry><entry>gint</entry><entry></entry><entry>Yes</entry><entry></entry></row></tbody></tgroup></informaltable></para>
   </sect3>
   <sect3 id="is:_domains">
     <title>_domains table</title>
@@ -143,8 +143,8 @@
   </sect3>
   <sect3 id="is:_routines">
     <title>_routines table</title>
-    <para>List of functions and stored procedures</para>
-    <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>specific_catalog</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>specific_schema</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>specific_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>routine_catalog</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>routine_schema</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>routine_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry></entry></row><row><entry>routine_type</entry><entry>string</
 entry><entry></entry><entry>Yes</entry><entry>FUNCTION, PROCEDURE, AGGREGATE</entry></row><row><entry>return_type</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>returns_set</entry><entry>boolean</entry><entry></entry><entry>No</entry><entry>True if function returns a set (i.e., multiple values of the specified data type)</entry></row><row><entry>routine_body</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>routine_definition</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>external_name</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>external_language</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>parameter_style</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>is_deterministic</entry><entry>boolean</entr
 y><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>sql_data_access</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>is_null_call</entry><entry>boolean</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>routine_comments</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>routine_short_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry></entry></row><row><entry>routine_full_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry></entry></row><row><entry>routine_owner</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row></tbody></tgroup></informaltable></para>
+    <para>List of functions and stored procedures (note: the primary jey for that table is composed of (specific_catalog, specific_schema, specific_name))</para>
+    <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>specific_catalog</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry>Specific name of catalog that contains the routine</entry></row><row><entry>specific_schema</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry>Specific name of schema that contains the routine</entry></row><row><entry>specific_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry>Specific name of the routine (may be mangled for polymorphic routines)</entry></row><row><entry>routine_catalog</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Name of catalog that contains the routine (may be NULL)</entry></row><row><entry>routine_schema</entry><ent
 ry>string</entry><entry></entry><entry>Yes</entry><entry>Name of schema that contains the routine (may be NULL)</entry></row><row><entry>routine_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry>Name of the routine</entry></row><row><entry>routine_type</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>FUNCTION, PROCEDURE, AGGREGATE</entry></row><row><entry>return_type</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Data type returned by the routine (may be NULL if routine does not return any value)</entry></row><row><entry>returns_set</entry><entry>boolean</entry><entry></entry><entry>No</entry><entry>True if routine returns a set (i.e., multiple values of the specified data type or if data type may vary)</entry></row><row><entry>nb_args</entry><entry>gint</entry><entry></entry><entry>No</entry><entry>Number of arguments (-1 for variable number of arguments)</entry></row><row><entry>routine_body</entry><entry>string
 </entry><entry></entry><entry>Yes</entry><entry>If the routine is an SQL function, then SQL, else EXTERNAL</entry></row><row><entry>routine_definition</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>The source text of the routine</entry></row><row><entry>external_name</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>If the routine is an external function, then the external name (link symbol) of the function</entry></row><row><entry>external_language</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>The language the routine is written in</entry></row><row><entry>parameter_style</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Parameter style (GENERAL, JAVA, SQL, GENERAL WITH NULLS)</entry></row><row><entry>is_deterministic</entry><entry>boolean</entry><entry></entry><entry>Yes</entry><entry>Tells if the routine returns the same results given the same arguments forever</entry></row><row><entry>sql_data
 _access</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Whether the routine contains SQL and whether it reads or modifies data (NONE, CONTAINS, READS, MODIFIES)</entry></row><row><entry>is_null_call</entry><entry>boolean</entry><entry></entry><entry>Yes</entry><entry>Tells if the routine will be called if any one of its arguments is NULL</entry></row><row><entry>routine_comments</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>routine_short_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry></entry></row><row><entry>routine_full_name</entry><entry>string</entry><entry></entry><entry>No</entry><entry></entry></row><row><entry>routine_owner</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row></tbody></tgroup></informaltable></para>
     <para>
       <itemizedlist>
         <listitem>
@@ -278,8 +278,8 @@
   </sect3>
   <sect3 id="is:_parameters">
     <title>_parameters table</title>
-    <para>List of routines' (functions and stored procedures) parameters</para>
-    <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>specific_catalog</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>specific_schema</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>specific_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>ordinal_position</entry><entry>gint</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>parameter_mode</entry><entry>string</entry><entry></entry><entry>No</entry><entry></entry></row><row><entry>parameter_name</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>data_type</entry><entry>string</
 entry><entry></entry><entry>Yes</entry><entry>Data type of the parameter (if the parameter is an array, then 'array_spec' is set, and this may be NULL)</entry></row><row><entry>array_spec</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Array description if the parameter is an array</entry></row></tbody></tgroup></informaltable></para>
+    <para>List of routines' (functions and stored procedures) parameters (may not contain data for some routines which accept any type of parameter)</para>
+    <para>The following table describes the columns:<informaltable frame="all"><tgroup cols="5" colsep="1" rowsep="1" align="justify"><thead><row><entry>Column name</entry><entry>Type</entry><entry>Key</entry><entry>Can be NULL</entry><entry>description</entry></row></thead><tbody><row><entry>specific_catalog</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>specific_schema</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>specific_name</entry><entry>string</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>ordinal_position</entry><entry>gint</entry><entry>Yes</entry><entry>No</entry><entry></entry></row><row><entry>parameter_mode</entry><entry>string</entry><entry></entry><entry>No</entry><entry></entry></row><row><entry>parameter_name</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry></entry></row><row><entry>data_type</entry><entry>string</
 entry><entry></entry><entry>Yes</entry><entry>Data type of the parameter (if the parameter is an array, then 'array_spec' is set, and this may be NULL; can also be NULL if any type of parameter is accepted)</entry></row><row><entry>array_spec</entry><entry>string</entry><entry></entry><entry>Yes</entry><entry>Array description if the parameter is an array</entry></row></tbody></tgroup></informaltable></para>
     <para>
       <itemizedlist>
         <listitem>

Modified: trunk/doc/C/libgda-4.0-docs.sgml
==============================================================================
--- trunk/doc/C/libgda-4.0-docs.sgml	(original)
+++ trunk/doc/C/libgda-4.0-docs.sgml	Sun Jul 27 19:25:27 2008
@@ -110,6 +110,7 @@
 <!ENTITY fdl-appendix SYSTEM "fdl-appendix.sgml">
 <!ENTITY howto SYSTEM "howto.xml">
 <!ENTITY libgda-TreeIndex SYSTEM "xml/tree_index.sgml">
+<!ENTITY GdaSqlManual SYSTEM "gda-sql-manual.xml">
 ]>
 
 <book id="index">
@@ -1235,6 +1236,11 @@
     </chapter>
   </part>
 
+  <part id="gda-sql">
+    <title>Gda SQL console' user manual</title>
+    &GdaSqlManual;
+  </part>
+
   <part id="part_providers">
     <title>Databases providers for developers</title>
       <para>

Modified: trunk/doc/C/libgda-4.0-sections.txt
==============================================================================
--- trunk/doc/C/libgda-4.0-sections.txt	(original)
+++ trunk/doc/C/libgda-4.0-sections.txt	Sun Jul 27 19:25:27 2008
@@ -736,6 +736,10 @@
 gda_rfc1738_decode
 gda_dsn_split
 gda_connection_string_split
+<SUBSECTION>
+gda_parse_iso8601_date
+gda_parse_iso8601_time
+gda_parse_iso8601_timestamp
 </SECTION>
 
 <SECTION>

Modified: trunk/doc/C/limitations.xml
==============================================================================
--- trunk/doc/C/limitations.xml	(original)
+++ trunk/doc/C/limitations.xml	Sun Jul 27 19:25:27 2008
@@ -96,11 +96,19 @@
       </para>
     </sect2>
 
+    <sect2><title>Date and time</title>
+      <para>
+	As SQLite stores dates and times as strings, &LIBGDA; only handles dates in the format recommended by SQLite,
+	which is "YYYY-MM-DD" for dates, "HH:MM:SS" for times and "YYYY-MM-DD HH:MM:SS" for timestamps (see 
+	<ulink url="http://www.sqlite.org/cvstrac/wiki?p=DateAndTimeFunctions";>SQLite's documentation</ulink>).
+      </para>
+    </sect2>
+
     <sect2><title>Multi threaded environment</title>
       <para>
-	While waiting for the SQLite 3.6 (and the <option>SQLITE_CONFIG_SERIALIZED</option> flag), 
-	a connection object can only be used from the thread which created it (see
-	SQLite's <ulink url="http://www.sqlite.org/cvstrac/wiki?p=MultiThreading";>documentation about threads</ulink>).
+	No limitation if sqlite has been compiled with the SQLITE_THREADSAFE=1 flag (which is the case for the
+	embedded version of SQLite). If the system installed SQLite is used and if it was not compiled using that
+	flag, then &LIBGDA; sets the SQLite library in a state where multi threading is fully supported.
       </para>
     </sect2>
   </sect1>

Modified: trunk/doc/C/tmpl/gda-server-provider.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-server-provider.sgml	(original)
+++ trunk/doc/C/tmpl/gda-server-provider.sgml	Sun Jul 27 19:25:27 2008
@@ -87,6 +87,7 @@
 @GDA_SERVER_PROVIDER_BUSY_ERROR: 
 @GDA_SERVER_PROVIDER_NON_SUPPORTED_ERROR: 
 @GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR: 
+ GDA_SERVER_PROVIDER_DATA_ERROR: 
 
 <!-- ##### STRUCT GdaServerProviderMeta ##### -->
 <para>

Modified: trunk/doc/C/tmpl/gda-util.sgml
==============================================================================
--- trunk/doc/C/tmpl/gda-util.sgml	(original)
+++ trunk/doc/C/tmpl/gda-util.sgml	Sun Jul 27 19:25:27 2008
@@ -125,3 +125,33 @@
 @out_password: 
 
 
+<!-- ##### FUNCTION gda_parse_iso8601_date ##### -->
+<para>
+
+</para>
+
+ gdate: 
+ value: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gda_parse_iso8601_time ##### -->
+<para>
+
+</para>
+
+ timegda: 
+ value: 
+ Returns: 
+
+
+<!-- ##### FUNCTION gda_parse_iso8601_timestamp ##### -->
+<para>
+
+</para>
+
+ timestamp: 
+ value: 
+ Returns: 
+
+

Modified: trunk/libgda/gda-connection.c
==============================================================================
--- trunk/libgda/gda-connection.c	(original)
+++ trunk/libgda/gda-connection.c	Sun Jul 27 19:25:27 2008
@@ -2342,7 +2342,7 @@
 				return TRUE; /* nothing to do */
 
 			ASSERT_TABLE_NAME (tname, "domain_constraints");
-			if (!PROV_CLASS (provider)->meta_funcs.constraints_tab) {
+			if (!PROV_CLASS (provider)->meta_funcs.constraints_dom) {
 				WARN_METHOD_NOT_IMPLEMENTED (provider, "constraints_dom");
 				break;
 			}
@@ -2967,7 +2967,7 @@
 		} RMeta;
 
 		gint nb = 0, i;
-		static RMeta rmeta[] = {
+		RMeta rmeta[] = {
 			{"_information_schema_catalog_name", "_info", NULL},
 			{"_builtin_data_types", "_btypes", NULL},
 			{"_udt", "_udt", NULL},
@@ -3030,6 +3030,11 @@
 			else {
 				lcontext.table_name = rmeta [i].table_name;
 				if (!rmeta [i].func (provider, cnc, store, &lcontext, error)) {
+					g_print ("TH %p CNC %p ERROR, prov=%p (%s)\n", g_thread_self(), cnc,
+						 gda_connection_get_provider_obj (cnc),
+						 gda_connection_get_provider_name (cnc));
+					g_warning ("//");
+
 					WARN_META_UPDATE_FAILURE (FALSE, rmeta [i].func_name);
 					goto onerror;
 				}

Modified: trunk/libgda/gda-data-comparator.c
==============================================================================
--- trunk/libgda/gda-data-comparator.c	(original)
+++ trunk/libgda/gda-data-comparator.c	Sun Jul 27 19:25:27 2008
@@ -476,10 +476,10 @@
 		GdaDiff *diff = NULL;
 		gboolean stop;
 		
-		erow = find_row_in_model (comp, i,  &has_changed, error);
+		erow = find_row_in_model (comp, i, &has_changed, error);
 		
 #ifdef DEBUG_STORE_MODIFY
-		g_print ("FIND row %d(/%d) returned row %d (%s)\n", i, new_n_rows - 1, erow, 
+		g_print ("FIND row %d returned row %d (%s)\n", i, erow, 
 			 has_changed ? "CHANGED" : "unchanged");
 #endif
 		if (erow < 0) {

Modified: trunk/libgda/gda-data-model-import.c
==============================================================================
--- trunk/libgda/gda-data-model-import.c	(original)
+++ trunk/libgda/gda-data-model-import.c	Sun Jul 27 19:25:27 2008
@@ -1126,6 +1126,7 @@
 			g_free (str);
 			xmlFreeTextReader (reader);
 			model->priv->extract.xml.reader = NULL;
+			return;
 		}
 		node = xmlTextReaderCurrentNode (reader);
 		

Modified: trunk/libgda/gda-data-model.c
==============================================================================
--- trunk/libgda/gda-data-model.c	(original)
+++ trunk/libgda/gda-data-model.c	Sun Jul 27 19:25:27 2008
@@ -2121,7 +2121,7 @@
 		GdaColumn *gdacol;
 		GType coltype;
 
-#ifdef GDA_DEBUG
+#ifdef GDA_DEBUG_NO
 		{
 			GdaColumn *col = gda_data_model_describe_column (model, i);
 			g_print ("Model col %d has type %s\n", i, gda_g_type_to_string (gda_column_get_g_type (col)));

Modified: trunk/libgda/gda-meta-struct-io.c
==============================================================================
--- trunk/libgda/gda-meta-struct-io.c	(original)
+++ trunk/libgda/gda-meta-struct-io.c	Sun Jul 27 19:25:27 2008
@@ -122,8 +122,22 @@
 	if (! gda_meta_struct_sort_db_objects (mstruct, GDA_META_SORT_DEPENDENCIES, error)) 
 		return FALSE;
 
+#ifdef GDA_DEBUG_NO
+	GSList *objlist, *list;
+	objlist = gda_meta_struct_get_all_db_objects (mstruct);
+
+	for (list = objlist; list; list = list->next) {
+		GSList *dl;
+		g_print ("Database object: %s\n", GDA_META_DB_OBJECT (list->data)->obj_name);
+		for (dl = GDA_META_DB_OBJECT (list->data)->depend_list; dl; dl = dl->next) {
+			g_print ("   depend on %s\n", GDA_META_DB_OBJECT (dl->data)->obj_name);
+		}
+	}
+	g_slist_free (objlist);
+#endif
+
 	/* dump as a graph */
-#ifdef GDA_DEBUG
+#ifdef GDA_DEBUG_NO
 	gchar *graph;
 	GError *lerror = NULL;
 	graph = gda_meta_struct_dump_as_graph (mstruct, GDA_META_GRAPH_COLUMNS, &lerror);
@@ -360,6 +374,12 @@
 			g_array_free (fk_names_array, FALSE);
 			g_array_free (ref_pk_names_array, FALSE);
 			mtable->fk_list = g_slist_append (mtable->fk_list, mfkey);
+
+			if (mfkey->depend_on->obj_type == GDA_META_DB_TABLE) {
+				GdaMetaTable *dot = GDA_META_TABLE (mfkey->depend_on);
+				dot->reverse_fk_list = g_slist_prepend (dot->reverse_fk_list, mfkey);
+			}
+			dbobj->depend_list = g_slist_append (dbobj->depend_list, mfkey->depend_on);
 		}
 	}
 	mtable->pk_cols_array = (gint*) pk_cols_array->data;

Modified: trunk/libgda/gda-meta-struct.c
==============================================================================
--- trunk/libgda/gda-meta-struct.c	(original)
+++ trunk/libgda/gda-meta-struct.c	Sun Jul 27 19:25:27 2008
@@ -509,7 +509,7 @@
 			dbo->obj_short_name = g_strdup (g_value_get_string (short_name));
 		if (full_name)
 			dbo->obj_full_name = g_strdup (g_value_get_string (full_name));
-		if (owner)
+		if (owner && !gda_value_is_null (owner))
 			dbo->obj_owner = g_strdup (g_value_get_string (owner));
 	}
 	else if (dbo->obj_type == type) 
@@ -613,8 +613,11 @@
 			dbo->obj_short_name = g_strdup (g_value_get_string (gda_data_model_get_value_at (model, 4, 0)));
 		if (!dbo->obj_full_name)
 			dbo->obj_full_name = g_strdup (g_value_get_string (gda_data_model_get_value_at (model, 5, 0)));
-		if (!dbo->obj_owner)
-			dbo->obj_owner = g_strdup (g_value_get_string (gda_data_model_get_value_at (model, 7, 0)));
+		if (!dbo->obj_owner) {
+			const GValue *cv = gda_data_model_get_value_at (model, 7, 0);
+			if (cv && !gda_value_is_null (cv))
+				dbo->obj_owner = g_strdup (g_value_get_string (cv));
+		}
 
 		mt = GDA_META_TABLE (dbo);
 		for (i = 0; i < nrows; i++) {
@@ -1866,7 +1869,7 @@
 	}
 	else {
 		mstruct->priv->db_objects = g_slist_append (mstruct->priv->db_objects, dbo);
-		g_hash_table_insert (mstruct->priv->index, dbo->obj_full_name, dbo);
+		g_hash_table_insert (mstruct->priv->index, g_strdup (dbo->obj_full_name), dbo);
 		return dbo;
 	}
 }

Modified: trunk/libgda/gda-server-provider.h
==============================================================================
--- trunk/libgda/gda-server-provider.h	(original)
+++ trunk/libgda/gda-server-provider.h	Sun Jul 27 19:25:27 2008
@@ -56,7 +56,8 @@
 	GDA_SERVER_PROVIDER_INTERNAL_ERROR,
 	GDA_SERVER_PROVIDER_BUSY_ERROR,
 	GDA_SERVER_PROVIDER_NON_SUPPORTED_ERROR,
-	GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR
+	GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
+	GDA_SERVER_PROVIDER_DATA_ERROR
 } GdaServerProviderError;
 
 struct _GdaServerProvider {

Modified: trunk/libgda/gda-util.c
==============================================================================
--- trunk/libgda/gda-util.c	(original)
+++ trunk/libgda/gda-util.c	Sun Jul 27 19:25:27 2008
@@ -261,12 +261,13 @@
 
 /**
  * gda_utility_data_model_dump_data_to_xml
- * @model: 
+ * @model: a #GdaDataModel
+ * @parent: the parent XML node
  * @cols: an array containing which columns of @model will be exported, or %NULL for all columns
  * @nb_cols: the number of columns in @cols
  * @rows: an array containing which rows of @model will be exported, or %NULL for all rows
  * @nb_rows: the number of rows in @rows
- * @name: name to use for the XML resulting table.
+ * @use_col_ids:
  *
  * Dump the data in a #GdaDataModel into a xmlNodePtr (as used in libxml).
  */
@@ -317,7 +318,7 @@
 	else
 		nrows = nb_rows;
 	if (nrows > 0) {
-		xmlNodePtr row, data, field;
+		xmlNodePtr row, data;
 		gint r, c;
 
 		data = xmlNewChild (parent, NULL, (xmlChar*)"gda_array_data", NULL);
@@ -326,34 +327,32 @@
 			for (c = 0; c < rnb_cols; c++) {
 				GValue *value;
 				gchar *str = NULL;
-				gboolean isnull = FALSE;
+				xmlNodePtr field = NULL;
 
 				value = (GValue *) gda_data_model_get_value_at (model, rcols [c], rows ? rows [r] : r);
-				if (!value || gda_value_is_null ((GValue *) value)) 
-					isnull = TRUE;
-				else {
+				
+				if (value && !gda_value_is_null ((GValue *) value)) { 
 					if (G_VALUE_TYPE (value) == G_TYPE_BOOLEAN)
 						str = g_strdup (g_value_get_boolean (value) ? "TRUE" : "FALSE");
 					else if (G_VALUE_TYPE (value) == G_TYPE_STRING) {
-						if (!g_value_get_string (value))
-							isnull = TRUE;
-						else
+						if (g_value_get_string (value))
 							str = gda_value_stringify (value);	
 					}
 					else
 						str = gda_value_stringify (value);
 				}
 				if (!use_col_ids) {
-					if (! str || (str && (*str == 0)))
-						field = xmlNewChild (row, NULL,  (xmlChar*)"gda_value", NULL);
-					else
+					if (str && *str) 
 						field = xmlNewChild (row, NULL,  (xmlChar*)"gda_value", (xmlChar*)str);
+					else
+						field = xmlNewChild (row, NULL,  (xmlChar*)"gda_value", NULL);
 				}
 				else {
 					field = xmlNewChild (row, NULL,  (xmlChar*)"gda_array_value", (xmlChar*)str);
 					xmlSetProp(field, (xmlChar*)"colid",  (xmlChar*)col_ids [c]);
 				}
-				if (isnull)
+
+				if (!str)
 					xmlSetProp(field,  (xmlChar*)"isnull", (xmlChar*)"t");
 
 				g_free (str);
@@ -1616,3 +1615,150 @@
 	gda_rfc1738_decode (*out_username);
 	gda_rfc1738_decode (*out_password);
 }
+
+/**
+ * gda_parse_iso8601_date
+ * @gdate: a pointer to a #GDate structure which will be filled
+ * @value: a string
+ *
+ * Extracts date parts from @value, and sets @gdate's contents
+ *
+ * Accepted date format is "YYYY-MM-DD".
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_parse_iso8601_date (GDate *gdate, const gchar *value)
+{
+	GDateYear year;
+	GDateMonth month;
+	GDateDay day;
+
+	year = atoi (value);
+	value += 5;
+	month = atoi (value);
+	value += 3;
+	day = atoi (value);
+	
+	g_date_clear (gdate, 1);
+	if (g_date_valid_dmy (day, month, year)) {
+		g_date_set_dmy (gdate, day, month, year);
+		return TRUE;
+	}
+	else
+		return FALSE;
+}
+
+/**
+ * gda_parse_iso8601_time
+ * @timegda: a pointer to a #GdaTime structure which will be filled
+ * @value: a string
+ *
+ * Extracts time parts from @value, and sets @timegda's contents
+ *
+ * Accepted date format is "HH:MM:SS[.ms][TZ]" where TZ is +hour or -hour
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_parse_iso8601_time (GdaTime *timegda, const gchar *value)
+{
+	timegda->hour = atoi (value);
+	value += 3;
+	timegda->minute = atoi (value);
+	value += 3;
+	timegda->second = atoi (value);
+	value += 2;
+	if (*value != '.') {
+		timegda->fraction = 0;
+	} else {
+		gint ndigits = 0;
+		gint64 fraction;
+
+		value++;
+		fraction = atol (value);
+		while (*value && *value != '+') {
+			value++;
+			ndigits++;
+		}
+
+		while (ndigits < 3) {
+			fraction *= 10;
+			ndigits++;
+		}
+
+		while (fraction > 0 && ndigits > 3) {
+			fraction /= 10;
+			ndigits--;
+		}
+		
+		timegda->fraction = fraction;
+	}
+
+	if (*value)
+		timegda->timezone = atol (value) * 60 * 60;
+	else
+		timegda->timezone = 0;
+
+	return TRUE;
+}
+
+/**
+ * gda_parse_iso8601_timestamp
+ * @timestamp: a pointer to a #GdaTimeStamp structure which will be filled
+ * @value: a string
+ *
+ * Extracts date and time parts from @value, and sets @timestamp's contents
+ *
+ * Accepted date format is "YYYY-MM-DD HH:MM:SS[.ms][TZ]" where TZ is +hour or -hour
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_parse_iso8601_timestamp (GdaTimestamp *timestamp, const gchar *value)
+{
+	timestamp->year = atoi (value);
+	value += 5;
+	timestamp->month = atoi (value);
+	value += 3;
+	timestamp->day = atoi (value);
+	value += 3;
+	timestamp->hour = atoi (value);
+	value += 3;
+	timestamp->minute = atoi (value);
+	value += 3;
+	timestamp->second = atoi (value);
+	value += 2;
+	if (*value != '.') {
+		timestamp->fraction = 0;
+	} else {
+		gint ndigits = 0;
+		gint64 fraction;
+
+		value++;
+		fraction = atol (value);
+		while (*value && *value != '+') {
+			value++;
+			ndigits++;
+		}
+
+		while (ndigits < 3) {
+			fraction *= 10;
+			ndigits++;
+		}
+
+		while (fraction > 0 && ndigits > 3) {
+			fraction /= 10;
+			ndigits--;
+		}
+		
+		timestamp->fraction = fraction;
+	}
+
+	if (*value)
+		timestamp->timezone = atol (value) * 60 * 60;
+	else
+		timestamp->timezone = 0;
+
+	return TRUE;
+}

Modified: trunk/libgda/gda-util.h
==============================================================================
--- trunk/libgda/gda-util.h	(original)
+++ trunk/libgda/gda-util.h	Sun Jul 27 19:25:27 2008
@@ -78,6 +78,14 @@
 					  gchar **out_username, gchar **out_password);
 void         gda_connection_string_split (const gchar *string, gchar **out_cnc_params, gchar **out_provider, 
 					  gchar **out_username, gchar **out_password);
+
+/*
+ * Date and time parsing from ISO 8601 (well, part of it)
+ */
+gboolean     gda_parse_iso8601_date (GDate *gdate, const gchar *value);
+gboolean     gda_parse_iso8601_time (GdaTime *timegda, const gchar *value);
+gboolean     gda_parse_iso8601_timestamp (GdaTimestamp *timestamp, const gchar *value);
+
 G_END_DECLS
 
 #endif

Modified: trunk/libgda/gda-value.c
==============================================================================
--- trunk/libgda/gda-value.c	(original)
+++ trunk/libgda/gda-value.c	Sun Jul 27 19:25:27 2008
@@ -63,58 +63,38 @@
 	type = G_VALUE_TYPE (value);
 	g_value_reset (value);
 
-	if (g_value_type_transformable (G_TYPE_STRING, type)) {
-		/* use the GLib type transformation function */
-		GValue *string;
-
-                string = g_new0 (GValue, 1);
-                g_value_init (string, G_TYPE_STRING);
-                g_value_set_string (string, as_string);
-
-                g_value_transform (string, value);
-                gda_value_free (string);
-
-                return TRUE;
-	}
-
 	/* custom transform function */
 	retval = FALSE;
 	if (type == G_TYPE_BOOLEAN) {
-		if (g_ascii_strcasecmp (as_string, "true") == 0) {
+		if (((as_string[0] == 't') || (as_string[0] == 'T')) &&
+		    ((as_string[1] == 'r') || (as_string[1] == 'R')) &&
+		    ((as_string[2] == 'u') || (as_string[2] == 'U')) &&
+		    ((as_string[3] == 'e') || (as_string[3] == 'E'))) {
 			g_value_set_boolean (value, TRUE);
 			retval = TRUE;
 		}
-		else {
-			if (g_ascii_strcasecmp (as_string, "false") == 0) {
-				g_value_set_boolean (value, FALSE);
-				retval = TRUE;
-			}
+		else if (((as_string[0] == 'f') || (as_string[0] == 'F')) &&
+			 ((as_string[1] == 'a') || (as_string[1] == 'A')) &&
+			 ((as_string[2] == 'l') || (as_string[2] == 'L')) &&
+			 ((as_string[3] == 's') || (as_string[3] == 'S')) &&
+			 ((as_string[4] == 'e') || (as_string[4] == 'E'))) {
+			g_value_set_boolean (value, FALSE);
+			retval = TRUE;
 		}
 	}
-	else if (type == GDA_TYPE_BINARY) {
-		GdaBinary binary;
-		retval = gda_string_to_binary (as_string, &binary);
-		if (retval)
-			gda_value_set_binary (value, &binary);
-	}
-	else if (type == GDA_TYPE_BLOB) {
-		GdaBlob blob;
-		retval = gda_string_to_blob (as_string, &blob);
-		if (retval)
-			gda_value_set_blob (value, &blob);
-	}
 	else if (type == G_TYPE_INT64) {
-		/* Use g_strtod instead of strtoll */
-		dvalue = g_strtod (as_string, endptr);
+		gint64 i64;
+		i64 = g_ascii_strtoll (as_string, endptr, 10);
 		if (*as_string != '\0' && **endptr == '\0'){
-			g_value_set_int64 (value, (gint64) dvalue);
+			g_value_set_int64 (value, i64);
 			retval = TRUE;
 		}
 	}
 	else if (type == G_TYPE_UINT64) {
- 	        dvalue = g_strtod (as_string, endptr);
-                if (*as_string!=0 && **endptr==0) {
-			g_value_set_uint64(value,(guint64)dvalue);
+		guint64 ui64;
+		ui64 = g_ascii_strtoull (as_string, endptr, 10);
+		if (*as_string != '\0' && **endptr == '\0'){
+			g_value_set_uint64 (value, ui64);
 			retval = TRUE;
                 }
 	}
@@ -147,28 +127,28 @@
 		}
 	}
 	else if (type == G_TYPE_CHAR) {
-		lvalue = strtol(as_string, endptr, 10);
+		lvalue = strtol (as_string, endptr, 10);
 		if (*as_string!=0 && **endptr==0) {
 			g_value_set_char(value,(gchar)lvalue);
 			retval = TRUE;
 		}
 	}
 	else if (type == G_TYPE_UCHAR) {
-		ulvalue = strtoul(as_string,endptr, 10);
+		ulvalue = strtoul (as_string,endptr, 10);
 		if (*as_string!=0 && **endptr==0) {
 			g_value_set_uchar(value,(guchar)ulvalue);
 			retval = TRUE;
 		}
 	}
 	else if (type == G_TYPE_FLOAT) {
-		dvalue = g_strtod (as_string, endptr);
+		dvalue = g_ascii_strtod (as_string, endptr);
 		if (*as_string != '\0' && **endptr == '\0'){
 			g_value_set_float (value, (gfloat) dvalue);
 			retval = TRUE;
 		}
 	}
 	else if (type == G_TYPE_DOUBLE) {
-		dvalue = g_strtod (as_string, endptr);
+		dvalue = g_ascii_strtod (as_string, endptr);
 		if (*as_string != '\0' && **endptr == '\0'){
 			g_value_set_double (value, dvalue);
 			retval = TRUE;
@@ -176,7 +156,7 @@
 	}
 	else if (type == GDA_TYPE_NUMERIC) {
 		GdaNumeric numeric;
-		/* FIXME: what test whould i do for numeric? */
+		/* FIXME: what test whould i do for numeric? Use GMP (http://gmplib.org/) ?*/
 		numeric.number = g_strdup (as_string);
 		numeric.precision = 0; /* FIXME */
 		numeric.width = 0; /* FIXME */
@@ -187,14 +167,28 @@
 	else if (type == G_TYPE_DATE) {
 		GDate *gdate;
 		gdate = g_date_new ();
-		g_date_set_parse (gdate, as_string);
-		if (g_date_valid (gdate)) {
+
+		if (gda_parse_iso8601_date (gdate, as_string)) {
 			g_value_take_boxed (value, gdate);
 			retval = TRUE;
 		}
 		else
 			g_date_free (gdate);
 	}
+	else if (type == GDA_TYPE_TIME) {
+		GdaTime timegda;
+		if (gda_parse_iso8601_time (&timegda, as_string)) {
+			gda_value_set_time (value, &timegda);
+			retval = TRUE;
+		}
+	}
+	else if (type == GDA_TYPE_TIMESTAMP) {
+		GdaTimestamp timestamp;
+		if (gda_parse_iso8601_timestamp (&timestamp, as_string)) {
+			gda_value_set_timestamp (value, &timestamp);
+			retval = TRUE;
+		}
+	}
 	else if (type == GDA_TYPE_NULL) {
 		gda_value_set_null (value);
 		retval = TRUE;
@@ -212,6 +206,33 @@
 			}
 		}
 	}
+	else if (type == GDA_TYPE_BINARY) {
+		GdaBinary binary;
+		retval = gda_string_to_binary (as_string, &binary);
+		if (retval)
+			gda_value_set_binary (value, &binary);
+	}
+	else if (type == GDA_TYPE_BLOB) {
+		GdaBlob blob;
+		retval = gda_string_to_blob (as_string, &blob);
+		if (retval)
+			gda_value_set_blob (value, &blob);
+	}
+
+
+	if (!retval && g_value_type_transformable (G_TYPE_STRING, type)) {
+		/* use the GLib type transformation function */
+		GValue *string;
+
+                string = g_new0 (GValue, 1);
+                g_value_init (string, G_TYPE_STRING);
+                g_value_set_string (string, as_string);
+
+                g_value_transform (string, value);
+                gda_value_free (string);
+
+                retval = TRUE;
+	}
 
 	return retval;
 }
@@ -1145,7 +1166,12 @@
  * @as_string: stringified representation of the value.
  * @type: the new value type.
  *
- * Makes a new #GValue of type @type from its string representation.
+ * Makes a new #GValue of type @type from its string representation. 
+ *
+ * For more information
+ * about the string format, see the gda_value_set_from_string() function.
+ * This function is typically used when reading configuration files or other non-user input that should be locale 
+ * independent.
  *
  * Returns: the newly created #GValue or %NULL if the string representation
  * cannot be converted to the specified @type.
@@ -1172,9 +1198,14 @@
  *
  * Creates a GValue from an XML representation of it. That XML
  * node corresponds to the following string representation:
- *    &lt;value type="gdatype"&gt;value&lt;/value&gt;
+ * &lt;value type="gdatype"&gt;value&lt;/value&gt;
  *
- * Returns:  the newly created #GValue.
+ * For more information
+ * about the string format, see the gda_value_set_from_string() function.
+ * This function is typically used when reading configuration files or other non-user input that should be locale 
+ * independent.
+ *
+ * Returns: the newly created #GValue.
  */
 GValue *
 gda_value_new_from_xml (const xmlNodePtr node)
@@ -1666,6 +1697,18 @@
  *
  * Stores the value data from its string representation as @type.
  *
+ * The accepted formats are:
+ * <itemizedlist>
+ *   <listitem><para>G_TYPE_BOOLEAN: a caseless comparison is made with "true" or "false"</para></listitem>
+ *   <listitem><para>numerical types: C locale format (dot as a fraction separator)</para></listitem>
+ *   <listitem><para>G_TYPE_DATE: see <link linkend="gda-parse-iso8601-date">gda_parse_iso8601_date()</link></para></listitem>
+ *   <listitem><para>GDA_TYPE_TIME: see <link linkend="gda-parse-iso8601-time">gda_parse_iso8601_time()</link></para></listitem>
+ *   <listitem><para>GDA_TYPE_TIMESTAMP: see <link linkend="gda-parse-iso8601-timestamp">gda_parse_iso8601_timestamp()</link></para></listitem>
+ * </itemizedlist>
+ *
+ * This function is typically used when reading configuration files or other non-user input that should be locale 
+ * independent.
+ *
  * Returns: %TRUE if the value has been converted to @type from
  * its string representation; it not means that the value is converted 
  * successfully, just that the transformation is avairable. %FALSE otherwise.

Modified: trunk/libgda/information_schema.xml
==============================================================================
--- trunk/libgda/information_schema.xml	(original)
+++ trunk/libgda/information_schema.xml	Sun Jul 27 19:25:27 2008
@@ -130,7 +130,7 @@
     <column name="object_catalog" descr="Name of the catalog that contains the object that uses the array being described"/>
     <column name="object_schema" descr="Name of the schema that contains the object that uses the array being described"/>
     <column name="object_name" descr="Name of the object that uses the array being described"/>
-    <column name="object_type" descr="The type of the object that uses the array being described TABLE_COL, DOMAIN, UDT_COL, ROUTINE_COL or ROUTINE_PAR"/>
+    <column name="object_type" descr="The type of the object that uses the array being described TABLE_COL, DOMAIN, UDT_COL, ROUTINE_COL, ROUTINE_PAR"/>
     <column name="data_type" nullok="TRUE" descr="Base data type of the array (if the base data type is an array, then 'array_spec' is set, and this may be NULL)"/>
     <column name="array_spec" nullok="TRUE" descr="Array description if the base data type is an array"/>
     <column name="min_cardinality" type="gint" nullok="TRUE"/>
@@ -250,24 +250,25 @@
     </unique>
   </table>
 
-  <table name="_routines" descr="List of functions and stored procedures">
-    <column name="specific_catalog" pkey="TRUE"/>
-    <column name="specific_schema" pkey="TRUE"/>
-    <column name="specific_name" pkey="TRUE"/>
-    <column name="routine_catalog" nullok="TRUE"/>
-    <column name="routine_schema" nullok="TRUE"/>
-    <column name="routine_name"/>
+  <table name="_routines" descr="List of functions and stored procedures (note: the primary jey for that table is composed of (specific_catalog, specific_schema, specific_name))">
+    <column name="specific_catalog" pkey="TRUE" descr="Specific name of catalog that contains the routine"/>
+    <column name="specific_schema" pkey="TRUE" descr="Specific name of schema that contains the routine"/>
+    <column name="specific_name" pkey="TRUE" descr="Specific name of the routine (may be mangled for polymorphic routines)"/>
+    <column name="routine_catalog" nullok="TRUE" descr="Name of catalog that contains the routine (may be NULL)"/>
+    <column name="routine_schema" nullok="TRUE" descr="Name of schema that contains the routine (may be NULL)"/>
+    <column name="routine_name" descr="Name of the routine"/>
     <column name="routine_type" nullok="TRUE" descr="FUNCTION, PROCEDURE, AGGREGATE"/>
-    <column name="return_type" nullok="TRUE"/>
-    <column name="returns_set" type="boolean" descr="True if function returns a set (i.e., multiple values of the specified data type)"/>
-    <column name="routine_body" nullok="TRUE"/>
-    <column name="routine_definition" nullok="TRUE"/>
-    <column name="external_name" nullok="TRUE"/>
-    <column name="external_language" nullok="TRUE"/>
-    <column name="parameter_style" nullok="TRUE"/>
-    <column name="is_deterministic" type="boolean" nullok="TRUE"/>
-    <column name="sql_data_access" nullok="TRUE"/>
-    <column name="is_null_call" type="boolean" nullok="TRUE"/>
+    <column name="return_type" nullok="TRUE" descr="Data type returned by the routine (may be NULL if routine does not return any value)"/>
+    <column name="returns_set" type="boolean" descr="True if routine returns a set (i.e., multiple values of the specified data type or if data type may vary)"/>
+    <column name="nb_args" type="gint" descr="Number of arguments (-1 for variable number of arguments)"/>
+    <column name="routine_body" nullok="TRUE" descr="If the routine is an SQL function, then SQL, else EXTERNAL"/>
+    <column name="routine_definition" nullok="TRUE" descr="The source text of the routine"/>
+    <column name="external_name" nullok="TRUE" descr="If the routine is an external function, then the external name (link symbol) of the function"/>
+    <column name="external_language" nullok="TRUE" descr="The language the routine is written in"/>
+    <column name="parameter_style" nullok="TRUE" descr="Parameter style (GENERAL, JAVA, SQL, GENERAL WITH NULLS)"/>
+    <column name="is_deterministic" type="boolean" nullok="TRUE" descr="Tells if the routine returns the same results given the same arguments forever"/>
+    <column name="sql_data_access" nullok="TRUE" descr="Whether the routine contains SQL and whether it reads or modifies data (NONE, CONTAINS, READS, MODIFIES)"/>
+    <column name="is_null_call" type="boolean" nullok="TRUE" descr="Tells if the routine will be called if any one of its arguments is NULL"/>
     <column name="routine_comments" nullok="TRUE"/>
     <column name="routine_short_name"/>
     <column name="routine_full_name"/>
@@ -492,14 +493,14 @@
     </fkey>
   </table>
 
-  <table name="_parameters" descr="List of routines' (functions and stored procedures) parameters">
+  <table name="_parameters" descr="List of routines' (functions and stored procedures) parameters (may not contain data for some routines which accept any type of parameter)">
     <column name="specific_catalog" pkey="TRUE"/>
     <column name="specific_schema" pkey="TRUE"/>
     <column name="specific_name" pkey="TRUE"/>
     <column name="ordinal_position" type="gint" pkey="TRUE"/>
     <column name="parameter_mode"/>
     <column name="parameter_name" nullok="TRUE"/>
-    <column name="data_type" nullok="TRUE" descr="Data type of the parameter (if the parameter is an array, then 'array_spec' is set, and this may be NULL)"/>
+    <column name="data_type" nullok="TRUE" descr="Data type of the parameter (if the parameter is an array, then 'array_spec' is set, and this may be NULL; can also be NULL if any type of parameter is accepted)"/>
     <column name="array_spec" nullok="TRUE" descr="Array description if the parameter is an array"/>
     <fkey ref_table="_routines">
       <part column="specific_catalog"/>

Modified: trunk/libgda/sqlite/gda-sqlite-meta.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-meta.c	(original)
+++ trunk/libgda/sqlite/gda-sqlite-meta.c	Sun Jul 27 19:25:27 2008
@@ -43,7 +43,8 @@
 	I_PRAGMA_TABLE_INFO,
 	I_PRAGMA_INDEX_LIST,
 	I_PRAGMA_INDEX_INFO,
-	I_PRAGMA_FK_LIST
+	I_PRAGMA_FK_LIST,
+	I_PRAGMA_PROCLIST
 } InternalStatementItem;
 
 
@@ -64,7 +65,10 @@
 	"PRAGMA index_info (##idxname::string)",
 
 	/* I_PRAGMA_FK_LIST */
-	"PRAGMA foreign_key_list (##tblname::string)"
+	"PRAGMA foreign_key_list (##tblname::string)",
+
+	/* I_PRAGMA_PROCLIST */
+	"PRAGMA proc_list"
 };
 /* name of the temporary database we don't want */
 #define TMP_DATABASE_NAME "temp"
@@ -86,6 +90,7 @@
 static GValue       *view_type_value;
 static GValue       *view_check_option;
 static GValue       *false_value;
+static GValue       *true_value;
 static GValue       *zero_value;
 static GValue       *rule_value;
 static GdaSet       *pragma_set;
@@ -122,6 +127,7 @@
 	g_value_set_string ((view_type_value = gda_value_new (G_TYPE_STRING)), "VIEW");
 	g_value_set_string ((view_check_option = gda_value_new (G_TYPE_STRING)), "NONE");
 	g_value_set_boolean ((false_value = gda_value_new (G_TYPE_BOOLEAN)), FALSE);
+	g_value_set_boolean ((true_value = gda_value_new (G_TYPE_BOOLEAN)), TRUE);
 	g_value_set_int ((zero_value = gda_value_new (G_TYPE_INT)), 0);
 	g_value_set_string ((rule_value = gda_value_new (G_TYPE_STRING)), "NONE");
 
@@ -176,8 +182,6 @@
 	mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
 	g_assert (mod_model);
 
-	GValue *vint;
-	g_value_set_boolean (vint = gda_value_new (G_TYPE_BOOLEAN), FALSE);
 	for (i = 0; i < sizeof (internal_types) / sizeof (InternalType); i++) {
 		GValue *v1, *v2, *v3, *v4;
 		InternalType *it = &(internal_types[i]);
@@ -196,7 +200,7 @@
 				   TRUE, v2, /* gtype */
 				   TRUE, v3, /* comments */
 				   TRUE, v4, /* synonyms */
-				   FALSE, vint /* internal */)) {
+				   FALSE, false_value /* internal */)) {
 			retval = FALSE;
 			break;
 		}
@@ -204,18 +208,186 @@
 	if (retval) 
 		retval = gda_meta_store_modify (store, context->table_name, mod_model, NULL, error, NULL);
 	g_object_unref (mod_model);
-	gda_value_free (vint);
 
 	return retval;
 }
 
+/* 
+ * copied from SQLite's sources to determine column affinity 
+ */
+static gint
+get_affinity (const gchar *type)
+{
+	guint32 h = 0;
+	gint aff = SQLITE_TEXT;
+	const unsigned char *ptr = (unsigned char *) type;
+	
+	while( *ptr ){
+		h = (h<<8) + g_ascii_tolower(*ptr);
+		ptr++;
+		if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){             /* CHAR */
+			aff = SQLITE_TEXT;
+		}else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){       /* CLOB */
+			aff = SQLITE_TEXT;
+		}else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){       /* TEXT */
+			aff = SQLITE_TEXT;
+		}else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */
+			  && (aff==SQLITE_INTEGER || aff==SQLITE_FLOAT) ){
+			aff = 0;
+		}else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l')          /* REAL */
+			  && aff==SQLITE_INTEGER ){
+			aff = SQLITE_FLOAT;
+		}else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a')          /* FLOA */
+			  && aff==SQLITE_INTEGER ){
+			aff = SQLITE_FLOAT;
+		}else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b')          /* DOUB */
+			  && aff==SQLITE_INTEGER ){
+			aff = SQLITE_FLOAT;
+		}else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */
+			aff = SQLITE_INTEGER;
+			break;
+		}
+	}
+	
+	return aff;
+}
+
+static gboolean
+fill_udt_model (SqliteConnectionData *cdata, GHashTable *added_hash, 
+		GdaDataModel *mod_model, const GValue *p_udt_schema, GError **error)
+{
+	gint status;
+	sqlite3_stmt *tables_stmt = NULL;
+	gchar *str;
+	const gchar *cstr;
+	gboolean retval = TRUE;
+
+	cstr = g_value_get_string (p_udt_schema);
+	str = g_strdup_printf ("SELECT name FROM %s.sqlite_master WHERE type='table' AND name not like 'sqlite_%%'", cstr);
+	status = sqlite3_prepare_v2 (cdata->connection, str, -1, &tables_stmt, NULL);
+	g_free (str);
+	if ((status != SQLITE_OK) || !tables_stmt)
+		return FALSE;
+	
+	if (!cdata->types)
+                _gda_sqlite_compute_types_hash (cdata);
+
+	for (status = sqlite3_step (tables_stmt); status == SQLITE_ROW; status = sqlite3_step (tables_stmt)) {
+		gchar *sql;
+		sqlite3_stmt *fields_stmt;
+		gint fields_status;
+
+		if (strcmp (cstr, "main")) 
+			sql = g_strdup_printf ("PRAGMA table_info('%s.%s');", cstr, sqlite3_column_text (tables_stmt, 0));
+		else
+			sql = g_strdup_printf ("PRAGMA table_info('%s');", sqlite3_column_text (tables_stmt, 0));
+		fields_status = sqlite3_prepare_v2 (cdata->connection, sql, -1, &fields_stmt, NULL);
+		g_free (sql);
+		if ((fields_status != SQLITE_OK) || !fields_stmt)
+			break;
+		
+		for (fields_status = sqlite3_step (fields_stmt); fields_status == SQLITE_ROW; 
+		     fields_status = sqlite3_step (fields_stmt)) {
+			GType gtype;
+			const gchar *typname = (gchar *) sqlite3_column_text (fields_stmt, 2);
+			if (!typname || !(*typname)) 
+				continue;
+
+			gtype = GPOINTER_TO_INT (g_hash_table_lookup (cdata->types, typname));
+			if ((gtype == GDA_TYPE_NULL) && !g_hash_table_lookup (added_hash, typname)) {
+				GValue *vname, *vgtyp;
+
+				gtype = _gda_sqlite_compute_g_type (get_affinity (typname));
+				g_value_set_string ((vname = gda_value_new (G_TYPE_STRING)), typname);
+				g_value_set_string ((vgtyp = gda_value_new (G_TYPE_STRING)), g_type_name (gtype));
+
+				if (!append_a_row (mod_model, error, 9,
+						   FALSE, catalog_value, /* udt_catalog */
+						   FALSE, p_udt_schema, /* udt_schema */
+						   FALSE, vname, /* udt_name */
+						   TRUE, vgtyp, /* udt_gtype */
+						   TRUE, NULL, /* udt_comments */
+						   FALSE, vname, /* udt_short_name */
+						   TRUE, vname, /* udt_full_name */
+						   FALSE, false_value, /* udt_internal */
+						   FALSE, NULL /* udt_owner */)) {
+					retval = FALSE;
+					break;
+				}
+				g_hash_table_insert (added_hash, g_strdup (typname), GINT_TO_POINTER (1));
+			}
+		}
+		sqlite3_finalize (fields_stmt);
+	}
+	sqlite3_finalize (tables_stmt);
+
+	return retval;
+}
+
+static guint
+nocase_str_hash (gconstpointer v)
+{
+	guint ret;
+	gchar *up = g_ascii_strup ((gchar *) v, -1);
+	ret = g_str_hash ((gconstpointer) up);
+	g_free (up);
+	return ret;
+}
+
+static gboolean
+nocase_str_equal (gconstpointer v1, gconstpointer v2)
+{
+	return g_ascii_strcasecmp ((gchar *) v1, (gchar *) v2) == 0 ? TRUE : FALSE;
+}
+
 gboolean
 _gda_sqlite_meta__udt (GdaServerProvider *prov, GdaConnection *cnc, 
 		       GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
-	TO_IMPLEMENT;
-	/* get all the column types of all the tables */
-	return TRUE;
+	SqliteConnectionData *cdata;
+	GdaDataModel *mod_model = NULL;
+	gboolean retval = TRUE;
+
+	GHashTable *added_hash;
+	GdaDataModel *tmpmodel;
+	gint i, nrows;
+
+	/* get connection's private data */
+	cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+
+	/* get list of schemas */
+	tmpmodel = (GdaDataModel *) gda_connection_statement_execute (cnc, internal_stmt[I_PRAGMA_DATABASE_LIST],
+                                                                      NULL, GDA_STATEMENT_MODEL_RANDOM_ACCESS, NULL, error);
+        if (!tmpmodel)
+                return FALSE;
+
+	/* prepare modification model */
+	added_hash = g_hash_table_new_full (nocase_str_hash, nocase_str_equal, g_free, NULL); 
+	mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
+	g_assert (mod_model);
+
+	nrows = gda_data_model_get_n_rows (tmpmodel);
+        for (i = 0; i < nrows; i++) {
+		/* iterate through the schemas */
+                const GValue *cvalue = gda_data_model_get_value_at (tmpmodel, 1, i);
+                if (!strcmp (g_value_get_string (cvalue), TMP_DATABASE_NAME))
+			continue; /* nothing to do */
+		if (! fill_udt_model (cdata, added_hash, mod_model, cvalue, error)) {
+			retval = FALSE;
+                        break;
+		}
+	}
+	g_object_unref (tmpmodel);
+	g_hash_table_destroy (added_hash);
+
+	/* actually use mod_model */
+	if (retval) 
+		retval = gda_meta_store_modify (store, context->table_name, mod_model, NULL, error, NULL);
+	g_object_unref (mod_model);
+
+	return retval;
 }
 
 gboolean
@@ -223,9 +395,33 @@
 		      GdaMetaStore *store, GdaMetaContext *context, GError **error,
 		      const GValue *udt_catalog, const GValue *udt_schema)
 {
-	TO_IMPLEMENT;
-	/* get all the column types of all the tables, with the correct name */
-	return TRUE;
+	SqliteConnectionData *cdata;
+	GdaDataModel *mod_model = NULL;
+	gboolean retval = TRUE;
+
+	GHashTable *added_hash;
+
+	/* get connection's private data */
+	cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+
+	/* prepare modification model */
+	added_hash = g_hash_table_new_full (nocase_str_hash, nocase_str_equal, g_free, NULL); 
+	mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
+	g_assert (mod_model);
+
+	if (! fill_udt_model (cdata, added_hash, mod_model, udt_schema, error))
+		retval = FALSE;
+
+	g_hash_table_destroy (added_hash);
+
+	/* actually use mod_model */
+	if (retval) 
+		retval = gda_meta_store_modify (store, context->table_name, mod_model, NULL, error, NULL);
+	g_object_unref (mod_model);
+
+	return retval;
 }
 
 gboolean
@@ -1596,13 +1792,52 @@
 	return TRUE;
 }
 
+
 gboolean
 _gda_sqlite_meta__routines (GdaServerProvider *prov, GdaConnection *cnc, 
 			    GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
-	TO_IMPLEMENT;
-	/* use cdata->functions_model and cdata->aggregates_model */
-	return TRUE;
+	return _gda_sqlite_meta_routines (prov, cnc, store, context, error, NULL, NULL, NULL);
+}
+
+static gboolean
+fill_routines (GdaDataModel *mod_model, 
+	       const GValue *rname, const GValue *is_agg, const GValue *rnargs, const GValue *sname, GError **error)
+{
+	GValue *v0;
+	gboolean retval = TRUE;
+	
+	if (g_value_get_int (is_agg) == 0)
+		g_value_set_string ((v0 = gda_value_new (G_TYPE_STRING)), "FUNCTION");
+	else
+		g_value_set_string ((v0 = gda_value_new (G_TYPE_STRING)), "AGGREGATE");
+	if (!append_a_row (mod_model, error, 22,
+			   FALSE, catalog_value, /* specific_catalog */
+			   FALSE, catalog_value, /* specific_schema */
+			   FALSE, sname, /* specific_name */
+			   FALSE, NULL, /* routine_catalog */
+			   FALSE, NULL, /* routine_schema */
+			   FALSE, rname, /* routine_name */
+			   TRUE, v0, /* routine_type */
+			   FALSE, NULL, /* return_type */
+			   FALSE, false_value, /* returns_set */
+			   FALSE, rnargs, /* nb_args */
+			   FALSE, NULL, /* routine_body */
+			   FALSE, NULL, /* routine_definition */
+			   FALSE, NULL, /* external_name */
+			   FALSE, NULL, /* external_language */
+			   FALSE, NULL, /* parameter_style */
+			   FALSE, NULL, /* is_deterministic */
+			   FALSE, NULL, /* sql_data_access */
+			   FALSE, NULL, /* is_null_call */
+			   FALSE, NULL, /* routine_comments */
+			   FALSE, rname, /* routine_short_name */
+			   FALSE, rname, /* routine_full_name */
+			   FALSE, NULL /* routine_owner */)) {
+		retval = FALSE;
+	}
+
+	return retval;
 }
 
 gboolean
@@ -1611,9 +1846,104 @@
 			   const GValue *routine_catalog, const GValue *routine_schema, 
 			   const GValue *routine_name_n)
 {
-	TO_IMPLEMENT;
-	/* use cdata->functions_model and cdata->aggregates_model */
-	return TRUE;
+	SqliteConnectionData *cdata;
+	gboolean retval = TRUE;
+
+	cdata = (SqliteConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+	
+	if (cdata->functions_model) {
+		/* use cdata->functions_model and cdata->aggregates_model */
+		GdaDataModel *mod_model;
+		mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
+		g_assert (mod_model);
+		
+		if (cdata->functions_model) {
+			gint i, nrows;
+			for (i = 0; i < nrows; i++) {
+				const GValue *cv0, *cv2, *cv3;
+				cv0 = gda_data_model_get_value_at (cdata->functions_model, 0, i);
+				cv2 = gda_data_model_get_value_at (cdata->functions_model, 1, i);
+				cv3 = gda_data_model_get_value_at (cdata->functions_model, 2, i);
+				if (!cv0 || !cv2 ||!cv3) {
+					g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR,
+						     _("Can't read data"));
+					retval = FALSE;
+					break;
+				}
+				if ((!routine_name_n || (routine_name_n && !gda_value_compare (routine_name_n, cv0)))
+				    && ! fill_routines (mod_model, cv0, false_value, cv2, cv3, error)) {
+					retval = FALSE;
+					break;
+				}
+			}
+		}
+		if (cdata->aggregates_model) {
+			gint i, nrows;
+			for (i = 0; i < nrows; i++) {
+				const GValue *cv0, *cv2, *cv3;
+				cv0 = gda_data_model_get_value_at (cdata->aggregates_model, 0, i);
+				cv2 = gda_data_model_get_value_at (cdata->aggregates_model, 1, i);
+				cv3 = gda_data_model_get_value_at (cdata->aggregates_model, 2, i);
+				if (!cv0 || !cv2 ||!cv3) {
+					g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR,
+						     _("Can't read data"));
+					retval = FALSE;
+					break;
+				}
+				if ((!routine_name_n || (routine_name_n && !gda_value_compare (routine_name_n, cv0)))
+				    && ! fill_routines (mod_model, cv0, true_value, cv2, cv3, error)) {
+					retval = FALSE;
+					break;
+				}
+			}
+		}
+
+		if (retval)
+			retval = gda_meta_store_modify_with_context (store, context, mod_model, error);
+		g_object_unref (mod_model);
+	}
+	else {
+		/* get list of procedures */
+		GdaDataModel *tmpmodel, *mod_model;
+		gint i, nrows;
+		tmpmodel = (GdaDataModel *) gda_connection_statement_execute (cnc, internal_stmt[I_PRAGMA_PROCLIST],
+									      NULL, GDA_STATEMENT_MODEL_RANDOM_ACCESS, 
+									      NULL, error);
+		if (!tmpmodel)
+			return FALSE;
+
+		mod_model = gda_meta_store_create_modify_data_model (store, context->table_name);
+		g_assert (mod_model);
+
+		nrows = gda_data_model_get_n_rows (tmpmodel);
+		for (i = 0; i < nrows; i++) {
+			const GValue *cv0, *cv1, *cv2, *cv3;
+			cv0 = gda_data_model_get_value_at (tmpmodel, 0, i);
+			cv1 = gda_data_model_get_value_at (tmpmodel, 1, i);
+			cv2 = gda_data_model_get_value_at (tmpmodel, 2, i);
+			cv3 = gda_data_model_get_value_at (tmpmodel, 3, i);
+			if (!cv0 || !cv1 || !cv2 ||!cv3) {
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_DATA_ERROR,
+					     _("Can't read data"));
+				retval = FALSE;
+				break;
+			}
+			if ((!routine_name_n || (routine_name_n && !gda_value_compare (routine_name_n, cv0)))
+			    && ! fill_routines (mod_model, cv0, cv1, cv2, cv3, error)) {
+				retval = FALSE;
+				break;
+			}
+		}
+
+		if (retval)
+			retval = gda_meta_store_modify_with_context (store, context, mod_model, error);
+		g_object_unref (mod_model);
+		g_object_unref (tmpmodel);
+	}
+
+	return retval;
 }
 
 gboolean
@@ -1638,7 +1968,7 @@
 _gda_sqlite_meta__routine_par (GdaServerProvider *prov, GdaConnection *cnc, 
 			       GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
-	TO_IMPLEMENT;
+	/* Routines in SQLite accept any type of value => nothing to do */
 	return TRUE;
 }
 
@@ -1648,7 +1978,7 @@
 			      const GValue *rout_catalog, const GValue *rout_schema, 
 			      const GValue *rout_name)
 {
-	TO_IMPLEMENT;
+	/* Routines in SQLite accept any type of value => nothing to do */
 	return TRUE;
 }
 

Modified: trunk/libgda/sqlite/gda-sqlite-provider.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-provider.c	(original)
+++ trunk/libgda/sqlite/gda-sqlite-provider.c	Sun Jul 27 19:25:27 2008
@@ -122,7 +122,7 @@
 								   GdaStatement *stmt, GdaSet *params,
 								   GdaStatementModelUsage model_usage, 
 								   GType *col_types, GdaSet **last_inserted_row, 
-								   guint *task_id, GdaServerProviderAsyncCallback async_cb, 
+								   guint *task_id, GdaServerProviderExecCallback async_cb, 
 								   gpointer cb_data, GError **error);
 
 /* 
@@ -140,7 +140,7 @@
 	gpointer  user_data; /* retreive it in func. implementations using sqlite3_user_data() */
 	void    (*xFunc)(sqlite3_context*,int,sqlite3_value**);
 } ScalarFunction;
-ScalarFunction scalars[] = {
+static ScalarFunction scalars[] = {
 	{"gda_file_exists", 1, NULL, scalar_gda_file_exists_func},
 };
 
@@ -169,7 +169,7 @@
 	INTERNAL_ROLLBACK_NAMED,
 } InternalStatementItem;
 
-gchar *internal_sql[] = {
+static gchar *internal_sql[] = {
 	"PRAGMA index_list(##tblname::string)",
 	"PRAGMA index_info(##idxname::string)",
 	"PRAGMA foreign_key_list (##tblname::string)",
@@ -294,7 +294,11 @@
 
 	parser = gda_server_provider_internal_get_parser ((GdaServerProvider*) sqlite_prv);
 	g_static_mutex_lock (&init_mutex);
+
 	if (!internal_stmt) {
+		/* configure multi threading environment */
+		sqlite3_config (SQLITE_CONFIG_SERIALIZED);
+
 		internal_stmt = g_new0 (GdaStatement *, sizeof (internal_sql) / sizeof (gchar*));
 		for (i = INTERNAL_PRAGMA_INDEX_LIST; i < sizeof (internal_sql) / sizeof (gchar*); i++) {
 			internal_stmt[i] = gda_sql_parser_parse_string (parser, internal_sql[i], NULL, NULL);
@@ -305,6 +309,7 @@
 
 	/* meta data init */
 	_gda_sqlite_provider_meta_init ((GdaServerProvider*) sqlite_prv);
+	
 	g_static_mutex_unlock (&init_mutex);
 }
 
@@ -369,7 +374,8 @@
 
 int sqlite3CreateFunc (sqlite3 *db, const char *name, int nArg, int eTextRep, void *data,
 		       void (*xFunc)(sqlite3_context*,int,sqlite3_value **),
-		       void (*xStep)(sqlite3_context*,int,sqlite3_value **), void (*xFinal)(sqlite3_context*))
+		       void (*xStep)(sqlite3_context*,int,sqlite3_value **), 
+		       void (*xFinal)(sqlite3_context*))
 {
 	SqliteConnectionData *cdata = NULL;
 	gboolean is_func = FALSE;
@@ -380,7 +386,7 @@
 			    void (*)(sqlite3_context*,int,sqlite3_value **),
 			    void (*)(sqlite3_context*,int,sqlite3_value **), void (*)(sqlite3_context*)) = NULL;
 
-	if(!func)
+	if (!func)
 		func = (int (*) (sqlite3 *, const char *, int, int, void *,
 				 void (*)(sqlite3_context*,int,sqlite3_value **),
 				 void (*)(sqlite3_context*,int,sqlite3_value **), 
@@ -398,10 +404,16 @@
 		/* It's a function */
 		recset = (GdaDataModelArray *) cdata->functions_model;
 		if (!recset) {
-			recset = GDA_DATA_MODEL_ARRAY (gda_data_model_array_new 
-						       (gda_server_provider_get_schema_nb_columns (GDA_CONNECTION_SCHEMA_PROCEDURES)));
-			g_assert (gda_server_provider_init_schema_model (GDA_DATA_MODEL (recset), 
-									 GDA_CONNECTION_SCHEMA_PROCEDURES));
+			recset = GDA_DATA_MODEL_ARRAY (gda_data_model_array_new, 3);
+			gda_column_set_title (0, "name");
+			gda_column_set_name (0, "name");
+			gda_column_set_g_type (0, G_TYPE_STRING);
+			gda_column_set_title (1, "nargs");
+			gda_column_set_name (1, "nargs");
+			gda_column_set_g_type (1, G_TYPE_INT);
+			gda_column_set_title (2, "specificname");
+			gda_column_set_name (2, "specificname");
+			gda_column_set_g_type (2, G_TYPE_STRING);
 			cdata->functions_model = (GdaDataModel *) recset;
 		}
 		is_func = TRUE;
@@ -410,10 +422,17 @@
 		/* It's an aggregate */
 		recset = (GdaDataModelArray *) cdata->aggregates_model;
 		if (!recset) {
-			recset = GDA_DATA_MODEL_ARRAY (gda_data_model_array_new 
-						       (gda_server_provider_get_schema_nb_columns (GDA_CONNECTION_SCHEMA_AGGREGATES)));
-			g_assert (gda_server_provider_init_schema_model (GDA_DATA_MODEL (recset), 
-									 GDA_CONNECTION_SCHEMA_AGGREGATES));
+			recset = GDA_DATA_MODEL_ARRAY (gda_data_model_array_new, 3);
+			gda_column_set_title (0, "name");
+			gda_column_set_name (0, "name");
+			gda_column_set_g_type (0, G_TYPE_STRING);
+			gda_column_set_title (1, "nargs");
+			gda_column_set_name (1, "nargs");
+			gda_column_set_g_type (1, G_TYPE_INT);
+			gda_column_set_title (2, "specificname");
+			gda_column_set_name (2, "specificname");
+			gda_column_set_g_type (2, G_TYPE_STRING);
+			cdata->functions_model = (GdaDataModel *) recset;
 			cdata->aggregates_model = (GdaDataModel *) recset;
 		}
 		is_agg = TRUE;
@@ -457,65 +476,23 @@
 		/* 'unlock' the data model */
 		g_object_set (G_OBJECT (recset), "read-only", FALSE, NULL);
 
-		/* Proc name */
+		/* name */
 		g_value_set_string (value = gda_value_new (G_TYPE_STRING), name);
 		rowlist = g_list_append (rowlist, value);
+
+		/* Number of args */
+		g_value_set_int (value = gda_value_new (G_TYPE_INT), nArg);
+		rowlist = g_list_append (rowlist, value);			
 				
-		/* Proc_Id */
-		if (! is_agg)
-			str = g_strdup_printf ("p%d", gda_data_model_get_n_rows ((GdaDataModel*) recset));
-		else
-			str = g_strdup_printf ("a%d", gda_data_model_get_n_rows ((GdaDataModel*) recset));
+		/* specific name */
+		str = g_strdup_printf ("%s_%d_%d", name, nArg, eTextRep);
 		g_value_take_string (value = gda_value_new (G_TYPE_STRING), str);
 		rowlist = g_list_append (rowlist, value);
-				
-		/* Owner */
-		g_value_set_string (value = gda_value_new (G_TYPE_STRING), "system");
-		rowlist = g_list_append (rowlist, value);
-		
-		/* Comments */ 
-		rowlist = g_list_append (rowlist, gda_value_new_null());
-		
-		/* Out type */ 
-		g_value_set_string (value = gda_value_new (G_TYPE_STRING), "text");
-		rowlist = g_list_append (rowlist, value);
-				
-		if (! is_agg) {
-			/* Number of args */
-			g_value_set_int (value = gda_value_new (G_TYPE_INT), nArg);
-			rowlist = g_list_append (rowlist, value);
-		}
-				
-		/* In types */
-		if (! is_agg) {
-			if (nArg > 0) {
-				GString *string;
-				gint j;
-				
-				string = g_string_new ("");
-				for (j = 0; j < nArg; j++) {
-					if (j > 0)
-						g_string_append_c (string, ',');
-					g_string_append_c (string, '-');
-				}
-				g_value_take_string (value = gda_value_new (G_TYPE_STRING), string->str);
-				g_string_free (string, FALSE);
-			}
-			else
-				g_value_set_string (value = gda_value_new (G_TYPE_STRING), "");
-		}
-		else
-			g_value_set_string (value = gda_value_new (G_TYPE_STRING), "");
-		rowlist = g_list_append (rowlist, value);
-
-		/* Definition */
-		rowlist = g_list_append (rowlist, gda_value_new_null());
-
+								
 		add_g_list_row ((gpointer) rowlist, recset);
 
 		/* 'lock' the data model */
 		g_object_set (G_OBJECT (recset), "read-only", TRUE, NULL);
-
 	}
 
 	return func (db, name, nArg, eTextRep, data, xFunc, xStep, xFinal);
@@ -736,10 +713,9 @@
 	g_hash_table_insert (db_connections_hash, cdata->connection, cdata);
 #endif
 	
-	/* Note: we need to set the thread owner because as mentionned in
-	 * http://www.sqlite.org/cvstrac/wiki?p=MultiThreading, for portability, a connection should only
-	 * be used by the thread which created it. */
-	g_object_set (G_OBJECT (cnc), "thread-owner", g_thread_self (), NULL);
+	/* Note: we don't need to set the thread owner because as stating with SQLite version 3.6.0
+	 * connections and prepared statement can be shared by threads */
+	g_object_set (G_OBJECT (cnc), "thread-owner", NULL, NULL);
 
 	g_static_rec_mutex_unlock (&cnc_mutex);
 	return TRUE;
@@ -979,7 +955,6 @@
 		const GValue *value;
 		const gchar *dbname = NULL;
 		const gchar *dir = NULL;
-		gchar *filename, *tmp;
 		gboolean retval = TRUE;
 
 		value = gda_server_operation_get_value_at (op, "/DB_DESC_P/DB_NAME");
@@ -989,16 +964,24 @@
                 if (value && G_VALUE_HOLDS (value, G_TYPE_STRING) && g_value_get_string (value))
                         dir = g_value_get_string (value);
 
-		tmp = g_strdup_printf ("%s%s", dbname, FILE_EXTENSION);
-		filename = (gchar *) g_build_filename (dir, tmp, NULL);
-		g_free (tmp);
-
-		if (g_unlink (filename)) {
-			g_set_error (error, 0, 0,
-				     sys_errlist [errno]);
+		if (dbname && dir) {
+			gchar *filename, *tmp;
+			tmp = g_strdup_printf ("%s%s", dbname, FILE_EXTENSION);
+			filename = (gchar *) g_build_filename (dir, tmp, NULL);
+			g_free (tmp);
+
+			if (g_unlink (filename)) {
+				g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_OPERATION_ERROR,
+					     sys_errlist [errno]);
+				retval = FALSE;
+			}
+			g_free (filename);
+		}
+		else {
+			g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_OPERATION_ERROR,
+				     _("Missing database name or directory"));
 			retval = FALSE;
 		}
-		g_free (filename);
 		
 		return retval;
 	}
@@ -1216,13 +1199,10 @@
 	if (type == G_TYPE_BOOLEAN)
 		return "boolean";
 	
-	if ((type == G_TYPE_DATE) || 
-	    (type == GDA_TYPE_GEOMETRIC_POINT) ||
+	if ((type == GDA_TYPE_GEOMETRIC_POINT) ||
 	    (type == G_TYPE_OBJECT) ||
 	    (type == GDA_TYPE_LIST) ||
 	    (type == G_TYPE_STRING) ||
-	    (type == GDA_TYPE_TIME) ||
-	    (type == GDA_TYPE_TIMESTAMP) ||
 	    (type == G_TYPE_INVALID))
 		return "string";
 
@@ -1818,7 +1798,7 @@
 				       GdaStatement *stmt, GdaSet *params,
 				       GdaStatementModelUsage model_usage, 
 				       GType *col_types, GdaSet **last_inserted_row, 
-				       guint *task_id, GdaServerProviderAsyncCallback async_cb, 
+				       guint *task_id, GdaServerProviderExecCallback async_cb, 
 				       gpointer cb_data, GError **error)
 {
 	GdaSqlitePStmt *ps;

Modified: trunk/libgda/sqlite/gda-sqlite-recordset.c
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite-recordset.c	(original)
+++ trunk/libgda/sqlite/gda-sqlite-recordset.c	Sun Jul 27 19:25:27 2008
@@ -152,12 +152,16 @@
 		prow = fetch_next_sqlite_row (model, TRUE, NULL);
 		if (!prow)
 			break;
-		/*g_print ("Read row %d for prep stmt %p\n", model->priv->next_row_num - 1, pmodel->prep_stmt);*/
+#ifdef GDA_DEBUG_NO
+		g_print ("Read row %d for prep stmt %p\n", model->priv->next_row_num - 1, pmodel->prep_stmt);
+#endif
 		for (i = nb_missing - 1; i >= 0; i--) {
 			if (pmodel->prep_stmt->types [missing_cols [i]] != GDA_TYPE_NULL) {
-				/*g_print ("Found type '%s' for col %d\n", 
+#ifdef GDA_DEBUG_NO
+				g_print ("Found type '%s' for col %d\n", 
 					 g_type_name (pmodel->prep_stmt->types [missing_cols [i]]),
-					 missing_cols [i]);*/
+					 missing_cols [i]);
+#endif
 				memmove (missing_cols + i, missing_cols + i + 1, sizeof (gint) * (nb_missing - i - 1));
 				nb_missing --;
 			}
@@ -190,7 +194,7 @@
 		return NULL;
 
         if (!cdata->types)
-                _gda_sqlite_update_types_hash (cdata);
+                _gda_sqlite_compute_types_hash (cdata);
 
         /* make sure @ps reports the correct number of columns */
 	if (_GDA_PSTMT (ps)->ncols < 0) 
@@ -304,32 +308,9 @@
 	ctype = sqlite3_column_decltype (ps->sqlite_stmt, colnum);
 	if (ctype)
 		gtype = GPOINTER_TO_INT (g_hash_table_lookup (cdata->types, ctype));
-	if (gtype == GDA_TYPE_NULL) {
-		int stype;
-		stype = sqlite3_column_type (ps->sqlite_stmt, colnum);
-
-		switch (stype) {
-		case SQLITE_INTEGER:
-			gtype = G_TYPE_INT;
-			break;
-		case SQLITE_FLOAT:
-			gtype = G_TYPE_DOUBLE;
-			break;
-		case 0:
-		case SQLITE_TEXT:
-			gtype = G_TYPE_STRING;
-			break;
-		case SQLITE_BLOB:
-			gtype = GDA_TYPE_BINARY;
-			break;
-		case SQLITE_NULL:
-			gtype = GDA_TYPE_NULL;
-			break;
-		default:
-			g_error ("Unknown SQLite internal data type %d", stype);
-			break;
-		}
-	}
+	if (gtype == GDA_TYPE_NULL) 
+		gtype = _gda_sqlite_compute_g_type (sqlite3_column_type (ps->sqlite_stmt, colnum));
+
 	return gtype;
 }
 
@@ -351,6 +332,7 @@
 	switch (rc) {
 	case  SQLITE_ROW: {
 		gint col;
+		gboolean has_error = FALSE;
 		
 		prow = gda_prow_new (_GDA_PSTMT (ps)->ncols);
 		for (col = 0; col < _GDA_PSTMT (ps)->ncols; col++) {
@@ -372,52 +354,97 @@
 			
 			/* fill GValue */
 			value = gda_prow_get_value (prow, col);
-			if (type != GDA_TYPE_NULL)
-				g_value_init (value, type);
-			
-			if (type == GDA_TYPE_NULL)
-				;
-			else if (type == G_TYPE_INT)
-				g_value_set_int (value, sqlite3_column_int (ps->sqlite_stmt, col));
-			else if (type == G_TYPE_DOUBLE)
-				g_value_set_double (value, sqlite3_column_double (ps->sqlite_stmt, col));
-			else if (type == G_TYPE_STRING)
-				g_value_set_string (value, (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
-			else if (type == GDA_TYPE_BINARY) {
-				GdaBinary *bin;
+			if (sqlite3_column_text (ps->sqlite_stmt, col) == NULL) {
+				/* we have a NULL value */
+				gda_value_set_null (value);
+			}
+			else {
+				if (type != GDA_TYPE_NULL)
+					g_value_init (value, type);
 				
-				bin = g_new0 (GdaBinary, 1);
-				bin->binary_length = sqlite3_column_bytes (ps->sqlite_stmt, col);
-				if (bin->binary_length > 0) {
-					bin->data = g_new (guchar, bin->binary_length);
-					memcpy (bin->data, sqlite3_column_blob (ps->sqlite_stmt, col),
-						bin->binary_length);
+				if (type == GDA_TYPE_NULL)
+					;
+				else if (type == G_TYPE_INT)
+					g_value_set_int (value, sqlite3_column_int (ps->sqlite_stmt, col));
+				else if (type == G_TYPE_DOUBLE)
+					g_value_set_double (value, sqlite3_column_double (ps->sqlite_stmt, col));
+				else if (type == G_TYPE_STRING)
+					g_value_set_string (value, (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
+				else if (type == GDA_TYPE_BINARY) {
+					GdaBinary *bin;
+					
+					bin = g_new0 (GdaBinary, 1);
+					bin->binary_length = sqlite3_column_bytes (ps->sqlite_stmt, col);
+					if (bin->binary_length > 0) {
+						bin->data = g_new (guchar, bin->binary_length);
+						memcpy (bin->data, sqlite3_column_blob (ps->sqlite_stmt, col),
+							bin->binary_length);
+					}
+					else
+						bin->binary_length = 0;
+					gda_value_take_binary (value, bin);
 				}
-				else
-					bin->binary_length = 0;
-				gda_value_take_binary (value, bin);
-			}
-			else if (type == G_TYPE_BOOLEAN)
-				g_value_set_boolean (value, sqlite3_column_int (ps->sqlite_stmt, col) == 0 ? FALSE : TRUE);
-			else if (type == G_TYPE_DATE) {
-				TO_IMPLEMENT;
-			}
-			else if (type == GDA_TYPE_TIME) {
-				TO_IMPLEMENT;
-			}
-			else if (type == GDA_TYPE_TIMESTAMP) {
-				TO_IMPLEMENT;
+				else if (type == G_TYPE_BOOLEAN)
+					g_value_set_boolean (value, sqlite3_column_int (ps->sqlite_stmt, col) == 0 ? FALSE : TRUE);
+				else if (type == G_TYPE_DATE) {
+					GDate date;
+					if (!gda_parse_iso8601_date (&date, 
+								     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col))) {
+						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+							     GDA_SERVER_PROVIDER_DATA_ERROR,
+							     _("Invalid date '%s' (date format should be YYYY-MM-DD)"), 
+							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
+						has_error = TRUE;
+						break;
+					}
+					else
+						g_value_set_boxed (value, &date);
+				}
+				else if (type == GDA_TYPE_TIME) {
+					GdaTime timegda;
+					if (!gda_parse_iso8601_time (&timegda, 
+								     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col))) {
+						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+							     GDA_SERVER_PROVIDER_DATA_ERROR,
+							     _("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), 
+							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
+						has_error = TRUE;
+						break;
+					}
+					else
+						gda_value_set_time (value, &timegda);
+				}
+				else if (type == GDA_TYPE_TIMESTAMP) {
+					GdaTimestamp timestamp;
+					if (!gda_parse_iso8601_timestamp (&timestamp, 
+									  (gchar *) sqlite3_column_text (ps->sqlite_stmt, col))) {
+						g_set_error (error, GDA_SERVER_PROVIDER_ERROR,
+							     GDA_SERVER_PROVIDER_DATA_ERROR,
+							     _("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 
+							     (gchar *) sqlite3_column_text (ps->sqlite_stmt, col));
+						has_error = TRUE;
+						break;
+					}
+					else
+						gda_value_set_timestamp (value, &timestamp);
+				}
+				else 
+					g_error ("Unhandled GDA type %s in SQLite recordset", 
+						 gda_g_type_to_string (_GDA_PSTMT (ps)->types [col]));
 			}
-			else 
-				g_error ("Unhandled GDA type %s in SQLite recordset", 
-					 gda_g_type_to_string (_GDA_PSTMT (ps)->types [col]));
 		}
 		
-		if (do_store) {
-			/* insert row */
-			gda_pmodel_take_row (GDA_PMODEL (model), prow, model->priv->next_row_num);
+		if (has_error) {
+			g_object_unref (prow);
+			prow = NULL;
+		}
+		else {
+			if (do_store) {
+				/* insert row */
+				gda_pmodel_take_row (GDA_PMODEL (model), prow, model->priv->next_row_num);
+			}
+			model->priv->next_row_num ++;
 		}
-		model->priv->next_row_num ++;
 		break;
 	}
 	case SQLITE_BUSY:

Modified: trunk/libgda/sqlite/gda-sqlite.h
==============================================================================
--- trunk/libgda/sqlite/gda-sqlite.h	(original)
+++ trunk/libgda/sqlite/gda-sqlite.h	Sun Jul 27 19:25:27 2008
@@ -52,6 +52,7 @@
 /* 
  * Utility functions
  */
-void _gda_sqlite_update_types_hash (SqliteConnectionData *scnc);
+void  _gda_sqlite_compute_types_hash (SqliteConnectionData *scnc);
+GType _gda_sqlite_compute_g_type (int sqlite_type);
 
 #endif

Modified: trunk/libgda/sqlite/sqlite-src/Makefile.am
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/Makefile.am	(original)
+++ trunk/libgda/sqlite/sqlite-src/Makefile.am	Sun Jul 27 19:25:27 2008
@@ -1,6 +1,6 @@
 noinst_LTLIBRARIES = \
 	libsqlite.la
-AM_CPPFLAGS = -DSQLITE_ENABLE_COLUMN_METADATA -DTHREADSAFE=1
+AM_CPPFLAGS = -DSQLITE_ENABLE_COLUMN_METADATA -DSQLITE_THREADSAFE=1
 
 # Download the Windows prepared SQLite (series 3.x) sources in a ZIP, and
 # extract the zip in this directory (thanks to http://aaronbock.net/articles/sqlite!)

Modified: trunk/libgda/sqlite/sqlite-src/PragmasPatch
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/PragmasPatch	(original)
+++ trunk/libgda/sqlite/sqlite-src/PragmasPatch	Sun Jul 27 19:25:27 2008
@@ -1,6 +1,6 @@
---- sqlite3.c.orig	2008-05-14 18:20:59.000000000 +0200
-+++ sqlite3.c	2008-05-22 21:46:26.000000000 +0200
-@@ -62028,6 +62028,39 @@
+--- sqlite3.c.orig	2008-07-24 11:07:44.000000000 +0200
++++ sqlite3.c	2008-07-24 11:46:03.000000000 +0200
+@@ -64139,6 +64139,48 @@
  
  #ifndef SQLITE_OMIT_SCHEMA_PRAGMAS
    /*
@@ -11,6 +11,7 @@
 +  ** name:         Procedure name
 +  ** is_aggregate: True is procedure is an aggregate
 +  ** nargs:        Number of arguments of the procedure, or -1 if unlimited
++  ** spe_name:     Specific name (unique procedure name)
 +  */
 +  if( sqlite3StrICmp(zLeft, "proc_list")==0 ){
 +    Hash *func_hash;
@@ -19,20 +20,28 @@
 +    if( sqlite3ReadSchema(pParse) ) goto pragma_out;
 +    func_hash = &(db->aFunc);
 +
-+    sqlite3VdbeSetNumCols(v, 3);
-+    pParse->nMem = 3;
++    sqlite3VdbeSetNumCols(v, 4);
++    pParse->nMem = 4;
 +    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "name", P4_STATIC);
 +    sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "is_aggregate", P4_STATIC);
 +    sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "nargs", P4_STATIC);
++    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "spe_name", P4_STATIC);
 +
 +    for (func_elem = sqliteHashFirst (func_hash); func_elem ; func_elem = sqliteHashNext (func_elem)) {
 +      FuncDef *func;
++      char *sname;
++      int size;
 +      func = sqliteHashData (func_elem);
 +
++      size = strlen (func->zName) + 25;
++      sname = sqlite3_malloc (sizeof (char) * size);
++      snprintf (sname, size-1, "%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
 +      sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
 +      sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
 +      sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
-+      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
++      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
++      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
++      sqlite3_free (sname);
 +    }
 +  }else
 +

Modified: trunk/libgda/sqlite/sqlite-src/sqlite3.c
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/sqlite3.c	(original)
+++ trunk/libgda/sqlite/sqlite-src/sqlite3.c	Sun Jul 27 19:25:27 2008
@@ -1,6 +1,6 @@
 /******************************************************************************
 ** This file is an amalgamation of many separate C source files from SQLite
-** version 3.5.9.  By combining all the individual C code files into this 
+** version 3.6.0.  By combining all the individual C code files into this 
 ** single large file, the entire code can be compiled as a one translation
 ** unit.  This allows many compilers to do optimizations that would not be
 ** possible if the files were compiled separately.  Performance improvements
@@ -11,13 +11,13 @@
 ** programs, you need this file and the "sqlite3.h" header file that defines
 ** the programming interface to the SQLite library.  (If you do not have 
 ** the "sqlite3.h" header file at hand, you will find a copy in the first
-** 5638 lines past this header comment.)  Additional code files may be
+** 6139 lines past this header comment.)  Additional code files may be
 ** needed 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.
 **
-** This amalgamation was generated on 2008-05-14 16:20:58 UTC.
+** This amalgamation was generated on 2008-07-16 14:52:32 UTC.
 */
 #define SQLITE_CORE 1
 #define SQLITE_AMALGAMATION 1
@@ -41,7 +41,7 @@
 *************************************************************************
 ** Internal interface definitions for SQLite.
 **
-** @(#) $Id: sqliteInt.h,v 1.704 2008/05/13 13:27:34 drh Exp $
+** @(#) $Id: sqliteInt.h,v 1.742 2008/07/12 14:52:20 drh Exp $
 */
 #ifndef _SQLITEINT_H_
 #define _SQLITEINT_H_
@@ -279,6 +279,26 @@
 # define testcase(X)
 #endif
 
+/*
+** The ALWAYS and NEVER macros surround boolean expressions which 
+** are intended to always be true or false, respectively.  Such
+** expressions could be omitted from the code completely.  But they
+** are included in a few cases in order to enhance the resilience
+** of SQLite to unexpected behavior - to make the code "self-healing"
+** or "ductile" rather than being "brittle" and crashing at the first
+** hint of unplanned behavior.
+**
+** When doing coverage testing ALWAYS and NEVER are hard-coded to
+** be true and false so that the unreachable code then specify will
+** not be counted as untested code.
+*/
+#ifdef SQLITE_COVERAGE_TEST
+# define ALWAYS(X)      (1)
+# define NEVER(X)       (0)
+#else
+# define ALWAYS(X)      (X)
+# define NEVER(X)       (X)
+#endif
 
 /*
 ** The macro unlikely() is a hint that surrounds a boolean
@@ -294,6 +314,22 @@
 # define unlikely(X)  !!(X)
 #endif
 
+/*
+ * This macro is used to "hide" some ugliness in casting an int
+ * value to a ptr value under the MSVC 64-bit compiler.   Casting
+ * non 64-bit values to ptr types results in a "hard" error with 
+ * the MSVC 64-bit compiler which this attempts to avoid.  
+ *
+ * A simple compiler pragma or casting sequence could not be found
+ * to correct this in all situations, so this macro was introduced.
+ *
+ * It could be argued that the intptr_t type could be used in this
+ * case, but that type is not available on all compilers, or 
+ * requires the #include of specific headers which differs between
+ * platforms.
+ */
+#define SQLITE_INT_TO_PTR(X)   ((void*)&((char*)0)[X])
+#define SQLITE_PTR_TO_INT(X)   ((int)(((char*)X)-(char*)0))
 
 /*
 ** These #defines should enable >2GB file support on Posix if the
@@ -423,7 +459,7 @@
 **
 ** Some of the definitions that are in this file are marked as
 ** "experimental".  Experimental interfaces are normally new
-** features recently added to SQLite.  We do not anticipate changes 
+** features recently added to SQLite.  We do not anticipate changes
 ** to experimental interfaces but reserve to make minor changes if
 ** experience from use "in the wild" suggest such changes are prudent.
 **
@@ -436,7 +472,7 @@
 ** the version number) and changes its name to "sqlite3.h" as
 ** part of the build process.
 **
-** @(#) $Id: sqlite.h.in,v 1.312 2008/05/12 12:39:56 drh Exp $
+** @(#) $Id: sqlite.h.in,v 1.372 2008/07/16 13:29:51 drh Exp $
 */
 #ifndef _SQLITE3_H_
 #define _SQLITE3_H_
@@ -458,8 +494,7 @@
 #endif
 
 /*
-** Make sure these symbols where not defined by some previous header
-** file.
+** Ensure these symbols were not defined by some previous header file.
 */
 #ifdef SQLITE_VERSION
 # undef SQLITE_VERSION
@@ -478,29 +513,28 @@
 ** The "version" of SQLite is a string of the form "X.Y.Z".
 ** The phrase "alpha" or "beta" might be appended after the Z.
 ** The X value is major version number always 3 in SQLite3.
-** The X value only changes when  backwards compatibility is
-** broken and we intend to never break
-** backwards compatibility.  The Y value is the minor version
-** number and only changes when
+** The X value only changes when backwards compatibility is
+** broken and we intend to never break backwards compatibility.
+** The Y value is the minor version number and only changes when
 ** there are major feature enhancements that are forwards compatible
-** but not backwards compatible.  The Z value is release number
-** and is incremented with
-** each release but resets back to 0 when Y is incremented.
+** but not backwards compatible.
+** The Z value is the release number and is incremented with
+** each release but resets back to 0 whenever Y is incremented.
 **
 ** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()].
 **
 ** INVARIANTS:
 **
-** {F10011} The SQLITE_VERSION #define in the sqlite3.h header file
-**          evaluates to a string literal that is the SQLite version
+** {F10011} The SQLITE_VERSION #define in the sqlite3.h header file shall
+**          evaluate to a string literal that is the SQLite version
 **          with which the header file is associated.
 **
-** {F10014} The SQLITE_VERSION_NUMBER #define resolves to an integer
-**          with the value  (X*1000000 + Y*1000 + Z) where X, Y, and
-**          Z are the major version, minor version, and release number.
+** {F10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
+**          with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z
+**          are the major version, minor version, and release number.
 */
-#define SQLITE_VERSION         "3.5.9"
-#define SQLITE_VERSION_NUMBER  3005009
+#define SQLITE_VERSION         "3.6.0"
+#define SQLITE_VERSION_NUMBER  3006000
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers {F10020}
@@ -509,8 +543,8 @@
 ** These features provide the same information as the [SQLITE_VERSION]
 ** and [SQLITE_VERSION_NUMBER] #defines in the header, but are associated
 ** with the library instead of the header file.  Cautious programmers might
-** include a check in their application to verify that 
-** sqlite3_libversion_number() always returns the value 
+** include a check in their application to verify that
+** sqlite3_libversion_number() always returns the value
 ** [SQLITE_VERSION_NUMBER].
 **
 ** The sqlite3_libversion() function returns the same information as is
@@ -520,13 +554,13 @@
 **
 ** INVARIANTS:
 **
-** {F10021} The [sqlite3_libversion_number()] interface returns an integer
-**          equal to [SQLITE_VERSION_NUMBER]. 
+** {F10021} The [sqlite3_libversion_number()] interface shall return
+**          an integer equal to [SQLITE_VERSION_NUMBER].
 **
-** {F10022} The [sqlite3_version] string constant contains the text of the
-**          [SQLITE_VERSION] string. 
+** {F10022} The [sqlite3_version] string constant shall contain
+**          the text of the [SQLITE_VERSION] string.
 **
-** {F10023} The [sqlite3_libversion()] function returns
+** {F10023} The [sqlite3_libversion()] function shall return
 **          a pointer to the [sqlite3_version] string constant.
 */
 SQLITE_API const char sqlite3_version[];
@@ -537,25 +571,42 @@
 ** CAPI3REF: Test To See If The Library Is Threadsafe {F10100}
 **
 ** SQLite can be compiled with or without mutexes.  When
-** the SQLITE_THREADSAFE C preprocessor macro is true, mutexes
+** the [SQLITE_THREADSAFE] C preprocessor macro is true, mutexes
 ** are enabled and SQLite is threadsafe.  When that macro is false,
 ** the mutexes are omitted.  Without the mutexes, it is not safe
-** to use SQLite from more than one thread.
+** to use SQLite concurrently from more than one thread.
 **
-** There is a measurable performance penalty for enabling mutexes.
+** Enabling mutexes incurs a measurable performance penalty.
 ** So if speed is of utmost importance, it makes sense to disable
 ** the mutexes.  But for maximum safety, mutexes should be enabled.
 ** The default behavior is for mutexes to be enabled.
 **
 ** This interface can be used by a program to make sure that the
 ** version of SQLite that it is linking against was compiled with
-** the desired setting of the SQLITE_THREADSAFE macro.
+** the desired setting of the [SQLITE_THREADSAFE] macro.
+**
+** This interface only reports on the compile-time mutex setting
+** of the [SQLITE_THREADSAFE] flag.  If SQLite is compiled with
+** SQLITE_THREADSAFE=1 then mutexes are enabled by default but
+** can be fully or partially disabled using a call to [sqlite3_config()]
+** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
+** or [SQLITE_CONFIG_MUTEX].  The return value of this function shows
+** only the default compile-time setting, not any run-time changes
+** to that setting.
 **
 ** INVARIANTS:
 **
-** {F10101} The [sqlite3_threadsafe()] function returns nonzero if
-**          SQLite was compiled with its mutexes enabled or zero
-**          if SQLite was compiled with mutexes disabled.
+** {F10101} The [sqlite3_threadsafe()] function shall return nonzero if
+**          SQLite was compiled with the its mutexes enabled by default
+**          or zero if SQLite was compiled such that mutexes are
+**          permanently disabled.
+**
+** {F10102} The value returned by the [sqlite3_threadsafe()] function
+**          shall not change when mutex setting are modified at
+**          runtime using the [sqlite3_config()] interface and 
+**          especially the [SQLITE_CONFIG_SINGLETHREAD],
+**          [SQLITE_CONFIG_MULTITHREAD], [SQLITE_CONFIG_SERIALIZED],
+**          and [SQLITE_CONFIG_MUTEX] verbs.
 */
 SQLITE_API int sqlite3_threadsafe(void);
 
@@ -563,18 +614,17 @@
 ** CAPI3REF: Database Connection Handle {F12000}
 ** KEYWORDS: {database connection} {database connections}
 **
-** Each open SQLite database is represented by pointer to an instance of the
-** opaque structure named "sqlite3".  It is useful to think of an sqlite3
+** Each open SQLite database is represented by a pointer to an instance of
+** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
 ** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces are its constructors
-** and [sqlite3_close()] is its destructor.  There are many other interfaces
-** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and
-** [sqlite3_busy_timeout()] to name but three) that are methods on this
-** object.
+** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
+** is its destructor.  There are many other interfaces (such as
+** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
+** [sqlite3_busy_timeout()] to name but three) that are methods on an
+** sqlite3 object.
 */
 typedef struct sqlite3 sqlite3;
 
-
 /*
 ** CAPI3REF: 64-Bit Integer Types {F10200}
 ** KEYWORDS: sqlite_int64 sqlite_uint64
@@ -582,16 +632,16 @@
 ** Because there is no cross-platform way to specify 64-bit integer types
 ** SQLite includes typedefs for 64-bit signed and unsigned integers.
 **
-** The sqlite3_int64 and sqlite3_uint64 are the preferred type
-** definitions.  The sqlite_int64 and sqlite_uint64 types are
-** supported for backwards compatibility only.
+** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
+** The sqlite_int64 and sqlite_uint64 types are supported for backwards
+** compatibility only.
 **
 ** INVARIANTS:
 **
-** {F10201} The [sqlite_int64] and [sqlite3_int64] types specify a
-**          64-bit signed integer.
+** {F10201} The [sqlite_int64] and [sqlite3_int64] type shall specify
+**          a 64-bit signed integer.
 **
-** {F10202} The [sqlite_uint64] and [sqlite3_uint64] types specify
+** {F10202} The [sqlite_uint64] and [sqlite3_uint64] type shall specify
 **          a 64-bit unsigned integer.
 */
 #ifdef SQLITE_INT64_TYPE
@@ -609,7 +659,7 @@
 
 /*
 ** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point
+** substitute integer for floating-point.
 */
 #ifdef SQLITE_OMIT_FLOATING_POINT
 # define double sqlite3_int64
@@ -618,41 +668,53 @@
 /*
 ** CAPI3REF: Closing A Database Connection {F12010}
 **
-** This routine is the destructor for the [sqlite3] object.  
+** This routine is the destructor for the [sqlite3] object.
 **
-** Applications should [sqlite3_finalize | finalize] all
-** [prepared statements] and
-** [sqlite3_blob_close | close] all [sqlite3_blob | BLOBs] 
-** associated with the [sqlite3] object prior
-** to attempting to close the [sqlite3] object.
+** Applications should [sqlite3_finalize | finalize] all [prepared statements]
+** and [sqlite3_blob_close | close] all [BLOB handles] associated with
+** the [sqlite3] object prior to attempting to close the object.
+** The [sqlite3_next_stmt()] interface can be used to locate all
+** [prepared statements] associated with a [database connection] if desired.
+** Typical code might look like this:
+**
+** <blockquote><pre>
+** sqlite3_stmt *pStmt;
+** while( (pStmt = sqlite3_next_stmt(db, 0))!=0 ){
+** &nbsp;   sqlite3_finalize(pStmt);
+** }
+** </pre></blockquote>
 **
-** <todo>What happens to pending transactions?  Are they
-** rolled back, or abandoned?</todo>
+** If [sqlite3_close()] is invoked while a transaction is open,
+** the transaction is automatically rolled back.
 **
 ** INVARIANTS:
 **
-** {F12011} The [sqlite3_close()] interface destroys an [sqlite3] object
-**          allocated by a prior call to [sqlite3_open()],
-**          [sqlite3_open16()], or [sqlite3_open_v2()].
-**
-** {F12012} The [sqlite3_close()] function releases all memory used by the
-**          connection and closes all open files.
-**
-** {F12013} If the database connection contains
-**          [prepared statements] that have not been
-**          finalized by [sqlite3_finalize()], then [sqlite3_close()]
-**          returns [SQLITE_BUSY] and leaves the connection open.
+** {F12011} A successful call to [sqlite3_close(C)] shall destroy the
+**          [database connection] object C.
 **
-** {F12014} Giving sqlite3_close() a NULL pointer is a harmless no-op.
+** {F12012} A successful call to [sqlite3_close(C)] shall return SQLITE_OK.
 **
-** LIMITATIONS:
+** {F12013} A successful call to [sqlite3_close(C)] shall release all
+**          memory and system resources associated with [database connection]
+**          C.
 **
-** {U12015} The parameter to [sqlite3_close()] must be an [sqlite3] object
-**          pointer previously obtained from [sqlite3_open()] or the 
-**          equivalent, or NULL.
+** {F12014} A call to [sqlite3_close(C)] on a [database connection] C that
+**          has one or more open [prepared statements] shall fail with
+**          an [SQLITE_BUSY] error code.
+**
+** {F12015} A call to [sqlite3_close(C)] where C is a NULL pointer shall
+**          return SQLITE_OK.
+**
+** {F12019} When [sqlite3_close(C)] is invoked on a [database connection] C
+**          that has a pending transaction, the transaction shall be
+**          rolled back.
 **
-** {U12016} The parameter to [sqlite3_close()] must not have been previously
-**          closed.
+** LIMITATIONS:
+**
+** {A12016} The C parameter to [sqlite3_close(C)] must be either a NULL
+**          pointer or an [sqlite3] object pointer previously obtained
+**          from [sqlite3_open()], [sqlite3_open16()], or
+**          [sqlite3_open_v2()], and not previously closed.
 */
 SQLITE_API int sqlite3_close(sqlite3 *);
 
@@ -666,101 +728,112 @@
 /*
 ** CAPI3REF: One-Step Query Execution Interface {F12100}
 **
-** The sqlite3_exec() interface is a convenient way of running
-** one or more SQL statements without a lot of C code.  The
-** SQL statements are passed in as the second parameter to
-** sqlite3_exec().  The statements are evaluated one by one
-** until either an error or an interrupt is encountered or
-** until they are all done.  The 3rd parameter is an optional
-** callback that is invoked once for each row of any query results
-** produced by the SQL statements.  The 5th parameter tells where
+** The sqlite3_exec() interface is a convenient way of running one or more
+** SQL statements without having to write a lot of C code.  The UTF-8 encoded
+** SQL statements are passed in as the second parameter to sqlite3_exec().
+** The statements are evaluated one by one until either an error or
+** an interrupt is encountered, or until they are all done.  The 3rd parameter
+** is an optional callback that is invoked once for each row of any query
+** results produced by the SQL statements.  The 5th parameter tells where
 ** to write any error messages.
 **
+** The error message passed back through the 5th parameter is held
+** in memory obtained from [sqlite3_malloc()].  To avoid a memory leak,
+** the calling application should call [sqlite3_free()] on any error
+** message returned through the 5th parameter when it has finished using
+** the error message.
+**
+** If the SQL statement in the 2nd parameter is NULL or an empty string
+** or a string containing only whitespace and comments, then no SQL
+** statements are evaluated and the database is not changed.
+**
 ** The sqlite3_exec() interface is implemented in terms of
 ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-** The sqlite3_exec() routine does nothing that cannot be done
+** The sqlite3_exec() routine does nothing to the database that cannot be done
 ** by [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-** The sqlite3_exec() is just a convenient wrapper.
 **
 ** INVARIANTS:
-** 
-** {F12101} The [sqlite3_exec()] interface evaluates zero or more UTF-8
-**          encoded, semicolon-separated, SQL statements in the
-**          zero-terminated string of its 2nd parameter within the
-**          context of the [sqlite3] object given in the 1st parameter.
 **
-** {F12104} The return value of [sqlite3_exec()] is SQLITE_OK if all
-**          SQL statements run successfully.
+** {F12101} A successful invocation of [sqlite3_exec(D,S,C,A,E)]
+**          shall sequentially evaluate all of the UTF-8 encoded,
+**          semicolon-separated SQL statements in the zero-terminated
+**          string S within the context of the [database connection] D.
+**
+** {F12102} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL then
+**          the actions of the interface shall be the same as if the
+**          S parameter were an empty string.
 **
-** {F12105} The return value of [sqlite3_exec()] is an appropriate 
-**          non-zero error code if any SQL statement fails.
+** {F12104} The return value of [sqlite3_exec()] shall be [SQLITE_OK] if all
+**          SQL statements run successfully and to completion.
+**
+** {F12105} The return value of [sqlite3_exec()] shall be an appropriate
+**          non-zero [error code] if any SQL statement fails.
 **
 ** {F12107} If one or more of the SQL statements handed to [sqlite3_exec()]
 **          return results and the 3rd parameter is not NULL, then
-**          the callback function specified by the 3rd parameter is
+**          the callback function specified by the 3rd parameter shall be
 **          invoked once for each row of result.
 **
 ** {F12110} If the callback returns a non-zero value then [sqlite3_exec()]
-**          will aborted the SQL statement it is currently evaluating,
+**          shall abort the SQL statement it is currently evaluating,
 **          skip all subsequent SQL statements, and return [SQLITE_ABORT].
-**          <todo>What happens to *errmsg here?  Does the result code for
-**          sqlite3_errcode() get set?</todo>
 **
-** {F12113} The [sqlite3_exec()] routine will pass its 4th parameter through
+** {F12113} The [sqlite3_exec()] routine shall pass its 4th parameter through
 **          as the 1st parameter of the callback.
 **
-** {F12116} The [sqlite3_exec()] routine sets the 2nd parameter of its
+** {F12116} The [sqlite3_exec()] routine shall set the 2nd parameter of its
 **          callback to be the number of columns in the current row of
 **          result.
 **
-** {F12119} The [sqlite3_exec()] routine sets the 3rd parameter of its 
+** {F12119} The [sqlite3_exec()] routine shall set the 3rd parameter of its
 **          callback to be an array of pointers to strings holding the
 **          values for each column in the current result set row as
 **          obtained from [sqlite3_column_text()].
 **
-** {F12122} The [sqlite3_exec()] routine sets the 4th parameter of its
+** {F12122} The [sqlite3_exec()] routine shall set the 4th parameter of its
 **          callback to be an array of pointers to strings holding the
 **          names of result columns as obtained from [sqlite3_column_name()].
 **
 ** {F12125} If the 3rd parameter to [sqlite3_exec()] is NULL then
-**          [sqlite3_exec()] never invokes a callback.  All query
-**          results are silently discarded.
-**
-** {F12128} If an error occurs while parsing or evaluating any of the SQL
-**          statements handed to [sqlite3_exec()] then [sqlite3_exec()] will
-**          return an [error code] other than [SQLITE_OK].
+**          [sqlite3_exec()] shall silently discard query results.
 **
 ** {F12131} If an error occurs while parsing or evaluating any of the SQL
-**          handed to [sqlite3_exec()] and if the 5th parameter (errmsg)
-**          to [sqlite3_exec()] is not NULL, then an error message is
-**          allocated using the equivalent of [sqlite3_mprintf()] and
-**          *errmsg is made to point to that message.
-**
-** {F12134} The [sqlite3_exec()] routine does not change the value of
-**          *errmsg if errmsg is NULL or if there are no errors.
-**
-** {F12137} The [sqlite3_exec()] function sets the error code and message
-**          accessible via [sqlite3_errcode()], [sqlite3_errmsg()], and
-**          [sqlite3_errmsg16()].
+**          statements in the S parameter of [sqlite3_exec(D,S,C,A,E)] and if
+**          the E parameter is not NULL, then [sqlite3_exec()] shall store
+**          in *E an appropriate error message written into memory obtained
+**          from [sqlite3_malloc()].
+**
+** {F12134} The [sqlite3_exec(D,S,C,A,E)] routine shall set the value of
+**          *E to NULL if E is not NULL and there are no errors.
+**
+** {F12137} The [sqlite3_exec(D,S,C,A,E)] function shall set the [error code]
+**          and message accessible via [sqlite3_errcode()],
+**          [sqlite3_errmsg()], and [sqlite3_errmsg16()].
+**
+** {F12138} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL or an
+**          empty string or contains nothing other than whitespace, comments,
+**          and/or semicolons, then results of [sqlite3_errcode()],
+**          [sqlite3_errmsg()], and [sqlite3_errmsg16()]
+**          shall reset to indicate no errors.
 **
 ** LIMITATIONS:
 **
-** {U12141} The first parameter to [sqlite3_exec()] must be an valid and open
+** {A12141} The first parameter to [sqlite3_exec()] must be an valid and open
 **          [database connection].
 **
-** {U12142} The database connection must not be closed while
+** {A12142} The database connection must not be closed while
 **          [sqlite3_exec()] is running.
-** 
-** {U12143} The calling function is should use [sqlite3_free()] to free
+**
+** {A12143} The calling function should use [sqlite3_free()] to free
 **          the memory that *errmsg is left pointing at once the error
 **          message is no longer needed.
 **
-** {U12145} The SQL statement text in the 2nd parameter to [sqlite3_exec()]
+** {A12145} The SQL statement text in the 2nd parameter to [sqlite3_exec()]
 **          must remain unchanged while [sqlite3_exec()] is running.
 */
 SQLITE_API int sqlite3_exec(
   sqlite3*,                                  /* An open database */
-  const char *sql,                           /* SQL to be evaluted */
+  const char *sql,                           /* SQL to be evaluated */
   int (*callback)(void*,int,char**,char**),  /* Callback function */
   void *,                                    /* 1st argument to callback */
   char **errmsg                              /* Error msg written here */
@@ -769,10 +842,13 @@
 /*
 ** CAPI3REF: Result Codes {F10210}
 ** KEYWORDS: SQLITE_OK {error code} {error codes}
+** KEYWORDS: {result code} {result codes}
 **
 ** Many SQLite functions return an integer result code from the set shown
 ** here in order to indicates success or failure.
 **
+** New error codes may be added in future versions of SQLite.
+**
 ** See also: [SQLITE_IOERR_READ | extended result codes]
 */
 #define SQLITE_OK           0   /* Successful result */
@@ -810,18 +886,18 @@
 /*
 ** CAPI3REF: Extended Result Codes {F10220}
 ** KEYWORDS: {extended error code} {extended error codes}
-** KEYWORDS: {extended result codes}
+** KEYWORDS: {extended result code} {extended result codes}
 **
 ** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes].  However, experience has shown that
-** many of these result codes are too course-grained.  They do not provide as
+** [SQLITE_OK | result codes].  However, experience has shown that many of
+** these result codes are too coarse-grained.  They do not provide as
 ** much information about problems as programmers might like.  In an effort to
 ** address this, newer versions of SQLite (version 3.3.8 and later) include
 ** support for additional result codes that provide more detailed information
 ** about errors. The extended result codes are enabled or disabled
-** for each database connection using the [sqlite3_extended_result_codes()]
-** API.
-** 
+** on a per database connection basis using the
+** [sqlite3_extended_result_codes()] API.
+**
 ** Some of the available extended result codes are listed here.
 ** One may expect the number of extended result codes will be expand
 ** over time.  Software that uses extended result codes should expect
@@ -829,32 +905,34 @@
 **
 ** The SQLITE_OK result code will never be extended.  It will always
 ** be exactly zero.
-** 
+**
 ** INVARIANTS:
 **
-** {F10223} The symbolic name for an extended result code always contains
+** {F10223} The symbolic name for an extended result code shall contains
 **          a related primary result code as a prefix.
 **
-** {F10224} Primary result code names contain a single "_" character.
+** {F10224} Primary result code names shall contain a single "_" character.
 **
-** {F10225} Extended result code names contain two or more "_" characters.
+** {F10225} Extended result code names shall contain two or more "_" characters.
 **
-** {F10226} The numeric value of an extended result code contains the
+** {F10226} The numeric value of an extended result code shall contain the
 **          numeric value of its corresponding primary result code in
 **          its least significant 8 bits.
 */
-#define SQLITE_IOERR_READ          (SQLITE_IOERR | (1<<8))
-#define SQLITE_IOERR_SHORT_READ    (SQLITE_IOERR | (2<<8))
-#define SQLITE_IOERR_WRITE         (SQLITE_IOERR | (3<<8))
-#define SQLITE_IOERR_FSYNC         (SQLITE_IOERR | (4<<8))
-#define SQLITE_IOERR_DIR_FSYNC     (SQLITE_IOERR | (5<<8))
-#define SQLITE_IOERR_TRUNCATE      (SQLITE_IOERR | (6<<8))
-#define SQLITE_IOERR_FSTAT         (SQLITE_IOERR | (7<<8))
-#define SQLITE_IOERR_UNLOCK        (SQLITE_IOERR | (8<<8))
-#define SQLITE_IOERR_RDLOCK        (SQLITE_IOERR | (9<<8))
-#define SQLITE_IOERR_DELETE        (SQLITE_IOERR | (10<<8))
-#define SQLITE_IOERR_BLOCKED       (SQLITE_IOERR | (11<<8))
-#define SQLITE_IOERR_NOMEM         (SQLITE_IOERR | (12<<8))
+#define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
+#define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
+#define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
+#define SQLITE_IOERR_FSYNC             (SQLITE_IOERR | (4<<8))
+#define SQLITE_IOERR_DIR_FSYNC         (SQLITE_IOERR | (5<<8))
+#define SQLITE_IOERR_TRUNCATE          (SQLITE_IOERR | (6<<8))
+#define SQLITE_IOERR_FSTAT             (SQLITE_IOERR | (7<<8))
+#define SQLITE_IOERR_UNLOCK            (SQLITE_IOERR | (8<<8))
+#define SQLITE_IOERR_RDLOCK            (SQLITE_IOERR | (9<<8))
+#define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))
+#define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))
+#define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
+#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
+#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
 
 /*
 ** CAPI3REF: Flags For File Open Operations {F10230}
@@ -876,6 +954,7 @@
 #define SQLITE_OPEN_TEMP_JOURNAL     0x00001000
 #define SQLITE_OPEN_SUBJOURNAL       0x00002000
 #define SQLITE_OPEN_MASTER_JOURNAL   0x00004000
+#define SQLITE_OPEN_NOMUTEX          0x00008000
 
 /*
 ** CAPI3REF: Device Characteristics {F10240}
@@ -931,15 +1010,14 @@
 **
 ** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
 ** sync operation only needs to flush data to mass storage.  Inode
-** information need not be flushed. The SQLITE_SYNC_NORMAL flag means 
-** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means 
+** information need not be flushed. The SQLITE_SYNC_NORMAL flag means
+** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means
 ** to use Mac OS-X style fullsync instead of fsync().
 */
 #define SQLITE_SYNC_NORMAL        0x00002
 #define SQLITE_SYNC_FULL          0x00003
 #define SQLITE_SYNC_DATAONLY      0x00010
 
-
 /*
 ** CAPI3REF: OS Interface Open File Handle {F11110}
 **
@@ -958,17 +1036,18 @@
 /*
 ** CAPI3REF: OS Interface File Virtual Methods Object {F11120}
 **
-** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to
-** an instance of this object.  This object defines the
-** methods used to perform various operations against the open file.
+** Every file opened by the [sqlite3_vfs] xOpen method populates an
+** [sqlite3_file] object (or, more commonly, a subclass of the
+** [sqlite3_file] object) with a pointer to an instance of this object.
+** This object defines the methods used to perform various operations
+** against the open file represented by the [sqlite3_file] object.
 **
 ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
 ** [SQLITE_SYNC_FULL].  The first choice is the normal fsync().
-*  The second choice is an
-** OS-X style fullsync.  The SQLITE_SYNC_DATA flag may be ORed in to
-** indicate that only the data of the file and not its inode needs to be
-** synced.
-** 
+** The second choice is a Mac OS-X style fullsync.  The [SQLITE_SYNC_DATAONLY]
+** flag may be ORed in to indicate that only the data of the file
+** and not its inode needs to be synced.
+**
 ** The integer values to xLock() and xUnlock() are one of
 ** <ul>
 ** <li> [SQLITE_LOCK_NONE],
@@ -977,26 +1056,24 @@
 ** <li> [SQLITE_LOCK_PENDING], or
 ** <li> [SQLITE_LOCK_EXCLUSIVE].
 ** </ul>
-** xLock() increases the lock. xUnlock() decreases the lock.  
-** The xCheckReservedLock() method looks
-** to see if any database connection, either in this
-** process or in some other process, is holding an RESERVED,
+** 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
-** if such a lock exists and false if not.
-** 
+** if such a lock exists and false otherwise.
+**
 ** The xFileControl() method is a generic interface that allows custom
 ** VFS implementations to directly control an open file using the
-** [sqlite3_file_control()] interface.  The second "op" argument
-** is an integer opcode.   The third
-** argument is a generic pointer which is intended to be a pointer
-** to a structure that may contain arguments or space in which to
+** [sqlite3_file_control()] interface.  The second "op" argument is an
+** integer opcode.  The third argument is a generic pointer intended to
+** point to a structure that may contain arguments or space in which to
 ** write return values.  Potential uses for xFileControl() might be
 ** functions to enable blocking locks with timeouts, to change the
 ** locking strategy (for example to use dot-file locks), to inquire
 ** about the status of a lock, or to break stale locks.  The SQLite
-** core reserves opcodes less than 100 for its own use. 
+** core reserves all opcodes less than 100 for its own use.
 ** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
-** Applications that define a custom xFileControl method should use opcodes 
+** Applications that define a custom xFileControl method should use opcodes
 ** greater than 100 to avoid conflicts.
 **
 ** The xSectorSize() method returns the sector size of the
@@ -1042,7 +1119,7 @@
   int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
   int (*xLock)(sqlite3_file*, int);
   int (*xUnlock)(sqlite3_file*, int);
-  int (*xCheckReservedLock)(sqlite3_file*);
+  int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
   int (*xFileControl)(sqlite3_file*, int op, void *pArg);
   int (*xSectorSize)(sqlite3_file*);
   int (*xDeviceCharacteristics)(sqlite3_file*);
@@ -1053,7 +1130,7 @@
 ** CAPI3REF: Standard File Control Opcodes {F11310}
 **
 ** These integer constants are opcodes for the xFileControl method
-** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()]
+** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
 ** interface.
 **
 ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
@@ -1081,13 +1158,16 @@
 /*
 ** CAPI3REF: OS Interface Object {F11140}
 **
-** An instance of this object defines the interface between the
-** SQLite core and the underlying operating system.  The "vfs"
+** An instance of the sqlite3_vfs object defines the interface between
+** the SQLite core and the underlying operating system.  The "vfs"
 ** in the name of the object stands for "virtual file system".
 **
-** The iVersion field is initially 1 but may be larger for future
-** versions of SQLite.  Additional fields may be appended to this
-** object when the iVersion value is increased.
+** The value of the iVersion field is initially 1 but may be larger in
+** future versions of SQLite.  Additional fields may be appended to this
+** object when the iVersion value is increased.  Note that the structure
+** of the sqlite3_vfs object changes in the transaction between
+** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
+** modified.
 **
 ** The szOsFile field is the size of the subclassed [sqlite3_file]
 ** structure used by this VFS.  mxPathname is the maximum length of
@@ -1097,9 +1177,10 @@
 ** the pNext pointer.  The [sqlite3_vfs_register()]
 ** and [sqlite3_vfs_unregister()] interfaces manage this list
 ** in a thread-safe way.  The [sqlite3_vfs_find()] interface
-** searches the list.
+** searches the list.  Neither the application code nor the VFS
+** implementation should use the pNext pointer.
 **
-** The pNext field is the only field in the sqlite3_vfs 
+** The pNext field is the only field in the sqlite3_vfs
 ** structure that SQLite will ever modify.  SQLite will only access
 ** or modify this field while holding a particular static mutex.
 ** The application should never modify anything within the sqlite3_vfs
@@ -1108,23 +1189,28 @@
 ** The zName field holds the name of the VFS module.  The name must
 ** be unique across all VFS modules.
 **
-** {F11141} SQLite will guarantee that the zFilename string passed to
-** xOpen() is a full pathname as generated by xFullPathname() and
-** that the string will be valid and unchanged until xClose() is
-** called.  {END} So the [sqlite3_file] can store a pointer to the
+** {F11141} SQLite will guarantee that the zFilename parameter to xOpen
+** is either a NULL pointer or string obtained
+** from xFullPathname().  SQLite further guarantees that
+** the string will be valid and unchanged until xClose() is
+** called. {END}  Becasue of the previous sentense, 
+** the [sqlite3_file] can safely store a pointer to the
 ** filename if it needs to remember the filename for some reason.
+** If the zFilename parameter is xOpen is a NULL pointer then xOpen
+** must invite its own temporary name for the file.  Whenever the 
+** xFilename parameter is NULL it will also be the case that the
+** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
 **
 ** {F11142} The flags argument to xOpen() includes all bits set in
 ** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
 ** or [sqlite3_open16()] is used, then flags includes at least
 ** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. {END}
 ** If xOpen() opens a file read-only then it sets *pOutFlags to
-** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be
-** set.
-** 
+** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
+**
 ** {F11143} SQLite will also add one of the following flags to the xOpen()
 ** call, depending on the object being opened:
-** 
+**
 ** <ul>
 ** <li>  [SQLITE_OPEN_MAIN_DB]
 ** <li>  [SQLITE_OPEN_MAIN_JOURNAL]
@@ -1136,59 +1222,56 @@
 ** </ul> {END}
 **
 ** The file I/O implementation can use the object type flags to
-** changes the way it deals with files.  For example, an application
+** change the way it deals with files.  For example, an application
 ** that does not care about crash recovery or rollback might make
 ** the open of a journal file a no-op.  Writes to this journal would
-** also be no-ops, and any attempt to read the journal would return 
-** SQLITE_IOERR.  Or the implementation might recognize that a database 
-** file will be doing page-aligned sector reads and writes in a random 
+** also be no-ops, and any attempt to read the journal would return
+** SQLITE_IOERR.  Or the implementation might recognize that a database
+** file will be doing page-aligned sector reads and writes in a random
 ** order and set up its I/O subsystem accordingly.
-** 
-** SQLite might also add one of the following flags to the xOpen
-** method:
-** 
+**
+** SQLite might also add one of the following flags to the xOpen method:
+**
 ** <ul>
 ** <li> [SQLITE_OPEN_DELETEONCLOSE]
 ** <li> [SQLITE_OPEN_EXCLUSIVE]
 ** </ul>
-** 
+**
 ** {F11145} The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
 ** deleted when it is closed.  {F11146} The [SQLITE_OPEN_DELETEONCLOSE]
-** will be set for TEMP  databases, journals and for subjournals. 
+** will be set for TEMP  databases, journals and for subjournals.
+**
 ** {F11147} The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
 ** for exclusive access.  This flag is set for all files except
-** for the main database file. {END}
-** 
-** {F11148} At least szOsFile bytes of memory are allocated by SQLite 
-** to hold the  [sqlite3_file] structure passed as the third 
-** argument to xOpen.  {END}  The xOpen method does not have to
+** for the main database file.
+**
+** {F11148} At least szOsFile bytes of memory are allocated by SQLite
+** to hold the  [sqlite3_file] structure passed as the third
+** argument to xOpen. {END}  The xOpen method does not have to
 ** allocate the structure; it should just fill it in.
-** 
-** {F11149} The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] 
-** to test for the existance of a file,
-** or [SQLITE_ACCESS_READWRITE] to test to see
-** if a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test to see if a file is at least readable.  {END} The file can be a 
+**
+** {F11149} 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. {END}  The file can be a
 ** directory.
-** 
-** {F11150} SQLite will always allocate at least mxPathname+1 bytes for
-** the output buffers for xGetTempname and xFullPathname. {F11151} The exact
-** size of the output buffer is also passed as a parameter to both 
-** methods. {END} If the output buffer is not large enough, SQLITE_CANTOPEN
-** should be returned. As this is handled as a fatal error by SQLite,
-** vfs implementations should endeavor to prevent this by setting 
-** mxPathname to a sufficiently large value.
-** 
+**
+** {F11150} SQLite will always allocate at least mxPathname+1 bytes for the
+** output buffer xFullPathname. {F11151} The exact size of the output buffer
+** is also passed as a parameter to both  methods. {END}  If the output buffer
+** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
+** handled as a fatal error by SQLite, vfs implementations should endeavor
+** to prevent this by setting mxPathname to a sufficiently large value.
+**
 ** The xRandomness(), xSleep(), and xCurrentTime() interfaces
 ** are not strictly a part of the filesystem, but they are
 ** included in the VFS structure for completeness.
 ** The xRandomness() function attempts to return nBytes bytes
 ** of good-quality randomness into zOut.  The return value is
-** the actual number of bytes of randomness obtained.  The
-** xSleep() method causes the calling thread to sleep for at
+** the actual number of bytes of randomness obtained.
+** The xSleep() method causes the calling thread to sleep for at
 ** least the number of microseconds given.  The xCurrentTime()
-** method returns a Julian Day Number for the current date and
-** time.
+** method returns a Julian Day Number for the current date and time.
 */
 typedef struct sqlite3_vfs sqlite3_vfs;
 struct sqlite3_vfs {
@@ -1201,8 +1284,7 @@
   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 (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut);
+  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
   int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
   void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
   void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
@@ -1211,6 +1293,7 @@
   int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
   int (*xSleep)(sqlite3_vfs*, int microseconds);
   int (*xCurrentTime)(sqlite3_vfs*, double*);
+  int (*xGetLastError)(sqlite3_vfs*, int, char *);
   /* New fields may be appended in figure versions.  The iVersion
   ** value will increment whenever this happens. */
 };
@@ -1220,36 +1303,319 @@
 **
 ** {F11191} These integer constants can be used as the third parameter to
 ** the xAccess method of an [sqlite3_vfs] object. {END}  They determine
-** what kind of permissions the xAccess method is
-** looking for.  {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method
-** simply checks to see if the file exists. {F11193} With
-** SQLITE_ACCESS_READWRITE, the xAccess method checks to see
-** if the file is both readable and writable.  {F11194} With
-** SQLITE_ACCESS_READ the xAccess method
-** checks to see if the file is readable.
+** what kind of permissions the xAccess method is looking for.
+** {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method
+** simply checks whether the file exists.
+** {F11193} With SQLITE_ACCESS_READWRITE, the xAccess method
+** checks whether the file is both readable and writable.
+** {F11194} With SQLITE_ACCESS_READ, the xAccess method
+** checks whether the file is readable.
 */
 #define SQLITE_ACCESS_EXISTS    0
 #define SQLITE_ACCESS_READWRITE 1
 #define SQLITE_ACCESS_READ      2
 
 /*
+** CAPI3REF: Initialize The SQLite Library {F10130}
+**
+** The sqlite3_initialize() routine initializes the
+** SQLite library.  The sqlite3_shutdown() routine
+** deallocates any resources that were allocated by sqlite3_initialize().
+**
+** A call to sqlite3_initialize() is an "effective" call if it is
+** the first time sqlite3_initialize() is invoked during the lifetime of
+** the process, or if it is the first time sqlite3_initialize() is invoked
+** following a call to sqlite3_shutdown().  Only an effective call
+** of sqlite3_initialize() does any initialization.  All other calls
+** are harmless no-ops.
+**
+** Among other things, sqlite3_initialize() shall invoke
+** sqlite3_os_init().  Similarly, sqlite3_shutdown()
+** shall invoke sqlite3_os_end().
+**
+** The sqlite3_initialize() routine returns SQLITE_OK on success.
+** 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.
+**
+** 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.  For example, [sqlite3_open()]
+** calls sqlite3_initialize() so the SQLite library will be automatically
+** initialized when [sqlite3_open()] is called if it has not be initialized
+** already.  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.  For maximum portability,
+** it is recommended that applications always invoke sqlite3_initialize()
+** directly prior to using any other SQLite interface.  Future releases
+** of SQLite may require this.  In other words, the behavior exhibited
+** when SQLite is compiled with SQLITE_OMIT_AUTOINIT might become the
+** default behavior in some future release of SQLite.
+**
+** The sqlite3_os_init() routine does operating-system specific
+** initialization of the SQLite library.  The sqlite3_os_end()
+** routine undoes the effect of sqlite3_os_init().  Typical tasks
+** performed by these routines include allocation or deallocation
+** of static resources, initialization of global variables,
+** setting up a default [sqlite3_vfs] module, or setting up
+** a default configuration using [sqlite3_config()].
+**
+** The application should never invoke either sqlite3_os_init()
+** or sqlite3_os_end() directly.  The application should only invoke
+** sqlite3_initialize() and sqlite3_shutdown().  The sqlite3_os_init()
+** interface is called automatically by sqlite3_initialize() and
+** sqlite3_os_end() is called by sqlite3_shutdown().  Appropriate
+** implementations for sqlite3_os_init() and sqlite3_os_end()
+** are built into SQLite when it is compiled for unix, windows, or os/2.
+** When built for other platforms (using the SQLITE_OS_OTHER=1 compile-time
+** option) the application must supply a suitable implementation for
+** sqlite3_os_init() and sqlite3_os_end().  An application-supplied
+** implementation of sqlite3_os_init() or sqlite3_os_end()
+** must return SQLITE_OK on success and some other [error code] upon
+** failure.
+*/
+SQLITE_API int sqlite3_initialize(void);
+SQLITE_API int sqlite3_shutdown(void);
+SQLITE_API int sqlite3_os_init(void);
+SQLITE_API int sqlite3_os_end(void);
+
+/*
+** CAPI3REF: Configuring The SQLite Library {F10145}
+**
+** The sqlite3_config() interface is used to make global configuration
+** changes to SQLite in order to tune SQLite to the specific needs of
+** the application.  The default configuration is recommended for most
+** applications and so this routine is usually not necessary.  It is
+** provided to support rare applications with unusual needs.
+**
+** The sqlite3_config() interface is not threadsafe.  The application
+** must insure that no other SQLite interfaces are invoked by other
+** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
+** may only be invoked prior to library initialization using
+** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+** 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
+** [SQLITE_CONFIG_SINGLETHREAD | configuration option] that determines
+** what property of SQLite is to be configured.  Subsequent arguments
+** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | 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].
+**
+** The sqlite3_config() interface is considered experimental in that
+** new configuration options may be added in future releases and existing
+** configuration options may be discontinued or modified.
+*/
+SQLITE_API int sqlite3_config(int, ...);
+
+/*
+** CAPI3REF: Memory Allocation Routines {F10155}
+**
+** An instance of this object defines the interface between SQLite
+** and low-level memory allocation routines.
+**
+** This object is used in only one place in the SQLite interface.
+** A pointer to an instance of this object is the argument to
+** [sqlite3_config()] when the configuration option is
+** [SQLITE_CONFIG_MALLOC].  By creating an instance of this object
+** and passing it to [sqlite3_config()] during configuration, an
+** application can specify an alternative memory allocation subsystem
+** for SQLite to use for all of its dynamic memory needs.
+**
+** Note that SQLite comes with a built-in memory allocator that is
+** perfectly adequate for the overwhelming majority of applications
+** and that this object is only useful to a tiny minority of applications
+** with specialized memory allocation requirements.  This object is
+** also used during testing of SQLite in order to specify an alternative
+** memory allocator that simulates memory out-of-memory conditions in
+** order to verify that SQLite recovers gracefully from such
+** conditions.
+**
+** The xMalloc, xFree, and xRealloc methods must work like the
+** malloc(), free(), and realloc() functions from the standard library.
+**
+** xSize should return the allocated size of a memory allocation
+** previously obtained from xMalloc or xRealloc.  The allocated size
+** is always at least as big as the requested size but may be larger.
+**
+** The xRoundup method returns what would be the allocated size of
+** a memory allocation given a particular requested size.  Most memory
+** 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.
+**
+** The xInit method initializes the memory allocator.  (For example,
+** it might allocate any require mutexes or initialize internal data
+** structures.  The xShutdown method is invoked (indirectly) by
+** [sqlite3_shutdown()] and should deallocate any resources acquired
+** by xInit.  The pAppData pointer is used as the only parameter to
+** xInit and xShutdown.
+*/
+typedef struct sqlite3_mem_methods sqlite3_mem_methods;
+struct sqlite3_mem_methods {
+  void *(*xMalloc)(int);         /* Memory allocation function */
+  void (*xFree)(void*);          /* Free a prior allocation */
+  void *(*xRealloc)(void*,int);  /* Resize an allocation */
+  int (*xSize)(void*);           /* Return the size of an allocation */
+  int (*xRoundup)(int);          /* Round up request size to allocation size */
+  int (*xInit)(void*);           /* Initialize the memory allocator */
+  void (*xShutdown)(void*);      /* Deinitialize the memory allocator */
+  void *pAppData;                /* Argument to xInit() and xShutdown() */
+};
+
+/*
+** CAPI3REF: Configuration Options {F10160}
+**
+** These constants are the available integer configuration options that
+** can be passed as the first argument to the [sqlite3_config()] interface.
+**
+** 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
+** the call worked.  The [sqlite3_config()] interface will return a
+** non-zero [error code] if a discontinued or unsupported configuration option
+** is invoked.
+**
+** <dl>
+** <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
+** <dd>There are no arguments to this option.  This option disables
+** all mutexing and puts SQLite into a mode where it can only be used
+** by a single thread.</dd>
+**
+** <dt>SQLITE_CONFIG_MULTITHREAD</dt>
+** <dd>There are no arguments to this option.  This option disables
+** mutexing on [database connection] and [prepared statement] objects.
+** The application is responsible for serializing access to
+** [database connections] and [prepared statements].  But other mutexes
+** are enabled so that SQLite will be safe to use in a multi-threaded
+** environment.</dd>
+**
+** <dt>SQLITE_CONFIG_SERIALIZED</dt>
+** <dd>There are no arguments to this option.  This option enables
+** all mutexes including the recursive
+** mutexes on [database connection] and [prepared statement] objects.
+** In this mode (which is the default when SQLite is compiled with
+** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
+** to [database connections] and [prepared statements] so that the
+** application is free to use the same [database connection] or the
+** same [prepared statement] in different threads at the same time.
+**
+** <p>This configuration option merely sets the default mutex 
+** behavior to serialize access to [database connections].  Individual
+** [database connections] can override this setting
+** using the [SQLITE_OPEN_NOMUTEX] flag to [sqlite3_open_v2()].</p></dd>
+**
+** <dt>SQLITE_CONFIG_MALLOC</dt>
+** <dd>This 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.</dd>
+**
+** <dt>SQLITE_CONFIG_GETMALLOC</dt>
+** <dd>This 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.
+** This option can be used to overload the default memory allocation
+** routines with a wrapper that simulations memory allocation failure or
+** tracks memory usage, for example.</dd>
+**
+** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
+** <dd>This option takes single boolean argument which enables or disables
+** the collection of memory allocation statistics.  When disabled, the
+** following SQLite interfaces become non-operational:
+**   <ul>
+**   <li> [sqlite3_memory_used()]
+**   <li> [sqlite3_memory_highwater()]
+**   <li> [sqlite3_soft_heap_limit()]
+**   <li> sqlite3_memory_status()
+**   </ul>
+** </dd>
+**
+** <dt>SQLITE_CONFIG_SCRATCH</dt>
+** <dd>This option specifies a static memory buffer that SQLite can use for
+** scratch memory.  There are three arguments:  A pointer to the memory, the
+** size of each scratch buffer (sz), and the number of buffers (N).  The sz
+** argument must be a multiple of 16. The first
+** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** SQLite will use no more than one scratch buffer at once per thread, so
+** N should be set to the expected maximum number of threads.  The sz
+** parameter should be 6 times the size of the largest database page size.
+** Scratch buffers are used as part of the btree balance operation.  If
+** The btree balancer needs additional memory beyond what is provided by
+** scratch buffers or if no scratch buffer space is specified, then SQLite
+** goes to [sqlite3_malloc()] to obtain the memory it needs.</dd>
+**
+** <dt>SQLITE_CONFIG_PAGECACHE</dt>
+** <dd>This option specifies a static memory buffer that SQLite can use for
+** the database page cache.  There are three arguments: A pointer to the
+** memory, the size of each page buffer (sz), and the number of pages (N).
+** The sz argument must be a power of two between 512 and 32768.  The first
+** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** SQLite will use the memory provided by the first argument to satisfy its
+** memory needs for the first N pages that it adds to cache.  If additional
+** page cache memory is needed beyond what is provided by this option, then
+** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
+**
+** <dt>SQLITE_CONFIG_HEAP</dt>
+** <dd>This option specifies a static memory buffer that SQLite will use
+** for all of its dynamic memory allocation needs beyond those provided
+** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
+** There are three arguments: A pointer to the memory, the number of
+** bytes in the memory buffer, and the minimum allocation size.  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].  If the
+** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
+** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
+** allocator is engaged to handle all of SQLites memory allocation needs.</dd>
+**
+** <dt>SQLITE_CONFIG_MUTEX</dt>
+** <dd>This 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.</dd>
+**
+** <dt>SQLITE_CONFIG_GETMUTEX</dt>
+** <dd>This 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.
+** This option can be used to overload the default mutex allocation
+** routines with a wrapper used to track mutex usage for performance
+** profiling or testing, for example.</dd>
+*/
+#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  /* void*, int sz, int N */
+#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* */
+
+
+/*
 ** CAPI3REF: Enable Or Disable Extended Result Codes {F12200}
 **
 ** The sqlite3_extended_result_codes() routine enables or disables the
-** [SQLITE_IOERR_READ | extended result codes] feature of SQLite.
-** The extended result codes are disabled by default for historical
-** compatibility.
+** [extended result codes] feature of SQLite. The extended result
+** codes are disabled by default for historical compatibility considerations.
 **
 ** INVARIANTS:
 **
-** {F12201} Each new [database connection] has the 
-**          [extended result codes] feature
-**          disabled by default.
-**
-** {F12202} The [sqlite3_extended_result_codes(D,F)] interface will enable
-**          [extended result codes] for the 
-**          [database connection] D if the F parameter
-**          is true, or disable them if F is false.
+** {F12201} Each new [database connection] shall have the
+**          [extended result codes] feature disabled by default.
+**
+** {F12202} The [sqlite3_extended_result_codes(D,F)] interface shall enable
+**          [extended result codes] for the  [database connection] D
+**          if the F parameter is true, or disable them if F is false.
 */
 SQLITE_API int sqlite3_extended_result_codes(sqlite3*, int onoff);
 
@@ -1264,44 +1630,42 @@
 ** is another alias for the rowid.
 **
 ** This routine returns the rowid of the most recent
-** successful INSERT into the database from the database connection
-** shown in the first argument.  If no successful inserts
-** have ever occurred on this database connection, zero is returned.
-**
-** If an INSERT occurs within a trigger, then the rowid of the
-** inserted row is returned by this routine as long as the trigger
-** is running.  But once the trigger terminates, the value returned
-** by this routine reverts to the last value inserted before the
-** trigger fired.
+** successful INSERT into the database from the [database connection]
+** in the first argument.  If no successful INSERTs
+** have ever occurred on that database connection, zero is returned.
+**
+** If an INSERT occurs within a trigger, then the rowid of the inserted
+** row is returned by this routine as long as the trigger is running.
+** But once the trigger terminates, the value returned by this routine
+** reverts to the last value inserted before the trigger fired.
 **
 ** An INSERT that fails due to a constraint violation is not a
-** successful insert and does not change the value returned by this
+** successful INSERT and does not change the value returned by this
 ** routine.  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.  When INSERT OR REPLACE 
+** routine when their insertion fails.  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. 
+** the return value of this interface.
 **
-** For the purposes of this routine, an insert is considered to
+** For the purposes of this routine, an INSERT is considered to
 ** be successful even if it is subsequently rolled back.
 **
 ** INVARIANTS:
 **
-** {F12221} The [sqlite3_last_insert_rowid()] function returns the
-**          rowid of the most recent successful insert done
-**          on the same database connection and within the same
-**          trigger context, or zero if there have
-**          been no qualifying inserts on that connection.
+** {F12221} The [sqlite3_last_insert_rowid()] function returns the rowid
+**          of the most recent successful INSERT performed on the same
+**          [database connection] and within the same or higher level
+**          trigger context, or zero if there have been no qualifying inserts.
 **
-** {F12223} The [sqlite3_last_insert_rowid()] function returns
+** {F12223} The [sqlite3_last_insert_rowid()] function returns the
 **          same value when called from the same trigger context
 **          immediately before and after a ROLLBACK.
 **
 ** LIMITATIONS:
 **
-** {U12232} If a separate thread does a new insert on the same
+** {A12232} If a separate thread performs a new INSERT on the same
 **          database connection while the [sqlite3_last_insert_rowid()]
 **          function is running and thus changes the last insert rowid,
 **          then the value returned by [sqlite3_last_insert_rowid()] is
@@ -1315,9 +1679,9 @@
 **
 ** This function returns the number of database rows that were changed
 ** or inserted or deleted by the most recently completed SQL statement
-** on the connection specified by the first parameter.  Only
-** changes that are directly specified by the INSERT, UPDATE, or
-** DELETE statement are counted.  Auxiliary changes caused by
+** on the [database connection] specified by the first parameter.
+** Only changes that are directly specified by the INSERT, UPDATE,
+** or DELETE statement are counted.  Auxiliary changes caused by
 ** triggers are not counted. Use the [sqlite3_total_changes()] function
 ** to find the total number of changes including changes caused by triggers.
 **
@@ -1341,79 +1705,84 @@
 ** most recent INSERT, UPDATE, or DELETE statement within the same
 ** trigger context.
 **
-** So when called from the top level, this function returns the
+** Thus, when called from the top level, this function returns the
 ** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level.
-** Within the body of a trigger, the sqlite3_changes() interface
-** can be called to find the number of
+** that also occurred at the top level.  Within the body of a trigger,
+** the sqlite3_changes() interface can be called to find the number of
 ** changes in the most recently completed INSERT, UPDATE, or DELETE
 ** statement within the body of the same trigger.
-** However, the number returned does not include in changes
-** caused by subtriggers since they have their own context.
+** However, the number returned does not include changes
+** caused by subtriggers since those have their own context.
 **
-** SQLite implements the command "DELETE FROM table" without
-** a WHERE clause by dropping and recreating the table.  (This is much
-** faster than going through and deleting individual elements from the
-** table.)  Because of this optimization, the deletions in
-** "DELETE FROM table" are not row changes and will not be counted
-** by the sqlite3_changes() or [sqlite3_total_changes()] functions.
-** To get an accurate count of the number of rows deleted, use
+** SQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table.  (This is much faster than going
+** through and deleting individual elements from the table.)  Because of this
+** optimization, the deletions in "DELETE FROM table" are not row changes and
+** will not be counted by the sqlite3_changes() or [sqlite3_total_changes()]
+** functions, regardless of the number of elements that were originally
+** in the table.  To get an accurate count of the number of rows deleted, use
 ** "DELETE FROM table WHERE 1" instead.
 **
 ** INVARIANTS:
 **
-** {F12241} The [sqlite3_changes()] function returns the number of
+** {F12241} The [sqlite3_changes()] function shall return the number of
 **          row changes caused by the most recent INSERT, UPDATE,
 **          or DELETE statement on the same database connection and
-**          within the same trigger context, or zero if there have
+**          within the same or higher trigger context, or zero if there have
 **          not been any qualifying row changes.
 **
+** {F12243} Statements of the form "DELETE FROM tablename" with no
+**          WHERE clause shall cause subsequent calls to
+**          [sqlite3_changes()] to return zero, regardless of the
+**          number of rows originally in the table.
+**
 ** LIMITATIONS:
 **
-** {U12252} If a separate thread makes changes on the same database connection
+** {A12252} If a separate thread makes changes on the same database connection
 **          while [sqlite3_changes()] is running then the value returned
-**          is unpredictable and unmeaningful.
+**          is unpredictable and not meaningful.
 */
 SQLITE_API int sqlite3_changes(sqlite3*);
 
 /*
 ** CAPI3REF: Total Number Of Rows Modified {F12260}
-***
-** This function returns the number of row changes caused
-** by INSERT, UPDATE or DELETE statements since the database handle
-** was opened.  The count includes all changes from all trigger
-** contexts.  But the count does not include changes used to
-** implement REPLACE constraints, do rollbacks or ABORT processing,
-** or DROP table processing.
-** The changes
-** are counted as soon as the statement that makes them is completed 
-** (when the statement handle is passed to [sqlite3_reset()] or 
+**
+** This function returns the number of row changes caused by INSERT,
+** UPDATE or DELETE statements since the [database connection] was opened.
+** The count includes all changes from all trigger contexts.  However,
+** the count does not include changes used to implement REPLACE constraints,
+** do rollbacks or ABORT processing, or DROP table processing.
+** The changes are counted as soon as the statement that makes them is
+** completed (when the statement handle is passed to [sqlite3_reset()] or
 ** [sqlite3_finalize()]).
 **
-** SQLite implements the command "DELETE FROM table" without
-** a WHERE clause by dropping and recreating the table.  (This is much
-** faster than going
-** through and deleting individual elements from the table.)  Because of
-** this optimization, the change count for "DELETE FROM table" will be
-** zero regardless of the number of elements that were originally in the
-** table. To get an accurate count of the number of rows deleted, use
+** SQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table.  (This is much faster than going
+** through and deleting individual elements from the table.)  Because of this
+** optimization, the deletions in "DELETE FROM table" are not row changes and
+** will not be counted by the sqlite3_changes() or [sqlite3_total_changes()]
+** functions, regardless of the number of elements that were originally
+** in the table.  To get an accurate count of the number of rows deleted, use
 ** "DELETE FROM table WHERE 1" instead.
 **
 ** See also the [sqlite3_changes()] interface.
 **
 ** INVARIANTS:
-** 
+**
 ** {F12261} The [sqlite3_total_changes()] returns the total number
 **          of row changes caused by INSERT, UPDATE, and/or DELETE
 **          statements on the same [database connection], in any
-**          trigger context, since the database connection was
-**          created.
+**          trigger context, since the database connection was created.
+**
+** {F12263} Statements of the form "DELETE FROM tablename" with no
+**          WHERE clause shall not change the value returned
+**          by [sqlite3_total_changes()].
 **
 ** LIMITATIONS:
 **
-** {U12264} If a separate thread makes changes on the same database connection
-**          while [sqlite3_total_changes()] is running then the value 
-**          returned is unpredictable and unmeaningful.
+** {A12264} 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.
 */
 SQLITE_API int sqlite3_total_changes(sqlite3*);
 
@@ -1428,16 +1797,18 @@
 **
 ** 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 not safe to call this routine with a [database connection] that
 ** is closed or might close before sqlite3_interrupt() returns.
 **
-** If an SQL is very nearly finished at the time when sqlite3_interrupt()
-** is called, then it might not have an opportunity to be interrupted.
-** It 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.
+** 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.
+**
 ** A call to sqlite3_interrupt() has no effect on SQL statements
 ** that are started after sqlite3_interrupt() returns.
 **
@@ -1445,15 +1816,14 @@
 **
 ** {F12271} The [sqlite3_interrupt()] interface will force all running
 **          SQL statements associated with the same database connection
-**          to halt after processing at most one additional row of
-**          data.
+**          to halt after processing at most one additional row of data.
 **
 ** {F12272} Any SQL statement that is interrupted by [sqlite3_interrupt()]
 **          will return [SQLITE_INTERRUPT].
 **
 ** LIMITATIONS:
 **
-** {U12279} If the database connection closes while [sqlite3_interrupt()]
+** {A12279} If the database connection closes while [sqlite3_interrupt()]
 **          is running then bad things will likely happen.
 */
 SQLITE_API void sqlite3_interrupt(sqlite3*);
@@ -1472,23 +1842,27 @@
 ** independent tokens (they are part of the token in which they are
 ** embedded) and thus do not count as a statement terminator.
 **
-** These routines do not parse the SQL and
-** so will not detect syntactically incorrect SQL.
+** These routines do not parse the SQL statements thus
+** will not detect syntactically incorrect SQL.
 **
 ** INVARIANTS:
 **
-** {F10511} The sqlite3_complete() and sqlite3_complete16() functions
-**          return true (non-zero) if and only if the last
-**          non-whitespace token in their input is a semicolon that
-**          is not in between the BEGIN and END of a CREATE TRIGGER
-**          statement.
+** {F10511} A successful evaluation of [sqlite3_complete()] or
+**          [sqlite3_complete16()] functions shall
+**          return a numeric 1 if and only if the last non-whitespace
+**          token in their input is a semicolon that is not in between
+**          the BEGIN and END of a CREATE TRIGGER statement.
+**
+** {F10512} If a memory allocation error occurs during an invocation
+**          of [sqlite3_complete()] or [sqlite3_complete16()] then the
+**          routine shall return [SQLITE_NOMEM].
 **
 ** LIMITATIONS:
 **
-** {U10512} The input to sqlite3_complete() must be a zero-terminated
+** {A10512} The input to [sqlite3_complete()] must be a zero-terminated
 **          UTF-8 string.
 **
-** {U10513} The input to sqlite3_complete16() must be a zero-terminated
+** {A10513} The input to [sqlite3_complete16()] must be a zero-terminated
 **          UTF-16 string in native byte order.
 */
 SQLITE_API int sqlite3_complete(const char *sql);
@@ -1497,29 +1871,27 @@
 /*
 ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {F12310}
 **
-** This routine identifies a callback function that might be
-** invoked whenever an attempt is made to open a database table 
-** that another thread or process has locked.
-** If the busy callback is NULL, then [SQLITE_BUSY]
-** or [SQLITE_IOERR_BLOCKED]
-** is returned immediately upon encountering the lock.
-** If the busy callback is not NULL, then the
-** callback will be invoked with two arguments.  The
-** first argument to the handler is a copy of the void* pointer which
-** is the third argument to this routine.  The second argument to
-** the handler is the number of times that the busy handler has
-** been invoked for this locking event.   If the
+** This routine sets a callback function that might be invoked whenever
+** an attempt is made to open a database table that another thread
+** or process has locked.
+**
+** If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
+** is returned immediately upon encountering the lock. If the busy callback
+** is not NULL, then the callback will be invoked with two arguments.
+**
+** The first argument to the handler is a copy of the void* pointer which
+** is the third argument to sqlite3_busy_handler().  The second argument to
+** the handler callback is the number of times that the busy handler has
+** been invoked for this locking event.  If the
 ** busy callback returns 0, then no additional attempts are made to
 ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
 ** If the callback returns non-zero, then another attempt
 ** is made to open the database for reading and the cycle repeats.
 **
-** 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] or
-** [SQLITE_IOERR_BLOCKED] instead of invoking the
-** busy handler.
+** 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]
+** or [SQLITE_IOERR_BLOCKED] 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
 ** a second process is holding a reserved lock that it is trying
@@ -1544,77 +1916,77 @@
 ** code is promoted from the relatively benign [SQLITE_BUSY] to
 ** the more severe [SQLITE_IOERR_BLOCKED].  This error code promotion
 ** forces an automatic rollback of the changes.  See the
-** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError";>
+** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
 ** CorruptionFollowingBusyError</a> wiki page for a discussion of why
 ** this is important.
-**	
-** There can only be a single busy handler defined for each database
-** connection.  Setting a new busy handler clears any previous one. 
-** Note that calling [sqlite3_busy_timeout()] will also set or clear
-** the busy handler.
+**
+** There can only be a single busy handler defined for each
+** [database connection].  Setting a new busy handler clears any
+** previously set handler.  Note that calling [sqlite3_busy_timeout()]
+** will also set or clear the busy handler.
 **
 ** INVARIANTS:
 **
-** {F12311} The [sqlite3_busy_handler()] function replaces the busy handler
-**          callback in the database connection identified by the 1st
-**          parameter with a new busy handler identified by the 2nd and 3rd
-**          parameters.
+** {F12311} The [sqlite3_busy_handler(D,C,A)] function shall replace
+**          busy callback in the [database connection] D with a new
+**          a new busy handler C and application data pointer A.
 **
-** {F12312} The default busy handler for new database connections is NULL.
+** {F12312} Newly created [database connections] shall have a busy
+**          handler of NULL.
 **
-** {F12314} When two or more database connection share a common cache,
+** {F12314} When two or more [database connections] share a
+**          [sqlite3_enable_shared_cache | common cache],
 **          the busy handler for the database connection currently using
-**          the cache is invoked when the cache encounters a lock.
+**          the cache shall be invoked when the cache encounters a lock.
 **
-** {F12316} If a busy handler callback returns zero, then the SQLite
-**          interface that provoked the locking event will return
-**          [SQLITE_BUSY].
+** {F12316} If a busy handler callback returns zero, then the SQLite interface
+**          that provoked the locking event shall return [SQLITE_BUSY].
 **
-** {F12318} SQLite will invokes the busy handler with two argument which
+** {F12318} SQLite shall invokes the busy handler with two arguments which
 **          are a copy of the pointer supplied by the 3rd parameter to
 **          [sqlite3_busy_handler()] and a count of the number of prior
 **          invocations of the busy handler for the same locking event.
 **
 ** LIMITATIONS:
 **
-** {U12319} A busy handler should not call close the database connection
-**          or prepared statement that invoked the busy handler.
+** {A12319} A busy handler must not close the database connection
+**          or [prepared statement] that invoked the busy handler.
 */
 SQLITE_API int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
 
 /*
 ** CAPI3REF: Set A Busy Timeout {F12340}
 **
-** This routine sets a [sqlite3_busy_handler | busy handler]
-** that sleeps for a while when a
-** table is locked.  The handler will sleep multiple times until 
-** at least "ms" milliseconds of sleeping have been done. {F12343} After
-** "ms" milliseconds of sleeping, the handler returns 0 which
-** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
+** This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
+** for a specified amount of time when a table is locked.  The handler
+** will sleep multiple times until at least "ms" milliseconds of sleeping
+** have accumulated. {F12343} After "ms" milliseconds of sleeping,
+** the handler returns 0 which causes [sqlite3_step()] to return
+** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
 **
 ** Calling this routine with an argument less than or equal to zero
 ** turns off all busy handlers.
 **
-** There can only be a single busy handler for a particular database
-** connection.  If another busy handler was defined  
-** (using [sqlite3_busy_handler()]) prior to calling
+** There can only be a single busy handler for a particular
+** [database connection] any any given moment.  If another busy handler
+** was defined  (using [sqlite3_busy_handler()]) prior to calling
 ** this routine, that other busy handler is cleared.
 **
 ** INVARIANTS:
 **
-** {F12341} The [sqlite3_busy_timeout()] function overrides any prior
+** {F12341} The [sqlite3_busy_timeout()] function shall override any prior
 **          [sqlite3_busy_timeout()] or [sqlite3_busy_handler()] setting
-**          on the same database connection.
+**          on the same [database connection].
 **
 ** {F12343} If the 2nd parameter to [sqlite3_busy_timeout()] is less than
-**          or equal to zero, then the busy handler is cleared so that
+**          or equal to zero, then the busy handler shall be cleared so that
 **          all subsequent locking events immediately return [SQLITE_BUSY].
 **
 ** {F12344} If the 2nd parameter to [sqlite3_busy_timeout()] is a positive
-**          number N, then a busy handler is set that repeatedly calls
-**          the xSleep() method in the VFS interface until either the
-**          lock clears or until the cumulative sleep time reported back
-**          by xSleep() exceeds N milliseconds.
+**          number N, then a busy handler shall be set that repeatedly calls
+**          the xSleep() method in the [sqlite3_vfs | VFS interface] until
+**          either the lock clears or until the cumulative sleep time
+**          reported back by xSleep() exceeds N milliseconds.
 */
 SQLITE_API int sqlite3_busy_timeout(sqlite3*, int ms);
 
@@ -1630,16 +2002,14 @@
 ** numbers are obtained separately.  Let N be the number of rows
 ** and M be the number of columns.
 **
-** A result table is an array of pointers to zero-terminated
-** UTF-8 strings.  There are (N+1)*M elements in the array.  
-** The first M pointers point to zero-terminated strings that 
-** contain the names of the columns.
-** The remaining entries all point to query results.  NULL
-** values are give a NULL pointer.  All other values are in
-** their UTF-8 zero-terminated string representation as returned by
-** [sqlite3_column_text()].
+** A result table is an array of pointers to zero-terminated UTF-8 strings.
+** There are (N+1)*M elements in the array.  The first M pointers point
+** to zero-terminated strings that  contain the names of the columns.
+** The remaining entries all point to query results.  NULL values result
+** in NULL pointers.  All other values are in their UTF-8 zero-terminated
+** string representation as returned by [sqlite3_column_text()].
 **
-** A result table might consists of one or more memory allocations.
+** A result table might consist of one or more memory allocations.
 ** It is not safe to pass a result table directly to [sqlite3_free()].
 ** A result table should be deallocated using [sqlite3_free_table()].
 **
@@ -1674,11 +2044,11 @@
 ** string of its 2nd parameter.  It returns a result table to the
 ** pointer given in its 3rd parameter.
 **
-** After the calling function has finished using the result, it should 
-** pass the pointer to the result table to sqlite3_free_table() in order to 
-** release the memory that was malloc-ed.  Because of the way the 
+** After the calling function has finished using the result, it should
+** pass the pointer to the result table to sqlite3_free_table() in order to
+** release the memory that was malloced.  Because of the way the
 ** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
-** function must not try to call [sqlite3_free()] directly.  Only 
+** function must not try to call [sqlite3_free()] directly.  Only
 ** [sqlite3_free_table()] is able to release the memory properly and safely.
 **
 ** The sqlite3_get_table() interface is implemented as a wrapper around
@@ -1686,38 +2056,48 @@
 ** to any internal data structures of SQLite.  It uses only the public
 ** interface defined here.  As a consequence, errors that occur in the
 ** wrapper layer outside of the internal [sqlite3_exec()] call are not
-** reflected in subsequent calls to [sqlite3_errcode()] or
-** [sqlite3_errmsg()].
+** reflected in subsequent calls to [sqlite3_errcode()] or [sqlite3_errmsg()].
 **
 ** INVARIANTS:
 **
 ** {F12371} If a [sqlite3_get_table()] fails a memory allocation, then
-**          it frees the result table under construction, aborts the
-**          query in process, skips any subsequent queries, sets the
-**          *resultp output pointer to NULL and returns [SQLITE_NOMEM].
-**
-** {F12373} If the ncolumn parameter to [sqlite3_get_table()] is not NULL
-**          then [sqlite3_get_table()] write the number of columns in the
-**          result set of the query into *ncolumn if the query is
-**          successful (if the function returns SQLITE_OK).
-**
-** {F12374} If the nrow parameter to [sqlite3_get_table()] is not NULL
-**          then [sqlite3_get_table()] write the number of rows in the
-**          result set of the query into *nrow if the query is
-**          successful (if the function returns SQLITE_OK).
-**
-** {F12376} The [sqlite3_get_table()] function sets its *ncolumn value
-**          to the number of columns in the result set of the query in the
-**          sql parameter, or to zero if the query in sql has an empty
-**          result set.
+**          it shall free the result table under construction, abort the
+**          query in process, skip any subsequent queries, set the
+**          *pazResult output pointer to NULL and return [SQLITE_NOMEM].
+**
+** {F12373} If the pnColumn parameter to [sqlite3_get_table()] is not NULL
+**          then a successful invocation of [sqlite3_get_table()] shall
+**          write the number of columns in the
+**          result set of the query into *pnColumn.
+**
+** {F12374} If the pnRow parameter to [sqlite3_get_table()] is not NULL
+**          then a successful invocation of [sqlite3_get_table()] shall
+**          writes the number of rows in the
+**          result set of the query into *pnRow.
+**
+** {F12376} A successful invocation of [sqlite3_get_table()] that computes
+**          N rows of result with C columns per row shall make *pazResult
+**          point to an array of pointers to (N+1)*C strings where the first
+**          C strings are column names as obtained from
+**          [sqlite3_column_name()] and the rest are column result values
+**          obtained from [sqlite3_column_text()].
+**
+** {F12379} The values in the pazResult array returned by [sqlite3_get_table()]
+**          shall remain valid until cleared by [sqlite3_free_table()].
+**
+** {F12382} When an error occurs during evaluation of [sqlite3_get_table()]
+**          the function shall set *pazResult to NULL, write an error message
+**          into memory obtained from [sqlite3_malloc()], make
+**          **pzErrmsg point to that error message, and return a
+**          appropriate [error code].
 */
 SQLITE_API int sqlite3_get_table(
-  sqlite3*,             /* An open database */
-  const char *sql,      /* SQL to be evaluated */
-  char ***pResult,      /* Results of the query */
-  int *nrow,            /* Number of result rows written here */
-  int *ncolumn,         /* Number of result columns written here */
-  char **errmsg         /* Error msg written here */
+  sqlite3 *db,          /* An open database */
+  const char *zSql,     /* SQL to be evaluated */
+  char ***pazResult,    /* Results of the query */
+  int *pnRow,           /* Number of result rows written here */
+  int *pnColumn,        /* Number of result columns written here */
+  char **pzErrmsg       /* Error msg written here */
 );
 SQLITE_API void sqlite3_free_table(char **result);
 
@@ -1730,7 +2110,7 @@
 ** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
 ** results into memory obtained from [sqlite3_malloc()].
 ** The strings returned by these two routines should be
-** released by [sqlite3_free()].   Both routines return a
+** released by [sqlite3_free()].  Both routines return a
 ** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
 ** memory to hold the resulting string.
 **
@@ -1755,7 +2135,7 @@
 **
 ** These routines all implement some additional formatting
 ** options that are useful for constructing SQL statements.
-** All of the usual printf formatting options apply.  In addition, there
+** All of the usual printf() formatting options apply.  In addition, there
 ** is are "%q", "%Q", and "%z" options.
 **
 ** The %q option works like %s in that it substitutes a null-terminated
@@ -1764,7 +2144,7 @@
 ** character it escapes that character and allows it to be inserted into
 ** the string.
 **
-** For example, so some string variable contains text as follows:
+** For example, assume the string variable zText contains text as follows:
 **
 ** <blockquote><pre>
 **  char *zText = "It's a happy day!";
@@ -1792,14 +2172,13 @@
 **  INSERT INTO table1 VALUES('It's a happy day!');
 ** </pre></blockquote>
 **
-** This second example is an SQL syntax error.  As a general rule you
-** should always use %q instead of %s when inserting text into a string 
-** literal.
+** This second example is an SQL syntax error.  As a general rule you should
+** always use %q instead of %s when inserting text into a string literal.
 **
 ** The %Q option works like %q except it also adds single quotes around
-** the outside of the total string.  Or if the parameter in the argument
-** list is a NULL pointer, %Q substitutes the text "NULL" (without single
-** quotes) in place of the %Q option. {END}  So, for example, one could say:
+** the outside of the total string.  Additionally, if the parameter in the
+** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
+** single quotes) in place of the %Q option.  So, for example, one could say:
 **
 ** <blockquote><pre>
 **  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
@@ -1825,12 +2204,11 @@
 **           UTF-8 string into the buffer pointed to by the second parameter
 **           provided that the first parameter is greater than zero.
 **
-** {F17407}  The [sqlite3_snprintf()] interface does not writes slots of
+** {F17407}  The [sqlite3_snprintf()] interface does not write slots of
 **           its output buffer (the second parameter) outside the range
 **           of 0 through N-1 (where N is the first parameter)
 **           regardless of the length of the string
 **           requested by the format specification.
-**   
 */
 SQLITE_API char *sqlite3_mprintf(const char*,...);
 SQLITE_API char *sqlite3_vmprintf(const char*, va_list);
@@ -1842,7 +2220,7 @@
 ** The SQLite core  uses these three routines for all of its own
 ** internal memory allocation needs. "Core" in the previous sentence
 ** does not include operating-system specific VFS implementation.  The
-** windows VFS uses native malloc and free for some operations.
+** Windows VFS uses native malloc() and free() for some operations.
 **
 ** The sqlite3_malloc() routine returns a pointer to a block
 ** of memory at least N bytes in length, where N is the parameter.
@@ -1871,7 +2249,7 @@
 ** If the second parameter to sqlite3_realloc() is zero or
 ** negative then the behavior is exactly the same as calling
 ** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** Sqlite3_realloc() returns a pointer to a memory allocation
+** sqlite3_realloc() returns a pointer to a memory allocation
 ** of at least N bytes in size or NULL if sufficient memory is unavailable.
 ** 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
@@ -1882,38 +2260,34 @@
 ** The memory returned by sqlite3_malloc() and sqlite3_realloc()
 ** is always aligned to at least an 8 byte boundary. {END}
 **
-** The default implementation
-** of the memory allocation subsystem uses the malloc(), realloc()
-** and free() provided by the standard C library. {F17382} However, if 
-** SQLite is compiled with the following C preprocessor macro
-**
-** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote>
-**
-** where <i>NNN</i> is an integer, then SQLite create a static
-** array of at least <i>NNN</i> bytes in size and use that array
-** for all of its dynamic memory allocation needs. {END}  Additional
-** memory allocator options may be added in future releases.
+** The default implementation of the memory allocation subsystem uses
+** the malloc(), realloc() and free() provided by the standard C library.
+** {F17382} However, if SQLite is compiled with the
+** SQLITE_MEMORY_SIZE=<i>NNN</i> C preprocessor macro (where <i>NNN</i>
+** is an integer), then SQLite create a static array of at least
+** <i>NNN</i> bytes in size and uses that array for all of its dynamic
+** memory allocation needs. {END}  Additional memory allocator options
+** may be added in future releases.
 **
 ** In SQLite version 3.5.0 and 3.5.1, it was possible to define
 ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
 ** implementation of these routines to be omitted.  That capability
-** is no longer provided.  Only built-in memory allocators can be
-** used.
+** is no longer provided.  Only built-in memory allocators can be used.
 **
-** The windows OS interface layer calls
+** The Windows OS interface layer calls
 ** the system malloc() and free() directly when converting
 ** filenames between the UTF-8 encoding used by SQLite
-** and whatever filename encoding is used by the particular windows
+** and whatever filename encoding is used by the particular Windows
 ** installation.  Memory allocation errors are detected, but
 ** they are reported back as [SQLITE_CANTOPEN] or
 ** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
 **
 ** INVARIANTS:
 **
-** {F17303}  The [sqlite3_malloc(N)] interface returns either a pointer to 
-**           newly checked-out block of at least N bytes of memory
-**           that is 8-byte aligned, 
-**           or it returns NULL if it is unable to fulfill the request.
+** {F17303}  The [sqlite3_malloc(N)] interface returns either a pointer to
+**           a newly checked-out block of at least N bytes of memory
+**           that is 8-byte aligned, or it returns NULL if it is unable
+**           to fulfill the request.
 **
 ** {F17304}  The [sqlite3_malloc(N)] interface returns a NULL pointer if
 **           N is less than or equal to zero.
@@ -1939,8 +2313,9 @@
 **           that is 8-byte aligned, or a NULL pointer.
 **
 ** {F17321}  When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
-**           copies the first K bytes of content from P into the newly allocated
-**           where K is the lessor of N and the size of the buffer P.
+**           copies the first K bytes of content from P into the newly
+**           allocated block, where K is the lesser of N and the size of
+**           the buffer P.
 **
 ** {F17322}  When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
 **           releases the buffer P.
@@ -1950,15 +2325,14 @@
 **
 ** LIMITATIONS:
 **
-** {U17350}  The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
-**           must be either NULL or else a pointer obtained from a prior
-**           invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that has
-**           not been released.
+** {A17350}  The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
+**           must be either NULL or else pointers obtained from a prior
+**           invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
+**           not yet been released.
 **
-** {U17351}  The application must not read or write any part of 
+** {A17351}  The application must not read or write any part of
 **           a block of memory after it has been released using
 **           [sqlite3_free()] or [sqlite3_realloc()].
-**
 */
 SQLITE_API void *sqlite3_malloc(int);
 SQLITE_API void *sqlite3_realloc(void*, int);
@@ -1969,28 +2343,27 @@
 **
 ** SQLite provides these two interfaces for reporting on the status
 ** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
-** the memory allocation subsystem included within the SQLite.
+** routines, which form the built-in memory allocation subsystem.
 **
 ** INVARIANTS:
 **
-** {F17371} The [sqlite3_memory_used()] routine returns the
-**          number of bytes of memory currently outstanding 
-**          (malloced but not freed).
+** {F17371} The [sqlite3_memory_used()] routine returns the number of bytes
+**          of memory currently outstanding (malloced but not freed).
 **
 ** {F17373} The [sqlite3_memory_highwater()] routine returns the maximum
-**          value of [sqlite3_memory_used()] 
-**          since the highwater mark was last reset.
+**          value of [sqlite3_memory_used()] since the high-water mark
+**          was last reset.
 **
 ** {F17374} 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.
-** 
-** {F17375} The memory highwater mark is reset to the current value of
+**
+** {F17375} 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.  The value returned
-**          by [sqlite3_memory_highwater(1)] is the highwater mark
+**          by [sqlite3_memory_highwater(1)] is the high-water mark
 **          prior to the reset.
 */
 SQLITE_API sqlite3_int64 sqlite3_memory_used(void);
@@ -2003,7 +2376,7 @@
 ** select random ROWIDs when inserting new records into a table that
 ** already uses the largest possible ROWID.  The PRNG is also used for
 ** the build-in random() and randomblob() SQL functions.  This interface allows
-** appliations to access the same PRNG for other purposes.
+** applications to access the same PRNG for other purposes.
 **
 ** A call to this routine stores N bytes of randomness into buffer P.
 **
@@ -2035,9 +2408,9 @@
 ** 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.   If the authorizer callback returns
+** rejected with an error.  If the authorizer callback returns
 ** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
-** then [sqlite3_prepare_v2()] or equivalent call that triggered
+** then the [sqlite3_prepare_v2()] or equivalent call that triggered
 ** the authorizer will fail with an error message.
 **
 ** When the callback returns [SQLITE_OK], that means the operation
@@ -2052,19 +2425,17 @@
 ** return can be used to deny an untrusted user access to individual
 ** columns of a table.
 **
-** The first parameter to the authorizer callback is a copy of
-** the third parameter to the sqlite3_set_authorizer() interface.
-** The second parameter to the callback is an integer 
-** [SQLITE_COPY | action code] that specifies the particular action
-** to be authorized. The third through sixth
-** parameters to the callback are zero-terminated strings that contain 
-** additional details about the action to be authorized.
+** The first parameter to the authorizer callback is a copy of the third
+** parameter to the sqlite3_set_authorizer() interface. The second parameter
+** to the callback is an integer [SQLITE_COPY | action code] that specifies
+** the particular action to be authorized. The third through sixth parameters
+** to the callback are zero-terminated strings that contain additional
+** details about the action to be authorized.
 **
 ** An authorizer is used when [sqlite3_prepare | preparing]
-** SQL statements from an untrusted
-** source, to ensure that the SQL statements do not try to access data
-** that they are not allowed to see, or that they do not try to
-** execute malicious statements that damage the database.  For
+** SQL statements from an untrusted source, to ensure that the SQL statements
+** do not try to access data they are not allowed to see, or that they do not
+** try to execute malicious statements that damage the database.  For
 ** example, an application may allow a user to enter arbitrary
 ** SQL queries for evaluation by a database.  But the application does
 ** not want the user to be able to make arbitrary changes to the
@@ -2082,7 +2453,7 @@
 ** previous call.  Disable the authorizer by installing a NULL callback.
 ** The authorizer is disabled by default.
 **
-** Note that the authorizer callback is invoked only during 
+** Note that the authorizer callback is invoked only during
 ** [sqlite3_prepare()] or its variants.  Authorization is not
 ** performed during statement evaluation in [sqlite3_step()].
 **
@@ -2092,16 +2463,16 @@
 **          authorizer callback with database connection D.
 **
 ** {F12502} The authorizer callback is invoked as SQL statements are
-**          being compiled
+**          being compiled.
 **
 ** {F12503} If the authorizer callback returns any value other than
-**          [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] then
+**          [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY], then
 **          the [sqlite3_prepare_v2()] or equivalent call that caused
 **          the authorizer callback to run shall fail with an
 **          [SQLITE_ERROR] error code and an appropriate error message.
 **
 ** {F12504} When the authorizer callback returns [SQLITE_OK], the operation
-**          described is coded normally.
+**          described is processed normally.
 **
 ** {F12505} When the authorizer callback returns [SQLITE_DENY], the
 **          [sqlite3_prepare_v2()] or equivalent call that caused the
@@ -2111,26 +2482,26 @@
 **
 ** {F12506} If the authorizer code (the 2nd parameter to the authorizer
 **          callback) is [SQLITE_READ] and the authorizer callback returns
-**          [SQLITE_IGNORE] then the prepared statement is constructed to
+**          [SQLITE_IGNORE], then the prepared statement is constructed to
 **          insert a NULL value in place of the table column that would have
 **          been read if [SQLITE_OK] had been returned.
 **
 ** {F12507} If the authorizer code (the 2nd parameter to the authorizer
 **          callback) is anything other than [SQLITE_READ], then
-**          a return of [SQLITE_IGNORE] has the same effect as [SQLITE_DENY]. 
+**          a return of [SQLITE_IGNORE] has the same effect as [SQLITE_DENY].
 **
 ** {F12510} The first parameter to the authorizer callback is a copy of
 **          the third parameter to the [sqlite3_set_authorizer()] interface.
 **
-** {F12511} The second parameter to the callback is an integer 
+** {F12511} The second parameter to the callback is an integer
 **          [SQLITE_COPY | action code] that specifies the particular action
 **          to be authorized.
 **
 ** {F12512} The third through sixth parameters to the callback are
-**          zero-terminated strings that contain 
+**          zero-terminated strings that contain
 **          additional details about the action to be authorized.
 **
-** {F12520} Each call to [sqlite3_set_authorizer()] overrides the
+** {F12520} Each call to [sqlite3_set_authorizer()] overrides
 **          any previously installed authorizer.
 **
 ** {F12521} A NULL authorizer means that no authorization
@@ -2160,31 +2531,31 @@
 ** CAPI3REF: Authorizer Action Codes {F12550}
 **
 ** The [sqlite3_set_authorizer()] interface registers a callback function
-** that is invoked to authorizer certain SQL statement actions.  The
+** that is invoked to authorize certain SQL statement actions.  The
 ** second parameter to the callback is an integer code that specifies
 ** what action is being authorized.  These are the integer action codes that
 ** the authorizer callback may be passed.
 **
-** These action code values signify what kind of operation is to be 
+** These action code values signify what kind of operation is to be
 ** authorized.  The 3rd and 4th parameters to the authorization
 ** callback function will be parameters or NULL depending on which of these
 ** codes is used as the second parameter.  The 5th parameter to the
-** authorizer callback is the name of the database ("main", "temp", 
+** authorizer callback is the name of the database ("main", "temp",
 ** etc.) if applicable.  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 
+** the access attempt or NULL if this access attempt is directly from
 ** top-level SQL code.
 **
 ** INVARIANTS:
 **
-** {F12551} The second parameter to an 
-**          [sqlite3_set_authorizer | authorizer callback is always an integer
+** {F12551} The second parameter to an
+**          [sqlite3_set_authorizer | authorizer callback] is always an integer
 **          [SQLITE_COPY | authorizer code] that specifies what action
 **          is being authorized.
 **
-** {F12552} The 3rd and 4th parameters to the 
-**          [sqlite3_set_authorizer | authorization callback function]
-**          will be parameters or NULL depending on which 
+** {F12552} The 3rd and 4th parameters to the
+**          [sqlite3_set_authorizer | authorization callback]
+**          will be parameters or NULL depending on which
 **          [SQLITE_COPY | authorizer code] is used as the second parameter.
 **
 ** {F12553} The 5th parameter to the
@@ -2194,7 +2565,7 @@
 ** {F12554} The 6th parameter to the
 **          [sqlite3_set_authorizer | 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 
+**          the access attempt or NULL if this access attempt is directly from
 **          top-level SQL code.
 */
 /******************************************* 3rd ************ 4th ***********/
@@ -2241,9 +2612,9 @@
 ** various times when an SQL statement is being run by [sqlite3_step()].
 ** The callback returns a UTF-8 rendering of the SQL statement text
 ** as the statement first begins executing.  Additional callbacks occur
-** as each triggersubprogram is entered.  The callbacks for triggers
+** as each triggered subprogram is entered.  The callbacks for triggers
 ** contain a UTF-8 SQL comment that identifies the trigger.
-** 
+**
 ** The callback function registered by sqlite3_profile() is invoked
 ** as each SQL statement finishes.  The profile callback contains
 ** the original statement text and an estimate of wall-clock time
@@ -2254,7 +2625,7 @@
 **
 ** The trigger reporting feature of the trace callback is considered
 ** experimental and is subject to change or removal in future releases.
-** Future versions of SQLite might also add new trace callback 
+** Future versions of SQLite might also add new trace callback
 ** invocations.
 **
 ** INVARIANTS:
@@ -2272,7 +2643,7 @@
 **          the pointer which was the 3rd argument to [sqlite3_trace()].
 **
 ** {F12285} The second argument to the trace callback is a
-**          zero-terminated UTF8 string containing the original text
+**          zero-terminated UTF-8 string containing the original text
 **          of the SQL statement as it was passed into [sqlite3_prepare_v2()]
 **          or the equivalent, or an SQL comment indicating the beginning
 **          of a trigger subprogram.
@@ -2288,7 +2659,7 @@
 **          the SQL statement as it was processed by [sqlite3_prepare_v2()]
 **          or the equivalent.
 **
-** {F12290} The third parameter to the profile  callback is an estimate
+** {F12290} The third parameter to the profile callback is an estimate
 **          of the number of nanoseconds of wall-clock time required to
 **          run the SQL statement from start to finish.
 */
@@ -2302,37 +2673,37 @@
 ** This routine configures a callback function - the
 ** progress callback - that is invoked periodically during long
 ** running calls to [sqlite3_exec()], [sqlite3_step()] and
-** [sqlite3_get_table()].   An example use for this 
+** [sqlite3_get_table()].  An example use for this
 ** interface is to keep a GUI updated during a large query.
 **
-** If the progress callback returns non-zero, the opertion is
+** If the progress callback returns non-zero, the operation is
 ** interrupted.  This feature can be used to implement a
 ** "Cancel" button on a GUI dialog box.
 **
 ** INVARIANTS:
 **
-** {F12911} The callback function registered by [sqlite3_progress_handler()]
+** {F12911} The callback function registered by sqlite3_progress_handler()
 **          is invoked periodically during long running calls to
 **          [sqlite3_step()].
 **
 ** {F12912} The progress callback is invoked once for every N virtual
-**          machine opcodes, where N is the second argument to 
+**          machine opcodes, where N is the second argument to
 **          the [sqlite3_progress_handler()] call that registered
-**          the callback.  <todo>What if N is less than 1?</todo>
+**          the callback.  If N is less than 1, sqlite3_progress_handler()
+**          acts as if a NULL progress handler had been specified.
 **
 ** {F12913} The progress callback itself is identified by the third
-**          argument to [sqlite3_progress_handler()].
+**          argument to sqlite3_progress_handler().
 **
-** {F12914} The fourth argument [sqlite3_progress_handler()] is a
-***         void pointer passed to the progress callback
+** {F12914} The fourth argument to sqlite3_progress_handler() is a
+**          void pointer passed to the progress callback
 **          function each time it is invoked.
 **
-** {F12915} If a call to [sqlite3_step()] results in fewer than
-**          N opcodes being executed,
-**          then the progress callback is never invoked. {END}
-** 
+** {F12915} If a call to [sqlite3_step()] results in fewer than N opcodes
+**          being executed, then the progress callback is never invoked.
+**
 ** {F12916} Every call to [sqlite3_progress_handler()]
-**          overwrites any previously registere progress handler.
+**          overwrites any previously registered progress handler.
 **
 ** {F12917} If the progress handler callback is NULL then no progress
 **          handler is invoked.
@@ -2345,78 +2716,83 @@
 /*
 ** CAPI3REF: Opening A New Database Connection {F12700}
 **
-** These routines open an SQLite database file whose name
-** is given by the filename argument.
-** 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()].
-** An [sqlite3*] handle is usually returned in *ppDb, even
-** if an error occurs.  The only exception is 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.
-** If the database is opened (and/or created)
-** successfully, then [SQLITE_OK] is returned.  Otherwise an
-** error code is returned.  The
-** [sqlite3_errmsg()] or [sqlite3_errmsg16()]  routines can be used to obtain
+** These routines open an SQLite database file whose name is given by the
+** filename argument. 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(). 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. If the database is opened (and/or created) successfully, then
+** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.  The
+** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
 ** an English language description of the error.
 **
 ** The default encoding for the database will be UTF-8 if
-** [sqlite3_open()] or [sqlite3_open_v2()] is called and
-** UTF-16 in the native byte order if [sqlite3_open16()] is used.
+** sqlite3_open() or sqlite3_open_v2() is called and
+** UTF-16 in the native byte order if sqlite3_open16() is used.
 **
 ** Whether or not an error occurs when it is opened, resources
-** associated with the [sqlite3*] handle should be released by passing it
-** to [sqlite3_close()] when it is no longer required.
+** associated with the [database connection] handle should be released by
+** passing it to [sqlite3_close()] when it is no longer required.
 **
-** The [sqlite3_open_v2()] interface works like [sqlite3_open()] 
-** except that it acccepts two additional parameters for additional control
-** over the new database connection.  The flags parameter can be
-** one of:
+** The sqlite3_open_v2() interface works like sqlite3_open()
+** except that it accepts two additional parameters for additional control
+** over the new database connection.  The flags parameter can take one of
+** the following three values, optionally combined with the 
+** [SQLITE_OPEN_NOMUTEX] flag:
 **
-** <ol>
-** <li>  [SQLITE_OPEN_READONLY]
-** <li>  [SQLITE_OPEN_READWRITE]
-** <li>  [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
-** </ol>
+** <dl>
+** <dt>[SQLITE_OPEN_READONLY]</dt>
+** <dd>The database is opened in read-only mode.  If the database does not
+** already exist, an error is returned.</dd>
+**
+** <dt>[SQLITE_OPEN_READWRITE]</dt>
+** <dd>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.</dd>
+**
+** <dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
+** <dd>The database is opened for reading and writing, and is creates it if
+** it does not already exist. This is the behavior that is always used for
+** sqlite3_open() and sqlite3_open16().</dd>
+** </dl>
 **
-** The first value opens the database read-only. 
-** If the database does not previously exist, an error is returned.
-** The second option opens
-** the database for reading and writing if possible, or reading only if
-** if the file is write protected.  In either case the database
-** must already exist or an error is returned.  The third option
-** opens the database for reading and writing and creates it if it does
-** not already exist.
-** The third options is behavior that is always used for [sqlite3_open()]
-** and [sqlite3_open16()].
-**
-** If the 3rd parameter to [sqlite3_open_v2()] is not one of the
-** combinations shown above then the behavior is undefined.
-**
-** If the filename is ":memory:", then an private
-** in-memory database is created for the connection.  This in-memory
-** database will vanish when the database connection is closed.  Future
-** version of SQLite might make use of additional special filenames
-** that begin with the ":" character.  It is recommended that 
-** when a database filename really does begin with
-** ":" that you prefix the filename with a pathname like "./" to
-** avoid ambiguity.
+** If the 3rd parameter to sqlite3_open_v2() is not one of the
+** combinations shown above or one of the combinations shown above combined
+** with the [SQLITE_OPEN_NOMUTEX] flag, then the behavior is undefined.
+**
+** If the [SQLITE_OPEN_NOMUTEX] flag is set, then mutexes on the
+** opened [database connection] are disabled and the appliation must
+** insure that access to the [database connection] and its associated
+** [prepared statements] is serialized.  The [SQLITE_OPEN_NOMUTEX] flag
+** is the default behavior is SQLite is configured using the
+** [SQLITE_CONFIG_MULTITHREAD] or [SQLITE_CONFIG_SINGLETHREAD] options
+** to [sqlite3_config()].  The [SQLITE_OPEN_NOMUTEX] flag only makes a
+** difference when SQLite is in its default [SQLITE_CONFIG_SERIALIZED] mode.
+**
+** If the filename is ":memory:", then a private, temporary in-memory database
+** is created for the connection.  This in-memory database will vanish when
+** the database connection is closed.  Future versions of SQLite might
+** make use of additional special filenames that begin with the ":" character.
+** It is recommended that when a database filename actually does begin with
+** a ":" character you should prefix the filename with a pathname such as
+** "./" to avoid ambiguity.
 **
-** If the filename is an empty string, then a private temporary
+** If the filename is an empty string, then a private, temporary
 ** on-disk database will be created.  This private database will be
 ** automatically deleted as soon as the database connection is closed.
 **
 ** 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.  If the
-** fourth parameter is a NULL pointer then the default [sqlite3_vfs]
-** object is used.
+** [sqlite3_vfs] object that defines the operating system interface that
+** the new database connection should use.  If the fourth parameter is
+** a NULL pointer then the default [sqlite3_vfs] object is used.
 **
-** <b>Note to windows users:</b>  The encoding used for the filename argument
-** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever
+** <b>Note to Windows users:</b>  The encoding used for the filename argument
+** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
 ** codepage is currently defined.  Filenames containing international
 ** characters must be converted to UTF-8 prior to passing them into
-** [sqlite3_open()] or [sqlite3_open_v2()].
+** sqlite3_open() or sqlite3_open_v2().
 **
 ** INVARIANTS:
 **
@@ -2429,7 +2805,7 @@
 **          for [sqlite3_open()] and [sqlite3_open_v2()] and as UTF-16
 **          in the native byte order for [sqlite3_open16()].
 **
-** {F12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()], 
+** {F12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()],
 **          or [sqlite3_open_v2()] writes a pointer to a new
 **          [database connection] into *ppDb.
 **
@@ -2472,14 +2848,18 @@
 **          in sqlite3_open_v2()?</todo>
 **
 ** {F12719} If the filename is NULL or an empty string, then a private,
-**          ephermeral on-disk database will be created.
+**          ephemeral on-disk database will be created.
 **          <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
 **          in sqlite3_open_v2()?</todo>
 **
-** {F12721} The [database connection] created by 
-**          [sqlite3_open_v2(F,D,G,V)] will use the
-**          [sqlite3_vfs] object identified by the V parameter, or
-**          the default [sqlite3_vfs] object is V is a NULL pointer.
+** {F12721} The [database connection] created by [sqlite3_open_v2(F,D,G,V)]
+**          will use the [sqlite3_vfs] object identified by the V parameter,
+**          or the default [sqlite3_vfs] object if V is a NULL pointer.
+**
+** {F12723} Two [database connections] will share a common cache if both were
+**          opened with the same VFS while [shared cache mode] was enabled and
+**          if both filenames compare equal using memcmp() after having been
+**          processed by the [sqlite3_vfs | xFullPathname] method of the VFS.
 */
 SQLITE_API int sqlite3_open(
   const char *filename,   /* Database filename (UTF-8) */
@@ -2499,32 +2879,33 @@
 /*
 ** CAPI3REF: Error Codes And Messages {F12800}
 **
-** The sqlite3_errcode() interface returns the numeric
-** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code]
-** for the most recent failed sqlite3_* API call associated
-** with [sqlite3] handle 'db'. If a prior API call failed but the
-** most recent API call succeeded, the return value from sqlite3_errcode()
-** is undefined.
+** The sqlite3_errcode() interface returns the numeric [result code] or
+** [extended result code] for the most recent failed sqlite3_* API call
+** associated with a [database connection]. If a prior API call failed
+** but the most recent API call succeeded, the return value from
+** sqlite3_errcode() is undefined.
 **
 ** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
-** text that describes the error, as either UTF8 or UTF16 respectively.
+** text that describes the error, as either UTF-8 or UTF-16 respectively.
 ** Memory to hold the error message string is managed internally.
-** The application does not need to worry with freeing the result.
+** 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.
 **
+** If an interface fails with SQLITE_MISUSE, that means the interface
+** was invoked incorrectly by the application.  In that case, the
+** error code and message may or may not be set.
+**
 ** INVARIANTS:
 **
 ** {F12801} The [sqlite3_errcode(D)] interface returns the numeric
-**          [SQLITE_OK | result code] or
-**          [SQLITE_IOERR_READ | extended result code]
-**          for the most recently failed interface call associated
-**          with [database connection] D.
+**          [result code] or [extended result code] for the most recently
+**          failed interface call associated with the [database connection] D.
 **
 ** {F12803} The [sqlite3_errmsg(D)] and [sqlite3_errmsg16(D)]
 **          interfaces return English-language text that describes
 **          the error in the mostly recently failed interface call,
-**          encoded as either UTF8 or UTF16 respectively.
+**          encoded as either UTF-8 or UTF-16 respectively.
 **
 ** {F12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]
 **          are valid until the next SQLite interface call.
@@ -2548,17 +2929,17 @@
 ** CAPI3REF: SQL Statement Object {F13000}
 ** KEYWORDS: {prepared statement} {prepared statements}
 **
-** An instance of this object represent single SQL statements.  This
-** object is variously known as a "prepared statement" or a 
+** An instance of this object represents a single SQL statement.
+** This object is variously known as a "prepared statement" or a
 ** "compiled SQL statement" or simply as a "statement".
-** 
+**
 ** The life of a statement object goes something like this:
 **
 ** <ol>
 ** <li> Create the object using [sqlite3_prepare_v2()] or a related
 **      function.
-** <li> Bind values to host parameters using
-**      [sqlite3_bind_blob | sqlite3_bind_* interfaces].
+** <li> Bind values to [host parameters] using the sqlite3_bind_*()
+**      interfaces.
 ** <li> Run the SQL by calling [sqlite3_step()] one or more times.
 ** <li> Reset the statement using [sqlite3_reset()] then go back
 **      to step 2.  Do this zero or more times.
@@ -2582,7 +2963,7 @@
 **
 ** If the new limit is a negative number, the limit is unchanged.
 ** For the limit category of SQLITE_LIMIT_XYZ there is a hard upper
-** bound set by a compile-time C-preprocess macro named SQLITE_MAX_XYZ.
+** bound set by a compile-time C preprocessor macro named SQLITE_MAX_XYZ.
 ** (The "_LIMIT_" in the name is changed to "_MAX_".)
 ** Attempts to increase a limit above its hard upper bound are
 ** silently truncated to the hard upper limit.
@@ -2591,47 +2972,44 @@
 ** both their own internal database and also databases that are controlled
 ** by untrusted external sources.  An example application might be a
 ** webbrowser that has its own databases for storing history and
-** separate databases controlled by javascript applications downloaded
-** off the internet.  The internal databases can be given the
+** separate databases controlled by JavaScript applications downloaded
+** off the Internet.  The internal databases can be given the
 ** large, default limits.  Databases managed by external sources can
 ** be given much smaller limits designed to prevent a denial of service
-** attach.  Developers might also want to use the [sqlite3_set_authorizer()]
+** attack.  Developers might also want to use the [sqlite3_set_authorizer()]
 ** interface to further control untrusted SQL.  The size of the database
 ** created by an untrusted script can be contained using the
 ** [max_page_count] [PRAGMA].
 **
-** This interface is currently considered experimental and is subject
-** to change or removal without prior notice.
+** New run-time limit categories may be added in future releases.
 **
 ** INVARIANTS:
 **
 ** {F12762} A successful call to [sqlite3_limit(D,C,V)] where V is
-**          positive changes the
-**          limit on the size of construct C in [database connection] D
-**          to the lessor of V and the hard upper bound on the size
-**          of C that is set at compile-time.
+**          positive changes the limit on the size of construct C in the
+**          [database connection] D to the lesser of V and the hard upper
+**          bound on the size of C that is set at compile-time.
 **
 ** {F12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative
-**          leaves the state of [database connection] D unchanged.
+**          leaves the state of the [database connection] D unchanged.
 **
 ** {F12769} A successful call to [sqlite3_limit(D,C,V)] returns the
-**          value of the limit on the size of construct C in
-**          in [database connection] D as it was prior to the call.
+**          value of the limit on the size of construct C in the
+**          [database connection] D as it was prior to the call.
 */
 SQLITE_API int sqlite3_limit(sqlite3*, int id, int newVal);
 
 /*
 ** CAPI3REF: Run-Time Limit Categories {F12790}
 ** KEYWORDS: {limit category} {limit categories}
-** 
+**
 ** These constants define various aspects of a [database connection]
 ** that can be limited in size by calls to [sqlite3_limit()].
 ** The meanings of the various limits are as follows:
 **
 ** <dl>
 ** <dt>SQLITE_LIMIT_LENGTH</dt>
-** <dd>The maximum size of any
-** string or blob or table row.<dd>
+** <dd>The maximum size of any string or BLOB or table row.<dd>
 **
 ** <dt>SQLITE_LIMIT_SQL_LENGTH</dt>
 ** <dd>The maximum length of an SQL statement.</dd>
@@ -2679,51 +3057,49 @@
 
 /*
 ** CAPI3REF: Compiling An SQL Statement {F13010}
+** KEYWORDS: {SQL statement compiler}
 **
 ** To execute an SQL query, it must first be compiled into a byte-code
-** program using one of these routines. 
+** program using one of these routines.
 **
-** The first argument "db" is an [database connection] 
-** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()]
-** or [sqlite3_open16()]. 
-** The second argument "zSql" is the statement to be compiled, encoded
+** The first argument, "db", is a [database connection] obtained from a
+** prior call to [sqlite3_open()], [sqlite3_open_v2()] or [sqlite3_open16()].
+**
+** The second argument, "zSql", is the statement to be compiled, encoded
 ** as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
-** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2()
-** use UTF-16. {END}
+** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
+** use UTF-16.
 **
-** If the nByte argument is less
-** than zero, then zSql is read up to the first zero terminator.
-** If nByte is non-negative, then it is the maximum number of 
-** bytes read from zSql.  When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or 
+** If the nByte argument is less than zero, then zSql is read up to the
+** first zero terminator. If nByte is non-negative, then it is the maximum
+** number of  bytes read from zSql.  When nByte is non-negative, the
+** zSql string ends at either the first '\000' or '\u0000' character or
 ** the nByte-th byte, whichever comes first. If the caller knows
 ** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be had by passing an nByte parameter that 
-** is equal to the number of bytes in the input string <i>including</i> 
-** the nul-terminator bytes.{END}
+** performance advantage to be gained by passing an nByte parameter that
+** is equal to the number of bytes in the input string <i>including</i>
+** the nul-terminator bytes.
 **
 ** *pzTail is made to point to the first byte past the end of the
-** first SQL statement in zSql.  These routines only compiles the first
+** first SQL statement in zSql.  These routines only compile the first
 ** statement in zSql, so *pzTail is left pointing to what remains
 ** uncompiled.
 **
 ** *ppStmt is left pointing to a compiled [prepared statement] that can be
-** executed using [sqlite3_step()].  Or if there is an error, *ppStmt is
-** set to NULL.  If the input text contains no SQL (if the input
-** is and empty string or a comment) then *ppStmt is set to NULL.
-** {U13018} The calling procedure is responsible for deleting the
-** compiled SQL statement
-** using [sqlite3_finalize()] after it has finished with it.
+** executed using [sqlite3_step()].  If there is an error, *ppStmt is set
+** to NULL.  If the input text contains no SQL (if the input is an empty
+** string or a comment) then *ppStmt is set to NULL.
+** {A13018} The calling procedure is responsible for deleting the compiled
+** SQL statement using [sqlite3_finalize()] after it has finished with it.
 **
-** On success, [SQLITE_OK] is returned.  Otherwise an 
-** [error code] is returned.
+** On success, [SQLITE_OK] is returned, otherwise an [error code] is returned.
 **
 ** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
 ** recommended for all new programs. The two older interfaces are retained
 ** for backwards compatibility, but their use is discouraged.
 ** In the "v2" interfaces, the prepared statement
-** that is returned (the [sqlite3_stmt] object) contains a copy of the 
-** original SQL text. {END} This causes the [sqlite3_step()] interface to
+** that is returned (the [sqlite3_stmt] object) contains a copy of the
+** original SQL text. This causes the [sqlite3_step()] interface to
 ** behave a differently in two ways:
 **
 ** <ol>
@@ -2732,22 +3108,19 @@
 ** always used to do, [sqlite3_step()] will automatically recompile the SQL
 ** statement and try to run it again.  If the schema has changed in
 ** a way that makes the statement no longer valid, [sqlite3_step()] will still
-** return [SQLITE_SCHEMA].  But unlike the legacy behavior, 
-** [SQLITE_SCHEMA] is now a fatal error.  Calling
-** [sqlite3_prepare_v2()] again will not make the
+** return [SQLITE_SCHEMA].  But unlike the legacy behavior, [SQLITE_SCHEMA] is
+** now a fatal error.  Calling [sqlite3_prepare_v2()] again will not make the
 ** error go away.  Note: use [sqlite3_errmsg()] to find the text
-** of the parsing error that results in an [SQLITE_SCHEMA] return. {END}
+** of the parsing error that results in an [SQLITE_SCHEMA] return.
 ** </li>
 **
 ** <li>
-** When an error occurs, 
-** [sqlite3_step()] will return one of the detailed 
-** [error codes] or [extended error codes]. 
-** The legacy behavior was that [sqlite3_step()] would only return a generic
-** [SQLITE_ERROR] result code and you would have to make a second call to
-** [sqlite3_reset()] in order to find the underlying cause of the problem.
-** With the "v2" prepare interfaces, the underlying reason for the error is
-** returned immediately.
+** When an error occurs, [sqlite3_step()] will return one of the detailed
+** [error codes] or [extended error codes].  The legacy behavior was that
+** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
+** and you would have to make a second call to [sqlite3_reset()] in order
+** to find the underlying cause of the problem. With the "v2" prepare
+** interfaces, the underlying reason for the error is returned immediately.
 ** </li>
 ** </ol>
 **
@@ -2762,11 +3135,11 @@
 **          text in their zSql parameter as UTF-16 in the native byte order.
 **
 ** {F13013} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
-**          and its variants is less than zero, then SQL text is
+**          and its variants is less than zero, the SQL text is
 **          read from zSql is read up to the first zero terminator.
 **
 ** {F13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
-**          and its variants is non-negative, then at most nBytes bytes
+**          and its variants is non-negative, then at most nBytes bytes of
 **          SQL text is read from zSql.
 **
 ** {F13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants
@@ -2777,15 +3150,15 @@
 **
 ** {F13016} A successful call to [sqlite3_prepare_v2(db,zSql,N,ppStmt,...)]
 **          or one of its variants writes into *ppStmt a pointer to a new
-**          [prepared statement] or a pointer to NULL
-**          if zSql contains nothing other than whitespace or comments. 
+**          [prepared statement] or a pointer to NULL if zSql contains
+**          nothing other than whitespace or comments.
 **
 ** {F13019} The [sqlite3_prepare_v2()] interface and its variants return
 **          [SQLITE_OK] or an appropriate [error code] upon failure.
 **
 ** {F13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its
-**          variants returns an error (any value other than [SQLITE_OK])
-**          it first sets *ppStmt to NULL.
+**          variants returns an error (any value other than [SQLITE_OK]),
+**          they first set *ppStmt to NULL.
 */
 SQLITE_API int sqlite3_prepare(
   sqlite3 *db,            /* Database handle */
@@ -2819,24 +3192,21 @@
 /*
 ** CAPIREF: Retrieving Statement SQL {F13100}
 **
-** This intereface can be used to retrieve a saved copy of the original
-** SQL text used to create a [prepared statement].
+** This interface can be used to retrieve a saved copy of the original
+** SQL text used to create a [prepared statement] if that statement was
+** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
 **
 ** INVARIANTS:
 **
-** {F13101} If the [prepared statement] passed as 
-**          the an argument to [sqlite3_sql()] was compiled
-**          compiled using either [sqlite3_prepare_v2()] or
-**          [sqlite3_prepare16_v2()],
-**          then [sqlite3_sql()] function returns a pointer to a
-**          zero-terminated string containing a UTF-8 rendering
+** {F13101} If the [prepared statement] passed as the argument to
+**          [sqlite3_sql()] was compiled using either [sqlite3_prepare_v2()] or
+**          [sqlite3_prepare16_v2()], then [sqlite3_sql()] returns
+**          a pointer to a zero-terminated string containing a UTF-8 rendering
 **          of the original SQL statement.
 **
-** {F13102} If the [prepared statement] passed as 
-**          the an argument to [sqlite3_sql()] was compiled
-**          compiled using either [sqlite3_prepare()] or
-**          [sqlite3_prepare16()],
-**          then [sqlite3_sql()] function returns a NULL pointer.
+** {F13102} If the [prepared statement] passed as the argument to
+**          [sqlite3_sql()] was compiled using either [sqlite3_prepare()] or
+**          [sqlite3_prepare16()], then [sqlite3_sql()] returns a NULL pointer.
 **
 ** {F13103} The string returned by [sqlite3_sql(S)] is valid until the
 **          [prepared statement] S is deleted using [sqlite3_finalize(S)].
@@ -2844,58 +3214,65 @@
 SQLITE_API const char *sqlite3_sql(sqlite3_stmt *pStmt);
 
 /*
-** CAPI3REF:  Dynamically Typed Value Object  {F15000}
+** CAPI3REF: Dynamically Typed Value Object {F15000}
 ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
 **
 ** SQLite uses the sqlite3_value object to represent all values
-** that can be stored in a database table.
-** SQLite uses dynamic typing for the values it stores.  
-** Values stored in sqlite3_value objects can be
-** be integers, floating point values, strings, BLOBs, or NULL.
+** that can be stored in a database table. SQLite uses dynamic typing
+** for the values it stores. Values stored in sqlite3_value objects
+** can be integers, floating point values, strings, BLOBs, or NULL.
 **
 ** An sqlite3_value object may be either "protected" or "unprotected".
 ** Some interfaces require a protected sqlite3_value.  Other interfaces
 ** will accept either a protected or an unprotected sqlite3_value.
-** Every interface that accepts sqlite3_value arguments specifies 
+** Every interface that accepts sqlite3_value arguments specifies
 ** whether or not it requires a protected sqlite3_value.
 **
 ** The terms "protected" and "unprotected" refer to whether or not
 ** a mutex is held.  A internal mutex is held for a protected
 ** 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)
-** then there is no distinction between
-** protected and unprotected sqlite3_value objects and they can be
-** used interchangable.  However, for maximum code portability it
-** is recommended that applications make the distinction between
-** between protected and unprotected sqlite3_value objects even if
-** they are single threaded.
+** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
+** 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,
+** for maximum code portability it is recommended that applications
+** still make the distinction between between protected and unprotected
+** sqlite3_value objects even when not strictly required.
 **
 ** The sqlite3_value objects that are passed as parameters into the
-** implementation of application-defined SQL functions are protected.
+** implementation of [application-defined SQL functions] are protected.
 ** The sqlite3_value object returned by
 ** [sqlite3_column_value()] is unprotected.
 ** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].  All other
-** interfaces that use sqlite3_value require protected sqlite3_value objects.
+** [sqlite3_result_value()] and [sqlite3_bind_value()].
+** The [sqlite3_value_blob | sqlite3_value_type()] family of
+** interfaces require protected sqlite3_value objects.
 */
 typedef struct Mem sqlite3_value;
 
 /*
-** CAPI3REF:  SQL Function Context Object {F16001}
+** CAPI3REF: SQL Function Context Object {F16001}
 **
 ** The context in which an SQL function executes is stored in an
-** sqlite3_context object.  A pointer to an sqlite3_context
-** object is always first parameter to application-defined SQL functions.
+** sqlite3_context object.  A pointer to an sqlite3_context object
+** is always first parameter to [application-defined SQL functions].
+** The application-defined SQL function implementation will pass this
+** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
+** [sqlite3_aggregate_context()], [sqlite3_user_data()],
+** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
+** and/or [sqlite3_set_auxdata()].
 */
 typedef struct sqlite3_context sqlite3_context;
 
 /*
-** CAPI3REF:  Binding Values To Prepared Statements {F13500}
+** CAPI3REF: Binding Values To Prepared Statements {F13500}
+** KEYWORDS: {host parameter} {host parameters} {host parameter name}
+** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
 **
-** In the SQL strings input to [sqlite3_prepare_v2()] and its
-** variants, literals may be replace by a parameter in one
-** of these forms:
+** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
+** literals may be replaced by a parameter in one of these forms:
 **
 ** <ul>
 ** <li>  ?
@@ -2906,32 +3283,31 @@
 ** </ul>
 **
 ** In the parameter forms shown above NNN is an integer literal,
-** VVV alpha-numeric parameter name.
-** The values of these parameters (also called "host parameter names"
-** or "SQL parameters")
+** and VVV is an alpha-numeric parameter name. The values of these
+** parameters (also called "host parameter names" or "SQL parameters")
 ** can be set using the sqlite3_bind_*() routines defined here.
 **
-** The first argument to the sqlite3_bind_*() routines always
-** is a pointer to the [sqlite3_stmt] object returned from
-** [sqlite3_prepare_v2()] or its variants. The second
-** argument is the index of the parameter to be set. The
-** first parameter has an index of 1.  When the same named
-** parameter is used more than once, second and subsequent
-** occurrences have the same index as the first occurrence. 
+** 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.
+**
+** The second argument is the index of the SQL parameter to be set.
+** The leftmost SQL parameter has an index of 1.  When the same named
+** SQL parameter is used more than once, second and subsequent
+** occurrences have the same index as the first occurrence.
 ** The index for named parameters can be looked up using the
-** [sqlite3_bind_parameter_name()] API if desired.  The index
+** [sqlite3_bind_parameter_index()] API if desired.  The index
 ** for "?NNN" parameters is the value of NNN.
-** The NNN value must be between 1 and the compile-time
-** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999).
+** The NNN value must be between 1 and the [sqlite3_limit()]
+** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
 **
 ** The third argument is the value to bind to the parameter.
 **
-** 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 <u>bytes</u>
-** in the value, not the number of characters. 
+** 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 <u>bytes</u> in the value, not the number of characters.
 ** If the fourth parameter is negative, the length of the string is
-** number of bytes up to the first zero terminator.
+** the number of bytes up to the first zero terminator.
 **
 ** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
@@ -2943,12 +3319,12 @@
 ** the sqlite3_bind_*() routine returns.
 **
 ** The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
-** is filled with zeros.  A zeroblob uses a fixed amount of memory
-** (just an integer to hold it size) while it is being processed.
-** Zeroblobs are intended to serve as place-holders for BLOBs whose
-** content is later written using 
-** [sqlite3_blob_open | increment BLOB I/O] routines. A negative
-** value for the zeroblob results in a zero-length BLOB.
+** is filled with zeroes.  A zeroblob uses a fixed amount of memory
+** (just an integer to hold its size) while it is being processed.
+** Zeroblobs are intended to serve as placeholders for BLOBs whose
+** content is later written using
+** [sqlite3_blob_open | incremental BLOB I/O] routines.
+** A negative value for the zeroblob results in a zero-length BLOB.
 **
 ** The sqlite3_bind_*() routines must be called after
 ** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and
@@ -2958,7 +3334,7 @@
 **
 ** These routines return [SQLITE_OK] on success or an error code if
 ** anything goes wrong.  [SQLITE_RANGE] is returned if the parameter
-** index is out of range.  [SQLITE_NOMEM] is returned if malloc fails.
+** index is out of range.  [SQLITE_NOMEM] is returned if malloc() fails.
 ** [SQLITE_MISUSE] might be returned if these routines are called on a
 ** virtual machine that is the wrong state or which has already been finalized.
 ** Detection of misuse is unreliable.  Applications should not depend
@@ -2967,17 +3343,16 @@
 ** panic rather than return SQLITE_MISUSE.
 **
 ** See also: [sqlite3_bind_parameter_count()],
-** [sqlite3_bind_parameter_name()], and
-** [sqlite3_bind_parameter_index()].
+** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
 **
 ** INVARIANTS:
 **
-** {F13506} The [sqlite3_prepare | SQL statement compiler] recognizes
-**          tokens of the forms "?", "?NNN", "$VVV", ":VVV", and "@VVV"
-**          as SQL parameters, where NNN is any sequence of one or more
-**          digits and where VVV is any sequence of one or more 
-**          alphanumeric characters or "::" optionally followed by
-**          a string containing no spaces and contained within parentheses.
+** {F13506} The [SQL statement compiler] recognizes tokens of the forms
+**          "?", "?NNN", "$VVV", ":VVV", and "@VVV" as SQL parameters,
+**          where NNN is any sequence of one or more digits
+**          and where VVV is any sequence of one or more alphanumeric
+**          characters or "::" optionally followed by a string containing
+**          no spaces and contained within parentheses.
 **
 ** {F13509} The initial value of an SQL parameter is NULL.
 **
@@ -2988,14 +3363,15 @@
 ** {F13515} The index of an "?NNN" SQL parameter is the integer NNN.
 **
 ** {F13518} The index of an ":VVV", "$VVV", or "@VVV" SQL parameter is
-**          the same as the index of leftmost occurances of the same
+**          the same as the index of leftmost occurrences of the same
 **          parameter, or one more than the largest index over all
-**          parameters to the left if this is the first occurrance
+**          parameters to the left if this is the first occurrence
 **          of this parameter, or 1 if this is the leftmost parameter.
 **
-** {F13521} The [sqlite3_prepare | SQL statement compiler] fail with
-**          an [SQLITE_RANGE] error if the index of an SQL parameter
-**          is less than 1 or greater than SQLITE_MAX_VARIABLE_NUMBER.
+** {F13521} The [SQL statement compiler] fails with an [SQLITE_RANGE]
+**          error if the index of an SQL parameter is less than 1
+**          or greater than the compile-time SQLITE_MAX_VARIABLE_NUMBER
+**          parameter.
 **
 ** {F13524} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,V,...)]
 **          associate the value V with all SQL parameters having an
@@ -3010,7 +3386,7 @@
 ** {F13533} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
 **          [sqlite3_bind_text(S,N,V,L,D)], or
 **          [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds the first L
-**          bytes of the blob or string pointed to by V, when L
+**          bytes of the BLOB or string pointed to by V, when L
 **          is non-negative.
 **
 ** {F13536} In calls to [sqlite3_bind_text(S,N,V,L,D)] or
@@ -3027,17 +3403,17 @@
 ** {F13542} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
 **          [sqlite3_bind_text(S,N,V,L,D)], or
 **          [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
-**          constant [SQLITE_TRANSIENT], the routine makes a 
-**          private copy of V value before it returns.
+**          constant [SQLITE_TRANSIENT], the routine makes a
+**          private copy of the value V before it returns.
 **
 ** {F13545} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
 **          [sqlite3_bind_text(S,N,V,L,D)], or
 **          [sqlite3_bind_text16(S,N,V,L,D)] when D is a pointer to
 **          a function, SQLite invokes that function to destroy the
-**          V value after it has finished using the V value.
+**          value V after it has finished using the value V.
 **
 ** {F13548} In calls to [sqlite3_bind_zeroblob(S,N,V,L)] the value bound
-**          is a blob of L bytes, or a zero-length blob if L is negative.
+**          is a BLOB of L bytes, or a zero-length BLOB if L is negative.
 **
 ** {F13551} In calls to [sqlite3_bind_value(S,N,V)] the V argument may
 **          be either a [protected sqlite3_value] object or an
@@ -3056,16 +3432,16 @@
 /*
 ** CAPI3REF: Number Of SQL Parameters {F13600}
 **
-** This routine can be used to find the number of SQL parameters
-** in a prepared statement.  SQL parameters are tokens of the
+** This routine can be used to find the number of [SQL parameters]
+** in a [prepared statement].  SQL parameters are tokens of the
 ** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
-** place-holders for values that are [sqlite3_bind_blob | bound]
+** placeholders for values that are [sqlite3_bind_blob | bound]
 ** to the parameters at a later time.
 **
-** This routine actually returns the index of the largest parameter.
-** For all forms except ?NNN, this will correspond to the number of
-** unique parameters.  If parameters of the ?NNN are used, there may
-** be gaps in the list.
+** 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 are used,
+** there may be gaps in the list.
 **
 ** See also: [sqlite3_bind_blob|sqlite3_bind()],
 ** [sqlite3_bind_parameter_name()], and
@@ -3075,8 +3451,7 @@
 **
 ** {F13601} The [sqlite3_bind_parameter_count(S)] interface returns
 **          the largest index of all SQL parameters in the
-**          [prepared statement] S, or 0 if S
-**          contains no SQL parameters.
+**          [prepared statement] S, or 0 if S contains no SQL parameters.
 */
 SQLITE_API int sqlite3_bind_parameter_count(sqlite3_stmt*);
 
@@ -3084,19 +3459,20 @@
 ** CAPI3REF: Name Of A Host Parameter {F13620}
 **
 ** This routine returns a pointer to the name of the n-th
-** SQL parameter in a [prepared statement].
+** [SQL parameter] in a [prepared statement].
 ** 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.
-** Parameters of the form "?" without a following integer have no name.
+** Parameters of the form "?" without a following integer have no name
+** and are also referred to as "anonymous parameters".
 **
 ** The first host parameter has an index of 1, not 0.
 **
 ** If the value n is out of range or if the n-th parameter is
 ** nameless, then NULL is returned.  The returned string is
-** always in the UTF-8 encoding even if the named parameter was
+** always in UTF-8 encoding even if the named parameter was
 ** originally specified as UTF-16 in [sqlite3_prepare16()] or
 ** [sqlite3_prepare16_v2()].
 **
@@ -3108,7 +3484,7 @@
 **
 ** {F13621} The [sqlite3_bind_parameter_name(S,N)] interface returns
 **          a UTF-8 rendering of the name of the SQL parameter in
-**          [prepared statement] S having index N, or
+**          the [prepared statement] S having index N, or
 **          NULL if there is no SQL parameter with index N or if the
 **          parameter with index N is an anonymous parameter "?".
 */
@@ -3131,7 +3507,7 @@
 ** INVARIANTS:
 **
 ** {F13641} The [sqlite3_bind_parameter_index(S,N)] interface returns
-**          the index of SQL parameter in [prepared statement]
+**          the index of SQL parameter in the [prepared statement]
 **          S whose name matches the UTF-8 string N, or 0 if there is
 **          no match.
 */
@@ -3140,33 +3516,29 @@
 /*
 ** CAPI3REF: Reset All Bindings On A Prepared Statement {F13660}
 **
-** Contrary to the intuition of many, [sqlite3_reset()] does not
-** reset the [sqlite3_bind_blob | bindings] on a 
-** [prepared statement].  Use this routine to
-** reset all host parameters to NULL.
+** Contrary to the intuition of many, [sqlite3_reset()] does not reset
+** the [sqlite3_bind_blob | bindings] on a [prepared statement].
+** Use this routine to reset all host parameters to NULL.
 **
 ** INVARIANTS:
 **
-** {F13661} The [sqlite3_clear_bindings(S)] interface resets all
-**          SQL parameter bindings in [prepared statement] S
-**          back to NULL.
+** {F13661} The [sqlite3_clear_bindings(S)] interface resets all SQL
+**          parameter bindings in the [prepared statement] S back to NULL.
 */
 SQLITE_API int sqlite3_clear_bindings(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Number Of Columns In A Result Set {F13710}
 **
-** Return the number of columns in the result set returned by the 
-** [prepared statement]. This routine returns 0
-** if pStmt is an SQL statement that does not return data (for 
-** example an UPDATE).
+** Return the number of columns in the result set returned by the
+** [prepared statement]. This routine returns 0 if pStmt is an SQL
+** statement that does not return data (for example an [UPDATE]).
 **
 ** INVARIANTS:
 **
 ** {F13711} The [sqlite3_column_count(S)] interface returns the number of
-**          columns in the result set generated by the
-**          [prepared statement] S, or 0 if S does not generate
-**          a result set.
+**          columns in the result set generated by the [prepared statement] S,
+**          or 0 if S does not generate a result set.
 */
 SQLITE_API int sqlite3_column_count(sqlite3_stmt *pStmt);
 
@@ -3174,18 +3546,16 @@
 ** CAPI3REF: Column Names In A Result Set {F13720}
 **
 ** These routines return the name assigned to a particular column
-** in the result set of a SELECT statement.  The sqlite3_column_name()
-** interface returns a pointer to a zero-terminated UTF8 string
+** in the result set of a [SELECT] statement.  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
-** UTF16 string.  The first parameter is the
-** [prepared statement] that implements the SELECT statement.
-** The second parameter is the column number.  The left-most column is
-** number 0.
-**
-** The returned string pointer is valid until either the 
-** [prepared statement] is destroyed by [sqlite3_finalize()]
-** or until the next call sqlite3_column_name() or sqlite3_column_name16()
-** on the same column.
+** UTF-16 string.  The first parameter is the [prepared statement]
+** that implements the [SELECT] statement. The second parameter is the
+** column number.  The leftmost column is number 0.
+**
+** The returned string pointer is valid until either the [prepared statement]
+** is destroyed by [sqlite3_finalize()] or until the next call to
+** sqlite3_column_name() or sqlite3_column_name16() on the same column.
 **
 ** If sqlite3_malloc() fails during the processing of either routine
 ** (for example during a conversion from UTF-8 to UTF-16) then a
@@ -3199,32 +3569,31 @@
 ** INVARIANTS:
 **
 ** {F13721} A successful invocation of the [sqlite3_column_name(S,N)]
-**          interface returns the name
-**          of the Nth column (where 0 is the left-most column) for the
-**          result set of [prepared statement] S as a
-**          zero-terminated UTF-8 string.
+**          interface returns the name of the Nth column (where 0 is
+**          the leftmost column) for the result set of the
+**          [prepared statement] S as a zero-terminated UTF-8 string.
 **
 ** {F13723} A successful invocation of the [sqlite3_column_name16(S,N)]
-**          interface returns the name
-**          of the Nth column (where 0 is the left-most column) for the
-**          result set of [prepared statement] S as a
-**          zero-terminated UTF-16 string in the native byte order.
+**          interface returns the name of the Nth column (where 0 is
+**          the leftmost column) for the result set of the
+**          [prepared statement] S as a zero-terminated UTF-16 string
+**          in the native byte order.
 **
 ** {F13724} The [sqlite3_column_name()] and [sqlite3_column_name16()]
 **          interfaces return a NULL pointer if they are unable to
-**          allocate memory memory to hold there normal return strings.
+**          allocate memory to hold their normal return strings.
 **
 ** {F13725} If the N parameter to [sqlite3_column_name(S,N)] or
 **          [sqlite3_column_name16(S,N)] is out of range, then the
-**          interfaces returns a NULL pointer.
-** 
+**          interfaces return a NULL pointer.
+**
 ** {F13726} The strings returned by [sqlite3_column_name(S,N)] and
 **          [sqlite3_column_name16(S,N)] are valid until the next
 **          call to either routine with the same S and N parameters
 **          or until [sqlite3_finalize(S)] is called.
 **
 ** {F13727} When a result column of a [SELECT] statement contains
-**          an AS clause, the name of that column is the indentifier
+**          an AS clause, the name of that column is the identifier
 **          to the right of the AS keyword.
 */
 SQLITE_API const char *sqlite3_column_name(sqlite3_stmt*, int N);
@@ -3234,37 +3603,35 @@
 ** CAPI3REF: Source Of Data In A Query Result {F13740}
 **
 ** These routines provide a means to determine what column of what
-** table in which database a result of a SELECT statement comes from.
+** table in which database a result of a [SELECT] statement comes from.
 ** The name of the database or table or column can be returned as
-** either a UTF8 or UTF16 string.  The _database_ routines return
+** either a UTF-8 or UTF-16 string.  The _database_ routines return
 ** the database name, the _table_ routines return the table name, and
 ** the origin_ routines return the column name.
-** The returned string is valid until
-** the [prepared statement] is destroyed using
-** [sqlite3_finalize()] or until the same information is requested
+** The returned string is valid until the [prepared statement] is destroyed
+** using [sqlite3_finalize()] or until the same information is requested
 ** again in a different encoding.
 **
 ** The names returned are the original un-aliased names of the
 ** database, table, and column.
 **
 ** The first argument to the following calls is a [prepared statement].
-** These functions return information about the Nth column returned by 
+** These functions return information about the Nth column returned by
 ** the statement, where N is the second function argument.
 **
-** 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.  These routine might also return NULL if a memory
-** allocation error occurs.  Otherwise, they return the 
-** name of the attached database, table and column that query result
-** column was extracted from.
+** 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.  These routine might also return NULL if a memory allocation error
+** occurs.  Otherwise, they return the name of the attached database, table
+** and column that query result column was extracted from.
 **
 ** As with all other SQLite APIs, those postfixed with "16" return
 ** UTF-16 encoded strings, the other functions return UTF-8. {END}
 **
-** These APIs are only available if the library was compiled with the 
-** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+** These APIs are only available if the library was compiled with the
+** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
 **
-** {U13751}
+** {A13751}
 ** If two or more threads call one or more of these routines against the same
 ** prepared statement and column at the same time then the results are
 ** undefined.
@@ -3272,62 +3639,53 @@
 ** INVARIANTS:
 **
 ** {F13741} The [sqlite3_column_database_name(S,N)] interface returns either
-**          the UTF-8 zero-terminated name of the database from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-8 zero-terminated name of the database from which the
+**          Nth result column of the [prepared statement] S is extracted,
+**          or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13742} The [sqlite3_column_database_name16(S,N)] interface returns either
-**          the UTF-16 native byte order
-**          zero-terminated name of the database from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-16 native byte order zero-terminated name of the database
+**          from which the Nth result column of the [prepared statement] S is
+**          extracted, or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13743} The [sqlite3_column_table_name(S,N)] interface returns either
-**          the UTF-8 zero-terminated name of the table from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-8 zero-terminated name of the table from which the
+**          Nth result column of the [prepared statement] S is extracted,
+**          or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13744} The [sqlite3_column_table_name16(S,N)] interface returns either
-**          the UTF-16 native byte order
-**          zero-terminated name of the table from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-16 native byte order zero-terminated name of the table
+**          from which the Nth result column of the [prepared statement] S is
+**          extracted, or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13745} The [sqlite3_column_origin_name(S,N)] interface returns either
-**          the UTF-8 zero-terminated name of the table column from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-8 zero-terminated name of the table column from which the
+**          Nth result column of the [prepared statement] S is extracted,
+**          or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13746} The [sqlite3_column_origin_name16(S,N)] interface returns either
-**          the UTF-16 native byte order
-**          zero-terminated name of the table column from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
+**          the UTF-16 native byte order zero-terminated name of the table
+**          column from which the Nth result column of the
+**          [prepared statement] S is extracted, or NULL if the Nth column
+**          of S is a general expression or if unable to allocate memory
 **          to store the name.
-**          
+**
 ** {F13748} The return values from
-**          [sqlite3_column_database_name|column metadata interfaces]
-**          are valid
-**          for the lifetime of the [prepared statement]
+**          [sqlite3_column_database_name | column metadata interfaces]
+**          are valid for the lifetime of the [prepared statement]
 **          or until the encoding is changed by another metadata
 **          interface call for the same prepared statement and column.
 **
 ** LIMITATIONS:
 **
-** {U13751} If two or more threads call one or more
-**          [sqlite3_column_database_name|column metadata interfaces]
-**          the same [prepared statement] and result column
+** {A13751} If two or more threads call one or more
+**          [sqlite3_column_database_name | column metadata interfaces]
+**          for the same [prepared statement] and result column
 **          at the same time then the results are undefined.
 */
 SQLITE_API const char *sqlite3_column_database_name(sqlite3_stmt*,int);
@@ -3340,24 +3698,24 @@
 /*
 ** CAPI3REF: Declared Datatype Of A Query Result {F13760}
 **
-** 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
+** 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.  If the Nth column of the result set is an
 ** expression or subquery, then a NULL pointer is returned.
-** The returned string is always UTF-8 encoded.  {END} 
-** For example, in the database schema:
+** The returned string is always UTF-8 encoded. {END}
+**
+** For example, given the database schema:
 **
 ** CREATE TABLE t1(c1 VARIANT);
 **
-** And the following statement compiled:
+** and the following statement to be compiled:
 **
 ** SELECT c1 + 1, c1 FROM t1;
 **
-** Then 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).
+** 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).
 **
 ** SQLite uses dynamic run-time typing.  So just because a column
 ** is declared to contain a particular type does not mean that the
@@ -3368,11 +3726,10 @@
 **
 ** INVARIANTS:
 **
-** {F13761}  A successful call to [sqlite3_column_decltype(S,N)]
-**           returns a zero-terminated UTF-8 string containing the
-**           the declared datatype of the table column that appears
-**           as the Nth column (numbered from 0) of the result set to the
-**           [prepared statement] S.
+** {F13761}  A successful call to [sqlite3_column_decltype(S,N)] returns a
+**           zero-terminated UTF-8 string containing the declared datatype
+**           of the table column that appears as the Nth column (numbered
+**           from 0) of the result set to the [prepared statement] S.
 **
 ** {F13762}  A successful call to [sqlite3_column_decltype16(S,N)]
 **           returns a zero-terminated UTF-16 native byte order string
@@ -3381,9 +3738,9 @@
 **           [prepared statement] S.
 **
 ** {F13763}  If N is less than 0 or N is greater than or equal to
-**           the number of columns in [prepared statement] S
+**           the number of columns in the [prepared statement] S,
 **           or if the Nth column of S is an expression or subquery rather
-**           than a table column or if a memory allocation failure
+**           than a table column, or if a memory allocation failure
 **           occurs during encoding conversions, then
 **           calls to [sqlite3_column_decltype(S,N)] or
 **           [sqlite3_column_decltype16(S,N)] return NULL.
@@ -3391,32 +3748,30 @@
 SQLITE_API const char *sqlite3_column_decltype(sqlite3_stmt*,int);
 SQLITE_API const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
 
-/* 
-** CAPI3REF:  Evaluate An SQL Statement {F13200}
+/*
+** CAPI3REF: Evaluate An SQL Statement {F13200}
 **
-** After an [prepared statement] has been prepared with a call
-** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of
-** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()],
-** then this function must be called one or more times to evaluate the 
-** statement.
+** After a [prepared statement] has been prepared using either
+** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
+** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
+** must be called one or more times to evaluate the statement.
 **
-** The details of the behavior of this sqlite3_step() interface depend
+** The details of the behavior of the sqlite3_step() interface depend
 ** on whether the statement was prepared using the newer "v2" interface
 ** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
 ** interface [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
 ** new "v2" interface is recommended for new applications but the legacy
 ** interface will continue to be supported.
 **
-** In the legacy interface, the return value will be either [SQLITE_BUSY], 
+** In the legacy interface, the return value will be either [SQLITE_BUSY],
 ** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
-** With the "v2" interface, any of the other [SQLITE_OK | result code]
-** or [SQLITE_IOERR_READ | extended result code] might be returned as
-** well.
+** With the "v2" interface, any of the other [result codes] or
+** [extended result codes] might be returned as well.
 **
 ** [SQLITE_BUSY] means that the database engine was unable to acquire the
-** database locks it needs to do its job.  If the statement is a COMMIT
+** database locks it needs to do its job.  If the statement is a [COMMIT]
 ** or occurs outside of an explicit transaction, then you can retry the
-** statement.  If the statement is not a COMMIT and occurs within a
+** statement.  If the statement is not a [COMMIT] and occurs within a
 ** explicit transaction then you should rollback the transaction before
 ** continuing.
 **
@@ -3425,16 +3780,15 @@
 ** machine without first calling [sqlite3_reset()] to reset the virtual
 ** machine back to its initial state.
 **
-** 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. The values may be accessed using
-** the [sqlite3_column_int | column access functions].
+** 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. The values may be accessed using the [column access functions].
 ** sqlite3_step() is called again to retrieve the next row of data.
-** 
+**
 ** [SQLITE_ERROR] means that a run-time error (such as a constraint
 ** violation) has occurred.  sqlite3_step() should not be called again on
 ** the VM. More information may be found by calling [sqlite3_errmsg()].
-** With the legacy interface, a more specific error code (example:
+** 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].  In the "v2" interface,
@@ -3442,50 +3796,47 @@
 **
 ** [SQLITE_MISUSE] means that the this routine was called inappropriately.
 ** Perhaps it was called on a [prepared statement] that has
-** already been [sqlite3_finalize | finalized] or on one that had 
+** already been [sqlite3_finalize | finalized] or on one that had
 ** previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
 ** be the case that the same database connection is being used by two or
 ** more threads at the same moment in time.
 **
-** <b>Goofy Interface Alert:</b>
-** In the legacy interface, 
-** the sqlite3_step() API always returns a generic error code,
-** [SQLITE_ERROR], following any error other than [SQLITE_BUSY]
-** and [SQLITE_MISUSE].  You must call [sqlite3_reset()] or
-** [sqlite3_finalize()] in order to find one of the specific
-** [error codes] that better describes the error.
+** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
+** API always returns a generic error code, [SQLITE_ERROR], following any
+** error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
+** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
+** specific [error codes] that better describes the error.
 ** We admit that this is a goofy design.  The problem has been fixed
 ** with the "v2" interface.  If you prepare all of your SQL statements
 ** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
-** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the 
-** more specific [error codes] are returned directly
+** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+** then the more specific [error codes] are returned directly
 ** by sqlite3_step().  The use of the "v2" interface is recommended.
 **
 ** INVARIANTS:
 **
-** {F13202}  If [prepared statement] S is ready to be
-**           run, then [sqlite3_step(S)] advances that prepared statement
-**           until to completion or until it is ready to return another
-**           row of the result set or an interrupt or run-time error occurs.
-**
-** {F15304}  When a call to [sqlite3_step(S)] causes the 
-**           [prepared statement] S to run to completion,
-**           the function returns [SQLITE_DONE].
-**
-** {F15306}  When a call to [sqlite3_step(S)] stops because it is ready
-**           to return another row of the result set, it returns
-**           [SQLITE_ROW].
+** {F13202}  If the [prepared statement] S is ready to be run, then
+**           [sqlite3_step(S)] advances that prepared statement until
+**           completion or until it is ready to return another row of the
+**           result set, or until an [sqlite3_interrupt | interrupt]
+**           or a run-time error occurs.
+**
+** {F15304}  When a call to [sqlite3_step(S)] causes the [prepared statement]
+**           S to run to completion, the function returns [SQLITE_DONE].
+**
+** {F15306}  When a call to [sqlite3_step(S)] stops because it is ready to
+**           return another row of the result set, it returns [SQLITE_ROW].
 **
 ** {F15308}  If a call to [sqlite3_step(S)] encounters an
-**           [sqlite3_interrupt|interrupt] or a run-time error,
-**           it returns an appropraite error code that is not one of
+**           [sqlite3_interrupt | interrupt] or a run-time error,
+**           it returns an appropriate error code that is not one of
 **           [SQLITE_OK], [SQLITE_ROW], or [SQLITE_DONE].
 **
-** {F15310}  If an [sqlite3_interrupt|interrupt] or run-time error
+** {F15310}  If an [sqlite3_interrupt | interrupt] or a run-time error
 **           occurs during a call to [sqlite3_step(S)]
 **           for a [prepared statement] S created using
 **           legacy interfaces [sqlite3_prepare()] or
-**           [sqlite3_prepare16()] then the function returns either
+**           [sqlite3_prepare16()], then the function returns either
 **           [SQLITE_ERROR], [SQLITE_BUSY], or [SQLITE_MISUSE].
 */
 SQLITE_API int sqlite3_step(sqlite3_stmt*);
@@ -3493,21 +3844,19 @@
 /*
 ** CAPI3REF: Number of columns in a result set {F13770}
 **
-** Return the number of values in the current row of the result set.
+** Returns the number of values in the current row of the result set.
 **
 ** INVARIANTS:
 **
-** {F13771}  After a call to [sqlite3_step(S)] that returns
-**           [SQLITE_ROW], the [sqlite3_data_count(S)] routine
-**           will return the same value as the
-**           [sqlite3_column_count(S)] function.
+** {F13771}  After a call to [sqlite3_step(S)] that returns [SQLITE_ROW],
+**           the [sqlite3_data_count(S)] routine will return the same value
+**           as the [sqlite3_column_count(S)] function.
 **
 ** {F13772}  After [sqlite3_step(S)] has returned any value other than
-**           [SQLITE_ROW] or before [sqlite3_step(S)] has been 
-**           called on the [prepared statement] for
-**           the first time since it was [sqlite3_prepare|prepared]
-**           or [sqlite3_reset|reset], the [sqlite3_data_count(S)]
-**           routine returns zero.
+**           [SQLITE_ROW] or before [sqlite3_step(S)] has been called on the
+**           [prepared statement] for the first time since it was
+**           [sqlite3_prepare | prepared] or [sqlite3_reset | reset],
+**           the [sqlite3_data_count(S)] routine returns zero.
 */
 SQLITE_API int sqlite3_data_count(sqlite3_stmt *pStmt);
 
@@ -3515,7 +3864,7 @@
 ** CAPI3REF: Fundamental Datatypes {F10265}
 ** KEYWORDS: SQLITE_TEXT
 **
-** {F10266}Every value in SQLite has one of five fundamental datatypes:
+** {F10266} Every value in SQLite has one of five fundamental datatypes:
 **
 ** <ul>
 ** <li> 64-bit signed integer
@@ -3529,7 +3878,7 @@
 **
 ** Note that the SQLITE_TEXT constant was also used in SQLite version 2
 ** for a completely different meaning.  Software that links against both
-** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not
+** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
 ** SQLITE_TEXT.
 */
 #define SQLITE_INTEGER  1
@@ -3544,33 +3893,31 @@
 #define SQLITE3_TEXT     3
 
 /*
-** CAPI3REF: Results Values From A Query {F13800}
+** CAPI3REF: Result Values From A Query {F13800}
+** KEYWORDS: {column access functions}
 **
 ** These routines form the "result set query" interface.
 **
-** These routines return information about
-** a single column of the current result row of a query.  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.  The left-most column of the result set
-** has an index of 0.
+** These routines return information about a single column of the current
+** result row of a query.  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.  The leftmost column of the result set has the index 0.
 **
-** If the SQL statement is not currently point to a valid row, or if the
-** the column index is out of range, the result is undefined. 
+** If the SQL statement does not currently point to a valid row, or if the
+** column index is out of range, the result is undefined.
 ** These routines may only be called when the most recent call to
 ** [sqlite3_step()] has returned [SQLITE_ROW] and neither
-** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently.
+** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
 ** If any of these routines are called after [sqlite3_reset()] or
 ** [sqlite3_finalize()] or after [sqlite3_step()] has returned
 ** something other than [SQLITE_ROW], the results are undefined.
 ** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
 ** are called from a different thread while any of these routines
-** are pending, then the results are undefined.  
+** are pending, then the results are undefined.
 **
-** The sqlite3_column_type() routine returns 
+** The sqlite3_column_type() routine returns the
 ** [SQLITE_INTEGER | datatype code] for the initial data type
 ** of the result column.  The returned value is one of [SQLITE_INTEGER],
 ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].  The value
@@ -3580,7 +3927,7 @@
 ** versions of SQLite may change the behavior of sqlite3_column_type()
 ** following a type conversion.
 **
-** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() 
+** 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.
 ** 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.
@@ -3593,11 +3940,11 @@
 **
 ** Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
 ** even empty strings, are always zero terminated.  The return
-** value from sqlite3_column_blob() for a zero-length blob is an arbitrary
+** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary
 ** pointer, possibly even a NULL pointer.
 **
 ** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes()
-** but leaves the result in UTF-16 in native byte order instead of UTF-8.  
+** but leaves the result in UTF-16 in native byte order instead of UTF-8.
 ** The zero terminator is not included in this count.
 **
 ** The object returned by [sqlite3_column_value()] is an
@@ -3605,15 +3952,14 @@
 ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
 ** If the [unprotected sqlite3_value] object returned by
 ** [sqlite3_column_value()] is used in any other way, including calls
-** to routines like 
-** [sqlite3_value_int()], [sqlite3_value_text()], or [sqlite3_value_bytes()],
-** then the behavior is undefined.
+** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
+** or [sqlite3_value_bytes()], then the behavior is undefined.
 **
 ** These routines attempt to convert the value where appropriate.  For
 ** example, if the internal representation is FLOAT and a text result
-** is requested, [sqlite3_snprintf()] is used internally to do the conversion
-** automatically.  The following table details the conversions that
-** are applied:
+** is requested, [sqlite3_snprintf()] is used internally to perform the
+** conversion automatically.  The following table details the conversions
+** that are applied:
 **
 ** <blockquote>
 ** <table border="1">
@@ -3625,7 +3971,7 @@
 ** <tr><td>  NULL    <td>   BLOB    <td> Result is NULL pointer
 ** <tr><td> INTEGER  <td>  FLOAT    <td> Convert from integer to float
 ** <tr><td> INTEGER  <td>   TEXT    <td> ASCII rendering of the integer
-** <tr><td> INTEGER  <td>   BLOB    <td> Same as for INTEGER->TEXT
+** <tr><td> INTEGER  <td>   BLOB    <td> Same as INTEGER->TEXT
 ** <tr><td>  FLOAT   <td> INTEGER   <td> Convert from float to integer
 ** <tr><td>  FLOAT   <td>   TEXT    <td> ASCII rendering of the float
 ** <tr><td>  FLOAT   <td>   BLOB    <td> Same as FLOAT->TEXT
@@ -3640,57 +3986,56 @@
 **
 ** The table above makes reference to standard C library functions atoi()
 ** and atof().  SQLite does not really use these functions.  It has its
-** on equavalent internal routines.  The atoi() and atof() names are
+** own equivalent internal routines.  The atoi() and atof() names are
 ** used in the table for brevity and because they are familiar to most
 ** C programmers.
 **
 ** Note that when type conversions occur, pointers returned by prior
 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
-** sqlite3_column_text16() may be invalidated. 
+** sqlite3_column_text16() may be invalidated.
 ** Type conversions and pointer invalidations might occur
 ** in the following cases:
 **
 ** <ul>
-** <li><p>  The initial content is a BLOB and sqlite3_column_text() 
-**          or sqlite3_column_text16() is called.  A zero-terminator might
-**          need to be added to the string.</p></li>
-**
-** <li><p>  The initial content is UTF-8 text and sqlite3_column_bytes16() or
-**          sqlite3_column_text16() is called.  The content must be converted
-**          to UTF-16.</p></li>
-**
-** <li><p>  The initial content is UTF-16 text and sqlite3_column_bytes() or
-**          sqlite3_column_text() is called.  The content must be converted
-**          to UTF-8.</p></li>
+** <li> The initial content is a BLOB and sqlite3_column_text() or
+**      sqlite3_column_text16() is called.  A zero-terminator might
+**      need to be added to the string.</li>
+** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
+**      sqlite3_column_text16() is called.  The content must be converted
+**      to UTF-16.</li>
+** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
+**      sqlite3_column_text() is called.  The content must be converted
+**      to UTF-8.</li>
 ** </ul>
 **
 ** 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 points to will have been modified.  Other kinds
-** of conversion are done in place when it is possible, but sometime it is
-** not possible and in those cases prior pointers are invalidated.  
+** of conversion are done in place when it is possible, but sometimes they
+** are not possible and in those cases prior pointers are invalidated.
 **
 ** The safest and easiest to remember policy is to invoke these routines
 ** in one of the following ways:
 **
-**  <ul>
+** <ul>
 **  <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
 **  <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
 **  <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
-**  </ul>
+** </ul>
 **
-** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(),
-** or sqlite3_column_text16() first to force the result into the desired
-** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to
-** find the size of the result.  Do not mix call to sqlite3_column_text() or
-** sqlite3_column_blob() with calls to sqlite3_column_bytes16().  And do not
-** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes().
+** In other words, you should call sqlite3_column_text(),
+** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
+** into the desired format, then invoke sqlite3_column_bytes() or
+** sqlite3_column_bytes16() to find the size of the result.  Do not mix calls
+** to sqlite3_column_text() or sqlite3_column_blob() with calls to
+** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
+** with calls to sqlite3_column_bytes().
 **
 ** 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.  The memory space used to hold strings
-** and blobs is freed automatically.  Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into 
+** and BLOBs is freed automatically.  Do <b>not</b> pass the pointers returned
+** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
 ** [sqlite3_free()].
 **
 ** If a memory allocation error occurs during the evaluation of any
@@ -3703,11 +4048,11 @@
 **
 ** {F13803} The [sqlite3_column_blob(S,N)] interface converts the
 **          Nth column in the current row of the result set for
-**          [prepared statement] S into a blob and then returns a
+**          the [prepared statement] S into a BLOB and then returns a
 **          pointer to the converted value.
 **
 ** {F13806} The [sqlite3_column_bytes(S,N)] interface returns the
-**          number of bytes in the blob or string (exclusive of the
+**          number of bytes in the BLOB or string (exclusive of the
 **          zero terminator on the string) that was returned by the
 **          most recent call to [sqlite3_column_blob(S,N)] or
 **          [sqlite3_column_text(S,N)].
@@ -3718,41 +4063,41 @@
 **          most recent call to [sqlite3_column_text16(S,N)].
 **
 ** {F13812} The [sqlite3_column_double(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a floating point value and
 **          returns a copy of that value.
 **
 ** {F13815} The [sqlite3_column_int(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a 64-bit signed integer and
 **          returns the lower 32 bits of that integer.
 **
 ** {F13818} The [sqlite3_column_int64(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a 64-bit signed integer and
 **          returns a copy of that integer.
 **
 ** {F13821} The [sqlite3_column_text(S,N)] interface converts the
 **          Nth column in the current row of the result set for
-**          [prepared statement] S into a zero-terminated UTF-8 
+**          the [prepared statement] S into a zero-terminated UTF-8
 **          string and returns a pointer to that string.
 **
 ** {F13824} The [sqlite3_column_text16(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a zero-terminated 2-byte
-**          aligned UTF-16 native byte order
-**          string and returns a pointer to that string.
+**          aligned UTF-16 native byte order string and returns
+**          a pointer to that string.
 **
 ** {F13827} The [sqlite3_column_type(S,N)] interface returns
 **          one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
 **          [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
 **          the Nth column in the current row of the result set for
-**          [prepared statement] S.
+**          the [prepared statement] S.
 **
 ** {F13830} The [sqlite3_column_value(S,N)] interface returns a
 **          pointer to an [unprotected sqlite3_value] object for the
 **          Nth column in the current row of the result set for
-**          [prepared statement] S.
+**          the [prepared statement] S.
 */
 SQLITE_API const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
 SQLITE_API int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
@@ -3768,19 +4113,17 @@
 /*
 ** CAPI3REF: Destroy A Prepared Statement Object {F13300}
 **
-** The sqlite3_finalize() function is called to delete a 
-** [prepared statement]. If the statement was
-** executed successfully, or not executed at all, then SQLITE_OK is returned.
-** If execution of the statement failed then an 
-** [error code] or [extended error code]
-** is returned. 
+** The sqlite3_finalize() function is called to delete a [prepared statement].
+** If the statement was executed successfully or not executed at all, then
+** SQLITE_OK is returned. If execution of the statement failed then an
+** [error code] or [extended error code] is returned.
 **
 ** This routine can be called at any point during the execution of the
-** [prepared statement].  If the virtual machine has not 
+** [prepared statement].  If the virtual machine has not
 ** completed execution when this routine is called, that is like
-** encountering an error or an interrupt.  (See [sqlite3_interrupt()].) 
-** Incomplete updates may be rolled back and transactions cancelled,  
-** depending on the circumstances, and the 
+** encountering an error or an [sqlite3_interrupt | interrupt].
+** Incomplete updates may be rolled back and transactions canceled,
+** depending on the circumstances, and the
 ** [error code] returned will be [SQLITE_ABORT].
 **
 ** INVARIANTS:
@@ -3798,9 +4141,8 @@
 /*
 ** CAPI3REF: Reset A Prepared Statement Object {F13330}
 **
-** The sqlite3_reset() function is called to reset a 
-** [prepared statement] object.
-** back to its initial state, ready to be re-executed.
+** The sqlite3_reset() function is called to reset a [prepared statement]
+** object back to its initial state, ready to be re-executed.
 ** Any SQL statement variables that had values bound to them using
 ** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
 ** Use [sqlite3_clear_bindings()] to reset the bindings.
@@ -3808,48 +4150,49 @@
 ** {F11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
 **          back to the beginning of its program.
 **
-** {F11334} If the most recent call to [sqlite3_step(S)] for 
+** {F11334} 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].
 **
-** {F11336} If the most recent call to [sqlite3_step(S)] for
+** {F11336} 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].
 **
 ** {F11338} The [sqlite3_reset(S)] interface does not change the values
-**          of any [sqlite3_bind_blob|bindings] on [prepared statement] S.
+**          of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
 */
 SQLITE_API int sqlite3_reset(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Create Or Redefine SQL Functions {F16100}
-** KEYWORDS: {function creation routines} 
-**
-** These two 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
-** difference only between the two is that the second parameter, the
-** name of the (scalar) function or aggregate, is encoded in UTF-8 for
-** sqlite3_create_function() and UTF-16 for sqlite3_create_function16().
+** KEYWORDS: {function creation routines}
+** KEYWORDS: {application-defined SQL function}
+** KEYWORDS: {application-defined SQL functions}
+**
+** These two 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 difference between the
+** two is that the second parameter, the name of the (scalar) function or
+** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16
+** for sqlite3_create_function16().
 **
 ** The first parameter is the [database connection] to which the SQL
-** function is to be added.  If a single
-** program uses more than one [database connection] internally, then SQL
-** functions must be added individually to each [database connection].
-**
-** 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, exclusive of the 
-** zero-terminator.  Note that the name length limit is in bytes, not
+** function is to be added.  If a single program uses more than one database
+** connection internally, then SQL functions must be added individually to
+** each database connection.
+**
+** 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, exclusive of
+** the zero-terminator.  Note that the name length limit is in bytes, not
 ** characters.  Any attempt to create a function with a longer name
-** will result in an SQLITE_ERROR error.
+** will result in [SQLITE_ERROR] being returned.
 **
 ** The third parameter is the number of arguments that the SQL function or
 ** aggregate takes. If this parameter is negative, then the SQL function or
 ** aggregate may take any number of arguments.
 **
-** The fourth parameter, eTextRep, specifies what 
+** The fourth parameter, eTextRep, specifies what
 ** [SQLITE_UTF8 | text encoding] this SQL function prefers for
 ** its parameters.  Any SQL function implementation should be able to work
 ** work with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
@@ -3858,26 +4201,23 @@
 ** times with the same function but with different values of eTextRep.
 ** When multiple implementations of the same function are available, SQLite
 ** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what
-** text encoding is used, then the fourth argument should be
-** [SQLITE_ANY].
-**
-** The fifth parameter is an arbitrary pointer.  The implementation
-** of the function can gain access to this pointer using
-** [sqlite3_user_data()].
+** If there is only a single implementation which does not care what text
+** encoding is used, then the fourth argument should be [SQLITE_ANY].
+**
+** The fifth parameter is an arbitrary pointer.  The implementation of the
+** function can gain access to this pointer using [sqlite3_user_data()].
 **
 ** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
-** pointers to C-language functions that implement the SQL
-** function or aggregate. A scalar SQL function requires an implementation of
-** the xFunc callback only, NULL pointers should be passed as the xStep
-** and xFinal parameters. An aggregate SQL function requires an implementation
-** of xStep and xFinal and NULL should be passed for xFunc. To delete an
-** existing SQL function or aggregate, pass NULL for all three function
-** callback.
+** pointers to C-language functions that implement the SQL function or
+** aggregate. A scalar SQL function requires an implementation of the xFunc
+** callback only, NULL pointers should be passed as the xStep and xFinal
+** parameters. An aggregate SQL function requires an implementation of xStep
+** and xFinal and NULL should be passed for xFunc. To delete an existing
+** SQL function or aggregate, pass NULL for all three function callbacks.
 **
 ** It is permitted to register multiple implementations of the same
 ** functions with the same name but with either differing numbers of
-** arguments or differing perferred text encodings.  SQLite will use
+** arguments or differing preferred text encodings.  SQLite will use
 ** the implementation most closely matches the way in which the
 ** SQL function is used.
 **
@@ -3885,15 +4225,14 @@
 **
 ** {F16103} The [sqlite3_create_function16()] interface behaves exactly
 **          like [sqlite3_create_function()] in every way except that it
-**          interprets the zFunctionName argument as
-**          zero-terminated UTF-16 native byte order instead of as a
-**          zero-terminated UTF-8.
+**          interprets the zFunctionName argument as zero-terminated UTF-16
+**          native byte order instead of as zero-terminated UTF-8.
 **
 ** {F16106} A successful invocation of
 **          the [sqlite3_create_function(D,X,N,E,...)] interface registers
-**          or replaces callback functions in [database connection] D
+**          or replaces callback functions in the [database connection] D
 **          used to implement the SQL function named X with N parameters
-**          and having a perferred text encoding of E.
+**          and having a preferred text encoding of E.
 **
 ** {F16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)]
 **          replaces the P, F, S, and L values from any prior calls with
@@ -3937,7 +4276,7 @@
 **          database encoding is preferred.
 **
 ** {F16139} For an aggregate SQL function created using
-**          [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finializer
+**          [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finalizer
 **          function L will always be invoked exactly once if the
 **          step function S is called one or more times.
 **
@@ -4016,42 +4355,40 @@
 ** Any attempt to use these routines on an [unprotected sqlite3_value]
 ** object results in undefined behavior.
 **
-** These routines work just like the corresponding 
-** [sqlite3_column_blob | sqlite3_column_* routines] except that 
-** these routines take a single [protected sqlite3_value] object pointer
-** instead of an [sqlite3_stmt*] pointer and an integer column number.
+** 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.
 **
-** The sqlite3_value_text16() interface extracts a UTF16 string
+** The sqlite3_value_text16() interface extracts a UTF-16 string
 ** in the native byte-order of the host machine.  The
 ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
-** extract UTF16 strings as big-endian and little-endian respectively.
+** extract UTF-16 strings as big-endian and little-endian respectively.
 **
 ** 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 done.  Otherwise no conversion occurs.  The 
-** [SQLITE_INTEGER | datatype] after conversion is returned.
+** words, if the value is a string that looks like a number)
+** then the conversion is performed.  Otherwise no conversion occurs.
+** The [SQLITE_INTEGER | datatype] after conversion is returned.
 **
-** Please pay particular attention to the fact that the pointer that
-** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or
+** Please pay particular attention to the fact that the pointer returned
+** from [sqlite3_value_blob()], [sqlite3_value_text()], or
 ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
 ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
-** or [sqlite3_value_text16()].  
+** or [sqlite3_value_text16()].
 **
 ** These routines must be called from the same thread as
 ** the SQL function that supplied the [sqlite3_value*] parameters.
 **
-**
 ** INVARIANTS:
 **
 ** {F15103} The [sqlite3_value_blob(V)] interface converts the
-**          [protected sqlite3_value] object V into a blob and then returns a
-**          pointer to the converted value.
+**          [protected sqlite3_value] object V into a BLOB and then
+**          returns a pointer to the converted value.
 **
 ** {F15106} The [sqlite3_value_bytes(V)] interface returns the
-**          number of bytes in the blob or string (exclusive of the
+**          number of bytes in the BLOB or string (exclusive of the
 **          zero terminator on the string) that was returned by the
 **          most recent call to [sqlite3_value_blob(V)] or
 **          [sqlite3_value_text(V)].
@@ -4075,7 +4412,7 @@
 **          returns a copy of that integer.
 **
 ** {F15121} The [sqlite3_value_text(V)] interface converts the
-**          [protected sqlite3_value] object V into a zero-terminated UTF-8 
+**          [protected sqlite3_value] object V into a zero-terminated UTF-8
 **          string and returns a pointer to that string.
 **
 ** {F15124} The [sqlite3_value_text16(V)] interface converts the
@@ -4103,8 +4440,8 @@
 **          a floating point value if it can do so without loss of
 **          information, and returns one of [SQLITE_NULL],
 **          [SQLITE_INTEGER], [SQLITE_FLOAT], [SQLITE_TEXT], or
-**          [SQLITE_BLOB] as appropriate for
-**          the [protected sqlite3_value] object V after the conversion attempt.
+**          [SQLITE_BLOB] as appropriate for the
+**          [protected sqlite3_value] object V after the conversion attempt.
 */
 SQLITE_API const void *sqlite3_value_blob(sqlite3_value*);
 SQLITE_API int sqlite3_value_bytes(sqlite3_value*);
@@ -4123,22 +4460,21 @@
 ** CAPI3REF: Obtain Aggregate Function Context {F16210}
 **
 ** The implementation of aggregate SQL functions use this routine to allocate
-** a structure for storing their state.  
-** The first time the sqlite3_aggregate_context() routine is
-** is called for a particular aggregate, SQLite allocates nBytes of memory
-** zeros that memory, and returns a pointer to it.
-** On second and subsequent calls to sqlite3_aggregate_context()
-** for the same aggregate function index, the same buffer is returned.
-** The implementation
-** of the aggregate can use the returned buffer to accumulate data.
+** a structure for storing their state.
+**
+** The first time the sqlite3_aggregate_context() routine is called for a
+** particular aggregate, SQLite allocates nBytes of memory, zeroes out that
+** memory, and returns a pointer to it. On second and subsequent calls to
+** sqlite3_aggregate_context() for the same aggregate function index,
+** the same buffer is returned. The implementation of the aggregate can use
+** the returned buffer to accumulate data.
 **
 ** SQLite automatically frees the allocated buffer when the aggregate
 ** query concludes.
 **
-** The first parameter should be a copy of the 
-** [sqlite3_context | SQL function context] that is the first
-** parameter to the callback routine that implements the aggregate
-** function.
+** The first parameter should be a copy of the
+** [sqlite3_context | SQL function context] that is the first parameter
+** to the callback routine that implements the aggregate function.
 **
 ** This routine must be called from the same thread in which
 ** the aggregate SQL function is running.
@@ -4147,9 +4483,8 @@
 **
 ** {F16211} The first invocation of [sqlite3_aggregate_context(C,N)] for
 **          a particular instance of an aggregate function (for a particular
-**          context C) causes SQLite to allocation N bytes of memory,
-**          zero that memory, and return a pointer to the allocationed
-**          memory.
+**          context C) causes SQLite to allocate N bytes of memory,
+**          zero that memory, and return a pointer to the allocated memory.
 **
 ** {F16213} If a memory allocation error occurs during
 **          [sqlite3_aggregate_context(C,N)] then the function returns 0.
@@ -4171,7 +4506,7 @@
 **
 ** The sqlite3_user_data() interface returns a copy of
 ** the pointer that was the pUserData parameter (the 5th parameter)
-** of the the [sqlite3_create_function()]
+** of the [sqlite3_create_function()]
 ** and [sqlite3_create_function16()] routines that originally
 ** registered the application defined function. {END}
 **
@@ -4183,8 +4518,7 @@
 ** {F16243} The [sqlite3_user_data(C)] interface returns a copy of the
 **          P pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
 **          or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
-**          registered the SQL function associated with 
-**          [sqlite3_context] C.
+**          registered the SQL function associated with [sqlite3_context] C.
 */
 SQLITE_API void *sqlite3_user_data(sqlite3_context*);
 
@@ -4193,7 +4527,7 @@
 **
 ** The sqlite3_context_db_handle() interface returns a copy of
 ** the pointer to the [database connection] (the 1st parameter)
-** of the the [sqlite3_create_function()]
+** of the [sqlite3_create_function()]
 ** and [sqlite3_create_function16()] routines that originally
 ** registered the application defined function.
 **
@@ -4202,8 +4536,7 @@
 ** {F16253} The [sqlite3_context_db_handle(C)] interface returns a copy of the
 **          D pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
 **          or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
-**          registered the SQL function associated with 
-**          [sqlite3_context] C.
+**          registered the SQL function associated with [sqlite3_context] C.
 */
 SQLITE_API sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
 
@@ -4211,40 +4544,38 @@
 ** CAPI3REF: Function Auxiliary Data {F16270}
 **
 ** The following two functions may be used by scalar SQL functions to
-** associate meta-data with argument values. If the same value is passed 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 meta-data may be preserved. This may
+** some circumstances the associated metadata may be preserved. This may
 ** be used, for example, to add a regular-expression matching scalar
 ** function. The compiled version of the regular expression is stored as
-** meta-data associated with the SQL value passed as the regular expression
+** metadata associated with the SQL value passed as the regular expression
 ** pattern.  The compiled regular expression can be reused on multiple
 ** invocations of the same function so that the original pattern string
 ** does not need to be recompiled on each invocation.
 **
-** The sqlite3_get_auxdata() interface returns a pointer to the meta-data
+** The sqlite3_get_auxdata() interface returns a pointer to the metadata
 ** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function.
-** If no meta-data has been ever been set for the Nth
-** argument of the function, or if the cooresponding function parameter
-** has changed since the meta-data was set, then sqlite3_get_auxdata()
-** returns a NULL pointer.
+** value to the application-defined function. If no metadata has been ever
+** been set for the Nth argument of the function, or if the corresponding
+** function parameter has changed since the meta-data was set,
+** then sqlite3_get_auxdata() returns a NULL pointer.
 **
-** The sqlite3_set_auxdata() interface saves the meta-data
-** pointed to by its 3rd parameter as the meta-data for the N-th
+** The sqlite3_set_auxdata() interface saves the metadata
+** pointed to by its 3rd parameter as the metadata for the N-th
 ** argument of the application-defined function.  Subsequent
 ** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed. 
-** If it is not NULL, SQLite will invoke the destructor 
+** not been destroyed.
+** If it is not NULL, SQLite will invoke the destructor
 ** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the meta-data when the corresponding function parameter changes
+** the metadata when the corresponding function parameter changes
 ** or when the SQL statement completes, whichever comes first.
 **
-** SQLite is free to call the destructor and drop meta-data on
-** any parameter of any function at any time.  The only guarantee
-** is that the destructor will be called before the metadata is
-** dropped.
+** SQLite is free to call the destructor and drop metadata on any
+** parameter of any function at any time.  The only guarantee is that
+** the destructor will be called before the metadata is dropped.
 **
-** In practice, meta-data is preserved between function calls for
+** In practice, metadata is preserved between function calls for
 ** expressions that are constant at compile time. This includes literal
 ** values and SQL variables.
 **
@@ -4259,8 +4590,7 @@
 **          with that parameter.
 **
 ** {F16274} The [sqlite3_set_auxdata(C,N,P,D)] interface assigns a metadata
-**          pointer P to the Nth parameter of the SQL function with context
-**          C.
+**          pointer P to the Nth parameter of the SQL function with context C.
 **
 ** {F16276} SQLite will invoke the destructor D with a single argument
 **          which is the metadata pointer P following a call to
@@ -4285,10 +4615,10 @@
 /*
 ** CAPI3REF: Constants Defining Special Destructor Behavior {F10280}
 **
-** These are special value for the destructor that is passed in as the
+** These are special values for the destructor that is passed in as the
 ** final argument to routines like [sqlite3_result_blob()].  If the destructor
 ** argument is SQLITE_STATIC, it means that the content pointer is constant
-** and will never change.  It does not need to be destroyed.  The 
+** and will never change.  It does not need to be destroyed.  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.
@@ -4308,23 +4638,21 @@
 ** [sqlite3_create_function()] and [sqlite3_create_function16()]
 ** for additional information.
 **
-** These functions work very much like the 
-** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used
-** to bind values to host parameters in prepared statements.
-** Refer to the
-** [sqlite3_bind_blob | sqlite3_bind_* documentation] for
-** additional information.
+** These functions work very much like the [parameter binding] family of
+** functions used to bind values to host parameters in prepared statements.
+** Refer to the [SQL parameter] documentation for additional information.
 **
 ** The sqlite3_result_blob() interface sets the result from
-** an application defined function to be the BLOB whose content is pointed
+** 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. 
-** The sqlite3_result_zeroblob() inerfaces set the result of
-** the application defined function to be a BLOB containing all zero
+** third parameter.
+**
+** The sqlite3_result_zeroblob() interfaces set the result of
+** the application-defined function to be a BLOB containing all zero
 ** bytes and N bytes in size, where N is the value of the 2nd parameter.
 **
 ** The sqlite3_result_double() interface sets the result from
-** an application defined function to be a floating point value specified
+** an application-defined function to be a floating point value specified
 ** by its 2nd argument.
 **
 ** The sqlite3_result_error() and sqlite3_result_error16() functions
@@ -4332,8 +4660,8 @@
 ** 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.  SQLite interprets the error
-** message string from sqlite3_result_error() as UTF8. SQLite
-** interprets the string from sqlite3_result_error16() as UTF16 in native
+** message string from sqlite3_result_error() as UTF-8. SQLite
+** interprets the string from sqlite3_result_error16() as UTF-16 in native
 ** byte order.  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.
@@ -4341,7 +4669,7 @@
 ** sqlite3_result_error16() is non-negative then SQLite takes that many
 ** bytes (not characters) from the 2nd parameter as the error message.
 ** The sqlite3_result_error() and sqlite3_result_error16()
-** routines make a copy private copy of the error message text before
+** routines make a private copy of the error message text before
 ** they return.  Hence, the calling function can deallocate or
 ** modify the text after they return without harm.
 ** The sqlite3_result_error_code() function changes the error code
@@ -4349,11 +4677,11 @@
 ** the error code is SQLITE_ERROR.  A subsequent call to sqlite3_result_error()
 ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
 **
-** The sqlite3_result_toobig() interface causes SQLite
-** to throw an error indicating that a string or BLOB is to long
-** to represent.  The sqlite3_result_nomem() interface
-** causes SQLite to throw an exception indicating that the a
-** memory allocation failed.
+** The sqlite3_result_toobig() interface causes SQLite to throw an error
+** indicating that a string or BLOB is to long to represent.
+**
+** The sqlite3_result_nomem() interface causes SQLite to throw an error
+** indicating that a memory allocation failed.
 **
 ** The sqlite3_result_int() interface sets the return value
 ** of the application-defined function to be the 32-bit signed integer
@@ -4365,7 +4693,7 @@
 ** The sqlite3_result_null() interface sets the return value
 ** of the application-defined function to be NULL.
 **
-** The sqlite3_result_text(), sqlite3_result_text16(), 
+** 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,
@@ -4373,7 +4701,7 @@
 ** SQLite takes the text result from the application from
 ** the 2nd parameter of the sqlite3_result_text* interfaces.
 ** If the 3rd parameter to the sqlite3_result_text* interfaces
-** is negative, then SQLite takes result text from the 2nd parameter 
+** 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
@@ -4381,13 +4709,12 @@
 ** function result.
 ** 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.
-** If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is the special constant SQLITE_STATIC, then
-** SQLite assumes that the text or blob result is constant space and
-** does not copy the space or call a destructor when it has
+** function as the destructor on the text or BLOB result when it has
 ** finished using that result.
+** If the 4th parameter to the sqlite3_result_text* interfaces or
+** 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 it or call a destructor when it has finished using that result.
 ** 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
@@ -4397,14 +4724,14 @@
 ** the application-defined function to be a copy the
 ** [unprotected sqlite3_value] object specified by the 2nd parameter.  The
 ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
-** so that [sqlite3_value] specified in the parameter may change or
+** so that the [sqlite3_value] specified in the parameter may change or
 ** be deallocated after sqlite3_result_value() returns without harm.
 ** 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.
 **
-** If these routines are called from within the different thread 
-** than the one containing the application-defined function that recieved
+** If these routines are called from within the different thread
+** than the one containing the application-defined function that received
 ** the [sqlite3_context] pointer, the results are undefined.
 **
 ** INVARIANTS:
@@ -4412,7 +4739,7 @@
 ** {F16403} The default return value from any SQL function is NULL.
 **
 ** {F16406} The [sqlite3_result_blob(C,V,N,D)] interface changes the
-**          return value of function C to be a blob that is N bytes
+**          return value of function C to be a BLOB that is N bytes
 **          in length and with content pointed to by V.
 **
 ** {F16409} The [sqlite3_result_double(C,V)] interface changes the
@@ -4420,12 +4747,12 @@
 **
 ** {F16412} The [sqlite3_result_error(C,V,N)] interface changes the return
 **          value of function C to be an exception with error code
-**          [SQLITE_ERROR] and a UTF8 error message copied from V up to the
+**          [SQLITE_ERROR] and a UTF-8 error message copied from V up to the
 **          first zero byte or until N bytes are read if N is positive.
 **
 ** {F16415} The [sqlite3_result_error16(C,V,N)] interface changes the return
 **          value of function C to be an exception with error code
-**          [SQLITE_ERROR] and a UTF16 native byte order error message
+**          [SQLITE_ERROR] and a UTF-16 native byte order error message
 **          copied from V up to the first zero terminator or until N bytes
 **          are read if N is positive.
 **
@@ -4451,31 +4778,31 @@
 **          return value of function C to be NULL.
 **
 ** {F16436} The [sqlite3_result_text(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF8 string
+**          return value of function C to be the UTF-8 string
 **          V up to the first zero if N is negative
 **          or the first N bytes of V if N is non-negative.
 **
 ** {F16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF16 native byte order
-**          string V up to the first zero if N is
-**          negative or the first N bytes of V if N is non-negative.
+**          return value of function C to be the UTF-16 native byte order
+**          string V up to the first zero if N is negative
+**          or the first N bytes of V if N is non-negative.
 **
 ** {F16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF16 big-endian
-**          string V up to the first zero if N is
-**          is negative or the first N bytes or V if N is non-negative.
+**          return value of function C to be the UTF-16 big-endian
+**          string V up to the first zero if N is negative
+**          or the first N bytes or V if N is non-negative.
 **
 ** {F16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF16 little-endian
-**          string V up to the first zero if N is
-**          negative or the first N bytes of V if N is non-negative.
+**          return value of function C to be the UTF-16 little-endian
+**          string V up to the first zero if N is negative
+**          or the first N bytes of V if N is non-negative.
 **
 ** {F16448} The [sqlite3_result_value(C,V)] interface changes the
-**          return value of function C to be [unprotected sqlite3_value]
+**          return value of function C to be the [unprotected sqlite3_value]
 **          object V.
 **
 ** {F16451} The [sqlite3_result_zeroblob(C,N)] interface changes the
-**          return value of function C to be an N-byte blob of all zeros.
+**          return value of function C to be an N-byte BLOB of all zeros.
 **
 ** {F16454} The [sqlite3_result_error()] and [sqlite3_result_error16()]
 **          interfaces make a copy of their error message strings before
@@ -4499,7 +4826,7 @@
 **          [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
 **          [sqlite3_result_text16be(C,V,N,D)], or
 **          [sqlite3_result_text16le(C,V,N,D)] is some value other than
-**          the constants [SQLITE_STATIC] and [SQLITE_TRANSIENT] then 
+**          the constants [SQLITE_STATIC] and [SQLITE_TRANSIENT] then
 **          SQLite will invoke the destructor D with V as its only argument
 **          when it has finished with the V value.
 */
@@ -4524,7 +4851,7 @@
 ** CAPI3REF: Define New Collating Sequences {F16600}
 **
 ** These functions are used to add new collation sequences to the
-** [sqlite3*] handle specified as the first argument. 
+** [database connection] specified as the first argument.
 **
 ** The name of the new collation sequence is specified as a UTF-8 string
 ** for sqlite3_create_collation() and sqlite3_create_collation_v2()
@@ -4534,42 +4861,40 @@
 ** The third argument may be one of the constants [SQLITE_UTF8],
 ** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied
 ** routine expects to be passed pointers to strings encoded using UTF-8,
-** UTF-16 little-endian or UTF-16 big-endian respectively. The
+** UTF-16 little-endian, or UTF-16 big-endian, respectively. The
 ** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that
 ** the routine expects pointers to 16-bit word aligned strings
-** of UTF16 in the native byte order of the host computer.
+** of UTF-16 in the native byte order of the host computer.
 **
 ** A pointer to the user supplied routine must be passed as the fifth
 ** argument.  If it is NULL, this is the same as deleting the collation
 ** sequence (so that SQLite cannot call it anymore).
-** Each time the application
-** supplied function is invoked, it is passed a copy of the void* passed as
-** the fourth argument to sqlite3_create_collation() or
-** sqlite3_create_collation16() as its first parameter.
+** Each time the application supplied function is invoked, it is passed
+** as its first parameter a copy of the void* passed as the fourth argument
+** to sqlite3_create_collation() or sqlite3_create_collation16().
 **
 ** The remaining arguments to the application-supplied routine are two strings,
 ** each represented by a (length, data) pair and encoded in the encoding
 ** that was passed as the third argument when the collation sequence was
-** registered. {END} The application defined collation routine should
-** return negative, zero or positive if
-** the first string is less than, equal to, or greater than the second
-** string. i.e. (STRING1 - STRING2).
+** registered. {END}  The application defined collation routine should
+** return negative, zero or positive if the first string is less than,
+** equal to, or greater than the second string. i.e. (STRING1 - STRING2).
 **
 ** The sqlite3_create_collation_v2() works like sqlite3_create_collation()
-** excapt that it takes an extra argument which is a destructor for
+** except that it takes an extra argument which is a destructor for
 ** the collation.  The destructor is called when the collation is
 ** destroyed and is passed a copy of the fourth parameter void* pointer
 ** of the sqlite3_create_collation_v2().
-** Collations are destroyed when
-** they are overridden by later calls to the collation creation functions
-** or when the [sqlite3*] database handle is closed using [sqlite3_close()].
+** Collations are destroyed when they are overridden by later calls to the
+** collation creation functions or when the [database connection] is closed
+** using [sqlite3_close()].
 **
 ** INVARIANTS:
 **
 ** {F16603} A successful call to the
 **          [sqlite3_create_collation_v2(B,X,E,P,F,D)] interface
 **          registers function F as the comparison function used to
-**          implement collation X on [database connection] B for
+**          implement collation X on the [database connection] B for
 **          databases having encoding E.
 **
 ** {F16604} SQLite understands the X parameter to
@@ -4581,7 +4906,7 @@
 **          with the same values for B, X, and E, override prior values
 **          of P, F, and D.
 **
-** {F16609} The destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {F16609} If the destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
 **          is not NULL then it is called with argument P when the
 **          collating function is dropped by SQLite.
 **
@@ -4600,8 +4925,8 @@
 **
 ** {F16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)],
 **          SQLite uses the comparison function F for all text comparison
-**          operations on [database connection] B on text values that
-**          use the collating sequence name X.
+**          operations on the [database connection] B on text values that
+**          use the collating sequence named X.
 **
 ** {F16627} The [sqlite3_create_collation16(B,X,E,P,F)] works the same
 **          as [sqlite3_create_collation(B,X,E,P,F)] except that the
@@ -4630,7 +4955,7 @@
 );
 SQLITE_API int sqlite3_create_collation16(
   sqlite3*, 
-  const char *zName, 
+  const void *zName,
   int eTextRep, 
   void*,
   int(*xCompare)(void*,int,const void*,int,const void*)
@@ -4641,22 +4966,21 @@
 **
 ** To avoid having to register all collation sequences before a database
 ** can be used, a single callback function may be registered with the
-** database handle to be called whenever an undefined collation sequence is
-** required.
+** [database connection] to be called whenever an undefined collation
+** sequence is required.
 **
 ** 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. {F16703} If sqlite3_collation_needed16() is used, the names
-** are passed as UTF-16 in machine native byte order. A call to either
-** function replaces any existing callback.
+** encoded in UTF-8. {F16703} If sqlite3_collation_needed16() is used,
+** the names are passed as UTF-16 in machine native byte order.
+** A call to either function replaces any existing callback.
 **
 ** 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
-** handle.  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
+** 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.
 **
 ** The callback function should register the desired collation using
@@ -4681,8 +5005,6 @@
 **          was registered using [sqlite3_collation_needed()] and
 **          is in UTF-16 native byte order if the callback was
 **          registered using [sqlite3_collation_needed16()].
-**
-** 
 */
 SQLITE_API int sqlite3_collation_needed(
   sqlite3*, 
@@ -4721,15 +5043,14 @@
 );
 
 /*
-** CAPI3REF:  Suspend Execution For A Short Time {F10530}
+** CAPI3REF: Suspend Execution For A Short Time {F10530}
 **
-** The sqlite3_sleep() function
-** causes the current thread to suspend execution
+** The sqlite3_sleep() function causes the current thread to suspend execution
 ** for at least a number of milliseconds specified in its parameter.
 **
-** If the operating system does not support sleep requests with 
-** millisecond time resolution, then the time will be rounded up to 
-** the nearest second. The number of milliseconds of sleep actually 
+** If the operating system does not support sleep requests with
+** millisecond time resolution, then the time will be rounded up to
+** the nearest second. The number of milliseconds of sleep actually
 ** requested from the operating system is returned.
 **
 ** SQLite implements this interface by calling the xSleep()
@@ -4749,15 +5070,15 @@
 SQLITE_API int sqlite3_sleep(int);
 
 /*
-** CAPI3REF:  Name Of The Folder Holding Temporary Files {F10310}
+** CAPI3REF: Name Of The Folder Holding Temporary Files {F10310}
 **
 ** If this global variable is made to point to a string which is
-** the name of a folder (a.ka. directory), then all temporary files
+** the name of a folder (a.k.a. directory), then all temporary files
 ** created by SQLite will be placed in that directory.  If this variable
-** is NULL pointer, then SQLite does a search for an appropriate temporary
-** file directory.
+** is a NULL pointer, then SQLite performs a search for an appropriate
+** temporary file directory.
 **
-** It is not safe to modify this variable once a database connection
+** It is not safe to modify this variable once a [database connection]
 ** has been opened.  It is intended that this variable be set once
 ** as part of process initialization and before any SQLite interface
 ** routines have been call and remain unchanged thereafter.
@@ -4765,19 +5086,20 @@
 SQLITE_API char *sqlite3_temp_directory;
 
 /*
-** CAPI3REF:  Test To See If The Database Is In Auto-Commit Mode {F12930}
+** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode {F12930}
+** KEYWORDS: {autocommit mode}
 **
-** The sqlite3_get_autocommit() interfaces returns non-zero or
+** The sqlite3_get_autocommit() interface returns non-zero or
 ** zero if the given database connection is or is not in autocommit mode,
-** respectively.   Autocommit mode is on
-** by default.  Autocommit mode is disabled by a [BEGIN] statement.
-** Autocommit mode is reenabled by a [COMMIT] or [ROLLBACK].
+** respectively.  Autocommit mode is on by default.
+** Autocommit mode is disabled by a [BEGIN] statement.
+** Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
 **
 ** If certain kinds of errors occur on a statement within a multi-statement
-** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], 
+** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
 ** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
 ** transaction might be rolled back automatically.  The only way to
-** find out if SQLite automatically rolled back the transaction after
+** find out whether SQLite automatically rolled back the transaction after
 ** an error is to use this function.
 **
 ** INVARIANTS:
@@ -4792,35 +5114,62 @@
 **
 ** {F12934} Autocommit mode is enabled by a successful [COMMIT] or [ROLLBACK]
 **          statement.
-** 
 **
 ** LIMITATIONS:
-***
-** {U12936} If another thread changes the autocommit status of the database
+**
+** {A12936} If another thread changes the autocommit status of the database
 **          connection while this routine is running, then the return value
 **          is undefined.
 */
 SQLITE_API int sqlite3_get_autocommit(sqlite3*);
 
 /*
-** CAPI3REF:  Find The Database Handle Of A Prepared Statement {F13120}
+** CAPI3REF: Find The Database Handle Of A Prepared Statement {F13120}
 **
-** The sqlite3_db_handle interface
-** returns the [sqlite3*] database handle to which a
-** [prepared statement] belongs.
-** The database handle returned by sqlite3_db_handle
-** is the same database handle that was
-** the first argument to the [sqlite3_prepare_v2()] or its variants
-** that was used to create the statement in the first place.
+** The sqlite3_db_handle interface returns the [database connection] handle
+** to which a [prepared statement] belongs.  The database handle returned by
+** sqlite3_db_handle is the same database handle 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.
 **
 ** INVARIANTS:
 **
 ** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer
-**          to the [database connection] associated with
+**          to the [database connection] associated with the
 **          [prepared statement] S.
 */
 SQLITE_API sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 
+/*
+** CAPI3REF: Find the next prepared statement {F13140}
+**
+** This interface returns a pointer to the next [prepared statement] after
+** pStmt associated with the [database connection] pDb.  If pStmt is NULL
+** then this interface returns a pointer to the first prepared statement
+** associated with the database connection pDb.  If no prepared statement
+** satisfies the conditions of this routine, it returns NULL.
+**
+** INVARIANTS:
+**
+** {F13143} If D is a [database connection] that holds one or more
+**          unfinalized [prepared statements] and S is a NULL pointer,
+**          then [sqlite3_next_stmt(D, S)] routine shall return a pointer
+**          to one of the prepared statements associated with D.
+**
+** {F13146} If D is a [database connection] that holds no unfinalized
+**          [prepared statements] and S is a NULL pointer, then
+**          [sqlite3_next_stmt(D, S)] routine shall return a NULL pointer.
+**
+** {F13149} If S is a [prepared statement] in the [database connection] D
+**          and S is not the last prepared statement in D, then
+**          [sqlite3_next_stmt(D, S)] routine shall return a pointer
+**          to the next prepared statement in D after S.
+**
+** {F13152} If S is the last [prepared statement] in the
+**          [database connection] D then the [sqlite3_next_stmt(D, S)]
+**          routine shall return a NULL pointer.
+*/
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Commit And Rollback Notification Callbacks {F12950}
@@ -4833,16 +5182,16 @@
 ** function to be invoked whenever a transaction is committed.
 ** Any callback set by a previous call to sqlite3_commit_hook()
 ** for the same database connection is overridden.
-** The pArg argument is passed through
-** to the callback.  If the callback on a commit hook function 
-** returns non-zero, then the commit is converted into a rollback.
+** The pArg argument is passed through to the callback.
+** If the callback on a commit hook function returns non-zero,
+** then the commit is converted into a rollback.
 **
 ** If another function was previously registered, its
 ** pArg value is returned.  Otherwise NULL is returned.
 **
 ** Registering a NULL function disables the callback.
 **
-** For the purposes of this API, a transaction is said to have been 
+** 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.
 ** The rollback callback is not invoked if a transaction is
@@ -4851,24 +5200,21 @@
 ** rolled back because a commit callback returned non-zero.
 ** <todo> Check on this </todo>
 **
-** These are experimental interfaces and are subject to change.
-**
 ** INVARIANTS:
 **
 ** {F12951} The [sqlite3_commit_hook(D,F,P)] interface registers the
 **          callback function F to be invoked with argument P whenever
-**          a transaction commits on [database connection] D.
+**          a transaction commits on the [database connection] D.
 **
-** {F12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P
-**          argument from the previous call with the same 
-**          [database connection ] D , or NULL on the first call
-**          for a particular [database connection] D.
+** {F12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P argument
+**          from the previous call with the same [database connection] D,
+**          or NULL on the first call for a particular database connection D.
 **
 ** {F12953} Each call to [sqlite3_commit_hook()] overwrites the callback
 **          registered by prior calls.
 **
 ** {F12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL
-**          then the commit hook callback is cancelled and no callback
+**          then the commit hook callback is canceled and no callback
 **          is invoked when a transaction commits.
 **
 ** {F12955} If the commit callback returns non-zero then the commit is
@@ -4876,18 +5222,18 @@
 **
 ** {F12961} The [sqlite3_rollback_hook(D,F,P)] interface registers the
 **          callback function F to be invoked with argument P whenever
-**          a transaction rolls back on [database connection] D.
+**          a transaction rolls back on the [database connection] D.
 **
 ** {F12962} The [sqlite3_rollback_hook(D,F,P)] interface returns the P
-**          argument from the previous call with the same 
-**          [database connection ] D , or NULL on the first call
-**          for a particular [database connection] D.
+**          argument from the previous call with the same
+**          [database connection] D, or NULL on the first call
+**          for a particular database connection D.
 **
 ** {F12963} Each call to [sqlite3_rollback_hook()] overwrites the callback
 **          registered by prior calls.
 **
 ** {F12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL
-**          then the rollback hook callback is cancelled and no callback
+**          then the rollback hook callback is canceled and no callback
 **          is invoked when a transaction rolls back.
 */
 SQLITE_API void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
@@ -4896,26 +5242,23 @@
 /*
 ** CAPI3REF: Data Change Notification Callbacks {F12970}
 **
-** 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.
-** Any callback set by a previous call to this function for the same 
-** database connection is overridden.
-**
-** The second argument is a pointer to the function to invoke when a 
-** row is updated, inserted or deleted. 
-** The first argument to the callback is
-** a copy of the third argument to sqlite3_update_hook().
-** 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.
-** The third and 
-** fourth arguments to the callback contain pointers to the database and 
-** table name containing the affected row.
-** The final callback parameter is 
-** the rowid of the row.
-** In the case of an update, this is the rowid after 
-** the update takes place.
+** 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.
+** Any callback set by a previous call to this function
+** for the same database connection is overridden.
+**
+** The second argument is a pointer to the function to invoke when a
+** row is updated, inserted or deleted.
+** The first argument to the callback is a copy of the third argument
+** to sqlite3_update_hook().
+** 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.
+** The third and fourth arguments to the callback contain pointers to the
+** database and table name containing the affected row.
+** The final callback parameter is the rowid of the row. In the case of
+** an update, this is the rowid after the update takes place.
 **
 ** The update hook is not invoked when internal system tables are
 ** modified (i.e. sqlite_master and sqlite_sequence).
@@ -4925,10 +5268,10 @@
 **
 ** INVARIANTS:
 **
-** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes callback
+** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes the callback
 **          function F to be invoked with first parameter P whenever
 **          a table row is modified, inserted, or deleted on
-**          [database connection] D.
+**          the [database connection] D.
 **
 ** {F12973} The [sqlite3_update_hook(D,F,P)] interface returns the value
 **          of P for the previous call on the same [database connection] D,
@@ -4943,7 +5286,7 @@
 ** {F12979} The update hook callback is not invoked when internal system
 **          tables such as sqlite_master and sqlite_sequence are modified.
 **
-** {F12981} The second parameter to the update callback 
+** {F12981} The second parameter to the update callback
 **          is one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE],
 **          depending on the operation that caused the callback to be invoked.
 **
@@ -4961,37 +5304,36 @@
 );
 
 /*
-** CAPI3REF:  Enable Or Disable Shared Pager Cache {F10330}
+** CAPI3REF: Enable Or Disable Shared Pager Cache {F10330}
+** KEYWORDS: {shared cache} {shared cache mode}
 **
 ** 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.
-**
-** Cache sharing is enabled and disabled
-** for an entire process. {END} This is a change as of SQLite version 3.5.0.
-** In prior versions of SQLite, sharing was
-** enabled or disabled for each thread separately.
+** and schema data structures between [database connection | connections]
+** to the same database. Sharing is enabled if the argument is true
+** and disabled if the argument is false.
+**
+** Cache sharing is enabled and disabled for an entire process. {END}
+** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
+** sharing was enabled or disabled for each thread separately.
 **
 ** 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 use the sharing mode
 ** that was in effect at the time they were opened.
 **
-** Virtual tables cannot be used with a shared cache.   When shared
+** Virtual tables cannot be used with a shared cache.  When shared
 ** cache is enabled, the [sqlite3_create_module()] API used to register
 ** virtual tables will always return an error.
 **
-** This routine returns [SQLITE_OK] if shared cache was
-** enabled or disabled successfully.  An [error code]
-** is returned otherwise.
+** This routine returns [SQLITE_OK] if shared cache was enabled or disabled
+** successfully.  An [error code] is returned otherwise.
 **
 ** Shared cache is disabled by default. But this might change in
 ** future releases of SQLite.  Applications that care about shared
 ** cache setting should set it explicitly.
 **
 ** INVARIANTS:
-** 
+**
 ** {F10331} A successful invocation of [sqlite3_enable_shared_cache(B)]
 **          will enable or disable shared cache mode for any subsequently
 **          created [database connection] in the same process.
@@ -5007,21 +5349,20 @@
 SQLITE_API int sqlite3_enable_shared_cache(int);
 
 /*
-** CAPI3REF:  Attempt To Free Heap Memory {F17340}
+** CAPI3REF: Attempt To Free Heap Memory {F17340}
 **
-** The sqlite3_release_memory() interface attempts to
-** free N bytes of heap memory by deallocating non-essential memory
-** allocations held by the database labrary. {END}  Memory used
-** to cache database pages to improve performance is an example of
-** non-essential memory.  Sqlite3_release_memory() returns
-** the number of bytes actually freed, which might be more or less
-** than the amount requested.
+** The sqlite3_release_memory() interface attempts to free N bytes
+** of heap memory by deallocating non-essential memory allocations
+** held by the database library. {END}  Memory used to cache database
+** pages to improve performance is an example of non-essential memory.
+** sqlite3_release_memory() returns the number of bytes actually freed,
+** which might be more or less than the amount requested.
 **
 ** INVARIANTS:
 **
 ** {F17341} The [sqlite3_release_memory(N)] interface attempts to
 **          free N bytes of heap memory by deallocating non-essential
-**          memory allocations held by the database labrary.
+**          memory allocations held by the database library.
 **
 ** {F16342} The [sqlite3_release_memory(N)] returns the number
 **          of bytes actually freed, which might be more or less
@@ -5030,27 +5371,25 @@
 SQLITE_API int sqlite3_release_memory(int);
 
 /*
-** CAPI3REF:  Impose A Limit On Heap Size {F17350}
+** CAPI3REF: Impose A Limit On Heap Size {F17350}
 **
-** The sqlite3_soft_heap_limit() interface
-** places a "soft" limit on the amount of heap memory that may be allocated
-** by SQLite. If an internal allocation is requested 
-** that would exceed the soft heap limit, [sqlite3_release_memory()] is
-** invoked one or more times to free up some space before the allocation
-** is made.
-**
-** The limit is called "soft", because if
-** [sqlite3_release_memory()] cannot
-** free sufficient memory to prevent the limit from being exceeded,
+** The sqlite3_soft_heap_limit() interface places a "soft" limit
+** on the amount of heap memory that may be allocated by SQLite.
+** If an internal allocation is requested that would exceed the
+** soft heap limit, [sqlite3_release_memory()] is invoked one or
+** more times to free up some space before the allocation is performed.
+**
+** The limit is called "soft", because if [sqlite3_release_memory()]
+** cannot free sufficient memory to prevent the limit from being exceeded,
 ** the memory is allocated anyway and the current operation proceeds.
 **
 ** A negative or zero value for N means that there is no soft heap limit and
 ** [sqlite3_release_memory()] will only be called when memory is exhausted.
 ** The default value for the soft heap limit is zero.
 **
-** SQLite makes a best effort to honor the soft heap limit.  
-** But if the soft heap limit cannot honored, execution will
-** continue without error or notification.  This is why the limit is 
+** SQLite makes a best effort to honor the soft heap limit.
+** But if the soft heap limit cannot be honored, execution will
+** continue without error or notification.  This is why the limit is
 ** called a "soft" limit.  It is advisory only.
 **
 ** Prior to SQLite version 3.5.0, this routine only constrained the memory
@@ -5092,52 +5431,50 @@
 SQLITE_API void sqlite3_soft_heap_limit(int);
 
 /*
-** CAPI3REF:  Extract Metadata About A Column Of A Table {F12850}
+** CAPI3REF: Extract Metadata About A Column Of A Table {F12850}
 **
-** This routine
-** returns meta-data about a specific column of a specific database
-** table accessible using the connection handle passed as the first function 
-** argument.
+** This routine returns metadata about a specific column of a specific
+** database table accessible using the [database connection] handle
+** passed as the first function argument.
 **
-** The column is identified by the second, third and fourth parameters to 
+** The column is identified by the second, third and fourth parameters to
 ** this function. The second parameter is either the name of the database
 ** (i.e. "main", "temp" or an attached database) containing the specified
 ** table or NULL. If it is NULL, then all attached databases are searched
-** for the table using the same algorithm as the database engine uses to 
+** for the table using the same algorithm used by the database engine to
 ** resolve unqualified table references.
 **
-** The third and fourth parameters to this function are the table and column 
-** name of the desired column, respectively. Neither of these parameters 
+** The third and fourth parameters to this function are the table and column
+** name of the desired column, respectively. Neither of these parameters
 ** may be NULL.
 **
-** Meta information is returned by writing to the memory locations passed as
-** the 5th and subsequent parameters to this function. Any of these 
-** arguments may be NULL, in which case the corresponding element of meta 
-** information is ommitted.
-**
-** <pre>
-** Parameter     Output Type      Description
-** -----------------------------------
+** Metadata is returned by writing to the memory locations passed as the 5th
+** and subsequent parameters to this function. Any of these arguments may be
+** NULL, in which case the corresponding element of metadata is omitted.
 **
-**   5th         const char*      Data type
-**   6th         const char*      Name of the default collation sequence 
-**   7th         int              True if the column has a NOT NULL constraint
-**   8th         int              True if the column is part of the PRIMARY KEY
-**   9th         int              True if the column is AUTOINCREMENT
-** </pre>
+** <blockquote>
+** <table border="1">
+** <tr><th> Parameter <th> Output<br>Type <th>  Description
 **
+** <tr><td> 5th <td> const char* <td> Data type
+** <tr><td> 6th <td> const char* <td> Name of default collation sequence
+** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
+** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
+** <tr><td> 9th <td> int         <td> True if column is AUTOINCREMENT
+** </table>
+** </blockquote>
 **
-** The memory pointed to by the character pointers returned for the 
-** declaration type and collation sequence is valid only until the next 
-** call to any sqlite API function.
+** The memory pointed to by the character pointers returned for the
+** declaration type and collation sequence is valid only until the next
+** call to any SQLite API function.
 **
-** If the specified table is actually a view, then an error is returned.
+** If the specified table is actually a view, an [error code] is returned.
 **
-** If the specified column is "rowid", "oid" or "_rowid_" and an 
-** INTEGER PRIMARY KEY column has been explicitly declared, then the output 
+** If the specified column is "rowid", "oid" or "_rowid_" 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
-** explicitly declared IPK column, then the output parameters are set as 
-** follows:
+** explicitly declared INTEGER PRIMARY KEY column, then the output
+** parameters are set as follows:
 **
 ** <pre>
 **     data type: "INTEGER"
@@ -5149,11 +5486,11 @@
 **
 ** This function may load one or more schemas from database files. If an
 ** error occurs during this process, or if the requested table or column
-** cannot be found, an SQLITE error code is returned and an error message
-** left in the database handle (to be retrieved using sqlite3_errmsg()).
+** cannot be found, an [error code] is returned and an error message left
+** in the [database connection] (to be retrieved using sqlite3_errmsg()).
 **
 ** This API is only available if the library was compiled with the
-** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
 */
 SQLITE_API int sqlite3_table_column_metadata(
   sqlite3 *db,                /* Connection handle */
@@ -5170,25 +5507,28 @@
 /*
 ** CAPI3REF: Load An Extension {F12600}
 **
-** {F12601} The sqlite3_load_extension() interface
-** attempts to load an SQLite extension library contained in the file
-** zFile. {F12602} The entry point is zProc. {F12603} zProc may be 0
-** in which case the name of the entry point defaults
-** to "sqlite3_extension_init".
-**
-** {F12604} The sqlite3_load_extension() interface shall
-** return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
-**
-** {F12605}
-** 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()].
-** {END}  The calling function should free this memory
-** by calling [sqlite3_free()].
-**
-** {F12606}
-** Extension loading must be enabled using [sqlite3_enable_load_extension()]
-** prior to calling this API or an error will be returned.
+** This interface loads an SQLite extension library from the named file.
+**
+** {F12601} The sqlite3_load_extension() interface attempts to load an
+**          SQLite extension library contained in the file zFile.
+**
+** {F12602} The entry point is zProc.
+**
+** {F12603} zProc may be 0, in which case the name of the entry point
+**          defaults to "sqlite3_extension_init".
+**
+** {F12604} The sqlite3_load_extension() interface shall return
+**          [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
+**
+** {F12605} 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()]. {END}  The calling function
+**          should free this memory by calling [sqlite3_free()].
+**
+** {F12606} Extension loading must be enabled using
+**          [sqlite3_enable_load_extension()] prior to calling this API,
+**          otherwise an error will be returned.
 */
 SQLITE_API int sqlite3_load_extension(
   sqlite3 *db,          /* Load the extension into this database connection */
@@ -5198,65 +5538,64 @@
 );
 
 /*
-** CAPI3REF:  Enable Or Disable Extension Loading {F12620}
+** CAPI3REF: Enable Or Disable Extension Loading {F12620}
 **
 ** 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.  {F12622} It is off by default. {END} See ticket #1863.
-**
-** {F12621} 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. {END}
+** extension loading while evaluating user-entered SQL, the following API
+** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
+**
+** Extension loading is off by default. See ticket #1863.
+**
+** {F12621} 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.
+**
+** {F12622} Extension loading is off by default.
 */
 SQLITE_API int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
 /*
 ** CAPI3REF: Make Arrangements To Automatically Load An Extension {F12640}
 **
-** {F12641} This function
-** registers an extension entry point that is automatically invoked
-** whenever a new database connection is opened using
-** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. {END}
-**
 ** This API can be invoked at program startup in order to register
 ** one or more statically linked extensions that will be available
-** to all new database connections.
+** to all new [database connections]. {END}
 **
-** {F12642} Duplicate extensions are detected so calling this routine multiple
-** times with the same extension is harmless.
+** This routine stores a pointer to the extension in an array that is
+** obtained from [sqlite3_malloc()].  If you run a memory leak checker
+** on your program and it reports a leak because of this array, invoke
+** [sqlite3_reset_auto_extension()] prior to shutdown to free the memory.
+**
+** {F12641} This function registers an extension entry point that is
+**          automatically invoked whenever a new [database connection]
+**          is opened using [sqlite3_open()], [sqlite3_open16()],
+**          or [sqlite3_open_v2()].
 **
-** {F12643} This routine stores a pointer to the extension in an array
-** that is obtained from sqlite_malloc(). {END} If you run a memory leak
-** checker on your program and it reports a leak because of this
-** array, then invoke [sqlite3_reset_auto_extension()] prior
-** to shutdown to free the memory.
+** {F12642} Duplicate extensions are detected so calling this routine
+**          multiple times with the same extension is harmless.
 **
-** {F12644} Automatic extensions apply across all threads. {END}
+** {F12643} This routine stores a pointer to the extension in an array
+**          that is obtained from [sqlite3_malloc()].
 **
-** This interface is experimental and is subject to change or
-** removal in future releases of SQLite.
+** {F12644} Automatic extensions apply across all threads.
 */
 SQLITE_API int sqlite3_auto_extension(void *xEntryPoint);
 
-
 /*
 ** CAPI3REF: Reset Automatic Extension Loading {F12660}
 **
-** {F12661} This function disables all previously registered
-** automatic extensions. {END}  This
-** routine undoes the effect of all prior [sqlite3_auto_extension()]
-** calls.
+** This function disables all previously registered automatic
+** extensions. {END}  It undoes the effect of all prior
+** [sqlite3_auto_extension()] calls.
 **
-** {F12662} This call disabled automatic extensions in all threads. {END}
+** {F12661} This function disables all previously registered
+**          automatic extensions.
 **
-** This interface is experimental and is subject to change or
-** removal in future releases of SQLite.
+** {F12662} This function disables automatic extensions in all threads.
 */
 SQLITE_API void sqlite3_reset_auto_extension(void);
 
-
 /*
 ****** EXPERIMENTAL - subject to change without notice **************
 **
@@ -5264,7 +5603,7 @@
 ** to be experimental.  The interface might change in incompatible ways.
 ** If this is a problem for you, do not use the interface at this time.
 **
-** When the virtual-table mechanism stablizes, we will declare the
+** When the virtual-table mechanism stabilizes, we will declare the
 ** interface fixed, support it indefinitely, and remove this comment.
 */
 
@@ -5283,6 +5622,9 @@
 ** A module is a class of virtual tables.  Each module is defined
 ** by an instance of the following structure.  This structure consists
 ** mostly of methods for the module.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_module {
   int iVersion;
@@ -5325,14 +5667,12 @@
 ** inputs to xBestIndex and are read-only.  xBestIndex inserts its
 ** results into the **Outputs** fields.
 **
-** The aConstraint[] array records WHERE clause constraints of the
-** form:
+** The aConstraint[] array records WHERE clause constraints of the form:
 **
-**         column OP expr
+** <pre>column OP expr</pre>
 **
-** Where OP is =, &lt;, &lt;=, &gt;, or &gt;=.  
-** The particular operator is stored
-** in aConstraint[].op.  The index of the column is stored in 
+** where OP is =, &lt;, &lt;=, &gt;, or &gt;=.  The particular operator is
+** stored in aConstraint[].op.  The index of the column is stored in
 ** aConstraint[].iColumn.  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.
@@ -5364,6 +5704,9 @@
 ** particular lookup.  A full scan of a table with N entries should have
 ** a cost of N.  A binary search of a table of N entries should have a
 ** cost of approximately log(N).
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_index_info {
   /* Inputs */
@@ -5401,10 +5744,13 @@
 /*
 ** CAPI3REF: Register A Virtual Table Implementation {F18200}
 **
-** This routine is used to register a new module name with an SQLite
-** connection.  Module names must be registered before creating new
-** virtual tables on the module, or before using preexisting virtual
-** tables of the module.
+** This routine is used to register a new module name with a
+** [database connection].  Module names must be registered before
+** creating new virtual tables on the module, or before using
+** preexisting virtual tables of the module.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 SQLITE_API int sqlite3_create_module(
   sqlite3 *db,               /* SQLite connection to register module with */
@@ -5416,7 +5762,7 @@
 /*
 ** CAPI3REF: Register A Virtual Table Implementation {F18210}
 **
-** This routine is identical to the sqlite3_create_module() method above,
+** This routine is identical to the [sqlite3_create_module()] method above,
 ** except that it allows a destructor function to be specified. It is
 ** even more experimental than the rest of the virtual tables API.
 */
@@ -5434,19 +5780,22 @@
 **
 ** Every module implementation uses a subclass of the following structure
 ** to describe a particular instance of the module.  Each subclass will
-** be tailored to the specific needs of the module implementation.   The
-** purpose of this superclass is to define certain fields that are common
-** to all module implementations.
+** be tailored to the specific needs of the module implementation.
+** The purpose of this superclass is to define certain fields that are
+** common to all module implementations.
 **
 ** Virtual tables methods can set an error message by assigning a
-** string obtained from sqlite3_mprintf() to zErrMsg.  The method should
-** take care that any prior string is freed by a call to sqlite3_free()
+** string obtained from [sqlite3_mprintf()] to zErrMsg.  The method should
+** take care that any prior string is freed by a call to [sqlite3_free()]
 ** prior to assigning a new string to zErrMsg.  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.  Note
 ** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field
 ** since virtual tables are commonly implemented in loadable extensions which
 ** do not have access to sqlite3MPrintf() or sqlite3Free().
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_vtab {
   const sqlite3_module *pModule;  /* The module for this virtual table */
@@ -5467,6 +5816,9 @@
 **
 ** This superclass exists in order to define fields of the cursor that
 ** are common to all implementations.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_vtab_cursor {
   sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
@@ -5479,6 +5831,9 @@
 ** The xCreate and xConnect methods of a module use the following API
 ** to declare the format (the names and datatypes of the columns) of
 ** the virtual tables they implement.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 SQLITE_API int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable);
 
@@ -5494,7 +5849,7 @@
 ** before this API is called, a new function is created.  The implementation
 ** of the new function always causes an exception to be thrown.  So
 ** the new function is not good for anything by itself.  Its only
-** purpose is to be a place-holder function that can be overloaded
+** purpose is to be a placeholder function that can be overloaded
 ** by virtual tables.
 **
 ** This API should be considered part of the virtual table interface,
@@ -5516,67 +5871,82 @@
 
 /*
 ** CAPI3REF: A Handle To An Open BLOB {F17800}
+** KEYWORDS: {BLOB handle} {BLOB handles}
 **
 ** An instance of this object represents an open BLOB on which
-** incremental I/O can be preformed.
-** Objects of this type are created by
-** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()].
+** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
+** Objects of this type are created by [sqlite3_blob_open()]
+** and destroyed by [sqlite3_blob_close()].
 ** 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.
+** 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.
 */
 typedef struct sqlite3_blob sqlite3_blob;
 
 /*
 ** CAPI3REF: Open A BLOB For Incremental I/O {F17810}
 **
-** This interfaces opens a handle to the blob located
+** This interfaces opens a [BLOB handle | 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:
+** in other words, the same BLOB that would be selected by:
 **
 ** <pre>
 **     SELECT zColumn FROM zDb.zTable WHERE rowid = iRow;
 ** </pre> {END}
 **
-** If the flags parameter is non-zero, the blob is opened for 
-** read and write access. If it is zero, the blob is opened for read 
-** access.
+** If the flags parameter is non-zero, the the BLOB is opened for read
+** and write access. If it is zero, the BLOB is opened for read access.
 **
 ** Note that the database name is not the filename that contains
 ** the database but rather the symbolic name of the database that
 ** is assigned when the database is connected using [ATTACH].
-** For the main database file, the database name is "main".  For
-** TEMP tables, the database name is "temp".
+** For the main database file, the database name is "main".
+** For TEMP tables, the database name is "temp".
 **
-** On success, [SQLITE_OK] is returned and the new 
-** [sqlite3_blob | blob handle] is written to *ppBlob. 
-** Otherwise an error code is returned and 
-** any value written to *ppBlob should not be used by the caller.
-** This function sets the database-handle error code and message
+** On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
+** to *ppBlob. Otherwise an [error code] is returned and any value written
+** to *ppBlob should not be used by the caller.
+** This function sets the [database connection] error code and message
 ** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()].
-** 
+**
+** 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.
+** Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
+** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
+** Changes written into a BLOB prior to the BLOB expiring are not
+** rollback by the expiration of the BLOB.  Such changes will eventually
+** commit if the transaction continues to completion.
+**
 ** INVARIANTS:
 **
 ** {F17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)]
-**          interface opens an [sqlite3_blob] object P on the blob
-**          in column C of table T in database B on [database connection] D.
-**
-** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] starts
-**          a new transaction on [database connection] D if that connection
-**          is not already in a transaction.
-**
-** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface opens the blob
-**          for read and write access if and only if the F parameter
-**          is non-zero.
+**          interface shall open an [sqlite3_blob] object P on the BLOB
+**          in column C of the table T in the database B on
+**          the [database connection] D.
+**
+** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] shall start
+**          a new transaction on the [database connection] D if that
+**          connection is not already in a transaction.
+**
+** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface shall open
+**          the BLOB for read and write access if and only if the F
+**          parameter is non-zero.
 **
-** {F17819} The [sqlite3_blob_open()] interface returns [SQLITE_OK] on 
+** {F17819} The [sqlite3_blob_open()] interface shall return [SQLITE_OK] on
 **          success and an appropriate [error code] on failure.
 **
 ** {F17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)]
 **          then subsequent calls to [sqlite3_errcode(D)],
-**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return
-**          information approprate for that error.
+**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
+**          information appropriate for that error.
+**
+** {F17824} If any column in the row that a [sqlite3_blob] has open is
+**          changed by a separate [UPDATE] or [DELETE] statement or by
+**          an [ON CONFLICT] side effect, then the [sqlite3_blob] shall
+**          be marked as invalid.
 */
 SQLITE_API int sqlite3_blob_open(
   sqlite3*,
@@ -5589,15 +5959,16 @@
 );
 
 /*
-** CAPI3REF:  Close A BLOB Handle {F17830}
+** CAPI3REF: Close A BLOB Handle {F17830}
 **
-** Close an open [sqlite3_blob | blob handle].
+** Closes an open [BLOB handle].
 **
 ** Closing a BLOB shall cause the current transaction to commit
 ** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in autocommit mode.
+** database connection is in [autocommit mode].
 ** If any writes were made to the BLOB, they might be held in cache
 ** until the close operation if they will fit. {END}
+**
 ** Closing the BLOB often forces the changes
 ** out to disk and so if any I/O errors occur, they will likely occur
 ** at the time when the BLOB is closed.  {F17833} Any errors that occur during
@@ -5608,29 +5979,26 @@
 **
 ** INVARIANTS:
 **
-** {F17833} The [sqlite3_blob_close(P)] interface closes an
-**          [sqlite3_blob] object P previously opened using
-**          [sqlite3_blob_open()].
+** {F17833} The [sqlite3_blob_close(P)] interface closes an [sqlite3_blob]
+**          object P previously opened using [sqlite3_blob_open()].
 **
 ** {F17836} Closing an [sqlite3_blob] object using
 **          [sqlite3_blob_close()] shall cause the current transaction to
 **          commit if there are no other open [sqlite3_blob] objects
 **          or [prepared statements] on the same [database connection] and
-**          the [database connection] is in
-**          [sqlite3_get_autocommit | autocommit mode].
+**          the database connection is in [autocommit mode].
 **
-** {F17839} The [sqlite3_blob_close(P)] interfaces closes the 
+** {F17839} The [sqlite3_blob_close(P)] interfaces shall close the
 **          [sqlite3_blob] object P unconditionally, even if
 **          [sqlite3_blob_close(P)] returns something other than [SQLITE_OK].
-**          
 */
 SQLITE_API int sqlite3_blob_close(sqlite3_blob *);
 
 /*
-** CAPI3REF:  Return The Size Of An Open BLOB {F17840}
+** CAPI3REF: Return The Size Of An Open BLOB {F17840}
 **
-** Return the size in bytes of the blob accessible via the open 
-** [sqlite3_blob] object in its only argument.
+** Returns the size in bytes of the BLOB accessible via the open
+** []BLOB handle] in its only argument.
 **
 ** INVARIANTS:
 **
@@ -5641,106 +6009,126 @@
 SQLITE_API int sqlite3_blob_bytes(sqlite3_blob *);
 
 /*
-** CAPI3REF:  Read Data From A BLOB Incrementally {F17850}
+** CAPI3REF: Read Data From A BLOB Incrementally {F17850}
 **
-** This function is used to read data from an open 
-** [sqlite3_blob | blob-handle] into a caller supplied buffer.
-** N bytes of data are copied into buffer
-** Z from the open blob, starting at offset iOffset.
+** 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.
 **
-** If offset iOffset is less than N bytes from the end of the blob, 
+** If offset iOffset is less than N bytes from the end of the BLOB,
 ** [SQLITE_ERROR] is returned and no data is read.  If N or iOffset is
-** less than zero [SQLITE_ERROR] is returned and no data is read.
+** less than zero, [SQLITE_ERROR] is returned and no data is read.
 **
-** On success, SQLITE_OK is returned. Otherwise, an 
-** [error code] or an [extended error code] is returned.
+** An attempt to read from an expired [BLOB handle] fails with an
+** error code of [SQLITE_ABORT].
+**
+** On success, SQLITE_OK is returned.
+** Otherwise, an [error code] or an [extended error code] is returned.
 **
 ** INVARIANTS:
 **
-** {F17853} The [sqlite3_blob_read(P,Z,N,X)] interface reads N bytes
-**          beginning at offset X from
-**          the blob that [sqlite3_blob] object P refers to
-**          and writes those N bytes into buffer Z.
-**
-** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the blob
-**          is less than N+X bytes, then the function returns [SQLITE_ERROR]
-**          and nothing is read from the blob.
+** {F17853} A successful invocation of [sqlite3_blob_read(P,Z,N,X)] 
+**          shall reads N bytes of data out of the BLOB referenced by
+**          [BLOB handle] P beginning at offset X and store those bytes
+**          into buffer Z.
+**
+** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the BLOB
+**          is less than N+X bytes, then the function shall leave the
+**          Z buffer unchanged and return [SQLITE_ERROR].
 **
 ** {F17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero
-**          then the function returns [SQLITE_ERROR]
-**          and nothing is read from the blob.
+**          then the function shall leave the Z buffer unchanged
+**          and return [SQLITE_ERROR].
+**
+** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface shall return [SQLITE_OK]
+**          if N bytes are successfully read into buffer Z.
 **
-** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface returns [SQLITE_OK]
-**          if N bytes where successfully read into buffer Z.
+** {F17863} If the [BLOB handle] P is expired and X and N are within bounds
+**          then [sqlite3_blob_read(P,Z,N,X)] shall leave the Z buffer
+**          unchanged and return [SQLITE_ABORT].
 **
 ** {F17865} If the requested read could not be completed,
-**          the [sqlite3_blob_read(P,Z,N,X)] interface returns an
+**          the [sqlite3_blob_read(P,Z,N,X)] interface shall return an
 **          appropriate [error code] or [extended error code].
 **
 ** {F17868} If an error occurs during evaluation of [sqlite3_blob_read(P,...)]
 **          then subsequent calls to [sqlite3_errcode(D)],
-**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return
-**          information approprate for that error, where D is the
-**          database handle that was used to open blob handle P.
+**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
+**          information appropriate for that error, where D is the
+**          [database connection] that was used to open the [BLOB handle] P.
 */
 SQLITE_API int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 
 /*
-** CAPI3REF:  Write Data Into A BLOB Incrementally {F17870}
+** CAPI3REF: Write Data Into A BLOB Incrementally {F17870}
 **
-** This function is used to write data into an open 
-** [sqlite3_blob | blob-handle] from a user supplied buffer.
-** n bytes of data are copied from the buffer
-** pointed to by z into the open blob, starting at offset iOffset.
-**
-** If the [sqlite3_blob | 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].
-**
-** 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.  If n is
+** 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.
+**
+** 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].
+**
+** 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.  If N is
 ** less than zero [SQLITE_ERROR] is returned and no data is written.
 **
-** On success, SQLITE_OK is returned. Otherwise, an 
-** [error code] or an [extended error code] is returned.
+** An attempt to write to an expired [BLOB handle] fails with an
+** error code of [SQLITE_ABORT].  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.
+**
+** On success, SQLITE_OK is returned.
+** Otherwise, an  [error code] or an [extended error code] is returned.
 **
 ** INVARIANTS:
 **
-** {F17873} The [sqlite3_blob_write(P,Z,N,X)] interface writes N bytes
-**          from buffer Z into
-**          the blob that [sqlite3_blob] object P refers to
-**          beginning at an offset of X into the blob.
-**
-** {F17875} The [sqlite3_blob_write(P,Z,N,X)] interface returns
-**          [SQLITE_READONLY] if the [sqlite3_blob] object P was
-**          [sqlite3_blob_open | opened] for reading only.
-**
-** {F17876} In [sqlite3_blob_write(P,Z,N,X)] if the size of the blob
-**          is less than N+X bytes, then the function returns [SQLITE_ERROR]
-**          and nothing is written into the blob.
-**
-** {F17879} In [sqlite3_blob_write(P,Z,N,X)] if X or N is less than zero
-**          then the function returns [SQLITE_ERROR]
-**          and nothing is written into the blob.
+** {F17873} A successful invocation of [sqlite3_blob_write(P,Z,N,X)]
+**          shall write N bytes of data from buffer Z into the BLOB 
+**          referenced by [BLOB handle] P beginning at offset X into
+**          the BLOB.
+**
+** {F17874} In the absence of other overridding changes, the changes
+**          written to a BLOB by [sqlite3_blob_write()] shall
+**          remain in effect after the associated [BLOB handle] expires.
+**
+** {F17875} If the [BLOB handle] P was opened for reading only then
+**          an invocation of [sqlite3_blob_write(P,Z,N,X)] shall leave
+**          the referenced BLOB unchanged and return [SQLITE_READONLY].
+**
+** {F17876} If the size of the BLOB referenced by [BLOB handle] P is
+**          less than N+X bytes then [sqlite3_blob_write(P,Z,N,X)] shall
+**          leave the BLOB unchanged and return [SQLITE_ERROR].
+**
+** {F17877} If the [BLOB handle] P is expired and X and N are within bounds
+**          then [sqlite3_blob_read(P,Z,N,X)] shall leave the BLOB
+**          unchanged and return [SQLITE_ABORT].
+**
+** {F17879} If X or N are less than zero then [sqlite3_blob_write(P,Z,N,X)]
+**          shall leave the BLOB referenced by [BLOB handle] P unchanged
+**          and return [SQLITE_ERROR].
 **
-** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface returns [SQLITE_OK]
-**          if N bytes where successfully written into blob.
+** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface shall return
+**          [SQLITE_OK] if N bytes where successfully written into the BLOB.
 **
 ** {F17885} If the requested write could not be completed,
-**          the [sqlite3_blob_write(P,Z,N,X)] interface returns an
+**          the [sqlite3_blob_write(P,Z,N,X)] interface shall return an
 **          appropriate [error code] or [extended error code].
 **
 ** {F17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)]
 **          then subsequent calls to [sqlite3_errcode(D)],
-**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return
-**          information approprate for that error.
+**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
+**          information appropriate for that error.
 */
 SQLITE_API int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
 
 /*
-** CAPI3REF:  Virtual File System Objects {F11200}
+** CAPI3REF: Virtual File System Objects {F11200}
 **
 ** A virtual filesystem (VFS) is an [sqlite3_vfs] object
 ** that SQLite uses to interact
@@ -5749,12 +6137,11 @@
 ** New VFSes can be registered and existing VFSes can be unregistered.
 ** The following interfaces are provided.
 **
-** The sqlite3_vfs_find() interface returns a pointer to 
-** a VFS given its name.  Names are case sensitive.
+** The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
+** Names are case sensitive.
 ** Names are zero-terminated UTF-8 strings.
-** If there is no match, a NULL
-** pointer is returned.  If zVfsName is NULL then the default 
-** VFS is returned. 
+** If there is no match, a NULL pointer is returned.
+** If zVfsName is NULL then the default VFS is returned.
 **
 ** New VFSes are registered with sqlite3_vfs_register().
 ** Each new VFS becomes the default VFS if the makeDflt flag is set.
@@ -5764,7 +6151,7 @@
 ** same name are registered, the behavior is undefined.  If a
 ** VFS is registered with a name that is NULL or an empty string,
 ** then the behavior is undefined.
-** 
+**
 ** 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.
@@ -5778,7 +6165,7 @@
 **
 ** {F11206} If the N parameter to [sqlite3_vfs_find(N)] is NULL then
 **          the function returns a pointer to the default [sqlite3_vfs]
-**          object if there is one, or NULL if there is no default 
+**          object if there is one, or NULL if there is no default
 **          [sqlite3_vfs] object.
 **
 ** {F11209} The [sqlite3_vfs_register(P,F)] interface registers the
@@ -5788,9 +6175,8 @@
 ** {F11212} Using the [sqlite3_vfs_register(P,F)] interface to register
 **          the same [sqlite3_vfs] object multiple times is a harmless no-op.
 **
-** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the
-**          the [sqlite3_vfs] object P the default [sqlite3_vfs] object
-**          if F is non-zero.
+** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the [sqlite3_vfs]
+**          object P the default [sqlite3_vfs] object if F is non-zero.
 **
 ** {F11218} The [sqlite3_vfs_unregister(P)] interface unregisters the
 **          [sqlite3_vfs] object P so that it is no longer returned by
@@ -5804,11 +6190,11 @@
 ** CAPI3REF: Mutexes {F17000}
 **
 ** The SQLite core uses these routines for thread
-** synchronization.  Though they are intended for internal
+** synchronization. Though they are intended for internal
 ** use by SQLite, code that links against SQLite is
 ** permitted to use any of these routines.
 **
-** The SQLite source code contains multiple implementations 
+** The SQLite source code contains multiple implementations
 ** of these mutex routines.  An appropriate implementation
 ** is selected automatically at compile-time.  The following
 ** implementations are available in the SQLite core:
@@ -5820,20 +6206,19 @@
 ** <li>   SQLITE_MUTEX_NOOP
 ** </ul>
 **
-** The SQLITE_MUTEX_NOOP implementation is a set of routines 
-** that does no real locking and is appropriate for use in 
+** The SQLITE_MUTEX_NOOP implementation is a set of routines
+** that does no real locking and is appropriate for use in
 ** a single-threaded application.  The SQLITE_MUTEX_OS2,
 ** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations
-** are appropriate for use on os/2, unix, and windows.
-** 
+** are appropriate for use on OS/2, Unix, and Windows.
+**
 ** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
 ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
-** implementation is included with the library.  The
-** mutex interface routines defined here become external
-** references in the SQLite library for which implementations
-** must be provided by the application.  This facility allows an
-** application that links against SQLite to provide its own mutex
-** implementation without having to modify the SQLite core.
+** implementation is included with the library. In this case the
+** application must supply a custom mutex implementation using the
+** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
+** before calling sqlite3_initialize() or any other public sqlite3_
+** function that calls sqlite3_initialize().
 **
 ** {F17011} The sqlite3_mutex_alloc() routine allocates a new
 ** mutex and returns a pointer to it. {F17012} If it returns NULL
@@ -5850,7 +6235,7 @@
 ** <li>  SQLITE_MUTEX_STATIC_PRNG
 ** <li>  SQLITE_MUTEX_STATIC_LRU
 ** <li>  SQLITE_MUTEX_STATIC_LRU2
-** </ul> {END}
+** </ul>
 **
 ** {F17015} The first two constants cause sqlite3_mutex_alloc() to create
 ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
@@ -5872,41 +6257,45 @@
 **
 ** {F17018} 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.  {F17034} But for the static 
+** returns a different mutex on every call.  {F17034} But for the static
 ** mutex types, the same mutex is returned on every call that has
-** the same type number. {END}
+** the same type number.
 **
 ** {F17019} The sqlite3_mutex_free() routine deallocates a previously
 ** allocated dynamic mutex. {F17020} SQLite is careful to deallocate every
-** dynamic mutex that it allocates. {U17021} The dynamic mutexes must not be in 
-** use when they are deallocated. {U17022} Attempting to deallocate a static
+** dynamic mutex that it allocates. {A17021} The dynamic mutexes must not be in
+** use when they are deallocated. {A17022} Attempting to deallocate a static
 ** mutex results in undefined behavior. {F17023} SQLite never deallocates
 ** a static mutex. {END}
 **
 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
 ** to enter a mutex. {F17024} If another thread is already within the mutex,
 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. {F17025}  The sqlite3_mutex_try() interface returns SQLITE_OK
+** SQLITE_BUSY. {F17025}  The sqlite3_mutex_try() interface returns [SQLITE_OK]
 ** upon successful entry.  {F17026} Mutexes created using
 ** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
 ** {F17027} In such cases the,
 ** mutex must be exited an equal number of times before another thread
-** can enter.  {U17028} If the same thread tries to enter any other
+** can enter.  {A17028} If the same thread tries to enter any other
 ** kind of mutex more than once, the behavior is undefined.
 ** {F17029} SQLite will never exhibit
-** such behavior in its own use of mutexes. {END}
+** such behavior in its own use of mutexes.
 **
-** Some systems (ex: windows95) do not the operation implemented by
-** sqlite3_mutex_try().  On those systems, sqlite3_mutex_try() will
-** always return SQLITE_BUSY.  {F17030} The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior. {END}
+** 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.  {F17030} The SQLite core only ever uses
+** sqlite3_mutex_try() as an optimization so this is acceptable behavior.
 **
 ** {F17031} The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread.  {U17032} The behavior
+** previously entered by the same thread.  {A17032} The behavior
 ** is undefined if the mutex is not currently entered by the
 ** calling thread or is not currently allocated.  {F17033} SQLite will
 ** never do either. {END}
 **
+** 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()].
 */
 SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int);
@@ -5916,26 +6305,87 @@
 SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex*);
 
 /*
-** CAPI3REF: Mutex Verifcation Routines {F17080}
+** CAPI3REF: Mutex Methods Object {F17120}
+**
+** An instance of this structure defines the low-level routines
+** used to allocate and use mutexes.
+**
+** Usually, the default mutex implementations provided by SQLite are
+** sufficient, however the user has the option of substituting a custom
+** implementation for specialized deployments or systems for which SQLite
+** does not provide a suitable implementation. In this case, the user
+** creates and populates an instance of this structure to pass
+** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
+** Additionally, an instance of this structure can be used as an
+** output variable when querying the system for the current mutex
+** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
+**
+** The xMutexInit method defined by this structure is invoked as
+** part of system initialization by the sqlite3_initialize() function.
+** {F17001} The xMutexInit routine shall be called by SQLite once for each
+** effective call to [sqlite3_initialize()].
+**
+** The xMutexEnd method defined by this structure is invoked as
+** part of system shutdown by the sqlite3_shutdown() function. The
+** implementation of this method is expected to release all outstanding
+** resources obtained by the mutex methods implementation, especially
+** those obtained by the xMutexInit method. {F17003} The xMutexEnd()
+** interface shall be invoked once for each call to [sqlite3_shutdown()].
+**
+** The remaining seven methods defined by this structure (xMutexAlloc,
+** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
+** xMutexNotheld) implement the following interfaces (respectively):
+**
+** <ul>
+**   <li>  [sqlite3_mutex_alloc()] </li>
+**   <li>  [sqlite3_mutex_free()] </li>
+**   <li>  [sqlite3_mutex_enter()] </li>
+**   <li>  [sqlite3_mutex_try()] </li>
+**   <li>  [sqlite3_mutex_leave()] </li>
+**   <li>  [sqlite3_mutex_held()] </li>
+**   <li>  [sqlite3_mutex_notheld()] </li>
+** </ul>
+**
+** The only difference is that the public sqlite3_XXX functions enumerated
+** above silently ignore any invocations that pass a NULL pointer instead
+** of a valid mutex handle. The implementations of the methods defined
+** by this structure are not required to handle this case, the results
+** of passing a NULL pointer instead of a valid mutex handle are undefined
+** (i.e. it is acceptable to provide an implementation that segfaults if
+** it is passed a NULL pointer).
+*/
+typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
+struct sqlite3_mutex_methods {
+  int (*xMutexInit)(void);
+  int (*xMutexEnd)(void);
+  sqlite3_mutex *(*xMutexAlloc)(int);
+  void (*xMutexFree)(sqlite3_mutex *);
+  void (*xMutexEnter)(sqlite3_mutex *);
+  int (*xMutexTry)(sqlite3_mutex *);
+  void (*xMutexLeave)(sqlite3_mutex *);
+  int (*xMutexHeld)(sqlite3_mutex *);
+  int (*xMutexNotheld)(sqlite3_mutex *);
+};
+
+/*
+** CAPI3REF: Mutex Verification Routines {F17080}
 **
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
 ** are intended for use inside assert() statements. {F17081} The SQLite core
 ** never uses these routines except inside an assert() and applications
 ** are advised to follow the lead of the core.  {F17082} The core only
 ** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag.  {U17087} External mutex implementations
+** with the SQLITE_DEBUG flag.  {A17087} External mutex implementations
 ** are only required to provide these routines if SQLITE_DEBUG is
 ** defined and if NDEBUG is not defined.
 **
 ** {F17083} These routines should return true if the mutex in their argument
-** is held or not held, respectively, by the calling thread. {END}
+** is held or not held, respectively, by the calling thread.
 **
 ** {X17084} The implementation is not required to provided versions of these
-** routines that actually work.
-** If the implementation does not provide working
-** versions of these routines, it should at least provide stubs
-** that always return true so that one does not get spurious
-** assertion failures. {END}
+** routines that actually work. If the implementation does not provide working
+** versions of these routines, it should at least provide stubs that always
+** return true so that one does not get spurious assertion failures.
 **
 ** {F17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
 ** the routine should return 1.  {END} This seems counter-intuitive since
@@ -5943,7 +6393,7 @@
 ** the reason the mutex does not exist is because the build is not
 ** using mutexes.  And we do not want the assert() containing the
 ** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do.  {F17086} The sqlite3_mutex_notheld() 
+** the appropriate thing to do.  {F17086} The sqlite3_mutex_notheld()
 ** interface should also return 1 when given a NULL pointer.
 */
 SQLITE_API int sqlite3_mutex_held(sqlite3_mutex*);
@@ -5953,7 +6403,7 @@
 ** CAPI3REF: Mutex Types {F17001}
 **
 ** {F17002} The [sqlite3_mutex_alloc()] interface takes a single argument
-** which is one of these integer constants. {END}
+** which is one of these integer constants.
 */
 #define SQLITE_MUTEX_FAST             0
 #define SQLITE_MUTEX_RECURSIVE        1
@@ -5981,8 +6431,8 @@
 ** {F11306} If the second parameter (zDbName) does not match the name of any
 ** open database file, then SQLITE_ERROR is returned. {F11307} This error
 ** code is not remembered and will not be recalled by [sqlite3_errcode()]
-** or [sqlite3_errmsg()]. {U11308} The underlying xFileControl method might
-** also return SQLITE_ERROR.  {U11309} There is no way to distinguish between
+** or [sqlite3_errmsg()]. {A11308} The underlying xFileControl method might
+** also return SQLITE_ERROR.  {A11309} There is no way to distinguish between
 ** an incorrect zDbName and an SQLITE_ERROR return from the underlying
 ** xFileControl method. {END}
 **
@@ -5995,7 +6445,7 @@
 **
 ** The sqlite3_test_control() interface is used to read out internal
 ** state of SQLite and to inject faults into SQLite for testing
-** purposes.  The first parameter a operation code that determines
+** purposes.  The first parameter is an operation code that determines
 ** the number, meaning, and operation of all subsequent parameters.
 **
 ** This interface is not for use by applications.  It exists solely
@@ -6015,19 +6465,106 @@
 ** These constants are the valid operation code parameters used
 ** as the first argument to [sqlite3_test_control()].
 **
-** These parameters and their meansing are subject to change
+** These parameters and their meanings are subject to change
 ** without notice.  These values are for testing purposes only.
 ** Applications should not use any of these parameters or the
 ** [sqlite3_test_control()] interface.
 */
-#define SQLITE_TESTCTRL_FAULT_CONFIG             1
-#define SQLITE_TESTCTRL_FAULT_FAILURES           2
-#define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES    3
-#define SQLITE_TESTCTRL_FAULT_PENDING            4
 #define SQLITE_TESTCTRL_PRNG_SAVE                5
 #define SQLITE_TESTCTRL_PRNG_RESTORE             6
 #define SQLITE_TESTCTRL_PRNG_RESET               7
 #define SQLITE_TESTCTRL_BITVEC_TEST              8
+#define SQLITE_TESTCTRL_FAULT_INSTALL            9
+#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
+
+/*
+** CAPI3REF: SQLite Runtime Status {F17200}
+**
+** This interface is used to retrieve runtime status information
+** about the preformance of SQLite, and optionally to reset various
+** highwater marks.  The first argument is an integer code for
+** the specific parameter to measure.  Recognized integer codes
+** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].
+** The current value of the parameter is returned into *pCurrent.
+** The highest recorded value is returned in *pHighwater.  If the
+** resetFlag is true, then the highest record value is reset after
+** *pHighwater is written. Some parameters do not record the highest
+** value.  For those parameters
+** nothing is written into *pHighwater and the resetFlag is ignored.
+** Other parameters record only the highwater mark and not the current
+** value.  For these latter parameters nothing is written into *pCurrent.
+**
+** This routine returns SQLITE_OK on success and a non-zero
+** [error code] on failure.
+**
+** This routine is threadsafe but is not atomic.  This routine can
+** called while other threads are running the same or different SQLite
+** interfaces.  However the values returned in *pCurrent and
+** *pHighwater reflect the status of SQLite at different points in time
+** and it is possible that another thread might change the parameter
+** in between the times when *pCurrent and *pHighwater are written.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
+*/
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+
+/*
+** CAPI3REF: Status Parameters {F17250}
+**
+** These integer constants designate various run-time status parameters
+** that can be returned by [sqlite3_status()].
+**
+** <dl>
+** <dt>SQLITE_STATUS_MEMORY_USED</dt>
+** <dd>This parameter is the current amount of memory checked out
+** using [sqlite3_malloc()], either directly or indirectly.  The
+** figure includes calls made to [sqlite3_malloc()] by the application
+** and internal memory usage by the SQLite library.  Scratch memory
+** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
+** 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].</dd>
+**
+** <dt>SQLITE_STATUS_PAGECACHE_USED</dt>
+** <dd>This parameter returns the number of pages used out of the
+** page cache buffer configured using [SQLITE_CONFIG_PAGECACHE].  The
+** value returned is in pages, not in bytes.</dd>
+**
+** <dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
+** <dd>This parameter returns the number of bytes of page cache
+** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
+** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+**
+** <dt>SQLITE_STATUS_SCRATCH_USED</dt>
+** <dd>This parameter returns the number of allocations used out of the
+** scratch allocation lookaside buffer configured using
+** [SQLITE_CONFIG_SCRATCH].  The value returned is in allocations, not
+** in bytes.  Since a single thread may only have one allocation
+** outstanding at time, this parameter also reports the number of threads
+** using scratch memory at the same time.</dd>
+**
+** <dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
+** <dd>This parameter returns the number of bytes of scratch memory
+** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
+** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+**
+** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
+** internal equivalents).  The value of interest is return in the
+** *pHighwater parameter to [sqlite3_status()].  The value written
+** into the *pCurrent parameter is undefined.</dd>
+** </dl>
+**
+** New status parameters may be added from time to time.
+*/
+#define SQLITE_STATUS_MEMORY_USED          0
+#define SQLITE_STATUS_PAGECACHE_USED       1
+#define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
+#define SQLITE_STATUS_SCRATCH_USED         3
+#define SQLITE_STATUS_SCRATCH_OVERFLOW     4
+#define SQLITE_STATUS_MALLOC_SIZE          5
 
 
 /*
@@ -6378,11 +6915,11 @@
 #endif
 
 /*
-** Provide a default value for TEMP_STORE in case it is not specified
+** Provide a default value for SQLITE_TEMP_STORE in case it is not specified
 ** on the command-line
 */
-#ifndef TEMP_STORE
-# define TEMP_STORE 1
+#ifndef SQLITE_TEMP_STORE
+# define SQLITE_TEMP_STORE 1
 #endif
 
 /*
@@ -6578,7 +7115,7 @@
 ** subsystem.  See comments in the source code for a detailed description
 ** of what each interface routine does.
 **
-** @(#) $Id: btree.h,v 1.98 2008/04/26 13:39:47 drh Exp $
+** @(#) $Id: btree.h,v 1.102 2008/07/11 21:02:54 drh Exp $
 */
 #ifndef _BTREE_H_
 #define _BTREE_H_
@@ -6641,11 +7178,6 @@
 #define BTREE_READWRITE    16  /* Open for both reading and writing */
 #define BTREE_CREATE       32  /* Create the database if it does not exist */
 
-/* Additional values for the 4th argument of sqlite3BtreeOpen that
-** are not associated with PAGER_ values.
-*/
-#define BTREE_PRIVATE      64  /* Never share with other connections */
-
 SQLITE_PRIVATE int sqlite3BtreeClose(Btree*);
 SQLITE_PRIVATE int sqlite3BtreeSetCacheSize(Btree*,int);
 SQLITE_PRIVATE int sqlite3BtreeSetSafetyLevel(Btree*,int,int);
@@ -6712,6 +7244,7 @@
   int bias,
   int *pRes
 );
+SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor*, int*);
 SQLITE_PRIVATE int sqlite3BtreeDelete(BtCursor*);
 SQLITE_PRIVATE int sqlite3BtreeInsert(BtCursor*, const void *pKey, i64 nKey,
                                   const void *pData, int nData,
@@ -6739,7 +7272,6 @@
 #ifdef SQLITE_TEST
 SQLITE_PRIVATE int sqlite3BtreeCursorInfo(BtCursor*, int*, int);
 SQLITE_PRIVATE void sqlite3BtreeCursorList(Btree*);
-SQLITE_PRIVATE int sqlite3BtreePageDump(Btree*, int, int recursive);
 #endif
 
 /*
@@ -6750,24 +7282,36 @@
 #if !defined(SQLITE_OMIT_SHARED_CACHE) && SQLITE_THREADSAFE
 SQLITE_PRIVATE   void sqlite3BtreeEnter(Btree*);
 SQLITE_PRIVATE   void sqlite3BtreeLeave(Btree*);
+#ifndef NDEBUG
+  /* This routine is used inside assert() statements only. */
 SQLITE_PRIVATE   int sqlite3BtreeHoldsMutex(Btree*);
+#endif
 SQLITE_PRIVATE   void sqlite3BtreeEnterCursor(BtCursor*);
 SQLITE_PRIVATE   void sqlite3BtreeLeaveCursor(BtCursor*);
 SQLITE_PRIVATE   void sqlite3BtreeEnterAll(sqlite3*);
 SQLITE_PRIVATE   void sqlite3BtreeLeaveAll(sqlite3*);
+#ifndef NDEBUG
+  /* This routine is used inside assert() statements only. */
 SQLITE_PRIVATE   int sqlite3BtreeHoldsAllMutexes(sqlite3*);
+#endif
 SQLITE_PRIVATE   void sqlite3BtreeMutexArrayEnter(BtreeMutexArray*);
 SQLITE_PRIVATE   void sqlite3BtreeMutexArrayLeave(BtreeMutexArray*);
 SQLITE_PRIVATE   void sqlite3BtreeMutexArrayInsert(BtreeMutexArray*, Btree*);
 #else
 # define sqlite3BtreeEnter(X)
 # define sqlite3BtreeLeave(X)
+#ifndef NDEBUG
+  /* This routine is used inside assert() statements only. */
 # define sqlite3BtreeHoldsMutex(X) 1
+#endif
 # define sqlite3BtreeEnterCursor(X)
 # define sqlite3BtreeLeaveCursor(X)
 # define sqlite3BtreeEnterAll(X)
 # define sqlite3BtreeLeaveAll(X)
+#ifndef NDEBUG
+  /* This routine is used inside assert() statements only. */
 # define sqlite3BtreeHoldsAllMutexes(X) 1
+#endif
 # define sqlite3BtreeMutexArrayEnter(X)
 # define sqlite3BtreeMutexArrayLeave(X)
 # define sqlite3BtreeMutexArrayInsert(X,Y)
@@ -6797,7 +7341,7 @@
 ** or VDBE.  The VDBE implements an abstract machine that runs a
 ** simple program to access and modify the underlying database.
 **
-** $Id: vdbe.h,v 1.131 2008/05/01 17:03:49 drh Exp $
+** $Id: vdbe.h,v 1.134 2008/06/25 00:12:41 drh Exp $
 */
 #ifndef _SQLITE_VDBE_H_
 #define _SQLITE_VDBE_H_
@@ -6842,13 +7386,14 @@
     Mem *pMem;             /* Used when p4type is P4_MEM */
     sqlite3_vtab *pVtab;   /* Used when p4type is P4_VTAB */
     KeyInfo *pKeyInfo;     /* Used when p4type is P4_KEYINFO */
+    int *ai;               /* Used when p4type is P4_INTARRAY */
   } p4;
 #ifdef SQLITE_DEBUG
-  char *zComment;     /* Comment to improve readability */
+  char *zComment;          /* Comment to improve readability */
 #endif
 #ifdef VDBE_PROFILE
-  int cnt;            /* Number of times this instruction was executed */
-  long long cycles;   /* Total time spend executing this instruction */
+  int cnt;                 /* Number of times this instruction was executed */
+  u64 cycles;              /* Total time spent executing this instruction */
 #endif
 };
 typedef struct VdbeOp VdbeOp;
@@ -6882,6 +7427,7 @@
 #define P4_REAL     (-12) /* P4 is a 64-bit floating point value */
 #define P4_INT64    (-13) /* P4 is a 64-bit signed integer */
 #define P4_INT32    (-14) /* P4 is a 32-bit signed integer */
+#define P4_INTARRAY (-15) /* P4 is a vector of 32-bit integers */
 
 /* When adding a P4 argument using P4_KEYINFO, a copy of the KeyInfo structure
 ** is made.  That copy is freed when the Vdbe is finalized.  But if the
@@ -6890,7 +7436,8 @@
 ** from a single sqliteMalloc().  But no copy is made and the calling
 ** function should *not* try to free the KeyInfo.
 */
-#define P4_KEYINFO_HANDOFF (-9)
+#define P4_KEYINFO_HANDOFF (-16)
+#define P4_KEYINFO_STATIC  (-17)
 
 /*
 ** The Vdbe.aColName array contains 5n Mem structures, where n is the 
@@ -6949,121 +7496,121 @@
 #define OP_Expire                              14
 #define OP_AutoCommit                          15
 #define OP_Gt                                  69   /* same as TK_GT       */
-#define OP_IntegrityCk                         17
-#define OP_Sort                                18
-#define OP_Copy                                19
-#define OP_Trace                               20
-#define OP_Function                            21
-#define OP_IfNeg                               22
+#define OP_Pagecount                           17
+#define OP_IntegrityCk                         18
+#define OP_Sort                                19
+#define OP_Copy                                20
+#define OP_Trace                               21
+#define OP_Function                            22
+#define OP_IfNeg                               23
 #define OP_And                                 61   /* same as TK_AND      */
 #define OP_Subtract                            79   /* same as TK_MINUS    */
-#define OP_Noop                                23
-#define OP_Return                              24
+#define OP_Noop                                24
+#define OP_Return                              25
 #define OP_Remainder                           82   /* same as TK_REM      */
-#define OP_NewRowid                            25
+#define OP_NewRowid                            26
 #define OP_Multiply                            80   /* same as TK_STAR     */
-#define OP_Variable                            26
-#define OP_String                              27
-#define OP_RealAffinity                        28
-#define OP_VRename                             29
-#define OP_ParseSchema                         30
-#define OP_VOpen                               31
-#define OP_Close                               32
-#define OP_CreateIndex                         33
-#define OP_IsUnique                            34
-#define OP_NotFound                            35
-#define OP_Int64                               36
-#define OP_MustBeInt                           37
-#define OP_Halt                                38
-#define OP_Rowid                               39
-#define OP_IdxLT                               40
-#define OP_AddImm                              41
-#define OP_Statement                           42
-#define OP_RowData                             43
-#define OP_MemMax                              44
+#define OP_Variable                            27
+#define OP_String                              28
+#define OP_RealAffinity                        29
+#define OP_VRename                             30
+#define OP_ParseSchema                         31
+#define OP_VOpen                               32
+#define OP_Close                               33
+#define OP_CreateIndex                         34
+#define OP_IsUnique                            35
+#define OP_NotFound                            36
+#define OP_Int64                               37
+#define OP_MustBeInt                           38
+#define OP_Halt                                39
+#define OP_Rowid                               40
+#define OP_IdxLT                               41
+#define OP_AddImm                              42
+#define OP_Statement                           43
+#define OP_RowData                             44
+#define OP_MemMax                              45
 #define OP_Or                                  60   /* same as TK_OR       */
-#define OP_NotExists                           45
-#define OP_Gosub                               46
+#define OP_NotExists                           46
+#define OP_Gosub                               47
 #define OP_Divide                              81   /* same as TK_SLASH    */
-#define OP_Integer                             47
+#define OP_Integer                             48
 #define OP_ToNumeric                          140   /* same as TK_TO_NUMERIC*/
-#define OP_Prev                                48
+#define OP_Prev                                49
 #define OP_Concat                              83   /* same as TK_CONCAT   */
 #define OP_BitAnd                              74   /* same as TK_BITAND   */
-#define OP_VColumn                             49
-#define OP_CreateTable                         50
-#define OP_Last                                51
+#define OP_VColumn                             50
+#define OP_CreateTable                         51
+#define OP_Last                                52
 #define OP_IsNull                              65   /* same as TK_ISNULL   */
-#define OP_IncrVacuum                          52
-#define OP_IdxRowid                            53
+#define OP_IncrVacuum                          53
+#define OP_IdxRowid                            54
 #define OP_ShiftRight                          77   /* same as TK_RSHIFT   */
-#define OP_ResetCount                          54
-#define OP_FifoWrite                           55
-#define OP_ContextPush                         56
-#define OP_DropTrigger                         57
-#define OP_DropIndex                           58
-#define OP_IdxGE                               59
-#define OP_IdxDelete                           62
-#define OP_Vacuum                              63
-#define OP_MoveLe                              64
-#define OP_IfNot                               73
-#define OP_DropTable                           84
-#define OP_MakeRecord                          85
+#define OP_ResetCount                          55
+#define OP_FifoWrite                           56
+#define OP_ContextPush                         57
+#define OP_Yield                               58
+#define OP_DropTrigger                         59
+#define OP_DropIndex                           62
+#define OP_IdxGE                               63
+#define OP_IdxDelete                           64
+#define OP_Vacuum                              73
+#define OP_MoveLe                              84
+#define OP_IfNot                               85
+#define OP_DropTable                           86
+#define OP_MakeRecord                          89
 #define OP_ToBlob                             139   /* same as TK_TO_BLOB  */
-#define OP_ResultRow                           86
-#define OP_Delete                              89
-#define OP_AggFinal                            90
+#define OP_ResultRow                           90
+#define OP_Delete                              91
+#define OP_AggFinal                            92
+#define OP_Compare                             93
 #define OP_ShiftLeft                           76   /* same as TK_LSHIFT   */
-#define OP_Goto                                91
-#define OP_TableLock                           92
-#define OP_FifoRead                            93
-#define OP_Clear                               94
-#define OP_MoveLt                              95
+#define OP_Goto                                94
+#define OP_TableLock                           95
+#define OP_FifoRead                            96
+#define OP_Clear                               97
+#define OP_MoveLt                              98
 #define OP_Le                                  70   /* same as TK_LE       */
-#define OP_VerifyCookie                        96
-#define OP_AggStep                             97
+#define OP_VerifyCookie                        99
+#define OP_AggStep                            100
 #define OP_ToText                             138   /* same as TK_TO_TEXT  */
 #define OP_Not                                 16   /* same as TK_NOT      */
 #define OP_ToReal                             142   /* same as TK_TO_REAL  */
-#define OP_SetNumColumns                       98
-#define OP_Transaction                         99
-#define OP_VFilter                            100
+#define OP_SetNumColumns                      101
+#define OP_Transaction                        102
+#define OP_VFilter                            103
 #define OP_Ne                                  67   /* same as TK_NE       */
-#define OP_VDestroy                           101
-#define OP_ContextPop                         102
+#define OP_VDestroy                           104
+#define OP_ContextPop                         105
 #define OP_BitOr                               75   /* same as TK_BITOR    */
-#define OP_Next                               103
-#define OP_IdxInsert                          104
+#define OP_Next                               106
+#define OP_IdxInsert                          107
 #define OP_Lt                                  71   /* same as TK_LT       */
-#define OP_Insert                             105
-#define OP_Destroy                            106
-#define OP_ReadCookie                         107
-#define OP_ForceInt                           108
-#define OP_LoadAnalysis                       109
-#define OP_Explain                            110
-#define OP_OpenPseudo                         111
-#define OP_OpenEphemeral                      112
-#define OP_Null                               113
-#define OP_Move                               114
-#define OP_Blob                               115
+#define OP_Insert                             108
+#define OP_Destroy                            109
+#define OP_ReadCookie                         110
+#define OP_ForceInt                           111
+#define OP_LoadAnalysis                       112
+#define OP_Explain                            113
+#define OP_OpenPseudo                         114
+#define OP_OpenEphemeral                      115
+#define OP_Null                               116
+#define OP_Move                               117
+#define OP_Blob                               118
 #define OP_Add                                 78   /* same as TK_PLUS     */
-#define OP_Rewind                             116
-#define OP_MoveGe                             117
-#define OP_VBegin                             118
-#define OP_VUpdate                            119
-#define OP_IfZero                             120
+#define OP_Rewind                             119
+#define OP_MoveGe                             120
+#define OP_VBegin                             121
+#define OP_VUpdate                            122
+#define OP_IfZero                             123
 #define OP_BitNot                              87   /* same as TK_BITNOT   */
-#define OP_VCreate                            121
-#define OP_Found                              122
-#define OP_IfPos                              123
-#define OP_NullRow                            124
+#define OP_VCreate                            124
+#define OP_Found                              126
+#define OP_IfPos                              127
+#define OP_NullRow                            128
+#define OP_Jump                               129
+#define OP_Permutation                        130
 
 /* The following opcode values are never used */
-#define OP_NotUsed_126                        126
-#define OP_NotUsed_127                        127
-#define OP_NotUsed_128                        128
-#define OP_NotUsed_129                        129
-#define OP_NotUsed_130                        130
 #define OP_NotUsed_131                        131
 #define OP_NotUsed_132                        132
 #define OP_NotUsed_133                        133
@@ -7086,21 +7633,21 @@
 #define OPFLG_INITIALIZER {\
 /*   0 */ 0x00, 0x01, 0x00, 0x00, 0x10, 0x02, 0x11, 0x00,\
 /*   8 */ 0x00, 0x00, 0x05, 0x02, 0x00, 0x00, 0x00, 0x00,\
-/*  16 */ 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05, 0x00,\
-/*  24 */ 0x00, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00, 0x00,\
-/*  32 */ 0x00, 0x02, 0x11, 0x11, 0x02, 0x05, 0x00, 0x02,\
-/*  40 */ 0x11, 0x04, 0x00, 0x00, 0x0c, 0x11, 0x01, 0x02,\
-/*  48 */ 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00, 0x04,\
-/*  56 */ 0x00, 0x00, 0x00, 0x11, 0x2c, 0x2c, 0x00, 0x00,\
-/*  64 */ 0x11, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
-/*  72 */ 0x15, 0x05, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\
-/*  80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x00, 0x00, 0x00, 0x04,\
-/*  88 */ 0x02, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x11,\
-/*  96 */ 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x01,\
-/* 104 */ 0x08, 0x00, 0x02, 0x02, 0x05, 0x00, 0x00, 0x00,\
-/* 112 */ 0x00, 0x02, 0x00, 0x02, 0x01, 0x11, 0x00, 0x00,\
-/* 120 */ 0x05, 0x00, 0x11, 0x05, 0x00, 0x02, 0x00, 0x00,\
-/* 128 */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
+/*  16 */ 0x04, 0x02, 0x00, 0x01, 0x00, 0x00, 0x00, 0x05,\
+/*  24 */ 0x00, 0x04, 0x02, 0x02, 0x02, 0x04, 0x00, 0x00,\
+/*  32 */ 0x00, 0x00, 0x02, 0x11, 0x11, 0x02, 0x05, 0x00,\
+/*  40 */ 0x02, 0x11, 0x04, 0x00, 0x00, 0x0c, 0x11, 0x01,\
+/*  48 */ 0x02, 0x01, 0x00, 0x02, 0x01, 0x01, 0x02, 0x00,\
+/*  56 */ 0x04, 0x00, 0x00, 0x00, 0x2c, 0x2c, 0x00, 0x11,\
+/*  64 */ 0x00, 0x05, 0x05, 0x15, 0x15, 0x15, 0x15, 0x15,\
+/*  72 */ 0x15, 0x00, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c, 0x2c,\
+/*  80 */ 0x2c, 0x2c, 0x2c, 0x2c, 0x11, 0x05, 0x00, 0x04,\
+/*  88 */ 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00,\
+/*  96 */ 0x01, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x01,\
+/* 104 */ 0x00, 0x00, 0x01, 0x08, 0x00, 0x02, 0x02, 0x05,\
+/* 112 */ 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x02, 0x01,\
+/* 120 */ 0x11, 0x00, 0x00, 0x05, 0x00, 0x02, 0x11, 0x05,\
+/* 128 */ 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\
 /* 136 */ 0x00, 0x00, 0x04, 0x04, 0x04, 0x04, 0x04,}
 
 /************** End of opcodes.h *********************************************/
@@ -7155,8 +7702,11 @@
 #ifndef NDEBUG
 SQLITE_PRIVATE   void sqlite3VdbeComment(Vdbe*, const char*, ...);
 # define VdbeComment(X)  sqlite3VdbeComment X
+SQLITE_PRIVATE   void sqlite3VdbeNoopComment(Vdbe*, const char*, ...);
+# define VdbeNoopComment(X)  sqlite3VdbeNoopComment X
 #else
 # define VdbeComment(X)
+# define VdbeNoopComment(X)
 #endif
 
 #endif
@@ -7180,17 +7730,25 @@
 ** subsystem.  The page cache subsystem reads and writes a file a page
 ** at a time and provides a journal for rollback.
 **
-** @(#) $Id: pager.h,v 1.72 2008/05/01 17:03:49 drh Exp $
+** @(#) $Id: pager.h,v 1.76 2008/06/07 08:58:22 danielk1977 Exp $
 */
 
 #ifndef _PAGER_H_
 #define _PAGER_H_
 
 /*
+** If defined as non-zero, auto-vacuum is enabled by default. Otherwise
+** it must be turned on for each database using "PRAGMA auto_vacuum = 1".
+*/
+#ifndef SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT
+  #define SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT -1
+#endif
+
+/*
 ** The type used to represent a page number.  The first page in a file
 ** is called page 1.  0 is used to represent "not a page".
 */
-typedef unsigned int Pgno;
+typedef u32 Pgno;
 
 /*
 ** Each open file is managed by a separate instance of the "Pager" structure.
@@ -7244,7 +7802,7 @@
 SQLITE_PRIVATE int sqlite3PagerRef(DbPage*);
 SQLITE_PRIVATE int sqlite3PagerUnref(DbPage*);
 SQLITE_PRIVATE int sqlite3PagerWrite(DbPage*);
-SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*);
+SQLITE_PRIVATE int sqlite3PagerPagecount(Pager*, int*);
 SQLITE_PRIVATE int sqlite3PagerTruncate(Pager*,Pgno);
 SQLITE_PRIVATE int sqlite3PagerBegin(DbPage*, int exFlag);
 SQLITE_PRIVATE int sqlite3PagerCommitPhaseOne(Pager*,const char *zMaster, Pgno, int);
@@ -7269,6 +7827,7 @@
 SQLITE_PRIVATE void *sqlite3PagerGetExtra(DbPage *); 
 SQLITE_PRIVATE int sqlite3PagerLockingMode(Pager *, int);
 SQLITE_PRIVATE int sqlite3PagerJournalMode(Pager *, int);
+SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *, i64);
 SQLITE_PRIVATE void *sqlite3PagerTempSpace(Pager*);
 SQLITE_PRIVATE int sqlite3PagerSync(Pager *pPager);
 
@@ -7288,6 +7847,7 @@
 #ifdef SQLITE_TEST
 SQLITE_PRIVATE   int *sqlite3PagerStats(Pager*);
 SQLITE_PRIVATE   void sqlite3PagerRefdump(Pager*);
+SQLITE_PRIVATE   int sqlite3PagerIsMemdb(Pager*);
 #endif
 
 #ifdef SQLITE_TEST
@@ -7323,6 +7883,8 @@
 **
 ** This header file is #include-ed by sqliteInt.h and thus ends up
 ** being included by every source file.
+**
+** $Id: os.h,v 1.105 2008/06/26 10:41:19 danielk1977 Exp $
 */
 #ifndef _SQLITE_OS_H_
 #define _SQLITE_OS_H_
@@ -7330,56 +7892,66 @@
 /*
 ** Figure out if we are dealing with Unix, Windows, or some other
 ** operating system.  After the following block of preprocess macros,
-** all of OS_UNIX, OS_WIN, OS_OS2, and OS_OTHER will defined to either
-** 1 or 0.  One of the four will be 1.  The other three will be 0.
-*/
-#if defined(OS_OTHER)
-# if OS_OTHER==1
-#   undef OS_UNIX
-#   define OS_UNIX 0
-#   undef OS_WIN
-#   define OS_WIN 0
-#   undef OS_OS2
-#   define OS_OS2 0
+** all of SQLITE_OS_UNIX, SQLITE_OS_WIN, SQLITE_OS_OS2, and SQLITE_OS_OTHER 
+** will defined to either 1 or 0.  One of the four will be 1.  The other 
+** three will be 0.
+*/
+#if defined(SQLITE_OS_OTHER)
+# if SQLITE_OS_OTHER==1
+#   undef SQLITE_OS_UNIX
+#   define SQLITE_OS_UNIX 0
+#   undef SQLITE_OS_WIN
+#   define SQLITE_OS_WIN 0
+#   undef SQLITE_OS_OS2
+#   define SQLITE_OS_OS2 0
 # else
-#   undef OS_OTHER
+#   undef SQLITE_OS_OTHER
 # endif
 #endif
-#if !defined(OS_UNIX) && !defined(OS_OTHER)
-# define OS_OTHER 0
-# ifndef OS_WIN
+#if !defined(SQLITE_OS_UNIX) && !defined(SQLITE_OS_OTHER)
+# define SQLITE_OS_OTHER 0
+# ifndef SQLITE_OS_WIN
 #   if defined(_WIN32) || defined(WIN32) || defined(__CYGWIN__) || defined(__MINGW32__) || defined(__BORLANDC__)
-#     define OS_WIN 1
-#     define OS_UNIX 0
-#     define OS_OS2 0
+#     define SQLITE_OS_WIN 1
+#     define SQLITE_OS_UNIX 0
+#     define SQLITE_OS_OS2 0
 #   elif defined(__EMX__) || defined(_OS2) || defined(OS2) || defined(_OS2_) || defined(__OS2__)
-#     define OS_WIN 0
-#     define OS_UNIX 0
-#     define OS_OS2 1
+#     define SQLITE_OS_WIN 0
+#     define SQLITE_OS_UNIX 0
+#     define SQLITE_OS_OS2 1
 #   else
-#     define OS_WIN 0
-#     define OS_UNIX 1
-#     define OS_OS2 0
+#     define SQLITE_OS_WIN 0
+#     define SQLITE_OS_UNIX 1
+#     define SQLITE_OS_OS2 0
 #  endif
 # else
-#  define OS_UNIX 0
-#  define OS_OS2 0
+#  define SQLITE_OS_UNIX 0
+#  define SQLITE_OS_OS2 0
 # endif
 #else
-# ifndef OS_WIN
-#  define OS_WIN 0
+# ifndef SQLITE_OS_WIN
+#  define SQLITE_OS_WIN 0
 # endif
 #endif
 
+/*
+** Determine if we are dealing with WindowsCE - which has a much
+** reduced API.
+*/
+#if defined(_WIN32_WCE)
+# define SQLITE_OS_WINCE 1
+#else
+# define SQLITE_OS_WINCE 0
+#endif
 
 
 /*
 ** Define the maximum size of a temporary filename
 */
-#if OS_WIN
+#if SQLITE_OS_WIN
 # include <windows.h>
 # define SQLITE_TEMPNAME_SIZE (MAX_PATH+50)
-#elif OS_OS2
+#elif SQLITE_OS_OS2
 # if (__GNUC__ > 3 || __GNUC__ == 3 && __GNUC_MINOR__ >= 3) && defined(OS2_HIGH_MEMORY)
 #  include <os2safe.h> /* has to be included before os2.h for linking to work */
 # endif
@@ -7538,7 +8110,7 @@
 SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file*, i64 *pSize);
 SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file*, int);
 SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file*, int);
-SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id);
+SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut);
 SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file*,int,void*);
 SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id);
 SQLITE_PRIVATE int sqlite3OsDeviceCharacteristics(sqlite3_file *id);
@@ -7548,13 +8120,14 @@
 */
 SQLITE_PRIVATE int sqlite3OsOpen(sqlite3_vfs *, const char *, sqlite3_file*, int, int *);
 SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *, const char *, int);
-SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int);
-SQLITE_PRIVATE int sqlite3OsGetTempname(sqlite3_vfs *, int, char *);
+SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *, const char *, int, int *pResOut);
 SQLITE_PRIVATE int sqlite3OsFullPathname(sqlite3_vfs *, const char *, int, char *);
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
 SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *, const char *);
 SQLITE_PRIVATE void sqlite3OsDlError(sqlite3_vfs *, int, char *);
 SQLITE_PRIVATE void *sqlite3OsDlSym(sqlite3_vfs *, void *, const char *);
 SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *, void *);
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
 SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *, int, char *);
 SQLITE_PRIVATE int sqlite3OsSleep(sqlite3_vfs *, int);
 SQLITE_PRIVATE int sqlite3OsCurrentTime(sqlite3_vfs *, double*);
@@ -7566,16 +8139,6 @@
 SQLITE_PRIVATE int sqlite3OsOpenMalloc(sqlite3_vfs *, const char *, sqlite3_file **, int,int*);
 SQLITE_PRIVATE int sqlite3OsCloseFree(sqlite3_file *);
 
-/*
-** Each OS-specific backend defines an instance of the following
-** structure for returning a pointer to its sqlite3_vfs.  If OS_OTHER
-** is defined (meaning that the application-defined OS interface layer
-** is used) then there is no default VFS.   The application must
-** register one or more VFS structures using sqlite3_vfs_register()
-** before attempting to use SQLite.
-*/
-SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void);
-
 #endif /* _SQLITE_OS_H_ */
 
 /************** End of os.h **************************************************/
@@ -7603,7 +8166,7 @@
 ** Source files should #include the sqliteInt.h file and let that file
 ** include this one indirectly.
 **
-** $Id: mutex.h,v 1.2 2007/08/30 14:10:30 drh Exp $
+** $Id: mutex.h,v 1.8 2008/06/26 10:41:19 danielk1977 Exp $
 */
 
 
@@ -7637,15 +8200,15 @@
 # undef SQLITE_MUTEX_NOOP
 # define SQLITE_MUTEX_NOOP_DEBUG
 #endif
-#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_UNIX
+#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && SQLITE_OS_UNIX
 # undef SQLITE_MUTEX_NOOP
 # define SQLITE_MUTEX_PTHREADS
 #endif
-#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_WIN
+#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && SQLITE_OS_WIN
 # undef SQLITE_MUTEX_NOOP
 # define SQLITE_MUTEX_W32
 #endif
-#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && OS_OS2
+#if defined(SQLITE_MUTEX_NOOP) && SQLITE_THREADSAFE && SQLITE_OS_OS2
 # undef SQLITE_MUTEX_NOOP
 # define SQLITE_MUTEX_OS2
 #endif
@@ -7661,6 +8224,9 @@
 #define sqlite3_mutex_leave(X)
 #define sqlite3_mutex_held(X)     1
 #define sqlite3_mutex_notheld(X)  1
+#define sqlite3MutexAlloc(X)      ((sqlite3_mutex*)8)
+#define sqlite3MutexInit()        SQLITE_OK
+#define sqlite3MutexEnd()
 #endif
 
 #endif /* SQLITE_MUTEX_APPDEF */
@@ -8027,8 +8593,7 @@
 ** changing the affinity.
 */
 #define SQLITE_JUMPIFNULL   0x08  /* jumps if either operand is NULL */
-#define SQLITE_NULLEQUAL    0x10  /* compare NULLs equal */
-#define SQLITE_STOREP2      0x80  /* Store result in reg[P2] rather than jump */
+#define SQLITE_STOREP2      0x10  /* Store result in reg[P2] rather than jump */
 
 /*
 ** Each SQL table is represented in memory by an instance of the
@@ -8371,8 +8936,7 @@
   Select *pSelect;       /* When the expression is a sub-select.  Also the
                          ** right side of "<expr> IN (<select>)" */
   Table *pTab;           /* Table for OP_Column expressions. */
-/*  Schema *pSchema; */
-#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
+#if SQLITE_MAX_EXPR_DEPTH>0
   int nHeight;           /* Height of the tree headed by this node */
 #endif
 };
@@ -8391,7 +8955,7 @@
 #define EP_ExpCollate 0x0100  /* Collating sequence specified explicitly */
 #define EP_AnyAff     0x0200  /* Can take a cached column of any affinity */
 #define EP_FixedDest  0x0400  /* Result needed in a specific register */
-
+#define EP_IntValue   0x0800  /* Integer value contained in iTable */
 /*
 ** These macros can be used to test, set, or clear bits in the 
 ** Expr.flags field.
@@ -8665,10 +9229,10 @@
 
 #define SRT_Callback     5  /* Invoke a callback with each row of result */
 #define SRT_Mem          6  /* Store result in a memory cell */
-#define SRT_Set          7  /* Store non-null results as keys in an index */
+#define SRT_Set          7  /* Store results as keys in an index */
 #define SRT_Table        8  /* Store result as data with an automatic rowid */
 #define SRT_EphemTab     9  /* Create transient tab and store like SRT_Table */
-#define SRT_Subroutine  10  /* Call a subroutine to handle results */
+#define SRT_Coroutine   10  /* Generate a single row of result */
 
 /*
 ** A structure used to customize the behaviour of sqlite3Select(). See
@@ -8762,9 +9326,7 @@
   int nVtabLock;             /* Number of virtual tables to lock */
   Table **apVtabLock;        /* Pointer to virtual tables needing locking */
 #endif
-#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
   int nHeight;            /* Expression tree height of current sub-select */
-#endif
 };
 
 #ifdef SQLITE_OMIT_VIRTUALTABLE
@@ -8963,6 +9525,32 @@
 } InitData;
 
 /*
+** Structure containing global configuration data for the SQLite library.
+**
+** This structure also contains some state information.
+*/
+struct Sqlite3Config {
+  int bMemstat;                     /* True to enable memory status */
+  int bCoreMutex;                   /* True to enable core mutexing */
+  int bFullMutex;                   /* True to enable full mutexing */
+  int mxStrlen;                     /* Maximum string length */
+  sqlite3_mem_methods m;            /* Low-level memory allocation interface */
+  sqlite3_mutex_methods mutex;      /* Low-level mutex interface */
+  void *pHeap;                      /* Heap storage space */
+  int nHeap;                        /* Size of pHeap[] */
+  int mnReq, mxReq;                 /* Min and max heap requests sizes */
+  void *pScratch;                   /* Scratch memory */
+  int szScratch;                    /* Size of each scratch buffer */
+  int nScratch;                     /* Number of scratch buffers */
+  void *pPage;                      /* Page cache memory */
+  int szPage;                       /* Size of each page in pPage[] */
+  int nPage;                        /* Number of pages in pPage[] */
+  int isInit;                       /* True after initialization has finished */
+  int isMallocInit;                 /* True after malloc is initialized */
+  sqlite3_mutex *pInitMutex;        /* Mutex used by sqlite3_initialize() */
+};
+
+/*
 ** Assuming zIn points to the first byte of a UTF-8 character,
 ** advance zIn to point to the first byte of the next UTF-8 character.
 */
@@ -8981,10 +9569,8 @@
 #ifdef SQLITE_DEBUG
 SQLITE_PRIVATE   int sqlite3Corrupt(void);
 # define SQLITE_CORRUPT_BKPT sqlite3Corrupt()
-# define DEBUGONLY(X)        X
 #else
 # define SQLITE_CORRUPT_BKPT SQLITE_CORRUPT
-# define DEBUGONLY(X)
 #endif
 
 /*
@@ -8993,29 +9579,55 @@
 SQLITE_PRIVATE int sqlite3StrICmp(const char *, const char *);
 SQLITE_PRIVATE int sqlite3StrNICmp(const char *, const char *, int);
 SQLITE_PRIVATE int sqlite3IsNumber(const char*, int*, u8);
+SQLITE_PRIVATE int sqlite3Strlen(sqlite3*, const char*);
 
-SQLITE_PRIVATE void *sqlite3MallocZero(unsigned);
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, unsigned);
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, unsigned);
+SQLITE_PRIVATE int sqlite3MallocInit(void);
+SQLITE_PRIVATE void sqlite3MallocEnd(void);
+SQLITE_PRIVATE void *sqlite3Malloc(int);
+SQLITE_PRIVATE void *sqlite3MallocZero(int);
+SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3*, int);
+SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3*, int);
 SQLITE_PRIVATE char *sqlite3StrDup(const char*);
 SQLITE_PRIVATE char *sqlite3StrNDup(const char*, int);
 SQLITE_PRIVATE char *sqlite3DbStrDup(sqlite3*,const char*);
 SQLITE_PRIVATE char *sqlite3DbStrNDup(sqlite3*,const char*, int);
+SQLITE_PRIVATE void *sqlite3Realloc(void*, int);
 SQLITE_PRIVATE void *sqlite3DbReallocOrFree(sqlite3 *, void *, int);
 SQLITE_PRIVATE void *sqlite3DbRealloc(sqlite3 *, void *, int);
 SQLITE_PRIVATE int sqlite3MallocSize(void *);
+SQLITE_PRIVATE void *sqlite3ScratchMalloc(int);
+SQLITE_PRIVATE void sqlite3ScratchFree(void*);
+SQLITE_PRIVATE void *sqlite3PageMalloc(int);
+SQLITE_PRIVATE void sqlite3PageFree(void*);
+SQLITE_PRIVATE void sqlite3MemSetDefault(void);
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void);
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void);
+SQLITE_PRIVATE void sqlite3BenignMallocHooks(void (*)(void), void (*)(void));
+
+#ifndef SQLITE_MUTEX_NOOP
+SQLITE_PRIVATE   sqlite3_mutex_methods *sqlite3DefaultMutex(void);
+SQLITE_PRIVATE   sqlite3_mutex *sqlite3MutexAlloc(int);
+SQLITE_PRIVATE   int sqlite3MutexInit(void);
+SQLITE_PRIVATE   int sqlite3MutexEnd(void);
+#endif
+
+SQLITE_PRIVATE void sqlite3StatusReset(void);
+SQLITE_PRIVATE int sqlite3StatusValue(int);
+SQLITE_PRIVATE void sqlite3StatusAdd(int, int);
+SQLITE_PRIVATE void sqlite3StatusSet(int, int);
 
 SQLITE_PRIVATE int sqlite3IsNaN(double);
 
+SQLITE_PRIVATE void sqlite3VXPrintf(StrAccum*, int, const char*, va_list);
 SQLITE_PRIVATE char *sqlite3MPrintf(sqlite3*,const char*, ...);
 SQLITE_PRIVATE char *sqlite3VMPrintf(sqlite3*,const char*, va_list);
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
 SQLITE_PRIVATE   void sqlite3DebugPrintf(const char*, ...);
 #endif
 #if defined(SQLITE_TEST)
-SQLITE_PRIVATE   void *sqlite3TextToPtr(const char*);
+SQLITE_PRIVATE   void *sqlite3TestTextToPtr(const char*);
 #endif
-SQLITE_PRIVATE void sqlite3SetString(char **, ...);
+SQLITE_PRIVATE void sqlite3SetString(char **, sqlite3*, const char*, ...);
 SQLITE_PRIVATE void sqlite3ErrorMsg(Parse*, const char*, ...);
 SQLITE_PRIVATE void sqlite3ErrorClear(Parse*);
 SQLITE_PRIVATE void sqlite3Dequote(char*);
@@ -9086,7 +9698,7 @@
 SQLITE_PRIVATE void sqlite3CreateIndex(Parse*,Token*,Token*,SrcList*,ExprList*,int,Token*,
                         Token*, int, int);
 SQLITE_PRIVATE void sqlite3DropIndex(Parse*, SrcList*, int);
-SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*, Select*, int, int*, char *aff);
+SQLITE_PRIVATE int sqlite3Select(Parse*, Select*, SelectDest*, Select*, int, int*);
 SQLITE_PRIVATE Select *sqlite3SelectNew(Parse*,ExprList*,SrcList*,Expr*,ExprList*,
                          Expr*,ExprList*,int,Expr*,Expr*);
 SQLITE_PRIVATE void sqlite3SelectDelete(Select*);
@@ -9098,7 +9710,8 @@
 SQLITE_PRIVATE WhereInfo *sqlite3WhereBegin(Parse*, SrcList*, Expr*, ExprList**, u8);
 SQLITE_PRIVATE void sqlite3WhereEnd(WhereInfo*);
 SQLITE_PRIVATE int sqlite3ExprCodeGetColumn(Parse*, Table*, int, int, int, int);
-SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int);
+SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse*, int, int, int);
+SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse*, int, int, int);
 SQLITE_PRIVATE void sqlite3ExprClearColumnCache(Parse*, int);
 SQLITE_PRIVATE void sqlite3ExprCacheAffinityChange(Parse*, int, int);
 SQLITE_PRIVATE int sqlite3ExprWritableRegister(Parse*,int,int);
@@ -9291,6 +9904,7 @@
 SQLITE_PRIVATE void sqlite3ValueApplyAffinity(sqlite3_value *, u8, u8);
 #ifndef SQLITE_AMALGAMATION
 SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[];
+SQLITE_PRIVATE struct Sqlite3Config sqlite3Config;
 #endif
 SQLITE_PRIVATE void sqlite3RootPageMoved(Db*, int, int);
 SQLITE_PRIVATE void sqlite3Reindex(Parse*, Token*, Token*);
@@ -9299,7 +9913,7 @@
 SQLITE_PRIVATE int sqlite3GetToken(const unsigned char *, int *);
 SQLITE_PRIVATE void sqlite3NestedParse(Parse*, const char*, ...);
 SQLITE_PRIVATE void sqlite3ExpirePreparedStatements(sqlite3*);
-SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *, Expr *);
+SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *, Expr *, int);
 SQLITE_PRIVATE int sqlite3SelectResolve(Parse *, Select *, NameContext *);
 SQLITE_PRIVATE void sqlite3ColumnDefault(Vdbe *, Table *, int);
 SQLITE_PRIVATE void sqlite3AlterFinishAddColumn(Parse *, Token *);
@@ -9325,6 +9939,7 @@
 SQLITE_PRIVATE int sqlite3ApiExit(sqlite3 *db, int);
 SQLITE_PRIVATE int sqlite3OpenTempDatabase(Parse *);
 
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum*, char*, int, int);
 SQLITE_PRIVATE void sqlite3StrAccumAppend(StrAccum*,const char*,int);
 SQLITE_PRIVATE char *sqlite3StrAccumFinish(StrAccum*);
 SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum*);
@@ -9390,34 +10005,22 @@
 #define SQLITE_FAULTINJECTOR_COUNT      1
 
 /*
-** The interface to the fault injector subsystem.  If the fault injector
-** mechanism is disabled at compile-time then set up macros so that no
-** unnecessary code is generated.
+** The interface to the code in fault.c used for identifying "benign"
+** malloc failures. This is only present if SQLITE_OMIT_BUILTIN_TEST
+** is not defined.
 */
 #ifndef SQLITE_OMIT_BUILTIN_TEST
-SQLITE_PRIVATE   void sqlite3FaultConfig(int,int,int);
-SQLITE_PRIVATE   int sqlite3FaultFailures(int);
-SQLITE_PRIVATE   int sqlite3FaultBenignFailures(int);
-SQLITE_PRIVATE   int sqlite3FaultPending(int);
-SQLITE_PRIVATE   void sqlite3FaultBeginBenign(int);
-SQLITE_PRIVATE   void sqlite3FaultEndBenign(int);
-SQLITE_PRIVATE   int sqlite3FaultStep(int);
+SQLITE_PRIVATE   void sqlite3BeginBenignMalloc(void);
+SQLITE_PRIVATE   void sqlite3EndBenignMalloc(void);
 #else
-# define sqlite3FaultConfig(A,B,C)
-# define sqlite3FaultFailures(A)         0
-# define sqlite3FaultBenignFailures(A)   0
-# define sqlite3FaultPending(A)          (-1)
-# define sqlite3FaultBeginBenign(A)
-# define sqlite3FaultEndBenign(A)
-# define sqlite3FaultStep(A)             0
+  #define sqlite3BeginBenignMalloc()
+  #define sqlite3EndBenignMalloc()
 #endif
-  
-  
 
 #define IN_INDEX_ROWID           1
 #define IN_INDEX_EPH             2
 #define IN_INDEX_INDEX           3
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int);
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *, Expr *, int*);
 
 #ifdef SQLITE_ENABLE_ATOMIC_WRITE
 SQLITE_PRIVATE   int sqlite3JournalOpen(sqlite3_vfs *, const char *, sqlite3_file *, int, int);
@@ -9427,11 +10030,12 @@
   #define sqlite3JournalSize(pVfs) ((pVfs)->szOsFile)
 #endif
 
-#if defined(SQLITE_TEST) || SQLITE_MAX_EXPR_DEPTH>0
-SQLITE_PRIVATE   void sqlite3ExprSetHeight(Expr *);
+#if SQLITE_MAX_EXPR_DEPTH>0
+SQLITE_PRIVATE   void sqlite3ExprSetHeight(Parse *pParse, Expr *p);
 SQLITE_PRIVATE   int sqlite3SelectExprHeight(Select *);
 #else
-  #define sqlite3ExprSetHeight(x)
+  #define sqlite3ExprSetHeight(x,y)
+  #define sqlite3SelectExprHeight(x) 0
 #endif
 
 SQLITE_PRIVATE u32 sqlite3Get4byte(const u8*);
@@ -9462,6 +10066,164 @@
 #endif
 
 /************** End of sqliteInt.h *******************************************/
+/************** Begin file global.c ******************************************/
+/*
+** 2008 June 13
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+**
+** This file contains definitions of global variables and contants.
+**
+** $Id: global.c,v 1.3 2008/07/08 14:52:10 drh Exp $
+*/
+
+
+/* An array to map all upper-case characters into their corresponding
+** lower-case character. 
+**
+** SQLite only considers US-ASCII (or EBCDIC) characters.  We do not
+** handle case conversions for the UTF character set since the tables
+** involved are nearly as big or bigger than SQLite itself.
+*/
+SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
+#ifdef SQLITE_ASCII
+      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
+     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
+     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
+     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
+    104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
+    122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
+    108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
+    126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
+    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
+    162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
+    180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
+    198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
+    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
+    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
+    252,253,254,255
+#endif
+#ifdef SQLITE_EBCDIC
+      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 0x */
+     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
+     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
+     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
+     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
+     80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
+     96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
+    112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
+    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
+    144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
+    160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
+    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
+    192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
+    208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
+    224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
+    239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
+#endif
+};
+
+/*
+** The following singleton contains the global configuration for
+** the SQLite library.
+*/
+SQLITE_PRIVATE struct Sqlite3Config sqlite3Config = { 1, 1, 1, 0x7ffffffe };
+
+/************** End of global.c **********************************************/
+/************** Begin file status.c ******************************************/
+/*
+** 2008 June 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 module implements the sqlite3_status() interface and related
+** functionality.
+**
+** $Id: status.c,v 1.3 2008/07/11 16:15:18 drh Exp $
+*/
+
+/*
+** Variables in which to record status information.
+*/
+static struct {
+  int nowValue[6];         /* Current value */
+  int mxValue[6];          /* Maximum value */
+} sqlite3Stat;
+
+
+/*
+** Reset the status records.  This routine is called by
+** sqlite3_initialize().
+*/
+SQLITE_PRIVATE void sqlite3StatusReset(void){
+  memset(&sqlite3Stat, 0, sizeof(sqlite3Stat));
+}
+
+/*
+** Return the current value of a status parameter.
+*/
+SQLITE_PRIVATE int sqlite3StatusValue(int op){
+  assert( op>=0 && op<ArraySize(sqlite3Stat.nowValue) );
+  return sqlite3Stat.nowValue[op];
+}
+
+/*
+** Add N to the value of a status record.  It is assumed that the
+** caller holds appropriate locks.
+*/
+SQLITE_PRIVATE void sqlite3StatusAdd(int op, int N){
+  assert( op>=0 && op<ArraySize(sqlite3Stat.nowValue) );
+  sqlite3Stat.nowValue[op] += N;
+  if( sqlite3Stat.nowValue[op]>sqlite3Stat.mxValue[op] ){
+    sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op];
+  }
+}
+
+/*
+** Set the value of a status to X.
+*/
+SQLITE_PRIVATE void sqlite3StatusSet(int op, int X){
+  assert( op>=0 && op<ArraySize(sqlite3Stat.nowValue) );
+  sqlite3Stat.nowValue[op] = X;
+  if( sqlite3Stat.nowValue[op]>sqlite3Stat.mxValue[op] ){
+    sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op];
+  }
+}
+
+/*
+** Query status information.
+**
+** This implementation assumes that reading or writing an aligned
+** 32-bit integer is an atomic operation.  If that assumption is not true,
+** then this routine is not threadsafe.
+*/
+SQLITE_API int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag){
+  if( op<0 || op>=ArraySize(sqlite3Stat.nowValue) ){
+    return SQLITE_MISUSE;
+  }
+  *pCurrent = sqlite3Stat.nowValue[op];
+  *pHighwater = sqlite3Stat.mxValue[op];
+  if( resetFlag ){
+    sqlite3Stat.mxValue[op] = sqlite3Stat.nowValue[op];
+  }
+  return SQLITE_OK;
+}
+
+/************** End of status.c **********************************************/
 /************** Begin file date.c ********************************************/
 /*
 ** 2003 October 31
@@ -9481,7 +10243,7 @@
 ** sqlite3RegisterDateTimeFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: date.c,v 1.79 2008/03/20 14:03:29 drh Exp $
+** $Id: date.c,v 1.85 2008/06/18 17:09:10 danielk1977 Exp $
 **
 ** SQLite processes all times and dates as Julian Day numbers.  The
 ** dates and times are stored as the number of days since noon
@@ -9516,19 +10278,36 @@
 #ifndef SQLITE_OMIT_DATETIME_FUNCS
 
 /*
+** On recent Windows platforms, the localtime_s() function is available
+** as part of the "Secure CRT". It is essentially equivalent to 
+** localtime_r() available under most POSIX platforms, except that the 
+** order of the parameters is reversed.
+**
+** See http://msdn.microsoft.com/en-us/library/a442x3ye(VS.80).aspx.
+**
+** If the user has not indicated to use localtime_r() or localtime_s()
+** already, check for an MSVC build environment that provides 
+** localtime_s().
+*/
+#if !defined(HAVE_LOCALTIME_R) && !defined(HAVE_LOCALTIME_S) && \
+     defined(_MSC_VER) && defined(_CRT_INSECURE_DEPRECATE)
+#define HAVE_LOCALTIME_S 1
+#endif
+
+/*
 ** A structure for holding a single date and time.
 */
 typedef struct DateTime DateTime;
 struct DateTime {
-  double rJD;      /* The julian day number */
-  int Y, M, D;     /* Year, month, and day */
-  int h, m;        /* Hour and minutes */
-  int tz;          /* Timezone offset in minutes */
-  double s;        /* Seconds */
-  char validYMD;   /* True if Y,M,D are valid */
-  char validHMS;   /* True if h,m,s are valid */
-  char validJD;    /* True if rJD is valid */
-  char validTZ;    /* True if tz is valid */
+  sqlite3_int64 iJD; /* The julian day number times 86400000 */
+  int Y, M, D;       /* Year, month, and day */
+  int h, m;          /* Hour and minutes */
+  int tz;            /* Timezone offset in minutes */
+  double s;          /* Seconds */
+  char validYMD;     /* True if Y,M,D are valid */
+  char validHMS;     /* True if h,m,s are valid */
+  char validJD;      /* True if iJD is valid */
+  char validTZ;      /* True if tz is valid */
 };
 
 
@@ -9701,12 +10480,12 @@
   B = 2 - A + (A/4);
   X1 = 365.25*(Y+4716);
   X2 = 30.6001*(M+1);
-  p->rJD = X1 + X2 + D + B - 1524.5;
+  p->iJD = (X1 + X2 + D + B - 1524.5)*86400000;
   p->validJD = 1;
   if( p->validHMS ){
-    p->rJD += (p->h*3600.0 + p->m*60.0 + p->s)/86400.0;
+    p->iJD += p->h*3600000 + p->m*60000 + p->s*1000;
     if( p->validTZ ){
-      p->rJD -= p->tz*60/86400.0;
+      p->iJD -= p->tz*60000;
       p->validYMD = 0;
       p->validHMS = 0;
       p->validTZ = 0;
@@ -9759,6 +10538,17 @@
 }
 
 /*
+** Set the time to the current time reported by the VFS
+*/
+static void setDateTimeToCurrent(sqlite3_context *context, DateTime *p){
+  double r;
+  sqlite3 *db = sqlite3_context_db_handle(context);
+  sqlite3OsCurrentTime(db->pVfs, &r);
+  p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
+  p->validJD = 1;
+}
+
+/*
 ** Attempt to parse the given string into a Julian Day Number.  Return
 ** the number of errors.
 **
@@ -9779,20 +10569,17 @@
   const char *zDate, 
   DateTime *p
 ){
-  memset(p, 0, sizeof(*p));
   if( parseYyyyMmDd(zDate,p)==0 ){
     return 0;
   }else if( parseHhMmSs(zDate, p)==0 ){
     return 0;
   }else if( sqlite3StrICmp(zDate,"now")==0){
-    double r;
-    sqlite3 *db = sqlite3_context_db_handle(context);
-    sqlite3OsCurrentTime(db->pVfs, &r);
-    p->rJD = r;
-    p->validJD = 1;
+    setDateTimeToCurrent(context, p);
     return 0;
   }else if( sqlite3IsNumber(zDate, 0, SQLITE_UTF8) ){
-    getValue(zDate, &p->rJD);
+    double r;
+    getValue(zDate, &r);
+    p->iJD = (sqlite3_int64)(r*86400000.0 + 0.5);
     p->validJD = 1;
     return 0;
   }
@@ -9810,7 +10597,7 @@
     p->M = 1;
     p->D = 1;
   }else{
-    Z = p->rJD + 0.5;
+    Z = (p->iJD + 43200000)/86400000;
     A = (Z - 1867216.25)/36524.25;
     A = Z + 1 + A - (A/4);
     B = A + 1524;
@@ -9829,12 +10616,11 @@
 ** Compute the Hour, Minute, and Seconds from the julian day number.
 */
 static void computeHMS(DateTime *p){
-  int Z, s;
+  int s;
   if( p->validHMS ) return;
   computeJD(p);
-  Z = p->rJD + 0.5;
-  s = (p->rJD + 0.5 - Z)*86400000.0 + 0.5;
-  p->s = 0.001*s;
+  s = (p->iJD + 43200000) % 86400000;
+  p->s = s/1000.0;
   s = p->s;
   p->s -= s;
   p->h = s/3600;
@@ -9861,11 +10647,13 @@
   p->validTZ = 0;
 }
 
+#ifndef SQLITE_OMIT_LOCALTIME
 /*
-** Compute the difference (in days) between localtime and UTC (a.k.a. GMT)
+** Compute the difference (in milliseconds)
+** between localtime and UTC (a.k.a. GMT)
 ** for the time value p where p is in UTC.
 */
-static double localtimeOffset(DateTime *p){
+static int localtimeOffset(DateTime *p){
   DateTime x, y;
   time_t t;
   x = *p;
@@ -9884,7 +10672,7 @@
   x.tz = 0;
   x.validJD = 0;
   computeJD(&x);
-  t = (x.rJD-2440587.5)*86400.0 + 0.5;
+  t = x.iJD/1000 - 2440587.5*86400.0;
 #ifdef HAVE_LOCALTIME_R
   {
     struct tm sLocal;
@@ -9896,10 +10684,21 @@
     y.m = sLocal.tm_min;
     y.s = sLocal.tm_sec;
   }
+#elif defined(HAVE_LOCALTIME_S)
+  {
+    struct tm sLocal;
+    localtime_s(&sLocal, &t);
+    y.Y = sLocal.tm_year + 1900;
+    y.M = sLocal.tm_mon + 1;
+    y.D = sLocal.tm_mday;
+    y.h = sLocal.tm_hour;
+    y.m = sLocal.tm_min;
+    y.s = sLocal.tm_sec;
+  }
 #else
   {
     struct tm *pTm;
-    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
     pTm = localtime(&t);
     y.Y = pTm->tm_year + 1900;
     y.M = pTm->tm_mon + 1;
@@ -9907,7 +10706,7 @@
     y.h = pTm->tm_hour;
     y.m = pTm->tm_min;
     y.s = pTm->tm_sec;
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   }
 #endif
   y.validYMD = 1;
@@ -9915,8 +10714,9 @@
   y.validJD = 0;
   y.validTZ = 0;
   computeJD(&y);
-  return y.rJD - x.rJD;
+  return y.iJD - x.iJD;
 }
+#endif /* SQLITE_OMIT_LOCALTIME */
 
 /*
 ** Process a modifier to a date-time stamp.  The modifiers are
@@ -9950,6 +10750,7 @@
   }
   z[n] = 0;
   switch( z[0] ){
+#ifndef SQLITE_OMIT_LOCALTIME
     case 'l': {
       /*    localtime
       **
@@ -9958,30 +10759,31 @@
       */
       if( strcmp(z, "localtime")==0 ){
         computeJD(p);
-        p->rJD += localtimeOffset(p);
+        p->iJD += localtimeOffset(p);
         clearYMD_HMS_TZ(p);
         rc = 0;
       }
       break;
     }
+#endif
     case 'u': {
       /*
       **    unixepoch
       **
-      ** Treat the current value of p->rJD as the number of
+      ** Treat the current value of p->iJD as the number of
       ** seconds since 1970.  Convert to a real julian day number.
       */
       if( strcmp(z, "unixepoch")==0 && p->validJD ){
-        p->rJD = p->rJD/86400.0 + 2440587.5;
+        p->iJD = p->iJD/86400.0 + 2440587.5*86400000.0;
         clearYMD_HMS_TZ(p);
         rc = 0;
       }else if( strcmp(z, "utc")==0 ){
         double c1;
         computeJD(p);
         c1 = localtimeOffset(p);
-        p->rJD -= c1;
+        p->iJD -= c1;
         clearYMD_HMS_TZ(p);
-        p->rJD += c1 - localtimeOffset(p);
+        p->iJD += c1 - localtimeOffset(p);
         rc = 0;
       }
       break;
@@ -9996,15 +10798,14 @@
       */
       if( strncmp(z, "weekday ", 8)==0 && getValue(&z[8],&r)>0
                  && (n=r)==r && n>=0 && r<7 ){
-        int Z;
+        sqlite3_int64 Z;
         computeYMD_HMS(p);
         p->validTZ = 0;
         p->validJD = 0;
         computeJD(p);
-        Z = p->rJD + 1.5;
-        Z %= 7;
+        Z = ((p->iJD + 129600000)/86400000) % 7;
         if( Z>n ) Z -= 7;
-        p->rJD += n - Z;
+        p->iJD += (n - Z)*86400000;
         clearYMD_HMS_TZ(p);
         rc = 0;
       }
@@ -10060,18 +10861,18 @@
         */
         const char *z2 = z;
         DateTime tx;
-        int day;
+        sqlite3_int64 day;
         if( !isdigit(*(u8*)z2) ) z2++;
         memset(&tx, 0, sizeof(tx));
         if( parseHhMmSs(z2, &tx) ) break;
         computeJD(&tx);
-        tx.rJD -= 0.5;
-        day = (int)tx.rJD;
-        tx.rJD -= day;
-        if( z[0]=='-' ) tx.rJD = -tx.rJD;
+        tx.iJD -= 43200000;
+        day = tx.iJD/86400000;
+        tx.iJD -= day*86400000;
+        if( z[0]=='-' ) tx.iJD = -tx.iJD;
         computeJD(p);
         clearYMD_HMS_TZ(p);
-        p->rJD += tx.rJD;
+        p->iJD += tx.iJD;
         rc = 0;
         break;
       }
@@ -10083,13 +10884,13 @@
       computeJD(p);
       rc = 0;
       if( n==3 && strcmp(z,"day")==0 ){
-        p->rJD += r;
+        p->iJD += r*86400000.0 + 0.5;
       }else if( n==4 && strcmp(z,"hour")==0 ){
-        p->rJD += r/24.0;
+        p->iJD += r*(86400000.0/24.0) + 0.5;
       }else if( n==6 && strcmp(z,"minute")==0 ){
-        p->rJD += r/(24.0*60.0);
+        p->iJD += r*(86400000.0/(24.0*60.0)) + 0.5;
       }else if( n==6 && strcmp(z,"second")==0 ){
-        p->rJD += r/(24.0*60.0*60.0);
+        p->iJD += r*(86400000.0/(24.0*60.0*60.0)) + 0.5;
       }else if( n==5 && strcmp(z,"month")==0 ){
         int x, y;
         computeYMD_HMS(p);
@@ -10101,7 +10902,7 @@
         computeJD(p);
         y = r;
         if( y!=r ){
-          p->rJD += (r - y)*30.0;
+          p->iJD += (r - y)*30.0*86400000.0 + 0.5;
         }
       }else if( n==4 && strcmp(z,"year")==0 ){
         computeYMD_HMS(p);
@@ -10138,14 +10939,19 @@
 ){
   int i;
   const unsigned char *z;
-  static const unsigned char zDflt[] = "now";
+  int eType;
+  memset(p, 0, sizeof(*p));
   if( argc==0 ){
-    z = zDflt;
+    setDateTimeToCurrent(context, p);
+  }else if( (eType = sqlite3_value_type(argv[0]))==SQLITE_FLOAT
+                   || eType==SQLITE_INTEGER ){
+    p->iJD = sqlite3_value_double(argv[0])*86400000.0 + 0.5;
+    p->validJD = 1;
   }else{
     z = sqlite3_value_text(argv[0]);
-  }
-  if( !z || parseDateOrTime(context, (char*)z, p) ){
-    return 1;
+    if( !z || parseDateOrTime(context, (char*)z, p) ){
+      return 1;
+    }
   }
   for(i=1; i<argc; i++){
     if( (z = sqlite3_value_text(argv[i]))==0 || parseModifier((char*)z, p) ){
@@ -10174,7 +10980,7 @@
   DateTime x;
   if( isDate(context, argc, argv, &x)==0 ){
     computeJD(&x);
-    sqlite3_result_double(context, x.rJD);
+    sqlite3_result_double(context, x.iJD/86400000.0);
   }
 }
 
@@ -10306,7 +11112,7 @@
     sqlite3_result_error_toobig(context);
     return;
   }else{
-    z = sqlite3_malloc( n );
+    z = sqlite3Malloc( n );
     if( z==0 ){
       sqlite3_result_error_nomem(context);
       return;
@@ -10337,10 +11143,10 @@
           y.M = 1;
           y.D = 1;
           computeJD(&y);
-          nDay = x.rJD - y.rJD + 0.5;
+          nDay = (x.iJD - y.iJD)/86400000.0 + 0.5;
           if( zFmt[i]=='W' ){
             int wd;   /* 0=Monday, 1=Tuesday, ... 6=Sunday */
-            wd = ((int)(x.rJD+0.5)) % 7;
+            wd = ((x.iJD+43200000)/86400000) % 7;
             sqlite3_snprintf(3, &z[j],"%02d",(nDay+7-wd)/7);
             j += 2;
           }else{
@@ -10350,7 +11156,7 @@
           break;
         }
         case 'J': {
-          sqlite3_snprintf(20, &z[j],"%.16g",x.rJD);
+          sqlite3_snprintf(20, &z[j],"%.16g",x.iJD/86400000.0);
           j+=strlen(&z[j]);
           break;
         }
@@ -10358,12 +11164,12 @@
         case 'M':  sqlite3_snprintf(3, &z[j],"%02d",x.m); j+=2; break;
         case 's': {
           sqlite3_snprintf(30,&z[j],"%d",
-                           (int)((x.rJD-2440587.5)*86400.0 + 0.5));
+                           (int)(x.iJD/1000.0 - 210866760000.0));
           j += strlen(&z[j]);
           break;
         }
         case 'S':  sqlite3_snprintf(3,&z[j],"%02d",(int)x.s); j+=2; break;
-        case 'w':  z[j++] = (((int)(x.rJD+1.5)) % 7) + '0'; break;
+        case 'w':  z[j++] = (((x.iJD+129600000)/86400000) % 7) + '0'; break;
         case 'Y':  sqlite3_snprintf(5,&z[j],"%04d",x.Y); j+=strlen(&z[j]);break;
         default:   z[j++] = '%'; break;
       }
@@ -10449,10 +11255,10 @@
 #else
   {
     struct tm *pTm;
-    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
     pTm = gmtime(&t);
     strftime(zBuf, 20, zFormat, pTm);
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
   }
 #endif
 
@@ -10521,6 +11327,8 @@
 **
 ** This file contains OS interface code that is common to all
 ** architectures.
+**
+** $Id: os.c,v 1.119 2008/06/26 18:16:06 drh Exp $
 */
 #define _SQLITE_OS_C_ 1
 #undef _SQLITE_OS_C_
@@ -10542,9 +11350,9 @@
 **     sqlite3OsLock()
 **
 */
-#if defined(SQLITE_TEST) && (OS_WIN==0)
+#if defined(SQLITE_TEST) && (SQLITE_OS_WIN==0)
   #define DO_OS_MALLOC_TEST if (1) {            \
-    void *pTstAlloc = sqlite3_malloc(10);       \
+    void *pTstAlloc = sqlite3Malloc(10);       \
     if (!pTstAlloc) return SQLITE_IOERR_NOMEM;  \
     sqlite3_free(pTstAlloc);                    \
   }
@@ -10582,6 +11390,7 @@
   return id->pMethods->xSync(id, flags);
 }
 SQLITE_PRIVATE int sqlite3OsFileSize(sqlite3_file *id, i64 *pSize){
+  DO_OS_MALLOC_TEST;
   return id->pMethods->xFileSize(id, pSize);
 }
 SQLITE_PRIVATE int sqlite3OsLock(sqlite3_file *id, int lockType){
@@ -10591,11 +11400,12 @@
 SQLITE_PRIVATE int sqlite3OsUnlock(sqlite3_file *id, int lockType){
   return id->pMethods->xUnlock(id, lockType);
 }
-SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id){
-  return id->pMethods->xCheckReservedLock(id);
+SQLITE_PRIVATE int sqlite3OsCheckReservedLock(sqlite3_file *id, int *pResOut){
+  DO_OS_MALLOC_TEST;
+  return id->pMethods->xCheckReservedLock(id, pResOut);
 }
 SQLITE_PRIVATE int sqlite3OsFileControl(sqlite3_file *id, int op, void *pArg){
-  return id->pMethods->xFileControl(id,op,pArg);
+  return id->pMethods->xFileControl(id, op, pArg);
 }
 SQLITE_PRIVATE int sqlite3OsSectorSize(sqlite3_file *id){
   int (*xSectorSize)(sqlite3_file*) = id->pMethods->xSectorSize;
@@ -10622,18 +11432,14 @@
 SQLITE_PRIVATE int sqlite3OsDelete(sqlite3_vfs *pVfs, const char *zPath, int dirSync){
   return pVfs->xDelete(pVfs, zPath, dirSync);
 }
-SQLITE_PRIVATE int sqlite3OsAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
-  int rc;
-#ifdef SQLITE_TEST
-  void *pTstAlloc = sqlite3_malloc(10);
-  if (!pTstAlloc) return -1;
-  sqlite3_free(pTstAlloc);
-#endif
-  rc = pVfs->xAccess(pVfs, zPath, flags);
-  return rc;
-}
-SQLITE_PRIVATE int sqlite3OsGetTempname(sqlite3_vfs *pVfs, int nBufOut, char *zBufOut){
-  return pVfs->xGetTempname(pVfs, nBufOut, zBufOut);
+SQLITE_PRIVATE int sqlite3OsAccess(
+  sqlite3_vfs *pVfs, 
+  const char *zPath, 
+  int flags, 
+  int *pResOut
+){
+  DO_OS_MALLOC_TEST;
+  return pVfs->xAccess(pVfs, zPath, flags, pResOut);
 }
 SQLITE_PRIVATE int sqlite3OsFullPathname(
   sqlite3_vfs *pVfs, 
@@ -10643,6 +11449,7 @@
 ){
   return pVfs->xFullPathname(pVfs, zPath, nPathOut, zPathOut);
 }
+#ifndef SQLITE_OMIT_LOAD_EXTENSION
 SQLITE_PRIVATE void *sqlite3OsDlOpen(sqlite3_vfs *pVfs, const char *zPath){
   return pVfs->xDlOpen(pVfs, zPath);
 }
@@ -10655,6 +11462,7 @@
 SQLITE_PRIVATE void sqlite3OsDlClose(sqlite3_vfs *pVfs, void *pHandle){
   pVfs->xDlClose(pVfs, pHandle);
 }
+#endif /* SQLITE_OMIT_LOAD_EXTENSION */
 SQLITE_PRIVATE int sqlite3OsRandomness(sqlite3_vfs *pVfs, int nByte, char *zBufOut){
   return pVfs->xRandomness(pVfs, nByte, zBufOut);
 }
@@ -10674,7 +11482,7 @@
 ){
   int rc = SQLITE_NOMEM;
   sqlite3_file *pFile;
-  pFile = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile);
+  pFile = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile);
   if( pFile ){
     rc = sqlite3OsOpen(pVfs, zFile, pFile, flags, pOutFlags);
     if( rc!=SQLITE_OK ){
@@ -10694,9 +11502,7 @@
 }
 
 /*
-** The list of all registered VFS implementations.  This list is
-** initialized to the single VFS returned by sqlite3OsDefaultVfs()
-** upon the first call to sqlite3_vfs_find().
+** The list of all registered VFS implementations.
 */
 static sqlite3_vfs *vfsList = 0;
 
@@ -10705,16 +11511,18 @@
 ** first VFS on the list.
 */
 SQLITE_API sqlite3_vfs *sqlite3_vfs_find(const char *zVfs){
+  sqlite3_vfs *pVfs = 0;
 #ifndef SQLITE_MUTEX_NOOP
-  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+  sqlite3_mutex *mutex;
+#endif
+#ifndef SQLITE_OMIT_AUTOINIT
+  int rc = sqlite3_initialize();
+  if( rc ) return 0;
+#endif
+#ifndef SQLITE_MUTEX_NOOP
+  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
-  sqlite3_vfs *pVfs = 0;
-  static int isInit = 0;
   sqlite3_mutex_enter(mutex);
-  if( !isInit ){
-    vfsList = sqlite3OsDefaultVfs();
-    isInit = 1;
-  }
   for(pVfs = vfsList; pVfs; pVfs=pVfs->pNext){
     if( zVfs==0 ) break;
     if( strcmp(zVfs, pVfs->zName)==0 ) break;
@@ -10727,7 +11535,7 @@
 ** Unlink a VFS from the linked list
 */
 static void vfsUnlink(sqlite3_vfs *pVfs){
-  assert( sqlite3_mutex_held(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER)) );
+  assert( sqlite3_mutex_held(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER)) );
   if( pVfs==0 ){
     /* No-op */
   }else if( vfsList==pVfs ){
@@ -10749,10 +11557,12 @@
 ** true.
 */
 SQLITE_API int sqlite3_vfs_register(sqlite3_vfs *pVfs, int makeDflt){
-#ifndef SQLITE_MUTEX_NOOP
-  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+  sqlite3_mutex *mutex = 0;
+#ifndef SQLITE_OMIT_AUTOINIT
+  int rc = sqlite3_initialize();
+  if( rc ) return rc;
 #endif
-  sqlite3_vfs_find(0);  /* Make sure we are initialized */
+  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   sqlite3_mutex_enter(mutex);
   vfsUnlink(pVfs);
   if( makeDflt || vfsList==0 ){
@@ -10772,7 +11582,7 @@
 */
 SQLITE_API int sqlite3_vfs_unregister(sqlite3_vfs *pVfs){
 #ifndef SQLITE_MUTEX_NOOP
-  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
   sqlite3_mutex_enter(mutex);
   vfsUnlink(pVfs);
@@ -10780,14 +11590,6 @@
   return SQLITE_OK;
 }
 
-/*
-** Provide a default sqlite3OsDefaultVfs() implementation in the
-** cases where none of the standard backends are used.
-*/
-#if !OS_UNIX && !OS_WIN && !OS_OS2
-SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){ return 0; }
-#endif
-
 /************** End of os.c **************************************************/
 /************** Begin file fault.c *******************************************/
 /*
@@ -10801,159 +11603,65 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file contains code to implement a fault-injector used for
-** testing and verification of SQLite.
 **
-** Subsystems within SQLite can call sqlite3FaultStep() to see if
-** they should simulate a fault.  sqlite3FaultStep() normally returns
-** zero but will return non-zero if a fault should be simulated.
-** Fault injectors can be used, for example, to simulate memory
-** allocation failures or I/O errors.
-**
-** The fault injector is omitted from the code if SQLite is
-** compiled with -DSQLITE_OMIT_BUILTIN_TEST=1.  There is a very
-** small performance hit for leaving the fault injector in the code.
-** Commerical products will probably want to omit the fault injector
-** from production builds.  But safety-critical systems who work
-** under the motto "fly what you test and test what you fly" may
-** choose to leave the fault injector enabled even in production.
-*/
-
-#ifndef SQLITE_OMIT_BUILTIN_TEST
-
-/*
-** There can be various kinds of faults.  For example, there can be
-** a memory allocation failure.  Or an I/O failure.  For each different
-** fault type, there is a separate FaultInjector structure to keep track
-** of the status of that fault.
+** $Id: fault.c,v 1.10 2008/06/22 12:37:58 drh Exp $
 */
-static struct FaultInjector {
-  int iCountdown;   /* Number of pending successes before we hit a failure */
-  int nRepeat;      /* Number of times to repeat the failure */
-  int nBenign;      /* Number of benign failures seen since last config */
-  int nFail;        /* Number of failures seen since last config */
-  u8 enable;        /* True if enabled */
-  i16 benign;       /* Positive if next failure will be benign */
-} aFault[SQLITE_FAULTINJECTOR_COUNT];
 
 /*
-** This routine configures and enables a fault injector.  After
-** calling this routine, aFaultStep() will return false (zero)
-** nDelay times, then it will return true nRepeat times,
-** then it will again begin returning false.
+** This file contains code to support the concept of "benign" 
+** malloc failures (when the xMalloc() or xRealloc() method of the
+** sqlite3_mem_methods structure fails to allocate a block of memory
+** and returns 0). 
+**
+** Most malloc failures are non-benign. After they occur, SQLite
+** abandons the current operation and returns an error code (usually
+** SQLITE_NOMEM) to the user. However, sometimes a fault is not necessarily
+** fatal. For example, if a malloc fails while resizing a hash table, this 
+** is completely recoverable simply by not carrying out the resize. The 
+** hash table will continue to function normally.  So a malloc failure 
+** during a hash table resize is a benign fault.
 */
-SQLITE_PRIVATE void sqlite3FaultConfig(int id, int nDelay, int nRepeat){
-  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
-  aFault[id].iCountdown = nDelay;
-  aFault[id].nRepeat = nRepeat;
-  aFault[id].nBenign = 0;
-  aFault[id].nFail = 0;
-  aFault[id].enable = nDelay>=0;
-  aFault[id].benign = 0;
-}
 
-/*
-** Return the number of faults (both hard and benign faults) that have
-** occurred since the injector was last configured.
-*/
-SQLITE_PRIVATE int sqlite3FaultFailures(int id){
-  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
-  return aFault[id].nFail;
-}
 
-/*
-** Return the number of benign faults that have occurred since the
-** injector was last configured.
-*/
-SQLITE_PRIVATE int sqlite3FaultBenignFailures(int id){
-  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
-  return aFault[id].nBenign;
-}
+#ifndef SQLITE_OMIT_BUILTIN_TEST
 
 /*
-** Return the number of successes that will occur before the next failure.
-** If no failures are scheduled, return -1.
-*/
-SQLITE_PRIVATE int sqlite3FaultPending(int id){
-  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
-  if( aFault[id].enable ){
-    return aFault[id].iCountdown;
-  }else{
-    return -1;
-  }
-}
-
-/* 
-** After this routine causes subsequent faults to be either benign
-** or hard (not benign), according to the "enable" parameter.
-**
-** Most faults are hard.  In other words, most faults cause
-** an error to be propagated back up to the application interface.
-** However, sometimes a fault is easily recoverable.  For example,
-** if a malloc fails while resizing a hash table, this is completely
-** recoverable simply by not carrying out the resize.  The hash table
-** will continue to function normally.  So a malloc failure during
-** a hash table resize is a benign fault.  
+** Global variables.
 */
-SQLITE_PRIVATE void sqlite3FaultBeginBenign(int id){
-  if( id<0 ){
-    for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
-      aFault[id].benign++;
-    }
-  }else{
-    assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
-    aFault[id].benign++;
-  }
-}
-SQLITE_PRIVATE void sqlite3FaultEndBenign(int id){
-  if( id<0 ){
-    for(id=0; id<SQLITE_FAULTINJECTOR_COUNT; id++){
-      assert( aFault[id].benign>0 );
-      aFault[id].benign--;
-    }
-  }else{
-    assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
-    assert( aFault[id].benign>0 );
-    aFault[id].benign--;
-  }
-}
+static struct BenignMallocHooks {
+  void (*xBenignBegin)(void);
+  void (*xBenignEnd)(void);
+} hooks;
 
 /*
-** This routine exists as a place to set a breakpoint that will
-** fire on any simulated fault.
+** Register hooks to call when sqlite3BeginBenignMalloc() and
+** sqlite3EndBenignMalloc() are called, respectively.
 */
-static void sqlite3Fault(void){
-  static int cnt = 0;
-  cnt++;
+SQLITE_PRIVATE void sqlite3BenignMallocHooks(
+  void (*xBenignBegin)(void),
+  void (*xBenignEnd)(void)
+){
+  hooks.xBenignBegin = xBenignBegin;
+  hooks.xBenignEnd = xBenignEnd;
 }
 
-
 /*
-** Check to see if a fault should be simulated.  Return true to simulate
-** the fault.  Return false if the fault should not be simulated.
+** This (sqlite3EndBenignMalloc()) is called by SQLite code to indicate that
+** subsequent malloc failures are benign. A call to sqlite3EndBenignMalloc()
+** indicates that subsequent malloc failures are non-benign.
 */
-SQLITE_PRIVATE int sqlite3FaultStep(int id){
-  assert( id>=0 && id<SQLITE_FAULTINJECTOR_COUNT );
-  if( likely(!aFault[id].enable) ){
-    return 0;
+SQLITE_PRIVATE void sqlite3BeginBenignMalloc(void){
+  if( hooks.xBenignBegin ){
+    hooks.xBenignBegin();
   }
-  if( aFault[id].iCountdown>0 ){
-    aFault[id].iCountdown--;
-    return 0;
-  }
-  sqlite3Fault();
-  aFault[id].nFail++;
-  if( aFault[id].benign>0 ){
-    aFault[id].nBenign++;
-  }
-  aFault[id].nRepeat--;
-  if( aFault[id].nRepeat<=0 ){
-    aFault[id].enable = 0;
+}
+SQLITE_PRIVATE void sqlite3EndBenignMalloc(void){
+  if( hooks.xBenignEnd ){
+    hooks.xBenignEnd();
   }
-  return 1;  
 }
 
-#endif /* SQLITE_OMIT_BUILTIN_TEST */
+#endif   /* #ifndef SQLITE_OMIT_BUILTIN_TEST */
 
 /************** End of fault.c ***********************************************/
 /************** Begin file mem1.c ********************************************/
@@ -10968,10 +11676,15 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file contains the C functions that implement a memory
-** allocation subsystem for use by SQLite.  
 **
-** $Id: mem1.c,v 1.17 2008/03/18 00:07:11 drh Exp $
+** This file contains low-level memory allocation drivers for when
+** SQLite will use the standard C-library malloc/realloc/free interface
+** to obtain the memory it needs.
+**
+** This file contains implementations of the low-level memory allocation
+** routines specified in the sqlite3_mem_methods object.
+**
+** $Id: mem1.c,v 1.23 2008/06/23 15:10:25 danielk1977 Exp $
 */
 
 /*
@@ -10982,212 +11695,115 @@
 #ifdef SQLITE_SYSTEM_MALLOC
 
 /*
-** All of the static variables used by this module are collected
-** into a single structure named "mem".  This is to keep the
-** static variables organized and to reduce namespace pollution
-** when this module is combined with other in the amalgamation.
-*/
-static struct {
-  /*
-  ** The alarm callback and its arguments.  The mem.mutex lock will
-  ** be held while the callback is running.  Recursive calls into
-  ** the memory subsystem are allowed, but no new callbacks will be
-  ** issued.  The alarmBusy variable is set to prevent recursive
-  ** callbacks.
-  */
-  sqlite3_int64 alarmThreshold;
-  void (*alarmCallback)(void*, sqlite3_int64,int);
-  void *alarmArg;
-  int alarmBusy;
-  
-  /*
-  ** Mutex to control access to the memory allocation subsystem.
-  */
-  sqlite3_mutex *mutex;
-  
-  /*
-  ** Current allocation and high-water mark.
-  */
-  sqlite3_int64 nowUsed;
-  sqlite3_int64 mxUsed;
-  
- 
-} mem;
-
-/*
-** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
+** Like malloc(), but remember the size of the allocation
+** so that we can find it later using sqlite3MemSize().
+**
+** For this low-level routine, we are guaranteed that nByte>0 because
+** cases of nByte<=0 will be intercepted and dealt with by higher level
+** routines.
 */
-static void enterMem(void){
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
+static void *sqlite3MemMalloc(int nByte){
+  sqlite3_int64 *p;
+  assert( nByte>0 );
+  nByte = (nByte+7)&~7;
+  p = malloc( nByte+8 );
+  if( p ){
+    p[0] = nByte;
+    p++;
   }
-  sqlite3_mutex_enter(mem.mutex);
+  return (void *)p;
 }
 
 /*
-** Return the amount of memory currently checked out.
+** Like free() but works for allocations obtained from sqlite3MemMalloc()
+** or sqlite3MemRealloc().
+**
+** For this low-level routine, we already know that pPrior!=0 since
+** cases where pPrior==0 will have been intecepted and dealt with
+** by higher-level routines.
 */
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
-  sqlite3_int64 n;
-  enterMem();
-  n = mem.nowUsed;
-  sqlite3_mutex_leave(mem.mutex);  
-  return n;
+static void sqlite3MemFree(void *pPrior){
+  sqlite3_int64 *p = (sqlite3_int64*)pPrior;
+  assert( pPrior!=0 );
+  p--;
+  free(p);
 }
 
 /*
-** Return the maximum amount of memory that has ever been
-** checked out since either the beginning of this process
-** or since the most recent reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
-  sqlite3_int64 n;
-  enterMem();
-  n = mem.mxUsed;
-  if( resetFlag ){
-    mem.mxUsed = mem.nowUsed;
+** Like realloc().  Resize an allocation previously obtained from
+** sqlite3MemMalloc().
+**
+** For this low-level interface, we know that pPrior!=0.  Cases where
+** pPrior==0 while have been intercepted by higher-level routine and
+** redirected to xMalloc.  Similarly, we know that nByte>0 becauses
+** cases where nByte<=0 will have been intercepted by higher-level
+** routines and redirected to xFree.
+*/
+static void *sqlite3MemRealloc(void *pPrior, int nByte){
+  sqlite3_int64 *p = (sqlite3_int64*)pPrior;
+  assert( pPrior!=0 && nByte>0 );
+  nByte = (nByte+7)&~7;
+  p = (sqlite3_int64*)pPrior;
+  p--;
+  p = realloc(p, nByte+8 );
+  if( p ){
+    p[0] = nByte;
+    p++;
   }
-  sqlite3_mutex_leave(mem.mutex);  
-  return n;
-}
-
-/*
-** Change the alarm callback
-*/
-SQLITE_API int sqlite3_memory_alarm(
-  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
-  void *pArg,
-  sqlite3_int64 iThreshold
-){
-  enterMem();
-  mem.alarmCallback = xCallback;
-  mem.alarmArg = pArg;
-  mem.alarmThreshold = iThreshold;
-  sqlite3_mutex_leave(mem.mutex);
-  return SQLITE_OK;
+  return (void*)p;
 }
 
 /*
-** Trigger the alarm 
+** Report the allocated size of a prior return from xMalloc()
+** or xRealloc().
 */
-static void sqlite3MemsysAlarm(int nByte){
-  void (*xCallback)(void*,sqlite3_int64,int);
-  sqlite3_int64 nowUsed;
-  void *pArg;
-  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
-  mem.alarmBusy = 1;
-  xCallback = mem.alarmCallback;
-  nowUsed = mem.nowUsed;
-  pArg = mem.alarmArg;
-  sqlite3_mutex_leave(mem.mutex);
-  xCallback(pArg, nowUsed, nByte);
-  sqlite3_mutex_enter(mem.mutex);
-  mem.alarmBusy = 0;
+static int sqlite3MemSize(void *pPrior){
+  sqlite3_int64 *p;
+  if( pPrior==0 ) return 0;
+  p = (sqlite3_int64*)pPrior;
+  p--;
+  return p[0];
 }
 
 /*
-** Allocate nBytes of memory
+** Round up a request size to the next valid allocation size.
 */
-SQLITE_API void *sqlite3_malloc(int nBytes){
-  sqlite3_int64 *p = 0;
-  if( nBytes>0 ){
-    enterMem();
-    if( mem.alarmCallback!=0 && mem.nowUsed+nBytes>=mem.alarmThreshold ){
-      sqlite3MemsysAlarm(nBytes);
-    }
-    if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
-      p = 0;
-    }else{
-      p = malloc(nBytes+8);
-      if( p==0 ){
-        sqlite3MemsysAlarm(nBytes);
-        p = malloc(nBytes+8);
-      }
-    }
-    if( p ){
-      p[0] = nBytes;
-      p++;
-      mem.nowUsed += nBytes;
-      if( mem.nowUsed>mem.mxUsed ){
-        mem.mxUsed = mem.nowUsed;
-      }
-    }
-    sqlite3_mutex_leave(mem.mutex);
-  }
-  return (void*)p; 
+static int sqlite3MemRoundup(int n){
+  return (n+7) & ~7;
 }
 
 /*
-** Free memory.
+** Initialize this module.
 */
-SQLITE_API void sqlite3_free(void *pPrior){
-  sqlite3_int64 *p;
-  int nByte;
-  if( pPrior==0 ){
-    return;
-  }
-  assert( mem.mutex!=0 );
-  p = pPrior;
-  p--;
-  nByte = (int)*p;
-  sqlite3_mutex_enter(mem.mutex);
-  mem.nowUsed -= nByte;
-  free(p);
-  sqlite3_mutex_leave(mem.mutex);  
+static int sqlite3MemInit(void *NotUsed){
+  return SQLITE_OK;
 }
 
 /*
-** Return the number of bytes allocated at p.
+** Deinitialize this module.
 */
-SQLITE_PRIVATE int sqlite3MallocSize(void *p){
-  sqlite3_int64 *pInt;
-  if( !p ) return 0;
-  pInt = p;
-  return pInt[-1];
+static void sqlite3MemShutdown(void *NotUsed){
+  return;
 }
 
 /*
-** Change the size of an existing memory allocation
+** This routine is the only routine in this file with external linkage.
+**
+** Populate the low-level memory allocation function pointers in
+** sqlite3Config.m with pointers to the routines in this file.
 */
-SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){
-  int nOld;
-  sqlite3_int64 *p;
-  if( pPrior==0 ){
-    return sqlite3_malloc(nBytes);
-  }
-  if( nBytes<=0 ){
-    sqlite3_free(pPrior);
-    return 0;
-  }
-  p = pPrior;
-  p--;
-  nOld = (int)p[0];
-  assert( mem.mutex!=0 );
-  sqlite3_mutex_enter(mem.mutex);
-  if( mem.nowUsed+nBytes-nOld>=mem.alarmThreshold ){
-    sqlite3MemsysAlarm(nBytes-nOld);
-  }
-  if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
-    p = 0;
-  }else{
-    p = realloc(p, nBytes+8);
-    if( p==0 ){
-      sqlite3MemsysAlarm(nBytes);
-      p = pPrior;
-      p--;
-      p = realloc(p, nBytes+8);
-    }
-  }
-  if( p ){
-    p[0] = nBytes;
-    p++;
-    mem.nowUsed += nBytes-nOld;
-    if( mem.nowUsed>mem.mxUsed ){
-      mem.mxUsed = mem.nowUsed;
-    }
-  }
-  sqlite3_mutex_leave(mem.mutex);
-  return (void*)p;
+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
+  static const sqlite3_mem_methods defaultMethods = {
+     sqlite3MemMalloc,
+     sqlite3MemFree,
+     sqlite3MemRealloc,
+     sqlite3MemSize,
+     sqlite3MemRoundup,
+     sqlite3MemInit,
+     sqlite3MemShutdown,
+     0
+  };
+  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
 }
 
 #endif /* SQLITE_SYSTEM_MALLOC */
@@ -11205,10 +11821,17 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** This file contains the C functions that implement a memory
-** allocation subsystem for use by SQLite.  
 **
-** $Id: mem2.c,v 1.26 2008/04/10 14:57:25 drh Exp $
+** This file contains low-level memory allocation drivers for when
+** SQLite will use the standard C-library malloc/realloc/free interface
+** to obtain the memory it needs while adding lots of additional debugging
+** information to each allocation in order to help detect and fix memory
+** leaks and memory usage errors.
+**
+** This file contains implementations of the low-level memory allocation
+** routines specified in the sqlite3_mem_methods object.
+**
+** $Id: mem2.c,v 1.34 2008/07/10 18:13:42 drh Exp $
 */
 
 /*
@@ -11268,29 +11891,12 @@
 ** when this module is combined with other in the amalgamation.
 */
 static struct {
-  /*
-  ** The alarm callback and its arguments.  The mem.mutex lock will
-  ** be held while the callback is running.  Recursive calls into
-  ** the memory subsystem are allowed, but no new callbacks will be
-  ** issued.  The alarmBusy variable is set to prevent recursive
-  ** callbacks.
-  */
-  sqlite3_int64 alarmThreshold;
-  void (*alarmCallback)(void*, sqlite3_int64, int);
-  void *alarmArg;
-  int alarmBusy;
   
   /*
   ** Mutex to control access to the memory allocation subsystem.
   */
   sqlite3_mutex *mutex;
-  
-  /*
-  ** Current allocation and high-water mark.
-  */
-  sqlite3_int64 nowUsed;
-  sqlite3_int64 mxUsed;
-  
+
   /*
   ** Head and tail of a linked list of all outstanding allocations
   */
@@ -11325,78 +11931,6 @@
 
 } mem;
 
-
-/*
-** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
-*/
-static void enterMem(void){
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-  }
-  sqlite3_mutex_enter(mem.mutex);
-}
-
-/*
-** Return the amount of memory currently checked out.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
-  sqlite3_int64 n;
-  enterMem();
-  n = mem.nowUsed;
-  sqlite3_mutex_leave(mem.mutex);  
-  return n;
-}
-
-/*
-** Return the maximum amount of memory that has ever been
-** checked out since either the beginning of this process
-** or since the most recent reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
-  sqlite3_int64 n;
-  enterMem();
-  n = mem.mxUsed;
-  if( resetFlag ){
-    mem.mxUsed = mem.nowUsed;
-  }
-  sqlite3_mutex_leave(mem.mutex);  
-  return n;
-}
-
-/*
-** Change the alarm callback
-*/
-SQLITE_API int sqlite3_memory_alarm(
-  void(*xCallback)(void *pArg, sqlite3_int64 used, int N),
-  void *pArg,
-  sqlite3_int64 iThreshold
-){
-  enterMem();
-  mem.alarmCallback = xCallback;
-  mem.alarmArg = pArg;
-  mem.alarmThreshold = iThreshold;
-  sqlite3_mutex_leave(mem.mutex);
-  return SQLITE_OK;
-}
-
-/*
-** Trigger the alarm 
-*/
-static void sqlite3MemsysAlarm(int nByte){
-  void (*xCallback)(void*,sqlite3_int64,int);
-  sqlite3_int64 nowUsed;
-  void *pArg;
-  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
-  mem.alarmBusy = 1;
-  xCallback = mem.alarmCallback;
-  nowUsed = mem.nowUsed;
-  pArg = mem.alarmArg;
-  sqlite3_mutex_leave(mem.mutex);
-  xCallback(pArg, nowUsed, nByte);
-  sqlite3_mutex_enter(mem.mutex);
-  mem.alarmBusy = 0;
-}
-
 /*
 ** Given an allocation, find the MemBlockHdr for that allocation.
 **
@@ -11425,7 +11959,7 @@
 /*
 ** Return the number of bytes currently allocated at address p.
 */
-SQLITE_PRIVATE int sqlite3MallocSize(void *p){
+static int sqlite3MemSize(void *p){
   struct MemBlockHdr *pHdr;
   if( !p ){
     return 0;
@@ -11435,99 +11969,103 @@
 }
 
 /*
+** Initialize the memory allocation subsystem.
+*/
+static int sqlite3MemInit(void *NotUsed){
+  if( !sqlite3Config.bMemstat ){
+    /* If memory status is enabled, then the malloc.c wrapper will already
+    ** hold the STATIC_MEM mutex when the routines here are invoked. */
+    mem.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+  }
+  return SQLITE_OK;
+}
+
+/*
+** Deinitialize the memory allocation subsystem.
+*/
+static void sqlite3MemShutdown(void *NotUsed){
+  mem.mutex = 0;
+}
+
+/*
+** Round up a request size to the next valid allocation size.
+*/
+static int sqlite3MemRoundup(int n){
+  return (n+7) & ~7;
+}
+
+/*
 ** Allocate nByte bytes of memory.
 */
-SQLITE_API void *sqlite3_malloc(int nByte){
+static void *sqlite3MemMalloc(int nByte){
   struct MemBlockHdr *pHdr;
   void **pBt;
   char *z;
   int *pInt;
   void *p = 0;
   int totalSize;
-
-  if( nByte>0 ){
-    int nReserve;
-    enterMem();
-    assert( mem.disallow==0 );
-    if( mem.alarmCallback!=0 && mem.nowUsed+nByte>=mem.alarmThreshold ){
-      sqlite3MemsysAlarm(nByte);
-    }
-    nReserve = (nByte+7)&~7;
-    if( nReserve/8>NCSIZE-1 ){
-      mem.sizeCnt[NCSIZE-1]++;
-    }else{
-      mem.sizeCnt[nReserve/8]++;
-    }
-    totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
-                 mem.nBacktrace*sizeof(void*) + mem.nTitle;
-    if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ){
-      p = 0;
-    }else{
-      p = malloc(totalSize);
-      if( p==0 ){
-        sqlite3MemsysAlarm(nByte);
-        p = malloc(totalSize);
-      }
-    }
-    if( p ){
-      z = p;
-      pBt = (void**)&z[mem.nTitle];
-      pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
-      pHdr->pNext = 0;
-      pHdr->pPrev = mem.pLast;
-      if( mem.pLast ){
-        mem.pLast->pNext = pHdr;
-      }else{
-        mem.pFirst = pHdr;
-      }
-      mem.pLast = pHdr;
-      pHdr->iForeGuard = FOREGUARD;
-      pHdr->nBacktraceSlots = mem.nBacktrace;
-      pHdr->nTitle = mem.nTitle;
-      if( mem.nBacktrace ){
-        void *aAddr[40];
-        pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
-        memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
-	if( mem.xBacktrace ){
-          mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
-	}
-      }else{
-        pHdr->nBacktrace = 0;
-      }
-      if( mem.nTitle ){
-        memcpy(z, mem.zTitle, mem.nTitle);
-      }
-      pHdr->iSize = nByte;
-      pInt = (int*)&pHdr[1];
-      pInt[nReserve/sizeof(int)] = REARGUARD;
-      memset(pInt, 0x65, nReserve);
-      mem.nowUsed += nByte;
-      if( mem.nowUsed>mem.mxUsed ){
-        mem.mxUsed = mem.nowUsed;
-      }
-      p = (void*)pInt;
-    }
-    sqlite3_mutex_leave(mem.mutex);
+  int nReserve;
+  sqlite3_mutex_enter(mem.mutex);
+  assert( mem.disallow==0 );
+  nReserve = (nByte+7)&~7;
+  if( nReserve/8>NCSIZE-1 ){
+    mem.sizeCnt[NCSIZE-1]++;
+  }else{
+    mem.sizeCnt[nReserve/8]++;
+  }
+  totalSize = nReserve + sizeof(*pHdr) + sizeof(int) +
+               mem.nBacktrace*sizeof(void*) + mem.nTitle;
+  p = malloc(totalSize);
+  if( p ){
+    z = p;
+    pBt = (void**)&z[mem.nTitle];
+    pHdr = (struct MemBlockHdr*)&pBt[mem.nBacktrace];
+    pHdr->pNext = 0;
+    pHdr->pPrev = mem.pLast;
+    if( mem.pLast ){
+      mem.pLast->pNext = pHdr;
+    }else{
+      mem.pFirst = pHdr;
+    }
+    mem.pLast = pHdr;
+    pHdr->iForeGuard = FOREGUARD;
+    pHdr->nBacktraceSlots = mem.nBacktrace;
+    pHdr->nTitle = mem.nTitle;
+    if( mem.nBacktrace ){
+      void *aAddr[40];
+      pHdr->nBacktrace = backtrace(aAddr, mem.nBacktrace+1)-1;
+      memcpy(pBt, &aAddr[1], pHdr->nBacktrace*sizeof(void*));
+      if( mem.xBacktrace ){
+        mem.xBacktrace(nByte, pHdr->nBacktrace-1, &aAddr[1]);
+      }
+    }else{
+      pHdr->nBacktrace = 0;
+    }
+    if( mem.nTitle ){
+      memcpy(z, mem.zTitle, mem.nTitle);
+    }
+    pHdr->iSize = nByte;
+    pInt = (int*)&pHdr[1];
+    pInt[nReserve/sizeof(int)] = REARGUARD;
+    memset(pInt, 0x65, nReserve);
+    p = (void*)pInt;
   }
+  sqlite3_mutex_leave(mem.mutex);
   return p; 
 }
 
 /*
 ** Free memory.
 */
-SQLITE_API void sqlite3_free(void *pPrior){
+static void sqlite3MemFree(void *pPrior){
   struct MemBlockHdr *pHdr;
   void **pBt;
   char *z;
-  if( pPrior==0 ){
-    return;
-  }
-  assert( mem.mutex!=0 );
+  assert( sqlite3Config.bMemstat || mem.mutex!=0 );
   pHdr = sqlite3MemsysGetHeader(pPrior);
   pBt = (void**)pHdr;
   pBt -= pHdr->nBacktraceSlots;
   sqlite3_mutex_enter(mem.mutex);
-  mem.nowUsed -= pHdr->iSize;
   if( pHdr->pPrev ){
     assert( pHdr->pPrev->pNext==pHdr );
     pHdr->pPrev->pNext = pHdr->pNext;
@@ -11559,32 +12097,44 @@
 ** much more likely to break and we are much more liking to find
 ** the error.
 */
-SQLITE_API void *sqlite3_realloc(void *pPrior, int nByte){
+static void *sqlite3MemRealloc(void *pPrior, int nByte){
   struct MemBlockHdr *pOldHdr;
   void *pNew;
-  if( pPrior==0 ){
-    return sqlite3_malloc(nByte);
-  }
-  if( nByte<=0 ){
-    sqlite3_free(pPrior);
-    return 0;
-  }
   assert( mem.disallow==0 );
   pOldHdr = sqlite3MemsysGetHeader(pPrior);
-  pNew = sqlite3_malloc(nByte);
+  pNew = sqlite3MemMalloc(nByte);
   if( pNew ){
     memcpy(pNew, pPrior, nByte<pOldHdr->iSize ? nByte : pOldHdr->iSize);
     if( nByte>pOldHdr->iSize ){
       memset(&((char*)pNew)[pOldHdr->iSize], 0x2b, nByte - pOldHdr->iSize);
     }
-    sqlite3_free(pPrior);
+    sqlite3MemFree(pPrior);
   }
   return pNew;
 }
 
+
+/*
+** Populate the low-level memory allocation function pointers in
+** sqlite3Config.m with pointers to the routines in this file.
+*/
+SQLITE_PRIVATE void sqlite3MemSetDefault(void){
+  static const sqlite3_mem_methods defaultMethods = {
+     sqlite3MemMalloc,
+     sqlite3MemFree,
+     sqlite3MemRealloc,
+     sqlite3MemSize,
+     sqlite3MemRoundup,
+     sqlite3MemInit,
+     sqlite3MemShutdown,
+     0
+  };
+  sqlite3_config(SQLITE_CONFIG_MALLOC, &defaultMethods);
+}
+
 /*
 ** Set the number of backtrace levels kept for each allocation.
-** A value of zero turns of backtracing.  The number is always rounded
+** A value of zero turns off backtracing.  The number is always rounded
 ** up to a multiple of 2.
 */
 SQLITE_PRIVATE void sqlite3MemdebugBacktrace(int depth){
@@ -11603,7 +12153,7 @@
 */
 SQLITE_PRIVATE void sqlite3MemdebugSettitle(const char *zTitle){
   int n = strlen(zTitle) + 1;
-  enterMem();
+  sqlite3_mutex_enter(mem.mutex);
   if( n>=sizeof(mem.zTitle) ) n = sizeof(mem.zTitle)-1;
   memcpy(mem.zTitle, zTitle, n);
   mem.zTitle[n] = 0;
@@ -11661,7 +12211,7 @@
 }
 
 /*
-** Return the number of times sqlite3_malloc() has been called.
+** Return the number of times sqlite3MemMalloc() has been called.
 */
 SQLITE_PRIVATE int sqlite3MemdebugMallocCount(){
   int i;
@@ -11692,21 +12242,27 @@
 ** allocation subsystem for use by SQLite. 
 **
 ** This version of the memory allocation subsystem omits all
-** use of malloc().  All dynamically allocatable memory is
-** contained in a static array, mem.aPool[].  The size of this
-** fixed memory pool is SQLITE_MEMORY_SIZE bytes.
+** use of malloc(). The SQLite user supplies a block of memory
+** before calling sqlite3_initialize() from which allocations
+** are made and returned by the xMalloc() and xRealloc() 
+** implementations. Once sqlite3_initialize() has been called,
+** the amount of memory available to SQLite is fixed and cannot
+** be changed.
 **
-** This version of the memory allocation subsystem is used if
-** and only if SQLITE_MEMORY_SIZE is defined.
+** This version of the memory allocation subsystem is included
+** in the build only if SQLITE_ENABLE_MEMSYS3 is defined.
 **
-** $Id: mem3.c,v 1.12 2008/02/19 15:15:16 drh Exp $
+** $Id: mem3.c,v 1.19 2008/07/16 12:25:32 drh Exp $
 */
 
 /*
-** This version of the memory allocator is used only when 
-** SQLITE_MEMORY_SIZE is defined.
+** This version of the memory allocator is only built into the library
+** SQLITE_ENABLE_MEMSYS3 is defined. Defining this symbol does not
+** mean that the library will use a memory-pool by default, just that
+** it is available. The mempool allocator is activated by calling
+** sqlite3_config().
 */
-#ifdef SQLITE_MEMORY_SIZE
+#ifdef SQLITE_ENABLE_MEMSYS3
 
 /*
 ** Maximum size (in Mem3Blocks) of a "small" chunk.
@@ -11736,7 +12292,7 @@
 ** u.hdr.prevSize can be part of the data for that chunk and should
 ** not be read or written.
 **
-** We often identify a chunk by its index in mem.aPool[].  When
+** We often identify a chunk by its index in mem3.aPool[].  When
 ** this is done, the chunk index refers to the second block of
 ** the chunk.  In this way, the first chunk has an index of 1.
 ** A chunk index of 0 means "no such chunk" and is the equivalent
@@ -11744,8 +12300,8 @@
 **
 ** The second block of free chunks is of the form u.list.  The
 ** two fields form a double-linked list of chunks of related sizes.
-** Pointers to the head of the list are stored in mem.aiSmall[] 
-** for smaller chunks and mem.aiHash[] for larger chunks.
+** Pointers to the head of the list are stored in mem3.aiSmall[] 
+** for smaller chunks and mem3.aiHash[] for larger chunks.
 **
 ** The second block of a chunk is user data if the chunk is checked 
 ** out.  If a chunk is checked out, the user data may extend into
@@ -11759,15 +12315,15 @@
       u32 size4x;     /* 4x the size of current chunk in Mem3Block elements */
     } hdr;
     struct {
-      u32 next;       /* Index in mem.aPool[] of next free chunk */
-      u32 prev;       /* Index in mem.aPool[] of previous free chunk */
+      u32 next;       /* Index in mem3.aPool[] of next free chunk */
+      u32 prev;       /* Index in mem3.aPool[] of previous free chunk */
     } list;
   } u;
 };
 
 /*
 ** All of the static variables used by this module are collected
-** into a single structure named "mem".  This is to keep the
+** into a single structure named "mem3".  This is to keep the
 ** static variables organized and to reduce namespace pollution
 ** when this module is combined with other in the amalgamation.
 */
@@ -11805,29 +12361,32 @@
   u32 aiHash[N_HASH];        /* For sizes MX_SMALL+1 and larger */
 
   /*
-  ** Memory available for allocation
+  ** Memory available for allocation. nPool is the size of the array
+  ** (in Mem3Blocks) pointed to by aPool less 2.
   */
-  Mem3Block aPool[SQLITE_MEMORY_SIZE/sizeof(Mem3Block)+2];
-} mem;
+  u32 nPool;
+  Mem3Block *aPool;
+  /* Mem3Block aPool[SQLITE_MEMORY_SIZE/sizeof(Mem3Block)+2]; */
+} mem3;
 
 /*
-** Unlink the chunk at mem.aPool[i] from list it is currently
+** Unlink the chunk at mem3.aPool[i] from list it is currently
 ** on.  *pRoot is the list that i is a member of.
 */
 static void memsys3UnlinkFromList(u32 i, u32 *pRoot){
-  u32 next = mem.aPool[i].u.list.next;
-  u32 prev = mem.aPool[i].u.list.prev;
-  assert( sqlite3_mutex_held(mem.mutex) );
+  u32 next = mem3.aPool[i].u.list.next;
+  u32 prev = mem3.aPool[i].u.list.prev;
+  assert( sqlite3_mutex_held(mem3.mutex) );
   if( prev==0 ){
     *pRoot = next;
   }else{
-    mem.aPool[prev].u.list.next = next;
+    mem3.aPool[prev].u.list.next = next;
   }
   if( next ){
-    mem.aPool[next].u.list.prev = prev;
+    mem3.aPool[next].u.list.prev = prev;
   }
-  mem.aPool[i].u.list.next = 0;
-  mem.aPool[i].u.list.prev = 0;
+  mem3.aPool[i].u.list.next = 0;
+  mem3.aPool[i].u.list.prev = 0;
 }
 
 /*
@@ -11836,30 +12395,30 @@
 */
 static void memsys3Unlink(u32 i){
   u32 size, hash;
-  assert( sqlite3_mutex_held(mem.mutex) );
-  assert( (mem.aPool[i-1].u.hdr.size4x & 1)==0 );
+  assert( sqlite3_mutex_held(mem3.mutex) );
+  assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
   assert( i>=1 );
-  size = mem.aPool[i-1].u.hdr.size4x/4;
-  assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
+  size = mem3.aPool[i-1].u.hdr.size4x/4;
+  assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
   assert( size>=2 );
   if( size <= MX_SMALL ){
-    memsys3UnlinkFromList(i, &mem.aiSmall[size-2]);
+    memsys3UnlinkFromList(i, &mem3.aiSmall[size-2]);
   }else{
     hash = size % N_HASH;
-    memsys3UnlinkFromList(i, &mem.aiHash[hash]);
+    memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
   }
 }
 
 /*
-** Link the chunk at mem.aPool[i] so that is on the list rooted
+** Link the chunk at mem3.aPool[i] so that is on the list rooted
 ** at *pRoot.
 */
 static void memsys3LinkIntoList(u32 i, u32 *pRoot){
-  assert( sqlite3_mutex_held(mem.mutex) );
-  mem.aPool[i].u.list.next = *pRoot;
-  mem.aPool[i].u.list.prev = 0;
+  assert( sqlite3_mutex_held(mem3.mutex) );
+  mem3.aPool[i].u.list.next = *pRoot;
+  mem3.aPool[i].u.list.prev = 0;
   if( *pRoot ){
-    mem.aPool[*pRoot].u.list.prev = i;
+    mem3.aPool[*pRoot].u.list.prev = i;
   }
   *pRoot = i;
 }
@@ -11870,110 +12429,49 @@
 */
 static void memsys3Link(u32 i){
   u32 size, hash;
-  assert( sqlite3_mutex_held(mem.mutex) );
+  assert( sqlite3_mutex_held(mem3.mutex) );
   assert( i>=1 );
-  assert( (mem.aPool[i-1].u.hdr.size4x & 1)==0 );
-  size = mem.aPool[i-1].u.hdr.size4x/4;
-  assert( size==mem.aPool[i+size-1].u.hdr.prevSize );
+  assert( (mem3.aPool[i-1].u.hdr.size4x & 1)==0 );
+  size = mem3.aPool[i-1].u.hdr.size4x/4;
+  assert( size==mem3.aPool[i+size-1].u.hdr.prevSize );
   assert( size>=2 );
   if( size <= MX_SMALL ){
-    memsys3LinkIntoList(i, &mem.aiSmall[size-2]);
+    memsys3LinkIntoList(i, &mem3.aiSmall[size-2]);
   }else{
     hash = size % N_HASH;
-    memsys3LinkIntoList(i, &mem.aiHash[hash]);
+    memsys3LinkIntoList(i, &mem3.aiHash[hash]);
   }
 }
 
 /*
-** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
-**
-** Also:  Initialize the memory allocation subsystem the first time
-** this routine is called.
+** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
+** will already be held (obtained by code in malloc.c) if
+** sqlite3Config.bMemStat is true.
 */
 static void memsys3Enter(void){
-  if( mem.mutex==0 ){
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-    mem.aPool[0].u.hdr.size4x = SQLITE_MEMORY_SIZE/2 + 2;
-    mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.prevSize = SQLITE_MEMORY_SIZE/8;
-    mem.aPool[SQLITE_MEMORY_SIZE/8].u.hdr.size4x = 1;
-    mem.iMaster = 1;
-    mem.szMaster = SQLITE_MEMORY_SIZE/8;
-    mem.mnMaster = mem.szMaster;
-  }
-  sqlite3_mutex_enter(mem.mutex);
-}
-
-/*
-** Return the amount of memory currently checked out.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
-  sqlite3_int64 n;
-  memsys3Enter();
-  n = SQLITE_MEMORY_SIZE - mem.szMaster*8;
-  sqlite3_mutex_leave(mem.mutex);  
-  return n;
-}
-
-/*
-** Return the maximum amount of memory that has ever been
-** checked out since either the beginning of this process
-** or since the most recent reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
-  sqlite3_int64 n;
-  memsys3Enter();
-  n = SQLITE_MEMORY_SIZE - mem.mnMaster*8;
-  if( resetFlag ){
-    mem.mnMaster = mem.szMaster;
+  if( sqlite3Config.bMemstat==0 && mem3.mutex==0 ){
+    mem3.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
   }
-  sqlite3_mutex_leave(mem.mutex);  
-  return n;
+  sqlite3_mutex_enter(mem3.mutex);
 }
-
-/*
-** Change the alarm callback.
-**
-** This is a no-op for the static memory allocator.  The purpose
-** of the memory alarm is to support sqlite3_soft_heap_limit().
-** But with this memory allocator, the soft_heap_limit is really
-** a hard limit that is fixed at SQLITE_MEMORY_SIZE.
-*/
-SQLITE_API int sqlite3_memory_alarm(
-  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
-  void *pArg,
-  sqlite3_int64 iThreshold
-){
-  return SQLITE_OK;
+static void memsys3Leave(void){
+  sqlite3_mutex_leave(mem3.mutex);
 }
 
 /*
 ** Called when we are unable to satisfy an allocation of nBytes.
 */
 static void memsys3OutOfMemory(int nByte){
-  if( !mem.alarmBusy ){
-    mem.alarmBusy = 1;
-    assert( sqlite3_mutex_held(mem.mutex) );
-    sqlite3_mutex_leave(mem.mutex);
+  if( !mem3.alarmBusy ){
+    mem3.alarmBusy = 1;
+    assert( sqlite3_mutex_held(mem3.mutex) );
+    sqlite3_mutex_leave(mem3.mutex);
     sqlite3_release_memory(nByte);
-    sqlite3_mutex_enter(mem.mutex);
-    mem.alarmBusy = 0;
+    sqlite3_mutex_enter(mem3.mutex);
+    mem3.alarmBusy = 0;
   }
 }
 
-/*
-** Return the size of an outstanding allocation, in bytes.  The
-** size returned omits the 8-byte header overhead.  This only
-** works for chunks that are currently checked out.
-*/
-SQLITE_PRIVATE int sqlite3MallocSize(void *p){
-  int iSize = 0;
-  if( p ){
-    Mem3Block *pBlock = (Mem3Block*)p;
-    assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
-    iSize = (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
-  }
-  return iSize;
-}
 
 /*
 ** Chunk i is a free chunk that has been unlinked.  Adjust its 
@@ -11982,62 +12480,62 @@
 */
 static void *memsys3Checkout(u32 i, int nBlock){
   u32 x;
-  assert( sqlite3_mutex_held(mem.mutex) );
+  assert( sqlite3_mutex_held(mem3.mutex) );
   assert( i>=1 );
-  assert( mem.aPool[i-1].u.hdr.size4x/4==nBlock );
-  assert( mem.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
-  x = mem.aPool[i-1].u.hdr.size4x;
-  mem.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
-  mem.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
-  mem.aPool[i+nBlock-1].u.hdr.size4x |= 2;
-  return &mem.aPool[i];
+  assert( mem3.aPool[i-1].u.hdr.size4x/4==nBlock );
+  assert( mem3.aPool[i+nBlock-1].u.hdr.prevSize==nBlock );
+  x = mem3.aPool[i-1].u.hdr.size4x;
+  mem3.aPool[i-1].u.hdr.size4x = nBlock*4 | 1 | (x&2);
+  mem3.aPool[i+nBlock-1].u.hdr.prevSize = nBlock;
+  mem3.aPool[i+nBlock-1].u.hdr.size4x |= 2;
+  return &mem3.aPool[i];
 }
 
 /*
-** Carve a piece off of the end of the mem.iMaster free chunk.
+** Carve a piece off of the end of the mem3.iMaster free chunk.
 ** Return a pointer to the new allocation.  Or, if the master chunk
 ** is not large enough, return 0.
 */
 static void *memsys3FromMaster(int nBlock){
-  assert( sqlite3_mutex_held(mem.mutex) );
-  assert( mem.szMaster>=nBlock );
-  if( nBlock>=mem.szMaster-1 ){
+  assert( sqlite3_mutex_held(mem3.mutex) );
+  assert( mem3.szMaster>=nBlock );
+  if( nBlock>=mem3.szMaster-1 ){
     /* Use the entire master */
-    void *p = memsys3Checkout(mem.iMaster, mem.szMaster);
-    mem.iMaster = 0;
-    mem.szMaster = 0;
-    mem.mnMaster = 0;
+    void *p = memsys3Checkout(mem3.iMaster, mem3.szMaster);
+    mem3.iMaster = 0;
+    mem3.szMaster = 0;
+    mem3.mnMaster = 0;
     return p;
   }else{
     /* Split the master block.  Return the tail. */
     u32 newi, x;
-    newi = mem.iMaster + mem.szMaster - nBlock;
-    assert( newi > mem.iMaster+1 );
-    mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = nBlock;
-    mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size4x |= 2;
-    mem.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
-    mem.szMaster -= nBlock;
-    mem.aPool[newi-1].u.hdr.prevSize = mem.szMaster;
-    x = mem.aPool[mem.iMaster-1].u.hdr.size4x & 2;
-    mem.aPool[mem.iMaster-1].u.hdr.size4x = mem.szMaster*4 | x;
-    if( mem.szMaster < mem.mnMaster ){
-      mem.mnMaster = mem.szMaster;
+    newi = mem3.iMaster + mem3.szMaster - nBlock;
+    assert( newi > mem3.iMaster+1 );
+    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = nBlock;
+    mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x |= 2;
+    mem3.aPool[newi-1].u.hdr.size4x = nBlock*4 + 1;
+    mem3.szMaster -= nBlock;
+    mem3.aPool[newi-1].u.hdr.prevSize = mem3.szMaster;
+    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
+    mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
+    if( mem3.szMaster < mem3.mnMaster ){
+      mem3.mnMaster = mem3.szMaster;
     }
-    return (void*)&mem.aPool[newi];
+    return (void*)&mem3.aPool[newi];
   }
 }
 
 /*
 ** *pRoot is the head of a list of free chunks of the same size
 ** or same size hash.  In other words, *pRoot is an entry in either
-** mem.aiSmall[] or mem.aiHash[].  
+** mem3.aiSmall[] or mem3.aiHash[].  
 **
 ** This routine examines all entries on the given list and tries
 ** to coalesce each entries with adjacent free chunks.  
 **
-** If it sees a chunk that is larger than mem.iMaster, it replaces 
-** the current mem.iMaster with the new larger chunk.  In order for
-** this mem.iMaster replacement to work, the master chunk must be
+** If it sees a chunk that is larger than mem3.iMaster, it replaces 
+** the current mem3.iMaster with the new larger chunk.  In order for
+** this mem3.iMaster replacement to work, the master chunk must be
 ** linked into the hash tables.  That is not the normal state of
 ** affairs, of course.  The calling routine must link the master
 ** chunk before invoking this routine, then must unlink the (possibly
@@ -12046,31 +12544,31 @@
 static void memsys3Merge(u32 *pRoot){
   u32 iNext, prev, size, i, x;
 
-  assert( sqlite3_mutex_held(mem.mutex) );
+  assert( sqlite3_mutex_held(mem3.mutex) );
   for(i=*pRoot; i>0; i=iNext){
-    iNext = mem.aPool[i].u.list.next;
-    size = mem.aPool[i-1].u.hdr.size4x;
+    iNext = mem3.aPool[i].u.list.next;
+    size = mem3.aPool[i-1].u.hdr.size4x;
     assert( (size&1)==0 );
     if( (size&2)==0 ){
       memsys3UnlinkFromList(i, pRoot);
-      assert( i > mem.aPool[i-1].u.hdr.prevSize );
-      prev = i - mem.aPool[i-1].u.hdr.prevSize;
+      assert( i > mem3.aPool[i-1].u.hdr.prevSize );
+      prev = i - mem3.aPool[i-1].u.hdr.prevSize;
       if( prev==iNext ){
-        iNext = mem.aPool[prev].u.list.next;
+        iNext = mem3.aPool[prev].u.list.next;
       }
       memsys3Unlink(prev);
       size = i + size/4 - prev;
-      x = mem.aPool[prev-1].u.hdr.size4x & 2;
-      mem.aPool[prev-1].u.hdr.size4x = size*4 | x;
-      mem.aPool[prev+size-1].u.hdr.prevSize = size;
+      x = mem3.aPool[prev-1].u.hdr.size4x & 2;
+      mem3.aPool[prev-1].u.hdr.size4x = size*4 | x;
+      mem3.aPool[prev+size-1].u.hdr.prevSize = size;
       memsys3Link(prev);
       i = prev;
     }else{
       size /= 4;
     }
-    if( size>mem.szMaster ){
-      mem.iMaster = i;
-      mem.szMaster = size;
+    if( size>mem3.szMaster ){
+      mem3.iMaster = i;
+      mem3.szMaster = size;
     }
   }
 }
@@ -12078,20 +12576,23 @@
 /*
 ** Return a block of memory of at least nBytes in size.
 ** Return NULL if unable.
+**
+** This function assumes that the necessary mutexes, if any, are
+** already held by the caller. Hence "Unsafe".
 */
-static void *memsys3Malloc(int nByte){
+static void *memsys3MallocUnsafe(int nByte){
   u32 i;
   int nBlock;
   int toFree;
 
-  assert( sqlite3_mutex_held(mem.mutex) );
+  assert( sqlite3_mutex_held(mem3.mutex) );
   assert( sizeof(Mem3Block)==8 );
   if( nByte<=12 ){
     nBlock = 2;
   }else{
     nBlock = (nByte + 11)/8;
   }
-  assert( nBlock >= 2 );
+  assert( nBlock>=2 );
 
   /* STEP 1:
   ** Look for an entry of the correct size in either the small
@@ -12099,16 +12600,16 @@
   ** successful most of the time (about 9 times out of 10).
   */
   if( nBlock <= MX_SMALL ){
-    i = mem.aiSmall[nBlock-2];
+    i = mem3.aiSmall[nBlock-2];
     if( i>0 ){
-      memsys3UnlinkFromList(i, &mem.aiSmall[nBlock-2]);
+      memsys3UnlinkFromList(i, &mem3.aiSmall[nBlock-2]);
       return memsys3Checkout(i, nBlock);
     }
   }else{
     int hash = nBlock % N_HASH;
-    for(i=mem.aiHash[hash]; i>0; i=mem.aPool[i].u.list.next){
-      if( mem.aPool[i-1].u.hdr.size4x/4==nBlock ){
-        memsys3UnlinkFromList(i, &mem.aiHash[hash]);
+    for(i=mem3.aiHash[hash]; i>0; i=mem3.aPool[i].u.list.next){
+      if( mem3.aPool[i-1].u.hdr.size4x/4==nBlock ){
+        memsys3UnlinkFromList(i, &mem3.aiHash[hash]);
         return memsys3Checkout(i, nBlock);
       }
     }
@@ -12118,7 +12619,7 @@
   ** Try to satisfy the allocation by carving a piece off of the end
   ** of the master chunk.  This step usually works if step 1 fails.
   */
-  if( mem.szMaster>=nBlock ){
+  if( mem3.szMaster>=nBlock ){
     return memsys3FromMaster(nBlock);
   }
 
@@ -12130,22 +12631,22 @@
   ** of the end of the master chunk.  This step happens very
   ** rarely (we hope!)
   */
-  for(toFree=nBlock*16; toFree<SQLITE_MEMORY_SIZE*2; toFree *= 2){
+  for(toFree=nBlock*16; toFree<(mem3.nPool*16); toFree *= 2){
     memsys3OutOfMemory(toFree);
-    if( mem.iMaster ){
-      memsys3Link(mem.iMaster);
-      mem.iMaster = 0;
-      mem.szMaster = 0;
+    if( mem3.iMaster ){
+      memsys3Link(mem3.iMaster);
+      mem3.iMaster = 0;
+      mem3.szMaster = 0;
     }
     for(i=0; i<N_HASH; i++){
-      memsys3Merge(&mem.aiHash[i]);
+      memsys3Merge(&mem3.aiHash[i]);
     }
     for(i=0; i<MX_SMALL-1; i++){
-      memsys3Merge(&mem.aiSmall[i]);
+      memsys3Merge(&mem3.aiSmall[i]);
     }
-    if( mem.szMaster ){
-      memsys3Unlink(mem.iMaster);
-      if( mem.szMaster>=nBlock ){
+    if( mem3.szMaster ){
+      memsys3Unlink(mem3.iMaster);
+      if( mem3.szMaster>=nBlock ){
         return memsys3FromMaster(nBlock);
       }
     }
@@ -12157,73 +12658,85 @@
 
 /*
 ** Free an outstanding memory allocation.
+**
+** This function assumes that the necessary mutexes, if any, are
+** already held by the caller. Hence "Unsafe".
 */
-void memsys3Free(void *pOld){
+void memsys3FreeUnsafe(void *pOld){
   Mem3Block *p = (Mem3Block*)pOld;
   int i;
   u32 size, x;
-  assert( sqlite3_mutex_held(mem.mutex) );
-  assert( p>mem.aPool && p<&mem.aPool[SQLITE_MEMORY_SIZE/8] );
-  i = p - mem.aPool;
-  assert( (mem.aPool[i-1].u.hdr.size4x&1)==1 );
-  size = mem.aPool[i-1].u.hdr.size4x/4;
-  assert( i+size<=SQLITE_MEMORY_SIZE/8+1 );
-  mem.aPool[i-1].u.hdr.size4x &= ~1;
-  mem.aPool[i+size-1].u.hdr.prevSize = size;
-  mem.aPool[i+size-1].u.hdr.size4x &= ~2;
+  assert( sqlite3_mutex_held(mem3.mutex) );
+  assert( p>mem3.aPool && p<&mem3.aPool[mem3.nPool] );
+  i = p - mem3.aPool;
+  assert( (mem3.aPool[i-1].u.hdr.size4x&1)==1 );
+  size = mem3.aPool[i-1].u.hdr.size4x/4;
+  assert( i+size<=mem3.nPool+1 );
+  mem3.aPool[i-1].u.hdr.size4x &= ~1;
+  mem3.aPool[i+size-1].u.hdr.prevSize = size;
+  mem3.aPool[i+size-1].u.hdr.size4x &= ~2;
   memsys3Link(i);
 
   /* Try to expand the master using the newly freed chunk */
-  if( mem.iMaster ){
-    while( (mem.aPool[mem.iMaster-1].u.hdr.size4x&2)==0 ){
-      size = mem.aPool[mem.iMaster-1].u.hdr.prevSize;
-      mem.iMaster -= size;
-      mem.szMaster += size;
-      memsys3Unlink(mem.iMaster);
-      x = mem.aPool[mem.iMaster-1].u.hdr.size4x & 2;
-      mem.aPool[mem.iMaster-1].u.hdr.size4x = mem.szMaster*4 | x;
-      mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;
-    }
-    x = mem.aPool[mem.iMaster-1].u.hdr.size4x & 2;
-    while( (mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size4x&1)==0 ){
-      memsys3Unlink(mem.iMaster+mem.szMaster);
-      mem.szMaster += mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.size4x/4;
-      mem.aPool[mem.iMaster-1].u.hdr.size4x = mem.szMaster*4 | x;
-      mem.aPool[mem.iMaster+mem.szMaster-1].u.hdr.prevSize = mem.szMaster;
+  if( mem3.iMaster ){
+    while( (mem3.aPool[mem3.iMaster-1].u.hdr.size4x&2)==0 ){
+      size = mem3.aPool[mem3.iMaster-1].u.hdr.prevSize;
+      mem3.iMaster -= size;
+      mem3.szMaster += size;
+      memsys3Unlink(mem3.iMaster);
+      x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
+      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
+      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
+    }
+    x = mem3.aPool[mem3.iMaster-1].u.hdr.size4x & 2;
+    while( (mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x&1)==0 ){
+      memsys3Unlink(mem3.iMaster+mem3.szMaster);
+      mem3.szMaster += mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.size4x/4;
+      mem3.aPool[mem3.iMaster-1].u.hdr.size4x = mem3.szMaster*4 | x;
+      mem3.aPool[mem3.iMaster+mem3.szMaster-1].u.hdr.prevSize = mem3.szMaster;
     }
   }
 }
 
 /*
-** Allocate nBytes of memory
+** Allocate nBytes of memory.
 */
-SQLITE_API void *sqlite3_malloc(int nBytes){
-  sqlite3_int64 *p = 0;
-  if( nBytes>0 ){
-    memsys3Enter();
-    p = memsys3Malloc(nBytes);
-    sqlite3_mutex_leave(mem.mutex);
-  }
+static void *memsys3Malloc(int nBytes){
+  sqlite3_int64 *p;
+  assert( nBytes>0 );          /* malloc.c filters out 0 byte requests */
+  memsys3Enter();
+  p = memsys3MallocUnsafe(nBytes);
+  memsys3Leave();
   return (void*)p; 
 }
 
 /*
 ** Free memory.
 */
-SQLITE_API void sqlite3_free(void *pPrior){
-  if( pPrior==0 ){
-    return;
-  }
-  assert( mem.mutex!=0 );
-  sqlite3_mutex_enter(mem.mutex);
-  memsys3Free(pPrior);
-  sqlite3_mutex_leave(mem.mutex);  
+void memsys3Free(void *pPrior){
+  assert( pPrior );
+  memsys3Enter();
+  memsys3FreeUnsafe(pPrior);
+  memsys3Leave();
+}
+
+/*
+** Return the size of an outstanding allocation, in bytes.  The
+** size returned omits the 8-byte header overhead.  This only
+** works for chunks that are currently checked out.
+*/
+static int memsys3Size(void *p){
+  Mem3Block *pBlock;
+  if( p==0 ) return 0;
+  pBlock = (Mem3Block*)p;
+  assert( (pBlock[-1].u.hdr.size4x&1)!=0 );
+  return (pBlock[-1].u.hdr.size4x&~3)*2 - 4;
 }
 
 /*
 ** Change the size of an existing memory allocation
 */
-SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){
+void *memsys3Realloc(void *pPrior, int nBytes){
   int nOld;
   void *p;
   if( pPrior==0 ){
@@ -12233,31 +12746,70 @@
     sqlite3_free(pPrior);
     return 0;
   }
-  assert( mem.mutex!=0 );
-  nOld = sqlite3MallocSize(pPrior);
+  nOld = memsys3Size(pPrior);
   if( nBytes<=nOld && nBytes>=nOld-128 ){
     return pPrior;
   }
-  sqlite3_mutex_enter(mem.mutex);
-  p = memsys3Malloc(nBytes);
+  memsys3Enter();
+  p = memsys3MallocUnsafe(nBytes);
   if( p ){
     if( nOld<nBytes ){
       memcpy(p, pPrior, nOld);
     }else{
       memcpy(p, pPrior, nBytes);
     }
-    memsys3Free(pPrior);
+    memsys3FreeUnsafe(pPrior);
   }
-  sqlite3_mutex_leave(mem.mutex);
+  memsys3Leave();
   return p;
 }
 
 /*
+** Round up a request size to the next valid allocation size.
+*/
+static int memsys3Roundup(int n){
+  return (n+7) & ~7;
+}
+
+/*
+** Initialize this module.
+*/
+static int memsys3Init(void *NotUsed){
+  if( !sqlite3Config.pHeap ){
+    return SQLITE_ERROR;
+  }
+
+  /* Store a pointer to the memory block in global structure mem3. */
+  assert( sizeof(Mem3Block)==8 );
+  mem3.aPool = (Mem3Block *)sqlite3Config.pHeap;
+  mem3.nPool = (sqlite3Config.nHeap / sizeof(Mem3Block)) - 2;
+
+  /* Initialize the master block. */
+  mem3.szMaster = mem3.nPool;
+  mem3.mnMaster = mem3.szMaster;
+  mem3.iMaster = 1;
+  mem3.aPool[0].u.hdr.size4x = (mem3.szMaster<<2) + 2;
+  mem3.aPool[mem3.nPool].u.hdr.prevSize = mem3.nPool;
+  mem3.aPool[mem3.nPool].u.hdr.size4x = 1;
+
+  return SQLITE_OK;
+}
+
+/*
+** Deinitialize this module.
+*/
+static void memsys3Shutdown(void *NotUsed){
+  return;
+}
+
+
+
+/*
 ** Open the file indicated and write a log of all unfreed memory 
 ** allocations into that log.
 */
-SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){
 #ifdef SQLITE_DEBUG
+SQLITE_PRIVATE void sqlite3Memsys3Dump(const char *zFilename){
   FILE *out;
   int i, j;
   u32 size;
@@ -12273,62 +12825,86 @@
   }
   memsys3Enter();
   fprintf(out, "CHUNKS:\n");
-  for(i=1; i<=SQLITE_MEMORY_SIZE/8; i+=size/4){
-    size = mem.aPool[i-1].u.hdr.size4x;
+  for(i=1; i<=mem3.nPool; i+=size/4){
+    size = mem3.aPool[i-1].u.hdr.size4x;
     if( size/4<=1 ){
-      fprintf(out, "%p size error\n", &mem.aPool[i]);
+      fprintf(out, "%p size error\n", &mem3.aPool[i]);
       assert( 0 );
       break;
     }
-    if( (size&1)==0 && mem.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){
-      fprintf(out, "%p tail size does not match\n", &mem.aPool[i]);
+    if( (size&1)==0 && mem3.aPool[i+size/4-1].u.hdr.prevSize!=size/4 ){
+      fprintf(out, "%p tail size does not match\n", &mem3.aPool[i]);
       assert( 0 );
       break;
     }
-    if( ((mem.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){
-      fprintf(out, "%p tail checkout bit is incorrect\n", &mem.aPool[i]);
+    if( ((mem3.aPool[i+size/4-1].u.hdr.size4x&2)>>1)!=(size&1) ){
+      fprintf(out, "%p tail checkout bit is incorrect\n", &mem3.aPool[i]);
       assert( 0 );
       break;
     }
     if( size&1 ){
-      fprintf(out, "%p %6d bytes checked out\n", &mem.aPool[i], (size/4)*8-8);
+      fprintf(out, "%p %6d bytes checked out\n", &mem3.aPool[i], (size/4)*8-8);
     }else{
-      fprintf(out, "%p %6d bytes free%s\n", &mem.aPool[i], (size/4)*8-8,
-                  i==mem.iMaster ? " **master**" : "");
+      fprintf(out, "%p %6d bytes free%s\n", &mem3.aPool[i], (size/4)*8-8,
+                  i==mem3.iMaster ? " **master**" : "");
     }
   }
   for(i=0; i<MX_SMALL-1; i++){
-    if( mem.aiSmall[i]==0 ) continue;
+    if( mem3.aiSmall[i]==0 ) continue;
     fprintf(out, "small(%2d):", i);
-    for(j = mem.aiSmall[i]; j>0; j=mem.aPool[j].u.list.next){
-      fprintf(out, " %p(%d)", &mem.aPool[j],
-              (mem.aPool[j-1].u.hdr.size4x/4)*8-8);
+    for(j = mem3.aiSmall[i]; j>0; j=mem3.aPool[j].u.list.next){
+      fprintf(out, " %p(%d)", &mem3.aPool[j],
+              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
     }
     fprintf(out, "\n"); 
   }
   for(i=0; i<N_HASH; i++){
-    if( mem.aiHash[i]==0 ) continue;
+    if( mem3.aiHash[i]==0 ) continue;
     fprintf(out, "hash(%2d):", i);
-    for(j = mem.aiHash[i]; j>0; j=mem.aPool[j].u.list.next){
-      fprintf(out, " %p(%d)", &mem.aPool[j],
-              (mem.aPool[j-1].u.hdr.size4x/4)*8-8);
+    for(j = mem3.aiHash[i]; j>0; j=mem3.aPool[j].u.list.next){
+      fprintf(out, " %p(%d)", &mem3.aPool[j],
+              (mem3.aPool[j-1].u.hdr.size4x/4)*8-8);
     }
     fprintf(out, "\n"); 
   }
-  fprintf(out, "master=%d\n", mem.iMaster);
-  fprintf(out, "nowUsed=%d\n", SQLITE_MEMORY_SIZE - mem.szMaster*8);
-  fprintf(out, "mxUsed=%d\n", SQLITE_MEMORY_SIZE - mem.mnMaster*8);
-  sqlite3_mutex_leave(mem.mutex);
+  fprintf(out, "master=%d\n", mem3.iMaster);
+  fprintf(out, "nowUsed=%d\n", mem3.nPool*8 - mem3.szMaster*8);
+  fprintf(out, "mxUsed=%d\n", mem3.nPool*8 - mem3.mnMaster*8);
+  sqlite3_mutex_leave(mem3.mutex);
   if( out==stdout ){
     fflush(stdout);
   }else{
     fclose(out);
   }
-#endif
 }
+#endif
 
+/*
+** This routine is the only routine in this file with external 
+** linkage.
+**
+** Populate the low-level memory allocation function pointers in
+** sqlite3Config.m with pointers to the routines in this file. The
+** arguments specify the block of memory to manage.
+**
+** This routine is only called by sqlite3_config(), and therefore
+** is not required to be threadsafe (it is not).
+*/
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys3(void){
+  static const sqlite3_mem_methods mempoolMethods = {
+     memsys3Malloc,
+     memsys3Free,
+     memsys3Realloc,
+     memsys3Size,
+     memsys3Roundup,
+     memsys3Init,
+     memsys3Shutdown,
+     0
+  };
+  return &mempoolMethods;
+}
 
-#endif /* !SQLITE_MEMORY_SIZE */
+#endif /* SQLITE_ENABLE_MEMSYS3 */
 
 /************** End of mem3.c ************************************************/
 /************** Begin file mem5.c ********************************************/
@@ -12347,21 +12923,24 @@
 ** allocation subsystem for use by SQLite. 
 **
 ** This version of the memory allocation subsystem omits all
-** use of malloc().  All dynamically allocatable memory is
-** contained in a static array, mem.aPool[].  The size of this
-** fixed memory pool is SQLITE_POW2_MEMORY_SIZE bytes.
+** use of malloc(). The SQLite user supplies a block of memory
+** before calling sqlite3_initialize() from which allocations
+** are made and returned by the xMalloc() and xRealloc() 
+** implementations. Once sqlite3_initialize() has been called,
+** the amount of memory available to SQLite is fixed and cannot
+** be changed.
 **
-** This version of the memory allocation subsystem is used if
-** and only if SQLITE_POW2_MEMORY_SIZE is defined.
+** This version of the memory allocation subsystem is included
+** in the build only if SQLITE_ENABLE_MEMSYS5 is defined.
 **
-** $Id: mem5.c,v 1.4 2008/02/19 15:15:16 drh Exp $
+** $Id: mem5.c,v 1.11 2008/07/16 12:25:32 drh Exp $
 */
 
 /*
 ** This version of the memory allocator is used only when 
 ** SQLITE_POW2_MEMORY_SIZE is defined.
 */
-#ifdef SQLITE_POW2_MEMORY_SIZE
+#ifdef SQLITE_ENABLE_MEMSYS5
 
 /*
 ** Log2 of the minimum size of an allocation.  For example, if
@@ -12371,13 +12950,12 @@
 #ifndef SQLITE_POW2_LOGMIN
 # define SQLITE_POW2_LOGMIN 6
 #endif
-#define POW2_MIN (1<<SQLITE_POW2_LOGMIN)
 
 /*
 ** Log2 of the maximum size of an allocation.
 */
 #ifndef SQLITE_POW2_LOGMAX
-# define SQLITE_POW2_LOGMAX 18
+# define SQLITE_POW2_LOGMAX 20
 #endif
 #define POW2_MAX (((unsigned int)1)<<SQLITE_POW2_LOGMAX)
 
@@ -12391,42 +12969,34 @@
 ** Larger allocations are an array of these structures where the
 ** size of the array is a power of 2.
 */
-typedef struct Mem5Block Mem5Block;
-struct Mem5Block {
-  union {
-    char aData[POW2_MIN];
-    struct {
-      int next;       /* Index in mem.aPool[] of next free chunk */
-      int prev;       /* Index in mem.aPool[] of previous free chunk */
-    } list;
-  } u;
+typedef struct Mem5Link Mem5Link;
+struct Mem5Link {
+  int next;       /* Index of next free chunk */
+  int prev;       /* Index of previous free chunk */
 };
 
 /*
-** Number of blocks of memory available for allocation.
-*/
-#define NBLOCK (SQLITE_POW2_MEMORY_SIZE/POW2_MIN)
-
-/*
-** The size in blocks of an POW2_MAX allocation
+** Maximum size of any allocation is ((1<<LOGMAX)*mem5.nAtom). Since
+** mem5.nAtom is always at least 8, this is not really a practical
+** limitation.
 */
-#define SZ_MAX (1<<(NSIZE-1))
+#define LOGMAX 30
 
 /*
-** Masks used for mem.aCtrl[] elements.
+** Masks used for mem5.aCtrl[] elements.
 */
 #define CTRL_LOGSIZE  0x1f    /* Log2 Size of this block relative to POW2_MIN */
 #define CTRL_FREE     0x20    /* True if not checked out */
 
 /*
 ** All of the static variables used by this module are collected
-** into a single structure named "mem".  This is to keep the
+** into a single structure named "mem5".  This is to keep the
 ** static variables organized and to reduce namespace pollution
 ** when this module is combined with other in the amalgamation.
 */
 static struct {
   /*
-  ** The alarm callback and its arguments.  The mem.mutex lock will
+  ** The alarm callback and its arguments.  The mem5.mutex lock will
   ** be held while the callback is running.  Recursive calls into
   ** the memory subsystem are allowed, but no new callbacks will be
   ** issued.  The alarmBusy variable is set to prevent recursive
@@ -12457,148 +13027,79 @@
   /*
   ** Lists of free blocks of various sizes.
   */
-  int aiFreelist[NSIZE];
+  int aiFreelist[LOGMAX+1];
 
   /*
   ** Space for tracking which blocks are checked out and the size
   ** of each block.  One byte per block.
   */
-  u8 aCtrl[NBLOCK];
+  u8 *aCtrl;
 
   /*
   ** Memory available for allocation
   */
-  Mem5Block aPool[NBLOCK];
-} mem;
+  int nAtom;       /* Smallest possible allocation in bytes */
+  int nBlock;      /* Number of nAtom sized blocks in zPool */
+  u8 *zPool;
+} mem5;
+
+#define MEM5LINK(idx) ((Mem5Link *)(&mem5.zPool[(idx)*mem5.nAtom]))
 
 /*
-** Unlink the chunk at mem.aPool[i] from list it is currently
-** on.  It should be found on mem.aiFreelist[iLogsize].
+** Unlink the chunk at mem5.aPool[i] from list it is currently
+** on.  It should be found on mem5.aiFreelist[iLogsize].
 */
 static void memsys5Unlink(int i, int iLogsize){
   int next, prev;
-  assert( i>=0 && i<NBLOCK );
-  assert( iLogsize>=0 && iLogsize<NSIZE );
-  assert( (mem.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
-  assert( sqlite3_mutex_held(mem.mutex) );
+  assert( i>=0 && i<mem5.nBlock );
+  assert( iLogsize>=0 && iLogsize<=LOGMAX );
+  assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
 
-  next = mem.aPool[i].u.list.next;
-  prev = mem.aPool[i].u.list.prev;
+  next = MEM5LINK(i)->next;
+  prev = MEM5LINK(i)->prev;
   if( prev<0 ){
-    mem.aiFreelist[iLogsize] = next;
+    mem5.aiFreelist[iLogsize] = next;
   }else{
-    mem.aPool[prev].u.list.next = next;
+    MEM5LINK(prev)->next = next;
   }
   if( next>=0 ){
-    mem.aPool[next].u.list.prev = prev;
+    MEM5LINK(next)->prev = prev;
   }
 }
 
 /*
-** Link the chunk at mem.aPool[i] so that is on the iLogsize
+** Link the chunk at mem5.aPool[i] so that is on the iLogsize
 ** free list.
 */
 static void memsys5Link(int i, int iLogsize){
   int x;
-  assert( sqlite3_mutex_held(mem.mutex) );
-  assert( i>=0 && i<NBLOCK );
-  assert( iLogsize>=0 && iLogsize<NSIZE );
-  assert( (mem.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
+  assert( sqlite3_mutex_held(mem5.mutex) );
+  assert( i>=0 && i<mem5.nBlock );
+  assert( iLogsize>=0 && iLogsize<=LOGMAX );
+  assert( (mem5.aCtrl[i] & CTRL_LOGSIZE)==iLogsize );
 
-  mem.aPool[i].u.list.next = x = mem.aiFreelist[iLogsize];
-  mem.aPool[i].u.list.prev = -1;
+  x = MEM5LINK(i)->next = mem5.aiFreelist[iLogsize];
+  MEM5LINK(i)->prev = -1;
   if( x>=0 ){
-    assert( x<NBLOCK );
-    mem.aPool[x].u.list.prev = i;
+    assert( x<mem5.nBlock );
+    MEM5LINK(x)->prev = i;
   }
-  mem.aiFreelist[iLogsize] = i;
+  mem5.aiFreelist[iLogsize] = i;
 }
 
 /*
-** Enter the mutex mem.mutex. Allocate it if it is not already allocated.
-**
-** Also:  Initialize the memory allocation subsystem the first time
-** this routine is called.
+** If the STATIC_MEM mutex is not already held, obtain it now. The mutex
+** will already be held (obtained by code in malloc.c) if
+** sqlite3Config.bMemStat is true.
 */
 static void memsys5Enter(void){
-  if( mem.mutex==0 ){
-    int i;
-    assert( sizeof(Mem5Block)==POW2_MIN );
-    assert( (SQLITE_POW2_MEMORY_SIZE % POW2_MAX)==0 );
-    assert( SQLITE_POW2_MEMORY_SIZE>=POW2_MAX );
-    mem.mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM);
-    sqlite3_mutex_enter(mem.mutex);
-    for(i=0; i<NSIZE; i++) mem.aiFreelist[i] = -1;
-    for(i=0; i<=NBLOCK-SZ_MAX; i += SZ_MAX){
-      mem.aCtrl[i] = (NSIZE-1) | CTRL_FREE;
-      memsys5Link(i, NSIZE-1);
-    }
-  }else{
-    sqlite3_mutex_enter(mem.mutex);
-  }
-}
-
-/*
-** Return the amount of memory currently checked out.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
-  return mem.currentOut;
-}
-
-/*
-** Return the maximum amount of memory that has ever been
-** checked out since either the beginning of this process
-** or since the most recent reset.
-*/
-SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
-  sqlite3_int64 n;
-  memsys5Enter();
-  n = mem.maxOut;
-  if( resetFlag ){
-    mem.maxOut = mem.currentOut;
+  if( sqlite3Config.bMemstat==0 && mem5.mutex==0 ){
+    mem5.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
   }
-  sqlite3_mutex_leave(mem.mutex);  
-  return n;
-}
-
-
-/*
-** Trigger the alarm 
-*/
-static void memsys5Alarm(int nByte){
-  void (*xCallback)(void*,sqlite3_int64,int);
-  sqlite3_int64 nowUsed;
-  void *pArg;
-  if( mem.alarmCallback==0 || mem.alarmBusy  ) return;
-  mem.alarmBusy = 1;
-  xCallback = mem.alarmCallback;
-  nowUsed = mem.currentOut;
-  pArg = mem.alarmArg;
-  sqlite3_mutex_leave(mem.mutex);
-  xCallback(pArg, nowUsed, nByte);
-  sqlite3_mutex_enter(mem.mutex);
-  mem.alarmBusy = 0;
+  sqlite3_mutex_enter(mem5.mutex);
 }
-
-/*
-** Change the alarm callback.
-**
-** This is a no-op for the static memory allocator.  The purpose
-** of the memory alarm is to support sqlite3_soft_heap_limit().
-** But with this memory allocator, the soft_heap_limit is really
-** a hard limit that is fixed at SQLITE_POW2_MEMORY_SIZE.
-*/
-SQLITE_API int sqlite3_memory_alarm(
-  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
-  void *pArg,
-  sqlite3_int64 iThreshold
-){
-  memsys5Enter();
-  mem.alarmCallback = xCallback;
-  mem.alarmArg = pArg;
-  mem.alarmThreshold = iThreshold;
-  sqlite3_mutex_leave(mem.mutex);
-  return SQLITE_OK;
+static void memsys5Leave(void){
+  sqlite3_mutex_leave(mem5.mutex);
 }
 
 /*
@@ -12606,12 +13107,12 @@
 ** size returned omits the 8-byte header overhead.  This only
 ** works for chunks that are currently checked out.
 */
-SQLITE_PRIVATE int sqlite3MallocSize(void *p){
+static int memsys5Size(void *p){
   int iSize = 0;
   if( p ){
-    int i = ((Mem5Block*)p) - mem.aPool;
-    assert( i>=0 && i<NBLOCK );
-    iSize = 1 << ((mem.aCtrl[i]&CTRL_LOGSIZE) + SQLITE_POW2_LOGMIN);
+    int i = ((u8 *)p-mem5.zPool)/mem5.nAtom;
+    assert( i>=0 && i<mem5.nBlock );
+    iSize = mem5.nAtom * (1 << (mem5.aCtrl[i]&CTRL_LOGSIZE));
   }
   return iSize;
 }
@@ -12624,12 +13125,12 @@
   int i;
   int iFirst;
 
-  assert( iLogsize>=0 && iLogsize<NSIZE );
-  i = iFirst = mem.aiFreelist[iLogsize];
+  assert( iLogsize>=0 && iLogsize<=LOGMAX );
+  i = iFirst = mem5.aiFreelist[iLogsize];
   assert( iFirst>=0 );
   while( i>0 ){
     if( i<iFirst ) iFirst = i;
-    i = mem.aPool[i].u.list.next;
+    i = MEM5LINK(i)->next;
   }
   memsys5Unlink(iFirst, iLogsize);
   return iFirst;
@@ -12639,121 +13140,117 @@
 ** Return a block of memory of at least nBytes in size.
 ** Return NULL if unable.
 */
-static void *memsys5Malloc(int nByte){
-  int i;           /* Index of a mem.aPool[] slot */
-  int iBin;        /* Index into mem.aiFreelist[] */
+static void *memsys5MallocUnsafe(int nByte){
+  int i;           /* Index of a mem5.aPool[] slot */
+  int iBin;        /* Index into mem5.aiFreelist[] */
   int iFullSz;     /* Size of allocation rounded up to power of 2 */
   int iLogsize;    /* Log2 of iFullSz/POW2_MIN */
 
-  assert( sqlite3_mutex_held(mem.mutex) );
-
   /* Keep track of the maximum allocation request.  Even unfulfilled
   ** requests are counted */
-  if( nByte>mem.maxRequest ){
-    mem.maxRequest = nByte;
+  if( nByte>mem5.maxRequest ){
+    mem5.maxRequest = nByte;
   }
 
-  /* Simulate a memory allocation fault */
-  if( sqlite3FaultStep(SQLITE_FAULTINJECTOR_MALLOC) ) return 0;
-
   /* Round nByte up to the next valid power of two */
   if( nByte>POW2_MAX ) return 0;
-  for(iFullSz=POW2_MIN, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
-
-  /* If we will be over the memory alarm threshold after this allocation,
-  ** then trigger the memory overflow alarm */
-  if( mem.alarmCallback!=0 && mem.currentOut+iFullSz>=mem.alarmThreshold ){
-    memsys5Alarm(iFullSz);
-  }
+  for(iFullSz=mem5.nAtom, iLogsize=0; iFullSz<nByte; iFullSz *= 2, iLogsize++){}
 
-  /* Make sure mem.aiFreelist[iLogsize] contains at least one free
+  /* Make sure mem5.aiFreelist[iLogsize] contains at least one free
   ** block.  If not, then split a block of the next larger power of
   ** two in order to create a new free block of size iLogsize.
   */
-  for(iBin=iLogsize; mem.aiFreelist[iBin]<0 && iBin<NSIZE; iBin++){}
-  if( iBin>=NSIZE ) return 0;
+  for(iBin=iLogsize; mem5.aiFreelist[iBin]<0 && iBin<=LOGMAX; iBin++){}
+  if( iBin>LOGMAX ) return 0;
   i = memsys5UnlinkFirst(iBin);
   while( iBin>iLogsize ){
     int newSize;
 
     iBin--;
     newSize = 1 << iBin;
-    mem.aCtrl[i+newSize] = CTRL_FREE | iBin;
+    mem5.aCtrl[i+newSize] = CTRL_FREE | iBin;
     memsys5Link(i+newSize, iBin);
   }
-  mem.aCtrl[i] = iLogsize;
+  mem5.aCtrl[i] = iLogsize;
 
   /* Update allocator performance statistics. */
-  mem.nAlloc++;
-  mem.totalAlloc += iFullSz;
-  mem.totalExcess += iFullSz - nByte;
-  mem.currentCount++;
-  mem.currentOut += iFullSz;
-  if( mem.maxCount<mem.currentCount ) mem.maxCount = mem.currentCount;
-  if( mem.maxOut<mem.currentOut ) mem.maxOut = mem.currentOut;
+  mem5.nAlloc++;
+  mem5.totalAlloc += iFullSz;
+  mem5.totalExcess += iFullSz - nByte;
+  mem5.currentCount++;
+  mem5.currentOut += iFullSz;
+  if( mem5.maxCount<mem5.currentCount ) mem5.maxCount = mem5.currentCount;
+  if( mem5.maxOut<mem5.currentOut ) mem5.maxOut = mem5.currentOut;
 
   /* Return a pointer to the allocated memory. */
-  return (void*)&mem.aPool[i];
+  return (void*)&mem5.zPool[i*mem5.nAtom];
 }
 
 /*
 ** Free an outstanding memory allocation.
 */
-void memsys5Free(void *pOld){
+static void memsys5FreeUnsafe(void *pOld){
   u32 size, iLogsize;
-  int i;
+  int iBlock;             
 
-  i = ((Mem5Block*)pOld) - mem.aPool;
-  assert( sqlite3_mutex_held(mem.mutex) );
-  assert( i>=0 && i<NBLOCK );
-  assert( (mem.aCtrl[i] & CTRL_FREE)==0 );
-  iLogsize = mem.aCtrl[i] & CTRL_LOGSIZE;
+  /* Set iBlock to the index of the block pointed to by pOld in 
+  ** the array of mem5.nAtom byte blocks pointed to by mem5.zPool.
+  */
+  iBlock = ((u8 *)pOld-mem5.zPool)/mem5.nAtom;
+
+  /* Check that the pointer pOld points to a valid, non-free block. */
+  assert( iBlock>=0 && iBlock<mem5.nBlock );
+  assert( ((u8 *)pOld-mem5.zPool)%mem5.nAtom==0 );
+  assert( (mem5.aCtrl[iBlock] & CTRL_FREE)==0 );
+
+  iLogsize = mem5.aCtrl[iBlock] & CTRL_LOGSIZE;
   size = 1<<iLogsize;
-  assert( i+size-1<NBLOCK );
-  mem.aCtrl[i] |= CTRL_FREE;
-  mem.aCtrl[i+size-1] |= CTRL_FREE;
-  assert( mem.currentCount>0 );
-  assert( mem.currentOut>=0 );
-  mem.currentCount--;
-  mem.currentOut -= size*POW2_MIN;
-  assert( mem.currentOut>0 || mem.currentCount==0 );
-  assert( mem.currentCount>0 || mem.currentOut==0 );
+  assert( iBlock+size-1<mem5.nBlock );
 
-  mem.aCtrl[i] = CTRL_FREE | iLogsize;
-  while( iLogsize<NSIZE-1 ){
-    int iBuddy;
+  mem5.aCtrl[iBlock] |= CTRL_FREE;
+  mem5.aCtrl[iBlock+size-1] |= CTRL_FREE;
+  assert( mem5.currentCount>0 );
+  assert( mem5.currentOut>=0 );
+  mem5.currentCount--;
+  mem5.currentOut -= size*mem5.nAtom;
+  assert( mem5.currentOut>0 || mem5.currentCount==0 );
+  assert( mem5.currentCount>0 || mem5.currentOut==0 );
 
-    if( (i>>iLogsize) & 1 ){
-      iBuddy = i - size;
+  mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
+  while( iLogsize<LOGMAX ){
+    int iBuddy;
+    if( (iBlock>>iLogsize) & 1 ){
+      iBuddy = iBlock - size;
     }else{
-      iBuddy = i + size;
+      iBuddy = iBlock + size;
     }
-    assert( iBuddy>=0 && iBuddy<NBLOCK );
-    if( mem.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
+    assert( iBuddy>=0 );
+    if( (iBuddy+(1<<iLogsize))>mem5.nBlock ) break;
+    if( mem5.aCtrl[iBuddy]!=(CTRL_FREE | iLogsize) ) break;
     memsys5Unlink(iBuddy, iLogsize);
     iLogsize++;
-    if( iBuddy<i ){
-      mem.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
-      mem.aCtrl[i] = 0;
-      i = iBuddy;
+    if( iBuddy<iBlock ){
+      mem5.aCtrl[iBuddy] = CTRL_FREE | iLogsize;
+      mem5.aCtrl[iBlock] = 0;
+      iBlock = iBuddy;
     }else{
-      mem.aCtrl[i] = CTRL_FREE | iLogsize;
-      mem.aCtrl[iBuddy] = 0;
+      mem5.aCtrl[iBlock] = CTRL_FREE | iLogsize;
+      mem5.aCtrl[iBuddy] = 0;
     }
     size *= 2;
   }
-  memsys5Link(i, iLogsize);
+  memsys5Link(iBlock, iLogsize);
 }
 
 /*
 ** Allocate nBytes of memory
 */
-SQLITE_API void *sqlite3_malloc(int nBytes){
+static void *memsys5Malloc(int nBytes){
   sqlite3_int64 *p = 0;
   if( nBytes>0 ){
     memsys5Enter();
-    p = memsys5Malloc(nBytes);
-    sqlite3_mutex_leave(mem.mutex);
+    p = memsys5MallocUnsafe(nBytes);
+    memsys5Leave();
   }
   return (void*)p; 
 }
@@ -12761,52 +13258,116 @@
 /*
 ** Free memory.
 */
-SQLITE_API void sqlite3_free(void *pPrior){
+static void memsys5Free(void *pPrior){
   if( pPrior==0 ){
+assert(0);
     return;
   }
-  assert( mem.mutex!=0 );
-  sqlite3_mutex_enter(mem.mutex);
-  memsys5Free(pPrior);
-  sqlite3_mutex_leave(mem.mutex);  
+  memsys5Enter();
+  memsys5FreeUnsafe(pPrior);
+  memsys5Leave();  
 }
 
 /*
 ** Change the size of an existing memory allocation
 */
-SQLITE_API void *sqlite3_realloc(void *pPrior, int nBytes){
+static void *memsys5Realloc(void *pPrior, int nBytes){
   int nOld;
   void *p;
   if( pPrior==0 ){
-    return sqlite3_malloc(nBytes);
+    return memsys5Malloc(nBytes);
   }
   if( nBytes<=0 ){
-    sqlite3_free(pPrior);
+    memsys5Free(pPrior);
     return 0;
   }
-  assert( mem.mutex!=0 );
-  nOld = sqlite3MallocSize(pPrior);
+  nOld = memsys5Size(pPrior);
   if( nBytes<=nOld ){
     return pPrior;
   }
-  sqlite3_mutex_enter(mem.mutex);
-  p = memsys5Malloc(nBytes);
+  memsys5Enter();
+  p = memsys5MallocUnsafe(nBytes);
   if( p ){
     memcpy(p, pPrior, nOld);
-    memsys5Free(pPrior);
+    memsys5FreeUnsafe(pPrior);
   }
-  sqlite3_mutex_leave(mem.mutex);
+  memsys5Leave();
   return p;
 }
 
 /*
+** Round up a request size to the next valid allocation size.
+*/
+static int memsys5Roundup(int n){
+  int iFullSz;
+  for(iFullSz=mem5.nAtom; iFullSz<n; iFullSz *= 2);
+  return iFullSz;
+}
+
+static int memsys5Log(int iValue){
+  int iLog;
+  for(iLog=0; (1<<iLog)<iValue; iLog++);
+  return iLog;
+}
+
+/*
+** Initialize this module.
+*/
+static int memsys5Init(void *NotUsed){
+  int ii;
+  int nByte = sqlite3Config.nHeap;
+  u8 *zByte = (u8 *)sqlite3Config.pHeap;
+  int nMinLog;                 /* Log of minimum allocation size in bytes*/
+  int iOffset;
+
+  if( !zByte ){
+    return SQLITE_ERROR;
+  }
+
+  nMinLog = memsys5Log(sqlite3Config.mnReq);
+  mem5.nAtom = (1<<nMinLog);
+  while( sizeof(Mem5Link)>mem5.nAtom ){
+    mem5.nAtom = mem5.nAtom << 1;
+  }
+
+  mem5.nBlock = (nByte / (mem5.nAtom+sizeof(u8)));
+  mem5.zPool = zByte;
+  mem5.aCtrl = (u8 *)&mem5.zPool[mem5.nBlock*mem5.nAtom];
+
+  for(ii=0; ii<=LOGMAX; ii++){
+    mem5.aiFreelist[ii] = -1;
+  }
+
+  iOffset = 0;
+  for(ii=LOGMAX; ii>=0; ii--){
+    int nAlloc = (1<<ii);
+    if( (iOffset+nAlloc)<=mem5.nBlock ){
+      mem5.aCtrl[iOffset] = ii | CTRL_FREE;
+      memsys5Link(iOffset, ii);
+      iOffset += nAlloc;
+    }
+    assert((iOffset+nAlloc)>mem5.nBlock);
+  }
+
+  return SQLITE_OK;
+}
+
+/*
+** Deinitialize this module.
+*/
+static void memsys5Shutdown(void *NotUsed){
+  return;
+}
+
+/*
 ** Open the file indicated and write a log of all unfreed memory 
 ** allocations into that log.
 */
-SQLITE_PRIVATE void sqlite3MemdebugDump(const char *zFilename){
+SQLITE_PRIVATE void sqlite3Memsys5Dump(const char *zFilename){
 #ifdef SQLITE_DEBUG
   FILE *out;
   int i, j, n;
+  int nMinLog;
 
   if( zFilename==0 || zFilename[0]==0 ){
     out = stdout;
@@ -12819,19 +13380,20 @@
     }
   }
   memsys5Enter();
-  for(i=0; i<NSIZE; i++){
-    for(n=0, j=mem.aiFreelist[i]; j>=0; j = mem.aPool[j].u.list.next, n++){}
-    fprintf(out, "freelist items of size %d: %d\n", POW2_MIN << i, n);
-  }
-  fprintf(out, "mem.nAlloc       = %llu\n", mem.nAlloc);
-  fprintf(out, "mem.totalAlloc   = %llu\n", mem.totalAlloc);
-  fprintf(out, "mem.totalExcess  = %llu\n", mem.totalExcess);
-  fprintf(out, "mem.currentOut   = %u\n", mem.currentOut);
-  fprintf(out, "mem.currentCount = %u\n", mem.currentCount);
-  fprintf(out, "mem.maxOut       = %u\n", mem.maxOut);
-  fprintf(out, "mem.maxCount     = %u\n", mem.maxCount);
-  fprintf(out, "mem.maxRequest   = %u\n", mem.maxRequest);
-  sqlite3_mutex_leave(mem.mutex);
+  nMinLog = memsys5Log(mem5.nAtom);
+  for(i=0; i<=LOGMAX && i+nMinLog<32; i++){
+    for(n=0, j=mem5.aiFreelist[i]; j>=0; j = MEM5LINK(j)->next, n++){}
+    fprintf(out, "freelist items of size %d: %d\n", mem5.nAtom << i, n);
+  }
+  fprintf(out, "mem5.nAlloc       = %llu\n", mem5.nAlloc);
+  fprintf(out, "mem5.totalAlloc   = %llu\n", mem5.totalAlloc);
+  fprintf(out, "mem5.totalExcess  = %llu\n", mem5.totalExcess);
+  fprintf(out, "mem5.currentOut   = %u\n", mem5.currentOut);
+  fprintf(out, "mem5.currentCount = %u\n", mem5.currentCount);
+  fprintf(out, "mem5.maxOut       = %u\n", mem5.maxOut);
+  fprintf(out, "mem5.maxCount     = %u\n", mem5.maxCount);
+  fprintf(out, "mem5.maxRequest   = %u\n", mem5.maxRequest);
+  memsys5Leave();
   if( out==stdout ){
     fflush(stdout);
   }else{
@@ -12840,8 +13402,26 @@
 #endif
 }
 
+/*
+** This routine is the only routine in this file with external 
+** linkage. It returns a pointer to a static sqlite3_mem_methods
+** struct populated with the memsys5 methods.
+*/
+SQLITE_PRIVATE const sqlite3_mem_methods *sqlite3MemGetMemsys5(void){
+  static const sqlite3_mem_methods memsys5Methods = {
+     memsys5Malloc,
+     memsys5Free,
+     memsys5Realloc,
+     memsys5Size,
+     memsys5Roundup,
+     memsys5Init,
+     memsys5Shutdown,
+     0
+  };
+  return &memsys5Methods;
+}
 
-#endif /* !SQLITE_POW2_MEMORY_SIZE */
+#endif /* SQLITE_ENABLE_MEMSYS5 */
 
 /************** End of mem5.c ************************************************/
 /************** Begin file mutex.c *******************************************/
@@ -12866,61 +13446,205 @@
 ** implementation is suitable for testing.
 ** debugging purposes
 **
-** $Id: mutex.c,v 1.17 2008/03/26 18:34:43 danielk1977 Exp $
+** $Id: mutex.c,v 1.27 2008/06/19 08:51:24 danielk1977 Exp $
 */
 
-#ifdef SQLITE_MUTEX_NOOP_DEBUG
+#ifndef SQLITE_MUTEX_NOOP
 /*
-** In this implementation, mutexes do not provide any mutual exclusion.
-** But the error checking is provided.  This implementation is useful
-** for test purposes.
+** Initialize the mutex system.
 */
+SQLITE_PRIVATE int sqlite3MutexInit(void){ 
+  int rc = SQLITE_OK;
+  if( sqlite3Config.bCoreMutex ){
+    if( !sqlite3Config.mutex.xMutexAlloc ){
+      /* If the xMutexAlloc method has not been set, then the user did not
+      ** install a mutex implementation via sqlite3_config() prior to 
+      ** sqlite3_initialize() being called. This block copies pointers to
+      ** the default implementation into the sqlite3Config structure.
+      **
+      ** The danger is that although sqlite3_config() is not a threadsafe
+      ** API, sqlite3_initialize() is, and so multiple threads may be
+      ** attempting to run this function simultaneously. To guard write
+      ** access to the sqlite3Config structure, the 'MASTER' static mutex
+      ** is obtained before modifying it.
+      */
+      sqlite3_mutex_methods *p = sqlite3DefaultMutex();
+      sqlite3_mutex *pMaster = 0;
+  
+      rc = p->xMutexInit();
+      if( rc==SQLITE_OK ){
+        pMaster = p->xMutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+        assert(pMaster);
+        p->xMutexEnter(pMaster);
+        assert( sqlite3Config.mutex.xMutexAlloc==0 
+             || sqlite3Config.mutex.xMutexAlloc==p->xMutexAlloc
+        );
+        if( !sqlite3Config.mutex.xMutexAlloc ){
+          sqlite3Config.mutex = *p;
+        }
+        p->xMutexLeave(pMaster);
+      }
+    }else{
+      rc = sqlite3Config.mutex.xMutexInit();
+    }
+  }
+
+  return rc;
+}
 
 /*
-** The mutex object
+** Shutdown the mutex system. This call frees resources allocated by
+** sqlite3MutexInit().
 */
-struct sqlite3_mutex {
-  int id;     /* The mutex type */
-  int cnt;    /* Number of entries without a matching leave */
-};
+SQLITE_PRIVATE int sqlite3MutexEnd(void){
+  int rc = SQLITE_OK;
+  rc = sqlite3Config.mutex.xMutexEnd();
+  return rc;
+}
 
 /*
-** The sqlite3_mutex_alloc() routine allocates a new
-** mutex and returns a pointer to it.  If it returns NULL
-** that means that a mutex could not be allocated. 
+** Retrieve a pointer to a static mutex or allocate a new dynamic one.
 */
 SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int id){
-  static sqlite3_mutex aStatic[6];
-  sqlite3_mutex *pNew = 0;
-  switch( id ){
-    case SQLITE_MUTEX_FAST:
-    case SQLITE_MUTEX_RECURSIVE: {
-      pNew = sqlite3_malloc(sizeof(*pNew));
-      if( pNew ){
-        pNew->id = id;
-        pNew->cnt = 0;
-      }
-      break;
-    }
-    default: {
-      assert( id-2 >= 0 );
-      assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
-      pNew = &aStatic[id-2];
-      pNew->id = id;
-      break;
-    }
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return sqlite3Config.mutex.xMutexAlloc(id);
+}
+
+SQLITE_PRIVATE sqlite3_mutex *sqlite3MutexAlloc(int id){
+  if( !sqlite3Config.bCoreMutex ){
+    return 0;
   }
-  return pNew;
+  return sqlite3Config.mutex.xMutexAlloc(id);
 }
 
 /*
-** This routine deallocates a previously allocated mutex.
+** Free a dynamic mutex.
 */
 SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
-  assert( p );
-  assert( p->cnt==0 );
-  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
-  sqlite3_free(p);
+  if( p ){
+    sqlite3Config.mutex.xMutexFree(p);
+  }
+}
+
+/*
+** Obtain the mutex p. If some other thread already has the mutex, block
+** until it can be obtained.
+*/
+SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
+  if( p ){
+    sqlite3Config.mutex.xMutexEnter(p);
+  }
+}
+
+/*
+** Obtain the mutex p. If successful, return SQLITE_OK. Otherwise, if another
+** thread holds the mutex and it cannot be obtained, return SQLITE_BUSY.
+*/
+SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
+  int rc = SQLITE_OK;
+  if( p ){
+    return sqlite3Config.mutex.xMutexTry(p);
+  }
+  return rc;
+}
+
+/*
+** The sqlite3_mutex_leave() routine exits a mutex that was previously
+** entered by the same thread.  The behavior is undefined if the mutex 
+** is not currently entered. If a NULL pointer is passed as an argument
+** this function is a no-op.
+*/
+SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
+  if( p ){
+    sqlite3Config.mutex.xMutexLeave(p);
+  }
+}
+
+#ifndef NDEBUG
+/*
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+** intended for use inside assert() statements.
+*/
+SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
+  return p==0 || sqlite3Config.mutex.xMutexHeld(p);
+}
+SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
+  return p==0 || sqlite3Config.mutex.xMutexNotheld(p);
+}
+#endif
+
+#endif
+
+#ifdef SQLITE_MUTEX_NOOP_DEBUG
+/*
+** In this implementation, mutexes do not provide any mutual exclusion.
+** But the error checking is provided.  This implementation is useful
+** for test purposes.
+*/
+
+/*
+** The mutex object
+*/
+struct sqlite3_mutex {
+  int id;     /* The mutex type */
+  int cnt;    /* Number of entries without a matching leave */
+};
+
+/*
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+** intended for use inside assert() statements.
+*/
+static int noopMutexHeld(sqlite3_mutex *p){
+  return p==0 || p->cnt>0;
+}
+static int noopMutexNotheld(sqlite3_mutex *p){
+  return p==0 || p->cnt==0;
+}
+
+/*
+** Initialize and deinitialize the mutex subsystem.
+*/
+static int noopMutexInit(void){ return SQLITE_OK; }
+static int noopMutexEnd(void){ return SQLITE_OK; }
+
+/*
+** The sqlite3_mutex_alloc() routine allocates a new
+** mutex and returns a pointer to it.  If it returns NULL
+** that means that a mutex could not be allocated. 
+*/
+static sqlite3_mutex *noopMutexAlloc(int id){
+  static sqlite3_mutex aStatic[6];
+  sqlite3_mutex *pNew = 0;
+  switch( id ){
+    case SQLITE_MUTEX_FAST:
+    case SQLITE_MUTEX_RECURSIVE: {
+      pNew = sqlite3Malloc(sizeof(*pNew));
+      if( pNew ){
+        pNew->id = id;
+        pNew->cnt = 0;
+      }
+      break;
+    }
+    default: {
+      assert( id-2 >= 0 );
+      assert( id-2 < sizeof(aStatic)/sizeof(aStatic[0]) );
+      pNew = &aStatic[id-2];
+      pNew->id = id;
+      break;
+    }
+  }
+  return pNew;
+}
+
+/*
+** This routine deallocates a previously allocated mutex.
+*/
+static void noopMutexFree(sqlite3_mutex *p){
+  assert( p->cnt==0 );
+  assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
+  sqlite3_free(p);
 }
 
 /*
@@ -12934,14 +13658,12 @@
 ** can enter.  If the same thread tries to enter any other kind of mutex
 ** more than once, the behavior is undefined.
 */
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+static void noopMutexEnter(sqlite3_mutex *p){
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
   p->cnt++;
 }
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+static int noopMutexTry(sqlite3_mutex *p){
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
   p->cnt++;
   return SQLITE_OK;
 }
@@ -12952,22 +13674,27 @@
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
-  assert( p );
-  assert( sqlite3_mutex_held(p) );
+static void noopMutexLeave(sqlite3_mutex *p){
+  assert( noopMutexHeld(p) );
   p->cnt--;
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || noopMutexNotheld(p) );
 }
 
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use inside assert() statements.
-*/
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
-  return p==0 || p->cnt>0;
-}
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
-  return p==0 || p->cnt==0;
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
+    noopMutexInit,
+    noopMutexEnd,
+    noopMutexAlloc,
+    noopMutexFree,
+    noopMutexEnter,
+    noopMutexTry,
+    noopMutexLeave,
+
+    noopMutexHeld,
+    noopMutexNotheld
+  };
+
+  return &sMutex;
 }
 #endif /* SQLITE_MUTEX_NOOP_DEBUG */
 
@@ -12986,7 +13713,7 @@
 *************************************************************************
 ** This file contains the C functions that implement mutexes for OS/2
 **
-** $Id: mutex_os2.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $
+** $Id: mutex_os2.c,v 1.10 2008/06/23 22:13:28 pweilbacher Exp $
 */
 
 /*
@@ -13014,6 +13741,12 @@
 #define OS2_MUTEX_INITIALIZER   0,0,0,0
 
 /*
+** Initialize and deinitialize the mutex subsystem.
+*/
+static int os2MutexInit(void){ return SQLITE_OK; }
+static int os2MutexEnd(void){ return SQLITE_OK; }
+
+/*
 ** The sqlite3_mutex_alloc() routine allocates a new
 ** mutex and returns a pointer to it.  If it returns NULL
 ** that means that a mutex could not be allocated. 
@@ -13052,7 +13785,7 @@
 ** mutex types, the same mutex is returned on every call that has
 ** the same type number.
 */
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int iType){
+static sqlite3_mutex *os2MutexAlloc(int iType){
   sqlite3_mutex *p = NULL;
   switch( iType ){
     case SQLITE_MUTEX_FAST:
@@ -13120,8 +13853,8 @@
 ** This routine deallocates a previously allocated mutex.
 ** SQLite is careful to deallocate every mutex that it allocates.
 */
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
-  assert( p );
+static void os2MutexFree(sqlite3_mutex *p){
+  if( p==0 ) return;
   assert( p->nRef==0 );
   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
   DosCloseMutexSem( p->mutex );
@@ -13139,24 +13872,24 @@
 ** can enter.  If the same thread tries to enter any other kind of mutex
 ** more than once, the behavior is undefined.
 */
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
+static void os2MutexEnter(sqlite3_mutex *p){
   TID tid;
   PID holder1;
   ULONG holder2;
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+  if( p==0 ) return;
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
   DosRequestMutexSem(p->mutex, SEM_INDEFINITE_WAIT);
   DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
   p->owner = tid;
   p->nRef++;
 }
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
+static int os2MutexTry(sqlite3_mutex *p){
   int rc;
   TID tid;
   PID holder1;
   ULONG holder2;
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+  if( p==0 ) return SQLITE_OK;
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || os2MutexNotheld(p) );
   if( DosRequestMutexSem(p->mutex, SEM_IMMEDIATE_RETURN) == NO_ERROR) {
     DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
     p->owner = tid;
@@ -13175,10 +13908,11 @@
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
+static void os2MutexLeave(sqlite3_mutex *p){
   TID tid;
   PID holder1;
   ULONG holder2;
+  if( p==0 ) return;
   assert( p->nRef>0 );
   DosQueryMutexSem(p->mutex, &holder1, &tid, &holder2);
   assert( p->owner==tid );
@@ -13187,11 +13921,12 @@
   DosReleaseMutexSem(p->mutex);
 }
 
+#ifdef SQLITE_DEBUG
 /*
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
 ** intended for use inside assert() statements.
 */
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
+static int os2MutexHeld(sqlite3_mutex *p){
   TID tid;
   PID pid;
   ULONG ulCount;
@@ -13204,7 +13939,7 @@
   }
   return p==0 || (p->nRef!=0 && p->owner==tid);
 }
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
+static int os2MutexNotheld(sqlite3_mutex *p){
   TID tid;
   PID pid;
   ULONG ulCount;
@@ -13217,6 +13952,25 @@
   }
   return p==0 || p->nRef==0 || p->owner!=tid;
 }
+#endif
+
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
+    os2MutexInit,
+    os2MutexEnd,
+    os2MutexAlloc,
+    os2MutexFree,
+    os2MutexEnter,
+    os2MutexTry,
+    os2MutexLeave,
+#ifdef SQLITE_DEBUG
+    os2MutexHeld,
+    os2MutexNotheld
+#endif
+  };
+
+  return &sMutex;
+}
 #endif /* SQLITE_MUTEX_OS2 */
 
 /************** End of mutex_os2.c *******************************************/
@@ -13234,7 +13988,7 @@
 *************************************************************************
 ** This file contains the C functions that implement mutexes for pthreads
 **
-** $Id: mutex_unix.c,v 1.7 2008/03/29 12:47:27 rse Exp $
+** $Id: mutex_unix.c,v 1.13 2008/07/16 12:33:24 drh Exp $
 */
 
 /*
@@ -13268,6 +14022,37 @@
 #endif
 
 /*
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+** intended for use only inside assert() statements.  On some platforms,
+** 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 
+** 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.
+**
+** On those platforms where pthread_equal() is not atomic, SQLite
+** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
+** make sure no assert() statements are evaluated and hence these
+** routines are never called.
+*/
+#ifndef NDEBUG
+static int pthreadMutexHeld(sqlite3_mutex *p){
+  return (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
+}
+static int pthreadMutexNotheld(sqlite3_mutex *p){
+  return p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
+}
+#endif
+
+/*
+** Initialize and deinitialize the mutex subsystem.
+*/
+static int pthreadMutexInit(void){ return SQLITE_OK; }
+static int pthreadMutexEnd(void){ return SQLITE_OK; }
+
+/*
 ** The sqlite3_mutex_alloc() routine allocates a new
 ** mutex and returns a pointer to it.  If it returns NULL
 ** that means that a mutex could not be allocated.  SQLite
@@ -13308,7 +14093,7 @@
 ** mutex types, the same mutex is returned on every call that has
 ** the same type number.
 */
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int iType){
+static sqlite3_mutex *pthreadMutexAlloc(int iType){
   static sqlite3_mutex staticMutexes[] = {
     SQLITE3_MUTEX_INITIALIZER,
     SQLITE3_MUTEX_INITIALIZER,
@@ -13363,8 +14148,7 @@
 ** allocated mutex.  SQLite is careful to deallocate every
 ** mutex that it allocates.
 */
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
-  assert( p );
+static void pthreadMutexFree(sqlite3_mutex *p){
   assert( p->nRef==0 );
   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
   pthread_mutex_destroy(&p->mutex);
@@ -13382,9 +14166,8 @@
 ** can enter.  If the same thread tries to enter any other kind of mutex
 ** more than once, the behavior is undefined.
 */
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+static void pthreadMutexEnter(sqlite3_mutex *p){
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
 
 #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   /* If recursive mutexes are not available, then we have to grow
@@ -13422,10 +14205,9 @@
   }
 #endif
 }
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
+static int pthreadMutexTry(sqlite3_mutex *p){
   int rc;
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || pthreadMutexNotheld(p) );
 
 #ifdef SQLITE_HOMEGROWN_RECURSIVE_MUTEX
   /* If recursive mutexes are not available, then we have to grow
@@ -13443,7 +14225,7 @@
     if( p->nRef>0 && pthread_equal(p->owner, self) ){
       p->nRef++;
       rc = SQLITE_OK;
-    }else if( pthread_mutex_lock(&p->mutex)==0 ){
+    }else if( pthread_mutex_trylock(&p->mutex)==0 ){
       assert( p->nRef==0 );
       p->owner = self;
       p->nRef = 1;
@@ -13478,9 +14260,8 @@
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
-  assert( p );
-  assert( sqlite3_mutex_held(p) );
+static void pthreadMutexLeave(sqlite3_mutex *p){
+  assert( pthreadMutexHeld(p) );
   p->nRef--;
   assert( p->nRef==0 || p->id==SQLITE_MUTEX_RECURSIVE );
 
@@ -13499,30 +14280,24 @@
 #endif
 }
 
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use only inside assert() statements.  On some platforms,
-** 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 
-** 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.
-**
-** On those platforms where pthread_equal() is not atomic, SQLite
-** should be compiled without -DSQLITE_DEBUG and with -DNDEBUG to
-** make sure no assert() statements are evaluated and hence these
-** routines are never called.
-*/
-#ifndef NDEBUG
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
-  return p==0 || (p->nRef!=0 && pthread_equal(p->owner, pthread_self()));
-}
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
-  return p==0 || p->nRef==0 || pthread_equal(p->owner, pthread_self())==0;
-}
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
+    pthreadMutexInit,
+    pthreadMutexEnd,
+    pthreadMutexAlloc,
+    pthreadMutexFree,
+    pthreadMutexEnter,
+    pthreadMutexTry,
+    pthreadMutexLeave,
+#ifdef SQLITE_DEBUG
+    pthreadMutexHeld,
+    pthreadMutexNotheld
 #endif
+  };
+
+  return &sMutex;
+}
+
 #endif /* SQLITE_MUTEX_PTHREAD */
 
 /************** End of mutex_unix.c ******************************************/
@@ -13540,7 +14315,7 @@
 *************************************************************************
 ** This file contains the C functions that implement mutexes for win32
 **
-** $Id: mutex_w32.c,v 1.6 2008/03/26 18:34:43 danielk1977 Exp $
+** $Id: mutex_w32.c,v 1.11 2008/06/26 10:41:19 danielk1977 Exp $
 */
 
 /*
@@ -13570,7 +14345,7 @@
 ** WinNT/2K/XP so that we will know whether or not we can safely call
 ** the LockFileEx() API.
 */
-#if OS_WINCE
+#if SQLITE_OS_WINCE
 # define mutexIsNT()  (1)
 #else
   static int mutexIsNT(void){
@@ -13583,8 +14358,28 @@
     }
     return osType==2;
   }
-#endif /* OS_WINCE */
+#endif /* SQLITE_OS_WINCE */
+
+
+#ifdef SQLITE_DEBUG
+/*
+** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
+** intended for use only inside assert() statements.
+*/
+static int winMutexHeld(sqlite3_mutex *p){
+  return p->nRef!=0 && p->owner==GetCurrentThreadId();
+}
+static int winMutexNotheld(sqlite3_mutex *p){
+  return p->nRef==0 || p->owner!=GetCurrentThreadId();
+}
+#endif
+
 
+/*
+** Initialize and deinitialize the mutex subsystem.
+*/
+static int winMutexInit(void){ return SQLITE_OK; }
+static int winMutexEnd(void){ return SQLITE_OK; }
 
 /*
 ** The sqlite3_mutex_alloc() routine allocates a new
@@ -13625,7 +14420,7 @@
 ** mutex types, the same mutex is returned on every call that has
 ** the same type number.
 */
-SQLITE_API sqlite3_mutex *sqlite3_mutex_alloc(int iType){
+static sqlite3_mutex *winMutexAlloc(int iType){
   sqlite3_mutex *p;
 
   switch( iType ){
@@ -13669,7 +14464,7 @@
 ** allocated mutex.  SQLite is careful to deallocate every
 ** mutex that it allocates.
 */
-SQLITE_API void sqlite3_mutex_free(sqlite3_mutex *p){
+static void winMutexFree(sqlite3_mutex *p){
   assert( p );
   assert( p->nRef==0 );
   assert( p->id==SQLITE_MUTEX_FAST || p->id==SQLITE_MUTEX_RECURSIVE );
@@ -13688,17 +14483,15 @@
 ** can enter.  If the same thread tries to enter any other kind of mutex
 ** more than once, the behavior is undefined.
 */
-SQLITE_API void sqlite3_mutex_enter(sqlite3_mutex *p){
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+static void winMutexEnter(sqlite3_mutex *p){
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
   EnterCriticalSection(&p->mutex);
   p->owner = GetCurrentThreadId(); 
   p->nRef++;
 }
-SQLITE_API int sqlite3_mutex_try(sqlite3_mutex *p){
+static int winMutexTry(sqlite3_mutex *p){
   int rc = SQLITE_BUSY;
-  assert( p );
-  assert( p->id==SQLITE_MUTEX_RECURSIVE || sqlite3_mutex_notheld(p) );
+  assert( p->id==SQLITE_MUTEX_RECURSIVE || winMutexNotheld(p) );
   /*
   ** The sqlite3_mutex_try() routine is very rarely used, and when it
   ** is used it is merely an optimization.  So it is OK for it to always
@@ -13726,7 +14519,7 @@
 ** is undefined if the mutex is not currently entered or
 ** is not currently allocated.  SQLite will never do either.
 */
-SQLITE_API void sqlite3_mutex_leave(sqlite3_mutex *p){
+static void winMutexLeave(sqlite3_mutex *p){
   assert( p->nRef>0 );
   assert( p->owner==GetCurrentThreadId() );
   p->nRef--;
@@ -13734,15 +14527,22 @@
   LeaveCriticalSection(&p->mutex);
 }
 
-/*
-** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routine are
-** intended for use only inside assert() statements.
-*/
-SQLITE_API int sqlite3_mutex_held(sqlite3_mutex *p){
-  return p==0 || (p->nRef!=0 && p->owner==GetCurrentThreadId());
-}
-SQLITE_API int sqlite3_mutex_notheld(sqlite3_mutex *p){
-  return p==0 || p->nRef==0 || p->owner!=GetCurrentThreadId();
+SQLITE_PRIVATE sqlite3_mutex_methods *sqlite3DefaultMutex(void){
+  static sqlite3_mutex_methods sMutex = {
+    winMutexInit,
+    winMutexEnd,
+    winMutexAlloc,
+    winMutexFree,
+    winMutexEnter,
+    winMutexTry,
+    winMutexLeave,
+#ifdef SQLITE_DEBUG
+    winMutexHeld,
+    winMutexNotheld
+#endif
+  };
+
+  return &sMutex;
 }
 #endif /* SQLITE_MUTEX_W32 */
 
@@ -13759,10 +14559,10 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** Memory allocation functions used throughout sqlite.
 **
+** Memory allocation functions used throughout sqlite.
 **
-** $Id: malloc.c,v 1.15 2008/03/26 18:34:43 danielk1977 Exp $
+** $Id: malloc.c,v 1.28 2008/07/14 12:38:21 drh Exp $
 */
 
 /*
@@ -13779,8 +14579,8 @@
 }
 
 /*
-** Set the soft heap-size limit for the current thread. Passing a
-** zero or negative value indicates no limit.
+** Set the soft heap-size limit for the library. Passing a zero or 
+** negative value indicates no limit.
 */
 SQLITE_API void sqlite3_soft_heap_limit(int n){
   sqlite3_uint64 iLimit;
@@ -13790,6 +14590,7 @@
   }else{
     iLimit = n;
   }
+  sqlite3_initialize();
   if( iLimit>0 ){
     sqlite3_memory_alarm(softHeapLimitEnforcer, 0, iLimit);
   }else{
@@ -13802,7 +14603,9 @@
 }
 
 /*
-** Release memory held by SQLite instances created by the current thread.
+** Attempt to release up to n bytes of non-essential memory currently
+** held by SQLite. An example of non-essential memory is memory used to
+** cache database pages that are not currently in use.
 */
 SQLITE_API int sqlite3_release_memory(int n){
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
@@ -13814,12 +14617,467 @@
 #endif
 }
 
+/*
+** State information local to the memory allocation subsystem.
+*/
+static struct {
+  sqlite3_mutex *mutex;         /* Mutex to serialize access */
+
+  /*
+  ** The alarm callback and its arguments.  The mem0.mutex lock will
+  ** be held while the callback is running.  Recursive calls into
+  ** the memory subsystem are allowed, but no new callbacks will be
+  ** issued.  The alarmBusy variable is set to prevent recursive
+  ** callbacks.
+  */
+  sqlite3_int64 alarmThreshold;
+  void (*alarmCallback)(void*, sqlite3_int64,int);
+  void *alarmArg;
+  int alarmBusy;
+
+  /*
+  ** Pointers to the end of sqlite3Config.pScratch and
+  ** sqlite3Config.pPage to a block of memory that records
+  ** which pages are available.
+  */
+  u32 *aScratchFree;
+  u32 *aPageFree;
+
+  /* Number of free pages for scratch and page-cache memory */
+  u32 nScratchFree;
+  u32 nPageFree;
+} mem0;
+
+/*
+** Initialize the memory allocation subsystem.
+*/
+SQLITE_PRIVATE int sqlite3MallocInit(void){
+  if( sqlite3Config.m.xMalloc==0 ){
+    sqlite3MemSetDefault();
+  }
+  memset(&mem0, 0, sizeof(mem0));
+  if( sqlite3Config.bCoreMutex ){
+    mem0.mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM);
+  }
+  if( sqlite3Config.pScratch && sqlite3Config.szScratch>=3000
+      && sqlite3Config.nScratch>0 ){
+    int i;
+    mem0.aScratchFree = (u32*)&((char*)sqlite3Config.pScratch)
+                  [sqlite3Config.szScratch*sqlite3Config.nScratch];
+    for(i=0; i<sqlite3Config.nScratch; i++){ mem0.aScratchFree[i] = i; }
+    mem0.nScratchFree = sqlite3Config.nScratch;
+  }else{
+    sqlite3Config.pScratch = 0;
+    sqlite3Config.szScratch = 0;
+  }
+  if( sqlite3Config.pPage && sqlite3Config.szPage>=512
+      && sqlite3Config.nPage>0 ){
+    int i;
+    mem0.aPageFree = (u32*)&((char*)sqlite3Config.pPage)
+                  [sqlite3Config.szPage*sqlite3Config.nPage];
+    for(i=0; i<sqlite3Config.nPage; i++){ mem0.aPageFree[i] = i; }
+    mem0.nPageFree = sqlite3Config.nPage;
+  }else{
+    sqlite3Config.pPage = 0;
+    sqlite3Config.szPage = 0;
+  }
+  return sqlite3Config.m.xInit(sqlite3Config.m.pAppData);
+}
+
+/*
+** Deinitialize the memory allocation subsystem.
+*/
+SQLITE_PRIVATE void sqlite3MallocEnd(void){
+  sqlite3Config.m.xShutdown(sqlite3Config.m.pAppData);
+  memset(&mem0, 0, sizeof(mem0));
+}
+
+/*
+** Return the amount of memory currently checked out.
+*/
+SQLITE_API sqlite3_int64 sqlite3_memory_used(void){
+  int n, mx;
+  sqlite3_int64 res;
+  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, 0);
+  res = (sqlite3_int64)n;  /* Work around bug in Borland C. Ticket #3216 */
+  return res;
+}
+
+/*
+** Return the maximum amount of memory that has ever been
+** checked out since either the beginning of this process
+** or since the most recent reset.
+*/
+SQLITE_API sqlite3_int64 sqlite3_memory_highwater(int resetFlag){
+  int n, mx;
+  sqlite3_int64 res;
+  sqlite3_status(SQLITE_STATUS_MEMORY_USED, &n, &mx, resetFlag);
+  res = (sqlite3_int64)mx;  /* Work around bug in Borland C. Ticket #3216 */
+  return res;
+}
+
+/*
+** Change the alarm callback
+*/
+SQLITE_API int sqlite3_memory_alarm(
+  void(*xCallback)(void *pArg, sqlite3_int64 used,int N),
+  void *pArg,
+  sqlite3_int64 iThreshold
+){
+  sqlite3_mutex_enter(mem0.mutex);
+  mem0.alarmCallback = xCallback;
+  mem0.alarmArg = pArg;
+  mem0.alarmThreshold = iThreshold;
+  sqlite3_mutex_leave(mem0.mutex);
+  return SQLITE_OK;
+}
+
+/*
+** Trigger the alarm 
+*/
+static void sqlite3MallocAlarm(int nByte){
+  void (*xCallback)(void*,sqlite3_int64,int);
+  sqlite3_int64 nowUsed;
+  void *pArg;
+  if( mem0.alarmCallback==0 || mem0.alarmBusy  ) return;
+  mem0.alarmBusy = 1;
+  xCallback = mem0.alarmCallback;
+  nowUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+  pArg = mem0.alarmArg;
+  sqlite3_mutex_leave(mem0.mutex);
+  xCallback(pArg, nowUsed, nByte);
+  sqlite3_mutex_enter(mem0.mutex);
+  mem0.alarmBusy = 0;
+}
+
+/*
+** Do a memory allocation with statistics and alarms.  Assume the
+** lock is already held.
+*/
+static int mallocWithAlarm(int n, void **pp){
+  int nFull;
+  void *p;
+  assert( sqlite3_mutex_held(mem0.mutex) );
+  nFull = sqlite3Config.m.xRoundup(n);
+  sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, n);
+  if( mem0.alarmCallback!=0 ){
+    int nUsed = sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED);
+    if( nUsed+nFull >= mem0.alarmThreshold ){
+      sqlite3MallocAlarm(nFull);
+    }
+  }
+  p = sqlite3Config.m.xMalloc(nFull);
+  if( p==0 && mem0.alarmCallback ){
+    sqlite3MallocAlarm(nFull);
+    p = sqlite3Config.m.xMalloc(nFull);
+  }
+  if( p ) sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nFull);
+  *pp = p;
+  return nFull;
+}
+
+/*
+** Allocate memory.  This routine is like sqlite3_malloc() except that it
+** assumes the memory subsystem has already been initialized.
+*/
+SQLITE_PRIVATE void *sqlite3Malloc(int n){
+  void *p;
+  if( n<=0 ){
+    p = 0;
+  }else if( sqlite3Config.bMemstat ){
+    sqlite3_mutex_enter(mem0.mutex);
+    mallocWithAlarm(n, &p);
+    sqlite3_mutex_leave(mem0.mutex);
+  }else{
+    p = sqlite3Config.m.xMalloc(n);
+  }
+  return p;
+}
+
+/*
+** This version of the memory allocation is for use by the application.
+** First make sure the memory subsystem is initialized, then do the
+** allocation.
+*/
+SQLITE_API void *sqlite3_malloc(int n){
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return sqlite3Malloc(n);
+}
+
+/*
+** Each thread may only have a single outstanding allocation from
+** xScratchMalloc().  We verify this constraint in the single-threaded
+** case by setting scratchAllocOut to 1 when an allocation
+** is outstanding clearing it when the allocation is freed.
+*/
+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+static int scratchAllocOut = 0;
+#endif
+
+
+/*
+** Allocate memory that is to be used and released right away.
+** This routine is similar to alloca() in that it is not intended
+** for situations where the memory might be held long-term.  This
+** routine is intended to get memory to old large transient data
+** structures that would not normally fit on the stack of an
+** embedded processor.
+*/
+SQLITE_PRIVATE void *sqlite3ScratchMalloc(int n){
+  void *p;
+  assert( n>0 );
+
+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+  /* Verify that no more than one scratch allocation per thread
+  ** is outstanding at one time.  (This is only checked in the
+  ** single-threaded case since checking in the multi-threaded case
+  ** would be much more complicated.) */
+  assert( scratchAllocOut==0 );
+#endif
+
+  if( sqlite3Config.szScratch<n ){
+    goto scratch_overflow;
+  }else{  
+    sqlite3_mutex_enter(mem0.mutex);
+    if( mem0.nScratchFree==0 ){
+      sqlite3_mutex_leave(mem0.mutex);
+      goto scratch_overflow;
+    }else{
+      int i;
+      i = mem0.aScratchFree[--mem0.nScratchFree];
+      sqlite3_mutex_leave(mem0.mutex);
+      i *= sqlite3Config.szScratch;
+      sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, 1);
+      p = (void*)&((char*)sqlite3Config.pScratch)[i];
+    }
+  }
+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+  scratchAllocOut = p!=0;
+#endif
+
+  return p;
+
+scratch_overflow:
+  if( sqlite3Config.bMemstat ){
+    sqlite3_mutex_enter(mem0.mutex);
+    n = mallocWithAlarm(n, &p);
+    if( p ) sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, n);
+    sqlite3_mutex_leave(mem0.mutex);
+  }else{
+    p = sqlite3Config.m.xMalloc(n);
+  }
+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+  scratchAllocOut = p!=0;
+#endif
+  return p;    
+}
+SQLITE_PRIVATE void sqlite3ScratchFree(void *p){
+  if( p ){
+
+#if SQLITE_THREADSAFE==0 && !defined(NDEBUG)
+    /* Verify that no more than one scratch allocation per thread
+    ** is outstanding at one time.  (This is only checked in the
+    ** single-threaded case since checking in the multi-threaded case
+    ** would be much more complicated.) */
+    assert( scratchAllocOut==1 );
+    scratchAllocOut = 0;
+#endif
+
+    if( sqlite3Config.pScratch==0
+           || p<sqlite3Config.pScratch
+           || p>=(void*)mem0.aScratchFree ){
+      if( sqlite3Config.bMemstat ){
+        int iSize = sqlite3MallocSize(p);
+        sqlite3_mutex_enter(mem0.mutex);
+        sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_OVERFLOW, -iSize);
+        sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
+        sqlite3Config.m.xFree(p);
+        sqlite3_mutex_leave(mem0.mutex);
+      }else{
+        sqlite3Config.m.xFree(p);
+      }
+    }else{
+      int i;
+      i = (u8 *)p - (u8 *)sqlite3Config.pScratch;
+      i /= sqlite3Config.szScratch;
+      assert( i>=0 && i<sqlite3Config.nScratch );
+      sqlite3_mutex_enter(mem0.mutex);
+      assert( mem0.nScratchFree<sqlite3Config.nScratch );
+      mem0.aScratchFree[mem0.nScratchFree++] = i;
+      sqlite3StatusAdd(SQLITE_STATUS_SCRATCH_USED, -1);
+      sqlite3_mutex_leave(mem0.mutex);
+    }
+  }
+}
+
+/*
+** Allocate memory to be used by the page cache.  Make use of the
+** memory buffer provided by SQLITE_CONFIG_PAGECACHE if there is one
+** and that memory is of the right size and is not completely
+** consumed.  Otherwise, failover to sqlite3Malloc().
+*/
+SQLITE_PRIVATE void *sqlite3PageMalloc(int n){
+  void *p;
+  assert( n>0 );
+  assert( (n & (n-1))==0 );
+  assert( n>=512 && n<=32768 );
+
+  if( sqlite3Config.szPage<n ){
+    goto page_overflow;
+  }else{  
+    sqlite3_mutex_enter(mem0.mutex);
+    if( mem0.nPageFree==0 ){
+      sqlite3_mutex_leave(mem0.mutex);
+      goto page_overflow;
+    }else{
+      int i;
+      i = mem0.aPageFree[--mem0.nPageFree];
+      sqlite3_mutex_leave(mem0.mutex);
+      i *= sqlite3Config.szPage;
+      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, 1);
+      p = (void*)&((char*)sqlite3Config.pPage)[i];
+    }
+  }
+  return p;
+
+page_overflow:
+  if( sqlite3Config.bMemstat ){
+    sqlite3_mutex_enter(mem0.mutex);
+    n = mallocWithAlarm(n, &p);
+    if( p ) sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, n);
+    sqlite3_mutex_leave(mem0.mutex);
+  }else{
+    p = sqlite3Config.m.xMalloc(n);
+  }
+  return p;    
+}
+SQLITE_PRIVATE void sqlite3PageFree(void *p){
+  if( p ){
+    if( sqlite3Config.pPage==0
+           || p<sqlite3Config.pPage
+           || p>=(void*)mem0.aPageFree ){
+      /* In this case, the page allocation was obtained from a regular 
+      ** call to sqlite3_mem_methods.xMalloc() (a page-cache-memory 
+      ** "overflow"). Free the block with sqlite3_mem_methods.xFree().
+      */
+      if( sqlite3Config.bMemstat ){
+        int iSize = sqlite3MallocSize(p);
+        sqlite3_mutex_enter(mem0.mutex);
+        sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_OVERFLOW, -iSize);
+        sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -iSize);
+        sqlite3Config.m.xFree(p);
+        sqlite3_mutex_leave(mem0.mutex);
+      }else{
+        sqlite3Config.m.xFree(p);
+      }
+    }else{
+      /* The page allocation was allocated from the sqlite3Config.pPage
+      ** buffer. In this case all that is add the index of the page in
+      ** the sqlite3Config.pPage array to the set of free indexes stored
+      ** in the mem0.aPageFree[] array.
+      */
+      int i;
+      i = (u8 *)p - (u8 *)sqlite3Config.pPage;
+      i /= sqlite3Config.szPage;
+      assert( i>=0 && i<sqlite3Config.nPage );
+      sqlite3_mutex_enter(mem0.mutex);
+      assert( mem0.nPageFree<sqlite3Config.nPage );
+      mem0.aPageFree[mem0.nPageFree++] = i;
+      sqlite3StatusAdd(SQLITE_STATUS_PAGECACHE_USED, -1);
+      sqlite3_mutex_leave(mem0.mutex);
+#ifndef NDEBUG
+      /* Assert that a duplicate was not just inserted into aPageFree[]. */
+      for(i=0; i<mem0.nPageFree-1; i++){
+        assert( mem0.aPageFree[i]!=mem0.aPageFree[mem0.nPageFree-1] );
+      }
+#endif
+    }
+  }
+}
+
+/*
+** Return the size of a memory allocation previously obtained from
+** sqlite3Malloc() or sqlite3_malloc().
+*/
+SQLITE_PRIVATE int sqlite3MallocSize(void *p){
+  return sqlite3Config.m.xSize(p);
+}
+
+/*
+** Free memory previously obtained from sqlite3Malloc().
+*/
+SQLITE_API void sqlite3_free(void *p){
+  if( p==0 ) return;
+  if( sqlite3Config.bMemstat ){
+    sqlite3_mutex_enter(mem0.mutex);
+    sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, -sqlite3MallocSize(p));
+    sqlite3Config.m.xFree(p);
+    sqlite3_mutex_leave(mem0.mutex);
+  }else{
+    sqlite3Config.m.xFree(p);
+  }
+}
+
+/*
+** Change the size of an existing memory allocation
+*/
+SQLITE_PRIVATE void *sqlite3Realloc(void *pOld, int nBytes){
+  int nOld, nNew;
+  void *pNew;
+  if( pOld==0 ){
+    return sqlite3Malloc(nBytes);
+  }
+  if( nBytes<=0 ){
+    sqlite3_free(pOld);
+    return 0;
+  }
+  nOld = sqlite3MallocSize(pOld);
+  if( sqlite3Config.bMemstat ){
+    sqlite3_mutex_enter(mem0.mutex);
+    sqlite3StatusSet(SQLITE_STATUS_MALLOC_SIZE, nBytes);
+    nNew = sqlite3Config.m.xRoundup(nBytes);
+    if( nOld==nNew ){
+      pNew = pOld;
+    }else{
+      if( sqlite3StatusValue(SQLITE_STATUS_MEMORY_USED)+nNew-nOld >= 
+            mem0.alarmThreshold ){
+        sqlite3MallocAlarm(nNew-nOld);
+      }
+      pNew = sqlite3Config.m.xRealloc(pOld, nNew);
+      if( pNew==0 && mem0.alarmCallback ){
+        sqlite3MallocAlarm(nBytes);
+        pNew = sqlite3Config.m.xRealloc(pOld, nNew);
+      }
+      if( pNew ){
+        sqlite3StatusAdd(SQLITE_STATUS_MEMORY_USED, nNew-nOld);
+      }
+    }
+    sqlite3_mutex_leave(mem0.mutex);
+  }else{
+    pNew = sqlite3Config.m.xRealloc(pOld, nBytes);
+  }
+  return pNew;
+}
+
+/*
+** The public interface to sqlite3Realloc.  Make sure that the memory
+** subsystem is initialized prior to invoking sqliteRealloc.
+*/
+SQLITE_API void *sqlite3_realloc(void *pOld, int n){
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
+  return sqlite3Realloc(pOld, n);
+}
+
 
 /*
 ** Allocate and zero memory.
 */ 
-SQLITE_PRIVATE void *sqlite3MallocZero(unsigned n){
-  void *p = sqlite3_malloc(n);
+SQLITE_PRIVATE void *sqlite3MallocZero(int n){
+  void *p = sqlite3Malloc(n);
   if( p ){
     memset(p, 0, n);
   }
@@ -13830,7 +15088,7 @@
 ** Allocate and zero memory.  If the allocation fails, make
 ** the mallocFailed flag in the connection pointer.
 */
-SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, unsigned n){
+SQLITE_PRIVATE void *sqlite3DbMallocZero(sqlite3 *db, int n){
   void *p = sqlite3DbMallocRaw(db, n);
   if( p ){
     memset(p, 0, n);
@@ -13842,10 +15100,10 @@
 ** Allocate and zero memory.  If the allocation fails, make
 ** the mallocFailed flag in the connection pointer.
 */
-SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, unsigned n){
+SQLITE_PRIVATE void *sqlite3DbMallocRaw(sqlite3 *db, int n){
   void *p = 0;
   if( !db || db->mallocFailed==0 ){
-    p = sqlite3_malloc(n);
+    p = sqlite3Malloc(n);
     if( !p && db ){
       db->mallocFailed = 1;
     }
@@ -13893,14 +15151,14 @@
   int n;
   if( z==0 ) return 0;
   n = strlen(z)+1;
-  zNew = sqlite3_malloc(n);
+  zNew = sqlite3Malloc(n);
   if( zNew ) memcpy(zNew, z, n);
   return zNew;
 }
 SQLITE_PRIVATE char *sqlite3StrNDup(const char *z, int n){
   char *zNew;
   if( z==0 ) return 0;
-  zNew = sqlite3_malloc(n+1);
+  zNew = sqlite3Malloc(n+1);
   if( zNew ){
     memcpy(zNew, z, n);
     zNew[n] = 0;
@@ -13924,39 +15182,19 @@
 }
 
 /*
-** Create a string from the 2nd and subsequent arguments (up to the
-** first NULL argument), store the string in memory obtained from
-** sqliteMalloc() and make the pointer indicated by the 1st argument
-** point to that string.  The 1st argument must either be NULL or 
-** point to memory obtained from sqliteMalloc().
+** Create a string from the zFromat argument and the va_list that follows.
+** Store the string in memory obtained from sqliteMalloc() and make *pz
+** point to that string.
 */
-SQLITE_PRIVATE void sqlite3SetString(char **pz, ...){
+SQLITE_PRIVATE void sqlite3SetString(char **pz, sqlite3 *db, const char *zFormat, ...){
   va_list ap;
-  int nByte;
-  const char *z;
-  char *zResult;
+  char *z;
 
-  assert( pz!=0 );
-  nByte = 1;
-  va_start(ap, pz);
-  while( (z = va_arg(ap, const char*))!=0 ){
-    nByte += strlen(z);
-  }
+  va_start(ap, zFormat);
+  z = sqlite3VMPrintf(db, zFormat, ap);
   va_end(ap);
   sqlite3_free(*pz);
-  *pz = zResult = sqlite3_malloc(nByte);
-  if( zResult==0 ){
-    return;
-  }
-  *zResult = 0;
-  va_start(ap, pz);
-  while( (z = va_arg(ap, const char*))!=0 ){
-    int n = strlen(z);
-    memcpy(zResult, z, n);
-    zResult += n;
-  }
-  zResult[0] = 0;
-  va_end(ap);
+  *pz = z;
 }
 
 
@@ -13996,6 +15234,8 @@
 ** an historical reference.  Most of the "enhancements" have been backed
 ** out so that the functionality is now the same as standard printf().
 **
+** $Id: printf.c,v 1.92 2008/07/15 00:27:35 drh Exp $
+**
 **************************************************************************
 **
 ** The following modules is an enhanced replacement for the "printf" subroutines
@@ -14056,15 +15296,14 @@
 #define etPERCENT     8 /* Percent symbol. %% */
 #define etCHARX       9 /* Characters. %c */
 /* The rest are extensions, not normally found in printf() */
-#define etCHARLIT    10 /* Literal characters.  %' */
-#define etSQLESCAPE  11 /* Strings with '\'' doubled.  %q */
-#define etSQLESCAPE2 12 /* Strings with '\'' doubled and enclosed in '',
+#define etSQLESCAPE  10 /* Strings with '\'' doubled.  %q */
+#define etSQLESCAPE2 11 /* Strings with '\'' doubled and enclosed in '',
                           NULL pointers replaced by SQL NULL.  %Q */
-#define etTOKEN      13 /* a pointer to a Token structure */
-#define etSRCLIST    14 /* a pointer to a SrcList */
-#define etPOINTER    15 /* The %p conversion */
-#define etSQLESCAPE3 16 /* %w -> Strings with '\"' doubled */
-#define etORDINAL    17 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
+#define etTOKEN      12 /* a pointer to a Token structure */
+#define etSRCLIST    13 /* a pointer to a SrcList */
+#define etPOINTER    14 /* The %p conversion */
+#define etSQLESCAPE3 15 /* %w -> Strings with '\"' doubled */
+#define etORDINAL    16 /* %r -> 1st, 2nd, 3rd, 4th, etc.  English only */
 
 
 /*
@@ -14209,7 +15448,7 @@
 ** seems to make a big difference in determining how fast this beast
 ** will run.
 */
-static void vxprintf(
+SQLITE_PRIVATE void sqlite3VXPrintf(
   StrAccum *pAccum,                  /* Accumulate results here */
   int useExtended,                   /* Allow extended %-conversions */
   const char *fmt,                   /* Format string */
@@ -14432,9 +15671,7 @@
           const char *pre;
           char x;
           pre = &aPrefix[infop->prefix];
-          if( *bufpt!=pre[0] ){
-            for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
-          }
+          for(; (x=(*pre))!=0; pre++) *(--bufpt) = x;
         }
         length = &buf[etBUFSIZE-1]-bufpt;
         break;
@@ -14473,9 +15710,9 @@
           while( realvalue>=1e32 && exp<=350 ){ realvalue *= 1e-32; exp+=32; }
           while( realvalue>=1e8 && exp<=350 ){ realvalue *= 1e-8; exp+=8; }
           while( realvalue>=10.0 && exp<=350 ){ realvalue *= 0.1; exp++; }
-          while( realvalue<1e-8 && exp>=-350 ){ realvalue *= 1e8; exp-=8; }
-          while( realvalue<1.0 && exp>=-350 ){ realvalue *= 10.0; exp--; }
-          if( exp>350 || exp<-350 ){
+          while( realvalue<1e-8 ){ realvalue *= 1e8; exp-=8; }
+          while( realvalue<1.0 ){ realvalue *= 10.0; exp--; }
+          if( exp>350 ){
             if( prefix=='-' ){
               bufpt = "-Inf";
             }else if( prefix=='+' ){
@@ -14533,7 +15770,8 @@
         }
         /* "0" digits after the decimal point but before the first
         ** significant digit of the number */
-        for(e2++; e2<0 && precision>0; precision--, e2++){
+        for(e2++; e2<0; precision--, e2++){
+          assert( precision>0 );
           *(bufpt++) = '0';
         }
         /* Significant digits after the decimal point */
@@ -14553,7 +15791,7 @@
           }
         }
         /* Add the "eNNN" suffix */
-        if( flag_exp || (xtype==etEXP && exp) ){
+        if( flag_exp || xtype==etEXP ){
           *(bufpt++) = aDigits[infop->charset];
           if( exp<0 ){
             *(bufpt++) = '-'; exp = -exp;
@@ -14598,9 +15836,8 @@
         bufpt = buf;
         length = 1;
         break;
-      case etCHARLIT:
       case etCHARX:
-        c = buf[0] = (xtype==etCHARX ? va_arg(ap,int) : *++fmt);
+        c = buf[0] = va_arg(ap,int);
         if( precision>=0 ){
           for(idx=1; idx<precision; idx++) buf[idx] = c;
           length = precision;
@@ -14638,7 +15875,7 @@
         needQuote = !isnull && xtype==etSQLESCAPE2;
         n += i + 1 + needQuote*2;
         if( n>etBUFSIZE ){
-          bufpt = zExtra = sqlite3_malloc( n );
+          bufpt = zExtra = sqlite3Malloc( n );
           if( bufpt==0 ) return;
         }else{
           bufpt = buf;
@@ -14658,7 +15895,7 @@
       }
       case etTOKEN: {
         Token *pToken = va_arg(ap, Token*);
-        if( pToken && pToken->z ){
+        if( pToken ){
           sqlite3StrAccumAppend(pAccum, (const char*)pToken->z, pToken->n);
         }
         length = width = 0;
@@ -14669,7 +15906,7 @@
         int k = va_arg(ap, int);
         struct SrcList_item *pItem = &pSrc->a[k];
         assert( k>=0 && k<pSrc->nSrc );
-        if( pItem->zDatabase && pItem->zDatabase[0] ){
+        if( pItem->zDatabase ){
           sqlite3StrAccumAppend(pAccum, pItem->zDatabase, -1);
           sqlite3StrAccumAppend(pAccum, ".", 1);
         }
@@ -14728,19 +15965,16 @@
         return;
       }
     }else{
-      i64 szNew = p->nAlloc;
+      i64 szNew = p->nChar;
       szNew += N + 1;
       if( szNew > p->mxAlloc ){
-        p->nAlloc = p->mxAlloc;
-        if( ((i64)p->nChar)+((i64)N) >= p->nAlloc ){
-          sqlite3StrAccumReset(p);
-          p->tooBig = 1;
-          return;
-        }
+        sqlite3StrAccumReset(p);
+        p->tooBig = 1;
+        return;
       }else{
         p->nAlloc = szNew;
       }
-      zNew = sqlite3_malloc( p->nAlloc );
+      zNew = sqlite3Malloc( p->nAlloc );
       if( zNew ){
         memcpy(zNew, p->zText, p->nChar);
         sqlite3StrAccumReset(p);
@@ -14765,7 +15999,7 @@
   if( p->zText ){
     p->zText[p->nChar] = 0;
     if( p->useMalloc && p->zText==p->zBase ){
-      p->zText = sqlite3_malloc( p->nChar+1 );
+      p->zText = sqlite3Malloc( p->nChar+1 );
       if( p->zText ){
         memcpy(p->zText, p->zBase, p->nChar+1);
       }else{
@@ -14782,14 +16016,14 @@
 SQLITE_PRIVATE void sqlite3StrAccumReset(StrAccum *p){
   if( p->zText!=p->zBase ){
     sqlite3_free(p->zText);
-    p->zText = 0;
   }
+  p->zText = 0;
 }
 
 /*
 ** Initialize a string accumulator
 */
-static void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
+SQLITE_PRIVATE void sqlite3StrAccumInit(StrAccum *p, char *zBase, int n, int mx){
   p->zText = p->zBase = zBase;
   p->nChar = 0;
   p->nAlloc = n;
@@ -14809,7 +16043,7 @@
   StrAccum acc;
   sqlite3StrAccumInit(&acc, zBase, sizeof(zBase),
                       db ? db->aLimit[SQLITE_LIMIT_LENGTH] : SQLITE_MAX_LENGTH);
-  vxprintf(&acc, 1, zFormat, ap);
+  sqlite3VXPrintf(&acc, 1, zFormat, ap);
   z = sqlite3StrAccumFinish(&acc);
   if( acc.mallocFailed && db ){
     db->mallocFailed = 1;
@@ -14838,8 +16072,11 @@
   char *z;
   char zBase[SQLITE_PRINT_BUF_SIZE];
   StrAccum acc;
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
   sqlite3StrAccumInit(&acc, zBase, sizeof(zBase), SQLITE_MAX_LENGTH);
-  vxprintf(&acc, 0, zFormat, ap);
+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
   z = sqlite3StrAccumFinish(&acc);
   return z;
 }
@@ -14851,6 +16088,9 @@
 SQLITE_API char *sqlite3_mprintf(const char *zFormat, ...){
   va_list ap;
   char *z;
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize() ) return 0;
+#endif
   va_start(ap, zFormat);
   z = sqlite3_vmprintf(zFormat, ap);
   va_end(ap);
@@ -14874,13 +16114,13 @@
   sqlite3StrAccumInit(&acc, zBuf, n, 0);
   acc.useMalloc = 0;
   va_start(ap,zFormat);
-  vxprintf(&acc, 0, zFormat, ap);
+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
   va_end(ap);
   z = sqlite3StrAccumFinish(&acc);
   return z;
 }
 
-#if defined(SQLITE_TEST) || defined(SQLITE_DEBUG) || defined(SQLITE_MEMDEBUG)
+#if defined(SQLITE_DEBUG)
 /*
 ** A version of printf() that understands %lld.  Used for debugging.
 ** The printf() built into some versions of windows does not understand %lld
@@ -14893,7 +16133,7 @@
   sqlite3StrAccumInit(&acc, zBuf, sizeof(zBuf), 0);
   acc.useMalloc = 0;
   va_start(ap,zFormat);
-  vxprintf(&acc, 0, zFormat, ap);
+  sqlite3VXPrintf(&acc, 0, zFormat, ap);
   va_end(ap);
   sqlite3StrAccumFinish(&acc);
   fprintf(stdout,"%s", zBuf);
@@ -14920,7 +16160,7 @@
 ** Random numbers are used by some of the database backends in order
 ** to generate random integer keys for tables or random filenames.
 **
-** $Id: random.c,v 1.23 2008/03/21 16:45:47 drh Exp $
+** $Id: random.c,v 1.25 2008/06/19 01:03:18 drh Exp $
 */
 
 
@@ -14996,10 +16236,9 @@
 */
 SQLITE_API void sqlite3_randomness(int N, void *pBuf){
   unsigned char *zBuf = pBuf;
-  static sqlite3_mutex *mutex = 0;
-  if( mutex==0 ){
-    mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_PRNG);
-  }
+#ifndef SQLITE_MUTEX_NOOP
+  sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_PRNG);
+#endif
   sqlite3_mutex_enter(mutex);
   while( N-- ){
     *(zBuf++) = randomByte();
@@ -15042,7 +16281,7 @@
 ** This file contains routines used to translate between UTF-8, 
 ** UTF-16, UTF-16BE, and UTF-16LE.
 **
-** $Id: utf.c,v 1.61 2008/03/28 15:44:10 danielk1977 Exp $
+** $Id: utf.c,v 1.62 2008/06/27 18:59:45 mihailim Exp $
 **
 ** Notes on UTF-8:
 **
@@ -15083,6 +16322,8 @@
 ** source code file "vdbe.c".  When that file became too big (over
 ** 6000 lines long) it was split up into several smaller files and
 ** this header information was factored out.
+**
+** $Id: vdbeInt.h,v 1.149 2008/06/25 00:12:41 drh Exp $
 */
 #ifndef _VDBEINT_H_
 #define _VDBEINT_H_
@@ -15378,8 +16619,6 @@
   unsigned uniqueCnt;     /* Used by OP_MakeRecord when P2!=0 */
   int errorAction;        /* Recovery action to do in case of an error */
   int inTempTrans;        /* True if temp database is transactioned */
-  int returnStack[25];    /* Return address stack for OP_Gosub & OP_Return */
-  int returnDepth;        /* Next unused element in returnStack[] */
   int nResColumn;         /* Number of columns in one row of the result set */
   char **azResColumn;     /* Values for one row of result */ 
   char *zErrMsg;          /* Error message written here */
@@ -15770,7 +17009,7 @@
         WRITE_UTF8(z, c);
       }
     }else{
-      /* UTF-16 Little-endian -> UTF-8 */
+      /* UTF-16 Big-endian -> UTF-8 */
       while( zIn<zTerm ){
         READ_UTF16BE(zIn, c); 
         WRITE_UTF8(z, c);
@@ -16021,7 +17260,7 @@
 ** This file contains functions for allocating memory, comparing
 ** strings, and stuff like that.
 **
-** $Id: util.c,v 1.229 2008/05/13 16:41:50 drh Exp $
+** $Id: util.c,v 1.238 2008/07/11 16:19:10 drh Exp $
 */
 
 
@@ -16038,8 +17277,26 @@
   **      which depend on an exact implementation of IEEE or ISO 
   **      rules/specifications for math functions.
   */
+#ifdef __FAST_MATH__
+# error SQLite will not work correctly with the -ffast-math option of GCC.
+#endif
   volatile double y = x;
-  return x!=y;
+  volatile double z = y;
+  return y!=z;
+}
+
+/*
+** Return the length of a string, except do not allow the string length
+** to exceed the SQLITE_LIMIT_LENGTH setting.
+*/
+SQLITE_PRIVATE int sqlite3Strlen(sqlite3 *db, const char *z){
+  const char *z2 = z;
+  while( *z2 ){ z2++; }
+  if( z2 > &z[db->aLimit[SQLITE_LIMIT_LENGTH]] ){
+    return db->aLimit[SQLITE_LIMIT_LENGTH];
+  }else{
+    return (int)(z2 - z);
+  }
 }
 
 /*
@@ -16154,46 +17411,7 @@
   }
 }
 
-/* An array to map all upper-case characters into their corresponding
-** lower-case character. 
-*/
-SQLITE_PRIVATE const unsigned char sqlite3UpperToLower[] = {
-#ifdef SQLITE_ASCII
-      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, 16, 17,
-     18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35,
-     36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53,
-     54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 97, 98, 99,100,101,102,103,
-    104,105,106,107,108,109,110,111,112,113,114,115,116,117,118,119,120,121,
-    122, 91, 92, 93, 94, 95, 96, 97, 98, 99,100,101,102,103,104,105,106,107,
-    108,109,110,111,112,113,114,115,116,117,118,119,120,121,122,123,124,125,
-    126,127,128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143,
-    144,145,146,147,148,149,150,151,152,153,154,155,156,157,158,159,160,161,
-    162,163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,179,
-    180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,195,196,197,
-    198,199,200,201,202,203,204,205,206,207,208,209,210,211,212,213,214,215,
-    216,217,218,219,220,221,222,223,224,225,226,227,228,229,230,231,232,233,
-    234,235,236,237,238,239,240,241,242,243,244,245,246,247,248,249,250,251,
-    252,253,254,255
-#endif
-#ifdef SQLITE_EBCDIC
-      0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14, 15, /* 0x */
-     16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, /* 1x */
-     32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, /* 2x */
-     48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, /* 3x */
-     64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, /* 4x */
-     80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, /* 5x */
-     96, 97, 66, 67, 68, 69, 70, 71, 72, 73,106,107,108,109,110,111, /* 6x */
-    112, 81, 82, 83, 84, 85, 86, 87, 88, 89,122,123,124,125,126,127, /* 7x */
-    128,129,130,131,132,133,134,135,136,137,138,139,140,141,142,143, /* 8x */
-    144,145,146,147,148,149,150,151,152,153,154,155,156,157,156,159, /* 9x */
-    160,161,162,163,164,165,166,167,168,169,170,171,140,141,142,175, /* Ax */
-    176,177,178,179,180,181,182,183,184,185,186,187,188,189,190,191, /* Bx */
-    192,129,130,131,132,133,134,135,136,137,202,203,204,205,206,207, /* Cx */
-    208,145,146,147,148,149,150,151,152,153,218,219,220,221,222,223, /* Dx */
-    224,225,162,163,164,165,166,167,168,169,232,203,204,205,206,207, /* Ex */
-    239,240,241,242,243,244,245,246,247,248,249,219,220,221,222,255, /* Fx */
-#endif
-};
+/* Convenient short-hand */
 #define UpperToLower sqlite3UpperToLower
 
 /*
@@ -16370,6 +17588,7 @@
   i64 v = 0;
   int neg;
   int i, c;
+  const char *zStart;
   while( isspace(*(u8*)zNum) ) zNum++;
   if( *zNum=='-' ){
     neg = 1;
@@ -16380,12 +17599,13 @@
   }else{
     neg = 0;
   }
+  zStart = zNum;
   while( zNum[0]=='0' ){ zNum++; } /* Skip over leading zeros. Ticket #2454 */
   for(i=0; (c=zNum[i])>='0' && c<='9'; i++){
     v = v*10 + c - '0';
   }
   *pNum = neg ? -v : v;
-  if( c!=0 || i==0 || i>19 ){
+  if( c!=0 || (i==0 && zStart==zNum) || i>19 ){
     /* zNum is empty or contains non-numeric text or is longer
     ** than 19 digits (thus guaranting that it is too large) */
     return 0;
@@ -16563,7 +17783,7 @@
   u32 a,b,s;
 
   a = *p;
-  // a: p0 (unmasked)
+  /* a: p0 (unmasked) */
   if (!(a&0x80))
   {
     *v = a;
@@ -16572,7 +17792,7 @@
 
   p++;
   b = *p;
-  // b: p1 (unmasked)
+  /* b: p1 (unmasked) */
   if (!(b&0x80))
   {
     a &= 0x7f;
@@ -16585,7 +17805,7 @@
   p++;
   a = a<<14;
   a |= *p;
-  // a: p0<<14 | p2 (unmasked)
+  /* a: p0<<14 | p2 (unmasked) */
   if (!(a&0x80))
   {
     a &= (0x7f<<14)|(0x7f);
@@ -16596,41 +17816,41 @@
     return 3;
   }
 
-  // CSE1 from below
+  /* CSE1 from below */
   a &= (0x7f<<14)|(0x7f);
   p++;
   b = b<<14;
   b |= *p;
-  // b: p1<<14 | p3 (unmasked)
+  /* b: p1<<14 | p3 (unmasked) */
   if (!(b&0x80))
   {
     b &= (0x7f<<14)|(0x7f);
-    // moved CSE1 up
-    // a &= (0x7f<<14)|(0x7f);
+    /* moved CSE1 up */
+    /* a &= (0x7f<<14)|(0x7f); */
     a = a<<7;
     a |= b;
     *v = a;
     return 4;
   }
 
-  // a: p0<<14 | p2 (masked)
-  // b: p1<<14 | p3 (unmasked)
-  // 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked)
-  // moved CSE1 up
-  // a &= (0x7f<<14)|(0x7f);
+  /* a: p0<<14 | p2 (masked) */
+  /* b: p1<<14 | p3 (unmasked) */
+  /* 1:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
+  /* moved CSE1 up */
+  /* a &= (0x7f<<14)|(0x7f); */
   b &= (0x7f<<14)|(0x7f);
   s = a;
-  // s: p0<<14 | p2 (masked)
+  /* s: p0<<14 | p2 (masked) */
 
   p++;
   a = a<<14;
   a |= *p;
-  // a: p0<<28 | p2<<14 | p4 (unmasked)
+  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
   if (!(a&0x80))
   {
-    // we can skip these cause they were (effectively) done above in calc'ing s
-    // a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
-    // b &= (0x7f<<14)|(0x7f);
+    /* we can skip these cause they were (effectively) done above in calc'ing s */
+    /* a &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
+    /* b &= (0x7f<<14)|(0x7f); */
     b = b<<7;
     a |= b;
     s = s>>18;
@@ -16638,19 +17858,19 @@
     return 5;
   }
 
-  // 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked)
+  /* 2:save off p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
   s = s<<7;
   s |= b;
-  // s: p0<<21 | p1<<14 | p2<<7 | p3 (masked)
+  /* s: p0<<21 | p1<<14 | p2<<7 | p3 (masked) */
 
   p++;
   b = b<<14;
   b |= *p;
-  // b: p1<<28 | p3<<14 | p5 (unmasked)
+  /* b: p1<<28 | p3<<14 | p5 (unmasked) */
   if (!(b&0x80))
   {
-    // we can skip this cause it was (effectively) done above in calc'ing s
-    // b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
+    /* we can skip this cause it was (effectively) done above in calc'ing s */
+    /* b &= (0x7f<<28)|(0x7f<<14)|(0x7f); */
     a &= (0x7f<<14)|(0x7f);
     a = a<<7;
     a |= b;
@@ -16662,7 +17882,7 @@
   p++;
   a = a<<14;
   a |= *p;
-  // a: p2<<28 | p4<<14 | p6 (unmasked)
+  /* a: p2<<28 | p4<<14 | p6 (unmasked) */
   if (!(a&0x80))
   {
     a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
@@ -16674,17 +17894,17 @@
     return 7;
   }
 
-  // CSE2 from below
+  /* CSE2 from below */
   a &= (0x7f<<14)|(0x7f);
   p++;
   b = b<<14;
   b |= *p;
-  // b: p3<<28 | p5<<14 | p7 (unmasked)
+  /* b: p3<<28 | p5<<14 | p7 (unmasked) */
   if (!(b&0x80))
   {
     b &= (0x7f<<28)|(0x7f<<14)|(0x7f);
-    // moved CSE2 up
-    // a &= (0x7f<<14)|(0x7f);
+    /* moved CSE2 up */
+    /* a &= (0x7f<<14)|(0x7f); */
     a = a<<7;
     a |= b;
     s = s>>4;
@@ -16695,10 +17915,10 @@
   p++;
   a = a<<15;
   a |= *p;
-  // a: p4<<29 | p6<<15 | p8 (unmasked)
+  /* a: p4<<29 | p6<<15 | p8 (unmasked) */
 
-  // moved CSE2 up
-  // a &= (0x7f<<29)|(0x7f<<15)|(0xff);
+  /* moved CSE2 up */
+  /* a &= (0x7f<<29)|(0x7f<<15)|(0xff); */
   b &= (0x7f<<14)|(0x7f);
   b = b<<8;
   a |= b;
@@ -16725,7 +17945,7 @@
   u32 a,b;
 
   a = *p;
-  // a: p0 (unmasked)
+  /* a: p0 (unmasked) */
 #ifndef getVarint32
   if (!(a&0x80))
   {
@@ -16736,7 +17956,7 @@
 
   p++;
   b = *p;
-  // b: p1 (unmasked)
+  /* b: p1 (unmasked) */
   if (!(b&0x80))
   {
     a &= 0x7f;
@@ -16748,7 +17968,7 @@
   p++;
   a = a<<14;
   a |= *p;
-  // a: p0<<14 | p2 (unmasked)
+  /* a: p0<<14 | p2 (unmasked) */
   if (!(a&0x80))
   {
     a &= (0x7f<<14)|(0x7f);
@@ -16761,7 +17981,7 @@
   p++;
   b = b<<14;
   b |= *p;
-  // b: p1<<14 | p3 (unmasked)
+  /* b: p1<<14 | p3 (unmasked) */
   if (!(b&0x80))
   {
     b &= (0x7f<<14)|(0x7f);
@@ -16774,7 +17994,7 @@
   p++;
   a = a<<14;
   a |= *p;
-  // a: p0<<28 | p2<<14 | p4 (unmasked)
+  /* a: p0<<28 | p2<<14 | p4 (unmasked) */
   if (!(a&0x80))
   {
     a &= (0x7f<<28)|(0x7f<<14)|(0x7f);
@@ -16977,7 +18197,7 @@
 ** This is the implementation of generic hash-tables
 ** used in SQLite.
 **
-** $Id: hash.c,v 1.28 2008/05/13 13:27:34 drh Exp $
+** $Id: hash.c,v 1.30 2008/06/20 14:59:51 danielk1977 Exp $
 */
 
 /* Turn bulk memory into a hash table object by initializing the
@@ -17196,9 +18416,9 @@
   ** is benign (since failing to resize a hash table is a performance
   ** hit only, not a fatal error).
   */
-  if( pH->htsize>0 ) sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
+  if( pH->htsize>0 ) sqlite3BeginBenignMalloc();
   new_ht = (struct _ht *)sqlite3MallocZero( new_size*sizeof(struct _ht) );
-  if( pH->htsize>0 ) sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
+  if( pH->htsize>0 ) sqlite3EndBenignMalloc();
 
   if( new_ht==0 ) return;
   sqlite3_free(pH->ht);
@@ -17350,10 +18570,10 @@
     }
   }
   if( data==0 ) return 0;
-  new_elem = (HashElem*)sqlite3_malloc( sizeof(HashElem) );
+  new_elem = (HashElem*)sqlite3Malloc( sizeof(HashElem) );
   if( new_elem==0 ) return data;
   if( pH->copyKey && pKey!=0 ){
-    new_elem->pKey = sqlite3_malloc( nKey );
+    new_elem->pKey = sqlite3Malloc( nKey );
     if( new_elem->pKey==0 ){
       sqlite3_free(new_elem);
       return data;
@@ -17408,54 +18628,54 @@
      /*  14 */ "Expire",
      /*  15 */ "AutoCommit",
      /*  16 */ "Not",
-     /*  17 */ "IntegrityCk",
-     /*  18 */ "Sort",
-     /*  19 */ "Copy",
-     /*  20 */ "Trace",
-     /*  21 */ "Function",
-     /*  22 */ "IfNeg",
-     /*  23 */ "Noop",
-     /*  24 */ "Return",
-     /*  25 */ "NewRowid",
-     /*  26 */ "Variable",
-     /*  27 */ "String",
-     /*  28 */ "RealAffinity",
-     /*  29 */ "VRename",
-     /*  30 */ "ParseSchema",
-     /*  31 */ "VOpen",
-     /*  32 */ "Close",
-     /*  33 */ "CreateIndex",
-     /*  34 */ "IsUnique",
-     /*  35 */ "NotFound",
-     /*  36 */ "Int64",
-     /*  37 */ "MustBeInt",
-     /*  38 */ "Halt",
-     /*  39 */ "Rowid",
-     /*  40 */ "IdxLT",
-     /*  41 */ "AddImm",
-     /*  42 */ "Statement",
-     /*  43 */ "RowData",
-     /*  44 */ "MemMax",
-     /*  45 */ "NotExists",
-     /*  46 */ "Gosub",
-     /*  47 */ "Integer",
-     /*  48 */ "Prev",
-     /*  49 */ "VColumn",
-     /*  50 */ "CreateTable",
-     /*  51 */ "Last",
-     /*  52 */ "IncrVacuum",
-     /*  53 */ "IdxRowid",
-     /*  54 */ "ResetCount",
-     /*  55 */ "FifoWrite",
-     /*  56 */ "ContextPush",
-     /*  57 */ "DropTrigger",
-     /*  58 */ "DropIndex",
-     /*  59 */ "IdxGE",
+     /*  17 */ "Pagecount",
+     /*  18 */ "IntegrityCk",
+     /*  19 */ "Sort",
+     /*  20 */ "Copy",
+     /*  21 */ "Trace",
+     /*  22 */ "Function",
+     /*  23 */ "IfNeg",
+     /*  24 */ "Noop",
+     /*  25 */ "Return",
+     /*  26 */ "NewRowid",
+     /*  27 */ "Variable",
+     /*  28 */ "String",
+     /*  29 */ "RealAffinity",
+     /*  30 */ "VRename",
+     /*  31 */ "ParseSchema",
+     /*  32 */ "VOpen",
+     /*  33 */ "Close",
+     /*  34 */ "CreateIndex",
+     /*  35 */ "IsUnique",
+     /*  36 */ "NotFound",
+     /*  37 */ "Int64",
+     /*  38 */ "MustBeInt",
+     /*  39 */ "Halt",
+     /*  40 */ "Rowid",
+     /*  41 */ "IdxLT",
+     /*  42 */ "AddImm",
+     /*  43 */ "Statement",
+     /*  44 */ "RowData",
+     /*  45 */ "MemMax",
+     /*  46 */ "NotExists",
+     /*  47 */ "Gosub",
+     /*  48 */ "Integer",
+     /*  49 */ "Prev",
+     /*  50 */ "VColumn",
+     /*  51 */ "CreateTable",
+     /*  52 */ "Last",
+     /*  53 */ "IncrVacuum",
+     /*  54 */ "IdxRowid",
+     /*  55 */ "ResetCount",
+     /*  56 */ "FifoWrite",
+     /*  57 */ "ContextPush",
+     /*  58 */ "Yield",
+     /*  59 */ "DropTrigger",
      /*  60 */ "Or",
      /*  61 */ "And",
-     /*  62 */ "IdxDelete",
-     /*  63 */ "Vacuum",
-     /*  64 */ "MoveLe",
+     /*  62 */ "DropIndex",
+     /*  63 */ "IdxGE",
+     /*  64 */ "IdxDelete",
      /*  65 */ "IsNull",
      /*  66 */ "NotNull",
      /*  67 */ "Ne",
@@ -17464,7 +18684,7 @@
      /*  70 */ "Le",
      /*  71 */ "Lt",
      /*  72 */ "Ge",
-     /*  73 */ "IfNot",
+     /*  73 */ "Vacuum",
      /*  74 */ "BitAnd",
      /*  75 */ "BitOr",
      /*  76 */ "ShiftLeft",
@@ -17475,53 +18695,53 @@
      /*  81 */ "Divide",
      /*  82 */ "Remainder",
      /*  83 */ "Concat",
-     /*  84 */ "DropTable",
-     /*  85 */ "MakeRecord",
-     /*  86 */ "ResultRow",
+     /*  84 */ "MoveLe",
+     /*  85 */ "IfNot",
+     /*  86 */ "DropTable",
      /*  87 */ "BitNot",
      /*  88 */ "String8",
-     /*  89 */ "Delete",
-     /*  90 */ "AggFinal",
-     /*  91 */ "Goto",
-     /*  92 */ "TableLock",
-     /*  93 */ "FifoRead",
-     /*  94 */ "Clear",
-     /*  95 */ "MoveLt",
-     /*  96 */ "VerifyCookie",
-     /*  97 */ "AggStep",
-     /*  98 */ "SetNumColumns",
-     /*  99 */ "Transaction",
-     /* 100 */ "VFilter",
-     /* 101 */ "VDestroy",
-     /* 102 */ "ContextPop",
-     /* 103 */ "Next",
-     /* 104 */ "IdxInsert",
-     /* 105 */ "Insert",
-     /* 106 */ "Destroy",
-     /* 107 */ "ReadCookie",
-     /* 108 */ "ForceInt",
-     /* 109 */ "LoadAnalysis",
-     /* 110 */ "Explain",
-     /* 111 */ "OpenPseudo",
-     /* 112 */ "OpenEphemeral",
-     /* 113 */ "Null",
-     /* 114 */ "Move",
-     /* 115 */ "Blob",
-     /* 116 */ "Rewind",
-     /* 117 */ "MoveGe",
-     /* 118 */ "VBegin",
-     /* 119 */ "VUpdate",
-     /* 120 */ "IfZero",
-     /* 121 */ "VCreate",
-     /* 122 */ "Found",
-     /* 123 */ "IfPos",
-     /* 124 */ "NullRow",
+     /*  89 */ "MakeRecord",
+     /*  90 */ "ResultRow",
+     /*  91 */ "Delete",
+     /*  92 */ "AggFinal",
+     /*  93 */ "Compare",
+     /*  94 */ "Goto",
+     /*  95 */ "TableLock",
+     /*  96 */ "FifoRead",
+     /*  97 */ "Clear",
+     /*  98 */ "MoveLt",
+     /*  99 */ "VerifyCookie",
+     /* 100 */ "AggStep",
+     /* 101 */ "SetNumColumns",
+     /* 102 */ "Transaction",
+     /* 103 */ "VFilter",
+     /* 104 */ "VDestroy",
+     /* 105 */ "ContextPop",
+     /* 106 */ "Next",
+     /* 107 */ "IdxInsert",
+     /* 108 */ "Insert",
+     /* 109 */ "Destroy",
+     /* 110 */ "ReadCookie",
+     /* 111 */ "ForceInt",
+     /* 112 */ "LoadAnalysis",
+     /* 113 */ "Explain",
+     /* 114 */ "OpenPseudo",
+     /* 115 */ "OpenEphemeral",
+     /* 116 */ "Null",
+     /* 117 */ "Move",
+     /* 118 */ "Blob",
+     /* 119 */ "Rewind",
+     /* 120 */ "MoveGe",
+     /* 121 */ "VBegin",
+     /* 122 */ "VUpdate",
+     /* 123 */ "IfZero",
+     /* 124 */ "VCreate",
      /* 125 */ "Real",
-     /* 126 */ "NotUsed_126",
-     /* 127 */ "NotUsed_127",
-     /* 128 */ "NotUsed_128",
-     /* 129 */ "NotUsed_129",
-     /* 130 */ "NotUsed_130",
+     /* 126 */ "Found",
+     /* 127 */ "IfPos",
+     /* 128 */ "NullRow",
+     /* 129 */ "Jump",
+     /* 130 */ "Permutation",
      /* 131 */ "NotUsed_131",
      /* 132 */ "NotUsed_132",
      /* 133 */ "NotUsed_133",
@@ -17554,10 +18774,12 @@
 ******************************************************************************
 **
 ** This file contains code that is specific to OS/2.
+**
+** $Id: os_os2.c,v 1.50 2008/07/15 22:59:05 pweilbacher Exp $
 */
 
 
-#if OS_OS2
+#if SQLITE_OS_OS2
 
 /*
 ** A Note About Memory Allocation:
@@ -17615,7 +18837,11 @@
 **
 ** This file should be #included by the os_*.c files only.  It is not a
 ** general purpose header file.
+**
+** $Id: os_common.h,v 1.37 2008/05/29 20:22:37 shane Exp $
 */
+#ifndef _OS_COMMON_H_
+#define _OS_COMMON_H_
 
 /*
 ** At least two bugs have slipped in because we changed the MEMORY_DEBUG
@@ -17661,35 +18887,111 @@
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
-__inline__ unsigned long long int hwtime(void){
-  unsigned long long int x;
-  __asm__("rdtsc\n\t"
-          "mov %%edx, %%ecx\n\t"
-          :"=A" (x));
-  return x;
-}
-static unsigned long long int g_start;
-static unsigned int elapse;
-#define TIMER_START       g_start=hwtime()
-#define TIMER_END         elapse=hwtime()-g_start
-#define TIMER_ELAPSED     elapse
-#else
-#define TIMER_START
-#define TIMER_END
-#define TIMER_ELAPSED     0
-#endif
 
-/*
-** If we compile with the SQLITE_TEST macro set, then the following block
-** of code will give us the ability to simulate a disk I/O error.  This
-** is used for testing the I/O recovery logic.
+/* 
+** hwtime.h contains inline assembler code for implementing 
+** high-performance timing routines.
 */
-#ifdef SQLITE_TEST
-SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
-SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
-SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
-SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
-SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
+/************** Include hwtime.h in the middle of os_common.h ****************/
+/************** Begin file hwtime.h ******************************************/
+/*
+** 2008 May 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 contains inline asm code for retrieving "high-performance"
+** counters for x86 class CPUs.
+**
+** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+*/
+#ifndef _HWTIME_H_
+#define _HWTIME_H_
+
+/*
+** 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.
+*/
+#if (defined(__GNUC__) || defined(_MSC_VER)) && \
+      (defined(i386) || defined(__i386__) || defined(_M_IX86))
+
+  #if defined(__GNUC__)
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+     unsigned int lo, hi;
+     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+     return (sqlite_uint64)hi << 32 | lo;
+  }
+
+  #elif defined(_MSC_VER)
+
+  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
+     __asm {
+        rdtsc
+        ret       ; return value at EDX:EAX
+     }
+  }
+
+  #endif
+
+#elif (defined(__GNUC__) && defined(__x86_64__))
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+      unsigned long val;
+      __asm__ __volatile__ ("rdtsc" : "=A" (val));
+      return val;
+  }
+ 
+#else
+
+  #error Need implementation of sqlite3Hwtime() for your platform.
+
+  /*
+  ** To compile without implementing sqlite3Hwtime() for your platform,
+  ** you can remove the above #error and use the following
+  ** stub function.  You will lose timing support for many
+  ** of the debugging and testing utilities, but it should at
+  ** least compile and run.
+  */
+SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
+
+#endif
+
+#endif /* !defined(_HWTIME_H_) */
+
+/************** End of hwtime.h **********************************************/
+/************** Continuing where we left off in os_common.h ******************/
+
+static sqlite_uint64 g_start;
+static sqlite_uint64 g_elapsed;
+#define TIMER_START       g_start=sqlite3Hwtime()
+#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
+#define TIMER_ELAPSED     g_elapsed
+#else
+#define TIMER_START
+#define TIMER_END
+#define TIMER_ELAPSED     ((sqlite_uint64)0)
+#endif
+
+/*
+** If we compile with the SQLITE_TEST macro set, then the following block
+** of code will give us the ability to simulate a disk I/O error.  This
+** is used for testing the I/O recovery logic.
+*/
+#ifdef SQLITE_TEST
+SQLITE_API int sqlite3_io_error_hit = 0;            /* Total number of I/O Errors */
+SQLITE_API int sqlite3_io_error_hardhit = 0;        /* Number of non-benign errors */
+SQLITE_API int sqlite3_io_error_pending = 0;        /* Count down to first I/O error */
+SQLITE_API int sqlite3_io_error_persist = 0;        /* True if I/O errors persist */
+SQLITE_API int sqlite3_io_error_benign = 0;         /* True if errors are benign */
 SQLITE_API int sqlite3_diskfull_pending = 0;
 SQLITE_API int sqlite3_diskfull = 0;
 #define SimulateIOErrorBenign(X) sqlite3_io_error_benign=(X)
@@ -17729,6 +19031,8 @@
 #define OpenCounter(X)
 #endif
 
+#endif /* !defined(_OS_COMMON_H_) */
+
 /************** End of os_common.h *******************************************/
 /************** Continuing where we left off in os_os2.c *********************/
 
@@ -17754,7 +19058,7 @@
 /*
 ** Close a file.
 */
-int os2Close( sqlite3_file *id ){
+static int os2Close( sqlite3_file *id ){
   APIRET rc = NO_ERROR;
   os2File *pFile;
   if( id && (pFile = (os2File*)id) != 0 ){
@@ -17778,7 +19082,7 @@
 ** bytes were read successfully and SQLITE_IOERR if anything goes
 ** wrong.
 */
-int os2Read(
+static int os2Read(
   sqlite3_file *id,               /* File to read from */
   void *pBuf,                     /* Write content into this buffer */
   int amt,                        /* Number of bytes to read */
@@ -17808,7 +19112,7 @@
 ** Write data from a buffer into a file.  Return SQLITE_OK on success
 ** or some other error code on failure.
 */
-int os2Write(
+static int os2Write(
   sqlite3_file *id,               /* File to write into */
   const void *pBuf,               /* The bytes to be written */
   int amt,                        /* Number of bytes to write */
@@ -17840,7 +19144,7 @@
 /*
 ** Truncate an open file to a specified size
 */
-int os2Truncate( sqlite3_file *id, i64 nByte ){
+static int os2Truncate( sqlite3_file *id, i64 nByte ){
   APIRET rc = NO_ERROR;
   os2File *pFile = (os2File*)id;
   OSTRACE3( "TRUNCATE %d %lld\n", pFile->h, nByte );
@@ -17861,7 +19165,7 @@
 /*
 ** Make sure all writes to a particular file are committed to disk.
 */
-int os2Sync( sqlite3_file *id, int flags ){
+static int os2Sync( sqlite3_file *id, int flags ){
   os2File *pFile = (os2File*)id;
   OSTRACE3( "SYNC %d lock=%d\n", pFile->h, pFile->locktype );
 #ifdef SQLITE_TEST
@@ -17876,7 +19180,7 @@
 /*
 ** Determine the current size of a file in bytes
 */
-int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){
+static int os2FileSize( sqlite3_file *id, sqlite3_int64 *pSize ){
   APIRET rc = NO_ERROR;
   FILESTATUS3 fsts3FileInfo;
   memset(&fsts3FileInfo, 0, sizeof(fsts3FileInfo));
@@ -17953,7 +19257,7 @@
 ** It is not possible to lower the locking level one step at a time.  You
 ** must go straight to locking level 0.
 */
-int os2Lock( sqlite3_file *id, int locktype ){
+static int os2Lock( sqlite3_file *id, int locktype ){
   int rc = SQLITE_OK;       /* Return code from subroutines */
   APIRET res = NO_ERROR;    /* Result of an OS/2 lock call */
   int newLocktype;       /* Set pFile->locktype to this value before exiting */
@@ -18089,7 +19393,7 @@
 ** file by this or any other process. If such a lock is held, return
 ** non-zero, otherwise zero.
 */
-int os2CheckReservedLock( sqlite3_file *id ){
+static int os2CheckReservedLock( sqlite3_file *id, int *pOut ){
   int r = 0;
   os2File *pFile = (os2File*)id;
   assert( pFile!=0 );
@@ -18120,7 +19424,8 @@
     r = !(rc == NO_ERROR);
     OSTRACE3( "TEST WR-LOCK %d %d (remote)\n", pFile->h, r );
   }
-  return r;
+  *pOut = r;
+  return SQLITE_OK;
 }
 
 /*
@@ -18134,7 +19439,7 @@
 ** is NO_LOCK.  If the second argument is SHARED_LOCK then this routine
 ** might return SQLITE_IOERR;
 */
-int os2Unlock( sqlite3_file *id, int locktype ){
+static int os2Unlock( sqlite3_file *id, int locktype ){
   int type;
   os2File *pFile = (os2File*)id;
   APIRET rc = SQLITE_OK;
@@ -18221,33 +19526,62 @@
   return 0;
 }
 
+
+/*
+** Character set conversion objects used by conversion routines.
+*/
+static UconvObject ucUtf8 = NULL; /* convert between UTF-8 and UCS-2 */
+static UconvObject uclCp = NULL;  /* convert between local codepage and UCS-2 */
+
+/*
+** Helper function to initialize the conversion objects from and to UTF-8.
+*/
+static void initUconvObjects( void ){
+	printf("init them\n");
+  if( UniCreateUconvObject( UTF_8, &ucUtf8 ) != ULS_SUCCESS )
+    ucUtf8 = NULL;
+  if ( UniCreateUconvObject( (UniChar *)L"@path=yes", &uclCp ) != ULS_SUCCESS )
+    uclCp = NULL;
+}
+
+/*
+** Helper function to free the conversion objects from and to UTF-8.
+*/
+static void freeUconvObjects( void ){
+	printf("free them\n");
+  if ( ucUtf8 )
+    UniFreeUconvObject( ucUtf8 );
+  if ( uclCp )
+    UniFreeUconvObject( uclCp );
+  ucUtf8 = NULL;
+  uclCp = NULL;
+}
+
 /*
 ** Helper function to convert UTF-8 filenames to local OS/2 codepage.
 ** The two-step process: first convert the incoming UTF-8 string
 ** into UCS-2 and then from UCS-2 to the current codepage.
 ** The returned char pointer has to be freed.
 */
-char *convertUtf8PathToCp(const char *in)
-{
-  UconvObject uconv;
-  UniChar ucsUtf8Cp[12],
-          tempPath[CCHMAXPATH];
-  char *out;
-  int rc = 0;
+static char *convertUtf8PathToCp( const char *in ){
+  UniChar tempPath[CCHMAXPATH];
+  char *out = (char *)calloc( CCHMAXPATH, 1 );
+printf("convertUtf8PathToCp(%s)\n", in);
+
+  if( !out )
+    return NULL;
 
-  out = (char *)calloc(CCHMAXPATH, 1);
+  if( !ucUtf8 || !uclCp )
+    initUconvObjects();
 
   /* determine string for the conversion of UTF-8 which is CP1208 */
-  rc = UniMapCpToUcsCp(1208, ucsUtf8Cp, 12);
-  rc = UniCreateUconvObject(ucsUtf8Cp, &uconv);
-  rc = UniStrToUcs(uconv, tempPath, (char *)in, CCHMAXPATH);
-  rc = UniFreeUconvObject(uconv);
+  if( UniStrToUcs( ucUtf8, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
+    return out; /* if conversion fails, return the empty string */
 
   /* conversion for current codepage which can be used for paths */
-  rc = UniCreateUconvObject((UniChar *)L"@path=yes", &uconv);
-  rc = UniStrFromUcs(uconv, out, tempPath, CCHMAXPATH);
-  rc = UniFreeUconvObject(uconv);
+  UniStrFromUcs( uclCp, out, tempPath, CCHMAXPATH );
 
+	printf("%s -> Cp = %s\n", in, out);
   return out;
 }
 
@@ -18256,28 +19590,29 @@
 ** The two-step process: first convert the incoming codepage-specific
 ** string into UCS-2 and then from UCS-2 to the codepage of UTF-8.
 ** The returned char pointer has to be freed.
+**
+** This function is non-static to be able to use this in shell.c and
+** similar applications that take command line arguments.
 */
-char *convertCpPathToUtf8(const char *in)
-{
-  UconvObject uconv;
-  UniChar ucsUtf8Cp[12],
-          tempPath[CCHMAXPATH];
-  char *out;
-  int rc = 0;
+char *convertCpPathToUtf8( const char *in ){
+  UniChar tempPath[CCHMAXPATH];
+  char *out = (char *)calloc( CCHMAXPATH, 1 );
+printf("convertCpPathToUtf8(%s)\n", in);
+
+  if( !out )
+    return NULL;
 
-  out = (char *)calloc(CCHMAXPATH, 1);
+  if( !ucUtf8 || !uclCp )
+    initUconvObjects();
 
   /* conversion for current codepage which can be used for paths */
-  rc = UniCreateUconvObject((UniChar *)L"@path=yes", &uconv);
-  rc = UniStrToUcs(uconv, tempPath, (char *)in, CCHMAXPATH);
-  rc = UniFreeUconvObject(uconv);
+  if( UniStrToUcs( uclCp, tempPath, (char *)in, CCHMAXPATH ) != ULS_SUCCESS )
+    return out; /* if conversion fails, return the empty string */
 
   /* determine string for the conversion of UTF-8 which is CP1208 */
-  rc = UniMapCpToUcsCp(1208, ucsUtf8Cp, 12);
-  rc = UniCreateUconvObject(ucsUtf8Cp, &uconv);
-  rc = UniStrFromUcs(uconv, out, tempPath, CCHMAXPATH);
-  rc = UniFreeUconvObject(uconv);
+  UniStrFromUcs( ucUtf8, out, tempPath, CCHMAXPATH );
 
+	printf("%s -> Utf8 = %s\n", in, out);
   return out;
 }
 
@@ -18308,6 +19643,60 @@
 ****************************************************************************/
 
 /*
+** Create a temporary file name in zBuf.  zBuf must be big enough to
+** hold at pVfs->mxPathname characters.
+*/
+static int getTempname(int nBuf, char *zBuf ){
+  static const unsigned char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "0123456789";
+  int i, j;
+  char zTempPathBuf[3];
+  PSZ zTempPath = (PSZ)&zTempPathBuf;
+  if( sqlite3_temp_directory ){
+    zTempPath = sqlite3_temp_directory;
+  }else{
+    if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){
+      if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){
+        if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){
+           ULONG ulDriveNum = 0, ulDriveMap = 0;
+           DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
+           sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) );
+        }
+      }
+    }
+  }
+  /* Strip off a trailing slashes or backslashes, otherwise we would get *
+   * multiple (back)slashes which causes DosOpen() to fail.              *
+   * Trailing spaces are not allowed, either.                            */
+  j = strlen(zTempPath);
+  while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/'
+                    || zTempPath[j-1] == ' ' ) ){
+    j--;
+  }
+  zTempPath[j] = '\0';
+  if( !sqlite3_temp_directory ){
+    char *zTempPathUTF = convertCpPathToUtf8( zTempPath );
+    sqlite3_snprintf( nBuf-30, zBuf,
+                      "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF );
+    free( zTempPathUTF );
+  }else{
+    sqlite3_snprintf( nBuf-30, zBuf,
+                      "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath );
+  }
+  j = strlen( zBuf );
+  sqlite3_randomness( 20, &zBuf[j] );
+  for( i = 0; i < 20; i++, j++ ){
+    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+  }
+  zBuf[j] = 0;
+  OSTRACE2( "TEMP FILENAME: %s\n", zBuf );
+  return SQLITE_OK;
+}
+
+
+/*
 ** Open a file.
 */
 static int os2Open(
@@ -18324,12 +19713,26 @@
   os2File *pFile = (os2File*)id;
   APIRET rc = NO_ERROR;
   ULONG ulAction;
+  char *zNameCp;
+  char zTmpname[CCHMAXPATH+1];    /* Buffer to hold name of temp file */
+
+  /* If the second argument to this function is NULL, generate a 
+  ** temporary file name to use 
+  */
+  if( !zName ){
+    int rc = getTempname(CCHMAXPATH+1, zTmpname);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+    zName = zTmpname;
+  }
+
 
   memset( pFile, 0, sizeof(*pFile) );
 
   OSTRACE2( "OPEN want %d\n", flags );
 
-  //ulOpenMode = flags & SQLITE_OPEN_READWRITE ? OPEN_ACCESS_READWRITE : OPEN_ACCESS_READONLY;
+  /*ulOpenMode = flags & SQLITE_OPEN_READWRITE ? OPEN_ACCESS_READWRITE : OPEN_ACCESS_READONLY;*/
   if( flags & SQLITE_OPEN_READWRITE ){
     ulOpenMode |= OPEN_ACCESS_READWRITE;
     OSTRACE1( "OPEN read/write\n" );
@@ -18338,7 +19741,7 @@
     OSTRACE1( "OPEN read only\n" );
   }
 
-  //ulOpenFlags = flags & SQLITE_OPEN_CREATE ? OPEN_ACTION_CREATE_IF_NEW : OPEN_ACTION_FAIL_IF_NEW;
+  /*ulOpenFlags = flags & SQLITE_OPEN_CREATE ? OPEN_ACTION_CREATE_IF_NEW : OPEN_ACTION_FAIL_IF_NEW;*/
   if( flags & SQLITE_OPEN_CREATE ){
     ulOpenFlags |= OPEN_ACTION_OPEN_IF_EXISTS | OPEN_ACTION_CREATE_IF_NEW;
     OSTRACE1( "OPEN open new/create\n" );
@@ -18347,7 +19750,7 @@
     OSTRACE1( "OPEN open existing\n" );
   }
 
-  //ulOpenMode |= flags & SQLITE_OPEN_MAIN_DB ? OPEN_SHARE_DENYNONE : OPEN_SHARE_DENYWRITE;
+  /*ulOpenMode |= flags & SQLITE_OPEN_MAIN_DB ? OPEN_SHARE_DENYNONE : OPEN_SHARE_DENYWRITE;*/
   if( flags & SQLITE_OPEN_MAIN_DB ){
     ulOpenMode |= OPEN_SHARE_DENYNONE;
     OSTRACE1( "OPEN share read/write\n" );
@@ -18359,7 +19762,7 @@
   if( flags & (SQLITE_OPEN_TEMP_DB | SQLITE_OPEN_TEMP_JOURNAL
                | SQLITE_OPEN_SUBJOURNAL) ){
     char pathUtf8[CCHMAXPATH];
-    //ulFileAttribute = FILE_HIDDEN;  //for debugging, we want to make sure it is deleted
+    /*ulFileAttribute = FILE_HIDDEN;  //for debugging, we want to make sure it is deleted*/
     ulFileAttribute = FILE_NORMAL;
     sqlite3OsFullPathname( pVfs, zName, CCHMAXPATH, pathUtf8 );
     pFile->pathToDel = convertUtf8PathToCp( pathUtf8 );
@@ -18375,7 +19778,7 @@
   ulOpenMode |= OPEN_FLAGS_FAIL_ON_ERROR;
   ulOpenMode |= OPEN_FLAGS_NOINHERIT;
 
-  char *zNameCp = convertUtf8PathToCp( zName );
+  zNameCp = convertUtf8PathToCp( zName );
   rc = DosOpen( (PSZ)zNameCp,
                 &h,
                 &ulAction,
@@ -18388,7 +19791,8 @@
   if( rc != NO_ERROR ){
     OSTRACE7( "OPEN Invalid handle rc=%d: zName=%s, ulAction=%#lx, ulAttr=%#lx, ulFlags=%#lx, ulMode=%#lx\n",
               rc, zName, ulAction, ulFileAttribute, ulOpenFlags, ulOpenMode );
-    free( pFile->pathToDel );
+    if( pFile->pathToDel )
+      free( pFile->pathToDel );
     pFile->pathToDel = NULL;
     if( flags & SQLITE_OPEN_READWRITE ){
       OSTRACE2( "OPEN %d Invalid handle\n", ((flags | SQLITE_OPEN_READONLY) & ~SQLITE_OPEN_READWRITE) );
@@ -18414,14 +19818,14 @@
 /*
 ** Delete the named file.
 */
-int os2Delete(
+static int os2Delete(
   sqlite3_vfs *pVfs,                     /* Not used on os2 */
   const char *zFilename,                 /* Name of file to delete */
   int syncDir                            /* Not used on os2 */
 ){
   APIRET rc = NO_ERROR;
-  SimulateIOError(return SQLITE_IOERR_DELETE);
   char *zFilenameCp = convertUtf8PathToCp( zFilename );
+  SimulateIOError( return SQLITE_IOERR_DELETE );
   rc = DosDelete( (PSZ)zFilenameCp );
   free( zFilenameCp );
   OSTRACE2( "DELETE \"%s\"\n", zFilename );
@@ -18434,13 +19838,14 @@
 static int os2Access(
   sqlite3_vfs *pVfs,        /* Not used on os2 */
   const char *zFilename,    /* Name of file to check */
-  int flags                 /* Type of test to make on this file */
+  int flags,                /* Type of test to make on this file */
+  int *pOut                 /* Write results here */
 ){
   FILESTATUS3 fsts3ConfigInfo;
   APIRET rc = NO_ERROR;
+  char *zFilenameCp = convertUtf8PathToCp( zFilename );
 
   memset( &fsts3ConfigInfo, 0, sizeof(fsts3ConfigInfo) );
-  char *zFilenameCp = convertUtf8PathToCp( zFilename );
   rc = DosQueryPathInfo( (PSZ)zFilenameCp, FIL_STANDARD,
                          &fsts3ConfigInfo, sizeof(FILESTATUS3) );
   free( zFilenameCp );
@@ -18453,56 +19858,13 @@
       OSTRACE3( "ACCESS %s access of read and exists  rc=%d\n", zFilename, rc );
       break;
     case SQLITE_ACCESS_READWRITE:
-      rc = (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0;
+      rc = (rc == NO_ERROR) && ( (fsts3ConfigInfo.attrFile & FILE_READONLY) == 0 );
       OSTRACE3( "ACCESS %s access of read/write  rc=%d\n", zFilename, rc );
       break;
     default:
       assert( !"Invalid flags argument" );
   }
-  return rc;
-}
-
-
-/*
-** Create a temporary file name in zBuf.  zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
-*/
-static int os2GetTempname( sqlite3_vfs *pVfs, int nBuf, char *zBuf ){
-  static const unsigned char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  char zTempPathBuf[3];
-  PSZ zTempPath = (PSZ)&zTempPathBuf;
-  char *zTempPathUTF;
-  if( DosScanEnv( (PSZ)"TEMP", &zTempPath ) ){
-    if( DosScanEnv( (PSZ)"TMP", &zTempPath ) ){
-      if( DosScanEnv( (PSZ)"TMPDIR", &zTempPath ) ){
-           ULONG ulDriveNum = 0, ulDriveMap = 0;
-           DosQueryCurrentDisk( &ulDriveNum, &ulDriveMap );
-           sprintf( (char*)zTempPath, "%c:", (char)( 'A' + ulDriveNum - 1 ) );
-      }
-    }
-  }
-  /* strip off a trailing slashes or backslashes, otherwise we would get *
-   * multiple (back)slashes which causes DosOpen() to fail               */
-  j = strlen(zTempPath);
-  while( j > 0 && ( zTempPath[j-1] == '\\' || zTempPath[j-1] == '/' ) ){
-    j--;
-  }
-  zTempPath[j] = '\0';
-  zTempPathUTF = convertCpPathToUtf8( zTempPath );
-  sqlite3_snprintf( nBuf-30, zBuf,
-                    "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPathUTF );
-  free( zTempPathUTF );
-  j = strlen( zBuf );
-  sqlite3_randomness( 20, &zBuf[j] );
-  for( i = 0; i < 20; i++, j++ ){
-    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-  }
-  zBuf[j] = 0;
-  OSTRACE2( "TEMP FILENAME: %s\n", zBuf );
+  *pOut = rc;
   return SQLITE_OK;
 }
 
@@ -18555,7 +19917,7 @@
 static void os2DlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
 /* no-op */
 }
-void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
+static void *os2DlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
   PFN pfn;
   APIRET rc;
   rc = DosQueryProcAddr((HMODULE)pHandle, 0L, zSymbol, &pfn);
@@ -18569,7 +19931,7 @@
   }
   return rc != NO_ERROR ? 0 : (void*)pfn;
 }
-void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
+static void os2DlClose(sqlite3_vfs *pVfs, void *pHandle){
   DosFreeModule((HMODULE)pHandle);
 }
 #else /* if SQLITE_OMIT_LOAD_EXTENSION is defined: */
@@ -18698,13 +20060,16 @@
   return 0;
 }
 
+static int os2GetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+  return 0;
+}
+
 /*
-** Return a pointer to the sqlite3DefaultVfs structure.   We use
-** a function rather than give the structure global scope because
-** some compilers (MSVC) do not allow forward declarations of
-** initialized structures.
+** Initialize and deinitialize the operating system interface.
 */
-SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){
+SQLITE_API int sqlite3_os_init(void){
+  initUconvObjects();
+
   static sqlite3_vfs os2Vfs = {
     1,                 /* iVersion */
     sizeof(os2File),   /* szOsFile */
@@ -18716,7 +20081,6 @@
     os2Open,           /* xOpen */
     os2Delete,         /* xDelete */
     os2Access,         /* xAccess */
-    os2GetTempname,    /* xGetTempname */
     os2FullPathname,   /* xFullPathname */
     os2DlOpen,         /* xDlOpen */
     os2DlError,        /* xDlError */
@@ -18724,13 +20088,18 @@
     os2DlClose,        /* xDlClose */
     os2Randomness,     /* xRandomness */
     os2Sleep,          /* xSleep */
-    os2CurrentTime     /* xCurrentTime */
+    os2CurrentTime,    /* xCurrentTime */
+    os2GetLastError    /* xGetLastError */
   };
-
-  return &os2Vfs;
+  sqlite3_vfs_register(&os2Vfs, 1);
+  return SQLITE_OK;
+}
+SQLITE_API int sqlite3_os_end(void){
+  freeUconvObjects();
+  return SQLITE_OK;
 }
 
-#endif /* OS_OS2 */
+#endif /* SQLITE_OS_OS2 */
 
 /************** End of os_os2.c **********************************************/
 /************** Begin file os_unix.c *****************************************/
@@ -18747,9 +20116,21 @@
 ******************************************************************************
 **
 ** This file contains code that is specific to Unix systems.
+**
+** $Id: os_unix.c,v 1.193 2008/07/10 00:32:42 drh Exp $
 */
-#if OS_UNIX              /* This file is used on unix only */
+#if SQLITE_OS_UNIX              /* This file is used on unix only */
 
+/*
+** If SQLITE_ENABLE_LOCKING_STYLE is defined, then several different 
+** locking implementations are provided:
+**
+**   * POSIX locking (the default),
+**   * No locking,
+**   * Dot-file locking,
+**   * flock() locking,
+**   * AFP locking (OSX only).
+*/
 /* #define SQLITE_ENABLE_LOCKING_STYLE 0 */
 
 /*
@@ -18782,6 +20163,7 @@
 #include <unistd.h>
 #include <sys/time.h>
 #include <errno.h>
+
 #ifdef SQLITE_ENABLE_LOCKING_STYLE
 #include <sys/ioctl.h>
 #include <sys/param.h>
@@ -18826,7 +20208,7 @@
   struct lockInfo *pLock;   /* Info about locks on this inode */
 #ifdef SQLITE_ENABLE_LOCKING_STYLE
   void *lockingContext;     /* Locking style specific state */
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+#endif
   int h;                    /* The file descriptor */
   unsigned char locktype;   /* The type of lock held on this fd */
   int dirfd;                /* File descriptor for the directory */
@@ -18858,7 +20240,11 @@
 **
 ** This file should be #included by the os_*.c files only.  It is not a
 ** general purpose header file.
+**
+** $Id: os_common.h,v 1.37 2008/05/29 20:22:37 shane Exp $
 */
+#ifndef _OS_COMMON_H_
+#define _OS_COMMON_H_
 
 /*
 ** At least two bugs have slipped in because we changed the MEMORY_DEBUG
@@ -18904,22 +20290,98 @@
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
-__inline__ unsigned long long int hwtime(void){
-  unsigned long long int x;
-  __asm__("rdtsc\n\t"
-          "mov %%edx, %%ecx\n\t"
-          :"=A" (x));
-  return x;
-}
-static unsigned long long int g_start;
-static unsigned int elapse;
-#define TIMER_START       g_start=hwtime()
-#define TIMER_END         elapse=hwtime()-g_start
-#define TIMER_ELAPSED     elapse
+
+/* 
+** hwtime.h contains inline assembler code for implementing 
+** high-performance timing routines.
+*/
+/************** Include hwtime.h in the middle of os_common.h ****************/
+/************** Begin file hwtime.h ******************************************/
+/*
+** 2008 May 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 contains inline asm code for retrieving "high-performance"
+** counters for x86 class CPUs.
+**
+** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+*/
+#ifndef _HWTIME_H_
+#define _HWTIME_H_
+
+/*
+** 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.
+*/
+#if (defined(__GNUC__) || defined(_MSC_VER)) && \
+      (defined(i386) || defined(__i386__) || defined(_M_IX86))
+
+  #if defined(__GNUC__)
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+     unsigned int lo, hi;
+     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+     return (sqlite_uint64)hi << 32 | lo;
+  }
+
+  #elif defined(_MSC_VER)
+
+  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
+     __asm {
+        rdtsc
+        ret       ; return value at EDX:EAX
+     }
+  }
+
+  #endif
+
+#elif (defined(__GNUC__) && defined(__x86_64__))
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+      unsigned long val;
+      __asm__ __volatile__ ("rdtsc" : "=A" (val));
+      return val;
+  }
+ 
+#else
+
+  #error Need implementation of sqlite3Hwtime() for your platform.
+
+  /*
+  ** To compile without implementing sqlite3Hwtime() for your platform,
+  ** you can remove the above #error and use the following
+  ** stub function.  You will lose timing support for many
+  ** of the debugging and testing utilities, but it should at
+  ** least compile and run.
+  */
+SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
+
+#endif
+
+#endif /* !defined(_HWTIME_H_) */
+
+/************** End of hwtime.h **********************************************/
+/************** Continuing where we left off in os_common.h ******************/
+
+static sqlite_uint64 g_start;
+static sqlite_uint64 g_elapsed;
+#define TIMER_START       g_start=sqlite3Hwtime()
+#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
+#define TIMER_ELAPSED     g_elapsed
 #else
 #define TIMER_START
 #define TIMER_END
-#define TIMER_ELAPSED     0
+#define TIMER_ELAPSED     ((sqlite_uint64)0)
 #endif
 
 /*
@@ -18972,6 +20434,8 @@
 #define OpenCounter(X)
 #endif
 
+#endif /* !defined(_OS_COMMON_H_) */
+
 /************** End of os_common.h *******************************************/
 /************** Continuing where we left off in os_unix.c ********************/
 
@@ -19044,8 +20508,6 @@
 ** by the same process.  It does not explicitly say so, but this implies
 ** that it overrides locks set by the same process using a different
 ** file descriptor.  Consider this test case:
-**
-**       int fd1 = open("./file1", O_RDWR|O_CREAT, 0644);
 **       int fd2 = open("./file2", O_RDWR|O_CREAT, 0644);
 **
 ** Suppose ./file1 and ./file2 are really the same file (because
@@ -19203,13 +20665,12 @@
 static Hash lockHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
 static Hash openHash = {SQLITE_HASH_BINARY, 0, 0, 0, 0, 0};
 
-#ifdef SQLITE_ENABLE_LOCKING_STYLE
 /*
 ** The locking styles are associated with the different file locking
 ** capabilities supported by different file systems.  
 **
 ** POSIX locking style fully supports shared and exclusive byte-range locks 
-** ADP locking only supports exclusive byte-range locks
+** AFP locking only supports exclusive byte-range locks
 ** FLOCK only supports a single file-global exclusive lock
 ** DOTLOCK isn't a true locking style, it refers to the use of a special
 **   file named the same as the database file with a '.lock' extension, this
@@ -19219,24 +20680,20 @@
 ** UNSUPPORTED means that no locking will be attempted, this is only used for
 **   file systems that are known to be unsupported
 */
-typedef enum {
-  posixLockingStyle = 0,       /* standard posix-advisory locks */
-  afpLockingStyle,             /* use afp locks */
-  flockLockingStyle,           /* use flock() */
-  dotlockLockingStyle,         /* use <file>.lock files */
-  noLockingStyle,              /* useful for read-only file system */
-  unsupportedLockingStyle      /* indicates unsupported file system */
-} sqlite3LockingStyle;
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+#define LOCKING_STYLE_POSIX        1
+#define LOCKING_STYLE_FLOCK        2
+#define LOCKING_STYLE_DOTFILE      3
+#define LOCKING_STYLE_NONE         4
+#define LOCKING_STYLE_AFP          5
 
 /*
 ** Helper functions to obtain and relinquish the global mutex.
 */
 static void enterMutex(){
-  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 }
 static void leaveMutex(){
-  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER));
+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER));
 }
 
 #if SQLITE_THREADSAFE
@@ -19382,12 +20839,12 @@
 ** Release a lockInfo structure previously allocated by findLockInfo().
 */
 static void releaseLockInfo(struct lockInfo *pLock){
-  if (pLock == NULL)
-    return;
-  pLock->nRef--;
-  if( pLock->nRef==0 ){
-    sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
-    sqlite3_free(pLock);
+  if( pLock ){
+    pLock->nRef--;
+    if( pLock->nRef==0 ){
+      sqlite3HashInsert(&lockHash, &pLock->key, sizeof(pLock->key), 0);
+      sqlite3_free(pLock);
+    }
   }
 }
 
@@ -19395,13 +20852,13 @@
 ** Release a openCnt structure previously allocated by findLockInfo().
 */
 static void releaseOpenCnt(struct openCnt *pOpen){
-  if (pOpen == NULL)
-    return;
-  pOpen->nRef--;
-  if( pOpen->nRef==0 ){
-    sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
-    free(pOpen->aPending);
-    sqlite3_free(pOpen);
+  if( pOpen ){
+    pOpen->nRef--;
+    if( pOpen->nRef==0 ){
+      sqlite3HashInsert(&openHash, &pOpen->key, sizeof(pOpen->key), 0);
+      free(pOpen->aPending);
+      sqlite3_free(pOpen);
+    }
   }
 }
 
@@ -19410,75 +20867,82 @@
 ** Tests a byte-range locking query to see if byte range locks are 
 ** supported, if not we fall back to dotlockLockingStyle.
 */
-static sqlite3LockingStyle sqlite3TestLockingStyle(
-  const char *filePath, 
-  int fd
-){
-  /* test byte-range lock using fcntl */
+static int testLockingStyle(int fd){
   struct flock lockInfo;
-  
+
+  /* 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;
   lockInfo.l_whence = SEEK_SET;
   lockInfo.l_type = F_RDLCK;
-  
   if( fcntl(fd, F_GETLK, &lockInfo)!=-1 ) {
-    return posixLockingStyle;
-  } 
+    return LOCKING_STYLE_POSIX;
+  }
   
-  /* testing for flock can give false positives.  So if if the above test
-  ** fails, then we fall back to using dot-lock style locking.
+  /* Testing for flock() can give false positives.  So if if the above 
+  ** test fails, then we fall back to using dot-file style locking.
   */  
-  return dotlockLockingStyle;
+  return LOCKING_STYLE_DOTFILE;
 }
+#endif
 
 /* 
-** Examines the f_fstypename entry in the statfs structure as returned by 
-** stat() for the file system hosting the database file, assigns the 
-** appropriate locking style based on its value.  These values and 
-** assignments are based on Darwin/OSX behavior and have not been tested on 
+** If SQLITE_ENABLE_LOCKING_STYLE is defined, this function Examines the 
+** f_fstypename entry in the statfs structure as returned by stat() for 
+** the file system hosting the database file and selects  the appropriate
+** locking style based on its value.  These values and assignments are 
+** based on Darwin/OSX behavior and have not been thoroughly tested on 
 ** other systems.
+**
+** If SQLITE_ENABLE_LOCKING_STYLE is not defined, this function always
+** returns LOCKING_STYLE_POSIX.
 */
-static sqlite3LockingStyle sqlite3DetectLockingStyle(
+static int detectLockingStyle(
+  sqlite3_vfs *pVfs,
   const char *filePath, 
   int fd
 ){
-
-#ifdef SQLITE_FIXED_LOCKING_STYLE
-  return (sqlite3LockingStyle)SQLITE_FIXED_LOCKING_STYLE;
-#else
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+  struct Mapping {
+    const char *zFilesystem;
+    int eLockingStyle;
+  } aMap[] = {
+    { "hfs",    LOCKING_STYLE_POSIX },
+    { "ufs",    LOCKING_STYLE_POSIX },
+    { "afpfs",  LOCKING_STYLE_AFP },
+    { "smbfs",  LOCKING_STYLE_FLOCK },
+    { "msdos",  LOCKING_STYLE_DOTFILE },
+    { "webdav", LOCKING_STYLE_NONE },
+    { 0, 0 }
+  };
+  int i;
   struct statfs fsInfo;
 
-  if( statfs(filePath, &fsInfo) == -1 ){
-    return sqlite3TestLockingStyle(filePath, fd);
-  }
-  if( fsInfo.f_flags & MNT_RDONLY ){
-    return noLockingStyle;
-  }
-  if( strcmp(fsInfo.f_fstypename, "hfs")==0 ||
-      strcmp(fsInfo.f_fstypename, "ufs")==0 ){
-    return posixLockingStyle;
+  if( !filePath ){
+    return LOCKING_STYLE_NONE;
   }
-  if( strcmp(fsInfo.f_fstypename, "afpfs")==0 ){
-    return afpLockingStyle;
+  if( pVfs->pAppData ){
+    return (int)pVfs->pAppData;
   }
-  if( strcmp(fsInfo.f_fstypename, "nfs")==0 ){
-    return sqlite3TestLockingStyle(filePath, fd);
-  }
-  if( strcmp(fsInfo.f_fstypename, "smbfs")==0 ){
-    return flockLockingStyle;
-  }
-  if( strcmp(fsInfo.f_fstypename, "msdos")==0 ){
-    return dotlockLockingStyle;
-  }
-  if( strcmp(fsInfo.f_fstypename, "webdav")==0 ){
-    return unsupportedLockingStyle;
+
+  if( statfs(filePath, &fsInfo) != -1 ){
+    if( fsInfo.f_flags & MNT_RDONLY ){
+      return LOCKING_STYLE_NONE;
+    }
+    for(i=0; aMap[i].zFilesystem; i++){
+      if( strcmp(fsInfo.f_fstypename, aMap[i].zFilesystem)==0 ){
+        return aMap[i].eLockingStyle;
+      }
+    }
   }
-  return sqlite3TestLockingStyle(filePath, fd);  
-#endif /* SQLITE_FIXED_LOCKING_STYLE */
-}
 
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
+  /* Default case. Handles, amongst others, "nfs". */
+  return testLockingStyle(fd);  
+#endif
+  return LOCKING_STYLE_POSIX;
+}
 
 /*
 ** Given a file descriptor, locate lockInfo and openCnt structures that
@@ -19671,7 +21135,7 @@
   got = read(id->h, pBuf, cnt);
 #endif
   TIMER_END;
-  OSTRACE5("READ    %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED);
+  OSTRACE5("READ    %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
   return got;
 }
 
@@ -19719,7 +21183,7 @@
   got = write(id->h, pBuf, cnt);
 #endif
   TIMER_END;
-  OSTRACE5("WRITE   %-3d %5d %7lld %d\n", id->h, got, offset, TIMER_ELAPSED);
+  OSTRACE5("WRITE   %-3d %5d %7lld %llu\n", id->h, got, offset, TIMER_ELAPSED);
   return got;
 }
 
@@ -19936,10 +21400,12 @@
 ** non-zero.  If the file is unlocked or holds only SHARED locks, then
 ** return zero.
 */
-static int unixCheckReservedLock(sqlite3_file *id){
+static int unixCheckReservedLock(sqlite3_file *id, int *pResOut){
   int r = 0;
   unixFile *pFile = (unixFile*)id;
 
+  SimulateIOError( return SQLITE_IOERR_CHECKRESERVEDLOCK; );
+
   assert( pFile );
   enterMutex(); /* Because pFile->pLock is shared across threads */
 
@@ -19965,7 +21431,8 @@
   leaveMutex();
   OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
 
-  return r;
+  *pResOut = r;
+  return SQLITE_OK;
 }
 
 /*
@@ -20288,43 +21755,58 @@
 }
 
 /*
+** 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.
+*/
+static int closeUnixFile(sqlite3_file *id){
+  unixFile *pFile = (unixFile*)id;
+  if( pFile ){
+    if( pFile->dirfd>=0 ){
+      close(pFile->dirfd);
+    }
+    if( pFile->h>=0 ){
+      close(pFile->h);
+    }
+    OSTRACE2("CLOSE   %-3d\n", pFile->h);
+    OpenCounter(-1);
+    memset(pFile, 0, sizeof(unixFile));
+  }
+  return SQLITE_OK;
+}
+
+/*
 ** Close a file.
 */
 static int unixClose(sqlite3_file *id){
-  unixFile *pFile = (unixFile *)id;
-  if( !pFile ) return SQLITE_OK;
-  unixUnlock(id, NO_LOCK);
-  if( pFile->dirfd>=0 ) close(pFile->dirfd);
-  pFile->dirfd = -1;
-  enterMutex();
-
-  if( pFile->pOpen->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 pOpen->aPending.  It will be automatically closed when
-    ** the last lock is cleared.
-    */
-    int *aNew;
-    struct openCnt *pOpen = pFile->pOpen;
-    aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
-    if( aNew==0 ){
-      /* If a malloc fails, just leak the file descriptor */
-    }else{
-      pOpen->aPending = aNew;
-      pOpen->aPending[pOpen->nPending] = pFile->h;
-      pOpen->nPending++;
+  if( id ){
+    unixFile *pFile = (unixFile *)id;
+    unixUnlock(id, NO_LOCK);
+    enterMutex();
+    if( pFile->pOpen && pFile->pOpen->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 pOpen->aPending.  It will be automatically closed when
+      ** the last lock is cleared.
+      */
+      int *aNew;
+      struct openCnt *pOpen = pFile->pOpen;
+      aNew = realloc( pOpen->aPending, (pOpen->nPending+1)*sizeof(int) );
+      if( aNew==0 ){
+        /* If a malloc fails, just leak the file descriptor */
+      }else{
+        pOpen->aPending = aNew;
+        pOpen->aPending[pOpen->nPending] = pFile->h;
+        pOpen->nPending++;
+        pFile->h = -1;
+      }
     }
-  }else{
-    /* There are no outstanding locks so we can close the file immediately */
-    close(pFile->h);
+    releaseLockInfo(pFile->pLock);
+    releaseOpenCnt(pFile->pOpen);
+    closeUnixFile(id);
+    leaveMutex();
   }
-  releaseLockInfo(pFile->pLock);
-  releaseOpenCnt(pFile->pOpen);
-
-  leaveMutex();
-  OSTRACE2("CLOSE   %-3d\n", pFile->h);
-  OpenCounter(-1);
-  memset(pFile, 0, sizeof(unixFile));
   return SQLITE_OK;
 }
 
@@ -20392,7 +21874,7 @@
  ** non-zero.  If the file is unlocked or holds only SHARED locks, then
  ** return zero.
  */
-static int afpUnixCheckReservedLock(sqlite3_file *id){
+static int afpCheckReservedLock(sqlite3_file *id, int *pResOut){
   int r = 0;
   unixFile *pFile = (unixFile*)id;
   
@@ -20420,16 +21902,16 @@
   }
   OSTRACE3("TEST WR-LOCK %d %d\n", pFile->h, r);
   
-  return r;
+  *pResOut = r;
+  return SQLITE_OK;
 }
 
 /* AFP-style locking following the behavior of unixLock, see the unixLock 
 ** function comments for details of lock management. */
-static int afpUnixLock(sqlite3_file *id, int locktype){
+static int afpLock(sqlite3_file *id, int locktype){
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
   afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
-  int gotPendingLock = 0;
   
   assert( pFile );
   OSTRACE5("LOCK    %d %s was %s pid=%d\n", pFile->h,
@@ -20483,7 +21965,6 @@
   */
   if( locktype==SHARED_LOCK ){
     int lk, failed;
-    int tries = 0;
     
     /* Now get the read-lock */
     /* note that the quality of the randomness doesn't matter that much */
@@ -20518,7 +21999,7 @@
       /* Acquire an EXCLUSIVE lock */
         
       /* Remove the shared lock before trying the range.  we'll need to 
-      ** reestablish the shared lock if we can't get the  afpUnixUnlock
+      ** reestablish the shared lock if we can't get the  afpUnlock
       */
       if (!_AFPFSSetLock(context->filePath, pFile->h, SHARED_FIRST +
                          context->sharedLockByte, 1, 0)) {
@@ -20559,8 +22040,7 @@
 ** If the locking level of the file descriptor is already at or below
 ** the requested locking level, this routine is a no-op.
 */
-static int afpUnixUnlock(sqlite3_file *id, int locktype) {
-  struct flock lock;
+static int afpUnlock(sqlite3_file *id, int locktype) {
   int rc = SQLITE_OK;
   unixFile *pFile = (unixFile*)id;
   afpLockingContext *context = (afpLockingContext *) pFile->lockingContext;
@@ -20627,21 +22107,13 @@
 /*
 ** Close a file & cleanup AFP specific locking context 
 */
-static int afpUnixClose(sqlite3_file *id) {
-  unixFile *pFile = (unixFile*)id;
-
-  if( !pFile ) return SQLITE_OK;
-  afpUnixUnlock(id, NO_LOCK);
-  sqlite3_free(pFile->lockingContext);
-  if( pFile->dirfd>=0 ) close(pFile->dirfd);
-  pFile->dirfd = -1;
-  enterMutex();
-  close(pFile->h);
-  leaveMutex();
-  OSTRACE2("CLOSE   %-3d\n", pFile->h);
-  OpenCounter(-1);
-  memset(pFile, 0, sizeof(unixFile));
-  return SQLITE_OK;
+static int afpClose(sqlite3_file *id) {
+  if( id ){
+    unixFile *pFile = (unixFile*)id;
+    afpUnlock(id, NO_LOCK);
+    sqlite3_free(pFile->lockingContext);
+  }
+  return closeUnixFile(id);
 }
 
 
@@ -20652,24 +22124,25 @@
 */
 typedef void flockLockingContext;
 
-static int flockUnixCheckReservedLock(sqlite3_file *id){
+static int flockCheckReservedLock(sqlite3_file *id, int *pResOut){
+  int r = 1;
   unixFile *pFile = (unixFile*)id;
   
-  if (pFile->locktype == RESERVED_LOCK) {
-    return 1; /* already have a reserved lock */
-  } else {
+  if (pFile->locktype != RESERVED_LOCK) {
     /* attempt to get the lock */
     int rc = flock(pFile->h, LOCK_EX | LOCK_NB);
     if (!rc) {
       /* got the lock, unlock it */
       flock(pFile->h, LOCK_UN);
-      return 0;  /* no one has it reserved */
+      r = 0;  /* no one has it reserved */
     }
-    return 1; /* someone else might have it reserved */
   }
+
+  *pResOut = r;
+  return SQLITE_OK;
 }
 
-static int flockUnixLock(sqlite3_file *id, int locktype) {
+static int flockLock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   
   /* if we already have a lock, it is exclusive.  
@@ -20691,7 +22164,7 @@
   }
 }
 
-static int flockUnixUnlock(sqlite3_file *id, int locktype) {
+static int flockUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
   
   assert( locktype<=SHARED_LOCK );
@@ -20720,80 +22193,55 @@
 /*
 ** Close a file.
 */
-static int flockUnixClose(sqlite3_file *id) {
-  unixFile *pFile = (unixFile*)id;
-  
-  if( !pFile ) return SQLITE_OK;
-  flockUnixUnlock(id, NO_LOCK);
-  
-  if( pFile->dirfd>=0 ) close(pFile->dirfd);
-  pFile->dirfd = -1;
-
-  enterMutex();
-  close(pFile->h);  
-  leaveMutex();
-  OSTRACE2("CLOSE   %-3d\n", pFile->h);
-  OpenCounter(-1);
-  memset(pFile, 0, sizeof(unixFile));
-  return SQLITE_OK;
+static int flockClose(sqlite3_file *id) {
+  if( id ){
+    flockUnlock(id, NO_LOCK);
+  }
+  return closeUnixFile(id);
 }
 
 #pragma mark Old-School .lock file based locking
 
-/*
-** The dotlockLockingContext structure contains all dotlock (.lock) lock
-** specific state
-*/
-typedef struct dotlockLockingContext dotlockLockingContext;
-struct dotlockLockingContext {
-  char *lockPath;
-};
-
-
-static int dotlockUnixCheckReservedLock(sqlite3_file *id) {
+static int dotlockCheckReservedLock(sqlite3_file *id, int *pResOut) {
+  int r = 1;
   unixFile *pFile = (unixFile*)id;
-  dotlockLockingContext *context;
+  char *zLockFile = (char *)pFile->lockingContext;
 
-  context = (dotlockLockingContext*)pFile->lockingContext;
-  if (pFile->locktype == RESERVED_LOCK) {
-    return 1; /* already have a reserved lock */
-  } else {
+  if (pFile->locktype != RESERVED_LOCK) {
     struct stat statBuf;
-    if (lstat(context->lockPath,&statBuf) == 0){
-      /* file exists, someone else has the lock */
-      return 1;
-    }else{
+    if (lstat(zLockFile, &statBuf) != 0){
       /* file does not exist, we could have it if we want it */
-      return 0;
+      r = 0;
     }
   }
+
+  *pResOut = r;
+  return SQLITE_OK;
 }
 
-static int dotlockUnixLock(sqlite3_file *id, int locktype) {
+static int dotlockLock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
-  dotlockLockingContext *context;
   int fd;
+  char *zLockFile = (char *)pFile->lockingContext;
 
-  context = (dotlockLockingContext*)pFile->lockingContext;
-  
   /* if we already have a lock, it is exclusive.  
   ** Just adjust level and punt on outta here. */
   if (pFile->locktype > NO_LOCK) {
     pFile->locktype = locktype;
     
     /* Always update the timestamp on the old file */
-    utimes(context->lockPath,NULL);
+    utimes(zLockFile, NULL);
     return SQLITE_OK;
   }
   
   /* check to see if lock file already exists */
   struct stat statBuf;
-  if (lstat(context->lockPath,&statBuf) == 0){
+  if (lstat(zLockFile,&statBuf) == 0){
     return SQLITE_BUSY; /* it does, busy */
   }
   
   /* grab an exclusive lock */
-  fd = open(context->lockPath,O_RDONLY|O_CREAT|O_EXCL,0600);
+  fd = open(zLockFile,O_RDONLY|O_CREAT|O_EXCL,0600);
   if( fd<0 ){
     /* failed to open/create the file, someone else may have stolen the lock */
     return SQLITE_BUSY; 
@@ -20805,12 +22253,10 @@
   return SQLITE_OK;
 }
 
-static int dotlockUnixUnlock(sqlite3_file *id, int locktype) {
+static int dotlockUnlock(sqlite3_file *id, int locktype) {
   unixFile *pFile = (unixFile*)id;
-  dotlockLockingContext *context;
+  char *zLockFile = (char *)pFile->lockingContext;
 
-  context = (dotlockLockingContext*)pFile->lockingContext;
-  
   assert( locktype<=SHARED_LOCK );
   
   /* no-op if possible */
@@ -20825,7 +22271,7 @@
   }
   
   /* no, really, unlock. */
-  unlink(context->lockPath);
+  unlink(zLockFile);
   pFile->locktype = NO_LOCK;
   return SQLITE_OK;
 }
@@ -20833,21 +22279,13 @@
 /*
  ** Close a file.
  */
-static int dotlockUnixClose(sqlite3_file *id) {
-  unixFile *pFile = (unixFile*)id;
-  
-  if( !pFile ) return SQLITE_OK;
-  dotlockUnixUnlock(id, NO_LOCK);
-  sqlite3_free(pFile->lockingContext);
-  if( pFile->dirfd>=0 ) close(pFile->dirfd);
-  pFile->dirfd = -1;
-  enterMutex();  
-  close(pFile->h);
-  leaveMutex();
-  OSTRACE2("CLOSE   %-3d\n", pFile->h);
-  OpenCounter(-1);
-  memset(pFile, 0, sizeof(unixFile));
-  return SQLITE_OK;
+static int dotlockClose(sqlite3_file *id) {
+  if( id ){
+    unixFile *pFile = (unixFile*)id;
+    dotlockUnlock(id, NO_LOCK);
+    sqlite3_free(pFile->lockingContext);
+  }
+  return closeUnixFile(id);
 }
 
 
@@ -20858,34 +22296,24 @@
 */
 typedef void nolockLockingContext;
 
-static int nolockUnixCheckReservedLock(sqlite3_file *id) {
-  return 0;
+static int nolockCheckReservedLock(sqlite3_file *id, int *pResOut) {
+  *pResOut = 0;
+  return SQLITE_OK;
 }
 
-static int nolockUnixLock(sqlite3_file *id, int locktype) {
+static int nolockLock(sqlite3_file *id, int locktype) {
   return SQLITE_OK;
 }
 
-static int nolockUnixUnlock(sqlite3_file *id, int locktype) {
+static int nolockUnlock(sqlite3_file *id, int locktype) {
   return SQLITE_OK;
 }
 
 /*
 ** Close a file.
 */
-static int nolockUnixClose(sqlite3_file *id) {
-  unixFile *pFile = (unixFile*)id;
-  
-  if( !pFile ) return SQLITE_OK;
-  if( pFile->dirfd>=0 ) close(pFile->dirfd);
-  pFile->dirfd = -1;
-  enterMutex();
-  close(pFile->h);
-  leaveMutex();
-  OSTRACE2("CLOSE   %-3d\n", pFile->h);
-  OpenCounter(-1);
-  memset(pFile, 0, sizeof(unixFile));
-  return SQLITE_OK;
+static int nolockClose(sqlite3_file *id) {
+  return closeUnixFile(id);
 }
 
 #endif /* SQLITE_ENABLE_LOCKING_STYLE */
@@ -20926,245 +22354,129 @@
 }
 
 /*
-** This vector defines all the methods that can operate on an sqlite3_file
-** for unix.
-*/
-static const sqlite3_io_methods sqlite3UnixIoMethod = {
-  1,                        /* iVersion */
-  unixClose,
-  unixRead,
-  unixWrite,
-  unixTruncate,
-  unixSync,
-  unixFileSize,
-  unixLock,
-  unixUnlock,
-  unixCheckReservedLock,
-  unixFileControl,
-  unixSectorSize,
-  unixDeviceCharacteristics
-};
-
-#ifdef SQLITE_ENABLE_LOCKING_STYLE
-/*
-** This vector defines all the methods that can operate on an sqlite3_file
-** for unix with AFP style file locking.
-*/
-static const sqlite3_io_methods sqlite3AFPLockingUnixIoMethod = {
-  1,                        /* iVersion */
-  afpUnixClose,
-  unixRead,
-  unixWrite,
-  unixTruncate,
-  unixSync,
-  unixFileSize,
-  afpUnixLock,
-  afpUnixUnlock,
-  afpUnixCheckReservedLock,
-  unixFileControl,
-  unixSectorSize,
-  unixDeviceCharacteristics
-};
-
-/*
-** This vector defines all the methods that can operate on an sqlite3_file
-** for unix with flock() style file locking.
-*/
-static const sqlite3_io_methods sqlite3FlockLockingUnixIoMethod = {
-  1,                        /* iVersion */
-  flockUnixClose,
-  unixRead,
-  unixWrite,
-  unixTruncate,
-  unixSync,
-  unixFileSize,
-  flockUnixLock,
-  flockUnixUnlock,
-  flockUnixCheckReservedLock,
-  unixFileControl,
-  unixSectorSize,
-  unixDeviceCharacteristics
-};
-
-/*
-** This vector defines all the methods that can operate on an sqlite3_file
-** for unix with dotlock style file locking.
-*/
-static const sqlite3_io_methods sqlite3DotlockLockingUnixIoMethod = {
-  1,                        /* iVersion */
-  dotlockUnixClose,
-  unixRead,
-  unixWrite,
-  unixTruncate,
-  unixSync,
-  unixFileSize,
-  dotlockUnixLock,
-  dotlockUnixUnlock,
-  dotlockUnixCheckReservedLock,
-  unixFileControl,
-  unixSectorSize,
-  unixDeviceCharacteristics
-};
-
-/*
-** This vector defines all the methods that can operate on an sqlite3_file
-** for unix with nolock style file locking.
-*/
-static const sqlite3_io_methods sqlite3NolockLockingUnixIoMethod = {
-  1,                        /* iVersion */
-  nolockUnixClose,
-  unixRead,
-  unixWrite,
-  unixTruncate,
-  unixSync,
-  unixFileSize,
-  nolockUnixLock,
-  nolockUnixUnlock,
-  nolockUnixCheckReservedLock,
-  unixFileControl,
-  unixSectorSize,
-  unixDeviceCharacteristics
-};
-
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
-
-/*
-** Allocate memory for a new unixFile and initialize that unixFile.
-** Write a pointer to the new unixFile into *pId.
-** If we run out of memory, close the file and return an error.
-*/
-#ifdef SQLITE_ENABLE_LOCKING_STYLE
-/* 
+** Initialize the contents of the unixFile structure pointed to by pId.
+**
 ** When locking extensions are enabled, the filepath and locking style 
 ** are needed to determine the unixFile pMethod to use for locking operations.
 ** The locking-style specific lockingContext data structure is created 
 ** and assigned here also.
 */
 static int fillInUnixFile(
+  sqlite3_vfs *pVfs,      /* Pointer to vfs object */
   int h,                  /* Open file descriptor of file being opened */
   int dirfd,              /* Directory file descriptor */
   sqlite3_file *pId,      /* Write to the unixFile structure here */
   const char *zFilename   /* Name of the file being opened */
 ){
-  sqlite3LockingStyle lockingStyle;
-  unixFile *pNew = (unixFile *)pId;
-  int rc;
-
-#ifdef FD_CLOEXEC
-  fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC);
+  /* Macro to define the static contents of an sqlite3_io_methods 
+  ** structure for a unix backend file. Different locking methods
+  ** require different functions for the xClose, xLock, xUnlock and
+  ** xCheckReservedLock methods.
+  */
+  #define IOMETHODS(xClose, xLock, xUnlock, xCheckReservedLock) {    \
+    1,                          /* iVersion */                           \
+    xClose,                     /* xClose */                             \
+    unixRead,                   /* xRead */                              \
+    unixWrite,                  /* xWrite */                             \
+    unixTruncate,               /* xTruncate */                          \
+    unixSync,                   /* xSync */                              \
+    unixFileSize,               /* xFileSize */                          \
+    xLock,                      /* xLock */                              \
+    xUnlock,                    /* xUnlock */                            \
+    xCheckReservedLock,         /* xCheckReservedLock */                 \
+    unixFileControl,            /* xFileControl */                       \
+    unixSectorSize,             /* xSectorSize */                        \
+    unixDeviceCharacteristics   /* xDeviceCapabilities */                \
+  }
+  static sqlite3_io_methods aIoMethod[] = {
+    IOMETHODS(unixClose, unixLock, unixUnlock, unixCheckReservedLock) 
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+   ,IOMETHODS(flockClose, flockLock, flockUnlock, flockCheckReservedLock)
+   ,IOMETHODS(dotlockClose, dotlockLock, dotlockUnlock,dotlockCheckReservedLock)
+   ,IOMETHODS(nolockClose, nolockLock, nolockUnlock, nolockCheckReservedLock)
+   ,IOMETHODS(afpClose, afpLock, afpUnlock, afpCheckReservedLock)
 #endif
+  };
 
-  lockingStyle = sqlite3DetectLockingStyle(zFilename, h);
-  if ( lockingStyle==posixLockingStyle ){
-    enterMutex();
-    rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
-    leaveMutex();
-    if( rc ){
-      if( dirfd>=0 ) close(dirfd);
-      close(h);
-      return rc;
-    }
-  } else {
-    /*  pLock and pOpen are only used for posix advisory locking */
-    pNew->pLock = NULL;
-    pNew->pOpen = NULL;
-  }
+  int eLockingStyle;
+  unixFile *pNew = (unixFile *)pId;
+  int rc = SQLITE_OK;
+
+  assert( pNew->pLock==NULL );
+  assert( pNew->pOpen==NULL );
 
   OSTRACE3("OPEN    %-3d %s\n", h, zFilename);    
-  pNew->dirfd = -1;
   pNew->h = h;
   pNew->dirfd = dirfd;
   SET_THREADID(pNew);
-    
-  switch(lockingStyle) {
-    case afpLockingStyle: {
-      /* afp locking uses the file path so it needs to be included in
-      ** the afpLockingContext */
-      afpLockingContext *context;
-      pNew->pMethod = &sqlite3AFPLockingUnixIoMethod;
-      pNew->lockingContext = context = sqlite3_malloc( sizeof(*context) );
-      if( context==0 ){
-        close(h);
-        if( dirfd>=0 ) close(dirfd);
-        return SQLITE_NOMEM;
-      }
 
-      /* NB: zFilename exists and remains valid until the file is closed
-      ** according to requirement F11141.  So we do not need to make a
-      ** copy of the filename. */
-      context->filePath = zFilename;
-      srandomdev();
+  assert(LOCKING_STYLE_POSIX==1);
+  assert(LOCKING_STYLE_FLOCK==2);
+  assert(LOCKING_STYLE_DOTFILE==3);
+  assert(LOCKING_STYLE_NONE==4);
+  assert(LOCKING_STYLE_AFP==5);
+  eLockingStyle = detectLockingStyle(pVfs, zFilename, h);
+
+  switch( eLockingStyle ){
+
+    case LOCKING_STYLE_POSIX: {
+      enterMutex();
+      rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
+      leaveMutex();
+      break;
+    }
+
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+    case LOCKING_STYLE_AFP: {
+      /* AFP locking uses the file path so it needs to be included in
+      ** the afpLockingContext.
+      */
+      afpLockingContext *pCtx;
+      pNew->lockingContext = pCtx = sqlite3_malloc( sizeof(*pCtx) );
+      if( pCtx==0 ){
+        rc = SQLITE_NOMEM;
+      }else{
+        /* NB: zFilename exists and remains valid until the file is closed
+        ** according to requirement F11141.  So we do not need to make a
+        ** copy of the filename. */
+        pCtx->filePath = zFilename;
+        srandomdev();
+      }
       break;
     }
-    case flockLockingStyle:
-      /* flock locking doesn't need additional lockingContext information */
-      pNew->pMethod = &sqlite3FlockLockingUnixIoMethod;
-      break;
-    case dotlockLockingStyle: {
-      /* dotlock locking uses the file path so it needs to be included in
-      ** the dotlockLockingContext */
-      dotlockLockingContext *context;
+
+    case LOCKING_STYLE_DOTFILE: {
+      /* Dotfile locking uses the file path so it needs to be included in
+      ** the dotlockLockingContext 
+      */
+      char *zLockFile;
       int nFilename;
-      nFilename = strlen(zFilename);
-      pNew->pMethod = &sqlite3DotlockLockingUnixIoMethod;
-      pNew->lockingContext = context = 
-         sqlite3_malloc( sizeof(*context) + nFilename + 6 );
-      if( context==0 ){
-        close(h);
-        if( dirfd>=0 ) close(dirfd);
-        return SQLITE_NOMEM;
+      nFilename = strlen(zFilename) + 6;
+      zLockFile = (char *)sqlite3_malloc(nFilename);
+      if( zLockFile==0 ){
+        rc = SQLITE_NOMEM;
+      }else{
+        sqlite3_snprintf(nFilename, zLockFile, "%s.lock", zFilename);
       }
-      context->lockPath = (char*)&context[1];
-      sqlite3_snprintf(nFilename, context->lockPath,
-                       "%s.lock", zFilename);
+      pNew->lockingContext = zLockFile;
       break;
     }
-    case posixLockingStyle:
-      /* posix locking doesn't need additional lockingContext information */
-      pNew->pMethod = &sqlite3UnixIoMethod;
-      break;
-    case noLockingStyle:
-    case unsupportedLockingStyle:
-    default: 
-      pNew->pMethod = &sqlite3NolockLockingUnixIoMethod;
-  }
-  OpenCounter(+1);
-  return SQLITE_OK;
-}
-#else /* SQLITE_ENABLE_LOCKING_STYLE */
-static int fillInUnixFile(
-  int h,                 /* Open file descriptor on file being opened */
-  int dirfd,
-  sqlite3_file *pId,     /* Write to the unixFile structure here */
-  const char *zFilename  /* Name of the file being opened */
-){
-  unixFile *pNew = (unixFile *)pId;
-  int rc;
 
-#ifdef FD_CLOEXEC
-  fcntl(h, F_SETFD, fcntl(h, F_GETFD, 0) | FD_CLOEXEC);
+    case LOCKING_STYLE_FLOCK: 
+    case LOCKING_STYLE_NONE: 
+      break;
 #endif
+  }
 
-  enterMutex();
-  rc = findLockInfo(h, &pNew->pLock, &pNew->pOpen);
-  leaveMutex();
-  if( rc ){
+  if( rc!=SQLITE_OK ){
     if( dirfd>=0 ) close(dirfd);
     close(h);
-    return rc;
+  }else{
+    pNew->pMethod = &aIoMethod[eLockingStyle-1];
+    OpenCounter(+1);
   }
-
-  OSTRACE3("OPEN    %-3d %s\n", h, zFilename);
-  pNew->dirfd = -1;
-  pNew->h = h;
-  pNew->dirfd = dirfd;
-  SET_THREADID(pNew);
-
-  pNew->pMethod = &sqlite3UnixIoMethod;
-  OpenCounter(+1);
-  return SQLITE_OK;
+  return rc;
 }
-#endif /* SQLITE_ENABLE_LOCKING_STYLE */
 
 /*
 ** Open a file descriptor to the directory containing file zFilename.
@@ -21198,6 +22510,63 @@
 }
 
 /*
+** Create a temporary file name in zBuf.  zBuf must be allocated
+** by the calling process and must be big enough to hold at least
+** pVfs->mxPathname bytes.
+*/
+static int getTempname(int nBuf, char *zBuf){
+  static const char *azDirs[] = {
+     0,
+     "/var/tmp",
+     "/usr/tmp",
+     "/tmp",
+     ".",
+  };
+  static const unsigned char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "0123456789";
+  int i, j;
+  struct stat buf;
+  const char *zDir = ".";
+
+  /* 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. 
+  */
+  SimulateIOError( return SQLITE_IOERR );
+
+  azDirs[0] = sqlite3_temp_directory;
+  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
+    if( azDirs[i]==0 ) continue;
+    if( stat(azDirs[i], &buf) ) continue;
+    if( !S_ISDIR(buf.st_mode) ) continue;
+    if( access(azDirs[i], 07) ) continue;
+    zDir = azDirs[i];
+    break;
+  }
+
+  /* Check that the output buffer is large enough for the temporary file 
+  ** name. If it is not, return SQLITE_ERROR.
+  */
+  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){
+    return SQLITE_ERROR;
+  }
+
+  do{
+    sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
+    j = strlen(zBuf);
+    sqlite3_randomness(15, &zBuf[j]);
+    for(i=0; i<15; i++, j++){
+      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+    }
+    zBuf[j] = 0;
+  }while( access(zBuf,0)==0 );
+  return SQLITE_OK;
+}
+
+
+/*
 ** Open the file zPath.
 ** 
 ** Previously, the SQLite OS layer used three functions in place of this
@@ -21245,6 +22614,12 @@
       (eType==SQLITE_OPEN_MASTER_JOURNAL || eType==SQLITE_OPEN_MAIN_JOURNAL)
   );
 
+  /* If argument zPath is a NULL pointer, this function is required to open
+  ** a temporary file. Use this buffer to store the file name in.
+  */
+  char zTmpname[MAX_PATHNAME+1];
+  const char *zName = zPath;
+
   /* Check the following statements are true: 
   **
   **   (a) Exactly one of the READWRITE and READONLY flags must be set, and 
@@ -21257,7 +22632,6 @@
   assert(isExclusive==0 || isCreate);
   assert(isDelete==0 || isCreate);
 
-
   /* The main DB, main journal, and master journal are never automatically
   ** deleted
   */
@@ -21272,14 +22646,25 @@
        || eType==SQLITE_OPEN_TRANSIENT_DB
   );
 
+  memset(pFile, 0, sizeof(unixFile));
+
+  if( !zName ){
+    int rc;
+    assert(isDelete && !isOpenDirectory);
+    rc = getTempname(MAX_PATHNAME+1, zTmpname);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+    zName = zTmpname;
+  }
+
   if( isReadonly )  oflags |= O_RDONLY;
   if( isReadWrite ) oflags |= O_RDWR;
   if( isCreate )    oflags |= O_CREAT;
   if( isExclusive ) oflags |= (O_EXCL|O_NOFOLLOW);
   oflags |= (O_LARGEFILE|O_BINARY);
 
-  memset(pFile, 0, sizeof(unixFile));
-  fd = open(zPath, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
+  fd = open(zName, oflags, isDelete?0600:SQLITE_DEFAULT_FILE_PERMISSIONS);
   if( fd<0 && errno!=EISDIR && isReadWrite && !isExclusive ){
     /* Failed to open the file for read/write access. Try read-only. */
     flags &= ~(SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE);
@@ -21290,7 +22675,7 @@
     return SQLITE_CANTOPEN;
   }
   if( isDelete ){
-    unlink(zPath);
+    unlink(zName);
   }
   if( pOutFlags ){
     *pOutFlags = flags;
@@ -21304,7 +22689,12 @@
       return rc;
     }
   }
-  return fillInUnixFile(fd, dirfd, pFile, zPath);
+
+#ifdef FD_CLOEXEC
+  fcntl(fd, F_SETFD, fcntl(fd, F_GETFD, 0) | FD_CLOEXEC);
+#endif
+
+  return fillInUnixFile(pVfs, fd, dirfd, pFile, zPath);
 }
 
 /*
@@ -21338,8 +22728,14 @@
 **
 ** Otherwise return 0.
 */
-static int unixAccess(sqlite3_vfs *pVfs, const char *zPath, int flags){
+static int unixAccess(
+  sqlite3_vfs *pVfs, 
+  const char *zPath, 
+  int flags, 
+  int *pResOut
+){
   int amode = 0;
+  SimulateIOError( return SQLITE_IOERR_ACCESS; );
   switch( flags ){
     case SQLITE_ACCESS_EXISTS:
       amode = F_OK;
@@ -21354,67 +22750,11 @@
     default:
       assert(!"Invalid flags argument");
   }
-  return (access(zPath, amode)==0);
+  *pResOut = (access(zPath, amode)==0);
+  return SQLITE_OK;
 }
 
-/*
-** Create a temporary file name in zBuf.  zBuf must be allocated
-** by the calling process and must be big enough to hold at least
-** pVfs->mxPathname bytes.
-*/
-static int unixGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-  static const char *azDirs[] = {
-     0,
-     "/var/tmp",
-     "/usr/tmp",
-     "/tmp",
-     ".",
-  };
-  static const unsigned char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  struct stat buf;
-  const char *zDir = ".";
-
-  /* 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. 
-  */
-  SimulateIOError( return SQLITE_ERROR );
-
-  azDirs[0] = sqlite3_temp_directory;
-  for(i=0; i<sizeof(azDirs)/sizeof(azDirs[0]); i++){
-    if( azDirs[i]==0 ) continue;
-    if( stat(azDirs[i], &buf) ) continue;
-    if( !S_ISDIR(buf.st_mode) ) continue;
-    if( access(azDirs[i], 07) ) continue;
-    zDir = azDirs[i];
-    break;
-  }
-
-  /* Check that the output buffer is large enough for the temporary file 
-  ** name. If it is not, return SQLITE_ERROR.
-  */
-  if( (strlen(zDir) + strlen(SQLITE_TEMP_FILE_PREFIX) + 17) >= nBuf ){
-    return SQLITE_ERROR;
-  }
-
-  do{
-    assert( pVfs->mxPathname==MAX_PATHNAME );
-    sqlite3_snprintf(nBuf-17, zBuf, "%s/"SQLITE_TEMP_FILE_PREFIX, zDir);
-    j = strlen(zBuf);
-    sqlite3_randomness(15, &zBuf[j]);
-    for(i=0; i<15; i++, j++){
-      zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-    }
-    zBuf[j] = 0;
-  }while( access(zBuf,0)==0 );
-  return SQLITE_OK;
-}
-
-
+
 /*
 ** Turn a relative pathname into a full pathname. The relative path
 ** is stored as a nul-terminated string in the buffer pointed to by
@@ -21609,39 +22949,68 @@
   return 0;
 }
 
+static int unixGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+  return 0;
+}
+
 /*
-** Return a pointer to the sqlite3DefaultVfs structure.   We use
-** a function rather than give the structure global scope because
-** some compilers (MSVC) do not allow forward declarations of
-** initialized structures.
-*/
-SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){
-  static sqlite3_vfs unixVfs = {
-    1,                  /* iVersion */
-    sizeof(unixFile),   /* szOsFile */
-    MAX_PATHNAME,       /* mxPathname */
-    0,                  /* pNext */
-    "unix",             /* zName */
-    0,                  /* pAppData */
-  
-    unixOpen,           /* xOpen */
-    unixDelete,         /* xDelete */
-    unixAccess,         /* xAccess */
-    unixGetTempname,    /* xGetTempName */
-    unixFullPathname,   /* xFullPathname */
-    unixDlOpen,         /* xDlOpen */
-    unixDlError,        /* xDlError */
-    unixDlSym,          /* xDlSym */
-    unixDlClose,        /* xDlClose */
-    unixRandomness,     /* xRandomness */
-    unixSleep,          /* xSleep */
-    unixCurrentTime     /* xCurrentTime */
+** Initialize the operating system interface.
+*/
+SQLITE_API int sqlite3_os_init(void){ 
+  /* Macro to define the static contents of an sqlite3_vfs structure for
+  ** the unix backend. The two parameters are the values to use for
+  ** the sqlite3_vfs.zName and sqlite3_vfs.pAppData fields, respectively.
+  ** 
+  */
+  #define UNIXVFS(zVfsName, pVfsAppData) {                  \
+    1,                    /* iVersion */                    \
+    sizeof(unixFile),     /* szOsFile */                    \
+    MAX_PATHNAME,         /* mxPathname */                  \
+    0,                    /* pNext */                       \
+    zVfsName,             /* zName */                       \
+    (void *)pVfsAppData,  /* pAppData */                    \
+    unixOpen,             /* xOpen */                       \
+    unixDelete,           /* xDelete */                     \
+    unixAccess,           /* xAccess */                     \
+    unixFullPathname,     /* xFullPathname */               \
+    unixDlOpen,           /* xDlOpen */                     \
+    unixDlError,          /* xDlError */                    \
+    unixDlSym,            /* xDlSym */                      \
+    unixDlClose,          /* xDlClose */                    \
+    unixRandomness,       /* xRandomness */                 \
+    unixSleep,            /* xSleep */                      \
+    unixCurrentTime,      /* xCurrentTime */                \
+    unixGetLastError      /* xGetLastError */               \
+  }
+
+  static sqlite3_vfs unixVfs = UNIXVFS("unix", 0);
+#ifdef SQLITE_ENABLE_LOCKING_STYLE
+#if 0
+  int i;
+  static sqlite3_vfs aVfs[] = {
+    UNIXVFS("unix-posix",   LOCKING_STYLE_POSIX), 
+    UNIXVFS("unix-afp",     LOCKING_STYLE_AFP), 
+    UNIXVFS("unix-flock",   LOCKING_STYLE_FLOCK), 
+    UNIXVFS("unix-dotfile", LOCKING_STYLE_DOTFILE), 
+    UNIXVFS("unix-none",    LOCKING_STYLE_NONE)
   };
-  
-  return &unixVfs;
+  for(i=0; i<(sizeof(aVfs)/sizeof(sqlite3_vfs)); i++){
+    sqlite3_vfs_register(&aVfs[i], 0);
+  }
+#endif
+#endif
+  sqlite3_vfs_register(&unixVfs, 1);
+  return SQLITE_OK; 
+}
+
+/*
+** Shutdown the operating system interface. This is a no-op for unix.
+*/
+SQLITE_API int sqlite3_os_end(void){ 
+  return SQLITE_OK; 
 }
  
-#endif /* OS_UNIX */
+#endif /* SQLITE_OS_UNIX */
 
 /************** End of os_unix.c *********************************************/
 /************** Begin file os_win.c ******************************************/
@@ -21658,8 +23027,10 @@
 ******************************************************************************
 **
 ** This file contains code that is specific to windows.
+**
+** $Id: os_win.c,v 1.129 2008/06/26 10:41:19 danielk1977 Exp $
 */
-#if OS_WIN               /* This file is used for windows only */
+#if SQLITE_OS_WIN               /* This file is used for windows only */
 
 
 /*
@@ -21724,7 +23095,11 @@
 **
 ** This file should be #included by the os_*.c files only.  It is not a
 ** general purpose header file.
+**
+** $Id: os_common.h,v 1.37 2008/05/29 20:22:37 shane Exp $
 */
+#ifndef _OS_COMMON_H_
+#define _OS_COMMON_H_
 
 /*
 ** At least two bugs have slipped in because we changed the MEMORY_DEBUG
@@ -21770,22 +23145,98 @@
 ** on i486 hardware.
 */
 #ifdef SQLITE_PERFORMANCE_TRACE
-__inline__ unsigned long long int hwtime(void){
-  unsigned long long int x;
-  __asm__("rdtsc\n\t"
-          "mov %%edx, %%ecx\n\t"
-          :"=A" (x));
-  return x;
-}
-static unsigned long long int g_start;
-static unsigned int elapse;
-#define TIMER_START       g_start=hwtime()
-#define TIMER_END         elapse=hwtime()-g_start
-#define TIMER_ELAPSED     elapse
+
+/* 
+** hwtime.h contains inline assembler code for implementing 
+** high-performance timing routines.
+*/
+/************** Include hwtime.h in the middle of os_common.h ****************/
+/************** Begin file hwtime.h ******************************************/
+/*
+** 2008 May 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 contains inline asm code for retrieving "high-performance"
+** counters for x86 class CPUs.
+**
+** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+*/
+#ifndef _HWTIME_H_
+#define _HWTIME_H_
+
+/*
+** 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.
+*/
+#if (defined(__GNUC__) || defined(_MSC_VER)) && \
+      (defined(i386) || defined(__i386__) || defined(_M_IX86))
+
+  #if defined(__GNUC__)
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+     unsigned int lo, hi;
+     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+     return (sqlite_uint64)hi << 32 | lo;
+  }
+
+  #elif defined(_MSC_VER)
+
+  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
+     __asm {
+        rdtsc
+        ret       ; return value at EDX:EAX
+     }
+  }
+
+  #endif
+
+#elif (defined(__GNUC__) && defined(__x86_64__))
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+      unsigned long val;
+      __asm__ __volatile__ ("rdtsc" : "=A" (val));
+      return val;
+  }
+ 
+#else
+
+  #error Need implementation of sqlite3Hwtime() for your platform.
+
+  /*
+  ** To compile without implementing sqlite3Hwtime() for your platform,
+  ** you can remove the above #error and use the following
+  ** stub function.  You will lose timing support for many
+  ** of the debugging and testing utilities, but it should at
+  ** least compile and run.
+  */
+SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
+
+#endif
+
+#endif /* !defined(_HWTIME_H_) */
+
+/************** End of hwtime.h **********************************************/
+/************** Continuing where we left off in os_common.h ******************/
+
+static sqlite_uint64 g_start;
+static sqlite_uint64 g_elapsed;
+#define TIMER_START       g_start=sqlite3Hwtime()
+#define TIMER_END         g_elapsed=sqlite3Hwtime()-g_start
+#define TIMER_ELAPSED     g_elapsed
 #else
 #define TIMER_START
 #define TIMER_END
-#define TIMER_ELAPSED     0
+#define TIMER_ELAPSED     ((sqlite_uint64)0)
 #endif
 
 /*
@@ -21838,6 +23289,8 @@
 #define OpenCounter(X)
 #endif
 
+#endif /* !defined(_OS_COMMON_H_) */
+
 /************** End of os_common.h *******************************************/
 /************** Continuing where we left off in os_win.c *********************/
 
@@ -21845,18 +23298,15 @@
 ** Determine if we are dealing with WindowsCE - which has a much
 ** reduced API.
 */
-#if defined(_WIN32_WCE)
-# define OS_WINCE 1
+#if defined(SQLITE_OS_WINCE)
 # define AreFileApisANSI() 1
-#else
-# define OS_WINCE 0
 #endif
 
 /*
 ** WinCE lacks native support for file locking so we have to fake it
 ** with some code of our own.
 */
-#if OS_WINCE
+#if SQLITE_OS_WINCE
 typedef struct winceLock {
   int nReaders;       /* Number of reader locks obtained */
   BOOL bPending;      /* Indicates a pending lock has been obtained */
@@ -21875,7 +23325,7 @@
   HANDLE h;               /* Handle for accessing the file */
   unsigned char locktype; /* Type of lock currently held on this file */
   short sharedLockByte;   /* Randomly chosen byte used as a shared lock */
-#if OS_WINCE
+#if SQLITE_OS_WINCE
   WCHAR *zDeleteOnClose;  /* Name of file to delete when closing */
   HANDLE hMutex;          /* Mutex used to control access to shared lock */  
   HANDLE hShared;         /* Shared memory segment used for locking */
@@ -21914,7 +23364,7 @@
 ** WinNT/2K/XP so that we will know whether or not we can safely call
 ** the LockFileEx() API.
 */
-#if OS_WINCE
+#if SQLITE_OS_WINCE
 # define isNT()  (1)
 #else
   static int isNT(void){
@@ -21926,7 +23376,7 @@
     }
     return sqlite3_os_type==2;
   }
-#endif /* OS_WINCE */
+#endif /* SQLITE_OS_WINCE */
 
 /*
 ** Convert a UTF-8 string to microsoft unicode (UTF-16?). 
@@ -22057,7 +23507,7 @@
   return zFilenameMbcs;
 }
 
-#if OS_WINCE
+#if SQLITE_OS_WINCE
 /*************************************************************************
 ** This section contains code for WinCE only.
 */
@@ -22360,7 +23810,7 @@
 /*
 ** End of the special code for wince
 *****************************************************************************/
-#endif /* OS_WINCE */
+#endif /* SQLITE_OS_WINCE */
 
 /*****************************************************************************
 ** The next group of routines implement the I/O methods specified
@@ -22385,7 +23835,7 @@
   do{
     rc = CloseHandle(pFile->h);
   }while( rc==0 && cnt++ < MX_CLOSE_ATTEMPT && (Sleep(100), 1) );
-#if OS_WINCE
+#if SQLITE_OS_WINCE
 #define WINCE_DELETION_ATTEMPTS 3
   winceDestroyLock(pFile);
   if( pFile->zDeleteOnClose ){
@@ -22718,7 +24168,7 @@
 ** file by this or any other process. If such a lock is held, return
 ** non-zero, otherwise zero.
 */
-static int winCheckReservedLock(sqlite3_file *id){
+static int winCheckReservedLock(sqlite3_file *id, int *pResOut){
   int rc;
   winFile *pFile = (winFile*)id;
   assert( pFile!=0 );
@@ -22733,7 +24183,8 @@
     rc = !rc;
     OSTRACE3("TEST WR-LOCK %d %d (remote)\n", pFile->h, rc);
   }
-  return rc;
+  *pResOut = rc;
+  return SQLITE_OK;
 }
 
 /*
@@ -22855,6 +24306,57 @@
 }
 
 /*
+** Create a temporary file name in zBuf.  zBuf must be big enough to
+** hold at pVfs->mxPathname characters.
+*/
+static int getTempname(int nBuf, char *zBuf){
+  static char zChars[] =
+    "abcdefghijklmnopqrstuvwxyz"
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+    "0123456789";
+  int i, j;
+  char zTempPath[MAX_PATH+1];
+  if( sqlite3_temp_directory ){
+    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
+  }else if( isNT() ){
+    char *zMulti;
+    WCHAR zWidePath[MAX_PATH];
+    GetTempPathW(MAX_PATH-30, zWidePath);
+    zMulti = unicodeToUtf8(zWidePath);
+    if( zMulti ){
+      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
+      free(zMulti);
+    }else{
+      return SQLITE_NOMEM;
+    }
+  }else{
+    char *zUtf8;
+    char zMbcsPath[MAX_PATH];
+    GetTempPathA(MAX_PATH-30, zMbcsPath);
+    zUtf8 = mbcsToUtf8(zMbcsPath);
+    if( zUtf8 ){
+      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
+      free(zUtf8);
+    }else{
+      return SQLITE_NOMEM;
+    }
+  }
+  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
+  zTempPath[i] = 0;
+  sqlite3_snprintf(nBuf-30, zBuf,
+                   "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
+  j = strlen(zBuf);
+  sqlite3_randomness(20, &zBuf[j]);
+  for(i=0; i<20; i++, j++){
+    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
+  }
+  zBuf[j] = 0;
+  OSTRACE2("TEMP FILENAME: %s\n", zBuf);
+  return SQLITE_OK; 
+}
+
+
+/*
 ** Open a file.
 */
 static int winOpen(
@@ -22871,7 +24373,23 @@
   DWORD dwFlagsAndAttributes = 0;
   int isTemp;
   winFile *pFile = (winFile*)id;
-  void *zConverted = convertUtf8Filename(zName);
+  void *zConverted;                 /* Filename in OS encoding */
+  const char *zUtf8Name = zName;    /* Filename in UTF-8 encoding */
+  char zTmpname[MAX_PATH+1];        /* Buffer used to create temp filename */
+
+  /* If the second argument to this function is NULL, generate a 
+  ** temporary file name to use 
+  */
+  if( !zUtf8Name ){
+    int rc = getTempname(MAX_PATH+1, zTmpname);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+    zUtf8Name = zTmpname;
+  }
+
+  /* Convert the filename to the system encoding. */
+  zConverted = convertUtf8Filename(zUtf8Name);
   if( zConverted==0 ){
     return SQLITE_NOMEM;
   }
@@ -22892,7 +24410,7 @@
     dwShareMode = 0;
   }
   if( flags & SQLITE_OPEN_DELETEONCLOSE ){
-#if OS_WINCE
+#if SQLITE_OS_WINCE
     dwFlagsAndAttributes = FILE_ATTRIBUTE_HIDDEN;
 #else
     dwFlagsAndAttributes = FILE_ATTRIBUTE_TEMPORARY
@@ -22917,7 +24435,7 @@
        NULL
     );
   }else{
-#if OS_WINCE
+#if SQLITE_OS_WINCE
     return SQLITE_NOMEM;
 #else
     h = CreateFileA((char*)zConverted,
@@ -22949,7 +24467,7 @@
   memset(pFile, 0, sizeof(*pFile));
   pFile->pMethod = &winIoMethod;
   pFile->h = h;
-#if OS_WINCE
+#if SQLITE_OS_WINCE
   if( (flags & (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)) ==
                (SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_DB)
        && !winceCreateLock(zName, pFile)
@@ -23000,7 +24518,7 @@
     }while( (rc = GetFileAttributesW(zConverted))!=0xffffffff 
             && cnt++ < MX_DELETION_ATTEMPTS && (Sleep(100), 1) );
   }else{
-#if OS_WINCE
+#if SQLITE_OS_WINCE
     return SQLITE_NOMEM;
 #else
     do{
@@ -23020,7 +24538,8 @@
 static int winAccess(
   sqlite3_vfs *pVfs,         /* Not used on win32 */
   const char *zFilename,     /* Name of file to check */
-  int flags                  /* Type of test to make on this file */
+  int flags,                 /* Type of test to make on this file */
+  int *pResOut               /* OUT: Result */
 ){
   DWORD attr;
   int rc;
@@ -23031,7 +24550,7 @@
   if( isNT() ){
     attr = GetFileAttributesW((WCHAR*)zConverted);
   }else{
-#if OS_WINCE
+#if SQLITE_OS_WINCE
     return SQLITE_NOMEM;
 #else
     attr = GetFileAttributesA((char*)zConverted);
@@ -23049,61 +24568,12 @@
     default:
       assert(!"Invalid flags argument");
   }
-  return rc;
+  *pResOut = rc;
+  return SQLITE_OK;
 }
 
 
 /*
-** Create a temporary file name in zBuf.  zBuf must be big enough to
-** hold at pVfs->mxPathname characters.
-*/
-static int winGetTempname(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
-  static char zChars[] =
-    "abcdefghijklmnopqrstuvwxyz"
-    "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
-    "0123456789";
-  int i, j;
-  char zTempPath[MAX_PATH+1];
-  if( sqlite3_temp_directory ){
-    sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", sqlite3_temp_directory);
-  }else if( isNT() ){
-    char *zMulti;
-    WCHAR zWidePath[MAX_PATH];
-    GetTempPathW(MAX_PATH-30, zWidePath);
-    zMulti = unicodeToUtf8(zWidePath);
-    if( zMulti ){
-      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zMulti);
-      free(zMulti);
-    }else{
-      return SQLITE_NOMEM;
-    }
-  }else{
-    char *zUtf8;
-    char zMbcsPath[MAX_PATH];
-    GetTempPathA(MAX_PATH-30, zMbcsPath);
-    zUtf8 = mbcsToUtf8(zMbcsPath);
-    if( zUtf8 ){
-      sqlite3_snprintf(MAX_PATH-30, zTempPath, "%s", zUtf8);
-      free(zUtf8);
-    }else{
-      return SQLITE_NOMEM;
-    }
-  }
-  for(i=strlen(zTempPath); i>0 && zTempPath[i-1]=='\\'; i--){}
-  zTempPath[i] = 0;
-  sqlite3_snprintf(nBuf-30, zBuf,
-                   "%s\\"SQLITE_TEMP_FILE_PREFIX, zTempPath);
-  j = strlen(zBuf);
-  sqlite3_randomness(20, &zBuf[j]);
-  for(i=0; i<20; i++, j++){
-    zBuf[j] = (char)zChars[ ((unsigned char)zBuf[j])%(sizeof(zChars)-1) ];
-  }
-  zBuf[j] = 0;
-  OSTRACE2("TEMP FILENAME: %s\n", zBuf);
-  return SQLITE_OK; 
-}
-
-/*
 ** Turn a relative pathname into a full pathname.  Write the full
 ** pathname into zOut[].  zOut[] will be at least pVfs->mxPathname
 ** bytes in size.
@@ -23120,13 +24590,13 @@
   return SQLITE_OK;
 #endif
 
-#if OS_WINCE
+#if SQLITE_OS_WINCE
   /* WinCE has no concept of a relative pathname, or so I am told. */
   sqlite3_snprintf(pVfs->mxPathname, zFull, "%s", zRelative);
   return SQLITE_OK;
 #endif
 
-#if !OS_WINCE && !defined(__CYGWIN__)
+#if !SQLITE_OS_WINCE && !defined(__CYGWIN__)
   int nByte;
   void *zConverted;
   char *zOut;
@@ -23184,7 +24654,7 @@
   if( isNT() ){
     h = LoadLibraryW((WCHAR*)zConverted);
   }else{
-#if OS_WINCE
+#if SQLITE_OS_WINCE
     return 0;
 #else
     h = LoadLibraryA((char*)zConverted);
@@ -23194,7 +24664,7 @@
   return (void*)h;
 }
 static void winDlError(sqlite3_vfs *pVfs, int nBuf, char *zBufOut){
-#if OS_WINCE
+#if SQLITE_OS_WINCE
   int error = GetLastError();
   if( error>0x7FFFFFF ){
     sqlite3_snprintf(nBuf, zBufOut, "OsError 0x%x", error);
@@ -23214,7 +24684,7 @@
 #endif
 }
 void *winDlSym(sqlite3_vfs *pVfs, void *pHandle, const char *zSymbol){
-#if OS_WINCE
+#if SQLITE_OS_WINCE
   /* The GetProcAddressA() routine is only available on wince. */
   return GetProcAddressA((HANDLE)pHandle, zSymbol);
 #else
@@ -23292,7 +24762,7 @@
      100-nanosecond intervals since January 1, 1601 (= JD 2305813.5). 
   */
   double now;
-#if OS_WINCE
+#if SQLITE_OS_WINCE
   SYSTEMTIME time;
   GetSystemTime(&time);
   SystemTimeToFileTime(&time,&ft);
@@ -23309,14 +24779,14 @@
   return 0;
 }
 
+static int winGetLastError(sqlite3_vfs *pVfs, int nBuf, char *zBuf){
+  return 0;
+}
 
 /*
-** Return a pointer to the sqlite3DefaultVfs structure.   We use
-** a function rather than give the structure global scope because
-** some compilers (MSVC) do not allow forward declarations of
-** initialized structures.
+** Initialize and deinitialize the operating system interface.
 */
-SQLITE_PRIVATE sqlite3_vfs *sqlite3OsDefaultVfs(void){
+SQLITE_API int sqlite3_os_init(void){
   static sqlite3_vfs winVfs = {
     1,                 /* iVersion */
     sizeof(winFile),   /* szOsFile */
@@ -23324,11 +24794,10 @@
     0,                 /* pNext */
     "win32",           /* zName */
     0,                 /* pAppData */
-  
+ 
     winOpen,           /* xOpen */
     winDelete,         /* xDelete */
     winAccess,         /* xAccess */
-    winGetTempname,    /* xGetTempName */
     winFullPathname,   /* xFullPathname */
     winDlOpen,         /* xDlOpen */
     winDlError,        /* xDlError */
@@ -23336,13 +24805,17 @@
     winDlClose,        /* xDlClose */
     winRandomness,     /* xRandomness */
     winSleep,          /* xSleep */
-    winCurrentTime     /* xCurrentTime */
+    winCurrentTime,    /* xCurrentTime */
+    winGetLastError    /* xGetLastError */
   };
-  
-  return &winVfs;
+  sqlite3_vfs_register(&winVfs, 1);
+  return SQLITE_OK; 
+}
+SQLITE_API int sqlite3_os_end(void){ 
+  return SQLITE_OK;
 }
 
-#endif /* OS_WIN */
+#endif /* SQLITE_OS_WIN */
 
 /************** End of os_win.c **********************************************/
 /************** Begin file bitvec.c ******************************************/
@@ -23380,7 +24853,7 @@
 ** start of a transaction, and is thus usually less than a few thousand,
 ** but can be as large as 2 billion for a really big database.
 **
-** @(#) $Id: bitvec.c,v 1.5 2008/05/13 13:27:34 drh Exp $
+** @(#) $Id: bitvec.c,v 1.6 2008/06/20 14:59:51 danielk1977 Exp $
 */
 
 #define BITVEC_SZ        512
@@ -23487,9 +24960,9 @@
     u32 bin = (i-1)/p->iDivisor;
     i = (i-1)%p->iDivisor + 1;
     if( p->u.apSub[bin]==0 ){
-      sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
+      sqlite3BeginBenignMalloc();
       p->u.apSub[bin] = sqlite3BitvecCreate( p->iDivisor );
-      sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
+      sqlite3EndBenignMalloc();
       if( p->u.apSub[bin]==0 ) return SQLITE_NOMEM;
     }
     return sqlite3BitvecSet(p->u.apSub[bin], i);
@@ -23693,7 +25166,7 @@
 ** file simultaneously, or one process from reading the database while
 ** another is writing.
 **
-** @(#) $Id: pager.c,v 1.446 2008/05/13 13:27:34 drh Exp $
+** @(#) $Id: pager.c,v 1.465 2008/07/11 03:34:10 drh Exp $
 */
 #ifndef SQLITE_OMIT_DISKIO
 
@@ -23941,6 +25414,7 @@
   short int nRef;                /* Number of users of this page */
   PgHdr *pDirty, *pPrevDirty;    /* Dirty pages */
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+  PgHdr *pPrevAll;               /* A list of all pages */
   PagerLruLink gfree;            /* Global list of nRef==0 pages */
 #endif
 #ifdef SQLITE_CHECK_PAGES
@@ -24044,7 +25518,6 @@
   char *zFilename;            /* Name of the database file */
   char *zJournal;             /* Name of the journal file */
   char *zDirectory;           /* Directory hold database and journal files */
-  char *zStmtJrnl;            /* Name of the statement journal file */
   sqlite3_file *fd, *jfd;     /* File descriptors for database and journal */
   sqlite3_file *stfd;         /* File descriptor for the statement subjournal*/
   BusyHandler *pBusyHandler;  /* Pointer to sqlite.busyHandler */
@@ -24073,11 +25546,12 @@
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   Pager *pNext;               /* Doubly linked list of pagers on which */
   Pager *pPrev;               /* sqlite3_release_memory() will work */
-  int iInUseMM;               /* Non-zero if unavailable to MM */
-  int iInUseDB;               /* Non-zero if in sqlite3_release_memory() */
+  volatile int iInUseMM;      /* Non-zero if unavailable to MM */
+  volatile int iInUseDB;      /* Non-zero if in sqlite3_release_memory() */
 #endif
   char *pTmpSpace;            /* Pager.pageSize bytes of space for tmp use */
   char dbFileVers[16];        /* Changes whenever database file changes */
+  i64 journalSizeLimit;       /* Size limit for persistent journal files */
 };
 
 /*
@@ -24190,7 +25664,7 @@
     if( p->iInUseMM && p->iInUseDB==1 ){
 #ifndef SQLITE_MUTEX_NOOP
       sqlite3_mutex *mutex;
-      mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
+      mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
 #endif
       p->iInUseDB = 0;
       sqlite3_mutex_enter(mutex);
@@ -24288,9 +25762,9 @@
   listAdd(&pPg->pPager->lru, &pPg->free, pPg);
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   if( !pPg->pPager->memDb ){
-    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
     listAdd(&sqlite3LruPageList, &pPg->gfree, pPg);
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   }
 #endif
 }
@@ -24304,9 +25778,9 @@
   listRemove(&pPg->pPager->lru, &pPg->free, pPg);
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   if( !pPg->pPager->memDb ){
-    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
     listRemove(&sqlite3LruPageList, &pPg->gfree, pPg);
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   }
 #endif
 }
@@ -24323,11 +25797,11 @@
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   if( !pPager->memDb ){
     PgHdr *p;
-    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
     for(p=sqlite3LruPageList.pFirst; p && p->needSync; p=p->gfree.pNext);
     assert(p==pPager->lru.pFirstSynced || p==sqlite3LruPageList.pFirstSynced);
     sqlite3LruPageList.pFirstSynced = p;
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
   }
 #endif
 }
@@ -24360,9 +25834,9 @@
   if( N==pPager->nHash ) return;
 #endif
   pagerLeave(pPager);
-  if( pPager->aHash!=0 ) sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
+  if( pPager->aHash!=0 ) sqlite3BeginBenignMalloc();
   aHash = sqlite3MallocZero( sizeof(aHash[0])*N );
-  if( pPager->aHash!=0 ) sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
+  if( pPager->aHash!=0 ) sqlite3EndBenignMalloc();
   pagerEnter(pPager);
   if( aHash==0 ){
     /* Failure to rehash is not an error.  It is only a performance hit. */
@@ -24445,19 +25919,20 @@
 static int jrnlBufferSize(Pager *pPager){
   int dc;           /* Device characteristics */
   int nSector;      /* Sector size */
-  int nPage;        /* Page size */
+  int szPage;        /* Page size */
   sqlite3_file *fd = pPager->fd;
 
   if( fd->pMethods ){
     dc = sqlite3OsDeviceCharacteristics(fd);
     nSector = sqlite3OsSectorSize(fd);
-    nPage = pPager->pageSize;
+    szPage = pPager->pageSize;
   }
 
   assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
   assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
 
-  if( !fd->pMethods || (dc&(SQLITE_IOCAP_ATOMIC|(nPage>>8))&&nSector<=nPage) ){
+  if( !fd->pMethods || 
+       (dc & (SQLITE_IOCAP_ATOMIC|(szPage>>8)) && nSector<=szPage) ){
     return JOURNAL_HDR_SZ(pPager) + JOURNAL_PG_SZ(pPager);
   }
   return 0;
@@ -24646,15 +26121,31 @@
   static const char zeroHdr[28];
 
   if( pPager->journalOff ){
+    i64 iLimit = pPager->journalSizeLimit;
+
     IOTRACE(("JZEROHDR %p\n", pPager))
-    if( doTruncate ){
+    if( doTruncate || iLimit==0 ){
       rc = sqlite3OsTruncate(pPager->jfd, 0);
     }else{
       rc = sqlite3OsWrite(pPager->jfd, zeroHdr, sizeof(zeroHdr), 0);
     }
-    if( rc==SQLITE_OK ){
+    if( rc==SQLITE_OK && !pPager->noSync ){
       rc = sqlite3OsSync(pPager->jfd, SQLITE_SYNC_DATAONLY|pPager->sync_flags);
     }
+
+    /* 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.
+    */
+    if( rc==SQLITE_OK && iLimit>0 ){
+      i64 sz;
+      rc = sqlite3OsFileSize(pPager->jfd, &sz);
+      if( rc==SQLITE_OK && sz>iLimit ){
+        rc = sqlite3OsTruncate(pPager->jfd, iLimit);
+      }
+    }
   }
   return rc;
 }
@@ -24950,7 +26441,7 @@
     PAGER_INCR(sqlite3_pager_pgfree_count);
     pNext = pPg->pNextAll;
     lruListRemove(pPg);
-    sqlite3_free(pPg->pData);
+    sqlite3PageFree(pPg->pData);
     sqlite3_free(pPg);
   }
   assert(pPager->lru.pFirst==0);
@@ -25030,9 +26521,9 @@
 static void pagerUnlockAndRollback(Pager *p){
   /* assert( p->state>=PAGER_RESERVED || p->journalOpen==0 ); */
   if( p->errCode==SQLITE_OK && p->state>=PAGER_RESERVED ){
-    sqlite3FaultBeginBenign(-1);
+    sqlite3BeginBenignMalloc();
     sqlite3PagerRollback(p);
-    sqlite3FaultEndBenign(-1);
+    sqlite3EndBenignMalloc();
   }
   pager_unlock(p);
 #if 0
@@ -25082,7 +26573,7 @@
     }else{
       sqlite3OsClose(pPager->jfd);
       pPager->journalOpen = 0;
-      if( rc==SQLITE_OK ){
+      if( rc==SQLITE_OK && !pPager->tempFile ){
         rc = sqlite3OsDelete(pPager->pVfs, pPager->zJournal, 0);
       }
     }
@@ -25306,7 +26797,7 @@
   /* Open the master journal file exclusively in case some other process
   ** is running this routine also. Not that it makes too much difference.
   */
-  pMaster = (sqlite3_file *)sqlite3_malloc(pVfs->szOsFile * 2);
+  pMaster = (sqlite3_file *)sqlite3Malloc(pVfs->szOsFile * 2);
   pJournal = (sqlite3_file *)(((u8 *)pMaster) + pVfs->szOsFile);
   if( !pMaster ){
     rc = SQLITE_NOMEM;
@@ -25328,7 +26819,7 @@
     /* Load the entire master journal file into space obtained from
     ** sqlite3_malloc() and pointed to by zMasterJournal. 
     */
-    zMasterJournal = (char *)sqlite3_malloc(nMasterJournal + nMasterPtr);
+    zMasterJournal = (char *)sqlite3Malloc(nMasterJournal + nMasterPtr);
     if( !zMasterJournal ){
       rc = SQLITE_NOMEM;
       goto delmaster_out;
@@ -25339,12 +26830,12 @@
 
     zJournal = zMasterJournal;
     while( (zJournal-zMasterJournal)<nMasterJournal ){
-      rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS);
-      if( rc!=0 && rc!=1 ){
-        rc = SQLITE_IOERR_NOMEM;
+      int exists;
+      rc = sqlite3OsAccess(pVfs, zJournal, SQLITE_ACCESS_EXISTS, &exists);
+      if( rc!=SQLITE_OK ){
         goto delmaster_out;
       }
-      if( rc==1 ){
+      if( exists ){
         /* One of the journals pointed to by the master journal exists.
         ** Open it and check if it points at the master journal. If
         ** so, return without deleting the master journal file.
@@ -25502,10 +26993,10 @@
   sqlite3_vfs *pVfs = pPager->pVfs;
   i64 szJ;                 /* Size of the journal file in bytes */
   u32 nRec;                /* Number of Records in the journal */
-  int i;                   /* Loop counter */
+  u32 i;                   /* Loop counter */
   Pgno mxPg = 0;           /* Size of the original file in pages */
   int rc;                  /* Result code of a subroutine */
-  int res = 0;             /* Value returned by sqlite3OsAccess() */
+  int res = 1;             /* Value returned by sqlite3OsAccess() */
   char *zMaster = 0;       /* Name of master journal file if any */
 
   /* Figure out how many records are in the journal.  Abort early if
@@ -25524,15 +27015,11 @@
   */
   zMaster = pPager->pTmpSpace;
   rc = readMasterJournal(pPager->jfd, zMaster, pPager->pVfs->mxPathname+1);
-  if( rc!=SQLITE_OK || (zMaster[0] 
-   && (res=sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS))==0 ) 
-  ){
-    zMaster = 0;
-    goto end_playback;
+  if( rc==SQLITE_OK && zMaster[0] ){
+    rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
   }
   zMaster = 0;
-  if( res<0 ){
-    rc = SQLITE_IOERR_NOMEM;
+  if( rc!=SQLITE_OK || !res ){
     goto end_playback;
   }
   pPager->journalOff = 0;
@@ -25791,13 +27278,11 @@
 ** file when it is closed.
 */
 static int sqlite3PagerOpentemp(
-  sqlite3_vfs *pVfs,    /* The virtual file system layer */
+  Pager *pPager,        /* The pager object */
   sqlite3_file *pFile,  /* Write the file descriptor here */
-  char *zFilename,      /* Name of the file.  Might be NULL */
   int vfsFlags          /* Flags passed through to the VFS */
 ){
   int rc;
-  assert( zFilename!=0 );
 
 #ifdef SQLITE_TEST
   sqlite3_opentemp_count++;  /* Used for testing and analysis only */
@@ -25805,7 +27290,7 @@
 
   vfsFlags |=  SQLITE_OPEN_READWRITE | SQLITE_OPEN_CREATE |
             SQLITE_OPEN_EXCLUSIVE | SQLITE_OPEN_DELETEONCLOSE;
-  rc = sqlite3OsOpen(pVfs, zFilename, pFile, vfsFlags, 0);
+  rc = sqlite3OsOpen(pPager->pVfs, 0, pFile, vfsFlags, 0);
   assert( rc!=SQLITE_OK || pFile->pMethods );
   return rc;
 }
@@ -25842,22 +27327,23 @@
   int useJournal = (flags & PAGER_OMIT_JOURNAL)==0;
   int noReadlock = (flags & PAGER_NO_READLOCK)!=0;
   int journalFileSize = sqlite3JournalSize(pVfs);
-  int nDefaultPage = SQLITE_DEFAULT_PAGE_SIZE;
-  char *zPathname;
-  int nPathname;
-  char *zStmtJrnl;
-  int nStmtJrnl;
+  int szPageDflt = SQLITE_DEFAULT_PAGE_SIZE;
+  char *zPathname = 0;
+  int nPathname = 0;
 
   /* The default return is a NULL pointer */
   *ppPager = 0;
 
-  /* Compute the full pathname */
-  nPathname = pVfs->mxPathname+1;
-  zPathname = sqlite3_malloc(nPathname*2);
-  if( zPathname==0 ){
-    return SQLITE_NOMEM;
-  }
+  /* Compute and store the full pathname in an allocated buffer pointed
+  ** to by zPathname, length nPathname. Or, if this is a temporary file,
+  ** leave both nPathname and zPathname set to 0.
+  */
   if( zFilename && zFilename[0] ){
+    nPathname = pVfs->mxPathname+1;
+    zPathname = sqlite3Malloc(nPathname*2);
+    if( zPathname==0 ){
+      return SQLITE_NOMEM;
+    }
 #ifndef SQLITE_OMIT_MEMORYDB
     if( strcmp(zFilename,":memory:")==0 ){
       memDb = 1;
@@ -25867,35 +27353,19 @@
     {
       rc = sqlite3OsFullPathname(pVfs, zFilename, nPathname, zPathname);
     }
-  }else{
-    rc = sqlite3OsGetTempname(pVfs, nPathname, zPathname);
-  }
-  if( rc!=SQLITE_OK ){
-    sqlite3_free(zPathname);
-    return rc;
-  }
-  nPathname = strlen(zPathname);
-
-  /* Put the statement journal in temporary disk space since this is
-  ** sometimes RAM disk or other optimized storage.  Unlikely the main
-  ** main journal file, the statement journal does not need to be 
-  ** colocated with the database nor does it need to be persistent.
-  */
-  zStmtJrnl = &zPathname[nPathname+1];
-  rc = sqlite3OsGetTempname(pVfs, pVfs->mxPathname+1, zStmtJrnl);
-  if( rc!=SQLITE_OK ){
-    sqlite3_free(zPathname);
-    return rc;
+    if( rc!=SQLITE_OK ){
+      sqlite3_free(zPathname);
+      return rc;
+    }
+    nPathname = strlen(zPathname);
   }
-  nStmtJrnl = strlen(zStmtJrnl);
 
   /* Allocate memory for the pager structure */
   pPager = sqlite3MallocZero(
     sizeof(*pPager) +           /* Pager structure */
     journalFileSize +           /* The journal file structure */ 
     pVfs->szOsFile * 3 +        /* The main db and two journal files */ 
-    3*nPathname + 40 +          /* zFilename, zDirectory, zJournal */
-    nStmtJrnl                   /* zStmtJrnl */
+    3*nPathname + 40            /* zFilename, zDirectory, zJournal */
   );
   if( !pPager ){
     sqlite3_free(zPathname);
@@ -25909,11 +27379,11 @@
   pPager->zFilename = (char*)&pPtr[pVfs->szOsFile*2+journalFileSize];
   pPager->zDirectory = &pPager->zFilename[nPathname+1];
   pPager->zJournal = &pPager->zDirectory[nPathname+1];
-  pPager->zStmtJrnl = &pPager->zJournal[nPathname+10];
   pPager->pVfs = pVfs;
-  memcpy(pPager->zFilename, zPathname, nPathname+1);
-  memcpy(pPager->zStmtJrnl, zStmtJrnl, nStmtJrnl+1);
-  sqlite3_free(zPathname);
+  if( zPathname ){
+    memcpy(pPager->zFilename, zPathname, nPathname+1);
+    sqlite3_free(zPathname);
+  }
 
   /* Open the pager file.
   */
@@ -25936,8 +27406,8 @@
       */
       if( rc==SQLITE_OK && !readOnly ){
         int iSectorSize = sqlite3OsSectorSize(pPager->fd);
-        if( nDefaultPage<iSectorSize ){
-          nDefaultPage = iSectorSize;
+        if( szPageDflt<iSectorSize ){
+          szPageDflt = iSectorSize;
         }
 #ifdef SQLITE_ENABLE_ATOMIC_WRITE
         {
@@ -25946,13 +27416,13 @@
           assert(SQLITE_IOCAP_ATOMIC512==(512>>8));
           assert(SQLITE_IOCAP_ATOMIC64K==(65536>>8));
           assert(SQLITE_MAX_DEFAULT_PAGE_SIZE<=65536);
-          for(ii=nDefaultPage; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
-            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ) nDefaultPage = ii;
+          for(ii=szPageDflt; ii<=SQLITE_MAX_DEFAULT_PAGE_SIZE; ii=ii*2){
+            if( iDc&(SQLITE_IOCAP_ATOMIC|(ii>>8)) ) szPageDflt = ii;
           }
         }
 #endif
-        if( nDefaultPage>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
-          nDefaultPage = SQLITE_MAX_DEFAULT_PAGE_SIZE;
+        if( szPageDflt>SQLITE_MAX_DEFAULT_PAGE_SIZE ){
+          szPageDflt = SQLITE_MAX_DEFAULT_PAGE_SIZE;
         }
       }
     }
@@ -25966,7 +27436,7 @@
   }
 
   if( pPager && rc==SQLITE_OK ){
-    pPager->pTmpSpace = sqlite3MallocZero(nDefaultPage);
+    pPager->pTmpSpace = sqlite3PageMalloc(szPageDflt);
   }
 
   /* If an error occured in either of the blocks above.
@@ -25989,8 +27459,12 @@
   if( i>0 ) pPager->zDirectory[i-1] = 0;
 
   /* Fill in Pager.zJournal[] */
-  memcpy(pPager->zJournal, pPager->zFilename, nPathname);
-  memcpy(&pPager->zJournal[nPathname], "-journal", 9);
+  if( zPathname ){
+    memcpy(pPager->zJournal, pPager->zFilename, nPathname);
+    memcpy(&pPager->zJournal[nPathname], "-journal", 9);
+  }else{
+    pPager->zJournal = 0;
+  }
 
   /* pPager->journalOpen = 0; */
   pPager->useJournal = useJournal && !memDb;
@@ -25999,7 +27473,7 @@
   /* pPager->stmtInUse = 0; */
   /* pPager->nRef = 0; */
   pPager->dbSize = memDb-1;
-  pPager->pageSize = nDefaultPage;
+  pPager->pageSize = szPageDflt;
   /* pPager->stmtSize = 0; */
   /* pPager->stmtJSize = 0; */
   /* pPager->nPage = 0; */
@@ -26023,6 +27497,7 @@
   /* pPager->pFirstSynced = 0; */
   /* pPager->pLast = 0; */
   pPager->nExtra = FORCE_ALIGNMENT(nExtra);
+  pPager->journalSizeLimit = SQLITE_DEFAULT_JOURNAL_SIZE_LIMIT;
   assert(pPager->fd->pMethods||memDb||tempFile);
   if( !memDb ){
     setSectorSize(pPager);
@@ -26035,7 +27510,7 @@
   pPager->iInUseDB = 0;
   if( !memDb ){
 #ifndef SQLITE_MUTEX_NOOP
-    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
+    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
 #endif
     sqlite3_mutex_enter(mutex);
     pPager->pNext = sqlite3PagerList;
@@ -26093,7 +27568,7 @@
   if( pageSize && pageSize!=pPager->pageSize 
    && !pPager->memDb && pPager->nRef==0 
   ){
-    char *pNew = (char *)sqlite3_malloc(pageSize);
+    char *pNew = (char *)sqlite3PageMalloc(pageSize);
     if( !pNew ){
       rc = SQLITE_NOMEM;
     }else{
@@ -26101,7 +27576,7 @@
       pager_reset(pPager);
       pPager->pageSize = pageSize;
       setSectorSize(pPager);
-      sqlite3_free(pPager->pTmpSpace);
+      sqlite3PageFree(pPager->pTmpSpace);
       pPager->pTmpSpace = pNew;
       pagerLeave(pPager);
     }
@@ -26133,7 +27608,7 @@
   if( mxPage>0 ){
     pPager->mxPgno = mxPage;
   }
-  sqlite3PagerPagecount(pPager);
+  sqlite3PagerPagecount(pPager, 0);
   return pPager->mxPgno;
 }
 
@@ -26194,12 +27669,12 @@
 ** PENDING_BYTE is byte 4096 (the first byte of page 5) and the size of the
 ** file is 4096 bytes, 5 is returned instead of 4.
 */
-SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager){
+SQLITE_PRIVATE int sqlite3PagerPagecount(Pager *pPager, int *pnPage){
   i64 n = 0;
   int rc;
   assert( pPager!=0 );
   if( pPager->errCode ){
-    return -1;
+    return pPager->errCode;
   }
   if( pPager->dbSize>=0 ){
     n = pPager->dbSize;
@@ -26210,7 +27685,7 @@
       pPager->nRef++;
       pager_error(pPager, rc);
       pPager->nRef--;
-      return -1;
+      return rc;
     }
     if( n>0 && n<pPager->pageSize ){
       n = 1;
@@ -26227,7 +27702,10 @@
   if( n>pPager->mxPgno ){
     pPager->mxPgno = n;
   }
-  return n;
+  if( pnPage ){
+    *pnPage = n;
+  }
+  return SQLITE_OK;
 }
 
 
@@ -26236,8 +27714,8 @@
 ** Clear a PgHistory block
 */
 static void clearHistory(PgHistory *pHist){
-  sqlite3_free(pHist->pOrig);
-  sqlite3_free(pHist->pStmt);
+  sqlite3PageFree(pHist->pOrig);
+  sqlite3PageFree(pHist->pStmt);
   pHist->pOrig = 0;
   pHist->pStmt = 0;
 }
@@ -26318,11 +27796,16 @@
       ppPg = &pPg->pNextAll;
     }else{
       *ppPg = pPg->pNextAll;
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+      if( *ppPg ){
+        (*ppPg)->pPrevAll = pPg->pPrevAll;
+      }
+#endif
       IOTRACE(("PGFREE %p %d\n", pPager, pPg->pgno));
       PAGER_INCR(sqlite3_pager_pgfree_count);
       unlinkPage(pPg);
       makeClean(pPg);
-      sqlite3_free(pPg->pData);
+      sqlite3PageFree(pPg->pData);
       sqlite3_free(pPg);
       pPager->nPage--;
     }
@@ -26369,7 +27852,7 @@
 SQLITE_PRIVATE int sqlite3PagerTruncate(Pager *pPager, Pgno nPage){
   int rc;
   assert( pPager->state>=PAGER_SHARED || MEMDB );
-  sqlite3PagerPagecount(pPager);
+  sqlite3PagerPagecount(pPager, 0);
   if( pPager->errCode ){
     rc = pPager->errCode;
     return rc;
@@ -26419,7 +27902,7 @@
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
   if( !MEMDB ){
 #ifndef SQLITE_MUTEX_NOOP
-    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
+    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
 #endif
     sqlite3_mutex_enter(mutex);
     if( pPager->pPrev ){
@@ -26435,13 +27918,13 @@
 #endif
 
   disable_simulated_io_errors();
-  sqlite3FaultBeginBenign(-1);
+  sqlite3BeginBenignMalloc();
   pPager->errCode = 0;
   pPager->exclusiveMode = 0;
   pager_reset(pPager);
   pagerUnlockAndRollback(pPager);
   enable_simulated_io_errors();
-  sqlite3FaultEndBenign(-1);
+  sqlite3EndBenignMalloc();
   PAGERTRACE2("CLOSE %d\n", PAGERID(pPager));
   IOTRACE(("CLOSE %p\n", pPager))
   if( pPager->journalOpen ){
@@ -26459,7 +27942,7 @@
   */
 
   sqlite3_free(pPager->aHash);
-  sqlite3_free(pPager->pTmpSpace);
+  sqlite3PageFree(pPager->pTmpSpace);
   sqlite3_free(pPager);
   return SQLITE_OK;
 }
@@ -26542,7 +28025,6 @@
   PgHdr *pPg;
   int rc = SQLITE_OK;
 
-
   /* Sync the journal before modifying the main database
   ** (assuming there is a journal and it needs to be synced.)
   */
@@ -26730,8 +28212,7 @@
     /* If the file has not yet been opened, open it now. */
     if( !pPager->fd->pMethods ){
       assert(pPager->tempFile);
-      rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->fd, pPager->zFilename,
-                                pPager->vfsFlags);
+      rc = sqlite3PagerOpentemp(pPager, pPager->fd, pPager->vfsFlags);
       if( rc ) return rc;
     }
 
@@ -26810,22 +28291,30 @@
 */
 static int hasHotJournal(Pager *pPager){
   sqlite3_vfs *pVfs = pPager->pVfs;
-  int rc;
-  if( !pPager->useJournal ) return 0;
-  if( !pPager->fd->pMethods ) return 0;
-  rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS);
-  if( rc<=0 ){
-    return rc;
-  }
-  if( sqlite3OsCheckReservedLock(pPager->fd) ){
-    return 0;
-  }
-  if( sqlite3PagerPagecount(pPager)==0 ){
-    sqlite3OsDelete(pVfs, pPager->zJournal, 0);
-    return 0;
-  }else{
-    return 1;
+  int res = 0;
+  if( pPager->useJournal && pPager->fd->pMethods ){
+    int rc;
+    int exists;
+    int locked;
+
+    rc = sqlite3OsAccess(pVfs, pPager->zJournal, SQLITE_ACCESS_EXISTS, &exists);
+    if( rc==SQLITE_OK && exists ){
+      rc = sqlite3OsCheckReservedLock(pPager->fd, &locked);
+    }
+
+    if( rc==SQLITE_OK && exists && !locked ){
+      int nPage;
+      rc = sqlite3PagerPagecount(pPager, &nPage);
+      if( rc==SQLITE_OK && nPage==0 ){
+        sqlite3OsDelete(pVfs, pPager->zJournal, 0);
+        exists = 0;
+      }
+    }
+
+    res = (rc!=SQLITE_OK ? -1 : (exists && !locked));
   }
+
+  return res;
 }
 
 /*
@@ -26854,26 +28343,28 @@
   ** very slow operation, so we work hard to avoid it.  But sometimes
   ** it can't be helped.
   */
-  if( pPg==0 && pPager->lru.pFirst){
-    int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
-    int rc = syncJournal(pPager);
-    if( rc!=0 ){
-      return rc;
-    }
-    if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
-      /* If in full-sync mode, write a new journal header into the
-      ** journal file. This is done to avoid ever modifying a journal
-      ** header that is involved in the rollback of pages that have
-      ** already been written to the database (in case the header is
-      ** trashed when the nRec field is updated).
-      */
-      pPager->nRec = 0;
-      assert( pPager->journalOff > 0 );
-      assert( pPager->doNotSync==0 );
-      rc = writeJournalHdr(pPager);
+  if( pPg==0 && pPager->lru.pFirst ){
+    if( !pPager->errCode ){
+      int iDc = sqlite3OsDeviceCharacteristics(pPager->fd);
+      int rc = syncJournal(pPager);
       if( rc!=0 ){
         return rc;
       }
+      if( pPager->fullSync && 0==(iDc&SQLITE_IOCAP_SAFE_APPEND) ){
+        /* If in full-sync mode, write a new journal header into the
+        ** journal file. This is done to avoid ever modifying a journal
+        ** header that is involved in the rollback of pages that have
+        ** already been written to the database (in case the header is
+        ** trashed when the nRec field is updated).
+        */
+        pPager->nRec = 0;
+        assert( pPager->journalOff > 0 );
+        assert( pPager->doNotSync==0 );
+        rc = writeJournalHdr(pPager);
+        if( rc!=0 ){
+          return rc;
+        }
+      }
     }
     pPg = pPager->lru.pFirst;
   }
@@ -26882,7 +28373,7 @@
 
   /* Write the page to the database file if it is dirty.
   */
-  if( pPg->dirty ){
+  if( pPg->dirty && !pPager->errCode ){
     int rc;
     assert( pPg->needSync==0 );
     makeClean(pPg);
@@ -26894,7 +28385,7 @@
       return rc;
     }
   }
-  assert( pPg->dirty==0 );
+  assert( pPg->dirty==0 || pPager->errCode );
 
   /* If the page we are recycling is marked as alwaysRollback, then
   ** set the global alwaysRollback flag, thus disabling the
@@ -26938,7 +28429,7 @@
   */
 #ifndef SQLITE_MUTEX_NOOP
   sqlite3_mutex *mutex;       /* The MEM2 mutex */
-  mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MEM2);
+  mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MEM2);
 #endif
   sqlite3_mutex_enter(mutex);
 
@@ -26956,7 +28447,7 @@
     /* Try to find a page to recycle that does not require a sync(). If
     ** this is not possible, find one that does require a sync().
     */
-    sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
     pPg = sqlite3LruPageList.pFirstSynced;
     while( pPg && (pPg->needSync || pPg->pPager->iInUseDB) ){
       pPg = pPg->gfree.pNext;
@@ -26967,7 +28458,7 @@
         pPg = pPg->gfree.pNext;
       }
     }
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU));
+    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU));
 
     /* If pPg==0, then the block above has failed to find a page to
     ** recycle. In this case return early - no further memory will
@@ -26996,10 +28487,20 @@
       PgHdr *pTmp;
       assert( pPg );
       if( pPg==pPager->pAll ){
+         assert(pPg->pPrevAll==0);
+         assert(pPg->pNextAll==0 || pPg->pNextAll->pPrevAll==pPg);
          pPager->pAll = pPg->pNextAll;
+         if( pPager->pAll ){
+           pPager->pAll->pPrevAll = 0;
+         }
       }else{
-        for( pTmp=pPager->pAll; pTmp->pNextAll!=pPg; pTmp=pTmp->pNextAll ){}
-        pTmp->pNextAll = pPg->pNextAll;
+         assert(pPg->pPrevAll);
+         assert(pPg->pPrevAll->pNextAll==pPg);
+         pTmp = pPg->pPrevAll;
+         pTmp->pNextAll = pPg->pNextAll;
+         if( pTmp->pNextAll ){
+           pTmp->pNextAll->pPrevAll = pTmp;
+         }
       }
       nReleased += (
           sizeof(*pPg) + pPager->pageSize
@@ -27008,7 +28509,7 @@
       );
       IOTRACE(("PGFREE %p %d *\n", pPager, pPg->pgno));
       PAGER_INCR(sqlite3_pager_pgfree_count);
-      sqlite3_free(pPg->pData);
+      sqlite3PageFree(pPg->pData);
       sqlite3_free(pPg);
       pPager->nPage--;
     }else{
@@ -27151,25 +28652,24 @@
         ** a read/write file handle.
         */
         if( !isHot && pPager->journalOpen==0 ){
-          int res = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS);
-          if( res==1 ){
-            int fout = 0;
-            int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
-            assert( !pPager->tempFile );
-            rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
-            assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
-            if( fout&SQLITE_OPEN_READONLY ){
+          int res;
+          rc = sqlite3OsAccess(pVfs,pPager->zJournal,SQLITE_ACCESS_EXISTS,&res);
+          if( rc==SQLITE_OK ){
+            if( res ){
+              int fout = 0;
+              int f = SQLITE_OPEN_READWRITE|SQLITE_OPEN_MAIN_JOURNAL;
+              assert( !pPager->tempFile );
+              rc = sqlite3OsOpen(pVfs, pPager->zJournal, pPager->jfd, f, &fout);
+              assert( rc!=SQLITE_OK || pPager->jfd->pMethods );
+              if( fout&SQLITE_OPEN_READONLY ){
+                rc = SQLITE_BUSY;
+                sqlite3OsClose(pPager->jfd);
+              }
+            }else{
+              /* If the journal does not exist, that means some other process
+              ** has already rolled it back */
               rc = SQLITE_BUSY;
-              sqlite3OsClose(pPager->jfd);
             }
-          }else if( res==0 ){
-            /* If the journal does not exist, that means some other process
-            ** has already rolled it back */
-            rc = SQLITE_BUSY;
-          }else{
-            /* If sqlite3OsAccess() returns a negative value, that means it
-            ** failed a memory allocation */
-            rc = SQLITE_IOERR_NOMEM;
           }
         }
         if( rc!=SQLITE_OK ){
@@ -27217,7 +28717,7 @@
         ** it can be neglected.
         */
         char dbFileVers[sizeof(pPager->dbFileVers)];
-        sqlite3PagerPagecount(pPager);
+        sqlite3PagerPagecount(pPager, 0);
 
         if( pPager->errCode ){
           rc = pPager->errCode;
@@ -27309,9 +28809,9 @@
     pagerLeave(pPager);
     nByteHdr = sizeof(*pPg) + sizeof(u32) + pPager->nExtra
               + MEMDB*sizeof(PgHistory);
-    pPg = sqlite3_malloc( nByteHdr );
+    pPg = sqlite3Malloc( nByteHdr );
     if( pPg ){
-      pData = sqlite3_malloc( pPager->pageSize );
+      pData = sqlite3PageMalloc( pPager->pageSize );
       if( pData==0 ){
         sqlite3_free(pPg);
         pPg = 0;
@@ -27326,6 +28826,11 @@
     pPg->pData = pData;
     pPg->pPager = pPager;
     pPg->pNextAll = pPager->pAll;
+#ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
+    if( pPg->pNextAll ){
+      pPg->pNextAll->pPrevAll = pPg;
+    }
+#endif
     pPager->pAll = pPg;
     pPager->nPage++;
   }else{
@@ -27453,9 +28958,8 @@
     if( pPager->nExtra>0 ){
       memset(PGHDR_TO_EXTRA(pPg, pPager), 0, pPager->nExtra);
     }
-    nMax = sqlite3PagerPagecount(pPager);
-    if( pPager->errCode ){
-      rc = pPager->errCode;
+    rc = sqlite3PagerPagecount(pPager, &nMax);
+    if( rc!=SQLITE_OK ){
       sqlite3PagerUnref(pPg);
       return rc;
     }
@@ -27613,7 +29117,7 @@
   assert( pPager->state>=PAGER_RESERVED );
   assert( pPager->useJournal );
   assert( pPager->pInJournal==0 );
-  sqlite3PagerPagecount(pPager);
+  sqlite3PagerPagecount(pPager, 0);
   pagerLeave(pPager);
   pPager->pInJournal = sqlite3BitvecCreate(pPager->dbSize);
   pagerEnter(pPager);
@@ -27743,7 +29247,7 @@
     assert( pPager->nRec==0 );
     assert( pPager->origDbSize==0 );
     assert( pPager->pInJournal==0 );
-    sqlite3PagerPagecount(pPager);
+    sqlite3PagerPagecount(pPager, 0);
     pagerLeave(pPager);
     pPager->pInJournal = sqlite3BitvecCreate( pPager->dbSize );
     pagerEnter(pPager);
@@ -27886,7 +29390,7 @@
           PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
           PAGERTRACE3("JOURNAL %d page %d\n", PAGERID(pPager), pPg->pgno);
           assert( pHist->pOrig==0 );
-          pHist->pOrig = sqlite3_malloc( pPager->pageSize );
+          pHist->pOrig = sqlite3PageMalloc( pPager->pageSize );
           if( !pHist->pOrig ){
             return SQLITE_NOMEM;
           }
@@ -27956,7 +29460,7 @@
       if( MEMDB ){
         PgHistory *pHist = PGHDR_TO_HIST(pPg, pPager);
         assert( pHist->pStmt==0 );
-        pHist->pStmt = sqlite3_malloc( pPager->pageSize );
+        pHist->pStmt = sqlite3PageMalloc( pPager->pageSize );
         if( pHist->pStmt ){
           memcpy(pHist->pStmt, PGHDR_TO_DATA(pPg), pPager->pageSize);
         }
@@ -28029,7 +29533,7 @@
     */
     pg1 = ((pPg->pgno-1) & ~(nPagePerSector-1)) + 1;
 
-    nPageCount = sqlite3PagerPagecount(pPager);
+    sqlite3PagerPagecount(pPager, (int *)&nPageCount);
     if( pPg->pgno>nPageCount ){
       nPage = (pPg->pgno - pg1)+1;
     }else if( (pg1+nPagePerSector-1)>nPageCount ){
@@ -28188,8 +29692,12 @@
   ** has not been previously called during the same transaction.
   ** And if DontWrite() has previously been called, the following
   ** conditions must be met.
+  **
+  ** (Later:)  Not true.  If the database is corrupted by having duplicate
+  ** pages on the freelist (ex: corrupt9.test) then the following is not
+  ** necessarily true:
   */
-  assert( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize );
+  /* assert( !pPg->inJournal && (int)pPg->pgno <= pPager->origDbSize ); */
 
   assert( pPager->pInJournal!=0 );
   sqlite3BitvecSet(pPager->pInJournal, pPg->pgno);
@@ -28285,6 +29793,10 @@
 ){
   int rc = SQLITE_OK;
 
+  if( pPager->errCode ){
+    return pPager->errCode;
+  }
+
   /* If no changes have been made, we can leave the transaction early.
   */
   if( pPager->dbModified==0 &&
@@ -28355,28 +29867,30 @@
     if( !pPager->setMaster ){
       rc = pager_incr_changecounter(pPager, 0);
       if( rc!=SQLITE_OK ) goto sync_exit;
+      if( pPager->journalMode!=PAGER_JOURNALMODE_OFF ){
 #ifndef SQLITE_OMIT_AUTOVACUUM
-      if( nTrunc!=0 ){
-        /* If this transaction has made the database smaller, then all pages
-        ** being discarded by the truncation must be written to the journal
-        ** file.
-        */
-        Pgno i;
-        int iSkip = PAGER_MJ_PGNO(pPager);
-        for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
-          if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
-            rc = sqlite3PagerGet(pPager, i, &pPg);
-            if( rc!=SQLITE_OK ) goto sync_exit;
-            rc = sqlite3PagerWrite(pPg);
-            sqlite3PagerUnref(pPg);
-            if( rc!=SQLITE_OK ) goto sync_exit;
-          }
-        } 
-      }
+        if( nTrunc!=0 ){
+          /* If this transaction has made the database smaller, then all pages
+          ** being discarded by the truncation must be written to the journal
+          ** file.
+          */
+          Pgno i;
+          int iSkip = PAGER_MJ_PGNO(pPager);
+          for( i=nTrunc+1; i<=pPager->origDbSize; i++ ){
+            if( !sqlite3BitvecTest(pPager->pInJournal, i) && i!=iSkip ){
+              rc = sqlite3PagerGet(pPager, i, &pPg);
+              if( rc!=SQLITE_OK ) goto sync_exit;
+              rc = sqlite3PagerWrite(pPg);
+              sqlite3PagerUnref(pPg);
+              if( rc!=SQLITE_OK ) goto sync_exit;
+            }
+          } 
+        }
 #endif
-      rc = writeMasterJournal(pPager, zMaster);
-      if( rc!=SQLITE_OK ) goto sync_exit;
-      rc = syncJournal(pPager);
+        rc = writeMasterJournal(pPager, zMaster);
+        if( rc!=SQLITE_OK ) goto sync_exit;
+        rc = syncJournal(pPager);
+      }
     }
     if( rc!=SQLITE_OK ) goto sync_exit;
 
@@ -28607,6 +30121,9 @@
   a[10] = pPager->nWrite;
   return a;
 }
+SQLITE_PRIVATE int sqlite3PagerIsMemdb(Pager *pPager){
+  return MEMDB;
+}
 #endif
 
 /*
@@ -28645,8 +30162,7 @@
   pPager->stmtHdrOff = 0;
   pPager->stmtCksum = pPager->cksumInit;
   if( !pPager->stmtOpen ){
-    rc = sqlite3PagerOpentemp(pPager->pVfs, pPager->stfd, pPager->zStmtJrnl,
-                              SQLITE_OPEN_SUBJOURNAL);
+    rc = sqlite3PagerOpentemp(pPager, pPager->stfd, SQLITE_OPEN_SUBJOURNAL);
     if( rc ){
       goto stmt_begin_failed;
     }
@@ -28690,7 +30206,7 @@
         assert( pHist->inStmt );
         pHist->inStmt = 0;
         pHist->pPrevStmt = pHist->pNextStmt = 0;
-        sqlite3_free(pHist->pStmt);
+        sqlite3PageFree(pHist->pStmt);
         pHist->pStmt = 0;
       }
     }
@@ -28718,7 +30234,7 @@
         pHist = PGHDR_TO_HIST(pPg, pPager);
         if( pHist->pStmt ){
           memcpy(PGHDR_TO_DATA(pPg), pHist->pStmt, pPager->pageSize);
-          sqlite3_free(pHist->pStmt);
+          sqlite3PageFree(pHist->pStmt);
           pHist->pStmt = 0;
         }
       }
@@ -28971,19 +30487,15 @@
   return (int)pPager->journalMode;
 }
 
-#ifdef SQLITE_TEST
 /*
-** Print a listing of all referenced pages and their ref count.
+** Get/set the size-limit used for persistent journal files.
 */
-SQLITE_PRIVATE void sqlite3PagerRefdump(Pager *pPager){
-  PgHdr *pPg;
-  for(pPg=pPager->pAll; pPg; pPg=pPg->pNextAll){
-    if( pPg->nRef<=0 ) continue;
-    sqlite3DebugPrintf("PAGE %3d addr=%p nRef=%d\n", 
-       pPg->pgno, PGHDR_TO_DATA(pPg), pPg->nRef);
+SQLITE_PRIVATE i64 sqlite3PagerJournalSizeLimit(Pager *pPager, i64 iLimit){
+  if( iLimit>=-1 ){
+    pPager->journalSizeLimit = iLimit;
   }
+  return pPager->journalSizeLimit;
 }
-#endif
 
 #endif /* SQLITE_OMIT_DISKIO */
 
@@ -29001,7 +30513,7 @@
 **
 *************************************************************************
 **
-** $Id: btmutex.c,v 1.9 2008/01/23 12:52:41 drh Exp $
+** $Id: btmutex.c,v 1.10 2008/07/14 19:39:17 drh Exp $
 **
 ** This file contains code used to implement mutexes on Btree objects.
 ** This code really belongs in btree.c.  But btree.c is getting too
@@ -29021,7 +30533,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btreeInt.h,v 1.21 2008/04/24 19:15:10 shane Exp $
+** $Id: btreeInt.h,v 1.26 2008/07/12 14:52:20 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** For a detailed discussion of BTrees, refer to
@@ -29378,9 +30890,6 @@
   MemPage *pPage1;      /* First page of the database */
   u8 inStmt;            /* True if we are in a statement subtransaction */
   u8 readOnly;          /* True if the underlying file is readonly */
-  u8 maxEmbedFrac;      /* Maximum payload as % of total page size */
-  u8 minEmbedFrac;      /* Minimum payload as % of total page size */
-  u8 minLeafFrac;       /* Minimum leaf payload as % of total page size */
   u8 pageSizeFixed;     /* True if the page size can no longer be changed */
 #ifndef SQLITE_OMIT_AUTOVACUUM
   u8 autoVacuum;        /* True if auto-vacuum is enabled */
@@ -29476,7 +30985,7 @@
 **   The table that this cursor was opened on still exists, but has been 
 **   modified since the cursor was last used. The cursor position is saved
 **   in variables BtCursor.pKey and BtCursor.nKey. When a cursor is in 
-**   this state, restoreOrClearCursorPosition() can be called to attempt to
+**   this state, restoreCursorPosition() can be called to attempt to
 **   seek the cursor to the saved position.
 **
 ** CURSOR_FAULT:
@@ -29491,17 +31000,6 @@
 #define CURSOR_REQUIRESEEK       2
 #define CURSOR_FAULT             3
 
-/*
-** The TRACE macro will print high-level status information about the
-** btree operation when the global variable sqlite3BtreeTrace is
-** enabled.
-*/
-#if SQLITE_TEST
-# define TRACE(X)   if( sqlite3BtreeTrace ){ printf X; fflush(stdout); }
-#else
-# define TRACE(X)
-#endif
-
 /* The database page the PENDING_BYTE occupies. This page is never used.
 ** TODO: This macro is very similary to PAGER_MJ_PGNO() in pager.c. They
 ** should possibly be consolidated (presumably in pager.h).
@@ -29622,8 +31120,8 @@
   int nPage;        /* Number of pages in the database */
   int *anRef;       /* Number of times each page is referenced */
   int mxErr;        /* Stop accumulating errors when this reaches zero */
-  char *zErrMsg;    /* An error message.  NULL if no errors seen. */
   int nErr;         /* Number of messages written to zErrMsg so far */
+  StrAccum errMsg;  /* Accumulate the error message text here */
 };
 
 /*
@@ -29641,10 +31139,7 @@
 SQLITE_PRIVATE int sqlite3BtreeInitPage(MemPage *pPage, MemPage *pParent);
 SQLITE_PRIVATE void sqlite3BtreeParseCellPtr(MemPage*, u8*, CellInfo*);
 SQLITE_PRIVATE void sqlite3BtreeParseCell(MemPage*, int, CellInfo*);
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell);
-#endif
-SQLITE_PRIVATE int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur);
+SQLITE_PRIVATE int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur);
 SQLITE_PRIVATE void sqlite3BtreeGetTempCursor(BtCursor *pCur, BtCursor *pTempCur);
 SQLITE_PRIVATE void sqlite3BtreeReleaseTempCursor(BtCursor *pCur);
 SQLITE_PRIVATE int sqlite3BtreeIsRootPage(MemPage *pPage);
@@ -29860,11 +31355,11 @@
 #endif /* NDEBUG */
 
 /*
-** Potentially dd a new Btree pointer to a BtreeMutexArray.
-** Really only add the Btree if it can possibly be shared with
+** Add a new Btree pointer to a BtreeMutexArray. 
+** if the pointer can possibly be shared with
 ** another database connection.
 **
-** The Btrees are kept in sorted order by pBtree->pBt.  That
+** The pointers are kept in sorted order by pBtree->pBt.  That
 ** way when we go to enter all the mutexes, we can enter them
 ** in order without every having to backup and retry and without
 ** worrying about deadlock.
@@ -29963,7 +31458,7 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-** $Id: btree.c,v 1.458 2008/05/09 16:57:51 danielk1977 Exp $
+** $Id: btree.c,v 1.482 2008/07/12 14:52:20 drh Exp $
 **
 ** This file implements a external (disk-based) database using BTrees.
 ** See the header comment on "btreeInt.h" for additional information.
@@ -29980,8 +31475,11 @@
 ** Set this global variable to 1 to enable tracing using the TRACE
 ** macro.
 */
-#if SQLITE_TEST
+#if 0
 int sqlite3BtreeTrace=0;  /* True to enable tracing */
+# define TRACE(X)  if(sqlite3BtreeTrace){printf X;fflush(stdout);}
+#else
+# define TRACE(X)
 #endif
 
 
@@ -30021,7 +31519,7 @@
 /*
 ** Forward declaration
 */
-static int checkReadLocks(Btree*,Pgno,BtCursor*);
+static int checkReadLocks(Btree*, Pgno, BtCursor*, i64);
 
 
 #ifdef SQLITE_OMIT_SHARED_CACHE
@@ -30050,6 +31548,8 @@
   BtLock *pIter;
 
   assert( sqlite3BtreeHoldsMutex(p) );
+  assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
+  assert( p->db!=0 );
   
   /* This is a no-op if the shared-cache is not enabled */
   if( !p->sharable ){
@@ -30078,7 +31578,6 @@
   ** write-cursor does not change.
   */
   if( 
-    !p->db || 
     0==(p->db->flags&SQLITE_ReadUncommitted) || 
     eLock==WRITE_LOCK ||
     iTab==MASTER_ROOT
@@ -30109,6 +31608,8 @@
   BtLock *pIter;
 
   assert( sqlite3BtreeHoldsMutex(p) );
+  assert( eLock==READ_LOCK || eLock==WRITE_LOCK );
+  assert( p->db!=0 );
 
   /* This is a no-op if the shared-cache is not enabled */
   if( !p->sharable ){
@@ -30123,7 +31624,6 @@
   ** the ReadUncommitted flag.
   */
   if( 
-    (p->db) && 
     (p->db->flags&SQLITE_ReadUncommitted) && 
     (eLock==READ_LOCK) &&
     iTable!=MASTER_ROOT
@@ -30253,7 +31753,7 @@
   ** data.
   */
   if( rc==SQLITE_OK && 0==pCur->pPage->intKey){
-    void *pKey = sqlite3_malloc(pCur->nKey);
+    void *pKey = sqlite3Malloc(pCur->nKey);
     if( pKey ){
       rc = sqlite3BtreeKey(pCur, 0, pCur->nKey, pKey);
       if( rc==SQLITE_OK ){
@@ -30312,25 +31812,16 @@
 ** 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 
 ** saved position info stored by saveCursorPosition(), so there can be
-** at most one effective restoreOrClearCursorPosition() call after each 
+** at most one effective restoreCursorPosition() call after each 
 ** saveCursorPosition().
-**
-** If the second argument argument - doSeek - is false, then instead of 
-** returning the cursor to its saved position, any saved position is deleted
-** and the cursor state set to CURSOR_INVALID.
 */
-SQLITE_PRIVATE int sqlite3BtreeRestoreOrClearCursorPosition(BtCursor *pCur){
+SQLITE_PRIVATE int sqlite3BtreeRestoreCursorPosition(BtCursor *pCur){
   int rc;
   assert( cursorHoldsMutex(pCur) );
   assert( pCur->eState>=CURSOR_REQUIRESEEK );
   if( pCur->eState==CURSOR_FAULT ){
     return pCur->skip;
   }
-#ifndef SQLITE_OMIT_INCRBLOB
-  if( pCur->isIncrblobHandle ){
-    return SQLITE_ABORT;
-  }
-#endif
   pCur->eState = CURSOR_INVALID;
   rc = sqlite3BtreeMoveto(pCur, pCur->pKey, 0, pCur->nKey, 0, &pCur->skip);
   if( rc==SQLITE_OK ){
@@ -30341,11 +31832,35 @@
   return rc;
 }
 
-#define restoreOrClearCursorPosition(p) \
+#define restoreCursorPosition(p) \
   (p->eState>=CURSOR_REQUIRESEEK ? \
-         sqlite3BtreeRestoreOrClearCursorPosition(p) : \
+         sqlite3BtreeRestoreCursorPosition(p) : \
          SQLITE_OK)
 
+/*
+** Determine whether or not a cursor has moved from the position it
+** was last placed at.  Cursor can move when the row they are pointing
+** at is deleted out from under them.
+**
+** This routine returns an error code if something goes wrong.  The
+** integer *pHasMoved is set to one if the cursor has moved and 0 if not.
+*/
+SQLITE_PRIVATE int sqlite3BtreeCursorHasMoved(BtCursor *pCur, int *pHasMoved){
+  int rc;
+
+  rc = restoreCursorPosition(pCur);
+  if( rc ){
+    *pHasMoved = 1;
+    return rc;
+  }
+  if( pCur->eState!=CURSOR_VALID || pCur->skip!=0 ){
+    *pHasMoved = 1;
+  }else{
+    *pHasMoved = 0;
+  }
+  return SQLITE_OK;
+}
+
 #ifndef SQLITE_OMIT_AUTOVACUUM
 /*
 ** Given a page number of a regular database page, return the page
@@ -30451,16 +31966,9 @@
 */
 #define findCell(pPage, iCell) \
   ((pPage)->aData + get2byte(&(pPage)->aData[(pPage)->cellOffset+2*(iCell)]))
-#ifdef SQLITE_TEST
-SQLITE_PRIVATE u8 *sqlite3BtreeFindCell(MemPage *pPage, int iCell){
-  assert( iCell>=0 );
-  assert( iCell<get2byte(&pPage->aData[pPage->hdrOffset+3]) );
-  return findCell(pPage, iCell);
-}
-#endif
 
 /*
-** This a more complex version of sqlite3BtreeFindCell() that works for
+** This a more complex version of findCell() that works for
 ** pages that do contain overflow cells.  See insert
 */
 static u8 *findOverflowCell(MemPage *pPage, int iCell){
@@ -30594,14 +32102,13 @@
 ** for the overflow page.
 */
 static int ptrmapPutOvflPtr(MemPage *pPage, u8 *pCell){
-  if( pCell ){
-    CellInfo info;
-    sqlite3BtreeParseCellPtr(pPage, pCell, &info);
-    assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
-    if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
-      Pgno ovfl = get4byte(&pCell[info.iOverflow]);
-      return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
-    }
+  CellInfo info;
+  assert( pCell!=0 );
+  sqlite3BtreeParseCellPtr(pPage, pCell, &info);
+  assert( (info.nData+(pPage->intKey?0:info.nKey))==info.nPayload );
+  if( (info.nData+(pPage->intKey?0:info.nKey))>info.nLocal ){
+    Pgno ovfl = get4byte(&pCell[info.iOverflow]);
+    return ptrmapPut(pPage->pBt, ovfl, PTRMAP_OVERFLOW1, pPage->pgno);
   }
   return SQLITE_OK;
 }
@@ -30625,7 +32132,7 @@
 ** big FreeBlk that occurs in between the header and cell
 ** pointer array and the cell content area.
 */
-static int defragmentPage(MemPage *pPage){
+static void defragmentPage(MemPage *pPage){
   int i;                     /* Loop counter */
   int pc;                    /* Address of a i-th cell */
   int addr;                  /* Offset of first byte after cell pointer array */
@@ -30670,15 +32177,14 @@
   data[hdr+7] = 0;
   addr = cellOffset+2*nCell;
   memset(&data[addr], 0, brk-addr);
-  return SQLITE_OK;
 }
 
 /*
 ** Allocate nByte bytes of space on a page.
 **
 ** Return the index into pPage->aData[] of the first byte of
-** the new allocation. Or return 0 if there is not enough free
-** space on the page to satisfy the allocation request.
+** the new allocation.  The caller guarantees that there is enough
+** space.  This routine will never fail.
 **
 ** If the page contains nBytes of free space but does not contain
 ** nBytes of contiguous free space, then this routine automatically
@@ -30698,8 +32204,9 @@
   assert( sqlite3PagerIswriteable(pPage->pDbPage) );
   assert( pPage->pBt );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-  if( nByte<4 ) nByte = 4;
-  if( pPage->nFree<nByte || pPage->nOverflow>0 ) return 0;
+  assert( nByte>=0 );  /* Minimum cell size is 4 */
+  assert( pPage->nFree>=nByte );
+  assert( pPage->nOverflow==0 );
   pPage->nFree -= nByte;
   hdr = pPage->hdrOffset;
 
@@ -30731,7 +32238,7 @@
   nCell = get2byte(&data[hdr+3]);
   cellOffset = pPage->cellOffset;
   if( nFrag>=60 || cellOffset + 2*nCell > top - nByte ){
-    if( defragmentPage(pPage) ) return 0;
+    defragmentPage(pPage);
     top = get2byte(&data[hdr+5]);
   }
   top -= nByte;
@@ -30757,7 +32264,7 @@
   assert( start>=pPage->hdrOffset+6+(pPage->leaf?0:4) );
   assert( (start + size)<=pPage->pBt->usableSize );
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
-  if( size<4 ) size = 4;
+  assert( size>=0 );   /* Minimum cell size is 4 */
 
 #ifdef SQLITE_SECURE_DELETE
   /* Overwrite deleted information with zeros when the SECURE_DELETE 
@@ -30860,6 +32367,9 @@
   int cellOffset;    /* Offset from start of page to first cell pointer */
   int nFree;         /* Number of unused bytes on the page */
   int top;           /* First byte of the cell content area */
+  u8 *pOff;          /* Iterator used to check all cell offsets are in range */
+  u8 *pEnd;          /* Pointer to end of cell offset array */
+  u8 mask;           /* Mask of bits that must be zero in MSB of cell offsets */
 
   pBt = pPage->pBt;
   assert( pBt!=0 );
@@ -30919,6 +32429,14 @@
     return SQLITE_CORRUPT_BKPT; 
   }
 
+  /* Check that all the offsets in the cell offset array are within range. */
+  mask = ~(((u8)(pBt->pageSize>>8))-1);
+  pEnd = &data[cellOffset + pPage->nCell*2];
+  for(pOff=&data[cellOffset]; pOff!=pEnd && !((*pOff)&mask); pOff+=2);
+  if( pOff!=pEnd ){
+    return SQLITE_CORRUPT_BKPT;
+  }
+
   pPage->isInit = 1;
   return SQLITE_OK;
 }
@@ -31130,25 +32648,22 @@
   ** If this Btree is a candidate for shared cache, try to find an
   ** existing BtShared object that we can share with
   */
-  if( (flags & BTREE_PRIVATE)==0
-   && isMemdb==0
+  if( isMemdb==0
    && (db->flags & SQLITE_Vtab)==0
    && zFilename && zFilename[0]
   ){
     if( sqlite3SharedCacheEnabled ){
       int nFullPathname = pVfs->mxPathname+1;
-      char *zFullPathname = (char *)sqlite3_malloc(nFullPathname);
+      char *zFullPathname = sqlite3Malloc(nFullPathname);
       sqlite3_mutex *mutexShared;
       p->sharable = 1;
-      if( db ){
-        db->flags |= SQLITE_SharedCache;
-      }
+      db->flags |= SQLITE_SharedCache;
       if( !zFullPathname ){
         sqlite3_free(p);
         return SQLITE_NOMEM;
       }
       sqlite3OsFullPathname(pVfs, zFilename, nFullPathname, zFullPathname);
-      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
       sqlite3_mutex_enter(mutexShared);
       for(pBt=sqlite3SharedCacheList; pBt; pBt=pBt->pNext){
         assert( pBt->nRef>0 );
@@ -31214,9 +32729,6 @@
          || ((pBt->pageSize-1)&pBt->pageSize)!=0 ){
       pBt->pageSize = 0;
       sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
-      pBt->maxEmbedFrac = 64;   /* 25% */
-      pBt->minEmbedFrac = 32;   /* 12.5% */
-      pBt->minLeafFrac = 32;    /* 12.5% */
 #ifndef SQLITE_OMIT_AUTOVACUUM
       /* If the magic name ":memory:" will create an in-memory database, then
       ** leave the autoVacuum mode at 0 (do not auto-vacuum), even if
@@ -31232,9 +32744,6 @@
       nReserve = 0;
     }else{
       nReserve = zDbHeader[20];
-      pBt->maxEmbedFrac = zDbHeader[21];
-      pBt->minEmbedFrac = zDbHeader[22];
-      pBt->minLeafFrac = zDbHeader[23];
       pBt->pageSizeFixed = 1;
 #ifndef SQLITE_OMIT_AUTOVACUUM
       pBt->autoVacuum = (get4byte(&zDbHeader[36 + 4*4])?1:0);
@@ -31251,9 +32760,9 @@
     if( p->sharable ){
       sqlite3_mutex *mutexShared;
       pBt->nRef = 1;
-      mutexShared = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
-      if( SQLITE_THREADSAFE ){
-        pBt->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_FAST);
+      mutexShared = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+      if( SQLITE_THREADSAFE && sqlite3Config.bCoreMutex ){
+        pBt->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_FAST);
         if( pBt->mutex==0 ){
           rc = SQLITE_NOMEM;
           db->mallocFailed = 0;
@@ -31326,7 +32835,7 @@
   int removed = 0;
 
   assert( sqlite3_mutex_notheld(pBt->mutex) );
-  pMaster = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+  pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
   sqlite3_mutex_enter(pMaster);
   pBt->nRef--;
   if( pBt->nRef<=0 ){
@@ -31334,10 +32843,10 @@
       sqlite3SharedCacheList = pBt->pNext;
     }else{
       pList = sqlite3SharedCacheList;
-      while( pList && pList->pNext!=pBt ){
+      while( ALWAYS(pList) && pList->pNext!=pBt ){
         pList=pList->pNext;
       }
-      if( pList ){
+      if( ALWAYS(pList) ){
         pList->pNext = pBt->pNext;
       }
     }
@@ -31354,6 +32863,24 @@
 }
 
 /*
+** Make sure pBt->pTmpSpace points to an allocation of 
+** MX_CELL_SIZE(pBt) bytes.
+*/
+static void allocateTempSpace(BtShared *pBt){
+  if( !pBt->pTmpSpace ){
+    pBt->pTmpSpace = sqlite3PageMalloc( pBt->pageSize );
+  }
+}
+
+/*
+** Free the pBt->pTmpSpace allocation
+*/
+static void freeTempSpace(BtShared *pBt){
+  sqlite3PageFree( pBt->pTmpSpace);
+  pBt->pTmpSpace = 0;
+}
+
+/*
 ** Close an open database and invalidate all cursors.
 */
 SQLITE_PRIVATE int sqlite3BtreeClose(Btree *p){
@@ -31397,7 +32924,7 @@
       pBt->xFreeSchema(pBt->pSchema);
     }
     sqlite3_free(pBt->pSchema);
-    sqlite3_free(pBt->pTmpSpace);
+    freeTempSpace(pBt);
     sqlite3_free(pBt);
   }
 
@@ -31502,8 +33029,7 @@
     assert( (pageSize & 7)==0 );
     assert( !pBt->pPage1 && !pBt->pCursor );
     pBt->pageSize = pageSize;
-    sqlite3_free(pBt->pTmpSpace);
-    pBt->pTmpSpace = 0;
+    freeTempSpace(pBt);
     rc = sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
   }
   pBt->usableSize = pBt->pageSize - nReserve;
@@ -31607,15 +33133,14 @@
   /* Do some checking to help insure the file we opened really is
   ** a valid database file. 
   */
-  rc = SQLITE_NOTADB;
-  nPage = sqlite3PagerPagecount(pBt->pPager);
-  if( nPage<0 ){
-    rc = SQLITE_IOERR;
+  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
+  if( rc!=SQLITE_OK ){
     goto page1_init_failed;
   }else if( nPage>0 ){
     int pageSize;
     int usableSize;
     u8 *page1 = pPage1->aData;
+    rc = SQLITE_NOTADB;
     if( memcmp(page1, zMagicHeader, 16)!=0 ){
       goto page1_init_failed;
     }
@@ -31625,6 +33150,15 @@
     if( page1[19]>1 ){
       goto page1_init_failed;
     }
+
+    /* The maximum embedded fraction must be exactly 25%.  And the minimum
+    ** embedded fraction must be 12.5% for both leaf-data and non-leaf-data.
+    ** The original design allowed these amounts to vary, but as of
+    ** version 3.6.0, we require them to be fixed.
+    */
+    if( memcmp(&page1[21], "\100\040\040",3)!=0 ){
+      goto page1_init_failed;
+    }
     pageSize = get2byte(&page1[16]);
     if( ((pageSize-1)&pageSize)!=0 || pageSize<512 ||
         (SQLITE_MAX_PAGE_SIZE<32768 && pageSize>SQLITE_MAX_PAGE_SIZE)
@@ -31643,8 +33177,7 @@
       releasePage(pPage1);
       pBt->usableSize = usableSize;
       pBt->pageSize = pageSize;
-      sqlite3_free(pBt->pTmpSpace);
-      pBt->pTmpSpace = 0;
+      freeTempSpace(pBt);
       sqlite3PagerSetPagesize(pBt->pPager, &pBt->pageSize);
       return SQLITE_OK;
     }
@@ -31653,9 +33186,6 @@
     }
     pBt->pageSize = pageSize;
     pBt->usableSize = usableSize;
-    pBt->maxEmbedFrac = page1[21];
-    pBt->minEmbedFrac = page1[22];
-    pBt->minLeafFrac = page1[23];
 #ifndef SQLITE_OMIT_AUTOVACUUM
     pBt->autoVacuum = (get4byte(&page1[36 + 4*4])?1:0);
     pBt->incrVacuum = (get4byte(&page1[36 + 7*4])?1:0);
@@ -31675,13 +33205,10 @@
   ** 17 bytes long, 0 to N bytes of payload, and an optional 4 byte overflow
   ** page pointer.
   */
-  pBt->maxLocal = (pBt->usableSize-12)*pBt->maxEmbedFrac/255 - 23;
-  pBt->minLocal = (pBt->usableSize-12)*pBt->minEmbedFrac/255 - 23;
+  pBt->maxLocal = (pBt->usableSize-12)*64/255 - 23;
+  pBt->minLocal = (pBt->usableSize-12)*32/255 - 23;
   pBt->maxLeaf = pBt->usableSize - 35;
-  pBt->minLeaf = (pBt->usableSize-12)*pBt->minLeafFrac/255 - 23;
-  if( pBt->minLocal>pBt->maxLocal || pBt->maxLocal<0 ){
-    goto page1_init_failed;
-  }
+  pBt->minLeaf = (pBt->usableSize-12)*32/255 - 23;
   assert( pBt->maxLeaf + 23 <= MX_CELL_SIZE(pBt) );
   pBt->pPage1 = pPage1;
   return SQLITE_OK;
@@ -31753,9 +33280,13 @@
   MemPage *pP1;
   unsigned char *data;
   int rc;
+  int nPage;
 
   assert( sqlite3_mutex_held(pBt->mutex) );
-  if( sqlite3PagerPagecount(pBt->pPager)>0 ) return SQLITE_OK;
+  rc = sqlite3PagerPagecount(pBt->pPager, &nPage);
+  if( rc!=SQLITE_OK || nPage>0 ){
+    return rc;
+  }
   pP1 = pBt->pPage1;
   assert( pP1!=0 );
   data = pP1->aData;
@@ -31767,9 +33298,9 @@
   data[18] = 1;
   data[19] = 1;
   data[20] = pBt->pageSize - pBt->usableSize;
-  data[21] = pBt->maxEmbedFrac;
-  data[22] = pBt->minEmbedFrac;
-  data[23] = pBt->minLeafFrac;
+  data[21] = 64;
+  data[22] = 32;
+  data[23] = 32;
   memset(&data[24], 0, 100-24);
   zeroPage(pP1, PTF_INTKEY|PTF_LEAF|PTF_LEAFDATA );
   pBt->pageSizeFixed = 1;
@@ -31942,7 +33473,7 @@
     if( !pPage->leaf ){
       Pgno childPgno = get4byte(pCell);
       rc = ptrmapPut(pBt, childPgno, PTRMAP_BTREE, pgno);
-      if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
+       if( rc!=SQLITE_OK ) goto set_child_ptrmaps_out;
     }
   }
 
@@ -32096,6 +33627,13 @@
   return rc;
 }
 
+static int pagerPagecount(Pager *pPager){
+  int rc;
+  int nPage;
+  rc = sqlite3PagerPagecount(pPager, &nPage);
+  return (rc==SQLITE_OK?nPage:-1);
+}
+
 /* Forward declaration required by incrVacuumStep(). */
 static int allocateBtreePage(BtShared *, MemPage **, Pgno *, Pgno, u8);
 
@@ -32121,7 +33659,7 @@
   assert( sqlite3_mutex_held(pBt->mutex) );
   iLastPg = pBt->nTrunc;
   if( iLastPg==0 ){
-    iLastPg = sqlite3PagerPagecount(pBt->pPager);
+    iLastPg = pagerPagecount(pBt->pPager);
   }
 
   if( !PTRMAP_ISPAGE(pBt, iLastPg) && iLastPg!=PENDING_BYTE_PAGE(pBt) ){
@@ -32254,7 +33792,7 @@
       Pgno nFree;
       Pgno nPtrmap;
       const int pgsz = pBt->pageSize;
-      Pgno nOrig = sqlite3PagerPagecount(pBt->pPager);
+      int nOrig = pagerPagecount(pBt->pPager);
 
       if( PTRMAP_ISPAGE(pBt, nOrig) ){
         return SQLITE_CORRUPT_BKPT;
@@ -32611,7 +34149,6 @@
   pBt->db = p->db;
   if( pBt->inStmt && !pBt->readOnly ){
     rc = sqlite3PagerStmtRollback(pBt->pPager);
-    assert( countWriteCursors(pBt)==0 );
     pBt->inStmt = 0;
   }
   sqlite3BtreeLeave(p);
@@ -32660,7 +34197,7 @@
     if( pBt->readOnly ){
       return SQLITE_READONLY;
     }
-    if( checkReadLocks(p, iTable, 0) ){
+    if( checkReadLocks(p, iTable, 0, 0) ){
       return SQLITE_LOCKED;
     }
   }
@@ -32675,7 +34212,7 @@
     }
   }
   pCur->pgnoRoot = (Pgno)iTable;
-  if( iTable==1 && sqlite3PagerPagecount(pBt->pPager)==0 ){
+  if( iTable==1 && pagerPagecount(pBt->pPager)==0 ){
     rc = SQLITE_EMPTY;
     goto create_cursor_exception;
   }
@@ -32702,9 +34239,7 @@
   return SQLITE_OK;
 
 create_cursor_exception:
-  if( pCur ){
-    releasePage(pCur->pPage);
-  }
+  releasePage(pCur->pPage);
   unlockBtreeIfUnused(pBt);
   return rc;
 }
@@ -32839,7 +34374,7 @@
   int rc;
 
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreOrClearCursorPosition(pCur);
+  rc = restoreCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
     if( pCur->eState==CURSOR_INVALID ){
@@ -32863,7 +34398,7 @@
   int rc;
 
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreOrClearCursorPosition(pCur);
+  rc = restoreCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_INVALID || pCur->eState==CURSOR_VALID );
     if( pCur->eState==CURSOR_INVALID ){
@@ -32930,7 +34465,7 @@
       iGuess++;
     }
 
-    if( iGuess<=sqlite3PagerPagecount(pBt->pPager) ){
+    if( iGuess<=pagerPagecount(pBt->pPager) ){
       rc = ptrmapGet(pBt, iGuess, &eType, &pgno);
       if( rc!=SQLITE_OK ){
         return rc;
@@ -33171,7 +34706,7 @@
   int rc;
 
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreOrClearCursorPosition(pCur);
+  rc = restoreCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_VALID );
     assert( pCur->pPage!=0 );
@@ -33197,8 +34732,14 @@
 SQLITE_PRIVATE int sqlite3BtreeData(BtCursor *pCur, u32 offset, u32 amt, void *pBuf){
   int rc;
 
+#ifndef SQLITE_OMIT_INCRBLOB
+  if ( pCur->eState==CURSOR_INVALID ){
+    return SQLITE_ABORT;
+  }
+#endif
+
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreOrClearCursorPosition(pCur);
+  rc = restoreCursorPosition(pCur);
   if( rc==SQLITE_OK ){
     assert( pCur->eState==CURSOR_VALID );
     assert( pCur->pPage!=0 );
@@ -33650,7 +35191,7 @@
         if( available>=nCellKey ){
           c = sqlite3VdbeRecordCompare(nCellKey, pCellKey, pUnKey);
         }else{
-          pCellKey = sqlite3_malloc( nCellKey );
+          pCellKey = sqlite3Malloc( nCellKey );
           if( pCellKey==0 ){
             rc = SQLITE_NOMEM;
             goto moveto_finish;
@@ -33749,7 +35290,7 @@
   MemPage *pPage;
 
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreOrClearCursorPosition(pCur);
+  rc = restoreCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -33818,7 +35359,7 @@
   MemPage *pPage;
 
   assert( cursorHoldsMutex(pCur) );
-  rc = restoreOrClearCursorPosition(pCur);
+  rc = restoreCursorPosition(pCur);
   if( rc!=SQLITE_OK ){
     return rc;
   }
@@ -33915,7 +35456,7 @@
     ** the entire-list will be searched for that page.
     */
 #ifndef SQLITE_OMIT_AUTOVACUUM
-    if( exact && nearby<=sqlite3PagerPagecount(pBt->pPager) ){
+    if( exact && nearby<=pagerPagecount(pBt->pPager) ){
       u8 eType;
       assert( nearby>0 );
       assert( pBt->autoVacuum );
@@ -33967,7 +35508,7 @@
         *ppPage = pTrunk;
         pTrunk = 0;
         TRACE(("ALLOCATE: %d trunk - %d free pages left\n", *pPgno, n-1));
-      }else if( k>pBt->usableSize/4 - 8 ){
+      }else if( k>pBt->usableSize/4 - 2 ){
         /* Value of k is out of range.  Database corruption */
         rc = SQLITE_CORRUPT_BKPT;
         goto end_allocate_page;
@@ -34050,8 +35591,10 @@
 
         iPage = get4byte(&aData[8+closest*4]);
         if( !searchList || iPage==nearby ){
+          int nPage;
           *pPgno = iPage;
-          if( *pPgno>sqlite3PagerPagecount(pBt->pPager) ){
+          nPage = pagerPagecount(pBt->pPager);
+          if( *pPgno>nPage ){
             /* Free page off the end of the file */
             rc = SQLITE_CORRUPT_BKPT;
             goto end_allocate_page;
@@ -34080,7 +35623,8 @@
   }else{
     /* There are no pages on the freelist, so create a new page at the
     ** end of the file */
-    *pPgno = sqlite3PagerPagecount(pBt->pPager) + 1;
+    int nPage = pagerPagecount(pBt->pPager);
+    *pPgno = nPage + 1;
 
 #ifndef SQLITE_OMIT_AUTOVACUUM
     if( pBt->nTrunc ){
@@ -34184,7 +35728,19 @@
     k = get4byte(&pTrunk->aData[4]);
     if( k>=pBt->usableSize/4 - 8 ){
       /* The trunk is full.  Turn the page being freed into a new
-      ** trunk page with no leaves. */
+      ** trunk page with no leaves.
+      **
+      ** Note that the trunk page is not really full until it contains
+      ** usableSize/4 - 2 entries, not usableSize/4 - 8 entries as we have
+      ** coded.  But due to a coding error in versions of SQLite prior to
+      ** 3.6.0, databases with freelist trunk pages holding more than
+      ** usableSize/4 - 8 entries will be reported as corrupt.  In order
+      ** to maintain backwards compatibility with older versions of SQLite,
+      ** we will contain to restrict the number of entries to usableSize/4 - 8
+      ** for now.  At some point in the future (once everyone has upgraded
+      ** to 3.6.0 or later) we should consider fixing the conditional above
+      ** to read "usableSize/4-2" instead of "usableSize/4-8".
+      */
       rc = sqlite3PagerWrite(pPage->pDbPage);
       if( rc==SQLITE_OK ){
         put4byte(pPage->aData, pTrunk->pgno);
@@ -34234,7 +35790,7 @@
   assert( ovflPgno==0 || nOvfl>0 );
   while( nOvfl-- ){
     MemPage *pOvfl;
-    if( ovflPgno==0 || ovflPgno>sqlite3PagerPagecount(pBt->pPager) ){
+    if( ovflPgno==0 || ovflPgno>pagerPagecount(pBt->pPager) ){
       return SQLITE_CORRUPT_BKPT;
     }
 
@@ -34546,8 +36102,7 @@
     end = cellOffset + 2*pPage->nCell + 2;
     ins = cellOffset + 2*i;
     if( end > top - sz ){
-      rc = defragmentPage(pPage);
-      if( rc!=SQLITE_OK ) return rc;
+      defragmentPage(pPage);
       top = get2byte(&data[hdr+5]);
       assert( end + sz <= top );
     }
@@ -34699,19 +36254,24 @@
   /* pPage is currently the right-child of pParent. Change this
   ** so that the right-child is the new page allocated above and
   ** pPage is the next-to-right child. 
+  **
+  ** Ignore the return value of the call to fillInCell(). fillInCell()
+  ** may only return other than SQLITE_OK if it is required to allocate
+  ** one or more overflow pages. Since an internal table B-Tree cell 
+  ** may never spill over onto an overflow page (it is a maximum of 
+  ** 13 bytes in size), it is not neccessary to check the return code.
+  **
+  ** Similarly, the insertCell() function cannot fail if the page
+  ** being inserted into is already writable and the cell does not 
+  ** contain an overflow pointer. So ignore this return code too.
   */
   assert( pPage->nCell>0 );
   pCell = findCell(pPage, pPage->nCell-1);
   sqlite3BtreeParseCellPtr(pPage, pCell, &info);
-  rc = fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
+  fillInCell(pParent, parentCell, 0, info.nKey, 0, 0, 0, &parentSize);
   assert( parentSize<64 );
-  rc = insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
-  if( rc!=SQLITE_OK ){
-    return rc;
-  }
+  assert( sqlite3PagerIswriteable(pParent->pDbPage) );
+  insertCell(pParent, parentIdx, parentCell, parentSize, 0, 4);
   put4byte(findOverflowCell(pParent,parentIdx), pPage->pgno);
   put4byte(&pParent->aData[pParent->hdrOffset+8], pgnoNew);
 
@@ -34786,7 +36346,9 @@
   int usableSpace;             /* Bytes in pPage beyond the header */
   int pageFlags;               /* Value of pPage->aData[0] */
   int subtotal;                /* Subtotal of bytes in cells on one page */
-  int iSpace = 0;              /* First unused byte of aSpace[] */
+  int iSpace1 = 0;             /* First unused byte of aSpace1[] */
+  int iSpace2 = 0;             /* First unused byte of aSpace2[] */
+  int szScratch;               /* Size of scratch memory requested */
   MemPage *apOld[NB];          /* pPage and up to two siblings */
   Pgno pgnoOld[NB];            /* Page numbers for each page in apOld[] */
   MemPage *apCopy[NB];         /* Private copies of apOld[] pages */
@@ -34797,8 +36359,9 @@
   int szNew[NB+2];             /* Combined size of cells place on i-th page */
   u8 **apCell = 0;             /* All cells begin balanced */
   u16 *szCell;                 /* Local size of all cells in apCell[] */
-  u8 *aCopy[NB];               /* Space for holding data of apCopy[] */
-  u8 *aSpace;                  /* Space to hold copies of dividers cells */
+  u8 *aCopy[NB];         /* Space for holding data of apCopy[] */
+  u8 *aSpace1;           /* Space for copies of dividers cells before balance */
+  u8 *aSpace2 = 0;       /* Space for overflow dividers cells after balance */
 #ifndef SQLITE_OMIT_AUTOVACUUM
   u8 *aFrom = 0;
 #endif
@@ -34816,6 +36379,7 @@
   if( SQLITE_OK!=(rc = sqlite3PagerWrite(pParent->pDbPage)) ){
     return rc;
   }
+
   TRACE(("BALANCE: begin page %d child of %d\n", pPage->pgno, pParent->pgno));
 
 #ifndef SQLITE_OMIT_QUICKBALANCE
@@ -34916,13 +36480,13 @@
   /*
   ** Allocate space for memory structures
   */
-  apCell = sqlite3_malloc( 
+  szScratch =
        nMaxCells*sizeof(u8*)                       /* apCell */
      + nMaxCells*sizeof(u16)                       /* szCell */
      + (ROUND8(sizeof(MemPage))+pBt->pageSize)*NB  /* aCopy */
-     + pBt->pageSize*5                             /* aSpace */
-     + (ISAUTOVACUUM ? nMaxCells : 0)              /* aFrom */
-  );
+     + pBt->pageSize                               /* aSpace1 */
+     + (ISAUTOVACUUM ? nMaxCells : 0);             /* aFrom */
+  apCell = sqlite3ScratchMalloc( szScratch ); 
   if( apCell==0 ){
     rc = SQLITE_NOMEM;
     goto balance_cleanup;
@@ -34934,13 +36498,18 @@
     aCopy[i] = &aCopy[i-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
     assert( ((aCopy[i] - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
   }
-  aSpace = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
-  assert( ((aSpace - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
+  aSpace1 = &aCopy[NB-1][pBt->pageSize+ROUND8(sizeof(MemPage))];
+  assert( ((aSpace1 - (u8*)apCell) & 7)==0 ); /* 8-byte alignment required */
 #ifndef SQLITE_OMIT_AUTOVACUUM
   if( pBt->autoVacuum ){
-    aFrom = &aSpace[5*pBt->pageSize];
+    aFrom = &aSpace1[pBt->pageSize];
   }
 #endif
+  aSpace2 = sqlite3PageMalloc(pBt->pageSize);
+  if( aSpace2==0 ){
+    rc = SQLITE_NOMEM;
+    goto balance_cleanup;
+  }
   
   /*
   ** Make copies of the content of pPage and its siblings into aOld[].
@@ -34958,12 +36527,12 @@
   /*
   ** Load pointers to all cells on sibling pages and the divider cells
   ** into the local apCell[] array.  Make copies of the divider cells
-  ** into space obtained form aSpace[] and remove the the divider Cells
+  ** into space obtained form aSpace1[] and remove the the divider Cells
   ** from pParent.
   **
   ** If the siblings are on leaf pages, then the child pointers of the
   ** divider cells are stripped from the cells before they are copied
-  ** into aSpace[].  In this way, all cells in apCell[] are without
+  ** into aSpace1[].  In this way, all cells in apCell[] are without
   ** child pointers.  If siblings are not leaves, then all cell in
   ** apCell[] include child pointers.  Either way, all cells in apCell[]
   ** are alike.
@@ -35008,9 +36577,10 @@
         u8 *pTemp;
         assert( nCell<nMaxCells );
         szCell[nCell] = sz;
-        pTemp = &aSpace[iSpace];
-        iSpace += sz;
-        assert( iSpace<=pBt->pageSize*5 );
+        pTemp = &aSpace1[iSpace1];
+        iSpace1 += sz;
+        assert( sz<=pBt->pageSize/4 );
+        assert( iSpace1<=pBt->pageSize );
         memcpy(pTemp, apDiv[i], sz);
         apCell[nCell] = pTemp+leafCorrection;
 #ifndef SQLITE_OMIT_AUTOVACUUM
@@ -35128,7 +36698,6 @@
       apNew[i] = pNew;
       nNew++;
     }
-    zeroPage(pNew, pageFlags);
   }
 
   /* Free any old pages that were not reused as new pages.
@@ -35195,6 +36764,7 @@
     MemPage *pNew = apNew[i];
     assert( j<nMaxCells );
     assert( pNew->pgno==pgnoNew[i] );
+    zeroPage(pNew, pageFlags);
     assemblePage(pNew, cntNew[i]-j, &apCell[j], &szCell[j]);
     assert( pNew->nCell>0 || (nNew==1 && cntNew[0]==0) );
     assert( pNew->nOverflow==0 );
@@ -35231,9 +36801,9 @@
       assert( j<nMaxCells );
       pCell = apCell[j];
       sz = szCell[j] + leafCorrection;
+      pTemp = &aSpace2[iSpace2];
       if( !pNew->leaf ){
         memcpy(&pNew->aData[8], pCell, 4);
-        pTemp = 0;
       }else if( leafData ){
         /* If the tree is a leaf-data tree, and the siblings are leaves, 
         ** then there is no divider cell in apCell[]. Instead, the divider 
@@ -35243,16 +36813,11 @@
         CellInfo info;
         j--;
         sqlite3BtreeParseCellPtr(pNew, apCell[j], &info);
-        pCell = &aSpace[iSpace];
+        pCell = pTemp;
         fillInCell(pParent, pCell, 0, info.nKey, 0, 0, 0, &sz);
-        iSpace += sz;
-        assert( iSpace<=pBt->pageSize*5 );
         pTemp = 0;
       }else{
         pCell -= 4;
-        pTemp = &aSpace[iSpace];
-        iSpace += sz;
-        assert( iSpace<=pBt->pageSize*5 );
         /* 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 
@@ -35269,6 +36834,9 @@
           sz = cellSizePtr(pParent, pCell);
         }
       }
+      iSpace2 += sz;
+      assert( sz<=pBt->pageSize/4 );
+      assert( iSpace2<=pBt->pageSize );
       rc = insertCell(pParent, nxDiv, pCell, sz, pTemp, 4);
       if( rc!=SQLITE_OK ) goto balance_cleanup;
       put4byte(findOverflowCell(pParent,nxDiv), pNew->pgno);
@@ -35319,13 +36887,16 @@
   ** But the parent page will always be initialized.
   */
   assert( pParent->isInit );
+  sqlite3ScratchFree(apCell);
+  apCell = 0;
   rc = balance(pParent, 0);
   
   /*
   ** Cleanup before returning.
   */
 balance_cleanup:
-  sqlite3_free(apCell);
+  sqlite3PageFree(aSpace2);
+  sqlite3ScratchFree(apCell);
   for(i=0; i<nOld; i++){
     releasePage(apOld[i]);
   }
@@ -35357,7 +36928,7 @@
   assert( sqlite3_mutex_held(pPage->pBt->mutex) );
   pBt = pPage->pBt;
   mxCellPerPage = MX_CELL(pBt);
-  apCell = sqlite3_malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) );
+  apCell = sqlite3Malloc( mxCellPerPage*(sizeof(u8*)+sizeof(u16)) );
   if( apCell==0 ) return SQLITE_NOMEM;
   szCell = (u16*)&apCell[mxCellPerPage];
   if( pPage->leaf ){
@@ -35378,7 +36949,7 @@
     */
     pgnoChild = get4byte(&pPage->aData[pPage->hdrOffset+8]);
     assert( pgnoChild>0 );
-    assert( pgnoChild<=sqlite3PagerPagecount(pPage->pBt->pPager) );
+    assert( pgnoChild<=pagerPagecount(pPage->pBt->pPager) );
     rc = sqlite3BtreeGetPage(pPage->pBt, pgnoChild, &pChild, 0);
     if( rc ) goto end_shallow_balance;
     if( pPage->pgno==1 ){
@@ -35470,7 +37041,7 @@
   cdata = pChild->aData;
   memcpy(cdata, &data[hdr], pPage->cellOffset+2*pPage->nCell-hdr);
   memcpy(&cdata[brk], &data[brk], usableSize-brk);
-  assert( pChild->isInit==0 );
+  if( pChild->isInit ) return SQLITE_CORRUPT;
   rc = sqlite3BtreeInitPage(pChild, pPage);
   if( rc ) goto balancedeeper_out;
   memcpy(pChild->aOvfl, pPage->aOvfl, pPage->nOverflow*sizeof(pPage->aOvfl[0]));
@@ -35490,7 +37061,7 @@
     for(i=0; i<pChild->nCell; i++){
       rc = ptrmapPutOvfl(pChild, i);
       if( rc!=SQLITE_OK ){
-        return rc;
+        goto balancedeeper_out;
       }
     }
   }
@@ -35534,47 +37105,68 @@
 ** is not in the ReadUncommmitted state, then this routine returns 
 ** SQLITE_LOCKED.
 **
-** In addition to checking for read-locks (where a read-lock 
-** means a cursor opened with wrFlag==0) this routine also moves
-** all write cursors so that they are pointing to the 
-** first Cell on the root page.  This is necessary because an insert 
-** or delete might change the number of cells on a page or delete
-** a page entirely and we do not want to leave any cursors 
-** pointing to non-existant pages or cells.
-*/
-static int checkReadLocks(Btree *pBtree, Pgno pgnoRoot, BtCursor *pExclude){
+** As well as cursors with wrFlag==0, cursors with wrFlag==1 and 
+** isIncrblobHandle==1 are also considered 'read' cursors. Incremental 
+** blob cursors are used for both reading and writing.
+**
+** When pgnoRoot is the root page of an intkey table, this function is also
+** responsible for invalidating incremental blob cursors when the table row
+** on which they are opened is deleted or modified. Cursors are invalidated
+** according to the following rules:
+**
+**   1) When BtreeClearTable() is called to completely delete the contents
+**      of a B-Tree table, pExclude is set to zero and parameter iRow is 
+**      set to non-zero. In this case all incremental blob cursors open
+**      on the table rooted at pgnoRoot are invalidated.
+**
+**   2) When BtreeInsert(), BtreeDelete() or BtreePutData() is called to 
+**      modify a table row via an SQL statement, pExclude is set to the 
+**      write cursor used to do the modification and parameter iRow is set
+**      to the integer row id of the B-Tree entry being modified. Unless
+**      pExclude is itself an incremental blob cursor, then all incremental
+**      blob cursors open on row iRow of the B-Tree are invalidated.
+**
+**   3) If both pExclude and iRow are set to zero, no incremental blob 
+**      cursors are invalidated.
+*/
+static int checkReadLocks(
+  Btree *pBtree, 
+  Pgno pgnoRoot, 
+  BtCursor *pExclude,
+  i64 iRow
+){
   BtCursor *p;
   BtShared *pBt = pBtree->pBt;
   sqlite3 *db = pBtree->db;
   assert( sqlite3BtreeHoldsMutex(pBtree) );
   for(p=pBt->pCursor; p; p=p->pNext){
     if( p==pExclude ) continue;
-    if( p->eState!=CURSOR_VALID ) continue;
     if( p->pgnoRoot!=pgnoRoot ) continue;
-    if( p->wrFlag==0 ){
+#ifndef SQLITE_OMIT_INCRBLOB
+    if( p->isIncrblobHandle && ( 
+         (!pExclude && iRow)
+      || (pExclude && !pExclude->isIncrblobHandle && p->info.nKey==iRow)
+    )){
+      p->eState = CURSOR_INVALID;
+    }
+#endif
+    if( p->eState!=CURSOR_VALID ) continue;
+    if( p->wrFlag==0 
+#ifndef SQLITE_OMIT_INCRBLOB
+     || p->isIncrblobHandle
+#endif
+    ){
       sqlite3 *dbOther = p->pBtree->db;
       if( dbOther==0 ||
          (dbOther!=db && (dbOther->flags & SQLITE_ReadUncommitted)==0) ){
         return SQLITE_LOCKED;
       }
-    }else if( p->pPage->pgno!=p->pgnoRoot ){
-      moveToRoot(p);
     }
   }
   return SQLITE_OK;
 }
 
 /*
-** Make sure pBt->pTmpSpace points to an allocation of 
-** MX_CELL_SIZE(pBt) bytes.
-*/
-static void allocateTempSpace(BtShared *pBt){
-  if( !pBt->pTmpSpace ){
-    pBt->pTmpSpace = sqlite3_malloc(MX_CELL_SIZE(pBt));
-  }
-}
-
-/*
 ** Insert a new record into the BTree.  The key is given by (pKey,nKey)
 ** and the data is given by (pData,nData).  The cursor is used only to
 ** define what table the record should be inserted into.  The cursor
@@ -35609,7 +37201,7 @@
   if( !pCur->wrFlag ){
     return SQLITE_PERM;   /* Cursor not open for writing */
   }
-  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
+  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur, nKey) ){
     return SQLITE_LOCKED; /* The table pCur points to has a read lock */
   }
   if( pCur->eState==CURSOR_FAULT ){
@@ -35665,8 +37257,6 @@
   rc = insertCell(pPage, pCur->idx, newCell, szNew, 0, 0);
   if( rc!=SQLITE_OK ) goto end_insert;
   rc = balance(pPage, 1);
-  /* sqlite3BtreePageDump(pCur->pBt, pCur->pgnoRoot, 1); */
-  /* fflush(stdout); */
   if( rc==SQLITE_OK ){
     moveToRoot(pCur);
   }
@@ -35703,7 +37293,7 @@
   if( !pCur->wrFlag ){
     return SQLITE_PERM;   /* Did not open this cursor for writing */
   }
-  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur) ){
+  if( checkReadLocks(pCur->pBtree, pCur->pgnoRoot, pCur, pCur->info.nKey) ){
     return SQLITE_LOCKED; /* The table pCur points to has a read lock */
   }
 
@@ -35713,7 +37303,7 @@
   ** that the entry will be deleted from.
   */
   if( 
-    (rc = restoreOrClearCursorPosition(pCur))!=0 ||
+    (rc = restoreCursorPosition(pCur))!=0 ||
     (rc = saveAllCursors(pBt, pCur->pgnoRoot, pCur))!=0 ||
     (rc = sqlite3PagerWrite(pPage->pDbPage))!=0
   ){
@@ -35956,7 +37546,7 @@
   int i;
 
   assert( sqlite3_mutex_held(pBt->mutex) );
-  if( pgno>sqlite3PagerPagecount(pBt->pPager) ){
+  if( pgno>pagerPagecount(pBt->pPager) ){
     return SQLITE_CORRUPT_BKPT;
   }
 
@@ -36002,7 +37592,7 @@
   pBt->db = p->db;
   if( p->inTrans!=TRANS_WRITE ){
     rc = pBt->readOnly ? SQLITE_READONLY : SQLITE_ERROR;
-  }else if( (rc = checkReadLocks(p, iTable, 0))!=SQLITE_OK ){
+  }else if( (rc = checkReadLocks(p, iTable, 0, 1))!=SQLITE_OK ){
     /* nothing to do */
   }else if( SQLITE_OK!=(rc = saveAllCursors(pBt, iTable, 0)) ){
     /* nothing to do */
@@ -36241,10 +37831,10 @@
 */
 SQLITE_PRIVATE int sqlite3BtreeFlags(BtCursor *pCur){
   /* TODO: What about CURSOR_REQUIRESEEK state? Probably need to call
-  ** restoreOrClearCursorPosition() here.
+  ** restoreCursorPosition() here.
   */
   MemPage *pPage;
-  restoreOrClearCursorPosition(pCur);
+  restoreCursorPosition(pCur);
   pPage = pCur->pPage;
   assert( cursorHoldsMutex(pCur) );
   assert( pPage->pBt==pCur->pBt );
@@ -36271,23 +37861,18 @@
   ...
 ){
   va_list ap;
-  char *zMsg2;
   if( !pCheck->mxErr ) return;
   pCheck->mxErr--;
   pCheck->nErr++;
   va_start(ap, zFormat);
-  zMsg2 = sqlite3VMPrintf(0, zFormat, ap);
-  va_end(ap);
-  if( zMsg1==0 ) zMsg1 = "";
-  if( pCheck->zErrMsg ){
-    char *zOld = pCheck->zErrMsg;
-    pCheck->zErrMsg = 0;
-    sqlite3SetString(&pCheck->zErrMsg, zOld, "\n", zMsg1, zMsg2, (char*)0);
-    sqlite3_free(zOld);
-  }else{
-    sqlite3SetString(&pCheck->zErrMsg, zMsg1, zMsg2, (char*)0);
+  if( pCheck->errMsg.nChar ){
+    sqlite3StrAccumAppend(&pCheck->errMsg, "\n", 1);
   }
-  sqlite3_free(zMsg2);
+  if( zMsg1 ){
+    sqlite3StrAccumAppend(&pCheck->errMsg, zMsg1, -1);
+  }
+  sqlite3VXPrintf(&pCheck->errMsg, 1, zFormat, ap);
+  va_end(ap);
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
 
@@ -36380,7 +37965,7 @@
         checkPtrmap(pCheck, iPage, PTRMAP_FREEPAGE, 0, zContext);
       }
 #endif
-      if( n>pCheck->pBt->usableSize/4-8 ){
+      if( n>pCheck->pBt->usableSize/4-2 ){
         checkAppendMsg(pCheck, zContext,
            "freelist leaf count too big on page %d", iPage);
         N--;
@@ -36530,8 +38115,9 @@
   */
   data = pPage->aData;
   hdr = pPage->hdrOffset;
-  hit = sqlite3MallocZero( usableSize );
+  hit = sqlite3PageMalloc( pBt->pageSize );
   if( hit ){
+    memset(hit, 0, usableSize );
     memset(hit, 1, get2byte(&data[hdr+5]));
     nCell = get2byte(&data[hdr+3]);
     cellStart = hdr + 12 - 4*pPage->leaf;
@@ -36573,7 +38159,7 @@
           cnt, data[hdr+7], iPage);
     }
   }
-  sqlite3_free(hit);
+  sqlite3PageFree(hit);
 
   releasePage(pPage);
   return depth+1;
@@ -36602,6 +38188,7 @@
   int nRef;
   IntegrityCk sCheck;
   BtShared *pBt = p->pBt;
+  char zErr[100];
 
   sqlite3BtreeEnter(p);
   pBt->db = p->db;
@@ -36612,7 +38199,7 @@
   }
   sCheck.pBt = pBt;
   sCheck.pPager = pBt->pPager;
-  sCheck.nPage = sqlite3PagerPagecount(sCheck.pPager);
+  sCheck.nPage = pagerPagecount(sCheck.pPager);
   sCheck.mxErr = mxErr;
   sCheck.nErr = 0;
   *pnErr = 0;
@@ -36626,7 +38213,7 @@
     sqlite3BtreeLeave(p);
     return 0;
   }
-  sCheck.anRef = sqlite3_malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
+  sCheck.anRef = sqlite3Malloc( (sCheck.nPage+1)*sizeof(sCheck.anRef[0]) );
   if( !sCheck.anRef ){
     unlockBtreeIfUnused(pBt);
     *pnErr = 1;
@@ -36639,7 +38226,7 @@
   if( i<=sCheck.nPage ){
     sCheck.anRef[i] = 1;
   }
-  sCheck.zErrMsg = 0;
+  sqlite3StrAccumInit(&sCheck.errMsg, zErr, sizeof(zErr), 20000);
 
   /* Check the integrity of the freelist
   */
@@ -36695,7 +38282,8 @@
   sqlite3BtreeLeave(p);
   sqlite3_free(sCheck.anRef);
   *pnErr = sCheck.nErr;
-  return sCheck.zErrMsg;
+  if( sCheck.nErr==0 ) sqlite3StrAccumReset(&sCheck.errMsg);
+  return sqlite3StrAccumFinish(&sCheck.errMsg);
 }
 #endif /* SQLITE_OMIT_INTEGRITY_CHECK */
 
@@ -36773,8 +38361,8 @@
     return SQLITE_BUSY;
   }
 
-  nToPage = sqlite3PagerPagecount(pBtTo->pPager);
-  nFromPage = sqlite3PagerPagecount(pBtFrom->pPager);
+  nToPage = pagerPagecount(pBtTo->pPager);
+  nFromPage = pagerPagecount(pBtFrom->pPager);
   iSkip = PENDING_BYTE_PAGE(pBtTo);
 
   /* Variable nNewPage is the number of pages required to store the
@@ -36987,6 +38575,10 @@
 ** call the nBytes parameter is ignored and a pointer to the same blob
 ** 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 
 ** blob of allocated memory. This function should not call sqlite3_free()
@@ -36995,7 +38587,7 @@
 SQLITE_PRIVATE void *sqlite3BtreeSchema(Btree *p, int nBytes, void(*xFree)(void *)){
   BtShared *pBt = p->pBt;
   sqlite3BtreeEnter(p);
-  if( !pBt->pSchema ){
+  if( !pBt->pSchema && nBytes ){
     pBt->pSchema = sqlite3MallocZero(nBytes);
     pBt->xFreeSchema = xFree;
   }
@@ -37052,12 +38644,11 @@
   assert( cursorHoldsMutex(pCsr) );
   assert( sqlite3_mutex_held(pCsr->pBtree->db->mutex) );
   assert(pCsr->isIncrblobHandle);
-  if( pCsr->eState>=CURSOR_REQUIRESEEK ){
-    if( pCsr->eState==CURSOR_FAULT ){
-      return pCsr->skip;
-    }else{
-      return SQLITE_ABORT;
-    }
+
+  restoreCursorPosition(pCsr);
+  assert( pCsr->eState!=CURSOR_REQUIRESEEK );
+  if( pCsr->eState!=CURSOR_VALID ){
+    return SQLITE_ABORT;
   }
 
   /* Check some preconditions: 
@@ -37070,7 +38661,7 @@
   }
   assert( !pCsr->pBt->readOnly 
           && pCsr->pBt->inTransaction==TRANS_WRITE );
-  if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr) ){
+  if( checkReadLocks(pCsr->pBtree, pCsr->pgnoRoot, pCsr, 0) ){
     return SQLITE_LOCKED; /* The table pCur points to has a read lock */
   }
   if( pCsr->eState==CURSOR_INVALID || !pCsr->pPage->intKey ){
@@ -37114,6 +38705,8 @@
 *************************************************************************
 ** This file implements a FIFO queue of rowids used for processing
 ** UPDATE and DELETE statements.
+**
+** $Id: vdbefifo.c,v 1.7 2008/06/15 02:51:48 drh Exp $
 */
 
 /*
@@ -37137,7 +38730,7 @@
   if( nEntry>FIFOSIZE_MAX ){
     nEntry = FIFOSIZE_MAX;
   }
-  pPage = sqlite3_malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
+  pPage = sqlite3Malloc( sizeof(FifoPage) + sizeof(i64)*(nEntry-1) );
   if( pPage ){
     pPage->nSlot = nEntry;
     pPage->iWrite = 0;
@@ -37244,6 +38837,8 @@
 ** stores a single value in the VDBE.  Mem is an opaque structure visible
 ** only within the VDBE.  Interface routines refer to a Mem using the
 ** name sqlite_value
+**
+** $Id: vdbemem.c,v 1.118 2008/07/09 16:51:51 drh Exp $
 */
 
 /*
@@ -37307,8 +38902,8 @@
     ((pMem->flags&MEM_Static) ? 1 : 0)
   );
 
-  if( !pMem->zMalloc || sqlite3MallocSize(pMem->zMalloc)<n ){
-    n = (n>32?n:32);
+  if( n<32 ) n = 32;
+  if( sqlite3MallocSize(pMem->zMalloc)<n ){
     if( preserve && pMem->z==pMem->zMalloc ){
       pMem->z = pMem->zMalloc = sqlite3DbReallocOrFree(pMem->db, pMem->z, n);
       if( !pMem->z ){
@@ -37813,6 +39408,7 @@
   void (*xDel)(void*) /* Destructor function */
 ){
   int nByte = n;      /* New value for pMem->n */
+  int iLimit;         /* Maximum allowed string or blob size */
   int flags = 0;      /* New value for pMem->flags */
 
   assert( pMem->db==0 || sqlite3_mutex_held(pMem->db->mutex) );
@@ -37823,16 +39419,24 @@
     return SQLITE_OK;
   }
 
+  if( pMem->db ){
+    iLimit = pMem->db->aLimit[SQLITE_LIMIT_LENGTH];
+  }else{
+    iLimit = SQLITE_MAX_LENGTH;
+  }
   flags = (enc==0?MEM_Blob:MEM_Str);
   if( nByte<0 ){
     assert( enc!=0 );
     if( enc==SQLITE_UTF8 ){
-      for(nByte=0; z[nByte]; nByte++){}
+      for(nByte=0; nByte<=iLimit && z[nByte]; nByte++){}
     }else{
-      for(nByte=0; z[nByte] | z[nByte+1]; nByte+=2){}
+      for(nByte=0; nByte<=iLimit && (z[nByte] | z[nByte+1]); nByte+=2){}
     }
     flags |= MEM_Term;
   }
+  if( nByte>iLimit ){
+    return SQLITE_TOOBIG;
+  }
 
   /* The following block sets the new values of Mem.z and Mem.xDel. It
   ** also sets a flag in local variable "flags" to indicate the memory
@@ -38120,7 +39724,7 @@
   expandBlob(pVal);
   if( pVal->flags&MEM_Str ){
     sqlite3VdbeChangeEncoding(pVal, enc & ~SQLITE_UTF16_ALIGNED);
-    if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&(int)pVal->z) ){
+    if( (enc & SQLITE_UTF16_ALIGNED)!=0 && 1==(1&SQLITE_PTR_TO_INT(pVal->z)) ){
       assert( (pVal->flags & (MEM_Ephem|MEM_Static))!=0 );
       if( sqlite3VdbeMemMakeWriteable(pVal)!=SQLITE_OK ){
         return 0;
@@ -38280,7 +39884,7 @@
 ** to version 2.8.7, all this code was combined into the vdbe.c source file.
 ** But that file was getting too big so this subroutines were split out.
 **
-** $Id: vdbeaux.c,v 1.383 2008/05/13 13:27:34 drh Exp $
+** $Id: vdbeaux.c,v 1.397 2008/07/11 21:02:54 drh Exp $
 */
 
 
@@ -38533,14 +40137,12 @@
   for(pOp=p->aOp, i=p->nOp-1; i>=0; i--, pOp++){
     u8 opcode = pOp->opcode;
 
-    if( opcode==OP_Function ){
+    if( opcode==OP_Function || opcode==OP_AggStep ){
       if( pOp->p5>nMaxArgs ) nMaxArgs = pOp->p5;
-    }else if( opcode==OP_AggStep 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
-        || opcode==OP_VUpdate
-#endif
-    ){
+    }else if( opcode==OP_VUpdate ){
       if( pOp->p2>nMaxArgs ) nMaxArgs = pOp->p2;
+#endif
     }
     if( opcode==OP_Halt ){
       if( pOp->p1==SQLITE_CONSTRAINT && pOp->p2==OE_Abort ){
@@ -38706,31 +40308,32 @@
 /*
 ** Delete a P4 value if necessary.
 */
-static void freeP4(int p4type, void *p3){
-  if( p3 ){
+static void freeP4(int p4type, void *p4){
+  if( p4 ){
     switch( p4type ){
       case P4_REAL:
       case P4_INT64:
       case P4_MPRINTF:
       case P4_DYNAMIC:
       case P4_KEYINFO:
+      case P4_INTARRAY:
       case P4_KEYINFO_HANDOFF: {
-        sqlite3_free(p3);
+        sqlite3_free(p4);
         break;
       }
       case P4_VDBEFUNC: {
-        VdbeFunc *pVdbeFunc = (VdbeFunc *)p3;
+        VdbeFunc *pVdbeFunc = (VdbeFunc *)p4;
         freeEphemeralFunction(pVdbeFunc->pFunc);
         sqlite3VdbeDeleteAuxData(pVdbeFunc, 0);
         sqlite3_free(pVdbeFunc);
         break;
       }
       case P4_FUNCDEF: {
-        freeEphemeralFunction((FuncDef*)p3);
+        freeEphemeralFunction((FuncDef*)p4);
         break;
       }
       case P4_MEM: {
-        sqlite3ValueFree((sqlite3_value*)p3);
+        sqlite3ValueFree((sqlite3_value*)p4);
         break;
       }
     }
@@ -38799,7 +40402,7 @@
   if( n==P4_INT32 ){
     /* Note: this cast is safe, because the origin data point was an int
     ** that was cast to a (const char *). */
-    pOp->p4.i = (int)zP4;
+    pOp->p4.i = SQLITE_PTR_TO_INT(zP4);
     pOp->p4type = n;
   }else if( zP4==0 ){
     pOp->p4.p = 0;
@@ -38810,22 +40413,16 @@
 
     nField = ((KeyInfo*)zP4)->nField;
     nByte = sizeof(*pKeyInfo) + (nField-1)*sizeof(pKeyInfo->aColl[0]) + nField;
-    pKeyInfo = sqlite3_malloc( nByte );
+    pKeyInfo = sqlite3Malloc( nByte );
     pOp->p4.pKeyInfo = pKeyInfo;
     if( pKeyInfo ){
+      u8 *aSortOrder;
       memcpy(pKeyInfo, zP4, nByte);
-      /* In the current implementation, P4_KEYINFO is only ever used on
-      ** KeyInfo structures that have no aSortOrder component.  Elements
-      ** with an aSortOrder always use P4_KEYINFO_HANDOFF.  So we do not
-      ** need to bother with duplicating the aSortOrder. */
-      assert( pKeyInfo->aSortOrder==0 );
-#if 0
       aSortOrder = pKeyInfo->aSortOrder;
       if( aSortOrder ){
         pKeyInfo->aSortOrder = (unsigned char*)&pKeyInfo->aColl[nField];
         memcpy(pKeyInfo->aSortOrder, aSortOrder, nField);
       }
-#endif
       pOp->p4type = P4_KEYINFO;
     }else{
       p->db->mallocFailed = 1;
@@ -38846,7 +40443,10 @@
 
 #ifndef NDEBUG
 /*
-** Change the comment on the the most recently coded instruction.
+** Change the comment on the the most recently coded instruction.  Or
+** insert a No-op and add the comment to that new instruction.  This
+** makes the code easier to read during debugging.  None of this happens
+** in a production build.
 */
 SQLITE_PRIVATE void sqlite3VdbeComment(Vdbe *p, const char *zFormat, ...){
   va_list ap;
@@ -38860,7 +40460,20 @@
     va_end(ap);
   }
 }
-#endif
+SQLITE_PRIVATE void sqlite3VdbeNoopComment(Vdbe *p, const char *zFormat, ...){
+  va_list ap;
+  sqlite3VdbeAddOp0(p, OP_Noop);
+  assert( p->nOp>0 || p->aOp==0 );
+  assert( p->aOp==0 || p->aOp[p->nOp-1].zComment==0 || p->db->mallocFailed );
+  if( p->nOp ){
+    char **pz = &p->aOp[p->nOp-1].zComment;
+    va_start(ap, zFormat);
+    sqlite3_free(*pz);
+    *pz = sqlite3VMPrintf(p->db, zFormat, ap);
+    va_end(ap);
+  }
+}
+#endif  /* NDEBUG */
 
 /*
 ** Return the opcode for a given address.
@@ -38881,6 +40494,7 @@
   char *zP4 = zTemp;
   assert( nTemp>=20 );
   switch( pOp->p4type ){
+    case P4_KEYINFO_STATIC:
     case P4_KEYINFO: {
       int i, j;
       KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
@@ -38951,6 +40565,10 @@
       break;
     }
 #endif
+    case P4_INTARRAY: {
+      sqlite3_snprintf(nTemp, zTemp, "intarray");
+      break;
+    }
     default: {
       zP4 = pOp->p4.z;
       if( zP4==0 ){
@@ -39081,7 +40699,7 @@
   }else if( db->u1.isInterrupted ){
     p->rc = SQLITE_INTERRUPT;
     rc = SQLITE_ERROR;
-    sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(p->rc), (char*)0);
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(p->rc));
   }else{
     char *z;
     Op *pOp = &p->aOp[i];
@@ -39306,7 +40924,6 @@
   p->pc = -1;
   p->rc = SQLITE_OK;
   p->uniqueCnt = 0;
-  p->returnDepth = 0;
   p->errorAction = OE_Abort;
   p->explain |= isExplain;
   p->magic = VDBE_MAGIC_RUN;
@@ -39333,11 +40950,12 @@
   if( pCx==0 ){
     return;
   }
-  if( pCx->pCursor ){
-    sqlite3BtreeCloseCursor(pCx->pCursor);
-  }
   if( pCx->pBt ){
     sqlite3BtreeClose(pCx->pBt);
+    /* The pCx->pCursor will be close automatically, if it exists, by
+    ** the call above. */
+  }else if( pCx->pCursor ){
+    sqlite3BtreeCloseCursor(pCx->pCursor);
   }
 #ifndef SQLITE_OMIT_VIRTUALTABLE
   if( pCx->pVtabCursor ){
@@ -39509,9 +41127,9 @@
   ** master-journal.
   **
   ** If the return value of sqlite3BtreeGetFilename() is a zero length
-  ** string, it means the main database is :memory:.  In that case we do
-  ** not support atomic multi-file commits, so use the simple case then
-  ** too.
+  ** 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==strlen(sqlite3BtreeGetFilename(db->aDb[0].pBt)) || nTrans<=1 ){
     for(i=0; rc==SQLITE_OK && i<db->nDb; i++){ 
@@ -39549,6 +41167,7 @@
     char const *zMainFile = sqlite3BtreeGetFilename(db->aDb[0].pBt);
     sqlite3_file *pMaster = 0;
     i64 offset = 0;
+    int res;
 
     /* Select a master journal file name */
     do {
@@ -39559,11 +41178,9 @@
       if( !zMaster ){
         return SQLITE_NOMEM;
       }
-      rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS);
-    }while( rc==1 );
-    if( rc!=0 ){
-      rc = SQLITE_IOERR_NOMEM;
-    }else{
+      rc = sqlite3OsAccess(pVfs, zMaster, SQLITE_ACCESS_EXISTS, &res);
+    }while( rc==SQLITE_OK && res );
+    if( rc==SQLITE_OK ){
       /* Open the master journal. */
       rc = sqlite3OsOpenMalloc(pVfs, zMaster, &pMaster, 
           SQLITE_OPEN_READWRITE|SQLITE_OPEN_CREATE|
@@ -39655,14 +41272,14 @@
     ** may be lying around. Returning an error code won't help matters.
     */
     disable_simulated_io_errors();
-    sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
+    sqlite3BeginBenignMalloc();
     for(i=0; i<db->nDb; i++){ 
       Btree *pBt = db->aDb[i].pBt;
       if( pBt ){
         sqlite3BtreeCommitPhaseTwo(pBt);
       }
     }
-    sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
+    sqlite3EndBenignMalloc();
     enable_simulated_io_errors();
 
     sqlite3VtabCommit(db);
@@ -39883,7 +41500,8 @@
         rc = xFunc(pBt);
         if( rc && (p->rc==SQLITE_OK || p->rc==SQLITE_CONSTRAINT) ){
           p->rc = rc;
-          sqlite3SetString(&p->zErrMsg, 0);
+          sqlite3_free(p->zErrMsg);
+          p->zErrMsg = 0;
         }
       }
     }
@@ -40113,6 +41731,14 @@
 #endif
     p->deferredMoveto = 0;
     p->cacheStatus = CACHE_STALE;
+  }else if( p->pCursor ){
+    int hasMoved;
+    int rc = sqlite3BtreeCursorHasMoved(p->pCursor, &hasMoved);
+    if( rc ) return rc;
+    if( hasMoved ){
+      p->cacheStatus = CACHE_STALE;
+      p->nullRow = 1;
+    }
   }
   return SQLITE_OK;
 }
@@ -40749,6 +42375,8 @@
 **
 ** This file contains code use to implement APIs that are part of the
 ** VDBE.
+**
+** $Id: vdbeapi.c,v 1.134 2008/06/19 02:52:25 drh Exp $
 */
 
 #ifdef SQLITE_ENABLE_MEMORY_MANAGEMENT
@@ -40801,10 +42429,10 @@
 ** is protected by the SQLITE_MUTEX_STATIC_LRU mutex.
 */
 static void stmtLruAdd(Vdbe *p){
-  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
 
   if( p->pLruPrev || p->pLruNext || sqlite3LruStatements.pFirst==p ){
-    sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
+    sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
     return;
   }
 
@@ -40823,7 +42451,7 @@
 
   assert( stmtLruCheck() );
 
-  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
 }
 
 /*
@@ -40856,9 +42484,9 @@
 ** statement is not currently part of the list, this call is a no-op.
 */
 static void stmtLruRemove(Vdbe *p){
-  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
   stmtLruRemoveNomutex(p);
-  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
 }
 
 /*
@@ -40870,7 +42498,7 @@
   Vdbe *pNext;
   int nFree = 0;
 
-  sqlite3_mutex_enter(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
+  sqlite3_mutex_enter(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
   for(p=sqlite3LruStatements.pFirst; p && nFree<n; p=pNext){
     pNext = p->pLruNext;
 
@@ -40885,7 +42513,7 @@
       sqlite3_mutex_leave(p->db->mutex);
     }
   }
-  sqlite3_mutex_leave(sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_LRU2));
+  sqlite3_mutex_leave(sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_LRU2));
 
   return nFree;
 }
@@ -41864,6 +43492,9 @@
   rc = vdbeUnbind(p, i);
   if( rc==SQLITE_OK ){
     rc = sqlite3VdbeMemCopy(&p->aVar[i-1], pValue);
+    if( rc==SQLITE_OK ){
+      rc = sqlite3VdbeChangeEncoding(&p->aVar[i-1], ENC(p->db));
+    }
   }
   rc = sqlite3ApiExit(p->db, rc);
   sqlite3_mutex_leave(p->db->mutex);
@@ -41987,6 +43618,24 @@
   return pStmt ? ((Vdbe*)pStmt)->db : 0;
 }
 
+/*
+** Return a pointer to the next prepared statement after pStmt associated
+** with database connection pDb.  If pStmt is NULL, return the first
+** prepared statement for the database connection.  Return NULL if there
+** are no more.
+*/
+SQLITE_API sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt){
+  sqlite3_stmt *pNext;
+  sqlite3_mutex_enter(pDb->mutex);
+  if( pStmt==0 ){
+    pNext = (sqlite3_stmt*)pDb->pVdbe;
+  }else{
+    pNext = (sqlite3_stmt*)((Vdbe*)pStmt)->pNext;
+  }
+  sqlite3_mutex_leave(pDb->mutex);
+  return pNext;
+}
+
 /************** End of vdbeapi.c *********************************************/
 /************** Begin file vdbe.c ********************************************/
 /*
@@ -42020,7 +43669,7 @@
 ** Computation results are stored on a set of registers numbered beginning
 ** with 1 and going up to Vdbe.nMem.  Each register can store
 ** either an integer, a null-terminated string, a floating point
-** number, or the SQL "NULL" value.  An inplicit conversion from one
+** number, or the SQL "NULL" value.  An implicit conversion from one
 ** type to the other occurs as necessary.
 ** 
 ** Most of the code in this file is taken up by the sqlite3VdbeExec()
@@ -42034,7 +43683,7 @@
 ** in this file for details.  If in doubt, do not deviate from existing
 ** commenting and indentation practices when changing or adding code.
 **
-** $Id: vdbe.c,v 1.740 2008/05/13 13:27:34 drh Exp $
+** $Id: vdbe.c,v 1.761 2008/07/11 21:02:54 drh Exp $
 */
 
 /*
@@ -42063,7 +43712,7 @@
 /*
 ** The next global variable is incremented each type the OP_Sort opcode
 ** is executed.  The test procedures use this information to make sure that
-** sorting is occurring or not occuring at appropriate times.   This variable
+** sorting is occurring or not occurring at appropriate times.   This variable
 ** has no function other than to help verify the correct operation of the
 ** library.
 */
@@ -42133,7 +43782,7 @@
 #define ExpandBlob(P) (((P)->flags&MEM_Zero)?sqlite3VdbeMemExpandBlob(P):0)
 
 /*
-** Argument pMem points at a regiser that will be passed to a
+** Argument pMem points at a register that will be passed to a
 ** user-defined function or returned to the user as the result of a query.
 ** The second argument, 'db_enc' is the text encoding used by the vdbe for
 ** register variables.  This routine sets the pMem->enc and pMem->type
@@ -42446,25 +44095,96 @@
 #endif
 
 #ifdef SQLITE_DEBUG
-#  define REGISTER_TRACE(R,M) if(p->trace&&R>0)registerTrace(p->trace,R,M)
+#  define REGISTER_TRACE(R,M) if(p->trace)registerTrace(p->trace,R,M)
 #else
 #  define REGISTER_TRACE(R,M)
 #endif
 
 
 #ifdef VDBE_PROFILE
+
+/* 
+** hwtime.h contains inline assembler code for implementing 
+** high-performance timing routines.
+*/
+/************** Include hwtime.h in the middle of vdbe.c *********************/
+/************** Begin file hwtime.h ******************************************/
+/*
+** 2008 May 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 contains inline asm code for retrieving "high-performance"
+** counters for x86 class CPUs.
+**
+** $Id: hwtime.h,v 1.2 2008/06/12 02:24:39 shane Exp $
+*/
+#ifndef _HWTIME_H_
+#define _HWTIME_H_
+
 /*
-** The following routine only works on pentium-class 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.
 */
-__inline__ unsigned long long int hwtime(void){
-   unsigned int lo, hi;
-   /* We cannot use "=A", since this would use %rax on x86_64 */
-   __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
-   return (unsigned long long int)hi << 32 | lo;
-}
+#if (defined(__GNUC__) || defined(_MSC_VER)) && \
+      (defined(i386) || defined(__i386__) || defined(_M_IX86))
+
+  #if defined(__GNUC__)
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+     unsigned int lo, hi;
+     __asm__ __volatile__ ("rdtsc" : "=a" (lo), "=d" (hi));
+     return (sqlite_uint64)hi << 32 | lo;
+  }
+
+  #elif defined(_MSC_VER)
+
+  __declspec(naked) __inline sqlite_uint64 __cdecl sqlite3Hwtime(void){
+     __asm {
+        rdtsc
+        ret       ; return value at EDX:EAX
+     }
+  }
+
+  #endif
+
+#elif (defined(__GNUC__) && defined(__x86_64__))
+
+  __inline__ sqlite_uint64 sqlite3Hwtime(void){
+      unsigned long val;
+      __asm__ __volatile__ ("rdtsc" : "=A" (val));
+      return val;
+  }
+ 
+#else
+
+  #error Need implementation of sqlite3Hwtime() for your platform.
+
+  /*
+  ** To compile without implementing sqlite3Hwtime() for your platform,
+  ** you can remove the above #error and use the following
+  ** stub function.  You will lose timing support for many
+  ** of the debugging and testing utilities, but it should at
+  ** least compile and run.
+  */
+SQLITE_PRIVATE   sqlite_uint64 sqlite3Hwtime(void){ return ((sqlite_uint64)0); }
+
+#endif
+
+#endif /* !defined(_HWTIME_H_) */
+
+/************** End of hwtime.h **********************************************/
+/************** Continuing where we left off in vdbe.c ***********************/
+
 #endif
 
 /*
@@ -42480,6 +44200,22 @@
 #define CHECK_FOR_INTERRUPT \
    if( db->u1.isInterrupted ) goto abort_due_to_interrupt;
 
+#ifdef SQLITE_DEBUG
+static int fileExists(sqlite3 *db, const char *zFile){
+  int res = 0;
+  int rc = SQLITE_OK;
+#ifdef SQLITE_TEST
+  /* If we are currently testing IO errors, then do not call OsAccess() to
+  ** test for the presence of zFile. This is because any IO error that
+  ** occurs here will not be reported, causing the test to fail.
+  */
+  extern int sqlite3_io_error_pending;
+  if( sqlite3_io_error_pending<=0 )
+#endif
+    rc = sqlite3OsAccess(db->pVfs, zFile, SQLITE_ACCESS_EXISTS, &res);
+  return (res && rc==SQLITE_OK);
+}
+#endif
 
 /*
 ** Execute as much of a VDBE program as we can then return.
@@ -42523,8 +44259,10 @@
   Mem *pIn1, *pIn2, *pIn3;   /* Input operands */
   Mem *pOut;                 /* Output operand */
   u8 opProperty;
+  int iCompare = 0;          /* Result of last OP_Compare operation */
+  int *aPermute = 0;         /* Permuation of columns for OP_Compare */
 #ifdef VDBE_PROFILE
-  unsigned long long start;  /* CPU clock count at start of opcode */
+  u64 start;                 /* CPU clock count at start of opcode */
   int origPc;                /* Program counter at start of opcode */
 #endif
 #ifndef SQLITE_OMIT_PROGRESS_CALLBACK
@@ -42547,9 +44285,9 @@
   CHECK_FOR_INTERRUPT;
   sqlite3VdbeIOTraceSql(p);
 #ifdef SQLITE_DEBUG
-  sqlite3FaultBeginBenign(-1);
-  if( p->pc==0 && ((p->db->flags & SQLITE_VdbeListing)!=0
-    || sqlite3OsAccess(db->pVfs, "vdbe_explain", SQLITE_ACCESS_EXISTS)==1 )
+  sqlite3BeginBenignMalloc();
+  if( p->pc==0 
+   && ((p->db->flags & SQLITE_VdbeListing) || fileExists(db, "vdbe_explain"))
   ){
     int i;
     printf("VDBE Program Listing:\n");
@@ -42558,17 +44296,17 @@
       sqlite3VdbePrintOp(stdout, i, &p->aOp[i]);
     }
   }
-  if( sqlite3OsAccess(db->pVfs, "vdbe_trace", SQLITE_ACCESS_EXISTS)==1 ){
+  if( fileExists(db, "vdbe_trace") ){
     p->trace = stdout;
   }
-  sqlite3FaultEndBenign(-1);
+  sqlite3EndBenignMalloc();
 #endif
   for(pc=p->pc; rc==SQLITE_OK; pc++){
     assert( pc>=0 && pc<p->nOp );
     if( db->mallocFailed ) goto no_mem;
 #ifdef VDBE_PROFILE
     origPc = pc;
-    start = hwtime();
+    start = sqlite3Hwtime();
 #endif
     pOp = &p->aOp[pc];
 
@@ -42583,11 +44321,11 @@
       sqlite3VdbePrintOp(p->trace, pc, pOp);
     }
     if( p->trace==0 && pc==0 ){
-      sqlite3FaultBeginBenign(-1);
-      if( sqlite3OsAccess(db->pVfs, "vdbe_sqltrace", SQLITE_ACCESS_EXISTS)==1 ){
+      sqlite3BeginBenignMalloc();
+      if( fileExists(db, "vdbe_sqltrace") ){
         sqlite3VdbePrintSql(p);
       }
-      sqlite3FaultEndBenign(-1);
+      sqlite3EndBenignMalloc();
     }
 #endif
       
@@ -42735,36 +44473,52 @@
   break;
 }
 
-/* Opcode:  Gosub * P2 * * *
+/* Opcode:  Gosub P1 P2 * * *
 **
-** Push the current address plus 1 onto the return address stack
+** Write the current address onto register P1
 ** and then jump to address P2.
-**
-** The return address stack is of limited depth.  If too many
-** OP_Gosub operations occur without intervening OP_Returns, then
-** the return address stack will fill up and processing will abort
-** with a fatal error.
 */
 case OP_Gosub: {            /* jump */
-  assert( p->returnDepth<sizeof(p->returnStack)/sizeof(p->returnStack[0]) );
-  p->returnStack[p->returnDepth++] = pc+1;
+  assert( pOp->p1>0 );
+  assert( pOp->p1<=p->nMem );
+  pIn1 = &p->aMem[pOp->p1];
+  assert( (pIn1->flags & MEM_Dyn)==0 );
+  pIn1->flags = MEM_Int;
+  pIn1->u.i = pc;
+  REGISTER_TRACE(pOp->p1, pIn1);
   pc = pOp->p2 - 1;
   break;
 }
 
-/* Opcode:  Return * * * * *
+/* Opcode:  Return P1 * * * *
+**
+** Jump to the next instruction after the address in register P1.
+*/
+case OP_Return: {           /* in1 */
+  assert( pIn1->flags & MEM_Int );
+  pc = pIn1->u.i;
+  break;
+}
+
+/* Opcode:  Yield P1 * * * *
 **
-** Jump immediately to the next instruction after the last unreturned
-** OP_Gosub.  If an OP_Return has occurred for all OP_Gosubs, then
-** processing aborts with a fatal error.
-*/
-case OP_Return: {
-  assert( p->returnDepth>0 );
-  p->returnDepth--;
-  pc = p->returnStack[p->returnDepth] - 1;
+** Swap the program counter with the value in register P1.
+*/
+case OP_Yield: {
+  int pcDest;
+  assert( pOp->p1>0 );
+  assert( pOp->p1<=p->nMem );
+  pIn1 = &p->aMem[pOp->p1];
+  assert( (pIn1->flags & MEM_Dyn)==0 );
+  pIn1->flags = MEM_Int;
+  pcDest = pIn1->u.i;
+  pIn1->u.i = pc;
+  REGISTER_TRACE(pOp->p1, pIn1);
+  pc = pcDest;
   break;
 }
 
+
 /* Opcode:  Halt P1 P2 * P4 *
 **
 ** Exit immediately.  All open cursors, Fifos, etc are closed
@@ -42789,7 +44543,7 @@
   p->pc = pc;
   p->errorAction = pOp->p2;
   if( pOp->p4.z ){
-    sqlite3SetString(&p->zErrMsg, pOp->p4.z, (char*)0);
+    sqlite3SetString(&p->zErrMsg, db, "%s", pOp->p4.z);
   }
   rc = sqlite3VdbeHalt(p);
   assert( rc==SQLITE_BUSY || rc==SQLITE_OK );
@@ -42918,7 +44672,7 @@
 **
 ** The value of variable P1 is written into register P2. A variable is
 ** an unknown in the original SQL string as handed to sqlite3_compile().
-** Any occurance of the '?' character in the original SQL is considered
+** Any occurrence of the '?' character in the original SQL is considered
 ** a variable.  Variables in the SQL string are number from left to
 ** right beginning with 1.  The values of variables are set using the
 ** sqlite3_bind() API.
@@ -42937,27 +44691,35 @@
   break;
 }
 
-/* Opcode: Move P1 P2 * * *
+/* Opcode: Move P1 P2 P3 * *
 **
-** Move the value in register P1 over into register P2.  Register P1
-** is left holding a NULL.  It is an error for P1 and P2 to be the
-** same register.
+** Move the values in register P1..P1+P3-1 over into
+** registers P2..P2+P3-1.  Registers P1..P1+P1-1 are
+** left holding a NULL.  It is an error for register ranges
+** P1..P1+P3-1 and P2..P2+P3-1 to overlap.
 */
 case OP_Move: {
   char *zMalloc;
-  assert( pOp->p1>0 );
-  assert( pOp->p1<=p->nMem );
-  pIn1 = &p->aMem[pOp->p1];
-  REGISTER_TRACE(pOp->p1, pIn1);
-  assert( pOp->p2>0 );
-  assert( pOp->p2<=p->nMem );
-  pOut = &p->aMem[pOp->p2];
-  assert( pOut!=pIn1 );
-  zMalloc = pOut->zMalloc;
-  pOut->zMalloc = 0;
-  sqlite3VdbeMemMove(pOut, pIn1);
-  pIn1->zMalloc = zMalloc;
-  REGISTER_TRACE(pOp->p2, pOut);
+  int n = pOp->p3;
+  int p1 = pOp->p1;
+  int p2 = pOp->p2;
+  assert( n>0 );
+  assert( p1>0 );
+  assert( p1+n<p->nMem );
+  pIn1 = &p->aMem[p1];
+  assert( p2>0 );
+  assert( p2+n<p->nMem );
+  pOut = &p->aMem[p2];
+  assert( p1+n<=p2 || p2+n<=p1 );
+  while( n-- ){
+    zMalloc = pOut->zMalloc;
+    pOut->zMalloc = 0;
+    sqlite3VdbeMemMove(pOut, pIn1);
+    pIn1->zMalloc = zMalloc;
+    REGISTER_TRACE(p2++, pOut);
+    pIn1++;
+    pOut++;
+  }
   break;
 }
 
@@ -42972,7 +44734,6 @@
   assert( pOp->p1>0 );
   assert( pOp->p1<=p->nMem );
   pIn1 = &p->aMem[pOp->p1];
-  REGISTER_TRACE(pOp->p1, pIn1);
   assert( pOp->p2>0 );
   assert( pOp->p2<=p->nMem );
   pOut = &p->aMem[pOp->p2];
@@ -43011,7 +44772,7 @@
 
 /* Opcode: ResultRow P1 P2 * * *
 **
-** The registers P1 throught P1+P2-1 contain a single row of
+** The registers P1 through P1+P2-1 contain a single row of
 ** results. This opcode causes the sqlite3_step() call to terminate
 ** with an SQLITE_ROW return code and it sets up the sqlite3_stmt
 ** structure to provide access to the top P1 values as the result
@@ -43028,13 +44789,14 @@
   p->cacheCtr = (p->cacheCtr + 2)|1;
 
   /* Make sure the results of the current row are \000 terminated
-  ** and have an assigned type.  The results are deephemeralized as
+  ** and have an assigned type.  The results are de-ephemeralized as
   ** as side effect.
   */
   pMem = p->pResultSet = &p->aMem[pOp->p1];
   for(i=0; i<pOp->p2; i++){
     sqlite3VdbeMemNulTerminate(&pMem[i]);
     storeTypeInfo(&pMem[i], encoding);
+    REGISTER_TRACE(pOp->p1+i, &pMem[i]);
   }
   if( db->mallocFailed ) goto no_mem;
 
@@ -43094,13 +44856,13 @@
 /* Opcode: Add P1 P2 P3 * *
 **
 ** Add the value in register P1 to the value in register P2
-** and store the result in regiser P3.
+** and store the result in register P3.
 ** If either input is NULL, the result is NULL.
 */
 /* Opcode: Multiply P1 P2 P3 * *
 **
 **
-** Multiply the value in regiser P1 by the value in regiser P2
+** Multiply the value in register P1 by the value in register P2
 ** and store the result in register P3.
 ** If either input is NULL, the result is NULL.
 */
@@ -43146,8 +44908,8 @@
         ** -1 returns an integer too large to store in a 64-bit data-type. On
         ** some architectures, the value overflows to (1<<63). On others,
         ** a SIGFPE is issued. The following statement normalizes this
-        ** behaviour so that all architectures behave as if integer 
-        ** overflow occured.
+        ** behavior so that all architectures behave as if integer 
+        ** overflow occurred.
         */
         if( a==-1 && b==SMALLEST_INT64 ) a = 1;
         b /= a;
@@ -43301,7 +45063,7 @@
     goto no_mem;
   }
 
-  /* If any auxilary data functions have been called by this user function,
+  /* If any auxiliary data functions have been called by this user function,
   ** immediately call the destructor for any non-static values.
   */
   if( ctx.pVdbeFunc ){
@@ -43312,7 +45074,7 @@
 
   /* If the function returned an error, throw an exception */
   if( ctx.isError ){
-    sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
     rc = ctx.isError;
   }
 
@@ -43379,7 +45141,7 @@
 
 /* Opcode: AddImm  P1 P2 * * *
 ** 
-** Add the constant P2 the value in register P1.
+** Add the constant P2 to the value in register P1.
 ** The result is always an integer.
 **
 ** To force any register to be an integer, just add 0.
@@ -43561,10 +45323,6 @@
 ** reg(P3) is NULL then take the jump.  If the SQLITE_JUMPIFNULL 
 ** bit is clear then fall thru if either operand is NULL.
 **
-** If the SQLITE_NULLEQUAL bit of P5 is set then treat NULL operands
-** as being equal to one another.  Normally NULLs are not equal to 
-** anything including other NULLs.
-**
 ** 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 
 ** to coerce both inputs according to this affinity before the
@@ -43625,41 +45383,21 @@
   int flags;
   int res;
   char affinity;
-  Mem x1, x3;
 
   flags = pIn1->flags|pIn3->flags;
 
   if( flags&MEM_Null ){
-    if( (pOp->p5 & SQLITE_NULLEQUAL)!=0 ){
-      /*
-      ** When SQLITE_NULLEQUAL set and either operand is NULL
-      ** then both operands are converted to integers prior to being 
-      ** passed down into the normal comparison logic below.  
-      ** NULL operands are converted to zero and non-NULL operands
-      ** are converted to 1.  Thus, for example, with SQLITE_NULLEQUAL
-      ** set,  NULL==NULL is true whereas it would normally NULL.
-      ** Similarly,  NULL!=123 is true.
-      */
-      x1.flags = MEM_Int;
-      x1.u.i = (pIn1->flags & MEM_Null)==0;
-      pIn1 = &x1;
-      x3.flags = MEM_Int;
-      x3.u.i = (pIn3->flags & MEM_Null)==0;
-      pIn3 = &x3;
-    }else{
-      /* If the SQLITE_NULLEQUAL bit is clear and either operand is NULL then
-      ** the result is always NULL.  The jump is taken if the 
-      ** SQLITE_JUMPIFNULL bit is set.
-      */
-      if( pOp->p5 & SQLITE_STOREP2 ){
-        pOut = &p->aMem[pOp->p2];
-        MemSetTypeFlag(pOut, MEM_Null);
-        REGISTER_TRACE(pOp->p2, pOut);
-      }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
-        pc = pOp->p2-1;
-      }
-      break;
+    /* If either operand is NULL then the result is always NULL.
+    ** The jump is taken if the SQLITE_JUMPIFNULL bit is set.
+    */
+    if( pOp->p5 & SQLITE_STOREP2 ){
+      pOut = &p->aMem[pOp->p2];
+      MemSetTypeFlag(pOut, MEM_Null);
+      REGISTER_TRACE(pOp->p2, pOut);
+    }else if( pOp->p5 & SQLITE_JUMPIFNULL ){
+      pc = pOp->p2-1;
     }
+    break;
   }
 
   affinity = pOp->p5 & SQLITE_AFF_MASK;
@@ -43692,6 +45430,82 @@
   break;
 }
 
+/* Opcode: Permutation * * * P4 *
+**
+** Set the permuation used by the OP_Compare operator to be the array
+** of integers in P4.
+**
+** The permutation is only valid until the next OP_Permutation, OP_Compare,
+** OP_Halt, or OP_ResultRow.  Typically the OP_Permutation should occur
+** immediately prior to the OP_Compare.
+*/
+case OP_Permutation: {
+  assert( pOp->p4type==P4_INTARRAY );
+  assert( pOp->p4.ai );
+  aPermute = pOp->p4.ai;
+  break;
+}
+
+/* Opcode: Compare P1 P2 P3 P4 *
+**
+** Compare to vectors of registers in reg(P1)..reg(P1+P3-1) (all this
+** one "A") and in reg(P2)..reg(P2+P3-1) ("B").  Save the result of
+** the comparison for use by the next OP_Jump instruct.
+**
+** P4 is a KeyInfo structure that defines collating sequences and sort
+** orders for the comparison.  The permutation applies to registers
+** only.  The KeyInfo elements are used sequentially.
+**
+** 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.
+*/
+case OP_Compare: {
+  int n = pOp->p3;
+  int i, p1, p2;
+  const KeyInfo *pKeyInfo = pOp->p4.pKeyInfo;
+  assert( n>0 );
+  assert( pKeyInfo!=0 );
+  p1 = pOp->p1;
+  assert( p1>0 && p1+n-1<p->nMem );
+  p2 = pOp->p2;
+  assert( p2>0 && p2+n-1<p->nMem );
+  for(i=0; i<n; i++){
+    int idx = aPermute ? aPermute[i] : i;
+    CollSeq *pColl;    /* Collating sequence to use on this term */
+    int bRev;          /* True for DESCENDING sort order */
+    REGISTER_TRACE(p1+idx, &p->aMem[p1+idx]);
+    REGISTER_TRACE(p2+idx, &p->aMem[p2+idx]);
+    assert( i<pKeyInfo->nField );
+    pColl = pKeyInfo->aColl[i];
+    bRev = pKeyInfo->aSortOrder[i];
+    iCompare = sqlite3MemCompare(&p->aMem[p1+idx], &p->aMem[p2+idx], pColl);
+    if( iCompare ){
+      if( bRev ) iCompare = -iCompare;
+      break;
+    }
+  }
+  aPermute = 0;
+  break;
+}
+
+/* Opcode: Jump P1 P2 P3 * *
+**
+** Jump to the instruction at address P1, P2, or P3 depending on whether
+** in the most recent OP_Compare instruction the P1 vector was less than
+** equal to, or greater than the P2 vector, respectively.
+*/
+case OP_Jump: {             /* jump */
+  if( iCompare<0 ){
+    pc = pOp->p1 - 1;
+  }else if( iCompare==0 ){
+    pc = pOp->p2 - 1;
+  }else{
+    pc = pOp->p3 - 1;
+  }
+  break;
+}
+
 /* Opcode: And P1 P2 P3 * *
 **
 ** Take the logical AND of the values in registers P1 and P2 and
@@ -44132,7 +45946,7 @@
 **
 ** Convert P2 registers beginning with P1 into a single entry
 ** suitable for use as a data record in a database table or as a key
-** in an index.  The details of the format are irrelavant as long as
+** in an index.  The details of the format are irrelevant as long as
 ** the OP_Column opcode can decode the record later.
 ** Refer to source code comments for the details of the record
 ** format.
@@ -44317,8 +46131,9 @@
     ** still running, and a transaction is active, return an error indicating
     ** that the other VMs must complete first. 
     */
-    sqlite3SetString(&p->zErrMsg, "cannot ", rollback?"rollback":"commit", 
-        " transaction - SQL statements in progress", (char*)0);
+    sqlite3SetString(&p->zErrMsg, db, "cannot %s transaction - "
+        "SQL statements in progress",
+        rollback ? "rollback" : "commit");
     rc = SQLITE_ERROR;
   }else if( i!=db->autoCommit ){
     if( pOp->p2 ){
@@ -44341,10 +46156,10 @@
     }
     goto vdbe_return;
   }else{
-    sqlite3SetString(&p->zErrMsg,
+    sqlite3SetString(&p->zErrMsg, db,
         (!i)?"cannot start a transaction within a transaction":(
         (rollback)?"cannot rollback - no transaction is active":
-                   "cannot commit - no transaction is active"), (char*)0);
+                   "cannot commit - no transaction is active"));
          
     rc = SQLITE_ERROR;
   }
@@ -44509,7 +46324,7 @@
     ** stored with the in-memory representation of the schema, do
     ** not reload the schema from the database file.
     **
-    ** If virtual-tables are in use, this is not just an optimisation.
+    ** If virtual-tables are in use, this is not just an optimization.
     ** Often, v-tables store their data in other SQLite tables, which
     ** are queried from within xNext() and other v-table methods using
     ** prepared queries. If such a query is out-of-date, we do not want to
@@ -44625,7 +46440,7 @@
     case SQLITE_OK: {
       int flags = sqlite3BtreeFlags(pCur->pCursor);
       /* Sanity checking.  Only the lower four bits of the flags byte should
-      ** be used.  Bit 3 (mask 0x08) is unpreditable.  The lower 3 bits
+      ** be used.  Bit 3 (mask 0x08) is unpredictable.  The lower 3 bits
       ** (mask 0x07) should be either 5 (intkey+leafdata for tables) or
       ** 2 (zerodata for indices).  If these conditions are not met it can
       ** only mean that we are dealing with a corrupt database file
@@ -44911,6 +46726,12 @@
     if( res ){
       pc = pOp->p2 - 1;
     }
+  }else if( !pC->pseudoTable ){
+    /* This happens when attempting to open the sqlite3_master table
+    ** for read access returns SQLITE_EMPTY. In this case always
+    ** take the jump (since there are no records in the table).
+    */
+    pc = pOp->p2 - 1;
   }
   break;
 }
@@ -44930,7 +46751,7 @@
 ** DISTINCT keyword in SELECT statements.
 **
 ** This instruction checks if index P1 contains a record for which 
-** the first N serialised values exactly match the N serialised values
+** the first N serialized values exactly match the N serialized values
 ** in the record in register P3, where N is the total number of values in
 ** the P3 record (the P3 record is a prefix of the P1 record). 
 **
@@ -45118,6 +46939,13 @@
       pc = pOp->p2 - 1;
       assert( pC->rowidIsValid==0 );
     }
+  }else if( !pC->pseudoTable ){
+    /* This happens when an attempt to open a read cursor on the 
+    ** sqlite_master table returns SQLITE_EMPTY.
+    */
+    assert( pC->isTable );
+    pc = pOp->p2 - 1;
+    assert( pC->rowidIsValid==0 );
   }
   break;
 }
@@ -45189,7 +47017,7 @@
     ** random number generator based on the RC4 algorithm.
     **
     ** To promote locality of reference for repetitive inserts, the
-    ** first few attempts at chosing a random rowid pick values just a little
+    ** first few attempts at choosing a random rowid pick values just a little
     ** larger than the previous rowid.  This has been shown experimentally
     ** to double the speed of the COPY operation.
     */
@@ -45360,7 +47188,7 @@
         pData->zMalloc = 0;
       }
     }else{
-      pC->pData = sqlite3_malloc( pC->nData+2 );
+      pC->pData = sqlite3Malloc( pC->nData+2 );
       if( !pC->pData ) goto no_mem;
       memcpy(pC->pData, pData->z, pC->nData);
       pC->pData[pC->nData] = 0;
@@ -45539,7 +47367,7 @@
 /* Opcode: Rowid P1 P2 * * *
 **
 ** Store in register P2 an integer which is the key of the table entry that
-** P1 is currently point to.  If p2==0 then push the integer.
+** P1 is currently point to.
 */
 case OP_Rowid: {                 /* out2-prerelease */
   int i = pOp->p1;
@@ -45692,6 +47520,7 @@
 case OP_Next: {        /* jump */
   Cursor *pC;
   BtCursor *pCrsr;
+  int res;
 
   CHECK_FOR_INTERRUPT;
   assert( pOp->p1>=0 && pOp->p1<p->nCursor );
@@ -45701,19 +47530,17 @@
   }
   pCrsr = pC->pCursor;
   assert( pCrsr );
-  if( pC->nullRow==0 ){
-    int res = 1;
-    assert( pC->deferredMoveto==0 );
-    rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
-                                sqlite3BtreePrevious(pCrsr, &res);
-    pC->nullRow = res;
-    pC->cacheStatus = CACHE_STALE;
-    if( res==0 ){
-      pc = pOp->p2 - 1;
+  res = 1;
+  assert( pC->deferredMoveto==0 );
+  rc = pOp->opcode==OP_Next ? sqlite3BtreeNext(pCrsr, &res) :
+                              sqlite3BtreePrevious(pCrsr, &res);
+  pC->nullRow = res;
+  pC->cacheStatus = CACHE_STALE;
+  if( res==0 ){
+    pc = pOp->p2 - 1;
 #ifdef SQLITE_TEST
-      sqlite3_search_count++;
+    sqlite3_search_count++;
 #endif
-    }
   }
   pC->rowidIsValid = 0;
   break;
@@ -46002,7 +47829,7 @@
 ** schema is already loaded into the symbol table.
 **
 ** This opcode invokes the parser to create a new virtual machine,
-** then runs the new virtual machine.  It is thus a reentrant opcode.
+** then runs the new virtual machine.  It is thus a re-entrant opcode.
 */
 case OP_ParseSchema: {
   char *zSql;
@@ -46120,7 +47947,7 @@
   
   nRoot = pOp->p2;
   assert( nRoot>0 );
-  aRoot = sqlite3_malloc( sizeof(int)*(nRoot+1) );
+  aRoot = sqlite3Malloc( sizeof(int)*(nRoot+1) );
   if( aRoot==0 ) goto no_mem;
   assert( pOp->p3>0 && pOp->p3<=p->nMem );
   pnErr = &p->aMem[pOp->p3];
@@ -46330,7 +48157,7 @@
   }
   (ctx.pFunc->xStep)(&ctx, n, apVal);
   if( ctx.isError ){
-    sqlite3SetString(&p->zErrMsg, sqlite3_value_text(&ctx.s), (char*)0);
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(&ctx.s));
     rc = ctx.isError;
   }
   sqlite3VdbeMemRelease(&ctx.s);
@@ -46356,7 +48183,7 @@
   assert( (pMem->flags & ~(MEM_Null|MEM_Agg))==0 );
   rc = sqlite3VdbeMemFinalize(pMem, pOp->p4.pFunc);
   if( rc==SQLITE_ERROR ){
-    sqlite3SetString(&p->zErrMsg, sqlite3_value_text(pMem), (char*)0);
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3_value_text(pMem));
   }
   sqlite3VdbeChangeEncoding(pMem, encoding);
   UPDATE_MAX_BLOBSIZE(pMem);
@@ -46446,7 +48273,7 @@
   rc = sqlite3BtreeLockTable(db->aDb[p1].pBt, pOp->p2, isWriteLock);
   if( rc==SQLITE_LOCKED ){
     const char *z = pOp->p4.z;
-    sqlite3SetString(&p->zErrMsg, "database table is locked: ", z, (char*)0);
+    sqlite3SetString(&p->zErrMsg, db, "database table is locked: %s", z);
   }
   break;
 }
@@ -46509,7 +48336,7 @@
   rc = pModule->xOpen(pVtab, &pVtabCursor);
   if( sqlite3SafetyOn(db) ) goto abort_due_to_misuse;
   if( SQLITE_OK==rc ){
-    /* Initialise sqlite3_vtab_cursor base class */
+    /* Initialize sqlite3_vtab_cursor base class */
     pVtabCursor->pVtab = pVtab;
 
     /* Initialise vdbe cursor object */
@@ -46539,8 +48366,8 @@
 ** This opcode invokes the xFilter method on the virtual table specified
 ** by P1.  The integer query plan parameter to xFilter is stored in register
 ** P3. Register P3+1 stores the argc parameter to be passed to the
-** xFilter method. Registers P3+2..P3+1+argc are the argc additional
-** parametersneath additional parameters which are passed to
+** xFilter method. Registers P3+2..P3+1+argc are the argc
+** additional parameters which are passed to
 ** xFilter as argv. Register P3+2 becomes argv[0] when passed to xFilter.
 **
 ** A jump is made to P2 if the result set after filtering would be empty.
@@ -46769,7 +48596,7 @@
   int nArg = pOp->p2;
   assert( pOp->p4type==P4_VTAB );
   if( pModule->xUpdate==0 ){
-    sqlite3SetString(&p->zErrMsg, "read-only table", 0);
+    sqlite3SetString(&p->zErrMsg, db, "read-only table");
     rc = SQLITE_ERROR;
   }else{
     int i;
@@ -46796,6 +48623,25 @@
 }
 #endif /* SQLITE_OMIT_VIRTUALTABLE */
 
+#ifndef  SQLITE_OMIT_PAGER_PRAGMAS
+/* Opcode: Pagecount P1 P2 * * *
+**
+** Write the current number of pages in database P1 to memory cell P2.
+*/
+case OP_Pagecount: {            /* out2-prerelease */
+  int p1 = pOp->p1; 
+  int nPage;
+  Pager *pPager = sqlite3BtreePager(db->aDb[p1].pBt);
+
+  rc = sqlite3PagerPagecount(pPager, &nPage);
+  if( rc==SQLITE_OK ){
+    pOut->flags = MEM_Int;
+    pOut->u.i = nPage;
+  }
+  break;
+}
+#endif
+
 #ifndef SQLITE_OMIT_TRACE
 /* Opcode: Trace * * * P4 *
 **
@@ -46843,11 +48689,11 @@
 
 #ifdef VDBE_PROFILE
     {
-      long long elapse = hwtime() - start;
-      pOp->cycles += elapse;
+      u64 elapsed = sqlite3Hwtime() - start;
+      pOp->cycles += elapsed;
       pOp->cnt++;
 #if 0
-        fprintf(stdout, "%10lld ", elapse);
+        fprintf(stdout, "%10llu ", elapsed);
         sqlite3VdbePrintOp(stdout, origPc, &p->aOp[origPc]);
 #endif
     }
@@ -46881,8 +48727,9 @@
 vdbe_error_halt:
   assert( rc );
   p->rc = rc;
-  rc = SQLITE_ERROR;
   sqlite3VdbeHalt(p);
+  if( rc==SQLITE_IOERR_NOMEM ) db->mallocFailed = 1;
+  rc = SQLITE_ERROR;
 
   /* This is the only way out of this procedure.  We have to
   ** release the mutexes on btrees that were acquired at the
@@ -46895,7 +48742,7 @@
   ** is encountered.
   */
 too_big:
-  sqlite3SetString(&p->zErrMsg, "string or blob too big", (char*)0);
+  sqlite3SetString(&p->zErrMsg, db, "string or blob too big");
   rc = SQLITE_TOOBIG;
   goto vdbe_error_halt;
 
@@ -46903,7 +48750,7 @@
   */
 no_mem:
   db->mallocFailed = 1;
-  sqlite3SetString(&p->zErrMsg, "out of memory", (char*)0);
+  sqlite3SetString(&p->zErrMsg, db, "out of memory");
   rc = SQLITE_NOMEM;
   goto vdbe_error_halt;
 
@@ -46919,7 +48766,9 @@
 abort_due_to_error:
   assert( p->zErrMsg==0 );
   if( db->mallocFailed ) rc = SQLITE_NOMEM;
-  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
+  if( rc!=SQLITE_IOERR_NOMEM ){
+    sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
+  }
   goto vdbe_error_halt;
 
   /* Jump to here if the sqlite3_interrupt() API sets the interrupt
@@ -46929,7 +48778,7 @@
   assert( db->u1.isInterrupted );
   rc = SQLITE_INTERRUPT;
   p->rc = rc;
-  sqlite3SetString(&p->zErrMsg, sqlite3ErrStr(rc), (char*)0);
+  sqlite3SetString(&p->zErrMsg, db, "%s", sqlite3ErrStr(rc));
   goto vdbe_error_halt;
 }
 
@@ -46949,7 +48798,7 @@
 **
 ** This file contains code used to implement incremental BLOB I/O.
 **
-** $Id: vdbeblob.c,v 1.22 2008/04/24 09:49:55 danielk1977 Exp $
+** $Id: vdbeblob.c,v 1.24 2008/07/10 00:32:42 drh Exp $
 */
 
 
@@ -47031,10 +48880,9 @@
     memset(&sParse, 0, sizeof(Parse));
     sParse.db = db;
 
-    rc = sqlite3SafetyOn(db);
-    if( rc!=SQLITE_OK ){
+    if( sqlite3SafetyOn(db) ){
       sqlite3_mutex_leave(db->mutex);
-      return rc;
+      return SQLITE_MISUSE;
     }
 
     sqlite3BtreeEnterAll(db);
@@ -47126,6 +48974,7 @@
       ** and offset cache without causing any IO.
       */
       sqlite3VdbeChangeP2(v, flags ? 4 : 2, pTab->nCol+1);
+      sqlite3VdbeChangeP2(v, 8, pTab->nCol);
       if( !db->mallocFailed ){
         sqlite3VdbeMakeReady(v, 1, 1, 1, 0);
       }
@@ -47539,7 +49388,7 @@
 ** This file contains routines used for analyzing expressions and
 ** for generating VDBE code that evaluates expressions in SQLite.
 **
-** $Id: expr.c,v 1.371 2008/05/01 17:16:53 drh Exp $
+** $Id: expr.c,v 1.385 2008/07/09 01:39:44 drh Exp $
 */
 
 /*
@@ -47771,13 +49620,108 @@
   addr = sqlite3VdbeAddOp4(pParse->pVdbe, opcode, in2, dest, in1,
                            (void*)p4, P4_COLLSEQ);
   sqlite3VdbeChangeP5(pParse->pVdbe, p5);
-  if( p5 & SQLITE_AFF_MASK ){
+  if( (p5 & SQLITE_AFF_MASK)!=SQLITE_AFF_NONE ){
     sqlite3ExprCacheAffinityChange(pParse, in1, 1);
     sqlite3ExprCacheAffinityChange(pParse, in2, 1);
   }
   return addr;
 }
 
+#if SQLITE_MAX_EXPR_DEPTH>0
+/*
+** Check that argument nHeight is less than or equal to the maximum
+** expression depth allowed. If it is not, leave an error message in
+** pParse.
+*/
+static int checkExprHeight(Parse *pParse, int nHeight){
+  int rc = SQLITE_OK;
+  int mxHeight = pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
+  if( nHeight>mxHeight ){
+    sqlite3ErrorMsg(pParse, 
+       "Expression tree is too large (maximum depth %d)", mxHeight
+    );
+    rc = SQLITE_ERROR;
+  }
+  return rc;
+}
+
+/* The following three functions, heightOfExpr(), heightOfExprList()
+** and heightOfSelect(), are used to determine the maximum height
+** of any expression tree referenced by the structure passed as the
+** first argument.
+**
+** If this maximum height is greater than the current value pointed
+** to by pnHeight, the second parameter, then set *pnHeight to that
+** value.
+*/
+static void heightOfExpr(Expr *p, int *pnHeight){
+  if( p ){
+    if( p->nHeight>*pnHeight ){
+      *pnHeight = p->nHeight;
+    }
+  }
+}
+static void heightOfExprList(ExprList *p, int *pnHeight){
+  if( p ){
+    int i;
+    for(i=0; i<p->nExpr; i++){
+      heightOfExpr(p->a[i].pExpr, pnHeight);
+    }
+  }
+}
+static void heightOfSelect(Select *p, int *pnHeight){
+  if( p ){
+    heightOfExpr(p->pWhere, pnHeight);
+    heightOfExpr(p->pHaving, pnHeight);
+    heightOfExpr(p->pLimit, pnHeight);
+    heightOfExpr(p->pOffset, pnHeight);
+    heightOfExprList(p->pEList, pnHeight);
+    heightOfExprList(p->pGroupBy, pnHeight);
+    heightOfExprList(p->pOrderBy, pnHeight);
+    heightOfSelect(p->pPrior, pnHeight);
+  }
+}
+
+/*
+** 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 
+** referenced Expr plus one.
+*/
+static void exprSetHeight(Expr *p){
+  int nHeight = 0;
+  heightOfExpr(p->pLeft, &nHeight);
+  heightOfExpr(p->pRight, &nHeight);
+  heightOfExprList(p->pList, &nHeight);
+  heightOfSelect(p->pSelect, &nHeight);
+  p->nHeight = nHeight + 1;
+}
+
+/*
+** Set the Expr.nHeight variable using the exprSetHeight() function. If
+** the height is greater than the maximum allowed expression depth,
+** leave an error in pParse.
+*/
+SQLITE_PRIVATE void sqlite3ExprSetHeight(Parse *pParse, Expr *p){
+  exprSetHeight(p);
+  checkExprHeight(pParse, p->nHeight);
+}
+
+/*
+** Return the maximum height of any expression tree referenced
+** by the select statement passed as an argument.
+*/
+SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
+  int nHeight = 0;
+  heightOfSelect(p, &nHeight);
+  return nHeight;
+}
+#else
+  #define checkExprHeight(x,y)
+  #define exprSetHeight(y)
+#endif /* SQLITE_MAX_EXPR_DEPTH>0 */
+
 /*
 ** Construct a new expression node and return a pointer to it.  Memory
 ** for this node is obtained from sqlite3_malloc().  The calling function
@@ -47805,12 +49749,15 @@
   pNew->pLeft = pLeft;
   pNew->pRight = pRight;
   pNew->iAgg = -1;
+  pNew->span.z = (u8*)"";
   if( pToken ){
     assert( pToken->dyn==0 );
     pNew->span = pNew->token = *pToken;
   }else if( pLeft ){
     if( pRight ){
-      sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
+      if( pRight->span.dyn==0 && pLeft->span.dyn==0 ){
+        sqlite3ExprSpan(pNew, &pLeft->span, &pRight->span);
+      }
       if( pRight->flags & EP_ExpCollate ){
         pNew->flags |= EP_ExpCollate;
         pNew->pColl = pRight->pColl;
@@ -47822,7 +49769,7 @@
     }
   }
 
-  sqlite3ExprSetHeight(pNew);
+  exprSetHeight(pNew);
   return pNew;
 }
 
@@ -47837,7 +49784,11 @@
   Expr *pRight,           /* Right operand */
   const Token *pToken     /* Argument token */
 ){
-  return sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
+  Expr *p = sqlite3Expr(pParse->db, op, pLeft, pRight, pToken);
+  if( p ){
+    checkExprHeight(pParse, p->nHeight);
+  }
+  return p;
 }
 
 /*
@@ -47882,19 +49833,15 @@
 
 /*
 ** Set the Expr.span field of the given expression to span all
-** text between the two given tokens.
+** text between the two given tokens.  Both tokens must be pointing
+** at the same string.
 */
 SQLITE_PRIVATE void sqlite3ExprSpan(Expr *pExpr, Token *pLeft, Token *pRight){
   assert( pRight!=0 );
   assert( pLeft!=0 );
   if( pExpr && pRight->z && pLeft->z ){
-    assert( pLeft->dyn==0 || pLeft->z[pLeft->n]==0 );
-    if( pLeft->dyn==0 && pRight->dyn==0 ){
-      pExpr->span.z = pLeft->z;
-      pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
-    }else{
-      pExpr->span.z = 0;
-    }
+    pExpr->span.z = pLeft->z;
+    pExpr->span.n = pRight->n + (pRight->z - pLeft->z);
   }
 }
 
@@ -47916,7 +49863,7 @@
   pNew->token = *pToken;
   pNew->span = pNew->token;
 
-  sqlite3ExprSetHeight(pNew);
+  sqlite3ExprSetHeight(pParse, pNew);
   return pNew;
 }
 
@@ -48182,8 +50129,8 @@
   pNew->pPrior = sqlite3SelectDup(db, p->pPrior);
   pNew->pLimit = sqlite3ExprDup(db, p->pLimit);
   pNew->pOffset = sqlite3ExprDup(db, p->pOffset);
-  pNew->iLimit = -1;
-  pNew->iOffset = -1;
+  pNew->iLimit = 0;
+  pNew->iOffset = 0;
   pNew->isResolved = p->isResolved;
   pNew->isAgg = p->isAgg;
   pNew->usesEphm = 0;
@@ -48263,70 +50210,6 @@
   }
 }
 
-
-/* The following three functions, heightOfExpr(), heightOfExprList()
-** and heightOfSelect(), are used to determine the maximum height
-** of any expression tree referenced by the structure passed as the
-** first argument.
-**
-** If this maximum height is greater than the current value pointed
-** to by pnHeight, the second parameter, then set *pnHeight to that
-** value.
-*/
-static void heightOfExpr(Expr *p, int *pnHeight){
-  if( p ){
-    if( p->nHeight>*pnHeight ){
-      *pnHeight = p->nHeight;
-    }
-  }
-}
-static void heightOfExprList(ExprList *p, int *pnHeight){
-  if( p ){
-    int i;
-    for(i=0; i<p->nExpr; i++){
-      heightOfExpr(p->a[i].pExpr, pnHeight);
-    }
-  }
-}
-static void heightOfSelect(Select *p, int *pnHeight){
-  if( p ){
-    heightOfExpr(p->pWhere, pnHeight);
-    heightOfExpr(p->pHaving, pnHeight);
-    heightOfExpr(p->pLimit, pnHeight);
-    heightOfExpr(p->pOffset, pnHeight);
-    heightOfExprList(p->pEList, pnHeight);
-    heightOfExprList(p->pGroupBy, pnHeight);
-    heightOfExprList(p->pOrderBy, pnHeight);
-    heightOfSelect(p->pPrior, pnHeight);
-  }
-}
-
-/*
-** 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 
-** referenced Expr plus one.
-*/
-SQLITE_PRIVATE void sqlite3ExprSetHeight(Expr *p){
-  int nHeight = 0;
-  heightOfExpr(p->pLeft, &nHeight);
-  heightOfExpr(p->pRight, &nHeight);
-  heightOfExprList(p->pList, &nHeight);
-  heightOfSelect(p->pSelect, &nHeight);
-  p->nHeight = nHeight + 1;
-}
-
-/*
-** Return the maximum height of any expression tree referenced
-** by the select statement passed as an argument.
-*/
-SQLITE_PRIVATE int sqlite3SelectExprHeight(Select *p){
-  int nHeight = 0;
-  heightOfSelect(p, &nHeight);
-  return nHeight;
-}
-
 /*
 ** Delete an entire expression list.
 */
@@ -48508,27 +50391,36 @@
 ** to fit in a signed 32-bit integer, return 0 and leave *pValue unchanged.
 */
 SQLITE_PRIVATE int sqlite3ExprIsInteger(Expr *p, int *pValue){
+  int rc = 0;
+  if( p->flags & EP_IntValue ){
+    *pValue = p->iTable;
+    return 1;
+  }
   switch( p->op ){
     case TK_INTEGER: {
-      if( sqlite3GetInt32((char*)p->token.z, pValue) ){
-        return 1;
-      }
+      rc = sqlite3GetInt32((char*)p->token.z, pValue);
       break;
     }
     case TK_UPLUS: {
-      return sqlite3ExprIsInteger(p->pLeft, pValue);
+      rc = sqlite3ExprIsInteger(p->pLeft, pValue);
+      break;
     }
     case TK_UMINUS: {
       int v;
       if( sqlite3ExprIsInteger(p->pLeft, &v) ){
         *pValue = -v;
-        return 1;
+        rc = 1;
       }
       break;
     }
     default: break;
   }
-  return 0;
+  if( rc ){
+    p->op = TK_INTEGER;
+    p->flags |= EP_IntValue;
+    p->iTable = *pValue;
+  }
+  return rc;
 }
 
 /*
@@ -49056,11 +50948,7 @@
   if( pExpr==0 ) return 0;
 #if SQLITE_MAX_EXPR_DEPTH>0
   {
-    int mxDepth = pNC->pParse->db->aLimit[SQLITE_LIMIT_EXPR_DEPTH];
-    if( (pExpr->nHeight+pNC->pParse->nHeight)>mxDepth ){
-      sqlite3ErrorMsg(pNC->pParse, 
-         "Expression tree is too large (maximum depth %d)", mxDepth
-      );
+    if( checkExprHeight(pNC->pParse, pExpr->nHeight + pNC->pParse->nHeight) ){
       return 1;
     }
     pNC->pParse->nHeight += pExpr->nHeight;
@@ -49158,22 +51046,46 @@
 **
 **     SELECT <column> FROM <table>
 **
-** If the mustBeUnique parameter is false, the structure will be used 
-** for fast set membership tests. In this case an epheremal table must 
-** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
-** be found with <column> as its left-most column.
-**
-** If mustBeUnique is true, then the structure will be used to iterate
+** If prNotFound parameter is 0, then the structure will be used to iterate
 ** through the set members, skipping any duplicates. In this case an
 ** epheremal table must be used unless the selected <column> is guaranteed
 ** to be unique - either because it is an INTEGER PRIMARY KEY or it
 ** is unique by virtue of a constraint or implicit index.
+**
+** If the prNotFound parameter is not 0, then the structure will be used 
+** for fast set membership tests. In this case an epheremal table must 
+** be used unless <column> is an INTEGER PRIMARY KEY or an index can 
+** be found with <column> as its left-most column.
+**
+** When the structure is being used for set membership tests, the user
+** needs to know whether or not the structure contains an SQL NULL 
+** value in order to correctly evaluate expressions like "X IN (Y, Z)".
+** If there is a chance that the structure may contain a NULL value at
+** runtime, then a register is allocated and the register number written
+** to *prNotFound. If there is no chance that the structure contains a
+** NULL value, then *prNotFound is left unchanged.
+**
+** If a register is allocated and its location stored in *prNotFound, then
+** its initial value is NULL. If the structure does not remain constant
+** for the duration of the query (i.e. the set is a correlated sub-select), 
+** the value of the allocated register is reset to NULL each time the 
+** structure is repopulated. This allows the caller to use vdbe code 
+** equivalent to the following:
+**
+**   if( register==NULL ){
+**     has_null = <test if data structure contains null>
+**     register = 1
+**   }
+**
+** in order to avoid running the <test if data structure contains null>
+** test more often than is necessary.
 */
 #ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int mustBeUnique){
+SQLITE_PRIVATE int sqlite3FindInIndex(Parse *pParse, Expr *pX, int *prNotFound){
   Select *p;
   int eType = 0;
   int iTab = pParse->nTab++;
+  int mustBeUnique = !prNotFound;
 
   /* The follwing if(...) expression is true if the SELECT is of the 
   ** simple form:
@@ -49249,13 +51161,20 @@
           eType = IN_INDEX_INDEX;
 
           sqlite3VdbeJumpHere(v, iAddr);
+          if( prNotFound && !pTab->aCol[iCol].notNull ){
+            *prNotFound = ++pParse->nMem;
+          }
         }
       }
     }
   }
 
   if( eType==0 ){
-    sqlite3CodeSubselect(pParse, pX);
+    int rMayHaveNull = 0;
+    if( prNotFound ){
+      *prNotFound = rMayHaveNull = ++pParse->nMem;
+    }
+    sqlite3CodeSubselect(pParse, pX, rMayHaveNull);
     eType = IN_INDEX_EPH;
   }else{
     pX->iTable = iTab;
@@ -49277,7 +51196,7 @@
 ** operator or subquery.
 */
 #ifndef SQLITE_OMIT_SUBQUERY
-SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr){
+SQLITE_PRIVATE void sqlite3CodeSubselect(Parse *pParse, Expr *pExpr, int rMayHaveNull){
   int testAddr = 0;                       /* One-time test address */
   Vdbe *v = sqlite3GetVdbe(pParse);
   if( v==0 ) return;
@@ -49306,6 +51225,10 @@
       KeyInfo keyInfo;
       int addr;        /* Address of OP_OpenEphemeral instruction */
 
+      if( rMayHaveNull ){
+        sqlite3VdbeAddOp2(v, OP_Null, 0, rMayHaveNull);
+      }
+
       affinity = sqlite3ExprAffinity(pExpr->pLeft);
 
       /* Whether this is an 'x IN(SELECT...)' or an 'x IN(<exprlist>)'
@@ -49338,7 +51261,7 @@
         sqlite3SelectDestInit(&dest, SRT_Set, pExpr->iTable);
         dest.affinity = (int)affinity;
         assert( (pExpr->iTable&0x0000FFFF)==pExpr->iTable );
-        if( sqlite3Select(pParse, pExpr->pSelect, &dest, 0, 0, 0, 0) ){
+        if( sqlite3Select(pParse, pExpr->pSelect, &dest, 0, 0, 0) ){
           return;
         }
         pEList = pExpr->pSelect->pEList;
@@ -49357,7 +51280,7 @@
         int i;
         ExprList *pList = pExpr->pList;
         struct ExprList_item *pItem;
-        int r1, r2;
+        int r1, r2, r3;
 
         if( !affinity ){
           affinity = SQLITE_AFF_NONE;
@@ -49382,11 +51305,11 @@
 
           /* Evaluate the expression and insert it into the temp table */
           pParse->disableColCache++;
-          sqlite3ExprCode(pParse, pE2, r1);
+          r3 = sqlite3ExprCodeTarget(pParse, pE2, r1);
           assert( pParse->disableColCache>0 );
           pParse->disableColCache--;
-          sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
-          sqlite3ExprCacheAffinityChange(pParse, r1, 1);
+          sqlite3VdbeAddOp4(v, OP_MakeRecord, r3, 1, r2, &affinity, 1);
+          sqlite3ExprCacheAffinityChange(pParse, r3, 1);
           sqlite3VdbeAddOp2(v, OP_IdxInsert, pExpr->iTable, r2);
         }
         sqlite3ReleaseTempReg(pParse, r1);
@@ -49419,7 +51342,7 @@
       }
       sqlite3ExprDelete(pSel->pLimit);
       pSel->pLimit = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, &one);
-      if( sqlite3Select(pParse, pSel, &dest, 0, 0, 0, 0) ){
+      if( sqlite3Select(pParse, pSel, &dest, 0, 0, 0) ){
         return;
       }
       pExpr->iColumn = dest.iParm;
@@ -49480,10 +51403,15 @@
 ** z[n] character is guaranteed to be something that does not look
 ** like the continuation of the number.
 */
-static void codeInteger(Vdbe *v, const char *z, int n, int negFlag, int iMem){
-  assert( z || v==0 || sqlite3VdbeDb(v)->mallocFailed );
-  if( z ){
+static void codeInteger(Vdbe *v, Expr *pExpr, int negFlag, int iMem){
+  const char *z;
+  if( pExpr->flags & EP_IntValue ){
+    int i = pExpr->iTable;
+    if( negFlag ) i = -i;
+    sqlite3VdbeAddOp2(v, OP_Integer, i, iMem);
+  }else if( (z = (char*)pExpr->token.z)!=0 ){
     int i;
+    int n = pExpr->token.n;
     assert( !isdigit(z[n]) );
     if( sqlite3GetInt32(z, &i) ){
       if( negFlag ) i = -i;
@@ -49606,21 +51534,34 @@
 }
 
 /*
-** Generate code to moves content from one register to another.
-** Keep the column cache up-to-date.
+** Generate code to move content from registers iFrom...iFrom+nReg-1
+** over to iTo..iTo+nReg-1. Keep the column cache up-to-date.
 */
-SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo){
+SQLITE_PRIVATE void sqlite3ExprCodeMove(Parse *pParse, int iFrom, int iTo, int nReg){
   int i;
   if( iFrom==iTo ) return;
-  sqlite3VdbeAddOp2(pParse->pVdbe, OP_Move, iFrom, iTo);
+  sqlite3VdbeAddOp3(pParse->pVdbe, OP_Move, iFrom, iTo, nReg);
   for(i=0; i<pParse->nColCache; i++){
-    if( pParse->aColCache[i].iReg==iFrom ){
-      pParse->aColCache[i].iReg = iTo;
+    int x = pParse->aColCache[i].iReg;
+    if( x>=iFrom && x<iFrom+nReg ){
+      pParse->aColCache[i].iReg += iTo-iFrom;
     }
   }
 }
 
 /*
+** Generate code to copy content from registers iFrom...iFrom+nReg-1
+** over to iTo..iTo+nReg-1.
+*/
+SQLITE_PRIVATE void sqlite3ExprCodeCopy(Parse *pParse, int iFrom, int iTo, int nReg){
+  int i;
+  if( iFrom==iTo ) return;
+  for(i=0; i<nReg; i++){
+    sqlite3VdbeAddOp2(pParse->pVdbe, OP_Copy, iFrom+i, iTo+i);
+  }
+}
+
+/*
 ** Return true if any register in the range iFrom..iTo (inclusive)
 ** is used as part of the column cache.
 */
@@ -49739,7 +51680,7 @@
       break;
     }
     case TK_INTEGER: {
-      codeInteger(v, (char*)pExpr->token.z, pExpr->token.n, 0, target);
+      codeInteger(v, pExpr, 0, target);
       break;
     }
     case TK_FLOAT: {
@@ -49877,11 +51818,10 @@
       Expr *pLeft = pExpr->pLeft;
       assert( pLeft );
       if( pLeft->op==TK_FLOAT || pLeft->op==TK_INTEGER ){
-        Token *p = &pLeft->token;
         if( pLeft->op==TK_FLOAT ){
-          codeReal(v, (char*)p->z, p->n, 1, target);
+          codeReal(v, (char*)pLeft->token.z, pLeft->token.n, 1, target);
         }else{
-          codeInteger(v, (char*)p->z, p->n, 1, target);
+          codeInteger(v, pLeft, 1, target);
         }
       }else{
         regFree1 = r1 = sqlite3GetTempReg(pParse);
@@ -50003,17 +51943,23 @@
       testcase( op==TK_EXISTS );
       testcase( op==TK_SELECT );
       if( pExpr->iColumn==0 ){
-        sqlite3CodeSubselect(pParse, pExpr);
+        sqlite3CodeSubselect(pParse, pExpr, 0);
       }
       inReg = pExpr->iColumn;
       break;
     }
     case TK_IN: {
-      int j1, j2, j3, j4, j5;
+      int rNotFound = 0;
+      int rMayHaveNull = 0;
+      int j2, j3, j4, j5;
       char affinity;
       int eType;
 
-      eType = sqlite3FindInIndex(pParse, pExpr, 0);
+      VdbeNoopComment((v, "begin IN expr r%d", target));
+      eType = sqlite3FindInIndex(pParse, pExpr, &rMayHaveNull);
+      if( rMayHaveNull ){
+        rNotFound = ++pParse->nMem;
+      }
 
       /* Figure out the affinity to use to create a key from the results
       ** of the expression. affinityStr stores a static string suitable for
@@ -50021,32 +51967,74 @@
       */
       affinity = comparisonAffinity(pExpr);
 
-      sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
 
       /* Code the <expr> from "<expr> IN (...)". The temporary table
       ** pExpr->iTable contains the values that make up the (...) set.
       */
-      r1 = sqlite3ExprCodeTemp(pParse, pExpr->pLeft, &regFree1);
-      testcase( regFree1==0 );
-      j1 = sqlite3VdbeAddOp1(v, OP_NotNull, r1);
-      sqlite3VdbeAddOp2(v, OP_Null, 0, target);
-      j2  = sqlite3VdbeAddOp0(v, OP_Goto);
-      sqlite3VdbeJumpHere(v, j1);
+      pParse->disableColCache++;
+      sqlite3ExprCode(pParse, pExpr->pLeft, target);
+      pParse->disableColCache--;
+      j2 = sqlite3VdbeAddOp1(v, OP_IsNull, target);
       if( eType==IN_INDEX_ROWID ){
-        j3 = sqlite3VdbeAddOp1(v, OP_MustBeInt, r1);
-        j4 = sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, 0, r1);
+        j3 = sqlite3VdbeAddOp1(v, OP_MustBeInt, target);
+        j4 = sqlite3VdbeAddOp3(v, OP_NotExists, pExpr->iTable, 0, target);
+        sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
         j5 = sqlite3VdbeAddOp0(v, OP_Goto);
         sqlite3VdbeJumpHere(v, j3);
         sqlite3VdbeJumpHere(v, j4);
+        sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
       }else{
         r2 = regFree2 = sqlite3GetTempReg(pParse);
-        sqlite3VdbeAddOp4(v, OP_MakeRecord, r1, 1, r2, &affinity, 1);
-        sqlite3ExprCacheAffinityChange(pParse, r1, 1);
+
+        /* Create a record and test for set membership. If the set contains
+        ** the value, then jump to the end of the test code. The target
+        ** register still contains the true (1) value written to it earlier.
+        */
+        sqlite3VdbeAddOp4(v, OP_MakeRecord, target, 1, r2, &affinity, 1);
+        sqlite3VdbeAddOp2(v, OP_Integer, 1, target);
         j5 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, r2);
+
+        /* If the set membership test fails, then the result of the 
+        ** "x IN (...)" expression must be either 0 or NULL. If the set
+        ** contains no NULL values, then the result is 0. If the set 
+        ** contains one or more NULL values, then the result of the
+        ** expression is also NULL.
+        */
+        if( rNotFound==0 ){
+          /* This branch runs if it is known at compile time (now) that 
+          ** the set contains no NULL values. This happens as the result
+          ** of a "NOT NULL" constraint in the database schema. No need
+          ** to test the data structure at runtime in this case.
+          */
+          sqlite3VdbeAddOp2(v, OP_Integer, 0, target);
+        }else{
+          /* This block populates the rNotFound register with either NULL
+          ** or 0 (an integer value). If the data structure contains one
+          ** or more NULLs, then set rNotFound to NULL. Otherwise, set it
+          ** to 0. If register rMayHaveNull is already set to some value
+          ** other than NULL, then the test has already been run and 
+          ** rNotFound is already populated.
+          */
+          static const char nullRecord[] = { 0x02, 0x00 };
+          j3 = sqlite3VdbeAddOp1(v, OP_NotNull, rMayHaveNull);
+          sqlite3VdbeAddOp2(v, OP_Null, 0, rNotFound);
+          sqlite3VdbeAddOp4(v, OP_Blob, 2, rMayHaveNull, 0, 
+                             nullRecord, P4_STATIC);
+          j4 = sqlite3VdbeAddOp3(v, OP_Found, pExpr->iTable, 0, rMayHaveNull);
+          sqlite3VdbeAddOp2(v, OP_Integer, 0, rNotFound);
+          sqlite3VdbeJumpHere(v, j4);
+          sqlite3VdbeJumpHere(v, j3);
+
+          /* Copy the value of register rNotFound (which is either NULL or 0)
+	  ** into the target register. This will be the result of the
+          ** expression.
+          */
+          sqlite3VdbeAddOp2(v, OP_Copy, rNotFound, target);
+        }
       }
-      sqlite3VdbeAddOp2(v, OP_AddImm, target, -1);
       sqlite3VdbeJumpHere(v, j2);
       sqlite3VdbeJumpHere(v, j5);
+      VdbeComment((v, "end IN expr r%d", target));
       break;
     }
 #endif
@@ -50934,25 +52922,14 @@
 ** Allocate or deallocate temporary use registers during code generation.
 */
 SQLITE_PRIVATE int sqlite3GetTempReg(Parse *pParse){
-  int i, r;
   if( pParse->nTempReg==0 ){
     return ++pParse->nMem;
   }
-  for(i=0; i<pParse->nTempReg; i++){
-    r = pParse->aTempReg[i];
-    if( usedAsColumnCache(pParse, r, r) ) continue;
-  }
-  if( i>=pParse->nTempReg ){
-    return ++pParse->nMem;
-  }
-  while( i<pParse->nTempReg-1 ){
-    pParse->aTempReg[i] = pParse->aTempReg[i+1];
-  }
-  pParse->nTempReg--;
-  return r;
+  return pParse->aTempReg[--pParse->nTempReg];
 }
 SQLITE_PRIVATE void sqlite3ReleaseTempReg(Parse *pParse, int iReg){
   if( iReg && pParse->nTempReg<ArraySize(pParse->aTempReg) ){
+    sqlite3ExprWritableRegister(pParse, iReg, iReg);
     pParse->aTempReg[pParse->nTempReg++] = iReg;
   }
 }
@@ -50996,7 +52973,7 @@
 ** This file contains C code routines that used to generate VDBE code
 ** that implements the ALTER TABLE command.
 **
-** $Id: alter.c,v 1.44 2008/05/09 14:17:52 drh Exp $
+** $Id: alter.c,v 1.46 2008/07/15 14:47:19 drh Exp $
 */
 
 /*
@@ -51037,7 +53014,7 @@
 
   /* The principle used to locate the table name in the CREATE TABLE 
   ** statement is that the table name is the first non-space token that
-  ** is immediately followed by a left parenthesis - TK_LP - or "USING" TK_USING.
+  ** is immediately followed by a TK_LP or TK_USING token.
   */
   if( zSql ){
     do {
@@ -51146,22 +53123,12 @@
 ** Register built-in functions used to help implement ALTER TABLE
 */
 SQLITE_PRIVATE void sqlite3AlterFunctions(sqlite3 *db){
-  static const struct {
-     char *zName;
-     signed char nArg;
-     void (*xFunc)(sqlite3_context*,int,sqlite3_value **);
-  } aFuncs[] = {
-    { "sqlite_rename_table",    2, renameTableFunc},
+  sqlite3CreateFunc(db, "sqlite_rename_table", 2, SQLITE_UTF8, 0,
+                         renameTableFunc, 0, 0);
 #ifndef SQLITE_OMIT_TRIGGER
-    { "sqlite_rename_trigger",  2, renameTriggerFunc},
+  sqlite3CreateFunc(db, "sqlite_rename_trigger", 2, SQLITE_UTF8, 0,
+                         renameTriggerFunc, 0, 0);
 #endif
-  };
-  int i;
-
-  for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
-    sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
-        SQLITE_UTF8, 0, aFuncs[i].xFunc, 0, 0);
-  }
 }
 
 /*
@@ -52053,7 +54020,7 @@
 *************************************************************************
 ** This file contains code used to implement the ATTACH and DETACH commands.
 **
-** $Id: attach.c,v 1.75 2008/04/17 17:02:01 drh Exp $
+** $Id: attach.c,v 1.76 2008/06/15 02:51:47 drh Exp $
 */
 
 #ifndef SQLITE_OMIT_ATTACH
@@ -52153,18 +54120,12 @@
   ** hash tables.
   */
   if( db->aDb==db->aDbStatic ){
-    aNew = sqlite3_malloc( sizeof(db->aDb[0])*3 );
-    if( aNew==0 ){
-      db->mallocFailed = 1;
-      return;
-    }
+    aNew = sqlite3DbMallocRaw(db, sizeof(db->aDb[0])*3 );
+    if( aNew==0 ) return;
     memcpy(aNew, db->aDb, sizeof(db->aDb[0])*2);
   }else{
-    aNew = sqlite3_realloc(db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
-    if( aNew==0 ){
-      db->mallocFailed = 1;
-      return;
-    } 
+    aNew = sqlite3DbRealloc(db, db->aDb, sizeof(db->aDb[0])*(db->nDb+1) );
+    if( aNew==0 ) return;
   }
   db->aDb = aNew;
   aNew = &db->aDb[db->nDb++];
@@ -52832,7 +54793,7 @@
 **     COMMIT
 **     ROLLBACK
 **
-** $Id: build.c,v 1.484 2008/05/01 17:16:53 drh Exp $
+** $Id: build.c,v 1.490 2008/07/08 23:40:20 drh Exp $
 */
 
 /*
@@ -53046,6 +55007,7 @@
 SQLITE_PRIVATE void sqlite3NestedParse(Parse *pParse, const char *zFormat, ...){
   va_list ap;
   char *zSql;
+  char *zErrMsg = 0;
 # define SAVE_SZ  (sizeof(Parse) - offsetof(Parse,nVar))
   char saveBuf[SAVE_SZ];
 
@@ -53061,7 +55023,8 @@
   pParse->nested++;
   memcpy(saveBuf, &pParse->nVar, SAVE_SZ);
   memset(&pParse->nVar, 0, SAVE_SZ);
-  sqlite3RunParser(pParse, zSql, 0);
+  sqlite3RunParser(pParse, zSql, &zErrMsg);
+  sqlite3_free(zErrMsg);
   sqlite3_free(zSql);
   memcpy(&pParse->nVar, saveBuf, SAVE_SZ);
   pParse->nested--;
@@ -53082,11 +55045,13 @@
 SQLITE_PRIVATE Table *sqlite3FindTable(sqlite3 *db, const char *zName, const char *zDatabase){
   Table *p = 0;
   int i;
+  int nName;
   assert( zName!=0 );
+  nName = sqlite3Strlen(db, zName) + 1;
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;   /* Search TEMP before MAIN */
     if( zDatabase!=0 && sqlite3StrICmp(zDatabase, db->aDb[j].zName) ) continue;
-    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, strlen(zName)+1);
+    p = sqlite3HashFind(&db->aDb[j].pSchema->tblHash, zName, nName);
     if( p ) break;
   }
   return p;
@@ -53144,13 +55109,14 @@
 SQLITE_PRIVATE Index *sqlite3FindIndex(sqlite3 *db, const char *zName, const char *zDb){
   Index *p = 0;
   int i;
+  int nName = sqlite3Strlen(db, zName)+1;
   for(i=OMIT_TEMPDB; i<db->nDb; i++){
     int j = (i<2) ? i^1 : i;  /* Search TEMP before MAIN */
     Schema *pSchema = db->aDb[j].pSchema;
     if( zDb && sqlite3StrICmp(zDb, db->aDb[j].zName) ) continue;
     assert( pSchema || (j==1 && !db->aDb[1].pBt) );
     if( pSchema ){
-      p = sqlite3HashFind(&pSchema->idxHash, zName, strlen(zName)+1);
+      p = sqlite3HashFind(&pSchema->idxHash, zName, nName);
     }
     if( p ) break;
   }
@@ -53177,7 +55143,7 @@
   Index *pOld;
   const char *zName = p->zName;
 
-  pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen( zName)+1, 0);
+  pOld = sqlite3HashInsert(&p->pSchema->idxHash, zName, strlen(zName)+1, 0);
   assert( pOld==0 || pOld==p );
   freeIndex(p);
 }
@@ -53193,7 +55159,7 @@
   int len;
   Hash *pHash = &db->aDb[iDb].pSchema->idxHash;
 
-  len = strlen(zIdxName);
+  len = sqlite3Strlen(db, zIdxName);
   pIndex = sqlite3HashInsert(pHash, zIdxName, len+1, 0);
   if( pIndex ){
     if( pIndex->pTable->pIndex==pIndex ){
@@ -54071,7 +56037,7 @@
     pColl = sqlite3GetCollSeq(db, pColl, zName, nName);
     if( !pColl ){
       if( nName<0 ){
-        nName = strlen(zName);
+        nName = sqlite3Strlen(db, zName);
       }
       sqlite3ErrorMsg(pParse, "no such collation sequence: %.*s", nName, zName);
       pColl = 0;
@@ -54175,7 +56141,7 @@
     zEnd = "\n)";
   }
   n += 35 + 6*p->nCol;
-  zStmt = sqlite3_malloc( n );
+  zStmt = sqlite3Malloc( n );
   if( zStmt==0 ){
     db->mallocFailed = 1;
     return 0;
@@ -54329,7 +56295,7 @@
       sqlite3VdbeChangeP5(v, 1);
       pParse->nTab = 2;
       sqlite3SelectDestInit(&dest, SRT_Table, 1);
-      sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
+      sqlite3Select(pParse, pSelect, &dest, 0, 0, 0);
       sqlite3VdbeAddOp1(v, OP_Close, 1);
       if( pParse->nErr==0 ){
         pSelTab = sqlite3ResultSetOfSelect(pParse, 0, pSelect);
@@ -55105,7 +57071,7 @@
     regRowid = regIdxKey + pIndex->nColumn;
     j1 = sqlite3VdbeAddOp3(v, OP_IsNull, regIdxKey, 0, pIndex->nColumn);
     j2 = sqlite3VdbeAddOp4(v, OP_IsUnique, iIdx,
-                           0, regRowid, (char*)regRecord, P4_INT32);
+                           0, regRowid, SQLITE_INT_TO_PTR(regRecord), P4_INT32);
     sqlite3VdbeAddOp4(v, OP_Halt, SQLITE_CONSTRAINT, OE_Abort, 0,
                     "indexed columns are not unique", P4_STATIC);
     sqlite3VdbeJumpHere(v, j1);
@@ -55261,15 +57227,11 @@
       goto exit_create_index;
     }
   }else{
-    char zBuf[30];
     int n;
     Index *pLoop;
     for(pLoop=pTab->pIndex, n=1; pLoop; pLoop=pLoop->pNext, n++){}
-    sqlite3_snprintf(sizeof(zBuf),zBuf,"_%d",n);
-    zName = 0;
-    sqlite3SetString(&zName, "sqlite_autoindex_", pTab->zName, zBuf, (char*)0);
+    zName = sqlite3MPrintf(db, "sqlite_autoindex_%s_%d", pTab->zName, n);
     if( zName==0 ){
-      db->mallocFailed = 1;
       goto exit_create_index;
     }
   }
@@ -56313,7 +58275,7 @@
 ** This file contains functions used to access the internal hash tables
 ** of user defined functions and collation sequences.
 **
-** $Id: callback.c,v 1.23 2007/08/29 12:31:26 danielk1977 Exp $
+** $Id: callback.c,v 1.25 2008/07/08 14:52:10 drh Exp $
 */
 
 
@@ -56324,7 +58286,7 @@
 */
 static void callCollNeeded(sqlite3 *db, const char *zName, int nName){
   assert( !db->xCollNeeded || !db->xCollNeeded16 );
-  if( nName<0 ) nName = strlen(zName);
+  if( nName<0 ) nName = sqlite3Strlen(db, zName);
   if( db->xCollNeeded ){
     char *zExternal = sqlite3DbStrNDup(db, zName, nName);
     if( !zExternal ) return;
@@ -56457,7 +58419,7 @@
   int create
 ){
   CollSeq *pColl;
-  if( nName<0 ) nName = strlen(zName);
+  if( nName<0 ) nName = sqlite3Strlen(db, zName);
   pColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
 
   if( 0==pColl && create ){
@@ -56627,6 +58589,8 @@
 ** at a Schema struct. This function does not call sqlite3_free() on the 
 ** pointer itself, it just cleans up subsiduary resources (i.e. the contents
 ** of the schema hash tables).
+**
+** The Schema.cache_size variable is not cleared.
 */
 SQLITE_PRIVATE void sqlite3SchemaFree(void *p){
   Hash temp1;
@@ -56692,7 +58656,7 @@
 ** This file contains C code routines that are called by the parser
 ** in order to generate code for DELETE FROM statements.
 **
-** $Id: delete.c,v 1.169 2008/04/28 18:46:43 drh Exp $
+** $Id: delete.c,v 1.170 2008/07/08 23:40:20 drh Exp $
 */
 
 /*
@@ -56785,7 +58749,7 @@
     pDup = sqlite3SelectNew(pParse, 0, pFrom, pWhere, 0, 0, 0, 0, 0, 0);
   }
   sqlite3SelectDestInit(&dest, SRT_EphemTab, iCur);
-  sqlite3Select(pParse, pDup, &dest, 0, 0, 0, 0);
+  sqlite3Select(pParse, pDup, &dest, 0, 0, 0);
   sqlite3SelectDelete(pDup);
 }
 #endif /* !defined(SQLITE_OMIT_VIEW) && !defined(SQLITE_OMIT_TRIGGER) */
@@ -57242,7 +59206,7 @@
 ** sqliteRegisterBuildinFunctions() found at the bottom of the file.
 ** All other code has file scope.
 **
-** $Id: func.c,v 1.192 2008/04/27 18:40:12 drh Exp $
+** $Id: func.c,v 1.195 2008/07/08 22:28:49 shane Exp $
 */
 
 
@@ -57470,7 +59434,7 @@
     sqlite3_result_error_toobig(context);
     z = 0;
   }else{
-    z = sqlite3_malloc(nByte);
+    z = sqlite3Malloc(nByte);
     if( !z && nByte>0 ){
       sqlite3_result_error_nomem(context);
     }
@@ -58129,7 +60093,7 @@
     }
   }
   if( nChar>0 ){
-    flags = (int)sqlite3_user_data(context);
+    flags = SQLITE_PTR_TO_INT(sqlite3_user_data(context));
     if( flags & 1 ){
       while( nIn>0 ){
         int len;
@@ -58387,8 +60351,8 @@
   const char *zVal;
   StrAccum *pAccum;
   const char *zSep;
-  int nVal, nSep;
-  if( sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
+  int nVal, nSep, i;
+  if( argc==0 || sqlite3_value_type(argv[0])==SQLITE_NULL ) return;
   pAccum = (StrAccum*)sqlite3_aggregate_context(context, sizeof(*pAccum));
 
   if( pAccum ){
@@ -58396,18 +60360,22 @@
     pAccum->useMalloc = 1;
     pAccum->mxAlloc = db->aLimit[SQLITE_LIMIT_LENGTH];
     if( pAccum->nChar ){
-      if( argc==2 ){
-        zSep = (char*)sqlite3_value_text(argv[1]);
-        nSep = sqlite3_value_bytes(argv[1]);
+      if( argc>1 ){
+        zSep = (char*)sqlite3_value_text(argv[argc-1]);
+        nSep = sqlite3_value_bytes(argv[argc-1]);
       }else{
         zSep = ",";
         nSep = 1;
       }
       sqlite3StrAccumAppend(pAccum, zSep, nSep);
     }
-    zVal = (char*)sqlite3_value_text(argv[0]);
-    nVal = sqlite3_value_bytes(argv[0]);
-    sqlite3StrAccumAppend(pAccum, zVal, nVal);
+    i = 0;
+    do{
+      zVal = (char*)sqlite3_value_text(argv[i]);
+      nVal = sqlite3_value_bytes(argv[i]);
+      sqlite3StrAccumAppend(pAccum, zVal, nVal);
+      i++;
+    }while( i<argc-1 );
   }
 }
 static void groupConcatFinalize(sqlite3_context *context){
@@ -58496,15 +60464,14 @@
     { "avg",    1, 0, 0, sumStep,      avgFinalize    },
     { "count",  0, 0, 0, countStep,    countFinalize  },
     { "count",  1, 0, 0, countStep,    countFinalize  },
-    { "group_concat", 1, 0, 0, groupConcatStep, groupConcatFinalize },
-    { "group_concat", 2, 0, 0, groupConcatStep, groupConcatFinalize },
+    { "group_concat", -1, 0, 0, groupConcatStep, groupConcatFinalize },
   };
   int i;
 
   for(i=0; i<sizeof(aFuncs)/sizeof(aFuncs[0]); i++){
     void *pArg;
     u8 argType = aFuncs[i].argType;
-    pArg = (void*)(int)argType;
+    pArg = SQLITE_INT_TO_PTR(argType);
     sqlite3CreateFunc(db, aFuncs[i].zName, aFuncs[i].nArg,
         aFuncs[i].eTextRep, pArg, aFuncs[i].xFunc, 0, 0);
     if( aFuncs[i].needCollSeq ){
@@ -58522,7 +60489,7 @@
   sqlite3AttachFunctions(db);
 #endif
   for(i=0; i<sizeof(aAggs)/sizeof(aAggs[0]); i++){
-    void *pArg = (void*)(int)aAggs[i].argType;
+    void *pArg = SQLITE_INT_TO_PTR(aAggs[i].argType);
     sqlite3CreateFunc(db, aAggs[i].zName, aAggs[i].nArg, SQLITE_UTF8, 
         pArg, 0, aAggs[i].xStep, aAggs[i].xFinalize);
     if( aAggs[i].needCollSeq ){
@@ -58632,7 +60599,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle INSERT statements in SQLite.
 **
-** $Id: insert.c,v 1.238 2008/04/28 18:46:43 drh Exp $
+** $Id: insert.c,v 1.247 2008/07/08 23:40:20 drh Exp $
 */
 
 /*
@@ -58794,14 +60761,15 @@
     sqlite3OpenTable(pParse, iCur, iDb, pDb->pSchema->pSeqTab, OP_OpenRead);
     addr = sqlite3VdbeCurrentAddr(v);
     sqlite3VdbeAddOp4(v, OP_String8, 0, memId-1, 0, pTab->zName, 0);
-    sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+8);
+    sqlite3VdbeAddOp2(v, OP_Rewind, iCur, addr+9);
     sqlite3VdbeAddOp3(v, OP_Column, iCur, 0, memId);
     sqlite3VdbeAddOp3(v, OP_Ne, memId-1, addr+7, memId);
     sqlite3VdbeChangeP5(v, SQLITE_JUMPIFNULL);
     sqlite3VdbeAddOp2(v, OP_Rowid, iCur, memId+1);
     sqlite3VdbeAddOp3(v, OP_Column, iCur, 1, memId);
-    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+8);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addr+9);
     sqlite3VdbeAddOp2(v, OP_Next, iCur, addr+2);
+    sqlite3VdbeAddOp2(v, OP_Integer, 0, memId);
     sqlite3VdbeAddOp2(v, OP_Close, iCur, 0);
   }
   return memId;
@@ -58887,7 +60855,8 @@
 **
 ** The code generated follows one of four templates.  For a simple
 ** select with data coming from a VALUES clause, the code executes
-** once straight down through.  The template looks like this:
+** once straight down through.  Pseudo-code follows (we call this
+** the "1st template"):
 **
 **         open write cursor to <table> and its indices
 **         puts VALUES clause expressions onto the stack
@@ -58905,7 +60874,7 @@
 ** schemas, including all the same indices, then a special optimization
 ** is invoked that copies raw records from <table2> over to <table1>.
 ** See the xferOptimization() function for the implementation of this
-** template.  This is the second template.
+** template.  This is the 2nd template.
 **
 **         open a write cursor to <table>
 **         open read cursor on <table2>
@@ -58918,45 +60887,58 @@
 **           close cursors
 **         end foreach
 **
-** The third template is for when the second template does not apply
+** The 3rd template is for when the second template does not apply
 ** and the SELECT clause does not read from <table> at any time.
 ** The generated code follows this template:
 **
+**         EOF <- 0
+**         X <- A
 **         goto B
 **      A: setup for the SELECT
 **         loop over the rows in the SELECT
-**           gosub C
+**           load values into registers R..R+n
+**           yield X
 **         end loop
 **         cleanup after the SELECT
-**         goto D
-**      B: open write cursor to <table> and its indices
+**         EOF <- 1
+**         yield X
 **         goto A
-**      C: insert the select result into <table>
-**         return
+**      B: open write cursor to <table> and its indices
+**      C: yield X
+**         if EOF goto D
+**         insert the select result into <table> from R..R+n
+**         goto C
 **      D: cleanup
 **
-** The fourth template is used if the insert statement takes its
+** The 4th template is used if the insert statement takes its
 ** values from a SELECT but the data is being inserted into a table
 ** that is also read as part of the SELECT.  In the third form,
 ** we have to use a intermediate table to store the results of
 ** the select.  The template is like this:
 **
+**         EOF <- 0
+**         X <- A
 **         goto B
 **      A: setup for the SELECT
 **         loop over the tables in the SELECT
-**           gosub C
+**           load value into register R..R+n
+**           yield X
 **         end loop
 **         cleanup after the SELECT
-**         goto D
-**      C: insert the select result into the intermediate table
-**         return
-**      B: open a cursor to an intermediate table
-**         goto A
-**      D: open write cursor to <table> and its indices
-**         loop over the intermediate table
+**         EOF <- 1
+**         yield X
+**         halt-error
+**      B: open temp table
+**      L: yield X
+**         if EOF goto M
+**         insert row from R..R+n into temp table
+**         goto L
+**      M: open write cursor to <table> and its indices
+**         rewind temp table
+**      C: loop over rows of intermediate table
 **           transfer values form intermediate table into <table>
-**         end the loop
-**         cleanup
+**         end loop
+**      D: cleanup
 */
 SQLITE_PRIVATE void sqlite3Insert(
   Parse *pParse,        /* Parser context */
@@ -58980,10 +60962,10 @@
   int endOfLoop;        /* Label for the end of the insertion loop */
   int useTempTable = 0; /* Store SELECT results in intermediate table */
   int srcTab = 0;       /* Data comes from this temporary cursor if >=0 */
-  int iCont=0,iBreak=0; /* Beginning and end of the loop over srcTab */
-  int iSelectLoop = 0;  /* Address of code that implements the SELECT */
-  int iCleanup = 0;     /* Address of the cleanup code */
-  int iInsertBlock = 0; /* Address of the subroutine used to insert data */
+  int addrInsTop = 0;   /* Jump to label "D" */
+  int addrCont = 0;     /* Top of insert loop. Label "C" in templates 3 and 4 */
+  int addrSelect = 0;   /* Address of coroutine that implements the SELECT */
+  SelectDest dest;      /* Destination for SELECT on rhs of INSERT */
   int newIdx = -1;      /* Cursor for the NEW pseudo-table */
   int iDb;              /* Index of database holding TABLE */
   Db *pDb;              /* The database containing table being inserted into */
@@ -58997,6 +60979,7 @@
   int regRowid;         /* registers holding insert rowid */
   int regData;          /* register holding first column to insert */
   int regRecord;        /* Holds the assemblied row record */
+  int regEof;           /* Register recording end of SELECT data */
   int *aRegIdx = 0;     /* One register allocated to each index */
 
 
@@ -59078,6 +61061,8 @@
   **
   ** Then special optimizations can be applied that make the transfer
   ** very fast and which reduce fragmentation of indices.
+  **
+  ** This is the 2nd template.
   */
   if( pColumn==0 && xferOptimization(pParse, pTab, pSelect, onError, iDb) ){
     assert( !triggers_exist );
@@ -59092,75 +61077,103 @@
   regAutoinc = autoIncBegin(pParse, iDb, pTab);
 
   /* Figure out how many columns of data are supplied.  If the data
-  ** is coming from a SELECT statement, then this step also generates
-  ** all the code to implement the SELECT statement and invoke a subroutine
-  ** to process each row of the result. (Template 2.) If the SELECT
-  ** statement uses the the table that is being inserted into, then the
-  ** subroutine is also coded here.  That subroutine stores the SELECT
-  ** results in a temporary table. (Template 3.)
+  ** is coming from a SELECT statement, then generate a co-routine that
+  ** produces a single row of the SELECT on each invocation.  The
+  ** co-routine is the common header to the 3rd and 4th templates.
   */
   if( pSelect ){
     /* Data is coming from a SELECT.  Generate code to implement that SELECT
-    */
-    SelectDest dest;
-    int rc, iInitCode;
-
-    iInitCode = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
-    iSelectLoop = sqlite3VdbeCurrentAddr(v);
-    iInsertBlock = sqlite3VdbeMakeLabel(v);
-    sqlite3SelectDestInit(&dest, SRT_Subroutine, iInsertBlock);
+    ** as a co-routine.  The code is common to both the 3rd and 4th
+    ** templates:
+    **
+    **         EOF <- 0
+    **         X <- A
+    **         goto B
+    **      A: setup for the SELECT
+    **         loop over the tables in the SELECT
+    **           load value into register R..R+n
+    **           yield X
+    **         end loop
+    **         cleanup after the SELECT
+    **         EOF <- 1
+    **         yield X
+    **         halt-error
+    **
+    ** On each invocation of the co-routine, it puts a single row of the
+    ** SELECT result into registers dest.iMem...dest.iMem+dest.nMem-1.
+    ** (These output registers are allocated by sqlite3Select().)  When
+    ** the SELECT completes, it sets the EOF flag stored in regEof.
+    */
+    int rc, j1;
+
+    regEof = ++pParse->nMem;
+    sqlite3VdbeAddOp2(v, OP_Integer, 0, regEof);      /* EOF <- 0 */
+    VdbeComment((v, "SELECT eof flag"));
+    sqlite3SelectDestInit(&dest, SRT_Coroutine, ++pParse->nMem);
+    addrSelect = sqlite3VdbeCurrentAddr(v)+2;
+    sqlite3VdbeAddOp2(v, OP_Integer, addrSelect-1, dest.iParm);
+    j1 = sqlite3VdbeAddOp2(v, OP_Goto, 0, 0);
+    VdbeComment((v, "Jump over SELECT coroutine"));
 
     /* Resolve the expressions in the SELECT statement and execute it. */
-    rc = sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
+    rc = sqlite3Select(pParse, pSelect, &dest, 0, 0, 0);
     if( rc || pParse->nErr || db->mallocFailed ){
       goto insert_cleanup;
     }
+    sqlite3VdbeAddOp2(v, OP_Integer, 1, regEof);         /* EOF <- 1 */
+    sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);   /* yield X */
+    sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_INTERNAL, OE_Abort);
+    VdbeComment((v, "End of SELECT coroutine"));
+    sqlite3VdbeJumpHere(v, j1);                          /* label B: */
 
     regFromSelect = dest.iMem;
-    iCleanup = sqlite3VdbeMakeLabel(v);
-    sqlite3VdbeAddOp2(v, OP_Goto, 0, iCleanup);
     assert( pSelect->pEList );
     nColumn = pSelect->pEList->nExpr;
+    assert( dest.nMem==nColumn );
 
     /* Set useTempTable to TRUE if the result of the SELECT statement
-    ** should be written into a temporary table.  Set to FALSE if each
-    ** row of the SELECT can be written directly into the result table.
+    ** should be written into a temporary table (template 4).  Set to
+    ** FALSE if each* row of the SELECT can be written directly into
+    ** 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 
     ** temp table in the case of row triggers.
     */
-    if( triggers_exist || readsTable(v, iSelectLoop, iDb, pTab) ){
+    if( triggers_exist || readsTable(v, addrSelect, iDb, pTab) ){
       useTempTable = 1;
     }
 
     if( useTempTable ){
-      /* Generate the subroutine that SELECT calls to process each row of
-      ** the result.  Store the result in a temporary table
+      /* Invoke the coroutine to extract information from the SELECT
+      ** and add it to a transient table srcTab.  The code generated
+      ** here is from the 4th template:
+      **
+      **      B: open temp table
+      **      L: yield X
+      **         if EOF goto M
+      **         insert row from R..R+n into temp table
+      **         goto L
+      **      M: ...
       */
-      int regRec, regRowid;
+      int regRec;      /* Register to hold packed record */
+      int regRowid;    /* Register to hold temp table ROWID */
+      int addrTop;     /* Label "L" */
+      int addrIf;      /* Address of jump to M */
 
       srcTab = pParse->nTab++;
       regRec = sqlite3GetTempReg(pParse);
       regRowid = sqlite3GetTempReg(pParse);
-      sqlite3VdbeResolveLabel(v, iInsertBlock);
+      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
+      addrTop = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
+      addrIf = sqlite3VdbeAddOp1(v, OP_If, regEof);
       sqlite3VdbeAddOp3(v, OP_MakeRecord, regFromSelect, nColumn, regRec);
       sqlite3VdbeAddOp2(v, OP_NewRowid, srcTab, regRowid);
       sqlite3VdbeAddOp3(v, OP_Insert, srcTab, regRec, regRowid);
-      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
+      sqlite3VdbeAddOp2(v, OP_Goto, 0, addrTop);
+      sqlite3VdbeJumpHere(v, addrIf);
       sqlite3ReleaseTempReg(pParse, regRec);
       sqlite3ReleaseTempReg(pParse, regRowid);
-
-      /* The following code runs first because the GOTO at the very top
-      ** of the program jumps to it.  Create the temporary table, then jump
-      ** back up and execute the SELECT code above.
-      */
-      sqlite3VdbeJumpHere(v, iInitCode);
-      sqlite3VdbeAddOp2(v, OP_OpenEphemeral, srcTab, nColumn);
-      sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
-      sqlite3VdbeResolveLabel(v, iCleanup);
-    }else{
-      sqlite3VdbeJumpHere(v, iInitCode);
     }
   }else{
     /* This is the case if the data for the INSERT is coming from a VALUES
@@ -59274,18 +61287,31 @@
     }
   }
 
-  /* If the data source is a temporary table, then we have to create
-  ** a loop because there might be multiple rows of data.  If the data
-  ** source is a subroutine call from the SELECT statement, then we need
-  ** to launch the SELECT statement processing.
-  */
+  /* This is the top of the main insertion loop */
   if( useTempTable ){
-    iBreak = sqlite3VdbeMakeLabel(v);
-    sqlite3VdbeAddOp2(v, OP_Rewind, srcTab, iBreak);
-    iCont = sqlite3VdbeCurrentAddr(v);
+    /* This block codes the top of loop only.  The complete loop is the
+    ** following pseudocode (template 4):
+    **
+    **         rewind temp table
+    **      C: loop over rows of intermediate table
+    **           transfer values form intermediate table into <table>
+    **         end loop
+    **      D: ...
+    */
+    addrInsTop = sqlite3VdbeAddOp1(v, OP_Rewind, srcTab);
+    addrCont = sqlite3VdbeCurrentAddr(v);
   }else if( pSelect ){
-    sqlite3VdbeAddOp2(v, OP_Goto, 0, iSelectLoop);
-    sqlite3VdbeResolveLabel(v, iInsertBlock);
+    /* This block codes the top of loop only.  The complete loop is the
+    ** following pseudocode (template 3):
+    **
+    **      C: yield X
+    **         if EOF goto D
+    **         insert the select result into <table> from R..R+n
+    **         goto C
+    **      D: ...
+    */
+    addrCont = sqlite3VdbeAddOp1(v, OP_Yield, dest.iParm);
+    addrInsTop = sqlite3VdbeAddOp1(v, OP_If, regEof);
   }
 
   /* Allocate registers for holding the rowid of the new row,
@@ -59396,7 +61422,7 @@
         VdbeOp *pOp;
         sqlite3ExprCode(pParse, pList->a[keyColumn].pExpr, regRowid);
         pOp = sqlite3VdbeGetOp(v, sqlite3VdbeCurrentAddr(v) - 1);
-        if( pOp && pOp->opcode==OP_Null ){
+        if( pOp && pOp->opcode==OP_Null && !IsVirtual(pTab) ){
           appendFlag = 1;
           pOp->opcode = OP_NewRowid;
           pOp->p1 = baseCur;
@@ -59409,9 +61435,14 @@
       */
       if( !appendFlag ){
         int j1;
-        j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
-        sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
-        sqlite3VdbeJumpHere(v, j1);
+        if( !IsVirtual(pTab) ){
+          j1 = sqlite3VdbeAddOp1(v, OP_NotNull, regRowid);
+          sqlite3VdbeAddOp3(v, OP_NewRowid, baseCur, regRowid, regAutoinc);
+          sqlite3VdbeJumpHere(v, j1);
+        }else{
+          j1 = sqlite3VdbeCurrentAddr(v);
+          sqlite3VdbeAddOp2(v, OP_IsNull, regRowid, j1+2);
+        }
         sqlite3VdbeAddOp1(v, OP_MustBeInt, regRowid);
       }
     }else if( IsVirtual(pTab) ){
@@ -59510,23 +61541,24 @@
     }
   }
 
-  /* The bottom of the loop, if the data source is a SELECT statement
+  /* The bottom of the main insertion loop, if the data source
+  ** is a SELECT statement.
   */
   sqlite3VdbeResolveLabel(v, endOfLoop);
   if( useTempTable ){
-    sqlite3VdbeAddOp2(v, OP_Next, srcTab, iCont);
-    sqlite3VdbeResolveLabel(v, iBreak);
-    sqlite3VdbeAddOp2(v, OP_Close, srcTab, 0);
+    sqlite3VdbeAddOp2(v, OP_Next, srcTab, addrCont);
+    sqlite3VdbeJumpHere(v, addrInsTop);
+    sqlite3VdbeAddOp1(v, OP_Close, srcTab);
   }else if( pSelect ){
-    sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
-    sqlite3VdbeResolveLabel(v, iCleanup);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrCont);
+    sqlite3VdbeJumpHere(v, addrInsTop);
   }
 
   if( !IsVirtual(pTab) && !isView ){
     /* Close all tables opened */
-    sqlite3VdbeAddOp2(v, OP_Close, baseCur, 0);
+    sqlite3VdbeAddOp1(v, OP_Close, baseCur);
     for(idx=1, pIdx=pTab->pIndex; pIdx; pIdx=pIdx->pNext, idx++){
-      sqlite3VdbeAddOp2(v, OP_Close, idx+baseCur, 0);
+      sqlite3VdbeAddOp1(v, OP_Close, idx+baseCur);
     }
   }
 
@@ -59684,10 +61716,10 @@
       case OE_Rollback:
       case OE_Abort:
       case OE_Fail: {
-        char *zMsg = 0;
+        char *zMsg;
         sqlite3VdbeAddOp2(v, OP_Halt, SQLITE_CONSTRAINT, onError);
-        sqlite3SetString(&zMsg, pTab->zName, ".", pTab->aCol[i].zName,
-                        " may not be NULL", (char*)0);
+        zMsg = sqlite3MPrintf(pParse->db, "%s.%s may not be NULL",
+                              pTab->zName, pTab->aCol[i].zName);
         sqlite3VdbeChangeP4(v, -1, zMsg, P4_DYNAMIC);
         break;
       }
@@ -59812,7 +61844,7 @@
     regR = sqlite3GetTempReg(pParse);
     sqlite3VdbeAddOp2(v, OP_SCopy, regRowid-hasTwoRowids, regR);
     j3 = sqlite3VdbeAddOp4(v, OP_IsUnique, baseCur+iCur+1, 0,
-                           regR, (char*)aRegIdx[iCur],
+                           regR, SQLITE_INT_TO_PTR(aRegIdx[iCur]),
                            P4_INT32);
 
     /* Generate code that executes if the new index entry is not unique */
@@ -60307,7 +62339,7 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: legacy.c,v 1.24 2008/03/21 18:01:14 drh Exp $
+** $Id: legacy.c,v 1.27 2008/06/15 02:51:47 drh Exp $
 */
 
 
@@ -60336,9 +62368,10 @@
   int nRetry = 0;
   int nCallback;
 
-  if( zSql==0 ) return SQLITE_OK;
+  if( zSql==0 ) zSql = "";
 
   sqlite3_mutex_enter(db->mutex);
+  sqlite3Error(db, SQLITE_OK, 0);
   while( (rc==SQLITE_OK || (rc==SQLITE_SCHEMA && (++nRetry)<2)) && zSql[0] ){
     int nCol;
     char **azVals = 0;
@@ -60393,6 +62426,9 @@
         }
         if( xCallback(pArg, nCol, azVals, azCols) ){
           rc = SQLITE_ABORT;
+          sqlite3_finalize(pStmt);
+          pStmt = 0;
+          sqlite3Error(db, SQLITE_ABORT, 0);
           goto exec_out;
         }
       }
@@ -60420,7 +62456,7 @@
   rc = sqlite3ApiExit(db, rc);
   if( rc!=SQLITE_OK && rc==sqlite3_errcode(db) && pzErrMsg ){
     int nErrMsg = 1 + strlen(sqlite3_errmsg(db));
-    *pzErrMsg = sqlite3_malloc(nErrMsg);
+    *pzErrMsg = sqlite3Malloc(nErrMsg);
     if( *pzErrMsg ){
       memcpy(*pzErrMsg, sqlite3_errmsg(db), nErrMsg);
     }
@@ -60448,6 +62484,8 @@
 *************************************************************************
 ** This file contains code used to dynamically load extensions into
 ** the SQLite library.
+**
+** $Id: loadext.c,v 1.51 2008/07/08 14:17:35 danielk1977 Exp $
 */
 
 #ifndef SQLITE_CORE
@@ -60472,7 +62510,7 @@
 ** as extensions by SQLite should #include this file instead of 
 ** sqlite3.h.
 **
-** @(#) $Id: sqlite3ext.h,v 1.21 2008/03/19 21:45:51 drh Exp $
+** @(#) $Id: sqlite3ext.h,v 1.24 2008/06/30 15:09:29 danielk1977 Exp $
 */
 #ifndef _SQLITE3EXT_H_
 #define _SQLITE3EXT_H_
@@ -60534,7 +62572,7 @@
   int  (*complete)(const char*sql);
   int  (*complete16)(const void*sql);
   int  (*create_collation)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*));
-  int  (*create_collation16)(sqlite3*,const char*,int,void*,int(*)(void*,int,const void*,int,const void*));
+  int  (*create_collation16)(sqlite3*,const void*,int,void*,int(*)(void*,int,const void*,int,const void*));
   int  (*create_function)(sqlite3*,const char*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*));
   int  (*create_function16)(sqlite3*,const void*,int,int,void*,void (*xFunc)(sqlite3_context*,int,sqlite3_value**),void (*xStep)(sqlite3_context*,int,sqlite3_value**),void (*xFinal)(sqlite3_context*));
   int (*create_module)(sqlite3*,const char*,const sqlite3_module*,void*);
@@ -60644,6 +62682,11 @@
   int (*test_control)(int, ...);
   void (*randomness)(int,void*);
   sqlite3 *(*context_db_handle)(sqlite3_context*);
+  int (*extended_result_codes)(sqlite3*,int);
+  int (*limit)(sqlite3*,int,int);
+  sqlite3_stmt *(*next_stmt)(sqlite3*,sqlite3_stmt*);
+  const char *(*sql)(sqlite3_stmt*);
+  int (*status)(int,int*,int*,int);
 };
 
 /*
@@ -60810,9 +62853,14 @@
 #define sqlite3_test_control           sqlite3_api->test_control
 #define sqlite3_randomness             sqlite3_api->randomness
 #define sqlite3_context_db_handle      sqlite3_api->context_db_handle
+#define sqlite3_extended_result_codes  sqlite3_api->extended_result_codes
+#define sqlite3_limit                  sqlite3_api->limit
+#define sqlite3_next_stmt              sqlite3_api->next_stmt
+#define sqlite3_sql                    sqlite3_api->sql
+#define sqlite3_status                 sqlite3_api->status
 #endif /* SQLITE_CORE */
 
-#define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api;
+#define SQLITE_EXTENSION_INIT1     const sqlite3_api_routines *sqlite3_api = 0;
 #define SQLITE_EXTENSION_INIT2(v)  sqlite3_api = v;
 
 #endif /* _SQLITE3EXT_H_ */
@@ -61102,6 +63150,15 @@
   sqlite3_test_control,
   sqlite3_randomness,
   sqlite3_context_db_handle,
+
+  /*
+  ** Added for 3.6.0
+  */
+  sqlite3_extended_result_codes,
+  sqlite3_limit,
+  sqlite3_next_stmt,
+  sqlite3_sql,
+  sqlite3_status,
 };
 
 /*
@@ -61266,44 +63323,57 @@
 ** loaded by every new database connection.
 */
 SQLITE_API int sqlite3_auto_extension(void *xInit){
-  int i;
   int rc = SQLITE_OK;
+#ifndef SQLITE_OMIT_AUTOINIT
+  rc = sqlite3_initialize();
+  if( rc ){
+    return rc;
+  }else
+#endif
+  {
+    int i;
 #ifndef SQLITE_MUTEX_NOOP
-  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
-  sqlite3_mutex_enter(mutex);
-  for(i=0; i<autoext.nExt; i++){
-    if( autoext.aExt[i]==xInit ) break;
-  }
-  if( i==autoext.nExt ){
-    int nByte = (autoext.nExt+1)*sizeof(autoext.aExt[0]);
-    void **aNew;
-    aNew = sqlite3_realloc(autoext.aExt, nByte);
-    if( aNew==0 ){
-      rc = SQLITE_NOMEM;
-    }else{
-      autoext.aExt = aNew;
-      autoext.aExt[autoext.nExt] = xInit;
-      autoext.nExt++;
+    sqlite3_mutex_enter(mutex);
+    for(i=0; i<autoext.nExt; i++){
+      if( autoext.aExt[i]==xInit ) break;
+    }
+    if( i==autoext.nExt ){
+      int nByte = (autoext.nExt+1)*sizeof(autoext.aExt[0]);
+      void **aNew;
+      aNew = sqlite3_realloc(autoext.aExt, nByte);
+      if( aNew==0 ){
+        rc = SQLITE_NOMEM;
+      }else{
+        autoext.aExt = aNew;
+        autoext.aExt[autoext.nExt] = xInit;
+        autoext.nExt++;
+      }
     }
+    sqlite3_mutex_leave(mutex);
+    assert( (rc&0xff)==rc );
+    return rc;
   }
-  sqlite3_mutex_leave(mutex);
-  assert( (rc&0xff)==rc );
-  return rc;
 }
 
 /*
 ** Reset the automatic extension loading mechanism.
 */
 SQLITE_API void sqlite3_reset_auto_extension(void){
+#ifndef SQLITE_OMIT_AUTOINIT
+  if( sqlite3_initialize()==SQLITE_OK )
+#endif
+  {
 #ifndef SQLITE_MUTEX_NOOP
-  sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
-  sqlite3_mutex_enter(mutex);
-  sqlite3_free(autoext.aExt);
-  autoext.aExt = 0;
-  autoext.nExt = 0;
-  sqlite3_mutex_leave(mutex);
+    sqlite3_mutex_enter(mutex);
+    sqlite3_free(autoext.aExt);
+    autoext.aExt = 0;
+    autoext.nExt = 0;
+    sqlite3_mutex_leave(mutex);
+  }
 }
 
 /*
@@ -61322,7 +63392,7 @@
   for(i=0; go; i++){
     char *zErrmsg = 0;
 #ifndef SQLITE_MUTEX_NOOP
-    sqlite3_mutex *mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_STATIC_MASTER);
+    sqlite3_mutex *mutex = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
 #endif
     sqlite3_mutex_enter(mutex);
     if( i>=autoext.nExt ){
@@ -61359,7 +63429,7 @@
 *************************************************************************
 ** This file contains code used to implement the PRAGMA command.
 **
-** $Id: pragma.c,v 1.176 2008/04/17 20:59:38 drh Exp $
+** $Id: pragma.c,v 1.182 2008/07/08 07:35:52 danielk1977 Exp $
 */
 
 /* Ignore this whole file if pragmas are disabled
@@ -61457,7 +63527,7 @@
 static int invalidateTempStorage(Parse *pParse){
   sqlite3 *db = pParse->db;
   if( db->aDb[1].pBt!=0 ){
-    if( !db->autoCommit ){
+    if( !db->autoCommit || sqlite3BtreeIsInReadTrans(db->aDb[1].pBt) ){
       sqlite3ErrorMsg(pParse, "temporary storage cannot be changed "
         "from within a transaction");
       return SQLITE_ERROR;
@@ -61473,7 +63543,7 @@
 #ifndef SQLITE_OMIT_PAGER_PRAGMAS
 /*
 ** If the TEMP database is open, close it and mark the database schema
-** as needing reloading.  This must be done when using the TEMP_STORE
+** as needing reloading.  This must be done when using the SQLITE_TEMP_STORE
 ** or DEFAULT_TEMP_STORE pragmas.
 */
 static int changeTempStorage(Parse *pParse, const char *zStorageType){
@@ -61725,6 +63795,24 @@
   }else
 
   /*
+  **  PRAGMA [database.]page_count
+  **
+  ** Return the number of pages in the specified database.
+  */
+  if( sqlite3StrICmp(zLeft,"page_count")==0 ){
+    Vdbe *v;
+    int iReg;
+    v = sqlite3GetVdbe(pParse);
+    if( !v || sqlite3ReadSchema(pParse) ) goto pragma_out;
+    sqlite3CodeVerifySchema(pParse, iDb);
+    iReg = ++pParse->nMem;
+    sqlite3VdbeAddOp2(v, OP_Pagecount, iDb, iReg);
+    sqlite3VdbeAddOp2(v, OP_ResultRow, iReg, 1);
+    sqlite3VdbeSetNumCols(v, 1);
+    sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "page_count", P4_STATIC);
+  }else
+
+  /*
   **  PRAGMA [database.]locking_mode
   **  PRAGMA [database.]locking_mode = (normal|exclusive)
   */
@@ -61789,7 +63877,7 @@
       }
     }
     if( pId2->n==0 && eMode==PAGER_JOURNALMODE_QUERY ){
-      /* Simple "PRAGMA persistent_journal;" statement. This is a query for
+      /* Simple "PRAGMA journal_mode;" statement. This is a query for
       ** the current default journal mode (which may be different to
       ** the journal-mode of the main database).
       */
@@ -61827,6 +63915,27 @@
            azModeName[eMode], P4_STATIC);
     sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
   }else
+
+  /*
+  **  PRAGMA [database.]journal_size_limit
+  **  PRAGMA [database.]journal_size_limit=N
+  **
+  ** Get or set the (boolean) value of the database 'auto-vacuum' parameter.
+  */
+  if( sqlite3StrICmp(zLeft,"journal_size_limit")==0 ){
+    Pager *pPager = sqlite3BtreePager(pDb->pBt);
+    i64 iLimit = -2;
+    if( zRight ){
+      int iLimit32 = atoi(zRight);
+      if( iLimit32<-1 ){
+        iLimit32 = -1;
+      }
+      iLimit = iLimit32;
+    }
+    iLimit = sqlite3PagerJournalSizeLimit(pPager, iLimit);
+    returnSingleInt(pParse, "journal_size_limit", (int)iLimit);
+  }else
+
 #endif /* SQLITE_OMIT_PAGER_PRAGMAS */
 
   /*
@@ -61973,15 +64082,17 @@
         sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 1);
       }
     }else{
-      if( zRight[0] 
-       && sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE)==0 
-      ){
-        sqlite3ErrorMsg(pParse, "not a writable directory");
-        goto pragma_out;
+      if( zRight[0] ){
+        int res;
+        sqlite3OsAccess(db->pVfs, zRight, SQLITE_ACCESS_READWRITE, &res);
+        if( res==0 ){
+          sqlite3ErrorMsg(pParse, "not a writable directory");
+          goto pragma_out;
+        }
       }
-      if( TEMP_STORE==0
-       || (TEMP_STORE==1 && db->temp_store<=1)
-       || (TEMP_STORE==2 && db->temp_store==1)
+      if( SQLITE_TEMP_STORE==0
+       || (SQLITE_TEMP_STORE==1 && db->temp_store<=1)
+       || (SQLITE_TEMP_STORE==2 && db->temp_store==1)
       ){
         invalidateTempStorage(pParse);
       }
@@ -62035,6 +64146,7 @@
   ** name:         Procedure name
   ** is_aggregate: True is procedure is an aggregate
   ** nargs:        Number of arguments of the procedure, or -1 if unlimited
+  ** spe_name:     Specific name (unique procedure name)
   */
   if( sqlite3StrICmp(zLeft, "proc_list")==0 ){
     Hash *func_hash;
@@ -62043,20 +64155,25 @@
     if( sqlite3ReadSchema(pParse) ) goto pragma_out;
     func_hash = &(db->aFunc);
 
-    sqlite3VdbeSetNumCols(v, 3);
-    pParse->nMem = 3;
+    sqlite3VdbeSetNumCols(v, 4);
+    pParse->nMem = 4;
     sqlite3VdbeSetColName(v, 0, COLNAME_NAME, "name", P4_STATIC);
     sqlite3VdbeSetColName(v, 1, COLNAME_NAME, "is_aggregate", P4_STATIC);
     sqlite3VdbeSetColName(v, 2, COLNAME_NAME, "nargs", P4_STATIC);
+    sqlite3VdbeSetColName(v, 3, COLNAME_NAME, "spe_name", P4_STATIC);
 
     for (func_elem = sqliteHashFirst (func_hash); func_elem ; func_elem = sqliteHashNext (func_elem)) {
       FuncDef *func;
+      char *sname;
       func = sqliteHashData (func_elem);
 
+      sname = sqlite3_mprintf ("%s_%d_%d", func->zName, func->nArg, func->iPrefEnc);
       sqlite3VdbeAddOp4(v, OP_String8, 0, 1, 0, func->zName, 0);
       sqlite3VdbeAddOp2(v, OP_Integer, func->xFinalize ? 1 : 0, 2);
       sqlite3VdbeAddOp2(v, OP_Integer, func->nArg, 3);
-      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 3);
+      sqlite3VdbeAddOp4(v, OP_String8, 0, 4, 0, sname, 0);
+      sqlite3VdbeAddOp2(v, OP_ResultRow, 1, 4);
+      sqlite3_free (sname);
     }
   }else
 
@@ -62342,7 +64459,7 @@
       sqlite3VdbeAddOp4(v, OP_String8, 0, 3, 0,
          sqlite3MPrintf(db, "*** in database %s ***\n", db->aDb[i].zName),
          P4_DYNAMIC);
-      sqlite3VdbeAddOp2(v, OP_Move, 2, 4);
+      sqlite3VdbeAddOp3(v, OP_Move, 2, 4, 1);
       sqlite3VdbeAddOp3(v, OP_Concat, 4, 3, 2);
       sqlite3VdbeAddOp2(v, OP_ResultRow, 2, 1);
       sqlite3VdbeJumpHere(v, addr);
@@ -62684,7 +64801,7 @@
 ** interface, and routines that contribute to loading the database schema
 ** from disk.
 **
-** $Id: prepare.c,v 1.83 2008/04/03 14:36:26 danielk1977 Exp $
+** $Id: prepare.c,v 1.89 2008/07/08 19:34:07 drh Exp $
 */
 
 /*
@@ -62698,8 +64815,12 @@
 ){
   if( !pData->db->mallocFailed ){
     if( zObj==0 ) zObj = "?";
-    sqlite3SetString(pData->pzErrMsg, "malformed database schema (",  zObj, ")",
-       zExtra!=0 && zExtra[0]!=0 ? " - " : (char*)0, zExtra, (char*)0);
+    sqlite3SetString(pData->pzErrMsg, pData->db,
+       "malformed database schema (%s)", zObj);
+    if( zExtra && zExtra[0] ){
+      *pData->pzErrMsg = sqlite3MPrintf(pData->db, "%z - %s",
+                                  *pData->pzErrMsg, zExtra);
+    }
   }
   pData->rc = SQLITE_CORRUPT;
 }
@@ -62884,7 +65005,7 @@
   sqlite3BtreeEnter(pDb->pBt);
   rc = sqlite3BtreeCursor(pDb->pBt, MASTER_ROOT, 0, 0, curMain);
   if( rc!=SQLITE_OK && rc!=SQLITE_EMPTY ){
-    sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
+    sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
     goto leave_error_out;
   }
 
@@ -62911,7 +65032,7 @@
       rc = sqlite3BtreeGetMeta(pDb->pBt, i+1, (u32 *)&meta[i]);
     }
     if( rc ){
-      sqlite3SetString(pzErrMsg, sqlite3ErrStr(rc), (char*)0);
+      sqlite3SetString(pzErrMsg, db, "%s", sqlite3ErrStr(rc));
       goto leave_error_out;
     }
   }else{
@@ -62932,8 +65053,8 @@
     }else{
       /* If opening an attached database, the encoding much match ENC(db) */
       if( meta[4]!=ENC(db) ){
-        sqlite3SetString(pzErrMsg, "attached databases must use the same"
-            " text encoding as main database", (char*)0);
+        sqlite3SetString(pzErrMsg, db, "attached databases must use the same"
+            " text encoding as main database");
         rc = SQLITE_ERROR;
         goto leave_error_out;
       }
@@ -62943,11 +65064,13 @@
   }
   pDb->pSchema->enc = ENC(db);
 
-  size = meta[2];
-  if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
-  if( size<0 ) size = -size;
-  pDb->pSchema->cache_size = size;
-  sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
+  if( pDb->pSchema->cache_size==0 ){
+    size = meta[2];
+    if( size==0 ){ size = SQLITE_DEFAULT_CACHE_SIZE; }
+    if( size<0 ) size = -size;
+    pDb->pSchema->cache_size = size;
+    sqlite3BtreeSetCacheSize(pDb->pBt, pDb->pSchema->cache_size);
+  }
 
   /*
   ** file_format==1    Version 3.0.0.
@@ -62960,7 +65083,7 @@
     pDb->pSchema->file_format = 1;
   }
   if( pDb->pSchema->file_format>SQLITE_MAX_FILE_FORMAT ){
-    sqlite3SetString(pzErrMsg, "unsupported file format", (char*)0);
+    sqlite3SetString(pzErrMsg, db, "unsupported file format");
     rc = SQLITE_ERROR;
     goto leave_error_out;
   }
@@ -63007,7 +65130,6 @@
 #endif
   }
   if( db->mallocFailed ){
-    /* sqlite3SetString(pzErrMsg, "out of memory", (char*)0); */
     rc = SQLITE_NOMEM;
     sqlite3ResetInternalSchema(db, 0);
   }
@@ -63117,7 +65239,7 @@
   int cookie;
   int allOk = 1;
 
-  curTemp = (BtCursor *)sqlite3_malloc(sqlite3BtreeCursorSize());
+  curTemp = (BtCursor *)sqlite3Malloc(sqlite3BtreeCursorSize());
   if( curTemp ){
     assert( sqlite3_mutex_held(db->mutex) );
     for(iDb=0; allOk && iDb<db->nDb; iDb++){
@@ -63214,20 +65336,20 @@
         const char *zDb = db->aDb[i].zName;
         sqlite3Error(db, SQLITE_LOCKED, "database schema is locked: %s", zDb);
         (void)sqlite3SafetyOff(db);
-        return SQLITE_LOCKED;
+        return sqlite3ApiExit(db, SQLITE_LOCKED);
       }
     }
   }
   
   memset(&sParse, 0, sizeof(sParse));
   sParse.db = db;
-  if( nBytes>=0 && zSql[nBytes-1]!=0 ){
+  if( nBytes>=0 && (nBytes==0 || zSql[nBytes-1]!=0) ){
     char *zSqlCopy;
     int mxLen = db->aLimit[SQLITE_LIMIT_SQL_LENGTH];
     if( nBytes>mxLen ){
       sqlite3Error(db, SQLITE_TOOBIG, "statement too long");
       (void)sqlite3SafetyOff(db);
-      return SQLITE_TOOBIG;
+      return sqlite3ApiExit(db, SQLITE_TOOBIG);
     }
     zSqlCopy = sqlite3DbStrNDup(db, zSql, nBytes);
     if( zSqlCopy ){
@@ -63488,7 +65610,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle SELECT statements in SQLite.
 **
-** $Id: select.c,v 1.429 2008/05/01 17:03:49 drh Exp $
+** $Id: select.c,v 1.457 2008/07/15 20:56:17 drh Exp $
 */
 
 
@@ -63559,8 +65681,6 @@
   assert( pOffset==0 || pLimit!=0 );
   pNew->pLimit = pLimit;
   pNew->pOffset = pOffset;
-  pNew->iLimit = -1;
-  pNew->iOffset = -1;
   pNew->addrOpenEphm[0] = -1;
   pNew->addrOpenEphm[1] = -1;
   pNew->addrOpenEphm[2] = -1;
@@ -63637,12 +65757,11 @@
      (jointype & (JT_INNER|JT_OUTER))==(JT_INNER|JT_OUTER) ||
      (jointype & JT_ERROR)!=0
   ){
-    const char *zSp1 = " ";
-    const char *zSp2 = " ";
-    if( pB==0 ){ zSp1++; }
-    if( pC==0 ){ zSp2++; }
+    const char *zSp = " ";
+    assert( pB!=0 );
+    if( pC==0 ){ zSp++; }
     sqlite3ErrorMsg(pParse, "unknown or unsupported join type: "
-       "%T%s%T%s%T", pA, zSp1, pB, zSp2, pC);
+       "%T %T%s%T", pA, pB, zSp, pC);
     jointype = JT_INNER;
   }else if( jointype & JT_RIGHT ){
     sqlite3ErrorMsg(pParse, 
@@ -63899,15 +66018,15 @@
   int regRecord = sqlite3GetTempReg(pParse);
   sqlite3ExprCodeExprList(pParse, pOrderBy, regBase, 0);
   sqlite3VdbeAddOp2(v, OP_Sequence, pOrderBy->iECursor, regBase+nExpr);
-  sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1);
+  sqlite3ExprCodeMove(pParse, regData, regBase+nExpr+1, 1);
   sqlite3VdbeAddOp3(v, OP_MakeRecord, regBase, nExpr + 2, regRecord);
   sqlite3VdbeAddOp2(v, OP_IdxInsert, pOrderBy->iECursor, regRecord);
   sqlite3ReleaseTempReg(pParse, regRecord);
   sqlite3ReleaseTempRange(pParse, regBase, nExpr+2);
-  if( pSelect->iLimit>=0 ){
+  if( pSelect->iLimit ){
     int addr1, addr2;
     int iLimit;
-    if( pSelect->pOffset ){
+    if( pSelect->iOffset ){
       iLimit = pSelect->iOffset+1;
     }else{
       iLimit = pSelect->iLimit;
@@ -63919,7 +66038,7 @@
     sqlite3VdbeAddOp1(v, OP_Last, pOrderBy->iECursor);
     sqlite3VdbeAddOp1(v, OP_Delete, pOrderBy->iECursor);
     sqlite3VdbeJumpHere(v, addr2);
-    pSelect->iLimit = -1;
+    pSelect->iLimit = 0;
   }
 }
 
@@ -63931,7 +66050,7 @@
   Select *p,        /* The SELECT statement being coded */
   int iContinue     /* Jump here to skip the current record */
 ){
-  if( p->iOffset>=0 && iContinue!=0 ){
+  if( p->iOffset && iContinue!=0 ){
     int addr;
     sqlite3VdbeAddOp2(v, OP_AddImm, p->iOffset, -1);
     addr = sqlite3VdbeAddOp1(v, OP_IfNeg, p->iOffset);
@@ -64008,8 +66127,7 @@
   int distinct,           /* If >=0, make sure results are distinct */
   SelectDest *pDest,      /* How to dispose of the results */
   int iContinue,          /* Jump here to continue with next row */
-  int iBreak,             /* Jump here to break out of the inner loop */
-  char *aff               /* affinity string if eDest is SRT_Union */
+  int iBreak              /* Jump here to break out of the inner loop */
 ){
   Vdbe *v = pParse->pVdbe;
   int i;
@@ -64021,11 +66139,7 @@
 
   if( v==0 ) return;
   assert( pEList!=0 );
-
-  /* If there was a LIMIT clause on the SELECT statement, then do the check
-  ** to see if this row should be output.
-  */
-  hasDistinct = distinct>=0 && pEList->nExpr>0;
+  hasDistinct = distinct>=0;
   if( pOrderBy==0 && !hasDistinct ){
     codeOffset(v, p, iContinue);
   }
@@ -64038,8 +66152,9 @@
     nResultCol = pEList->nExpr;
   }
   if( pDest->iMem==0 ){
-    pDest->iMem = sqlite3GetTempRange(pParse, nResultCol);
+    pDest->iMem = pParse->nMem+1;
     pDest->nMem = nResultCol;
+    pParse->nMem += nResultCol;
   }else if( pDest->nMem!=nResultCol ){
     /* This happens when two SELECTs of a compound SELECT have differing
     ** numbers of result columns.  The error message will be generated by
@@ -64085,9 +66200,6 @@
       int r1;
       r1 = sqlite3GetTempReg(pParse);
       sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
-      if( aff ){
-        sqlite3VdbeChangeP4(v, -1, aff, P4_STATIC);
-      }
       sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
       sqlite3ReleaseTempReg(pParse, r1);
       break;
@@ -64128,10 +66240,7 @@
     ** item into the set table with bogus data.
     */
     case SRT_Set: {
-      int addr2;
-
       assert( nColumn==1 );
-      addr2 = sqlite3VdbeAddOp1(v, OP_IsNull, regResult);
       p->affinity = sqlite3CompareAffinity(pEList->a[0].pExpr, pDest->affinity);
       if( pOrderBy ){
         /* At first glance you would think we could optimize out the
@@ -64146,7 +66255,6 @@
         sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, r1);
         sqlite3ReleaseTempReg(pParse, r1);
       }
-      sqlite3VdbeJumpHere(v, addr2);
       break;
     }
 
@@ -64167,7 +66275,7 @@
       if( pOrderBy ){
         pushOntoSorter(pParse, pOrderBy, p, regResult);
       }else{
-        sqlite3ExprCodeMove(pParse, regResult, iParm);
+        sqlite3ExprCodeMove(pParse, regResult, iParm, 1);
         /* The LIMIT clause will jump out of the loop for us */
       }
       break;
@@ -64178,15 +66286,15 @@
     ** case of a subroutine, the subroutine itself is responsible for
     ** popping the data from the stack.
     */
-    case SRT_Subroutine:
+    case SRT_Coroutine:
     case SRT_Callback: {
       if( pOrderBy ){
         int r1 = sqlite3GetTempReg(pParse);
         sqlite3VdbeAddOp3(v, OP_MakeRecord, regResult, nColumn, r1);
         pushOntoSorter(pParse, pOrderBy, p, r1);
         sqlite3ReleaseTempReg(pParse, r1);
-      }else if( eDest==SRT_Subroutine ){
-        sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
+      }else if( eDest==SRT_Coroutine ){
+        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
       }else{
         sqlite3VdbeAddOp2(v, OP_ResultRow, regResult, nColumn);
         sqlite3ExprCacheAffinityChange(pParse, regResult, nColumn);
@@ -64209,7 +66317,9 @@
 
   /* Jump to the end of the loop if the LIMIT is reached.
   */
-  if( p->iLimit>=0 && pOrderBy==0 ){
+  if( p->iLimit ){
+    assert( pOrderBy==0 );  /* If there is an ORDER BY, the call to
+                            ** pushOntoSorter() would have cleared p->iLimit */
     sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
     sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
   }
@@ -64284,7 +66394,7 @@
   int regRowid;
 
   iTab = pOrderBy->iECursor;
-  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
+  if( eDest==SRT_Callback || eDest==SRT_Coroutine ){
     pseudoTab = pParse->nTab++;
     sqlite3VdbeAddOp2(v, OP_SetNumColumns, 0, nColumn);
     sqlite3VdbeAddOp2(v, OP_OpenPseudo, pseudoTab, eDest==SRT_Callback);
@@ -64304,24 +66414,21 @@
     }
 #ifndef SQLITE_OMIT_SUBQUERY
     case SRT_Set: {
-      int j1;
       assert( nColumn==1 );
-      j1 = sqlite3VdbeAddOp1(v, OP_IsNull, regRow);
       sqlite3VdbeAddOp4(v, OP_MakeRecord, regRow, 1, regRowid, &p->affinity, 1);
       sqlite3ExprCacheAffinityChange(pParse, regRow, 1);
       sqlite3VdbeAddOp2(v, OP_IdxInsert, iParm, regRowid);
-      sqlite3VdbeJumpHere(v, j1);
       break;
     }
     case SRT_Mem: {
       assert( nColumn==1 );
-      sqlite3ExprCodeMove(pParse, regRow, iParm);
+      sqlite3ExprCodeMove(pParse, regRow, iParm, 1);
       /* The LIMIT clause will terminate the loop for us */
       break;
     }
 #endif
     case SRT_Callback:
-    case SRT_Subroutine: {
+    case SRT_Coroutine: {
       int i;
       sqlite3VdbeAddOp2(v, OP_Integer, 1, regRowid);
       sqlite3VdbeAddOp3(v, OP_Insert, pseudoTab, regRow, regRowid);
@@ -64333,7 +66440,7 @@
         sqlite3VdbeAddOp2(v, OP_ResultRow, pDest->iMem, nColumn);
         sqlite3ExprCacheAffinityChange(pParse, pDest->iMem, nColumn);
       }else{
-        sqlite3VdbeAddOp2(v, OP_Gosub, 0, iParm);
+        sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
       }
       break;
     }
@@ -64345,19 +66452,16 @@
   sqlite3ReleaseTempReg(pParse, regRow);
   sqlite3ReleaseTempReg(pParse, regRowid);
 
-  /* Jump to the end of the loop when the LIMIT is reached
+  /* LIMIT has been implemented by the pushOntoSorter() routine.
   */
-  if( p->iLimit>=0 ){
-    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
-    sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, brk);
-  }
+  assert( p->iLimit==0 );
 
   /* The bottom of the loop
   */
   sqlite3VdbeResolveLabel(v, cont);
   sqlite3VdbeAddOp2(v, OP_Next, iTab, addr);
   sqlite3VdbeResolveLabel(v, brk);
-  if( eDest==SRT_Callback || eDest==SRT_Subroutine ){
+  if( eDest==SRT_Callback || eDest==SRT_Coroutine ){
     sqlite3VdbeAddOp2(v, OP_Close, pseudoTab, 0);
   }
 
@@ -64570,9 +66674,7 @@
     if( pEList->a[i].zName ){
       char *zName = pEList->a[i].zName;
       sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, strlen(zName));
-      continue;
-    }
-    if( p->op==TK_COLUMN && pTabList ){
+    }else if( p->op==TK_COLUMN && pTabList ){
       Table *pTab;
       char *zCol;
       int iCol = p->iColumn;
@@ -64586,7 +66688,7 @@
       }else{
         zCol = pTab->aCol[iCol].zName;
       }
-      if( !shortNames && !fullNames && p->span.z && p->span.z[0] ){
+      if( !shortNames && !fullNames ){
         sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
       }else if( fullNames || (!shortNames && pTabList->nSrc>1) ){
         char *zName = 0;
@@ -64594,19 +66696,13 @@
  
         zTab = pTabList->a[j].zAlias;
         if( fullNames || zTab==0 ) zTab = pTab->zName;
-        sqlite3SetString(&zName, zTab, ".", zCol, (char*)0);
+        zName = sqlite3MPrintf(db, "%s.%s", zTab, zCol);
         sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, P4_DYNAMIC);
       }else{
         sqlite3VdbeSetColName(v, i, COLNAME_NAME, zCol, strlen(zCol));
       }
-    }else if( p->span.z && p->span.z[0] ){
-      sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
-      /* sqlite3VdbeCompressSpace(v, addr); */
     }else{
-      char zName[30];
-      assert( p->op!=TK_COLUMN || pTabList==0 );
-      sqlite3_snprintf(sizeof(zName), zName, "column%d", i+1);
-      sqlite3VdbeSetColName(v, i, COLNAME_NAME, zName, 0);
+      sqlite3VdbeSetColName(v, i, COLNAME_NAME, (char*)p->span.z, p->span.n);
     }
   }
   generateColumnTypes(pParse, pTabList, pEList);
@@ -64639,16 +66735,25 @@
 */
 SQLITE_PRIVATE Table *sqlite3ResultSetOfSelect(Parse *pParse, char *zTabName, Select *pSelect){
   Table *pTab;
-  int i, j;
+  int i, j, rc;
   ExprList *pEList;
   Column *aCol, *pCol;
   sqlite3 *db = pParse->db;
+  int savedFlags;
 
-  while( pSelect->pPrior ) pSelect = pSelect->pPrior;
-  if( prepSelectStmt(pParse, pSelect) ){
-    return 0;
+  savedFlags = db->flags;
+  db->flags &= ~SQLITE_FullColNames;
+  db->flags |= SQLITE_ShortColNames;
+  rc = sqlite3SelectResolve(pParse, pSelect, 0);
+  if( rc==SQLITE_OK ){
+    while( pSelect->pPrior ) pSelect = pSelect->pPrior;
+    rc = prepSelectStmt(pParse, pSelect);
+    if( rc==SQLITE_OK ){
+      rc = sqlite3SelectResolve(pParse, pSelect, 0);
+    }
   }
-  if( sqlite3SelectResolve(pParse, pSelect, 0) ){
+  db->flags = savedFlags;
+  if( rc ){
     return 0;
   }
   pTab = sqlite3DbMallocZero(db, sizeof(Table) );
@@ -64662,7 +66767,7 @@
   assert( pTab->nCol>0 );
   pTab->aCol = aCol = sqlite3DbMallocZero(db, sizeof(pTab->aCol[0])*pTab->nCol);
   for(i=0, pCol=aCol; i<pTab->nCol; i++, pCol++){
-    Expr *p, *pR;
+    Expr *p;
     char *zType;
     char *zName;
     int nName;
@@ -64677,16 +66782,14 @@
     if( (zName = pEList->a[i].zName)!=0 ){
       /* If the column contains an "AS <name>" phrase, use <name> as the name */
       zName = sqlite3DbStrDup(db, zName);
-    }else if( p->op==TK_DOT 
-              && (pR=p->pRight)!=0 && pR->token.z && pR->token.z[0] ){
-      /* For columns of the from A.B use B as the name */
-      zName = sqlite3MPrintf(db, "%T", &pR->token);
-    }else if( p->span.z && p->span.z[0] ){
+    }else if( p->op==TK_COLUMN && p->pTab ){
+      /* For columns use the column name name */
+      int iCol = p->iColumn;
+      if( iCol<0 ) iCol = p->pTab->iPKey;
+      zName = sqlite3MPrintf(db, "%s", p->pTab->aCol[iCol].zName);
+    }else{
       /* Use the original text of the column expression as its name */
       zName = sqlite3MPrintf(db, "%T", &p->span);
-    }else{
-      /* If all else fails, make up a name */
-      zName = sqlite3MPrintf(db, "column%d", i+1);
     }
     if( !zName || db->mallocFailed ){
       db->mallocFailed = 1;
@@ -64861,8 +66964,8 @@
     struct ExprList_item *a = pEList->a;
     ExprList *pNew = 0;
     int flags = pParse->db->flags;
-    int longNames = (flags & SQLITE_FullColNames)!=0 &&
-                      (flags & SQLITE_ShortColNames)==0;
+    int longNames = (flags & SQLITE_FullColNames)!=0
+                      && (flags & SQLITE_ShortColNames)==0;
 
     for(k=0; k<pEList->nExpr; k++){
       Expr *pE = a[k].pExpr;
@@ -64894,8 +66997,8 @@
           if( zTabName==0 || zTabName[0]==0 ){ 
             zTabName = pTab->zName;
           }
-          if( zTName && (zTabName==0 || zTabName[0]==0 || 
-                 sqlite3StrICmp(zTName, zTabName)!=0) ){
+          assert( zTabName );
+          if( zTName && sqlite3StrICmp(zTName, zTabName)!=0 ){
             continue;
           }
           tableSeen = 1;
@@ -64929,14 +67032,19 @@
             pRight = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
             if( pRight==0 ) break;
             setQuotedToken(pParse, &pRight->token, zName);
-            if( zTabName && (longNames || pTabList->nSrc>1) ){
+            if( longNames || pTabList->nSrc>1 ){
               Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, 0);
               pExpr = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
               if( pExpr==0 ) break;
               setQuotedToken(pParse, &pLeft->token, zTabName);
+#if 1
               setToken(&pExpr->span, 
                   sqlite3MPrintf(db, "%s.%s", zTabName, zName));
               pExpr->span.dyn = 1;
+#else
+              pExpr->span = pRight->token;
+              pExpr->span.dyn = 0;
+#endif
               pExpr->token.z = 0;
               pExpr->token.n = 0;
               pExpr->token.dyn = 0;
@@ -64982,9 +67090,9 @@
 ** pE is a pointer to an expression which is a single term in
 ** ORDER BY or GROUP BY clause.
 **
-** If pE evaluates to an integer constant i, then return i.
-** This is an indication to the caller that it should sort
-** by the i-th column of the result set.
+** At the point this routine is called, we already know that the
+** ORDER BY term is not an integer index into the result set.  That
+** casee is handled by the calling routine.
 **
 ** If pE is a well-formed expression and the SELECT statement
 ** is not compound, then return 0.  This indicates to the
@@ -65009,20 +67117,8 @@
   ExprList *pEList;  /* The columns of the result set */
   NameContext nc;    /* Name context for resolving pE */
 
-
-  /* If the term is an integer constant, return the value of that
-  ** constant */
+  assert( sqlite3ExprIsInteger(pE, &i)==0 );
   pEList = pSelect->pEList;
-  if( sqlite3ExprIsInteger(pE, &i) ){
-    if( i<=0 ){
-      /* If i is too small, make it too big.  That way the calling
-      ** function still sees a value that is out of range, but does
-      ** not confuse the column number with 0 or -1 result code.
-      */
-      i = pEList->nExpr+1;
-    }
-    return i;
-  }
 
   /* If the term is a simple identifier that try to match that identifier
   ** against a column name in the result set.
@@ -65112,16 +67208,19 @@
   for(i=0; i<pOrderBy->nExpr; i++){
     int iCol;
     Expr *pE = pOrderBy->a[i].pExpr;
-    iCol = matchOrderByTermToExprList(pParse, pSelect, pE, i+1, 0, pHasAgg);
-    if( iCol<0 ){
-      return 1;
-    }
-    if( iCol>pEList->nExpr ){
-      const char *zType = isOrder ? "ORDER" : "GROUP";
-      sqlite3ErrorMsg(pParse, 
-         "%r %s BY term out of range - should be "
-         "between 1 and %d", i+1, zType, pEList->nExpr);
-      return 1;
+    if( sqlite3ExprIsInteger(pE, &iCol) ){
+      if( iCol<=0 || iCol>pEList->nExpr ){
+        const char *zType = isOrder ? "ORDER" : "GROUP";
+        sqlite3ErrorMsg(pParse, 
+           "%r %s BY term out of range - should be "
+           "between 1 and %d", i+1, zType, pEList->nExpr);
+        return 1;
+      }
+    }else{
+      iCol = matchOrderByTermToExprList(pParse, pSelect, pE, i+1, 0, pHasAgg);
+      if( iCol<0 ){
+        return 1;
+      }
     }
     if( iCol>0 ){
       CollSeq *pColl = pE->pColl;
@@ -65142,22 +67241,15 @@
 ** Analyze and ORDER BY or GROUP BY clause in a SELECT statement.  Return
 ** the number of errors seen.
 **
-** The processing depends on whether the SELECT is simple or compound.
-** For a simple SELECT statement, evry term of the ORDER BY or GROUP BY
-** clause needs to be an expression.  If any expression is an integer
-** constant, then that expression is replaced by the corresponding 
-** expression from the result set.
+** If iTable>0 then make the N-th term of the ORDER BY clause refer to
+** the N-th column of table iTable.
 **
-** For compound SELECT statements, every expression needs to be of
-** type TK_COLUMN with a iTable value as given in the 4th parameter.
-** If any expression is an integer, that becomes the column number.
-** Otherwise, match the expression against result set columns from
-** the left-most SELECT.
+** If iTable==0 then transform each term of the ORDER BY clause to refer
+** to a column of the result set by number.
 */
 static int processCompoundOrderBy(
   Parse *pParse,        /* Parsing context.  Leave error messages here */
-  Select *pSelect,      /* The SELECT statement containing the ORDER BY */
-  int iTable            /* Output table for compound SELECT statements */
+  Select *pSelect       /* The SELECT statement containing the ORDER BY */
 ){
   int i;
   ExprList *pOrderBy;
@@ -65182,36 +67274,37 @@
   }
   while( pSelect && moreToDo ){
     moreToDo = 0;
+    pEList = pSelect->pEList;
+    if( pEList==0 ){
+      return 1;
+    }
     for(i=0; i<pOrderBy->nExpr; i++){
       int iCol = -1;
       Expr *pE, *pDup;
       if( pOrderBy->a[i].done ) continue;
       pE = pOrderBy->a[i].pExpr;
-      pDup = sqlite3ExprDup(db, pE);
-      if( !db->mallocFailed ){
-        assert(pDup);
-        iCol = matchOrderByTermToExprList(pParse, pSelect, pDup, i+1, 1, 0);
-      }
-      sqlite3ExprDelete(pDup);
-      if( iCol<0 ){
-        return 1;
-      }
-      pEList = pSelect->pEList;
-      if( pEList==0 ){
-        return 1;
-      }
-      if( iCol>pEList->nExpr ){
-        sqlite3ErrorMsg(pParse, 
-           "%r ORDER BY term out of range - should be "
-           "between 1 and %d", i+1, pEList->nExpr);
-        return 1;
+      if( sqlite3ExprIsInteger(pE, &iCol) ){
+        if( iCol<0 || iCol>pEList->nExpr ){
+          sqlite3ErrorMsg(pParse, 
+             "%r ORDER BY term out of range - should be "
+             "between 1 and %d", i+1, pEList->nExpr);
+          return 1;
+        }
+      }else{
+        pDup = sqlite3ExprDup(db, pE);
+        if( !db->mallocFailed ){
+          assert(pDup);
+          iCol = matchOrderByTermToExprList(pParse, pSelect, pDup, i+1, 1, 0);
+        }
+        sqlite3ExprDelete(pDup);
+        if( iCol<0 ){
+          return 1;
+        }
       }
       if( iCol>0 ){
-        pE->op = TK_COLUMN;
-        pE->iTable = iTable;
-        pE->iAgg = -1;
-        pE->iColumn = iCol-1;
-        pE->pTab = 0;
+        pE->op = TK_INTEGER;
+        pE->flags |= EP_IntValue;
+        pE->iTable = iCol;
         pOrderBy->a[i].done = 1;
       }else{
         moreToDo = 1;
@@ -65270,6 +67363,7 @@
   int iLimit = 0;
   int iOffset;
   int addr1;
+  if( p->iLimit ) return;
 
   /* 
   ** "LIMIT -1" always shows all rows.  There is some
@@ -65309,21 +67403,6 @@
   }
 }
 
-/*
-** Allocate a virtual index to use for sorting.
-*/
-static void createSortingIndex(Parse *pParse, Select *p, ExprList *pOrderBy){
-  if( pOrderBy ){
-    int addr;
-    assert( pOrderBy->iECursor==0 );
-    pOrderBy->iECursor = pParse->nTab++;
-    addr = sqlite3VdbeAddOp2(pParse->pVdbe, OP_OpenEphemeral,
-                            pOrderBy->iECursor, pOrderBy->nExpr+1);
-    assert( p->addrOpenEphm[2] == -1 );
-    p->addrOpenEphm[2] = addr;
-  }
-}
-
 #ifndef SQLITE_OMIT_COMPOUND_SELECT
 /*
 ** Return the appropriate collating sequence for the iCol-th column of
@@ -65347,10 +67426,19 @@
 }
 #endif /* SQLITE_OMIT_COMPOUND_SELECT */
 
+/* Forward reference */
+static int multiSelectOrderBy(
+  Parse *pParse,        /* Parsing context */
+  Select *p,            /* The right-most of SELECTs to be coded */
+  SelectDest *pDest     /* What to do with query results */
+);
+
+
 #ifndef SQLITE_OMIT_COMPOUND_SELECT
 /*
-** This routine is called to process a query that is really the union
-** or intersection of two or more separate queries.
+** This routine is called to process a compound query form from
+** two or more separate queries using UNION, UNION ALL, EXCEPT, or
+** INTERSECT
 **
 ** "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
@@ -65381,19 +67469,13 @@
 static int multiSelect(
   Parse *pParse,        /* Parsing context */
   Select *p,            /* The right-most of SELECTs to be coded */
-  SelectDest *pDest,    /* What to do with query results */
-  char *aff             /* If eDest is SRT_Union, the affinity string */
+  SelectDest *pDest     /* What to do with query results */
 ){
   int rc = SQLITE_OK;   /* Success code from a subroutine */
   Select *pPrior;       /* Another SELECT immediately to our left */
   Vdbe *v;              /* Generate code to this VDBE */
-  int nCol;             /* Number of columns in the result set */
-  ExprList *pOrderBy;   /* The ORDER BY clause on p */
-  int aSetP2[2];        /* Set P2 value of these op to number of columns */
-  int nSetP2 = 0;       /* Number of slots in aSetP2[] used */
   SelectDest dest;      /* Alternative data destination */
-
-  dest = *pDest;
+  Select *pDelete = 0;  /* Chain of simple selects to delete */
 
   /* Make sure there is no ORDER BY or LIMIT clause on prior SELECTs.  Only
   ** the last (right-most) SELECT in the series may have an ORDER BY or LIMIT.
@@ -65428,47 +67510,61 @@
 
   /* Create the destination temporary table if necessary
   */
+  dest = *pDest;
   if( dest.eDest==SRT_EphemTab ){
     assert( p->pEList );
-    assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
-    aSetP2[nSetP2++] = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, 0);
+    sqlite3VdbeAddOp2(v, OP_OpenEphemeral, dest.iParm, p->pEList->nExpr);
     dest.eDest = SRT_Table;
   }
 
+  /* Make sure all SELECTs in the statement have the same number of elements
+  ** in their result sets.
+  */
+  assert( p->pEList && pPrior->pEList );
+  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
+    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
+      " do not have the same number of result columns", selectOpName(p->op));
+    rc = 1;
+    goto multi_select_end;
+  }
+
+  /* Compound SELECTs that have an ORDER BY clause are handled separately.
+  */
+  if( p->pOrderBy ){
+    return multiSelectOrderBy(pParse, p, pDest);
+  }
+
   /* Generate code for the left and right SELECT statements.
   */
-  pOrderBy = p->pOrderBy;
   switch( p->op ){
     case TK_ALL: {
-      if( pOrderBy==0 ){
-        int addr = 0;
-        assert( !pPrior->pLimit );
-        pPrior->pLimit = p->pLimit;
-        pPrior->pOffset = p->pOffset;
-        rc = sqlite3Select(pParse, pPrior, &dest, 0, 0, 0, aff);
-        p->pLimit = 0;
-        p->pOffset = 0;
-        if( rc ){
-          goto multi_select_end;
-        }
-        p->pPrior = 0;
-        p->iLimit = pPrior->iLimit;
-        p->iOffset = pPrior->iOffset;
-        if( p->iLimit>=0 ){
-          addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
-          VdbeComment((v, "Jump ahead if LIMIT reached"));
-        }
-        rc = sqlite3Select(pParse, p, &dest, 0, 0, 0, aff);
-        p->pPrior = pPrior;
-        if( rc ){
-          goto multi_select_end;
-        }
-        if( addr ){
-          sqlite3VdbeJumpHere(v, addr);
-        }
-        break;
+      int addr = 0;
+      assert( !pPrior->pLimit );
+      pPrior->pLimit = p->pLimit;
+      pPrior->pOffset = p->pOffset;
+      rc = sqlite3Select(pParse, pPrior, &dest, 0, 0, 0);
+      p->pLimit = 0;
+      p->pOffset = 0;
+      if( rc ){
+        goto multi_select_end;
+      }
+      p->pPrior = 0;
+      p->iLimit = pPrior->iLimit;
+      p->iOffset = pPrior->iOffset;
+      if( p->iLimit ){
+        addr = sqlite3VdbeAddOp1(v, OP_IfZero, p->iLimit);
+        VdbeComment((v, "Jump ahead if LIMIT reached"));
+      }
+      rc = sqlite3Select(pParse, p, &dest, 0, 0, 0);
+      pDelete = p->pPrior;
+      p->pPrior = pPrior;
+      if( rc ){
+        goto multi_select_end;
+      }
+      if( addr ){
+        sqlite3VdbeJumpHere(v, addr);
       }
-      /* For UNION ALL ... ORDER BY fall through to the next case */
+      break;
     }
     case TK_EXCEPT:
     case TK_UNION: {
@@ -65479,8 +67575,8 @@
       int addr;
       SelectDest uniondest;
 
-      priorOp = p->op==TK_ALL ? SRT_Table : SRT_Union;
-      if( dest.eDest==priorOp && pOrderBy==0 && !p->pLimit && !p->pOffset ){
+      priorOp = SRT_Union;
+      if( dest.eDest==priorOp && !p->pLimit && !p->pOffset ){
         /* We can reuse a temporary table generated by a SELECT to our
         ** right.
         */
@@ -65490,20 +67586,11 @@
         ** intermediate results.
         */
         unionTab = pParse->nTab++;
-        if( processCompoundOrderBy(pParse, p, unionTab) ){
-          rc = 1;
-          goto multi_select_end;
-        }
+        assert( p->pOrderBy==0 );
         addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, unionTab, 0);
-        if( priorOp==SRT_Table ){
-          assert( nSetP2<sizeof(aSetP2)/sizeof(aSetP2[0]) );
-          aSetP2[nSetP2++] = addr;
-        }else{
-          assert( p->addrOpenEphm[0] == -1 );
-          p->addrOpenEphm[0] = addr;
-          p->pRightmost->usesEphm = 1;
-        }
-        createSortingIndex(pParse, p, pOrderBy);
+        assert( p->addrOpenEphm[0] == -1 );
+        p->addrOpenEphm[0] = addr;
+        p->pRightmost->usesEphm = 1;
         assert( p->pEList );
       }
 
@@ -65511,7 +67598,7 @@
       */
       assert( !pPrior->pOrderBy );
       sqlite3SelectDestInit(&uniondest, priorOp, unionTab);
-      rc = sqlite3Select(pParse, pPrior, &uniondest, 0, 0, 0, aff);
+      rc = sqlite3Select(pParse, pPrior, &uniondest, 0, 0, 0);
       if( rc ){
         goto multi_select_end;
       }
@@ -65524,24 +67611,24 @@
          case TK_ALL:     op = SRT_Table;    break;
       }
       p->pPrior = 0;
-      p->pOrderBy = 0;
-      p->disallowOrderBy = pOrderBy!=0;
+      p->disallowOrderBy = 0;
       pLimit = p->pLimit;
       p->pLimit = 0;
       pOffset = p->pOffset;
       p->pOffset = 0;
       uniondest.eDest = op;
-      rc = sqlite3Select(pParse, p, &uniondest, 0, 0, 0, aff);
+      rc = sqlite3Select(pParse, p, &uniondest, 0, 0, 0);
       /* Query flattening in sqlite3Select() might refill p->pOrderBy.
       ** Be sure to delete p->pOrderBy, therefore, to avoid a memory leak. */
       sqlite3ExprListDelete(p->pOrderBy);
+      pDelete = p->pPrior;
       p->pPrior = pPrior;
-      p->pOrderBy = pOrderBy;
+      p->pOrderBy = 0;
       sqlite3ExprDelete(p->pLimit);
       p->pLimit = pLimit;
       p->pOffset = pOffset;
-      p->iLimit = -1;
-      p->iOffset = -1;
+      p->iLimit = 0;
+      p->iOffset = 0;
       if( rc ){
         goto multi_select_end;
       }
@@ -65564,7 +67651,7 @@
         sqlite3VdbeAddOp2(v, OP_Rewind, unionTab, iBreak);
         iStart = sqlite3VdbeCurrentAddr(v);
         selectInnerLoop(pParse, p, p->pEList, unionTab, p->pEList->nExpr,
-                        pOrderBy, -1, &dest, iCont, iBreak, 0);
+                        0, -1, &dest, iCont, iBreak);
         sqlite3VdbeResolveLabel(v, iCont);
         sqlite3VdbeAddOp2(v, OP_Next, unionTab, iStart);
         sqlite3VdbeResolveLabel(v, iBreak);
@@ -65586,11 +67673,7 @@
       */
       tab1 = pParse->nTab++;
       tab2 = pParse->nTab++;
-      if( processCompoundOrderBy(pParse, p, tab1) ){
-        rc = 1;
-        goto multi_select_end;
-      }
-      createSortingIndex(pParse, p, pOrderBy);
+      assert( p->pOrderBy==0 );
 
       addr = sqlite3VdbeAddOp2(v, OP_OpenEphemeral, tab1, 0);
       assert( p->addrOpenEphm[0] == -1 );
@@ -65601,7 +67684,7 @@
       /* Code the SELECTs to our left into temporary table "tab1".
       */
       sqlite3SelectDestInit(&intersectdest, SRT_Union, tab1);
-      rc = sqlite3Select(pParse, pPrior, &intersectdest, 0, 0, 0, aff);
+      rc = sqlite3Select(pParse, pPrior, &intersectdest, 0, 0, 0);
       if( rc ){
         goto multi_select_end;
       }
@@ -65617,7 +67700,8 @@
       pOffset = p->pOffset;
       p->pOffset = 0;
       intersectdest.iParm = tab2;
-      rc = sqlite3Select(pParse, p, &intersectdest, 0, 0, 0, aff);
+      rc = sqlite3Select(pParse, p, &intersectdest, 0, 0, 0);
+      pDelete = p->pPrior;
       p->pPrior = pPrior;
       sqlite3ExprDelete(p->pLimit);
       p->pLimit = pLimit;
@@ -65644,7 +67728,7 @@
       sqlite3VdbeAddOp3(v, OP_NotFound, tab2, iCont, r1);
       sqlite3ReleaseTempReg(pParse, r1);
       selectInnerLoop(pParse, p, p->pEList, tab1, p->pEList->nExpr,
-                      pOrderBy, -1, &dest, iCont, iBreak, 0);
+                      0, -1, &dest, iCont, iBreak);
       sqlite3VdbeResolveLabel(v, iCont);
       sqlite3VdbeAddOp2(v, OP_Next, tab1, iStart);
       sqlite3VdbeResolveLabel(v, iBreak);
@@ -65654,46 +67738,26 @@
     }
   }
 
-  /* Make sure all SELECTs in the statement have the same number of elements
-  ** in their result sets.
-  */
-  assert( p->pEList && pPrior->pEList );
-  if( p->pEList->nExpr!=pPrior->pEList->nExpr ){
-    sqlite3ErrorMsg(pParse, "SELECTs to the left and right of %s"
-      " do not have the same number of result columns", selectOpName(p->op));
-    rc = 1;
-    goto multi_select_end;
-  }
-
-  /* Set the number of columns in temporary tables
-  */
-  nCol = p->pEList->nExpr;
-  while( nSetP2 ){
-    sqlite3VdbeChangeP2(v, aSetP2[--nSetP2], nCol);
-  }
-
-  /* Compute collating sequences used by either the ORDER BY clause or
-  ** by any temporary tables needed to implement the compound select.
-  ** Attach the KeyInfo structure to all temporary tables.  Invoke the
-  ** ORDER BY processing if there is an ORDER BY clause.
+  /* Compute collating sequences used by 
+  ** temporary tables needed to implement the compound select.
+  ** Attach the KeyInfo structure to all temporary tables.
   **
   ** This section is run by the right-most SELECT statement only.
   ** SELECT statements to the left always skip this part.  The right-most
   ** SELECT might also skip this part if it has no ORDER BY clause and
   ** no temp tables are required.
   */
-  if( pOrderBy || p->usesEphm ){
+  if( p->usesEphm ){
     int i;                        /* Loop counter */
     KeyInfo *pKeyInfo;            /* Collating sequence for the result set */
     Select *pLoop;                /* For looping through SELECT statements */
-    int nKeyCol;                  /* Number of entries in pKeyInfo->aCol[] */
     CollSeq **apColl;             /* For looping through pKeyInfo->aColl[] */
-    CollSeq **aCopy;              /* A copy of pKeyInfo->aColl[] */
+    int nCol;                     /* Number of columns in result set */
 
     assert( p->pRightmost==p );
-    nKeyCol = nCol + (pOrderBy ? pOrderBy->nExpr : 0);
+    nCol = p->pEList->nExpr;
     pKeyInfo = sqlite3DbMallocZero(pParse->db,
-                       sizeof(*pKeyInfo)+nKeyCol*(sizeof(CollSeq*) + 1));
+                       sizeof(*pKeyInfo)+nCol*(sizeof(CollSeq*) + 1));
     if( !pKeyInfo ){
       rc = SQLITE_NOMEM;
       goto multi_select_end;
@@ -65723,60 +67787,607 @@
         pLoop->addrOpenEphm[i] = -1;
       }
     }
+    sqlite3_free(pKeyInfo);
+  }
 
-    if( pOrderBy ){
-      struct ExprList_item *pOTerm = pOrderBy->a;
-      int nOrderByExpr = pOrderBy->nExpr;
-      int addr;
-      u8 *pSortOrder;
+multi_select_end:
+  pDest->iMem = dest.iMem;
+  pDest->nMem = dest.nMem;
+  sqlite3SelectDelete(pDelete);
+  return rc;
+}
+#endif /* SQLITE_OMIT_COMPOUND_SELECT */
 
-      /* Reuse the same pKeyInfo for the ORDER BY as was used above for
-      ** the compound select statements.  Except we have to change out the
-      ** pKeyInfo->aColl[] values.  Some of the aColl[] values will be
-      ** reused when constructing the pKeyInfo for the ORDER BY, so make
-      ** a copy.  Sufficient space to hold both the nCol entries for
-      ** the compound select and the nOrderbyExpr entries for the ORDER BY
-      ** was allocated above.  But we need to move the compound select
-      ** entries out of the way before constructing the ORDER BY entries.
-      ** Move the compound select entries into aCopy[] where they can be
-      ** accessed and reused when constructing the ORDER BY entries.
-      ** Because nCol might be greater than or less than nOrderByExpr
-      ** we have to use memmove() when doing the copy.
-      */
-      aCopy = &pKeyInfo->aColl[nOrderByExpr];
-      pSortOrder = pKeyInfo->aSortOrder = (u8*)&aCopy[nCol];
-      memmove(aCopy, pKeyInfo->aColl, nCol*sizeof(CollSeq*));
-
-      apColl = pKeyInfo->aColl;
-      for(i=0; i<nOrderByExpr; i++, pOTerm++, apColl++, pSortOrder++){
-        Expr *pExpr = pOTerm->pExpr;
-        if( (pExpr->flags & EP_ExpCollate) ){
-          assert( pExpr->pColl!=0 );
-          *apColl = pExpr->pColl;
+/*
+** Code an output subroutine for a coroutine implementation of a
+** SELECT statment.
+**
+** The data to be output is contained in pIn->iMem.  There are
+** pIn->nMem columns to be output.  pDest is where the output should
+** be sent.
+**
+** regReturn is the number of the register holding the subroutine
+** return address.
+**
+** If regPrev>0 then it is a the first register in a vector that
+** records the previous output.  mem[regPrev] is a flag that is false
+** if there has been no previous output.  If regPrev>0 then code is
+** generated to suppress duplicates.  pKeyInfo is used for comparing
+** keys.
+**
+** If the LIMIT found in p->iLimit is reached, jump immediately to
+** iBreak.
+*/
+static int generateOutputSubroutine(
+  Parse *pParse,          /* Parsing context */
+  Select *p,              /* The SELECT statement */
+  SelectDest *pIn,        /* Coroutine supplying data */
+  SelectDest *pDest,      /* Where to send the data */
+  int regReturn,          /* The return address register */
+  int regPrev,            /* Previous result register.  No uniqueness if 0 */
+  KeyInfo *pKeyInfo,      /* For comparing with previous entry */
+  int p4type,             /* The p4 type for pKeyInfo */
+  int iBreak              /* Jump here if we hit the LIMIT */
+){
+  Vdbe *v = pParse->pVdbe;
+  int iContinue;
+  int addr;
+
+  addr = sqlite3VdbeCurrentAddr(v);
+  iContinue = sqlite3VdbeMakeLabel(v);
+
+  /* Suppress duplicates for UNION, EXCEPT, and INTERSECT 
+  */
+  if( regPrev ){
+    int j1, j2;
+    j1 = sqlite3VdbeAddOp1(v, OP_IfNot, regPrev);
+    j2 = sqlite3VdbeAddOp4(v, OP_Compare, pIn->iMem, regPrev+1, pIn->nMem,
+                              (char*)pKeyInfo, p4type);
+    sqlite3VdbeAddOp3(v, OP_Jump, j2+2, iContinue, j2+2);
+    sqlite3VdbeJumpHere(v, j1);
+    sqlite3ExprCodeCopy(pParse, pIn->iMem, regPrev+1, pIn->nMem);
+    sqlite3VdbeAddOp2(v, OP_Integer, 1, regPrev);
+  }
+  if( pParse->db->mallocFailed ) return 0;
+
+  /* Suppress the the first OFFSET entries if there is an OFFSET clause
+  */
+  codeOffset(v, p, iContinue);
+
+  switch( pDest->eDest ){
+    /* Store the result as data using a unique key.
+    */
+    case SRT_Table:
+    case SRT_EphemTab: {
+      int r1 = sqlite3GetTempReg(pParse);
+      int r2 = sqlite3GetTempReg(pParse);
+      sqlite3VdbeAddOp3(v, OP_MakeRecord, pIn->iMem, pIn->nMem, r1);
+      sqlite3VdbeAddOp2(v, OP_NewRowid, pDest->iParm, r2);
+      sqlite3VdbeAddOp3(v, OP_Insert, pDest->iParm, r1, r2);
+      sqlite3VdbeChangeP5(v, OPFLAG_APPEND);
+      sqlite3ReleaseTempReg(pParse, r2);
+      sqlite3ReleaseTempReg(pParse, r1);
+      break;
+    }
+
+#ifndef SQLITE_OMIT_SUBQUERY
+    /* If we are creating a set for an "expr IN (SELECT ...)" construct,
+    ** then there should be a single item on the stack.  Write this
+    ** item into the set table with bogus data.
+    */
+    case SRT_Set: {
+      int r1;
+      assert( pIn->nMem==1 );
+      p->affinity = 
+         sqlite3CompareAffinity(p->pEList->a[0].pExpr, pDest->affinity);
+      r1 = sqlite3GetTempReg(pParse);
+      sqlite3VdbeAddOp4(v, OP_MakeRecord, pIn->iMem, 1, r1, &p->affinity, 1);
+      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, 1);
+      sqlite3VdbeAddOp2(v, OP_IdxInsert, pDest->iParm, r1);
+      sqlite3ReleaseTempReg(pParse, r1);
+      break;
+    }
+
+#if 0  /* Never occurs on an ORDER BY query */
+    /* If any row exist in the result set, record that fact and abort.
+    */
+    case SRT_Exists: {
+      sqlite3VdbeAddOp2(v, OP_Integer, 1, pDest->iParm);
+      /* The LIMIT clause will terminate the loop for us */
+      break;
+    }
+#endif
+
+    /* If this is a scalar select that is part of an expression, then
+    ** store the results in the appropriate memory cell and break out
+    ** of the scan loop.
+    */
+    case SRT_Mem: {
+      assert( pIn->nMem==1 );
+      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iParm, 1);
+      /* The LIMIT clause will jump out of the loop for us */
+      break;
+    }
+#endif /* #ifndef SQLITE_OMIT_SUBQUERY */
+
+    /* Send the data to the callback function or to a subroutine.  In the
+    ** case of a subroutine, the subroutine itself is responsible for
+    ** popping the data from the stack.
+    */
+    case SRT_Coroutine: {
+      if( pDest->iMem==0 ){
+        pDest->iMem = sqlite3GetTempRange(pParse, pIn->nMem);
+        pDest->nMem = pIn->nMem;
+      }
+      sqlite3ExprCodeMove(pParse, pIn->iMem, pDest->iMem, pDest->nMem);
+      sqlite3VdbeAddOp1(v, OP_Yield, pDest->iParm);
+      break;
+    }
+
+    case SRT_Callback: {
+      sqlite3VdbeAddOp2(v, OP_ResultRow, pIn->iMem, pIn->nMem);
+      sqlite3ExprCacheAffinityChange(pParse, pIn->iMem, pIn->nMem);
+      break;
+    }
+
+#if !defined(SQLITE_OMIT_TRIGGER)
+    /* Discard the results.  This is used for SELECT statements inside
+    ** the body of a TRIGGER.  The purpose of such selects is to call
+    ** user-defined functions that have side effects.  We do not care
+    ** about the actual results of the select.
+    */
+    default: {
+      break;
+    }
+#endif
+  }
+
+  /* Jump to the end of the loop if the LIMIT is reached.
+  */
+  if( p->iLimit ){
+    sqlite3VdbeAddOp2(v, OP_AddImm, p->iLimit, -1);
+    sqlite3VdbeAddOp2(v, OP_IfZero, p->iLimit, iBreak);
+  }
+
+  /* Generate the subroutine return
+  */
+  sqlite3VdbeResolveLabel(v, iContinue);
+  sqlite3VdbeAddOp1(v, OP_Return, regReturn);
+
+  return addr;
+}
+
+/*
+** Alternative compound select code generator for cases when there
+** is an ORDER BY clause.
+**
+** We assume a query of the following form:
+**
+**      <selectA>  <operator>  <selectB>  ORDER BY <orderbylist>
+**
+** <operator> is one of UNION ALL, UNION, EXCEPT, or INTERSECT.  The idea
+** is to code both <selectA> and <selectB> with the ORDER BY clause as
+** co-routines.  Then run the co-routines in parallel and merge the results
+** into the output.  In addition to the two coroutines (called selectA and
+** selectB) there are 7 subroutines:
+**
+**    outA:    Move the output of the selectA coroutine into the output
+**             of the compound query.
+**
+**    outB:    Move the output of the selectB coroutine into the output
+**             of the compound query.  (Only generated for UNION and
+**             UNION ALL.  EXCEPT and INSERTSECT never output a row that
+**             appears only in B.)
+**
+**    AltB:    Called when there is data from both coroutines and A<B.
+**
+**    AeqB:    Called when there is data from both coroutines and A==B.
+**
+**    AgtB:    Called when there is data from both coroutines and A>B.
+**
+**    EofA:    Called when data is exhausted from selectA.
+**
+**    EofB:    Called when data is exhausted from selectB.
+**
+** The implementation of the latter five subroutines depend on which 
+** <operator> is used:
+**
+**
+**             UNION ALL         UNION            EXCEPT          INTERSECT
+**          -------------  -----------------  --------------  -----------------
+**   AltB:   outA, nextA      outA, nextA       outA, nextA         nextA
+**
+**   AeqB:   outA, nextA         nextA             nextA         outA, nextA
+**
+**   AgtB:   outB, nextB      outB, nextB          nextB            nextB
+**
+**   EofA:   outB, nextB      outB, nextB          halt             halt
+**
+**   EofB:   outA, nextA      outA, nextA       outA, nextA         halt
+**
+** In the AltB, AeqB, and AgtB subroutines, an EOF on A following nextA
+** causes an immediate jump to EofA and an EOF on B following nextB causes
+** an immediate jump to EofB.  Within EofA and EofB, and EOF on entry or
+** following nextX causes a jump to the end of the select processing.
+**
+** Duplicate removal in the UNION, EXCEPT, and INTERSECT cases is handled
+** within the output subroutine.  The regPrev register set holds the previously
+** output value.  A comparison is made against this value and the output
+** is skipped if the next results would be the same as the previous.
+**
+** The implementation plan is to implement the two coroutines and seven
+** subroutines first, then put the control logic at the bottom.  Like this:
+**
+**          goto Init
+**     coA: coroutine for left query (A)
+**     coB: coroutine for right query (B)
+**    outA: output one row of A
+**    outB: output one row of B (UNION and UNION ALL only)
+**    EofA: ...
+**    EofB: ...
+**    AltB: ...
+**    AeqB: ...
+**    AgtB: ...
+**    Init: initialize coroutine registers
+**          yield coA
+**          if eof(A) goto EofA
+**          yield coB
+**          if eof(B) goto EofB
+**    Cmpr: Compare A, B
+**          Jump AltB, AeqB, AgtB
+**     End: ...
+**
+** 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,
+** and AgtB jump to either L2 or to one of EofA or EofB.
+*/
+static int multiSelectOrderBy(
+  Parse *pParse,        /* Parsing context */
+  Select *p,            /* The right-most of SELECTs to be coded */
+  SelectDest *pDest     /* What to do with query results */
+){
+  int i, j;             /* Loop counters */
+  Select *pPrior;       /* Another SELECT immediately to our left */
+  Vdbe *v;              /* Generate code to this VDBE */
+  SelectDest destA;     /* Destination for coroutine A */
+  SelectDest destB;     /* Destination for coroutine B */
+  int regAddrA;         /* Address register for select-A coroutine */
+  int regEofA;          /* Flag to indicate when select-A is complete */
+  int regAddrB;         /* Address register for select-B coroutine */
+  int regEofB;          /* Flag to indicate when select-B is complete */
+  int addrSelectA;      /* Address of the select-A coroutine */
+  int addrSelectB;      /* Address of the select-B coroutine */
+  int regOutA;          /* Address register for the output-A subroutine */
+  int regOutB;          /* Address register for the output-B subroutine */
+  int addrOutA;         /* Address of the output-A subroutine */
+  int addrOutB;         /* Address of the output-B subroutine */
+  int addrEofA;         /* Address of the select-A-exhausted subroutine */
+  int addrEofB;         /* Address of the select-B-exhausted subroutine */
+  int addrAltB;         /* Address of the A<B subroutine */
+  int addrAeqB;         /* Address of the A==B subroutine */
+  int addrAgtB;         /* Address of the A>B subroutine */
+  int regLimitA;        /* Limit register for select-A */
+  int regLimitB;        /* Limit register for select-A */
+  int regPrev;          /* A range of registers to hold previous output */
+  int savedLimit;       /* Saved value of p->iLimit */
+  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 j1;               /* Jump instructions that get retargetted */
+  int op;               /* One of TK_ALL, TK_UNION, TK_EXCEPT, TK_INTERSECT */
+  KeyInfo *pKeyDup;     /* Comparison information for duplicate removal */
+  KeyInfo *pKeyMerge;   /* Comparison information for merging rows */
+  sqlite3 *db;          /* Database connection */
+  ExprList *pOrderBy;   /* The ORDER BY clause */
+  int nOrderBy;         /* Number of terms in the ORDER BY clause */
+  int *aPermute;        /* Mapping from ORDER BY terms to result set columns */
+  u8 NotUsed;           /* Dummy variables */
+
+  assert( p->pOrderBy!=0 );
+  db = pParse->db;
+  v = pParse->pVdbe;
+  if( v==0 ) return SQLITE_NOMEM;
+  labelEnd = sqlite3VdbeMakeLabel(v);
+  labelCmpr = sqlite3VdbeMakeLabel(v);
+
+
+  /* Patch up the ORDER BY clause
+  */
+  op = p->op;  
+  pPrior = p->pPrior;
+  assert( pPrior->pOrderBy==0 );
+  pOrderBy = p->pOrderBy;
+  assert( pOrderBy );
+  if( processCompoundOrderBy(pParse, p) ){
+    return SQLITE_ERROR;
+  }
+  nOrderBy = pOrderBy->nExpr;
+
+  /* For operators other than UNION ALL we have to make sure that
+  ** the ORDER BY clause covers every term of the result set.  Add
+  ** terms to the ORDER BY clause as necessary.
+  */
+  if( op!=TK_ALL ){
+    for(i=1; db->mallocFailed==0 && i<=p->pEList->nExpr; i++){
+      for(j=0; j<nOrderBy; j++){
+        Expr *pTerm = pOrderBy->a[j].pExpr;
+        assert( pTerm->op==TK_INTEGER );
+        assert( (pTerm->flags & EP_IntValue)!=0 );
+        if( pTerm->iTable==i ) break;
+      }
+      if( j==nOrderBy ){
+        Expr *pNew = sqlite3PExpr(pParse, TK_INTEGER, 0, 0, 0);
+        if( pNew==0 ) return SQLITE_NOMEM;
+        pNew->flags |= EP_IntValue;
+        pNew->iTable = i;
+        pOrderBy = sqlite3ExprListAppend(pParse, pOrderBy, pNew, 0);
+        nOrderBy++;
+      }
+    }
+  }
+
+  /* Compute the comparison permutation and keyinfo that is used with
+  ** the permutation in order to comparisons to determine if the next
+  ** row of results comes from selectA or selectB.  Also add explicit
+  ** collations to the ORDER BY clause terms so that when the subqueries
+  ** to the right and the left are evaluated, they use the correct
+  ** collation.
+  */
+  aPermute = sqlite3DbMallocRaw(db, sizeof(int)*nOrderBy);
+  if( aPermute ){
+    for(i=0; i<nOrderBy; i++){
+      Expr *pTerm = pOrderBy->a[i].pExpr;
+      assert( pTerm->op==TK_INTEGER );
+      assert( (pTerm->flags & EP_IntValue)!=0 );
+      aPermute[i] = pTerm->iTable-1;
+      assert( aPermute[i]>=0 && aPermute[i]<p->pEList->nExpr );
+    }
+    pKeyMerge =
+      sqlite3DbMallocRaw(db, sizeof(*pKeyMerge)+nOrderBy*(sizeof(CollSeq*)+1));
+    if( pKeyMerge ){
+      pKeyMerge->aSortOrder = (u8*)&pKeyMerge->aColl[nOrderBy];
+      pKeyMerge->nField = nOrderBy;
+      pKeyMerge->enc = ENC(db);
+      for(i=0; i<nOrderBy; i++){
+        CollSeq *pColl;
+        Expr *pTerm = pOrderBy->a[i].pExpr;
+        if( pTerm->flags & EP_ExpCollate ){
+          pColl = pTerm->pColl;
         }else{
-          *apColl = aCopy[pExpr->iColumn];
+          pColl = multiSelectCollSeq(pParse, p, aPermute[i]);
+          pTerm->flags |= EP_ExpCollate;
+          pTerm->pColl = pColl;
         }
-        *pSortOrder = pOTerm->sortOrder;
+        pKeyMerge->aColl[i] = pColl;
+        pKeyMerge->aSortOrder[i] = pOrderBy->a[i].sortOrder;
       }
-      assert( p->pRightmost==p );
-      assert( p->addrOpenEphm[2]>=0 );
-      addr = p->addrOpenEphm[2];
-      sqlite3VdbeChangeP2(v, addr, p->pOrderBy->nExpr+2);
-      pKeyInfo->nField = nOrderByExpr;
-      sqlite3VdbeChangeP4(v, addr, (char*)pKeyInfo, P4_KEYINFO_HANDOFF);
-      pKeyInfo = 0;
-      generateSortTail(pParse, p, v, p->pEList->nExpr, &dest);
     }
+  }else{
+    pKeyMerge = 0;
+  }
 
-    sqlite3_free(pKeyInfo);
+  /* Reattach the ORDER BY clause to the query.
+  */
+  p->pOrderBy = pOrderBy;
+  pPrior->pOrderBy = sqlite3ExprListDup(pParse->db, pOrderBy);
+
+  /* Allocate a range of temporary registers and the KeyInfo needed
+  ** for the logic that removes duplicate result rows when the
+  ** operator is UNION, EXCEPT, or INTERSECT (but not UNION ALL).
+  */
+  if( op==TK_ALL ){
+    regPrev = 0;
+  }else{
+    int nExpr = p->pEList->nExpr;
+    assert( nOrderBy>=nExpr );
+    regPrev = sqlite3GetTempRange(pParse, nExpr+1);
+    sqlite3VdbeAddOp2(v, OP_Integer, 0, regPrev);
+    pKeyDup = sqlite3DbMallocZero(db,
+                  sizeof(*pKeyDup) + nExpr*(sizeof(CollSeq*)+1) );
+    if( pKeyDup ){
+      pKeyDup->aSortOrder = (u8*)&pKeyDup->aColl[nExpr];
+      pKeyDup->nField = nExpr;
+      pKeyDup->enc = ENC(db);
+      for(i=0; i<nExpr; i++){
+        pKeyDup->aColl[i] = multiSelectCollSeq(pParse, p, i);
+        pKeyDup->aSortOrder[i] = 0;
+      }
+    }
+  }
+ 
+  /* Separate the left and the right query from one another
+  */
+  p->pPrior = 0;
+  pPrior->pRightmost = 0;
+  processOrderGroupBy(pParse, p, p->pOrderBy, 1, &NotUsed);
+  if( pPrior->pPrior==0 ){
+    processOrderGroupBy(pParse, pPrior, pPrior->pOrderBy, 1, &NotUsed);
+  }
+
+  /* Compute the limit registers */
+  computeLimitRegisters(pParse, p, labelEnd);
+  if( p->iLimit && op==TK_ALL ){
+    regLimitA = ++pParse->nMem;
+    regLimitB = ++pParse->nMem;
+    sqlite3VdbeAddOp2(v, OP_Copy, p->iOffset ? p->iOffset+1 : p->iLimit,
+                                  regLimitA);
+    sqlite3VdbeAddOp2(v, OP_Copy, regLimitA, regLimitB);
+  }else{
+    regLimitA = regLimitB = 0;
   }
+  sqlite3ExprDelete(p->pLimit);
+  p->pLimit = 0;
+  sqlite3ExprDelete(p->pOffset);
+  p->pOffset = 0;
 
-multi_select_end:
-  pDest->iMem = dest.iMem;
-  pDest->nMem = dest.nMem;
-  return rc;
+  regAddrA = ++pParse->nMem;
+  regEofA = ++pParse->nMem;
+  regAddrB = ++pParse->nMem;
+  regEofB = ++pParse->nMem;
+  regOutA = ++pParse->nMem;
+  regOutB = ++pParse->nMem;
+  sqlite3SelectDestInit(&destA, SRT_Coroutine, regAddrA);
+  sqlite3SelectDestInit(&destB, SRT_Coroutine, regAddrB);
+
+  /* Jump past the various subroutines and coroutines to the main
+  ** merge loop
+  */
+  j1 = sqlite3VdbeAddOp0(v, OP_Goto);
+  addrSelectA = sqlite3VdbeCurrentAddr(v);
+
+
+  /* Generate a coroutine to evaluate the SELECT statement to the
+  ** left of the compound operator - the "A" select.
+  */
+  VdbeNoopComment((v, "Begin coroutine for left SELECT"));
+  pPrior->iLimit = regLimitA;
+  sqlite3Select(pParse, pPrior, &destA, 0, 0, 0);
+  sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofA);
+  sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
+  VdbeNoopComment((v, "End coroutine for left SELECT"));
+
+  /* Generate a coroutine to evaluate the SELECT statement on 
+  ** the right - the "B" select
+  */
+  addrSelectB = sqlite3VdbeCurrentAddr(v);
+  VdbeNoopComment((v, "Begin coroutine for right SELECT"));
+  savedLimit = p->iLimit;
+  savedOffset = p->iOffset;
+  p->iLimit = regLimitB;
+  p->iOffset = 0;  
+  sqlite3Select(pParse, p, &destB, 0, 0, 0);
+  p->iLimit = savedLimit;
+  p->iOffset = savedOffset;
+  sqlite3VdbeAddOp2(v, OP_Integer, 1, regEofB);
+  sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
+  VdbeNoopComment((v, "End coroutine for right SELECT"));
+
+  /* Generate a subroutine that outputs the current row of the A
+  ** select as the next output row of the compound select.
+  */
+  VdbeNoopComment((v, "Output routine for A"));
+  addrOutA = generateOutputSubroutine(pParse,
+                 p, &destA, pDest, regOutA,
+                 regPrev, pKeyDup, P4_KEYINFO_HANDOFF, labelEnd);
+  
+  /* Generate a subroutine that outputs the current row of the B
+  ** select as the next output row of the compound select.
+  */
+  if( op==TK_ALL || op==TK_UNION ){
+    VdbeNoopComment((v, "Output routine for B"));
+    addrOutB = generateOutputSubroutine(pParse,
+                 p, &destB, pDest, regOutB,
+                 regPrev, pKeyDup, P4_KEYINFO_STATIC, labelEnd);
+  }
+
+  /* Generate a subroutine to run when the results from select A
+  ** are exhausted and only data in select B remains.
+  */
+  VdbeNoopComment((v, "eof-A subroutine"));
+  if( op==TK_EXCEPT || op==TK_INTERSECT ){
+    addrEofA = sqlite3VdbeAddOp2(v, OP_Goto, 0, labelEnd);
+  }else{  
+    addrEofA = sqlite3VdbeAddOp2(v, OP_If, regEofB, labelEnd);
+    sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+    sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofA);
+  }
+
+  /* Generate a subroutine to run when the results from select B
+  ** are exhausted and only data in select A remains.
+  */
+  if( op==TK_INTERSECT ){
+    addrEofB = addrEofA;
+  }else{  
+    VdbeNoopComment((v, "eof-B subroutine"));
+    addrEofB = sqlite3VdbeAddOp2(v, OP_If, regEofA, labelEnd);
+    sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+    sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, addrEofB);
+  }
+
+  /* Generate code to handle the case of A<B
+  */
+  VdbeNoopComment((v, "A-lt-B subroutine"));
+  addrAltB = sqlite3VdbeAddOp2(v, OP_Gosub, regOutA, addrOutA);
+  sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
+  sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
+  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
+
+  /* Generate code to handle the case of A==B
+  */
+  if( op==TK_ALL ){
+    addrAeqB = addrAltB;
+  }else if( op==TK_INTERSECT ){
+    addrAeqB = addrAltB;
+    addrAltB++;
+  }else{
+    VdbeNoopComment((v, "A-eq-B subroutine"));
+    addrAeqB =
+    sqlite3VdbeAddOp1(v, OP_Yield, regAddrA);
+    sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
+    sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
+  }
+
+  /* Generate code to handle the case of A>B
+  */
+  VdbeNoopComment((v, "A-gt-B subroutine"));
+  addrAgtB = sqlite3VdbeCurrentAddr(v);
+  if( op==TK_ALL || op==TK_UNION ){
+    sqlite3VdbeAddOp2(v, OP_Gosub, regOutB, addrOutB);
+  }
+  sqlite3VdbeAddOp1(v, OP_Yield, regAddrB);
+  sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
+  sqlite3VdbeAddOp2(v, OP_Goto, 0, labelCmpr);
+
+  /* This code runs once to initialize everything.
+  */
+  sqlite3VdbeJumpHere(v, j1);
+  sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofA);
+  sqlite3VdbeAddOp2(v, OP_Integer, 0, regEofB);
+  sqlite3VdbeAddOp2(v, OP_Gosub, regAddrA, addrSelectA);
+  sqlite3VdbeAddOp2(v, OP_Gosub, regAddrB, addrSelectB);
+  sqlite3VdbeAddOp2(v, OP_If, regEofA, addrEofA);
+  sqlite3VdbeAddOp2(v, OP_If, regEofB, addrEofB);
+
+  /* Implement the main merge loop
+  */
+  sqlite3VdbeResolveLabel(v, labelCmpr);
+  sqlite3VdbeAddOp4(v, OP_Permutation, 0, 0, 0, (char*)aPermute, P4_INTARRAY);
+  sqlite3VdbeAddOp4(v, OP_Compare, destA.iMem, destB.iMem, nOrderBy,
+                         (char*)pKeyMerge, P4_KEYINFO_HANDOFF);
+  sqlite3VdbeAddOp3(v, OP_Jump, addrAltB, addrAeqB, addrAgtB);
+
+  /* Release temporary registers
+  */
+  if( regPrev ){
+    sqlite3ReleaseTempRange(pParse, regPrev, nOrderBy+1);
+  }
+
+  /* Jump to the this point in order to terminate the query.
+  */
+  sqlite3VdbeResolveLabel(v, labelEnd);
+
+  /* Set the number of output columns
+  */
+  if( pDest->eDest==SRT_Callback ){
+    Select *pFirst = pPrior;
+    while( pFirst->pPrior ) pFirst = pFirst->pPrior;
+    generateColumnNames(pParse, 0, pFirst->pEList);
+  }
+
+  /* Reassembly the compound query so that it will be freed correctly
+  ** by the calling function */
+  if( p->pPrior ){
+    sqlite3SelectDelete(p->pPrior);
+  }
+  p->pPrior = pPrior;
+
+  /*** TBD:  Insert subroutine calls to close cursors on incomplete
+  **** subqueries ****/
+  return SQLITE_OK;
 }
-#endif /* SQLITE_OMIT_COMPOUND_SELECT */
 
 #ifndef SQLITE_OMIT_VIEW
 /* Forward Declarations */
@@ -65935,6 +68546,22 @@
 **        not contain ORDER BY.  (Ticket #2942)  This used to not matter
 **        until we introduced the group_concat() function.  
 **
+**  (17)  The sub-query is not a compound select, or it is a UNION ALL 
+**        compound clause made up entirely of non-aggregate queries, and 
+**        the parent query:
+**
+**          * is not itself part of a compound select,
+**          * is not an aggregate or DISTINCT query, and
+**          * has no other tables or sub-selects in the FROM clause.
+**
+**        The parent and sub-query may contain WHERE clauses. Subject to
+**        rules (11), (13) and (14), they may also contain ORDER BY,
+**        LIMIT and OFFSET clauses.
+**
+**  (18)  If the sub-query is a compound select, then all terms of the
+**        ORDER by clause of the parent must be simple references to 
+**        columns of the sub-query.
+**
 ** In this routine, the "p" parameter is a pointer to the outer query.
 ** The subquery is p->pSrc->a[iFrom].  isAgg is true if the outer query
 ** uses aggregates and subqueryIsAgg is true if the subquery uses aggregates.
@@ -65946,13 +68573,16 @@
 ** the subquery before this routine runs.
 */
 static int flattenSubquery(
-  sqlite3 *db,         /* Database connection */
+  Parse *pParse,       /* Parsing context */
   Select *p,           /* The parent or outer SELECT statement */
   int iFrom,           /* Index in p->pSrc->a[] of the inner subquery */
   int isAgg,           /* True if outer SELECT uses aggregate functions */
   int subqueryIsAgg    /* True if the subquery uses aggregate functions */
 ){
+  const char *zSavedAuthContext = pParse->zAuthContext;
+  Select *pParent;
   Select *pSub;       /* The inner query or "subquery" */
+  Select *pSub1;      /* Pointer to the rightmost select in sub-query */
   SrcList *pSrc;      /* The FROM clause of the outer query */
   SrcList *pSubSrc;   /* The FROM clause of the subquery */
   ExprList *pList;    /* The result set of the outer query */
@@ -65960,6 +68590,7 @@
   int i;              /* Loop counter */
   Expr *pWhere;                    /* The WHERE clause */
   struct SrcList_item *pSubitem;   /* The subquery */
+  sqlite3 *db = pParse->db;
 
   /* Check to see if flattening is permitted.  Return 0 if not.
   */
@@ -65967,6 +68598,7 @@
   pSrc = p->pSrc;
   assert( pSrc && iFrom>=0 && iFrom<pSrc->nSrc );
   pSubitem = &pSrc->a[iFrom];
+  iParent = pSubitem->iCursor;
   pSub = pSubitem->pSelect;
   assert( pSub!=0 );
   if( isAgg && subqueryIsAgg ) return 0;                 /* Restriction (1)  */
@@ -66027,41 +68659,114 @@
     return 0;
   }
 
-  /* If we reach this point, it means flattening is permitted for the
-  ** iFrom-th entry of the FROM clause in the outer query.
+  /* Restriction 17: If the sub-query is a compound SELECT, then it must
+  ** use only the UNION ALL operator. And none of the simple select queries
+  ** that make up the compound SELECT are allowed to be aggregate or distinct
+  ** queries.
   */
+  if( pSub->pPrior ){
+    if( p->pPrior || isAgg || p->isDistinct || pSrc->nSrc!=1 ){
+      return 0;
+    }
+    for(pSub1=pSub; pSub1; pSub1=pSub1->pPrior){
+      if( pSub1->isAgg || pSub1->isDistinct 
+       || (pSub1->pPrior && pSub1->op!=TK_ALL) 
+       || !pSub1->pSrc || pSub1->pSrc->nSrc!=1
+      ){
+        return 0;
+      }
+    }
+
+    /* Restriction 18. */
+    if( p->pOrderBy ){
+      int ii;
+      for(ii=0; ii<p->pOrderBy->nExpr; ii++){
+        Expr *pExpr = p->pOrderBy->a[ii].pExpr;
+        if( pExpr->op!=TK_COLUMN || pExpr->iTable!=iParent ){ 
+          return 0;
+        }
+      }
+    }
+  }
+
+  pParse->zAuthContext = pSubitem->zName;
+  sqlite3AuthCheck(pParse, SQLITE_SELECT, 0, 0, 0);
+  pParse->zAuthContext = zSavedAuthContext;
+
+  /* If the sub-query is a compound SELECT statement, then it must be
+  ** a UNION ALL and the parent query must be of the form:
+  **
+  **     SELECT <expr-list> FROM (<sub-query>) <where-clause> 
+  **
+  ** followed by any ORDER BY, LIMIT and/or OFFSET clauses. This block
+  ** creates N 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.
+  */
+  for(pSub=pSub->pPrior; pSub; pSub=pSub->pPrior){
+    Select *pNew;
+    ExprList *pOrderBy = p->pOrderBy;
+    Expr *pLimit = p->pLimit;
+    Expr *pOffset = p->pOffset;
+    Select *pPrior = p->pPrior;
+    p->pOrderBy = 0;
+    p->pSrc = 0;
+    p->pPrior = 0;
+    p->pLimit = 0;
+    pNew = sqlite3SelectDup(db, p);
+    pNew->pPrior = pPrior;
+    p->pPrior = pNew;
+    p->pOrderBy = pOrderBy;
+    p->op = TK_ALL;
+    p->pSrc = pSrc;
+    p->pLimit = pLimit;
+    p->pOffset = pOffset;
+    p->pRightmost = 0;
+    pNew->pRightmost = 0;
+  }
 
-  /* Move all of the FROM elements of the subquery into the
-  ** the FROM clause of the outer query.  Before doing this, remember
-  ** the cursor number for the original outer query FROM element in
-  ** iParent.  The iParent cursor will never be used.  Subsequent code
-  ** will scan expressions looking for iParent references and replace
-  ** those references with expressions that resolve to the subquery FROM
-  ** elements we are now copying in.
+  /* If we reach this point, it means flattening is permitted for the
+  ** iFrom-th entry of the FROM clause in the outer query.
   */
-  iParent = pSubitem->iCursor;
-  {
+  pSub = pSub1 = pSubitem->pSelect;
+  for(pParent=p; pParent; pParent=pParent->pPrior, pSub=pSub->pPrior){
     int nSubSrc = pSubSrc->nSrc;
-    int jointype = pSubitem->jointype;
-
-    sqlite3DeleteTable(pSubitem->pTab);
-    sqlite3_free(pSubitem->zDatabase);
-    sqlite3_free(pSubitem->zName);
-    sqlite3_free(pSubitem->zAlias);
-    pSubitem->pTab = 0;
-    pSubitem->zDatabase = 0;
-    pSubitem->zName = 0;
-    pSubitem->zAlias = 0;
-    if( nSubSrc>1 ){
+    int jointype = 0;
+    pSubSrc = pSub->pSrc;
+    pSrc = pParent->pSrc;
+
+    /* Move all of the FROM elements of the subquery into the
+    ** the FROM clause of the outer query.  Before doing this, remember
+    ** the cursor number for the original outer query FROM element in
+    ** iParent.  The iParent cursor will never be used.  Subsequent code
+    ** will scan expressions looking for iParent references and replace
+    ** those references with expressions that resolve to the subquery FROM
+    ** elements we are now copying in.
+    */
+    if( pSrc ){
+      pSubitem = &pSrc->a[iFrom];
+      nSubSrc = pSubSrc->nSrc;
+      jointype = pSubitem->jointype;
+      sqlite3DeleteTable(pSubitem->pTab);
+      sqlite3_free(pSubitem->zDatabase);
+      sqlite3_free(pSubitem->zName);
+      sqlite3_free(pSubitem->zAlias);
+      pSubitem->pTab = 0;
+      pSubitem->zDatabase = 0;
+      pSubitem->zName = 0;
+      pSubitem->zAlias = 0;
+    }
+    if( nSubSrc!=1 || !pSrc ){
       int extra = nSubSrc - 1;
-      for(i=1; i<nSubSrc; i++){
+      for(i=(pSrc?1:0); i<nSubSrc; i++){
         pSrc = sqlite3SrcListAppend(db, pSrc, 0, 0);
         if( pSrc==0 ){
-          p->pSrc = 0;
+          pParent->pSrc = 0;
           return 1;
         }
       }
-      p->pSrc = pSrc;
+      pParent->pSrc = pSrc;
       for(i=pSrc->nSrc-1; i-extra>=iFrom; i--){
         pSrc->a[i] = pSrc->a[i-extra];
       }
@@ -66071,79 +68776,80 @@
       memset(&pSubSrc->a[i], 0, sizeof(pSubSrc->a[i]));
     }
     pSrc->a[iFrom].jointype = jointype;
-  }
-
-  /* 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;
-  **   \                     \_____________ subquery __________/          /
-  **    \_____________________ outer query ______________________________/
-  **
-  ** We look at every expression in the outer query and every place we see
-  ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
-  */
-  pList = p->pEList;
-  for(i=0; i<pList->nExpr; i++){
-    Expr *pExpr;
-    if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
-      pList->a[i].zName = 
-             sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n);
-    }
-  }
-  substExprList(db, p->pEList, iParent, pSub->pEList);
-  if( isAgg ){
-    substExprList(db, p->pGroupBy, iParent, pSub->pEList);
-    substExpr(db, p->pHaving, iParent, pSub->pEList);
-  }
-  if( pSub->pOrderBy ){
-    assert( p->pOrderBy==0 );
-    p->pOrderBy = pSub->pOrderBy;
-    pSub->pOrderBy = 0;
-  }else if( p->pOrderBy ){
-    substExprList(db, p->pOrderBy, iParent, pSub->pEList);
-  }
-  if( pSub->pWhere ){
-    pWhere = sqlite3ExprDup(db, pSub->pWhere);
-  }else{
-    pWhere = 0;
-  }
-  if( subqueryIsAgg ){
-    assert( p->pHaving==0 );
-    p->pHaving = p->pWhere;
-    p->pWhere = pWhere;
-    substExpr(db, p->pHaving, iParent, pSub->pEList);
-    p->pHaving = sqlite3ExprAnd(db, p->pHaving, 
-                                sqlite3ExprDup(db, pSub->pHaving));
-    assert( p->pGroupBy==0 );
-    p->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy);
-  }else{
-    substExpr(db, p->pWhere, iParent, pSub->pEList);
-    p->pWhere = sqlite3ExprAnd(db, p->pWhere, pWhere);
-  }
-
-  /* The flattened query is distinct if either the inner or the
-  ** outer query is distinct. 
-  */
-  p->isDistinct = p->isDistinct || pSub->isDistinct;
-
-  /*
-  ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
-  **
-  ** One is tempted to try to add a and b to combine the limits.  But this
-  ** does not work if either limit is negative.
-  */
-  if( pSub->pLimit ){
-    p->pLimit = pSub->pLimit;
-    pSub->pLimit = 0;
+  
+    /* 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;
+    **   \                     \_____________ subquery __________/          /
+    **    \_____________________ outer query ______________________________/
+    **
+    ** We look at every expression in the outer query and every place we see
+    ** "a" we substitute "x*3" and every place we see "b" we substitute "y+10".
+    */
+    pList = pParent->pEList;
+    for(i=0; i<pList->nExpr; i++){
+      Expr *pExpr;
+      if( pList->a[i].zName==0 && (pExpr = pList->a[i].pExpr)->span.z!=0 ){
+        pList->a[i].zName = 
+               sqlite3DbStrNDup(db, (char*)pExpr->span.z, pExpr->span.n);
+      }
+    }
+    substExprList(db, pParent->pEList, iParent, pSub->pEList);
+    if( isAgg ){
+      substExprList(db, pParent->pGroupBy, iParent, pSub->pEList);
+      substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+    }
+    if( pSub->pOrderBy ){
+      assert( pParent->pOrderBy==0 );
+      pParent->pOrderBy = pSub->pOrderBy;
+      pSub->pOrderBy = 0;
+    }else if( pParent->pOrderBy ){
+      substExprList(db, pParent->pOrderBy, iParent, pSub->pEList);
+    }
+    if( pSub->pWhere ){
+      pWhere = sqlite3ExprDup(db, pSub->pWhere);
+    }else{
+      pWhere = 0;
+    }
+    if( subqueryIsAgg ){
+      assert( pParent->pHaving==0 );
+      pParent->pHaving = pParent->pWhere;
+      pParent->pWhere = pWhere;
+      substExpr(db, pParent->pHaving, iParent, pSub->pEList);
+      pParent->pHaving = sqlite3ExprAnd(db, pParent->pHaving, 
+                                  sqlite3ExprDup(db, pSub->pHaving));
+      assert( pParent->pGroupBy==0 );
+      pParent->pGroupBy = sqlite3ExprListDup(db, pSub->pGroupBy);
+    }else{
+      substExpr(db, pParent->pWhere, iParent, pSub->pEList);
+      pParent->pWhere = sqlite3ExprAnd(db, pParent->pWhere, pWhere);
+    }
+  
+    /* The flattened query is distinct if either the inner or the
+    ** outer query is distinct. 
+    */
+    pParent->isDistinct = pParent->isDistinct || pSub->isDistinct;
+  
+    /*
+    ** SELECT ... FROM (SELECT ... LIMIT a OFFSET b) LIMIT x OFFSET y;
+    **
+    ** One is tempted to try to add a and b to combine the limits.  But this
+    ** does not work if either limit is negative.
+    */
+    if( pSub->pLimit ){
+      pParent->pLimit = pSub->pLimit;
+      pSub->pLimit = 0;
+    }
   }
 
   /* Finially, delete what is left of the subquery and return
   ** success.
   */
-  sqlite3SelectDelete(pSub);
+  sqlite3SelectDelete(pSub1);
+
   return 1;
 }
 #endif /* SQLITE_OMIT_VIEW */
@@ -66453,7 +69159,7 @@
 **
 **     SRT_Mem         Store first result in memory cell pDest->iParm
 **
-**     SRT_Set         Store non-null results as keys of table pDest->iParm. 
+**     SRT_Set         Store results as keys of table pDest->iParm. 
 **                     Apply the affinity pDest->affinity before storing them.
 **
 **     SRT_Union       Store results as a key in a temporary table pDest->iParm.
@@ -66466,9 +69172,8 @@
 **                     the result there. The cursor is left open after
 **                     returning.
 **
-**     SRT_Subroutine  For each row returned, push the results onto the
-**                     vdbe stack and call the subroutine (via OP_Gosub)
-**                     at address pDest->iParm.
+**     SRT_Coroutine   Invoke a co-routine to compute a single row of 
+**                     the result
 **
 **     SRT_Exists      Store a 1 in memory cell pDest->iParm if the result
 **                     set is not empty.
@@ -66512,8 +69217,7 @@
   SelectDest *pDest,     /* What to do with the query results */
   Select *pParent,       /* Another SELECT for which this is a sub-query */
   int parentTab,         /* Index in pParent->pSrc of this query */
-  int *pParentAgg,       /* True if pParent uses aggregate functions */
-  char *aff              /* If eDest is SRT_Union, the affinity string */
+  int *pParentAgg        /* True if pParent uses aggregate functions */
 ){
   int i, j;              /* Loop counters */
   WhereInfo *pWInfo;     /* Return from sqlite3WhereBegin() */
@@ -66556,37 +69260,11 @@
   }
   p->pOrderBy = pOrderBy;
 
-#ifndef SQLITE_OMIT_COMPOUND_SELECT
-  /* If there is are a sequence of queries, do the earlier ones first.
-  */
-  if( p->pPrior ){
-    if( p->pRightmost==0 ){
-      Select *pLoop, *pRight = 0;
-      int cnt = 0;
-      int mxSelect;
-      for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
-        pLoop->pRightmost = p;
-        pLoop->pNext = pRight;
-        pRight = pLoop;
-      }
-      mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
-      if( mxSelect && cnt>mxSelect ){
-        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
-        return 1;
-      }
-    }
-    return multiSelect(pParse, p, pDest, aff);
-  }
-#endif
 
   /* Make local copies of the parameters for this query.
   */
   pTabList = p->pSrc;
-  pWhere = p->pWhere;
-  pGroupBy = p->pGroupBy;
-  pHaving = p->pHaving;
   isAgg = p->isAgg;
-  isDistinct = p->isDistinct;
   pEList = p->pEList;
   if( pEList==0 ) goto select_end;
 
@@ -66596,15 +69274,6 @@
   */
   if( pParse->nErr>0 ) goto select_end;
 
-  /* If writing to memory or generating a set
-  ** only a single column may be output.
-  */
-#ifndef SQLITE_OMIT_SUBQUERY
-  if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
-    goto select_end;
-  }
-#endif
-
   /* ORDER BY is ignored for some destinations.
   */
   if( IgnorableOrderby(pDest) ){
@@ -66619,20 +69288,24 @@
   /* Generate code for all sub-queries in the FROM clause
   */
 #if !defined(SQLITE_OMIT_SUBQUERY) || !defined(SQLITE_OMIT_VIEW)
-  for(i=0; i<pTabList->nSrc; i++){
-    const char *zSavedAuthContext = 0;
-    int needRestoreContext;
+  for(i=0; !p->pPrior && i<pTabList->nSrc; i++){
     struct SrcList_item *pItem = &pTabList->a[i];
     SelectDest dest;
-
-    if( pItem->pSelect==0 || pItem->isPopulated ) continue;
-    if( pItem->zName!=0 ){
-      zSavedAuthContext = pParse->zAuthContext;
-      pParse->zAuthContext = pItem->zName;
-      needRestoreContext = 1;
-    }else{
-      needRestoreContext = 0;
+    Select *pSub = pItem->pSelect;
+    int isAggSub;
+    char *zName = pItem->zName;
+
+    if( pSub==0 || pItem->isPopulated ) continue;
+    if( zName!=0 ){   /* An sql view */
+      const char *zSavedAuthContext = pParse->zAuthContext;
+      pParse->zAuthContext = zName;
+      rc = sqlite3SelectResolve(pParse, pSub, 0);
+      pParse->zAuthContext = zSavedAuthContext;
+      if( rc ){
+        goto select_end;
+      }
     }
+
     /* Increment Parse.nHeight by the height of the largest expression
     ** tree refered to by this, the parent select. The child select
     ** may contain expression trees of at most
@@ -66641,33 +69314,62 @@
     ** an exact limit.
     */
     pParse->nHeight += sqlite3SelectExprHeight(p);
-    sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
-    sqlite3Select(pParse, pItem->pSelect, &dest, p, i, &isAgg, 0);
-    if( db->mallocFailed ){
+
+    /* Check to see if the subquery can be absorbed into the parent. */
+    isAggSub = pSub->isAgg;
+    if( flattenSubquery(pParse, p, i, isAgg, isAggSub) ){
+      if( isAggSub ){
+        p->isAgg = isAgg = 1;
+      }
+      i = -1;
+    }else{
+      sqlite3SelectDestInit(&dest, SRT_EphemTab, pItem->iCursor);
+      sqlite3Select(pParse, pSub, &dest, p, i, &isAgg);
+    }
+    if( pParse->nErr || db->mallocFailed ){
       goto select_end;
     }
     pParse->nHeight -= sqlite3SelectExprHeight(p);
-    if( needRestoreContext ){
-      pParse->zAuthContext = zSavedAuthContext;
-    }
     pTabList = p->pSrc;
-    pWhere = p->pWhere;
     if( !IgnorableOrderby(pDest) ){
       pOrderBy = p->pOrderBy;
     }
-    pGroupBy = p->pGroupBy;
-    pHaving = p->pHaving;
-    isDistinct = p->isDistinct;
   }
+  pEList = p->pEList;
 #endif
+  pWhere = p->pWhere;
+  pGroupBy = p->pGroupBy;
+  pHaving = p->pHaving;
+  isDistinct = p->isDistinct;
 
-  /* Check to see if this is a subquery that can be "flattened" into its parent.
-  ** If flattening is a possiblity, do so and return immediately.  
+#ifndef SQLITE_OMIT_COMPOUND_SELECT
+  /* If there is are a sequence of queries, do the earlier ones first.
   */
-#ifndef SQLITE_OMIT_VIEW
-  if( pParent && pParentAgg &&
-      flattenSubquery(db, pParent, parentTab, *pParentAgg, isAgg) ){
-    if( isAgg ) *pParentAgg = 1;
+  if( p->pPrior ){
+    if( p->pRightmost==0 ){
+      Select *pLoop, *pRight = 0;
+      int cnt = 0;
+      int mxSelect;
+      for(pLoop=p; pLoop; pLoop=pLoop->pPrior, cnt++){
+        pLoop->pRightmost = p;
+        pLoop->pNext = pRight;
+        pRight = pLoop;
+      }
+      mxSelect = db->aLimit[SQLITE_LIMIT_COMPOUND_SELECT];
+      if( mxSelect && cnt>mxSelect ){
+        sqlite3ErrorMsg(pParse, "too many terms in compound SELECT");
+        return 1;
+      }
+    }
+    return multiSelect(pParse, p, pDest);
+  }
+#endif
+
+  /* If writing to memory or generating a set
+  ** only a single column may be output.
+  */
+#ifndef SQLITE_OMIT_SUBQUERY
+  if( checkForMultiColumnSelectError(pParse, pDest, pEList->nExpr) ){
     goto select_end;
   }
 #endif
@@ -66746,7 +69448,7 @@
     */
     assert(!isDistinct);
     selectInnerLoop(pParse, p, pEList, 0, 0, pOrderBy, -1, pDest,
-                    pWInfo->iContinue, pWInfo->iBreak, aff);
+                    pWInfo->iContinue, pWInfo->iBreak);
 
     /* End the database scan loop.
     */
@@ -66766,14 +69468,14 @@
     /* The following variables hold addresses or labels for parts of the
     ** virtual machine program we are putting together */
     int addrOutputRow;      /* Start of subroutine that outputs a result row */
+    int regOutputRow;       /* Return address register for output subroutine */
     int addrSetAbort;       /* Set the abort flag and return */
     int addrInitializeLoop; /* Start of code that initializes the input loop */
     int addrTopOfLoop;      /* Top of the input loop */
-    int addrGroupByChange;  /* Code that runs when any GROUP BY term changes */
-    int addrProcessRow;     /* Code to process a single input row */
     int addrEnd;            /* End of all processing */
     int addrSortingIdx;     /* The OP_OpenEphemeral for the sorting index */
     int addrReset;          /* Subroutine for resetting the accumulator */
+    int regReset;           /* Return address register for reset subroutine */
 
     addrEnd = sqlite3VdbeMakeLabel(v);
 
@@ -66803,13 +69505,11 @@
     */
     if( pGroupBy ){
       KeyInfo *pKeyInfo;  /* Keying information for the group by clause */
+      int j1;
 
       /* Create labels that we will be needing
       */
-     
       addrInitializeLoop = sqlite3VdbeMakeLabel(v);
-      addrGroupByChange = sqlite3VdbeMakeLabel(v);
-      addrProcessRow = sqlite3VdbeMakeLabel(v);
 
       /* 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
@@ -66846,26 +69546,28 @@
       addrSetAbort = sqlite3VdbeCurrentAddr(v);
       sqlite3VdbeAddOp2(v, OP_Integer, 1, iAbortFlag);
       VdbeComment((v, "set abort flag"));
-      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
+      regOutputRow = ++pParse->nMem;
+      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
       addrOutputRow = sqlite3VdbeCurrentAddr(v);
       sqlite3VdbeAddOp2(v, OP_IfPos, iUseFlag, addrOutputRow+2);
       VdbeComment((v, "Groupby result generator entry point"));
-      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
+      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
       finalizeAggFunctions(pParse, &sAggInfo);
       if( pHaving ){
         sqlite3ExprIfFalse(pParse, pHaving, addrOutputRow+1, SQLITE_JUMPIFNULL);
       }
       selectInnerLoop(pParse, p, p->pEList, 0, 0, pOrderBy,
                       distinct, pDest,
-                      addrOutputRow+1, addrSetAbort, aff);
-      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
+                      addrOutputRow+1, addrSetAbort);
+      sqlite3VdbeAddOp1(v, OP_Return, regOutputRow);
       VdbeComment((v, "end groupby result generator"));
 
       /* Generate a subroutine that will reset the group-by accumulator
       */
       addrReset = sqlite3VdbeCurrentAddr(v);
+      regReset = ++pParse->nMem;
       resetAccumulator(pParse, &sAggInfo);
-      sqlite3VdbeAddOp2(v, OP_Return, 0, 0);
+      sqlite3VdbeAddOp1(v, OP_Return, regReset);
 
       /* Begin a loop that will extract all source rows in GROUP BY order.
       ** This might involve two separate loops with an OP_Sort in between, or
@@ -66873,7 +69575,7 @@
       ** in the right order to begin with.
       */
       sqlite3VdbeResolveLabel(v, addrInitializeLoop);
-      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
+      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
       pWInfo = sqlite3WhereBegin(pParse, pTabList, pWhere, &pGroupBy, 0);
       if( pWInfo==0 ) goto select_end;
       if( pGroupBy==0 ){
@@ -66945,18 +69647,13 @@
           sqlite3ExprCode(pParse, pGroupBy->a[j].pExpr, iBMem+j);
         }
       }
-      for(j=pGroupBy->nExpr-1; j>=0; j--){
-        if( j==0 ){
-          sqlite3VdbeAddOp3(v, OP_Eq, iAMem+j, addrProcessRow, iBMem+j);
-        }else{
-          sqlite3VdbeAddOp3(v, OP_Ne, iAMem+j, addrGroupByChange, iBMem+j);
-        }
-        sqlite3VdbeChangeP4(v, -1, (void*)pKeyInfo->aColl[j], P4_COLLSEQ);
-        sqlite3VdbeChangeP5(v, SQLITE_NULLEQUAL);
-      }
+      sqlite3VdbeAddOp4(v, OP_Compare, iAMem, iBMem, pGroupBy->nExpr,
+                          (char*)pKeyInfo, P4_KEYINFO);
+      j1 = sqlite3VdbeCurrentAddr(v);
+      sqlite3VdbeAddOp3(v, OP_Jump, j1+1, 0, j1+1);
 
       /* Generate code that runs whenever the GROUP BY changes.
-      ** Change in the GROUP BY are detected by the previous code
+      ** Changes in the GROUP BY are detected by the previous code
       ** block.  If there were no changes, this block is skipped.
       **
       ** This code copies current group by terms in b0,b1,b2,...
@@ -66964,21 +69661,18 @@
       ** and resets the aggregate accumulator registers in preparation
       ** for the next GROUP BY batch.
       */
-      sqlite3VdbeResolveLabel(v, addrGroupByChange);
-      for(j=0; j<pGroupBy->nExpr; j++){
-        sqlite3ExprCodeMove(pParse, iBMem+j, iAMem+j);
-      }
-      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
+      sqlite3ExprCodeMove(pParse, iBMem, iAMem, pGroupBy->nExpr);
+      sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
       VdbeComment((v, "output one row"));
       sqlite3VdbeAddOp2(v, OP_IfPos, iAbortFlag, addrEnd);
       VdbeComment((v, "check abort flag"));
-      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrReset);
+      sqlite3VdbeAddOp2(v, OP_Gosub, regReset, addrReset);
       VdbeComment((v, "reset accumulator"));
 
       /* Update the aggregate accumulators based on the content of
       ** the current row
       */
-      sqlite3VdbeResolveLabel(v, addrProcessRow);
+      sqlite3VdbeJumpHere(v, j1);
       updateAccumulator(pParse, &sAggInfo);
       sqlite3VdbeAddOp2(v, OP_Integer, 1, iUseFlag);
       VdbeComment((v, "indicate data in accumulator"));
@@ -66994,7 +69688,7 @@
 
       /* Output the final row of result
       */
-      sqlite3VdbeAddOp2(v, OP_Gosub, 0, addrOutputRow);
+      sqlite3VdbeAddOp2(v, OP_Gosub, regOutputRow, addrOutputRow);
       VdbeComment((v, "output final row"));
       
     } /* endif pGroupBy */
@@ -67032,7 +69726,7 @@
       if( flag ){
         pDel = pMinMax = sqlite3ExprListDup(db, p->pEList->a[0].pExpr->pList);
         if( pMinMax && !db->mallocFailed ){
-          pMinMax->a[0].sortOrder = ((flag==WHERE_ORDERBY_MIN)?0:1);
+          pMinMax->a[0].sortOrder = flag!=WHERE_ORDERBY_MIN;
           pMinMax->a[0].pExpr->op = TK_COLUMN;
         }
       }
@@ -67050,7 +69744,7 @@
       updateAccumulator(pParse, &sAggInfo);
       if( !pMinMax && flag ){
         sqlite3VdbeAddOp2(v, OP_Goto, 0, pWInfo->iBreak);
-        VdbeComment((v, "%s() by index", (flag==WHERE_ORDERBY_MIN?"min":"max")));
+        VdbeComment((v, "%s() by index",(flag==WHERE_ORDERBY_MIN?"min":"max")));
       }
       sqlite3WhereEnd(pWInfo);
       finalizeAggFunctions(pParse, &sAggInfo);
@@ -67059,7 +69753,7 @@
         sqlite3ExprIfFalse(pParse, pHaving, addrEnd, SQLITE_JUMPIFNULL);
       }
       selectInnerLoop(pParse, p, p->pEList, 0, 0, 0, -1, 
-                      pDest, addrEnd, addrEnd, aff);
+                      pDest, addrEnd, addrEnd);
 
       sqlite3ExprListDelete(pDel);
     }
@@ -67228,6 +69922,8 @@
 **
 ** These routines are in a separate files so that they will not be linked
 ** if they are not used.
+**
+** $Id: table.c,v 1.36 2008/07/08 22:28:49 shane Exp $
 */
 
 #ifndef SQLITE_OMIT_GET_TABLE
@@ -67355,7 +70051,7 @@
   res.azResult[0] = 0;
   rc = sqlite3_exec(db, zSql, sqlite3_get_table_cb, &res, pzErrMsg);
   assert( sizeof(res.azResult[0])>= sizeof(res.nData) );
-  res.azResult[0] = (char*)res.nData;
+  res.azResult[0] = SQLITE_INT_TO_PTR(res.nData);
   if( (rc&0xff)==SQLITE_ABORT ){
     sqlite3_free_table(&res.azResult[1]);
     if( res.zErrMsg ){
@@ -67400,7 +70096,7 @@
     int i, n;
     azResult--;
     assert( azResult!=0 );
-    n = (int)azResult[0];
+    n = SQLITE_PTR_TO_INT(azResult[0]);
     for(i=1; i<n; i++){ if( azResult[i] ) sqlite3_free(azResult[i]); }
     sqlite3_free(azResult);
   }
@@ -67420,7 +70116,9 @@
 **    May you share freely, never taking more than you give.
 **
 *************************************************************************
-*
+**
+**
+** $Id: trigger.c,v 1.127 2008/07/08 23:40:20 drh Exp $
 */
 
 #ifndef SQLITE_OMIT_TRIGGER
@@ -68089,7 +70787,7 @@
 
           sqlite3SelectDestInit(&dest, SRT_Discard, 0);
           sqlite3SelectResolve(pParse, ss, 0);
-          sqlite3Select(pParse, ss, &dest, 0, 0, 0, 0);
+          sqlite3Select(pParse, ss, &dest, 0, 0, 0);
           sqlite3SelectDelete(ss);
         }
         break;
@@ -68277,7 +70975,7 @@
 ** This file contains C code routines that are called by the parser
 ** to handle UPDATE statements.
 **
-** $Id: update.c,v 1.178 2008/04/28 18:46:43 drh Exp $
+** $Id: update.c,v 1.180 2008/07/09 16:51:51 drh Exp $
 */
 
 #ifndef SQLITE_OMIT_VIRTUALTABLE
@@ -68722,7 +71420,7 @@
       sqlite3ExprCacheAffinityChange(pParse, regCols, pTab->nCol);
     }
     sqlite3ReleaseTempRange(pParse, regCols, pTab->nCol);
-    if( pParse->nErr ) goto update_cleanup;
+    /* if( pParse->nErr ) goto update_cleanup; */
     sqlite3VdbeAddOp3(v, OP_Insert, newIdx, regRow, regRowid);
     sqlite3ReleaseTempReg(pParse, regRowid);
     sqlite3ReleaseTempReg(pParse, regRow);
@@ -68913,7 +71611,7 @@
   /* fill the ephemeral table 
   */
   sqlite3SelectDestInit(&dest, SRT_Table, ephemTab);
-  sqlite3Select(pParse, pSelect, &dest, 0, 0, 0, 0);
+  sqlite3Select(pParse, pSelect, &dest, 0, 0, 0);
 
   /* Generate code to scan the ephemeral table and call VUpdate. */
   iReg = ++pParse->nMem;
@@ -68959,7 +71657,7 @@
 ** Most of the code in this file may be omitted by defining the
 ** SQLITE_OMIT_VACUUM macro.
 **
-** $Id: vacuum.c,v 1.78 2008/04/30 16:38:23 drh Exp $
+** $Id: vacuum.c,v 1.81 2008/07/08 19:34:07 drh Exp $
 */
 
 #if !defined(SQLITE_OMIT_VACUUM) && !defined(SQLITE_OMIT_ATTACH)
@@ -69027,16 +71725,19 @@
   Btree *pTemp;           /* The temporary database we vacuum into */
   char *zSql = 0;         /* SQL statements */
   int saved_flags;        /* Saved value of the db->flags */
+  int saved_nChange;      /* Saved value of db->nChange */
+  int saved_nTotalChange; /* Saved value of db->nTotalChange */
   Db *pDb = 0;            /* Database to detach at end of vacuum */
   int nRes;
 
   /* Save the current value of the write-schema flag before setting it. */
   saved_flags = db->flags;
+  saved_nChange = db->nChange;
+  saved_nTotalChange = db->nTotalChange;
   db->flags |= SQLITE_WriteSchema | SQLITE_IgnoreChecks;
 
   if( !db->autoCommit ){
-    sqlite3SetString(pzErrMsg, "cannot VACUUM from within a transaction", 
-       (char*)0);
+    sqlite3SetString(pzErrMsg, db, "cannot VACUUM from within a transaction");
     rc = SQLITE_ERROR;
     goto end_of_vacuum;
   }
@@ -69064,6 +71765,18 @@
   pTemp = db->aDb[db->nDb-1].pBt;
 
   nRes = sqlite3BtreeGetReserve(pMain);
+
+  /* A VACUUM cannot change the pagesize of an encrypted database. */
+#ifdef SQLITE_HAS_CODEC
+  if( db->nextPagesize ){
+    extern void sqlite3CodecGetKey(sqlite3*, int, void**, int*);
+    int nKey;
+    char *zKey;
+    sqlite3CodecGetKey(db, 0, (void**)&zKey, &nKey);
+    if( nKey ) db->nextPagesize = 0;
+  }
+#endif
+
   if( sqlite3BtreeSetPageSize(pTemp, sqlite3BtreeGetPageSize(pMain), nRes)
    || sqlite3BtreeSetPageSize(pTemp, db->nextPagesize, nRes)
    || db->mallocFailed 
@@ -69196,6 +71909,8 @@
 end_of_vacuum:
   /* Restore the original value of db->flags */
   db->flags = saved_flags;
+  db->nChange = saved_nChange;
+  db->nTotalChange = saved_nTotalChange;
 
   /* Currently there is an SQL level transaction open on the vacuum
   ** database. No locks are held on any other files (since the main file
@@ -69233,7 +71948,7 @@
 *************************************************************************
 ** This file contains code used to help implement virtual tables.
 **
-** $Id: vtab.c,v 1.69 2008/05/05 13:23:04 drh Exp $
+** $Id: vtab.c,v 1.70 2008/06/23 17:44:19 danielk1977 Exp $
 */
 #ifndef SQLITE_OMIT_VIRTUALTABLE
 
@@ -69251,17 +71966,21 @@
   nName = strlen(zName);
   pMod = (Module *)sqlite3DbMallocRaw(db, sizeof(Module) + nName + 1);
   if( pMod ){
+    Module *pDel;
     char *zCopy = (char *)(&pMod[1]);
     memcpy(zCopy, zName, nName+1);
     pMod->zName = zCopy;
     pMod->pModule = pModule;
     pMod->pAux = pAux;
     pMod->xDestroy = xDestroy;
-    pMod = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
-    if( pMod && pMod->xDestroy ){
-      pMod->xDestroy(pMod->pAux);
+    pDel = (Module *)sqlite3HashInsert(&db->aModule, zCopy, nName, (void*)pMod);
+    if( pDel && pDel->xDestroy ){
+      pDel->xDestroy(pDel->pAux);
+    }
+    sqlite3_free(pDel);
+    if( pDel==pMod ){
+      db->mallocFailed = 1;
     }
-    sqlite3_free(pMod);
     sqlite3ResetInternalSchema(db, 0);
   }
   rc = sqlite3ApiExit(db, SQLITE_OK);
@@ -70060,13 +72779,13 @@
 **
 *************************************************************************
 ** This module contains C code that generates VDBE code used to process
-** the WHERE clause of SQL statements.  This module is reponsible for
+** the WHERE clause of SQL statements.  This module is responsible for
 ** generating the code that loops through a table looking for applicable
 ** rows.  Indices are selected and used to speed the search when doing
 ** so is applicable.  Because this module is responsible for selecting
 ** indices, you might also think of this module as the "query optimizer".
 **
-** $Id: where.c,v 1.302 2008/04/19 14:40:44 drh Exp $
+** $Id: where.c,v 1.317 2008/07/12 14:52:20 drh Exp $
 */
 
 /*
@@ -70079,6 +72798,8 @@
 */
 #if defined(SQLITE_TEST) || defined(SQLITE_DEBUG)
 SQLITE_PRIVATE int sqlite3WhereTrace = 0;
+#endif
+#if 0
 # define WHERETRACE(X)  if(sqlite3WhereTrace) sqlite3DebugPrintf X
 #else
 # define WHERETRACE(X)
@@ -70268,7 +72989,7 @@
 ** for freeing the expression p is assumed by the WhereClause object.
 **
 ** WARNING:  This routine might reallocate the space used to store
-** WhereTerms.  All pointers to WhereTerms should be invalided after
+** WhereTerms.  All pointers to WhereTerms should be invalidated after
 ** calling this routine.  Such pointers may be reinitialized by referencing
 ** the pWC->a[] array.
 */
@@ -70277,7 +72998,7 @@
   int idx;
   if( pWC->nTerm>=pWC->nSlot ){
     WhereTerm *pOld = pWC->a;
-    pWC->a = sqlite3_malloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
+    pWC->a = sqlite3Malloc( sizeof(pWC->a[0])*pWC->nSlot*2 );
     if( pWC->a==0 ){
       pWC->pParse->db->mallocFailed = 1;
       if( flags & TERM_DYNAMIC ){
@@ -70431,7 +73152,7 @@
 #define SWAP(TYPE,A,B) {TYPE t=A; A=B; B=t;}
 
 /*
-** Commute a comparision operator.  Expressions of the form "X op Y"
+** Commute a comparison operator.  Expressions of the form "X op Y"
 ** are converted into "Y op X".
 **
 ** If a collation sequence is associated with either the left or right
@@ -70499,13 +73220,14 @@
 ){
   WhereTerm *pTerm;
   int k;
+  assert( iCur>=0 );
   for(pTerm=pWC->a, k=pWC->nTerm; k; k--, pTerm++){
     if( pTerm->leftCursor==iCur
        && (pTerm->prereqRight & notReady)==0
        && pTerm->leftColumn==iColumn
        && (pTerm->eOperator & op)!=0
     ){
-      if( iCur>=0 && pIdx && pTerm->eOperator!=WO_ISNULL ){
+      if( pIdx && pTerm->eOperator!=WO_ISNULL ){
         Expr *pX = pTerm->pExpr;
         CollSeq *pColl;
         char idxaff;
@@ -70525,8 +73247,9 @@
           pColl = pParse->db->pDfltColl;
         }
 
-        for(j=0; j<pIdx->nColumn && pIdx->aiColumn[j]!=iColumn; j++){}
-        assert( j<pIdx->nColumn );
+        for(j=0; pIdx->aiColumn[j]!=iColumn; j++){
+          if( NEVER(j>=pIdx->nColumn) ) return 0;
+        }
         if( sqlite3StrICmp(pColl->zName, pIdx->azColl[j]) ) continue;
       }
       return pTerm;
@@ -70670,7 +73393,7 @@
 **           a=<expr1> OR  a=<expr2> OR b=<expr3>  OR ...
 **
 ** The pOrTerm input to this routine corresponds to a single term of
-** this OR clause.  In order for the term to be a condidate for
+** this OR clause.  In order for the term to be a candidate for
 ** conversion to an IN operator, the following must be true:
 **
 **     *  The left-hand side of the term must be the column which
@@ -70725,7 +73448,7 @@
 ** This routine merely checks to see if pOrTerm has a duplicate that
 ** might qualify.  If there is a duplicate that has not yet been
 ** disqualified, then return true.  If there are no duplicates, or
-** the duplicate has also been disqualifed, return false.
+** the duplicate has also been disqualified, return false.
 */
 static int orTermHasOkDuplicate(WhereClause *pOr, WhereTerm *pOrTerm){
   if( pOrTerm->flags & TERM_COPIED ){
@@ -70915,7 +73638,7 @@
       ExprList *pList = 0;
       Expr *pNew, *pDup;
       Expr *pLeft = 0;
-      for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0 && ok; i--, pOrTerm++){
+      for(i=sOr.nTerm-1, pOrTerm=sOr.a; i>=0; i--, pOrTerm++){
         if( (pOrTerm->flags & TERM_OR_OK)==0 ) continue;
         pDup = sqlite3ExprDup(db, pOrTerm->pExpr->pRight);
         pList = sqlite3ExprListAppend(pWC->pParse, pList, pDup, 0);
@@ -70951,8 +73674,7 @@
   **          x>='abc' AND x<'abd' AND x LIKE 'abc%'
   **
   ** The last character of the prefix "abc" is incremented to form the
-  ** termination condidtion "abd".  This trick of incrementing the last
-  ** is not 255 and if the character set is not EBCDIC.  
+  ** termination condition "abd".
   */
   if( isLikeOrGlob(db, pExpr, &nPattern, &isComplete, &noCase) ){
     Expr *pLeft, *pRight;
@@ -70974,7 +73696,10 @@
       assert( pStr2->token.dyn );
       pC = (u8*)&pStr2->token.z[nPattern-1];
       c = *pC;
-      if( noCase ) c = sqlite3UpperToLower[c];
+      if( noCase ){
+        if( c=='@' ) isComplete = 0;
+        c = sqlite3UpperToLower[c];
+      }
       *pC = c + 1;
     }
     pNewExpr1 = sqlite3PExpr(pParse, TK_GE, sqlite3ExprDup(db,pLeft), pStr1, 0);
@@ -71136,6 +73861,9 @@
         ** ORDER BY term, that is OK.  Just ignore that column of the index
         */
         continue;
+      }else if( i==pIdx->nColumn ){
+        /* Index column i is the rowid.  All other terms match. */
+        break;
       }else{
         /* If an index column fails to match and is not constrained by ==
         ** then the index cannot satisfy the ORDER BY constraint.
@@ -71213,7 +73941,7 @@
 /*
 ** Prepare a crude estimate of the logarithm of the input value.
 ** The results need not be exact.  This is only used for estimating
-** the total cost of performing operatings with O(logN) or O(NlogN)
+** the total cost of performing operations with O(logN) or O(NlogN)
 ** complexity.  Because N is just a guess, it is no great tragedy if
 ** logN is a little off.
 */
@@ -71528,7 +74256,7 @@
   int eqTermMask;             /* Mask of valid equality operators */
   double cost;                /* Cost of using pProbe */
 
-  WHERETRACE(("bestIndex: tbl=%s notReady=%x\n", pSrc->pTab->zName, notReady));
+  WHERETRACE(("bestIndex: tbl=%s notReady=%llx\n", pSrc->pTab->zName, notReady));
   lowestCost = SQLITE_BIG_DBL;
   pProbe = pSrc->pTab->pIndex;
 
@@ -71650,7 +74378,7 @@
         flags |= WHERE_COLUMN_IN;
         if( pExpr->pSelect!=0 ){
           inMultiplier *= 25;
-        }else if( pExpr->pList!=0 ){
+        }else if( ALWAYS(pExpr->pList) ){
           inMultiplier *= pExpr->pList->nExpr + 1;
         }
       }
@@ -71766,7 +74494,7 @@
 */
 static void disableTerm(WhereLevel *pLevel, WhereTerm *pTerm){
   if( pTerm
-      && (pTerm->flags & TERM_CODED)==0
+      && ALWAYS((pTerm->flags & TERM_CODED)==0)
       && (pLevel->iLeftJoin==0 || ExprHasProperty(pTerm->pExpr, EP_FromJoin))
   ){
     pTerm->flags |= TERM_CODED;
@@ -71831,7 +74559,7 @@
 
     assert( pX->op==TK_IN );
     iReg = iTarget;
-    eType = sqlite3FindInIndex(pParse, pX, 1);
+    eType = sqlite3FindInIndex(pParse, pX, 0);
     iTab = pX->iTable;
     sqlite3VdbeAddOp2(v, OP_Rewind, iTab, 0);
     VdbeComment((v, "%.*s", pX->span.n, pX->span.z));
@@ -71914,7 +74642,7 @@
     int r1;
     int k = pIdx->aiColumn[j];
     pTerm = findTerm(pWC, iCur, k, notReady, pLevel->flags, pIdx);
-    if( pTerm==0 ) break;
+    if( NEVER(pTerm==0) ) break;
     assert( (pTerm->flags & TERM_CODED)==0 );
     r1 = codeEqualityTerm(pParse, pTerm, pLevel, regBase+j);
     if( r1!=regBase+j ){
@@ -72233,7 +74961,7 @@
       }
       if( doNotReorder ) break;
     }
-    WHERETRACE(("*** Optimizer choose table %d for loop %d\n", bestJ,
+    WHERETRACE(("*** Optimizer selects table %d for loop %d\n", bestJ,
            pLevel-pWInfo->a));
     if( (bestFlags & WHERE_ORDERBY)!=0 ){
       *ppOrderBy = 0;
@@ -72404,24 +75132,28 @@
                                                   pBestIdx->aConstraint;
 
       iReg = sqlite3GetTempRange(pParse, nConstraint+2);
+      pParse->disableColCache++;
       for(j=1; j<=nConstraint; j++){
         int k;
         for(k=0; k<nConstraint; k++){
           if( aUsage[k].argvIndex==j ){
             int iTerm = aConstraint[k].iTermOffset;
+            assert( pParse->disableColCache );
             sqlite3ExprCode(pParse, wc.a[iTerm].pExpr->pRight, iReg+j+1);
             break;
           }
         }
         if( k==nConstraint ) break;
       }
+      assert( pParse->disableColCache );
+      pParse->disableColCache--;
       sqlite3VdbeAddOp2(v, OP_Integer, pBestIdx->idxNum, iReg);
       sqlite3VdbeAddOp2(v, OP_Integer, j-1, iReg+1);
       sqlite3VdbeAddOp4(v, OP_VFilter, iCur, brk, iReg, pBestIdx->idxStr,
                         pBestIdx->needToFreeIdxStr ? P4_MPRINTF : P4_STATIC);
       sqlite3ReleaseTempRange(pParse, iReg, nConstraint+2);
       pBestIdx->needToFreeIdxStr = 0;
-      for(j=0; j<pBestIdx->nConstraint; j++){
+      for(j=0; j<nConstraint; j++){
         if( aUsage[j].omit ){
           int iTerm = aConstraint[j].iTermOffset;
           disableTerm(pLevel, &wc.a[iTerm]);
@@ -72586,8 +75318,9 @@
       if( (wflags&WHERE_ORDERBY_MIN)!=0
        && (pLevel->flags&WHERE_ORDERBY)
        && (pIdx->nColumn>nEq)
-       && (pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq])
       ){
+        assert( pOrderBy->nExpr==1 );
+        assert( pOrderBy->a[0].pExpr->iColumn==pIdx->aiColumn[nEq] );
         isMinQuery = 1;
       }
 
@@ -72622,7 +75355,7 @@
       if( pRangeStart ){
         int dcc = pParse->disableColCache;
         if( pRangeEnd ){
-          pParse->disableColCache = 1;
+          pParse->disableColCache++;
         }
         sqlite3ExprCode(pParse, pRangeStart->pExpr->pRight, regBase+nEq);
         pParse->disableColCache = dcc;
@@ -72644,7 +75377,7 @@
       testcase( op==OP_MoveLe );
       testcase( op==OP_MoveLt );
       sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase, 
-                        (char*)nConstraint, P4_INT32);
+                        SQLITE_INT_TO_PTR(nConstraint), P4_INT32);
 
       /* Load the value for the inequality constraint at the end of the
       ** range (if any).
@@ -72666,7 +75399,7 @@
       testcase( op==OP_IdxGE );
       testcase( op==OP_IdxLT );
       sqlite3VdbeAddOp4(v, op, iIdxCur, nxt, regBase,
-                        (char*)nConstraint, P4_INT32);
+                        SQLITE_INT_TO_PTR(nConstraint), P4_INT32);
       sqlite3VdbeChangeP5(v, endEq!=bRev);
 
       /* If there are inequality constraints, check that the value
@@ -72925,8 +75658,8 @@
 /* Driver template for the LEMON parser generator.
 ** The author disclaims copyright to this source code.
 */
-/* First off, code is include which follows the "include" declaration
-** in the input file. */
+/* First off, code is included that follows the "include" declaration
+** in the input grammar file. */
 
 
 /*
@@ -73029,7 +75762,6 @@
   struct TrigEvent yy370;
   SrcList* yy373;
   struct {int value; int mask;} yy405;
-  Token yy410;
   IdList* yy432;
 } YYMINORTYPE;
 #ifndef YYSTACKDEPTH
@@ -73050,7 +75782,7 @@
 ** YYMINORTYPE objects to zero. */
 static const YYMINORTYPE yyzerominor;
 
-/* Next are that tables used to determine what action to take based on the
+/* Next are the tables used to determine what action to take based on the
 ** current state and lookahead token.  These tables are used to implement
 ** functions that take a state number and lookahead value and return an
 ** action integer.  
@@ -73516,7 +76248,7 @@
 ** 
 **      %fallback ID X Y Z.
 **
-** appears in the grammer, then ID becomes a fallback token for X, Y,
+** appears in the grammar, then ID becomes a fallback token for X, Y,
 ** and Z.  Whenever one of the tokens X, Y, or Z is input to the parser
 ** but it does not parse, the type of the token is changed to ID and
 ** the parse is retried before an error is thrown.
@@ -74186,161 +76918,60 @@
     ** inside the C code.
     */
     case 155: /* select */
+    case 189: /* oneselect */
+    case 206: /* seltablist_paren */
 {
 sqlite3SelectDelete((yypminor->yy219));
 }
       break;
     case 169: /* term */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
     case 170: /* expr */
+    case 194: /* where_opt */
+    case 196: /* having_opt */
+    case 204: /* on_opt */
+    case 210: /* sortitem */
+    case 218: /* escape */
+    case 221: /* case_operand */
+    case 223: /* case_else */
+    case 235: /* when_clause */
+    case 238: /* key_opt */
 {
 sqlite3ExprDelete((yypminor->yy172));
 }
       break;
     case 174: /* idxlist_opt */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
     case 182: /* idxlist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 188: /* fullname */
-{
-sqlite3SrcListDelete((yypminor->yy373));
-}
-      break;
-    case 189: /* oneselect */
-{
-sqlite3SelectDelete((yypminor->yy219));
-}
-      break;
     case 192: /* selcollist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 193: /* from */
-{
-sqlite3SrcListDelete((yypminor->yy373));
-}
-      break;
-    case 194: /* where_opt */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
     case 195: /* groupby_opt */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 196: /* having_opt */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
     case 197: /* orderby_opt */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
     case 199: /* sclp */
+    case 209: /* sortlist */
+    case 211: /* nexprlist */
+    case 212: /* setlist */
+    case 215: /* itemlist */
+    case 216: /* exprlist */
+    case 222: /* case_exprlist */
 {
 sqlite3ExprListDelete((yypminor->yy174));
 }
       break;
+    case 188: /* fullname */
+    case 193: /* from */
     case 201: /* seltablist */
-{
-sqlite3SrcListDelete((yypminor->yy373));
-}
-      break;
     case 202: /* stl_prefix */
 {
 sqlite3SrcListDelete((yypminor->yy373));
 }
       break;
-    case 204: /* on_opt */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
     case 205: /* using_opt */
-{
-sqlite3IdListDelete((yypminor->yy432));
-}
-      break;
-    case 206: /* seltablist_paren */
-{
-sqlite3SelectDelete((yypminor->yy219));
-}
-      break;
     case 208: /* inscollist */
-{
-sqlite3IdListDelete((yypminor->yy432));
-}
-      break;
-    case 209: /* sortlist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 210: /* sortitem */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
-    case 211: /* nexprlist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 212: /* setlist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
     case 214: /* inscollist_opt */
 {
 sqlite3IdListDelete((yypminor->yy432));
 }
       break;
-    case 215: /* itemlist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 216: /* exprlist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 218: /* escape */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
-    case 221: /* case_operand */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
-    case 222: /* case_exprlist */
-{
-sqlite3ExprListDelete((yypminor->yy174));
-}
-      break;
-    case 223: /* case_else */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
     case 231: /* trigger_cmd_list */
+    case 236: /* trigger_cmd */
 {
 sqlite3DeleteTriggerStep((yypminor->yy243));
 }
@@ -74350,21 +76981,6 @@
 sqlite3IdListDelete((yypminor->yy370).b);
 }
       break;
-    case 235: /* when_clause */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
-    case 236: /* trigger_cmd */
-{
-sqlite3DeleteTriggerStep((yypminor->yy243));
-}
-      break;
-    case 238: /* key_opt */
-{
-sqlite3ExprDelete((yypminor->yy172));
-}
-      break;
     default:  break;   /* If no destructor action specified: do nothing */
   }
 }
@@ -74538,7 +77154,7 @@
   yyParser *yypParser,          /* The parser to be shifted */
   int yyNewState,               /* The new state to shift in */
   int yyMajor,                  /* The major token to shift in */
-  YYMINORTYPE *yypMinor         /* Pointer ot the minor token to shift in */
+  YYMINORTYPE *yypMinor         /* Pointer to the minor token to shift in */
 ){
   yyStackEntry *yytos;
   yypParser->yyidx++;
@@ -75018,7 +77634,7 @@
         break;
       case 21: /* create_table ::= CREATE temp TABLE ifnotexists nm dbnm */
 {
-   sqlite3StartTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,yymsp[-4].minor.yy46,0,0,yymsp[-2].minor.yy46);
+   sqlite3StartTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,yymsp[-4].minor.yy46,0,0,yymsp[-2].minor.yy46);
 }
         break;
       case 22: /* ifnotexists ::= */
@@ -75046,7 +77662,7 @@
         break;
       case 26: /* create_table_args ::= LP columnlist conslist_opt RP */
 {
-  sqlite3EndTable(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy0,0);
+  sqlite3EndTable(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0);
 }
         break;
       case 27: /* create_table_args ::= AS select */
@@ -75057,14 +77673,14 @@
         break;
       case 30: /* column ::= columnid type carglist */
 {
-  yygotominor.yy410.z = yymsp[-2].minor.yy410.z;
-  yygotominor.yy410.n = (pParse->sLastToken.z-yymsp[-2].minor.yy410.z) + pParse->sLastToken.n;
+  yygotominor.yy0.z = yymsp[-2].minor.yy0.z;
+  yygotominor.yy0.n = (pParse->sLastToken.z-yymsp[-2].minor.yy0.z) + pParse->sLastToken.n;
 }
         break;
       case 31: /* columnid ::= nm */
 {
-  sqlite3AddColumn(pParse,&yymsp[0].minor.yy410);
-  yygotominor.yy410 = yymsp[0].minor.yy410;
+  sqlite3AddColumn(pParse,&yymsp[0].minor.yy0);
+  yygotominor.yy0 = yymsp[0].minor.yy0;
 }
         break;
       case 32: /* id ::= ID */
@@ -75072,12 +77688,6 @@
       case 34: /* nm ::= ID */
       case 35: /* nm ::= STRING */
       case 36: /* nm ::= JOIN_KW */
-      case 257: /* number ::= INTEGER|FLOAT */
-{yygotominor.yy410 = yymsp[0].minor.yy0;}
-        break;
-      case 38: /* type ::= typetoken */
-{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy410);}
-        break;
       case 39: /* typetoken ::= typename */
       case 42: /* typename ::= ids */
       case 119: /* as ::= AS nm */
@@ -75089,22 +77699,26 @@
       case 254: /* nmnum ::= nm */
       case 255: /* plus_num ::= plus_opt number */
       case 256: /* minus_num ::= MINUS number */
-{yygotominor.yy410 = yymsp[0].minor.yy410;}
+      case 257: /* number ::= INTEGER|FLOAT */
+{yygotominor.yy0 = yymsp[0].minor.yy0;}
+        break;
+      case 38: /* type ::= typetoken */
+{sqlite3AddColumnType(pParse,&yymsp[0].minor.yy0);}
         break;
       case 40: /* typetoken ::= typename LP signed RP */
 {
-  yygotominor.yy410.z = yymsp[-3].minor.yy410.z;
-  yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy410.z;
+  yygotominor.yy0.z = yymsp[-3].minor.yy0.z;
+  yygotominor.yy0.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-3].minor.yy0.z;
 }
         break;
       case 41: /* typetoken ::= typename LP signed COMMA signed RP */
 {
-  yygotominor.yy410.z = yymsp[-5].minor.yy410.z;
-  yygotominor.yy410.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy410.z;
+  yygotominor.yy0.z = yymsp[-5].minor.yy0.z;
+  yygotominor.yy0.n = &yymsp[0].minor.yy0.z[yymsp[0].minor.yy0.n] - yymsp[-5].minor.yy0.z;
 }
         break;
       case 43: /* typename ::= typename ids */
-{yygotominor.yy410.z=yymsp[-1].minor.yy410.z; yygotominor.yy410.n=yymsp[0].minor.yy410.n+(yymsp[0].minor.yy410.z-yymsp[-1].minor.yy410.z);}
+{yygotominor.yy0.z=yymsp[-1].minor.yy0.z; yygotominor.yy0.n=yymsp[0].minor.yy0.n+(yymsp[0].minor.yy0.z-yymsp[-1].minor.yy0.z);}
         break;
       case 50: /* ccons ::= DEFAULT term */
       case 52: /* ccons ::= DEFAULT PLUS term */
@@ -75121,7 +77735,7 @@
         break;
       case 54: /* ccons ::= DEFAULT id */
 {
-  Expr *p = sqlite3PExpr(pParse, TK_STRING, 0, 0, &yymsp[0].minor.yy410);
+  Expr *p = sqlite3PExpr(pParse, TK_STRING, 0, 0, &yymsp[0].minor.yy0);
   sqlite3AddDefaultValue(pParse,p);
 }
         break;
@@ -75138,13 +77752,13 @@
 {sqlite3AddCheckConstraint(pParse,yymsp[-1].minor.yy172);}
         break;
       case 60: /* ccons ::= REFERENCES nm idxlist_opt refargs */
-{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy410,yymsp[-1].minor.yy174,yymsp[0].minor.yy46);}
+{sqlite3CreateForeignKey(pParse,0,&yymsp[-2].minor.yy0,yymsp[-1].minor.yy174,yymsp[0].minor.yy46);}
         break;
       case 61: /* ccons ::= defer_subclause */
 {sqlite3DeferForeignKey(pParse,yymsp[0].minor.yy46);}
         break;
       case 62: /* ccons ::= COLLATE ids */
-{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy410);}
+{sqlite3AddCollateType(pParse, &yymsp[0].minor.yy0);}
         break;
       case 65: /* refargs ::= */
 { yygotominor.yy46 = OE_Restrict * 0x010101; }
@@ -75186,10 +77800,10 @@
 {yygotominor.yy46 = yymsp[0].minor.yy46;}
         break;
       case 80: /* conslist_opt ::= */
-{yygotominor.yy410.n = 0; yygotominor.yy410.z = 0;}
+{yygotominor.yy0.n = 0; yygotominor.yy0.z = 0;}
         break;
       case 81: /* conslist_opt ::= COMMA conslist */
-{yygotominor.yy410 = yymsp[-1].minor.yy0;}
+{yygotominor.yy0 = yymsp[-1].minor.yy0;}
         break;
       case 86: /* tcons ::= PRIMARY KEY LP idxlist autoinc RP onconf */
 {sqlite3AddPrimaryKey(pParse,yymsp[-3].minor.yy174,yymsp[0].minor.yy46,yymsp[-2].minor.yy46,0);}
@@ -75202,7 +77816,7 @@
         break;
       case 89: /* tcons ::= FOREIGN KEY LP idxlist RP REFERENCES nm idxlist_opt refargs defer_subclause_opt */
 {
-    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy174, &yymsp[-3].minor.yy410, yymsp[-2].minor.yy174, yymsp[-1].minor.yy46);
+    sqlite3CreateForeignKey(pParse, yymsp[-6].minor.yy174, &yymsp[-3].minor.yy0, yymsp[-2].minor.yy174, yymsp[-1].minor.yy46);
     sqlite3DeferForeignKey(pParse, yymsp[0].minor.yy46);
 }
         break;
@@ -75224,7 +77838,7 @@
         break;
       case 102: /* cmd ::= CREATE temp VIEW ifnotexists nm dbnm AS select */
 {
-  sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, yymsp[0].minor.yy219, yymsp[-6].minor.yy46, yymsp[-4].minor.yy46);
+  sqlite3CreateView(pParse, &yymsp[-7].minor.yy0, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, yymsp[0].minor.yy219, yymsp[-6].minor.yy46, yymsp[-4].minor.yy46);
 }
         break;
       case 103: /* cmd ::= DROP VIEW ifexists fullname */
@@ -75235,7 +77849,7 @@
       case 104: /* cmd ::= select */
 {
   SelectDest dest = {SRT_Callback, 0, 0, 0, 0};
-  sqlite3Select(pParse, yymsp[0].minor.yy219, &dest, 0, 0, 0, 0);
+  sqlite3Select(pParse, yymsp[0].minor.yy219, &dest, 0, 0, 0);
   sqlite3SelectDelete(yymsp[0].minor.yy219);
 }
         break;
@@ -75275,7 +77889,7 @@
         break;
       case 116: /* selcollist ::= sclp expr as */
 {
-   yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy410.n?&yymsp[0].minor.yy410:0);
+   yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-2].minor.yy174,yymsp[-1].minor.yy172,yymsp[0].minor.yy0.n?&yymsp[0].minor.yy0:0);
 }
         break;
       case 117: /* selcollist ::= sclp STAR */
@@ -75287,13 +77901,13 @@
       case 118: /* selcollist ::= sclp nm DOT STAR */
 {
   Expr *pRight = sqlite3PExpr(pParse, TK_ALL, 0, 0, 0);
-  Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy410);
+  Expr *pLeft = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
   Expr *pDot = sqlite3PExpr(pParse, TK_DOT, pLeft, pRight, 0);
   yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-3].minor.yy174, pDot, 0);
 }
         break;
       case 121: /* as ::= */
-{yygotominor.yy410.n = 0;}
+{yygotominor.yy0.n = 0;}
         break;
       case 122: /* from ::= */
 {yygotominor.yy373 = sqlite3DbMallocZero(pParse->db, sizeof(*yygotominor.yy373));}
@@ -75315,12 +77929,12 @@
         break;
       case 126: /* seltablist ::= stl_prefix nm dbnm as on_opt using_opt */
 {
-  yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy373,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,0,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
+  yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-5].minor.yy373,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,0,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
 }
         break;
       case 127: /* seltablist ::= stl_prefix LP seltablist_paren RP as on_opt using_opt */
 {
-    yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy373,0,0,&yymsp[-2].minor.yy410,yymsp[-4].minor.yy219,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
+    yygotominor.yy373 = sqlite3SrcListAppendFromTerm(pParse,yymsp[-6].minor.yy373,0,0,&yymsp[-2].minor.yy0,yymsp[-4].minor.yy219,yymsp[-1].minor.yy172,yymsp[0].minor.yy432);
   }
         break;
       case 129: /* seltablist_paren ::= seltablist */
@@ -75330,10 +77944,10 @@
   }
         break;
       case 130: /* dbnm ::= */
-{yygotominor.yy410.z=0; yygotominor.yy410.n=0;}
+{yygotominor.yy0.z=0; yygotominor.yy0.n=0;}
         break;
       case 132: /* fullname ::= nm dbnm */
-{yygotominor.yy373 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);}
+{yygotominor.yy373 = sqlite3SrcListAppend(pParse->db,0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);}
         break;
       case 133: /* joinop ::= COMMA|JOIN */
 { yygotominor.yy46 = JT_INNER; }
@@ -75342,10 +77956,10 @@
 { yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-1].minor.yy0,0,0); }
         break;
       case 135: /* joinop ::= JOIN_KW nm JOIN */
-{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy410,0); }
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0,0); }
         break;
       case 136: /* joinop ::= JOIN_KW nm nm JOIN */
-{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy410,&yymsp[-1].minor.yy410); }
+{ yygotominor.yy46 = sqlite3JoinType(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[-1].minor.yy0); }
         break;
       case 137: /* on_opt ::= ON expr */
       case 145: /* sortitem ::= expr */
@@ -75419,10 +78033,10 @@
 }
         break;
       case 161: /* setlist ::= setlist COMMA nm EQ expr */
-{yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
+{yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174,yymsp[0].minor.yy172,&yymsp[-2].minor.yy0);}
         break;
       case 162: /* setlist ::= nm EQ expr */
-{yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,&yymsp[-2].minor.yy410);}
+{yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,&yymsp[-2].minor.yy0);}
         break;
       case 163: /* cmd ::= insert_cmd INTO fullname inscollist_opt VALUES LP itemlist RP */
 {sqlite3Insert(pParse, yymsp[-5].minor.yy373, yymsp[-1].minor.yy174, 0, yymsp[-4].minor.yy432, yymsp[-7].minor.yy46);}
@@ -75442,10 +78056,10 @@
 {yygotominor.yy174 = sqlite3ExprListAppend(pParse,0,yymsp[0].minor.yy172,0);}
         break;
       case 172: /* inscollist ::= inscollist COMMA nm */
-{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy432,&yymsp[0].minor.yy410);}
+{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,yymsp[-2].minor.yy432,&yymsp[0].minor.yy0);}
         break;
       case 173: /* inscollist ::= nm */
-{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy410);}
+{yygotominor.yy432 = sqlite3IdListAppend(pParse->db,0,&yymsp[0].minor.yy0);}
         break;
       case 175: /* expr ::= LP expr RP */
 {yygotominor.yy172 = yymsp[-1].minor.yy172; sqlite3ExprSpan(yygotominor.yy172,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0); }
@@ -75461,16 +78075,16 @@
         break;
       case 179: /* expr ::= nm DOT nm */
 {
-  Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy410);
-  Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy410);
+  Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
+  Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
   yygotominor.yy172 = sqlite3PExpr(pParse, TK_DOT, temp1, temp2, 0);
 }
         break;
       case 180: /* expr ::= nm DOT nm DOT nm */
 {
-  Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy410);
-  Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy410);
-  Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy410);
+  Expr *temp1 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-4].minor.yy0);
+  Expr *temp2 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[-2].minor.yy0);
+  Expr *temp3 = sqlite3PExpr(pParse, TK_ID, 0, 0, &yymsp[0].minor.yy0);
   Expr *temp4 = sqlite3PExpr(pParse, TK_DOT, temp2, temp3, 0);
   yygotominor.yy172 = sqlite3PExpr(pParse, TK_DOT, temp1, temp4, 0);
 }
@@ -75487,12 +78101,12 @@
         break;
       case 185: /* expr ::= expr COLLATE ids */
 {
-  yygotominor.yy172 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy172, &yymsp[0].minor.yy410);
+  yygotominor.yy172 = sqlite3ExprSetColl(pParse, yymsp[-2].minor.yy172, &yymsp[0].minor.yy0);
 }
         break;
       case 186: /* expr ::= CAST LP expr AS typetoken RP */
 {
-  yygotominor.yy172 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy172, 0, &yymsp[-1].minor.yy410);
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_CAST, yymsp[-3].minor.yy172, 0, &yymsp[-1].minor.yy0);
   sqlite3ExprSpan(yygotominor.yy172,&yymsp[-5].minor.yy0,&yymsp[0].minor.yy0);
 }
         break;
@@ -75619,7 +78233,7 @@
     yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0);
     if( yygotominor.yy172 ){
       yygotominor.yy172->pList = yymsp[-1].minor.yy174;
-      sqlite3ExprSetHeight(yygotominor.yy172);
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
     }else{
       sqlite3ExprListDelete(yymsp[-1].minor.yy174);
     }
@@ -75632,7 +78246,7 @@
     yygotominor.yy172 = sqlite3PExpr(pParse, TK_SELECT, 0, 0, 0);
     if( yygotominor.yy172 ){
       yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
-      sqlite3ExprSetHeight(yygotominor.yy172);
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
     }else{
       sqlite3SelectDelete(yymsp[-1].minor.yy219);
     }
@@ -75644,7 +78258,7 @@
     yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-4].minor.yy172, 0, 0);
     if( yygotominor.yy172 ){
       yygotominor.yy172->pSelect = yymsp[-1].minor.yy219;
-      sqlite3ExprSetHeight(yygotominor.yy172);
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
     }else{
       sqlite3SelectDelete(yymsp[-1].minor.yy219);
     }
@@ -75654,16 +78268,16 @@
         break;
       case 221: /* expr ::= expr in_op nm dbnm */
 {
-    SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410);
+    SrcList *pSrc = sqlite3SrcListAppend(pParse->db, 0,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0);
     yygotominor.yy172 = sqlite3PExpr(pParse, TK_IN, yymsp[-3].minor.yy172, 0, 0);
     if( yygotominor.yy172 ){
       yygotominor.yy172->pSelect = sqlite3SelectNew(pParse, 0,pSrc,0,0,0,0,0,0,0);
-      sqlite3ExprSetHeight(yygotominor.yy172);
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
     }else{
       sqlite3SrcListDelete(pSrc);
     }
     if( yymsp[-2].minor.yy46 ) yygotominor.yy172 = sqlite3PExpr(pParse, TK_NOT, yygotominor.yy172, 0, 0);
-    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy410.z?&yymsp[0].minor.yy410:&yymsp[-1].minor.yy410);
+    sqlite3ExprSpan(yygotominor.yy172,&yymsp[-3].minor.yy172->span,yymsp[0].minor.yy0.z?&yymsp[0].minor.yy0:&yymsp[-1].minor.yy0);
   }
         break;
       case 222: /* expr ::= EXISTS LP select RP */
@@ -75672,7 +78286,7 @@
     if( p ){
       p->pSelect = yymsp[-1].minor.yy219;
       sqlite3ExprSpan(p,&yymsp[-3].minor.yy0,&yymsp[0].minor.yy0);
-      sqlite3ExprSetHeight(yygotominor.yy172);
+      sqlite3ExprSetHeight(pParse, yygotominor.yy172);
     }else{
       sqlite3SelectDelete(yymsp[-1].minor.yy219);
     }
@@ -75683,7 +78297,7 @@
   yygotominor.yy172 = sqlite3PExpr(pParse, TK_CASE, yymsp[-3].minor.yy172, yymsp[-1].minor.yy172, 0);
   if( yygotominor.yy172 ){
     yygotominor.yy172->pList = yymsp[-2].minor.yy174;
-    sqlite3ExprSetHeight(yygotominor.yy172);
+    sqlite3ExprSetHeight(pParse, yygotominor.yy172);
   }else{
     sqlite3ExprListDelete(yymsp[-2].minor.yy174);
   }
@@ -75704,8 +78318,8 @@
         break;
       case 234: /* cmd ::= CREATE uniqueflag INDEX ifnotexists nm dbnm ON nm LP idxlist RP */
 {
-  sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy410, &yymsp[-5].minor.yy410, 
-                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy410,0), yymsp[-1].minor.yy174, yymsp[-9].minor.yy46,
+  sqlite3CreateIndex(pParse, &yymsp[-6].minor.yy0, &yymsp[-5].minor.yy0, 
+                     sqlite3SrcListAppend(pParse->db,0,&yymsp[-3].minor.yy0,0), yymsp[-1].minor.yy174, yymsp[-9].minor.yy46,
                       &yymsp[-10].minor.yy0, &yymsp[0].minor.yy0, SQLITE_SO_ASC, yymsp[-7].minor.yy46);
 }
         break;
@@ -75719,11 +78333,11 @@
       case 239: /* idxlist ::= idxlist COMMA idxitem collate sortorder */
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy410.n>0 ){
+  if( yymsp[-1].minor.yy0.n>0 ){
     p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
-    sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy410);
+    sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
   }
-  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy410);
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,yymsp[-4].minor.yy174, p, &yymsp[-2].minor.yy0);
   sqlite3ExprListCheckLength(pParse, yygotominor.yy174, "index");
   if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
 }
@@ -75731,17 +78345,17 @@
       case 240: /* idxlist ::= idxitem collate sortorder */
 {
   Expr *p = 0;
-  if( yymsp[-1].minor.yy410.n>0 ){
+  if( yymsp[-1].minor.yy0.n>0 ){
     p = sqlite3PExpr(pParse, TK_COLUMN, 0, 0, 0);
-    sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy410);
+    sqlite3ExprSetColl(pParse, p, &yymsp[-1].minor.yy0);
   }
-  yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy410);
+  yygotominor.yy174 = sqlite3ExprListAppend(pParse,0, p, &yymsp[-2].minor.yy0);
   sqlite3ExprListCheckLength(pParse, yygotominor.yy174, "index");
   if( yygotominor.yy174 ) yygotominor.yy174->a[yygotominor.yy174->nExpr-1].sortOrder = yymsp[0].minor.yy46;
 }
         break;
       case 242: /* collate ::= */
-{yygotominor.yy410.z = 0; yygotominor.yy410.n = 0;}
+{yygotominor.yy0.z = 0; yygotominor.yy0.n = 0;}
         break;
       case 244: /* cmd ::= DROP INDEX ifexists fullname */
 {sqlite3DropIndex(pParse, yymsp[0].minor.yy373, yymsp[-1].minor.yy46);}
@@ -75751,35 +78365,33 @@
 {sqlite3Vacuum(pParse);}
         break;
       case 247: /* cmd ::= PRAGMA nm dbnm EQ nmnum */
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,0);}
-        break;
       case 248: /* cmd ::= PRAGMA nm dbnm EQ ON */
       case 249: /* cmd ::= PRAGMA nm dbnm EQ DELETE */
-{sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy0,0);}
+{sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,0);}
         break;
       case 250: /* cmd ::= PRAGMA nm dbnm EQ minus_num */
 {
-  sqlite3Pragma(pParse,&yymsp[-3].minor.yy410,&yymsp[-2].minor.yy410,&yymsp[0].minor.yy410,1);
+  sqlite3Pragma(pParse,&yymsp[-3].minor.yy0,&yymsp[-2].minor.yy0,&yymsp[0].minor.yy0,1);
 }
         break;
       case 251: /* cmd ::= PRAGMA nm dbnm LP nmnum RP */
-{sqlite3Pragma(pParse,&yymsp[-4].minor.yy410,&yymsp[-3].minor.yy410,&yymsp[-1].minor.yy410,0);}
+{sqlite3Pragma(pParse,&yymsp[-4].minor.yy0,&yymsp[-3].minor.yy0,&yymsp[-1].minor.yy0,0);}
         break;
       case 252: /* cmd ::= PRAGMA nm dbnm */
-{sqlite3Pragma(pParse,&yymsp[-1].minor.yy410,&yymsp[0].minor.yy410,0,0);}
+{sqlite3Pragma(pParse,&yymsp[-1].minor.yy0,&yymsp[0].minor.yy0,0,0);}
         break;
       case 260: /* cmd ::= CREATE trigger_decl BEGIN trigger_cmd_list END */
 {
   Token all;
-  all.z = yymsp[-3].minor.yy410.z;
-  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy410.z) + yymsp[0].minor.yy0.n;
+  all.z = yymsp[-3].minor.yy0.z;
+  all.n = (yymsp[0].minor.yy0.z - yymsp[-3].minor.yy0.z) + yymsp[0].minor.yy0.n;
   sqlite3FinishTrigger(pParse, yymsp[-1].minor.yy243, &all);
 }
         break;
       case 261: /* trigger_decl ::= temp TRIGGER ifnotexists nm dbnm trigger_time trigger_event ON fullname foreach_clause when_clause */
 {
-  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy410, &yymsp[-6].minor.yy410, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[0].minor.yy172, yymsp[-10].minor.yy46, yymsp[-8].minor.yy46);
-  yygotominor.yy410 = (yymsp[-6].minor.yy410.n==0?yymsp[-7].minor.yy410:yymsp[-6].minor.yy410);
+  sqlite3BeginTrigger(pParse, &yymsp[-7].minor.yy0, &yymsp[-6].minor.yy0, yymsp[-5].minor.yy46, yymsp[-4].minor.yy370.a, yymsp[-4].minor.yy370.b, yymsp[-2].minor.yy373, yymsp[0].minor.yy172, yymsp[-10].minor.yy46, yymsp[-8].minor.yy46);
+  yygotominor.yy0 = (yymsp[-6].minor.yy0.n==0?yymsp[-7].minor.yy0:yymsp[-6].minor.yy0);
 }
         break;
       case 262: /* trigger_time ::= BEFORE */
@@ -75822,16 +78434,16 @@
 { yygotominor.yy243 = 0; }
         break;
       case 275: /* trigger_cmd ::= UPDATE orconf nm SET setlist where_opt */
-{ yygotominor.yy243 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy410, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); }
+{ yygotominor.yy243 = sqlite3TriggerUpdateStep(pParse->db, &yymsp[-3].minor.yy0, yymsp[-1].minor.yy174, yymsp[0].minor.yy172, yymsp[-4].minor.yy46); }
         break;
       case 276: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt VALUES LP itemlist RP */
-{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy410, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);}
+{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-5].minor.yy0, yymsp[-4].minor.yy432, yymsp[-1].minor.yy174, 0, yymsp[-7].minor.yy46);}
         break;
       case 277: /* trigger_cmd ::= insert_cmd INTO nm inscollist_opt select */
-{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy410, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);}
+{yygotominor.yy243 = sqlite3TriggerInsertStep(pParse->db, &yymsp[-2].minor.yy0, yymsp[-1].minor.yy432, 0, yymsp[0].minor.yy219, yymsp[-4].minor.yy46);}
         break;
       case 278: /* trigger_cmd ::= DELETE FROM nm where_opt */
-{yygotominor.yy243 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy410, yymsp[0].minor.yy172);}
+{yygotominor.yy243 = sqlite3TriggerDeleteStep(pParse->db, &yymsp[-1].minor.yy0, yymsp[0].minor.yy172);}
         break;
       case 279: /* trigger_cmd ::= select */
 {yygotominor.yy243 = sqlite3TriggerSelectStep(pParse->db, yymsp[0].minor.yy219); }
@@ -75847,7 +78459,7 @@
         break;
       case 281: /* expr ::= RAISE LP raisetype COMMA nm RP */
 {
-  yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy410); 
+  yygotominor.yy172 = sqlite3PExpr(pParse, TK_RAISE, 0, 0, &yymsp[-1].minor.yy0); 
   if( yygotominor.yy172 ) {
     yygotominor.yy172->iColumn = yymsp[-3].minor.yy46;
     sqlite3ExprSpan(yygotominor.yy172, &yymsp[-5].minor.yy0, &yymsp[0].minor.yy0);
@@ -75879,22 +78491,22 @@
 {sqlite3Reindex(pParse, 0, 0);}
         break;
       case 293: /* cmd ::= REINDEX nm dbnm */
-{sqlite3Reindex(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
+{sqlite3Reindex(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
       case 294: /* cmd ::= ANALYZE */
 {sqlite3Analyze(pParse, 0, 0);}
         break;
       case 295: /* cmd ::= ANALYZE nm dbnm */
-{sqlite3Analyze(pParse, &yymsp[-1].minor.yy410, &yymsp[0].minor.yy410);}
+{sqlite3Analyze(pParse, &yymsp[-1].minor.yy0, &yymsp[0].minor.yy0);}
         break;
       case 296: /* cmd ::= ALTER TABLE fullname RENAME TO nm */
 {
-  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy410);
+  sqlite3AlterRenameTable(pParse,yymsp[-3].minor.yy373,&yymsp[0].minor.yy0);
 }
         break;
       case 297: /* cmd ::= ALTER TABLE add_column_fullname ADD kwcolumn_opt column */
 {
-  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy410);
+  sqlite3AlterFinishAddColumn(pParse, &yymsp[0].minor.yy0);
 }
         break;
       case 298: /* add_column_fullname ::= fullname */
@@ -75910,7 +78522,7 @@
         break;
       case 303: /* create_vtab ::= CREATE VIRTUAL TABLE nm dbnm USING nm */
 {
-    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy410, &yymsp[-2].minor.yy410, &yymsp[0].minor.yy410);
+    sqlite3VtabBeginParse(pParse, &yymsp[-3].minor.yy0, &yymsp[-2].minor.yy0, &yymsp[0].minor.yy0);
 }
         break;
       case 306: /* vtabarg ::= */
@@ -76180,7 +78792,7 @@
 ** individual tokens and sends those tokens one-by-one over to the
 ** parser for analysis.
 **
-** $Id: tokenize.c,v 1.142 2008/04/28 18:46:43 drh Exp $
+** $Id: tokenize.c,v 1.146 2008/07/08 19:34:07 drh Exp $
 */
 
 /*
@@ -76652,9 +79264,9 @@
 /*
 ** Run the parser on the given SQL string.  The parser structure is
 ** passed in.  An SQLITE_ status code is returned.  If an error occurs
-** and pzErrMsg!=NULL then an error message might be written into 
-** memory obtained from sqlite3_malloc() and *pzErrMsg made to point to that
-** error message.  Or maybe not.
+** then an and attempt is made to write an error message into 
+** memory obtained from sqlite3_malloc() and to make *pzErrMsg point to that
+** error message.
 */
 SQLITE_PRIVATE int sqlite3RunParser(Parse *pParse, const char *zSql, char **pzErrMsg){
   int nErr = 0;
@@ -76671,7 +79283,8 @@
   pParse->rc = SQLITE_OK;
   pParse->zTail = pParse->zSql = zSql;
   i = 0;
-  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3_malloc);
+  assert( pzErrMsg!=0 );
+  pEngine = sqlite3ParserAlloc((void*(*)(size_t))sqlite3Malloc);
   if( pEngine==0 ){
     db->mallocFailed = 1;
     return SQLITE_NOMEM;
@@ -76698,17 +79311,15 @@
       case TK_COMMENT: {
         if( db->u1.isInterrupted ){
           pParse->rc = SQLITE_INTERRUPT;
-          sqlite3SetString(pzErrMsg, "interrupt", (char*)0);
+          sqlite3SetString(pzErrMsg, db, "interrupt");
           goto abort_parse;
         }
         break;
       }
       case TK_ILLEGAL: {
-        if( pzErrMsg ){
-          sqlite3_free(*pzErrMsg);
-          *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
-                          &pParse->sLastToken);
-        }
+        sqlite3_free(*pzErrMsg);
+        *pzErrMsg = sqlite3MPrintf(db, "unrecognized token: \"%T\"",
+                        &pParse->sLastToken);
         nErr++;
         goto abort_parse;
       }
@@ -76739,10 +79350,10 @@
     pParse->rc = SQLITE_NOMEM;
   }
   if( pParse->rc!=SQLITE_OK && pParse->rc!=SQLITE_DONE && pParse->zErrMsg==0 ){
-    sqlite3SetString(&pParse->zErrMsg, sqlite3ErrStr(pParse->rc), (char*)0);
+    sqlite3SetString(&pParse->zErrMsg, db, "%s", sqlite3ErrStr(pParse->rc));
   }
   if( pParse->zErrMsg ){
-    if( pzErrMsg && *pzErrMsg==0 ){
+    if( *pzErrMsg==0 ){
       *pzErrMsg = pParse->zErrMsg;
     }else{
       sqlite3_free(pParse->zErrMsg);
@@ -76801,7 +79412,7 @@
 ** separating it out, the code will be automatically omitted from
 ** static links that do not use it.
 **
-** $Id: complete.c,v 1.6 2007/08/27 23:26:59 drh Exp $
+** $Id: complete.c,v 1.7 2008/06/13 18:24:27 drh Exp $
 */
 #ifndef SQLITE_OMIT_COMPLETE
 
@@ -77042,11 +79653,17 @@
   char const *zSql8;
   int rc = SQLITE_NOMEM;
 
+#ifndef SQLITE_OMIT_AUTOINIT
+  rc = sqlite3_initialize();
+  if( rc ) return rc;
+#endif
   pVal = sqlite3ValueNew(0);
   sqlite3ValueSetStr(pVal, -1, zSql, SQLITE_UTF16NATIVE, SQLITE_STATIC);
   zSql8 = sqlite3ValueText(pVal, SQLITE_UTF8);
   if( zSql8 ){
     rc = sqlite3_complete(zSql8);
+  }else{
+    rc = SQLITE_NOMEM;
   }
   sqlite3ValueFree(pVal);
   return sqlite3ApiExit(0, rc);
@@ -77072,8 +79689,9 @@
 ** other files are for internal use by SQLite and should not be
 ** accessed by users of the library.
 **
-** $Id: main.c,v 1.439 2008/05/13 13:27:34 drh Exp $
+** $Id: main.c,v 1.479 2008/07/16 14:02:33 drh Exp $
 */
+
 #ifdef SQLITE_ENABLE_FTS3
 /************** Include fts3.h in the middle of main.c ***********************/
 /************** Begin file fts3.h ********************************************/
@@ -77106,6 +79724,38 @@
 /************** End of fts3.h ************************************************/
 /************** Continuing where we left off in main.c ***********************/
 #endif
+#ifdef SQLITE_ENABLE_RTREE
+/************** Include rtree.h in the middle of main.c **********************/
+/************** Begin file rtree.h *******************************************/
+/*
+** 2008 May 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 header file is used by programs that want to link against the
+** RTREE library.  All it does is declare the sqlite3RtreeInit() interface.
+*/
+
+#if 0
+extern "C" {
+#endif  /* __cplusplus */
+
+SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db);
+
+#if 0
+}  /* extern "C" */
+#endif  /* __cplusplus */
+
+/************** End of rtree.h ***********************************************/
+/************** Continuing where we left off in main.c ***********************/
+#endif
 
 /*
 ** The version of the library
@@ -77135,6 +79785,215 @@
 SQLITE_API char *sqlite3_temp_directory = 0;
 
 /*
+** Initialize SQLite.  
+**
+** This routine must be called to initialize the memory allocation,
+** VFS, and mutex subsystesms 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().  
+**
+** 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.
+*/
+SQLITE_API int sqlite3_initialize(void){
+  static int inProgress = 0;
+  int rc;
+
+  /* If SQLite is already initialized, this call is a no-op. */
+  if( sqlite3Config.isInit ) return SQLITE_OK;
+
+  /* Make sure the mutex system is initialized. */
+  rc = sqlite3MutexInit();
+
+  if( rc==SQLITE_OK ){
+
+    /* Initialize the malloc() system and the recursive pInitMutex mutex.
+    ** This operation is protected by the STATIC_MASTER mutex.
+    */
+    sqlite3_mutex *pMaster = sqlite3MutexAlloc(SQLITE_MUTEX_STATIC_MASTER);
+    sqlite3_mutex_enter(pMaster);
+    if( !sqlite3Config.isMallocInit ){
+      rc = sqlite3MallocInit();
+    }
+    if( rc==SQLITE_OK ){
+      sqlite3Config.isMallocInit = 1;
+      if( !sqlite3Config.pInitMutex ){
+        sqlite3Config.pInitMutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
+        if( sqlite3Config.bCoreMutex && !sqlite3Config.pInitMutex ){
+          rc = SQLITE_NOMEM;
+        }
+      }
+    }
+    sqlite3_mutex_leave(pMaster);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+
+    /* Enter the recursive pInitMutex mutex. After doing so, if the
+    ** sqlite3Config.isInit flag is true, then some other thread has
+    ** finished doing the initialization. If the inProgress flag is
+    ** true, then this function is being called recursively from within
+    ** the sqlite3_os_init() call below. In either case, exit early.
+    */
+    sqlite3_mutex_enter(sqlite3Config.pInitMutex);
+    if( sqlite3Config.isInit || inProgress ){
+      sqlite3_mutex_leave(sqlite3Config.pInitMutex);
+      return SQLITE_OK;
+    }
+    sqlite3StatusReset();
+    inProgress = 1;
+    rc = sqlite3_os_init();
+    inProgress = 0;
+    sqlite3Config.isInit = (rc==SQLITE_OK ? 1 : 0);
+    sqlite3_mutex_leave(sqlite3Config.pInitMutex);
+  }
+  return rc;
+}
+
+/*
+** Undo the effects of sqlite3_initialize().  Must not be called while
+** there are outstanding database connections or memory allocations or
+** while any part of SQLite is otherwise in use in any thread.  This
+** routine is not threadsafe.  Not by a long shot.
+*/
+SQLITE_API int sqlite3_shutdown(void){
+  sqlite3_mutex_free(sqlite3Config.pInitMutex);
+  sqlite3Config.pInitMutex = 0;
+  sqlite3Config.isMallocInit = 0;
+  if( sqlite3Config.isInit ){
+    sqlite3_os_end();
+  }
+  if( sqlite3Config.m.xShutdown ){
+    sqlite3MallocEnd();
+  }
+  if( sqlite3Config.mutex.xMutexEnd ){
+    sqlite3MutexEnd();
+  }
+  sqlite3Config.isInit = 0;
+  return SQLITE_OK;
+}
+
+/*
+** This API allows applications to modify the global configuration of
+** the SQLite library at run-time.
+**
+** This routine should only be called when there are no outstanding
+** database connections or memory allocations.  This routine is not
+** threadsafe.  Failure to heed these warnings can lead to unpredictable
+** behavior.
+*/
+SQLITE_API int sqlite3_config(int op, ...){
+  va_list ap;
+  int rc = SQLITE_OK;
+
+  /* sqlite3_config() shall return SQLITE_MISUSE if it is invoked while
+  ** the SQLite library is in use. */
+  if( sqlite3Config.isInit ) return SQLITE_MISUSE;
+
+  va_start(ap, op);
+  switch( op ){
+    case SQLITE_CONFIG_SINGLETHREAD: {
+      /* Disable all mutexing */
+      sqlite3Config.bCoreMutex = 0;
+      sqlite3Config.bFullMutex = 0;
+      break;
+    }
+    case SQLITE_CONFIG_MULTITHREAD: {
+      /* Disable mutexing of database connections */
+      /* Enable mutexing of core data structures */
+      sqlite3Config.bCoreMutex = 1;
+      sqlite3Config.bFullMutex = 0;
+      break;
+    }
+    case SQLITE_CONFIG_SERIALIZED: {
+      /* Enable all mutexing */
+      sqlite3Config.bCoreMutex = 1;
+      sqlite3Config.bFullMutex = 1;
+      break;
+    }
+    case SQLITE_CONFIG_MALLOC: {
+      /* Specify an alternative malloc implementation */
+      sqlite3Config.m = *va_arg(ap, sqlite3_mem_methods*);
+      break;
+    }
+    case SQLITE_CONFIG_GETMALLOC: {
+      /* Retrieve the current malloc() implementation */
+      if( sqlite3Config.m.xMalloc==0 ) sqlite3MemSetDefault();
+      *va_arg(ap, sqlite3_mem_methods*) = sqlite3Config.m;
+      break;
+    }
+    case SQLITE_CONFIG_MUTEX: {
+      /* Specify an alternative mutex implementation */
+      sqlite3Config.mutex = *va_arg(ap, sqlite3_mutex_methods*);
+      break;
+    }
+    case SQLITE_CONFIG_GETMUTEX: {
+      /* Retrieve the current mutex implementation */
+      *va_arg(ap, sqlite3_mutex_methods*) = sqlite3Config.mutex;
+      break;
+    }
+    case SQLITE_CONFIG_MEMSTATUS: {
+      /* Enable or disable the malloc status collection */
+      sqlite3Config.bMemstat = va_arg(ap, int);
+      break;
+    }
+    case SQLITE_CONFIG_SCRATCH: {
+      /* Designate a buffer for scratch memory space */
+      sqlite3Config.pScratch = va_arg(ap, void*);
+      sqlite3Config.szScratch = va_arg(ap, int);
+      sqlite3Config.nScratch = va_arg(ap, int);
+      break;
+    }
+    case SQLITE_CONFIG_PAGECACHE: {
+      /* Designate a buffer for scratch memory space */
+      sqlite3Config.pPage = va_arg(ap, void*);
+      sqlite3Config.szPage = va_arg(ap, int);
+      sqlite3Config.nPage = va_arg(ap, int);
+      break;
+    }
+
+#if defined(SQLITE_ENABLE_MEMSYS3) || defined(SQLITE_ENABLE_MEMSYS5)
+    case SQLITE_CONFIG_HEAP: {
+      /* Designate a buffer for heap memory space */
+      sqlite3Config.pHeap = va_arg(ap, void*);
+      sqlite3Config.nHeap = va_arg(ap, int);
+      sqlite3Config.mnReq = va_arg(ap, int);
+
+      if( sqlite3Config.pHeap==0 ){
+        /* If the heap pointer is NULL, then restore the malloc implementation
+        ** back to NULL pointers too.  This will cause the malloc to go
+        ** back to its default implementation when sqlite3_initialize() is
+        ** run.
+        */
+        memset(&sqlite3Config.m, 0, sizeof(sqlite3Config.m));
+      }else{
+        /* The heap pointer is not NULL, then install one of the
+        ** mem5.c/mem3.c methods. If neither ENABLE_MEMSYS3 nor
+        ** ENABLE_MEMSYS5 is defined, return an error.
+        ** the default case and return an error.
+        */
+#ifdef SQLITE_ENABLE_MEMSYS3
+        sqlite3Config.m = *sqlite3MemGetMemsys3();
+#endif
+#ifdef SQLITE_ENABLE_MEMSYS5
+        sqlite3Config.m = *sqlite3MemGetMemsys5();
+#endif
+      }
+      break;
+    }
+#endif
+
+    default: {
+      rc = SQLITE_ERROR;
+      break;
+    }
+  }
+  va_end(ap);
+  return rc;
+}
+
+/*
 ** Routine needed to support the testcase() macro.
 */
 #ifdef SQLITE_COVERAGE_TEST
@@ -77339,7 +80198,7 @@
   int i;
   int inTrans = 0;
   assert( sqlite3_mutex_held(db->mutex) );
-  sqlite3FaultBeginBenign(SQLITE_FAULTINJECTOR_MALLOC);
+  sqlite3BeginBenignMalloc();
   for(i=0; i<db->nDb; i++){
     if( db->aDb[i].pBt ){
       if( sqlite3BtreeIsInTrans(db->aDb[i].pBt) ){
@@ -77350,7 +80209,7 @@
     }
   }
   sqlite3VtabRollback(db);
-  sqlite3FaultEndBenign(SQLITE_FAULTINJECTOR_MALLOC);
+  sqlite3EndBenignMalloc();
 
   if( db->flags&SQLITE_InternChanges ){
     sqlite3ExpirePreparedStatements(db);
@@ -77411,7 +80270,7 @@
  void *ptr,               /* Database connection */
  int count                /* Number of times table has been busy */
 ){
-#if OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
+#if SQLITE_OS_WIN || (defined(HAVE_USLEEP) && HAVE_USLEEP)
   static const u8 delays[] =
      { 1, 2, 5, 10, 15, 20, 25, 25,  25,  50,  50, 100 };
   static const u8 totals[] =
@@ -77455,7 +80314,7 @@
 */
 SQLITE_PRIVATE int sqlite3InvokeBusyHandler(BusyHandler *p){
   int rc;
-  if( p==0 || p->xFunc==0 || p->nBusy<0 ) return 0;
+  if( NEVER(p==0) || p->xFunc==0 || p->nBusy<0 ) return 0;
   rc = p->xFunc(p->pArg, p->nBusy);
   if( rc==0 ){
     p->nBusy = -1;
@@ -77494,19 +80353,17 @@
   int (*xProgress)(void*), 
   void *pArg
 ){
-  if( sqlite3SafetyCheckOk(db) ){
-    sqlite3_mutex_enter(db->mutex);
-    if( nOps>0 ){
-      db->xProgress = xProgress;
-      db->nProgressOps = nOps;
-      db->pProgressArg = pArg;
-    }else{
-      db->xProgress = 0;
-      db->nProgressOps = 0;
-      db->pProgressArg = 0;
-    }
-    sqlite3_mutex_leave(db->mutex);
+  sqlite3_mutex_enter(db->mutex);
+  if( nOps>0 ){
+    db->xProgress = xProgress;
+    db->nProgressOps = nOps;
+    db->pProgressArg = pArg;
+  }else{
+    db->xProgress = 0;
+    db->nProgressOps = 0;
+    db->pProgressArg = 0;
   }
+  sqlite3_mutex_leave(db->mutex);
 }
 #endif
 
@@ -77529,9 +80386,7 @@
 ** Cause any pending operation to stop at its earliest opportunity.
 */
 SQLITE_API void sqlite3_interrupt(sqlite3 *db){
-  if( sqlite3SafetyCheckOk(db) ){
-    db->u1.isInterrupted = 1;
-  }
+  db->u1.isInterrupted = 1;
 }
 
 
@@ -77559,8 +80414,8 @@
       (xFunc && (xFinal || xStep)) || 
       (!xFunc && (xFinal && !xStep)) ||
       (!xFunc && (!xFinal && xStep)) ||
-      (nArg<-1 || nArg>127) ||
-      (255<(nName = strlen(zFunctionName))) ){
+      (nArg<-1 || nArg>SQLITE_MAX_FUNCTION_ARG) ||
+      (255<(nName = sqlite3Strlen(db, zFunctionName))) ){
     sqlite3Error(db, SQLITE_ERROR, "bad parameters");
     return SQLITE_ERROR;
   }
@@ -77686,7 +80541,7 @@
   const char *zName,
   int nArg
 ){
-  int nName = strlen(zName);
+  int nName = sqlite3Strlen(db, zName);
   int rc;
   sqlite3_mutex_enter(db->mutex);
   if( sqlite3FindFunction(db, zName, nName, nArg, SQLITE_UTF8, 0)==0 ){
@@ -77806,19 +80661,19 @@
 **
 ** A virtual database can be either a disk file (that is automatically
 ** deleted when the file is closed) or it an be held entirely in memory,
-** depending on the values of the TEMP_STORE compile-time macro and the
+** depending on the values of the SQLITE_TEMP_STORE compile-time macro and the
 ** db->temp_store variable, according to the following chart:
 **
-**       TEMP_STORE     db->temp_store     Location of temporary database
-**       ----------     --------------     ------------------------------
-**           0               any             file
-**           1                1              file
-**           1                2              memory
-**           1                0              file
-**           2                1              file
-**           2                2              memory
-**           2                0              memory
-**           3               any             memory
+**   SQLITE_TEMP_STORE     db->temp_store     Location of temporary database
+**   -----------------     --------------     ------------------------------
+**   0                     any                file
+**   1                     1                  file
+**   1                     2                  memory
+**   1                     0                  file
+**   2                     1                  file
+**   2                     2                  memory
+**   2                     0                  memory
+**   3                     any                memory
 */
 SQLITE_PRIVATE int sqlite3BtreeFactory(
   const sqlite3 *db,        /* Main database when opening aux otherwise 0 */
@@ -77840,17 +80695,17 @@
     btFlags |= BTREE_NO_READLOCK;
   }
   if( zFilename==0 ){
-#if TEMP_STORE==0
+#if SQLITE_TEMP_STORE==0
     /* Do nothing */
 #endif
 #ifndef SQLITE_OMIT_MEMORYDB
-#if TEMP_STORE==1
+#if SQLITE_TEMP_STORE==1
     if( db->temp_store==2 ) zFilename = ":memory:";
 #endif
-#if TEMP_STORE==2
+#if SQLITE_TEMP_STORE==2
     if( db->temp_store!=1 ) zFilename = ":memory:";
 #endif
-#if TEMP_STORE==3
+#if SQLITE_TEMP_STORE==3
     zFilename = ":memory:";
 #endif
 #endif /* SQLITE_OMIT_MEMORYDB */
@@ -77860,7 +80715,13 @@
     vfsFlags = (vfsFlags & ~SQLITE_OPEN_MAIN_DB) | SQLITE_OPEN_TEMP_DB;
   }
   rc = sqlite3BtreeOpen(zFilename, (sqlite3 *)db, ppBtree, btFlags, vfsFlags);
-  if( rc==SQLITE_OK ){
+
+  /* If the B-Tree was successfully opened, set the pager-cache size to the
+  ** default value. Except, if the call to BtreeOpen() returned a handle
+  ** open on an existing shared pager-cache, do not change the pager-cache 
+  ** size.
+  */
+  if( rc==SQLITE_OK && 0==sqlite3BtreeSchema(*ppBtree, 0, 0) ){
     sqlite3BtreeSetCacheSize(*ppBtree, nCache);
   }
   return rc;
@@ -77875,12 +80736,13 @@
   if( !db ){
     return sqlite3ErrStr(SQLITE_NOMEM);
   }
-  if( !sqlite3SafetyCheckSickOrOk(db) || db->errCode==SQLITE_MISUSE ){
+  if( !sqlite3SafetyCheckSickOrOk(db) ){
     return sqlite3ErrStr(SQLITE_MISUSE);
   }
   sqlite3_mutex_enter(db->mutex);
   assert( !db->mallocFailed );
   z = (char*)sqlite3_value_text(db->pErr);
+  assert( !db->mallocFailed );
   if( z==0 ){
     z = sqlite3ErrStr(db->errCode);
   }
@@ -77917,7 +80779,7 @@
   if( !db ){
     return (void *)(&outOfMemBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
   }
-  if( !sqlite3SafetyCheckSickOrOk(db) || db->errCode==SQLITE_MISUSE ){
+  if( !sqlite3SafetyCheckSickOrOk(db) ){
     return (void *)(&misuseBe[SQLITE_UTF16NATIVE==SQLITE_UTF16LE?1:0]);
   }
   sqlite3_mutex_enter(db->mutex);
@@ -77928,7 +80790,12 @@
          SQLITE_UTF8, SQLITE_STATIC);
     z = sqlite3_value_text16(db->pErr);
   }
-  sqlite3ApiExit(0, 0);
+  /* A malloc() may have failed within the call to sqlite3_value_text16()
+  ** above. If this is the case, then the db->mallocFailed flag needs to
+  ** be cleared before returning. Do this directly, instead of via
+  ** sqlite3ApiExit(), to avoid setting the database handle error message.
+  */
+  db->mallocFailed = 0;
   sqlite3_mutex_leave(db->mutex);
   return z;
 }
@@ -77962,6 +80829,7 @@
 ){
   CollSeq *pColl;
   int enc2;
+  int nName;
   
   assert( sqlite3_mutex_held(db->mutex) );
 
@@ -77973,17 +80841,16 @@
   if( enc2==SQLITE_UTF16 ){
     enc2 = SQLITE_UTF16NATIVE;
   }
-
   if( (enc2&~3)!=0 ){
-    sqlite3Error(db, SQLITE_ERROR, "unknown encoding");
-    return SQLITE_ERROR;
+    return SQLITE_MISUSE;
   }
 
   /* 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, strlen(zName), 0);
+  nName = sqlite3Strlen(db, zName);
+  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 0);
   if( pColl && pColl->xCmp ){
     if( db->activeVdbeCnt ){
       sqlite3Error(db, SQLITE_BUSY, 
@@ -77999,7 +80866,7 @@
     ** to be called.
     */ 
     if( (pColl->enc & ~SQLITE_UTF16_ALIGNED)==enc2 ){
-      CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, strlen(zName));
+      CollSeq *aColl = sqlite3HashFind(&db->aCollSeq, zName, nName);
       int j;
       for(j=0; j<3; j++){
         CollSeq *p = &aColl[j];
@@ -78013,7 +80880,7 @@
     }
   }
 
-  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, strlen(zName), 1);
+  pColl = sqlite3FindCollSeq(db, (u8)enc2, zName, nName, 1);
   if( pColl ){
     pColl->xCmp = xCompare;
     pColl->pUser = pCtx;
@@ -78061,8 +80928,8 @@
 #if SQLITE_MAX_VDBE_OP<40
 # error SQLITE_MAX_VDBE_OP must be at least 40
 #endif
-#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>255
-# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 255
+#if SQLITE_MAX_FUNCTION_ARG<0 || SQLITE_MAX_FUNCTION_ARG>127
+# error SQLITE_MAX_FUNCTION_ARG must be between 0 and 127
 #endif
 #if SQLITE_MAX_ATTACH<0 || SQLITE_MAX_ATTACH>30
 # error SQLITE_MAX_ATTACH must be between 0 and 30
@@ -78114,6 +80981,16 @@
   sqlite3 *db;
   int rc;
   CollSeq *pColl;
+  int isThreadsafe = 1;
+
+#ifndef SQLITE_OMIT_AUTOINIT
+  rc = sqlite3_initialize();
+  if( rc ) return rc;
+#endif
+
+  if( flags&SQLITE_OPEN_NOMUTEX ){
+    isThreadsafe = 0;
+  }
 
   /* Remove harmful bits from the flags parameter */
   flags &=  ~( SQLITE_OPEN_DELETEONCLOSE |
@@ -78123,17 +81000,20 @@
                SQLITE_OPEN_MAIN_JOURNAL | 
                SQLITE_OPEN_TEMP_JOURNAL | 
                SQLITE_OPEN_SUBJOURNAL | 
-               SQLITE_OPEN_MASTER_JOURNAL
+               SQLITE_OPEN_MASTER_JOURNAL |
+               SQLITE_OPEN_NOMUTEX
              );
 
   /* Allocate the sqlite data structure */
   db = sqlite3MallocZero( sizeof(sqlite3) );
   if( db==0 ) goto opendb_out;
-  db->mutex = sqlite3_mutex_alloc(SQLITE_MUTEX_RECURSIVE);
-  if( db->mutex==0 ){
-    sqlite3_free(db);
-    db = 0;
-    goto opendb_out;
+  if( sqlite3Config.bFullMutex && isThreadsafe ){
+    db->mutex = sqlite3MutexAlloc(SQLITE_MUTEX_RECURSIVE);
+    if( db->mutex==0 ){
+      sqlite3_free(db);
+      db = 0;
+      goto opendb_out;
+    }
   }
   sqlite3_mutex_enter(db->mutex);
   db->errMask = 0xff;
@@ -78263,6 +81143,13 @@
     rc = sqlite3IcuInit(db);
   }
 #endif
+
+#ifdef SQLITE_ENABLE_RTREE
+  if( !db->mallocFailed && rc==SQLITE_OK){
+    rc = sqlite3RtreeInit(db);
+  }
+#endif
+
   sqlite3Error(db, rc, 0);
 
   /* -DSQLITE_DEFAULT_LOCKING_MODE=1 makes EXCLUSIVE the default locking
@@ -78277,7 +81164,7 @@
 
 opendb_out:
   if( db ){
-    assert( db->mutex!=0 );
+    assert( db->mutex!=0 || isThreadsafe==0 || sqlite3Config.bFullMutex==0 );
     sqlite3_mutex_leave(db->mutex);
   }
   if( SQLITE_NOMEM==(rc = sqlite3_errcode(db)) ){
@@ -78317,11 +81204,15 @@
 ){
   char const *zFilename8;   /* zFilename encoded in UTF-8 instead of UTF-16 */
   sqlite3_value *pVal;
-  int rc = SQLITE_NOMEM;
+  int rc;
 
   assert( zFilename );
   assert( ppDb );
   *ppDb = 0;
+#ifndef SQLITE_OMIT_AUTOINIT
+  rc = sqlite3_initialize();
+  if( rc ) return rc;
+#endif
   pVal = sqlite3ValueNew(0);
   sqlite3ValueSetStr(pVal, -1, zFilename, SQLITE_UTF16NATIVE, SQLITE_STATIC);
   zFilename8 = sqlite3ValueText(pVal, SQLITE_UTF8);
@@ -78332,6 +81223,8 @@
     if( rc==SQLITE_OK && !DbHasProperty(*ppDb, 0, DB_SchemaLoaded) ){
       ENC(*ppDb) = SQLITE_UTF16NATIVE;
     }
+  }else{
+    rc = SQLITE_NOMEM;
   }
   sqlite3ValueFree(pVal);
 
@@ -78384,7 +81277,7 @@
 */
 SQLITE_API int sqlite3_create_collation16(
   sqlite3* db, 
-  const char *zName, 
+  const void *zName,
   int enc, 
   void* pCtx,
   int(*xCompare)(void*,int,const void*,int,const void*)
@@ -78497,7 +81390,7 @@
   char const **pzCollSeq,     /* OUTPUT: Collation sequence name */
   int *pNotNull,              /* OUTPUT: True if NOT NULL constraint exists */
   int *pPrimaryKey,           /* OUTPUT: True if column part of PK */
-  int *pAutoinc               /* OUTPUT: True if colums is auto-increment */
+  int *pAutoinc               /* OUTPUT: True if column is auto-increment */
 ){
   int rc;
   char *zErrMsg = 0;
@@ -78560,9 +81453,9 @@
   if( pCol ){
     zDataType = pCol->zType;
     zCollSeq = pCol->zColl;
-    notnull = (pCol->notNull?1:0);
-    primarykey  = (pCol->isPrimKey?1:0);
-    autoinc = ((pTab->iPKey==iCol && pTab->autoInc)?1:0);
+    notnull = pCol->notNull!=0;
+    primarykey  = pCol->isPrimKey!=0;
+    autoinc = pTab->iPKey==iCol && pTab->autoInc;
   }else{
     zDataType = "INTEGER";
     primarykey = 1;
@@ -78585,8 +81478,9 @@
   if( pAutoinc ) *pAutoinc = autoinc;
 
   if( SQLITE_OK==rc && !pTab ){
-    sqlite3SetString(&zErrMsg, "no such table column: ", zTableName, ".", 
-        zColumnName, 0);
+    sqlite3_free(zErrMsg);
+    zErrMsg = sqlite3MPrintf(db, "no such table column: %s.%s", zTableName,
+        zColumnName);
     rc = SQLITE_ERROR;
   }
   sqlite3Error(db, rc, (zErrMsg?"%s":0), zErrMsg);
@@ -78604,6 +81498,7 @@
   sqlite3_vfs *pVfs;
   int rc;
   pVfs = sqlite3_vfs_find(0);
+  if( pVfs==0 ) return 0;
 
   /* This function works in milliseconds, but the underlying OsSleep() 
   ** API uses microseconds. Hence the 1000's.
@@ -78665,58 +81560,6 @@
   va_list ap;
   va_start(ap, op);
   switch( op ){
-    /*
-    ** sqlite3_test_control(FAULT_CONFIG, fault_id, nDelay, nRepeat)
-    **
-    ** Configure a fault injector.  The specific fault injector is
-    ** identified by the fault_id argument.  (ex: SQLITE_FAULTINJECTOR_MALLOC)
-    ** The fault will occur after a delay of nDelay calls.  The fault
-    ** will repeat nRepeat times.
-    */
-    case SQLITE_TESTCTRL_FAULT_CONFIG: {
-      int id = va_arg(ap, int);
-      int nDelay = va_arg(ap, int);
-      int nRepeat = va_arg(ap, int);
-      sqlite3FaultConfig(id, nDelay, nRepeat);
-      break;
-    }
-
-    /*
-    ** sqlite3_test_control(FAULT_FAILURES, fault_id)
-    **
-    ** Return the number of faults (both hard and benign faults) that have
-    ** occurred since the injector identified by fault_id) was last configured.
-    */
-    case SQLITE_TESTCTRL_FAULT_FAILURES: {
-      int id = va_arg(ap, int);
-      rc = sqlite3FaultFailures(id);
-      break;
-    }
-
-    /*
-    ** sqlite3_test_control(FAULT_BENIGN_FAILURES, fault_id)
-    **
-    ** Return the number of benign faults that have occurred since the
-    ** injector identified by fault_id was last configured.
-    */
-    case SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES: {
-      int id = va_arg(ap, int);
-      rc = sqlite3FaultBenignFailures(id);
-      break;
-    }
-
-    /*
-    ** sqlite3_test_control(FAULT_PENDING, fault_id)
-    **
-    ** Return the number of successes that will occur before the next
-    ** scheduled failure on fault injector fault_id.
-    ** If no failures are scheduled, return -1.
-    */
-    case SQLITE_TESTCTRL_FAULT_PENDING: {
-      int id = va_arg(ap, int);
-      rc = sqlite3FaultPending(id);
-      break;
-    }
 
     /*
     ** Save the current state of the PRNG.
@@ -78760,6 +81603,22 @@
       rc = sqlite3BitvecBuiltinTest(sz, aProg);
       break;
     }
+
+    /*
+    **  sqlite3_test_control(BENIGN_MALLOC_HOOKS, xBegin, xEnd)
+    **
+    ** Register hooks to call to indicate which malloc() failures 
+    ** are benign.
+    */
+    case SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS: {
+      typedef void (*void_function)(void);
+      void_function xBenignBegin;
+      void_function xBenignEnd;
+      xBenignBegin = va_arg(ap, void_function);
+      xBenignEnd = va_arg(ap, void_function);
+      sqlite3BenignMallocHooks(xBenignBegin, xBenignEnd);
+      break;
+    }
   }
   va_end(ap);
 #endif /* SQLITE_OMIT_BUILTIN_TEST */
@@ -80930,17 +83789,22 @@
   CONTENT_SELECT_STMT,
   CONTENT_UPDATE_STMT,
   CONTENT_DELETE_STMT,
+  CONTENT_EXISTS_STMT,
 
   BLOCK_INSERT_STMT,
   BLOCK_SELECT_STMT,
   BLOCK_DELETE_STMT,
+  BLOCK_DELETE_ALL_STMT,
 
   SEGDIR_MAX_INDEX_STMT,
   SEGDIR_SET_STMT,
-  SEGDIR_SELECT_STMT,
+  SEGDIR_SELECT_LEVEL_STMT,
   SEGDIR_SPAN_STMT,
   SEGDIR_DELETE_STMT,
+  SEGDIR_SELECT_SEGMENT_STMT,
   SEGDIR_SELECT_ALL_STMT,
+  SEGDIR_DELETE_ALL_STMT,
+  SEGDIR_COUNT_STMT,
 
   MAX_STMT                     /* Always at end! */
 } fulltext_statement;
@@ -80955,23 +83819,35 @@
   /* CONTENT_SELECT */ NULL,  /* generated in contentSelectStatement() */
   /* CONTENT_UPDATE */ NULL,  /* generated in contentUpdateStatement() */
   /* CONTENT_DELETE */ "delete from %_content where docid = ?",
+  /* CONTENT_EXISTS */ "select docid from %_content limit 1",
 
   /* BLOCK_INSERT */
   "insert into %_segments (blockid, block) values (null, ?)",
   /* BLOCK_SELECT */ "select block from %_segments where blockid = ?",
   /* BLOCK_DELETE */ "delete from %_segments where blockid between ? and ?",
+  /* BLOCK_DELETE_ALL */ "delete from %_segments",
 
   /* SEGDIR_MAX_INDEX */ "select max(idx) from %_segdir where level = ?",
   /* SEGDIR_SET */ "insert into %_segdir values (?, ?, ?, ?, ?, ?)",
-  /* SEGDIR_SELECT */
+  /* SEGDIR_SELECT_LEVEL */
   "select start_block, leaves_end_block, root from %_segdir "
   " where level = ? order by idx",
   /* SEGDIR_SPAN */
   "select min(start_block), max(end_block) from %_segdir "
   " where level = ? and start_block <> 0",
   /* SEGDIR_DELETE */ "delete from %_segdir where level = ?",
+
+  /* NOTE(shess): The first three results of the following two
+  ** statements must match.
+  */
+  /* SEGDIR_SELECT_SEGMENT */
+  "select start_block, leaves_end_block, root from %_segdir "
+  " where level = ? and idx = ?",
   /* SEGDIR_SELECT_ALL */
-  "select root, leaves_end_block from %_segdir order by level desc, idx",
+  "select start_block, leaves_end_block, root from %_segdir "
+  " order by level desc, idx asc",
+  /* SEGDIR_DELETE_ALL */ "delete from %_segdir",
+  /* SEGDIR_COUNT */ "select count(*), ifnull(max(level),0) from %_segdir",
 };
 
 /*
@@ -81136,15 +84012,18 @@
 }
 
 /* Like sql_get_statement(), but for special replicated LEAF_SELECT
-** statements.
+** statements.  idx -1 is a special case for an uncached version of
+** the statement (used in the optimize implementation).
 */
 /* TODO(shess) Write version for generic statements and then share
 ** that between the cached-statement functions.
 */
 static int sql_get_leaf_statement(fulltext_vtab *v, int idx,
                                   sqlite3_stmt **ppStmt){
-  assert( idx>=0 && idx<MERGE_COUNT );
-  if( v->pLeafSelectStmts[idx]==NULL ){
+  assert( idx>=-1 && idx<MERGE_COUNT );
+  if( idx==-1 ){
+    return sql_prepare(v->db, v->zDb, v->zName, ppStmt, LEAF_SELECT);
+  }else if( v->pLeafSelectStmts[idx]==NULL ){
     int rc = sql_prepare(v->db, v->zDb, v->zName, &v->pLeafSelectStmts[idx],
                          LEAF_SELECT);
     if( rc!=SQLITE_OK ) return rc;
@@ -81265,6 +84144,25 @@
   return sql_single_step(s);
 }
 
+/* Returns SQLITE_ROW if any rows exist in %_content, SQLITE_DONE if
+** no rows exist, and any error in case of failure.
+*/
+static int content_exists(fulltext_vtab *v){
+  sqlite3_stmt *s;
+  int rc = sql_get_statement(v, CONTENT_EXISTS_STMT, &s);
+  if( rc!=SQLITE_OK ) return rc;
+
+  rc = sqlite3_step(s);
+  if( rc!=SQLITE_ROW ) return rc;
+
+  /* We expect only one row.  We must execute another sqlite3_step()
+   * to complete the iteration; otherwise the table will remain locked. */
+  rc = sqlite3_step(s);
+  if( rc==SQLITE_DONE ) return SQLITE_ROW;
+  if( rc==SQLITE_ROW ) return SQLITE_ERROR;
+  return rc;
+}
+
 /* insert into %_segments values ([pData])
 **   returns assigned blockid in *piBlockid
 */
@@ -81439,6 +84337,54 @@
   return sql_single_step(s);
 }
 
+/* Delete entire fts index, SQLITE_OK on success, relevant error on
+** failure.
+*/
+static int segdir_delete_all(fulltext_vtab *v){
+  sqlite3_stmt *s;
+  int rc = sql_get_statement(v, SEGDIR_DELETE_ALL_STMT, &s);
+  if( rc!=SQLITE_OK ) return rc;
+
+  rc = sql_single_step(s);
+  if( rc!=SQLITE_OK ) return rc;
+
+  rc = sql_get_statement(v, BLOCK_DELETE_ALL_STMT, &s);
+  if( rc!=SQLITE_OK ) return rc;
+
+  return sql_single_step(s);
+}
+
+/* Returns SQLITE_OK with *pnSegments set to the number of entries in
+** %_segdir and *piMaxLevel set to the highest level which has a
+** segment.  Otherwise returns the SQLite error which caused failure.
+*/
+static int segdir_count(fulltext_vtab *v, int *pnSegments, int *piMaxLevel){
+  sqlite3_stmt *s;
+  int rc = sql_get_statement(v, SEGDIR_COUNT_STMT, &s);
+  if( rc!=SQLITE_OK ) return rc;
+
+  rc = sqlite3_step(s);
+  /* TODO(shess): This case should not be possible?  Should stronger
+  ** measures be taken if it happens?
+  */
+  if( rc==SQLITE_DONE ){
+    *pnSegments = 0;
+    *piMaxLevel = 0;
+    return SQLITE_OK;
+  }
+  if( rc!=SQLITE_ROW ) return rc;
+
+  *pnSegments = sqlite3_column_int(s, 0);
+  *piMaxLevel = sqlite3_column_int(s, 1);
+
+  /* We expect only one row.  We must execute another sqlite3_step()
+   * to complete the iteration; otherwise the table will remain locked. */
+  rc = sqlite3_step(s);
+  if( rc==SQLITE_DONE ) return SQLITE_OK;
+  if( rc==SQLITE_ROW ) return SQLITE_ERROR;
+  return rc;
+}
+
 /* TODO(shess) clearPendingTerms() is far down the file because
 ** writeZeroSegment() is far down the file because LeafWriter is far
 ** down the file.  Consider refactoring the code to move the non-vtab
@@ -84314,6 +87260,12 @@
 }
 
 static void leavesReaderDestroy(LeavesReader *pReader){
+  /* If idx is -1, that means we're using a non-cached statement
+  ** handle in the optimize() case, so we need to release it.
+  */
+  if( pReader->pStmt!=NULL && pReader->idx==-1 ){
+    sqlite3_finalize(pReader->pStmt);
+  }
   leafReaderDestroy(&pReader->leafReader);
   dataBufferDestroy(&pReader->rootData);
   SCRAMBLE(pReader);
@@ -84434,7 +87386,7 @@
 static int leavesReadersInit(fulltext_vtab *v, int iLevel,
                              LeavesReader *pReaders, int *piReaders){
   sqlite3_stmt *s;
-  int i, rc = sql_get_statement(v, SEGDIR_SELECT_STMT, &s);
+  int i, rc = sql_get_statement(v, SEGDIR_SELECT_LEVEL_STMT, &s);
   if( rc!=SQLITE_OK ) return rc;
 
   rc = sqlite3_bind_int(s, 1, iLevel);
@@ -84972,8 +87924,8 @@
   ** elements for given docids overwrite older elements.
   */
   while( (rc = sqlite3_step(s))==SQLITE_ROW ){
-    const char *pData = sqlite3_column_blob(s, 0);
-    const int nData = sqlite3_column_bytes(s, 0);
+    const char *pData = sqlite3_column_blob(s, 2);
+    const int nData = sqlite3_column_bytes(s, 2);
     const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
     rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, isPrefix,
                      &doclist);
@@ -85127,6 +88079,23 @@
 
   if( nArg<2 ){
     rc = index_delete(v, sqlite3_value_int64(ppArg[0]));
+    if( rc==SQLITE_OK ){
+      /* If we just deleted the last row in the table, clear out the
+      ** index data.
+      */
+      rc = content_exists(v);
+      if( rc==SQLITE_ROW ){
+        rc = SQLITE_OK;
+      }else if( rc==SQLITE_DONE ){
+        /* Clear the pending terms so we don't flush a useless level-0
+        ** segment when the transaction closes.
+        */
+        rc = clearPendingTerms(v);
+        if( rc==SQLITE_OK ){
+          rc = segdir_delete_all(v);
+        }
+      }
+    }
   } else if( sqlite3_value_type(ppArg[0]) != SQLITE_NULL ){
     /* An update:
      * ppArg[0] = old rowid
@@ -85263,119 +88232,795 @@
   }
 }
 
-/*
-** This routine implements the xFindFunction method for the FTS3
-** virtual table.
+/* OptLeavesReader is nearly identical to LeavesReader, except that
+** where LeavesReader is geared towards the merging of complete
+** segment levels (with exactly MERGE_COUNT segments), OptLeavesReader
+** is geared towards implementation of the optimize() function, and
+** can merge all segments simultaneously.  This version may be
+** somewhat less efficient than LeavesReader because it merges into an
+** accumulator rather than doing an N-way merge, but since segment
+** size grows exponentially (so segment count logrithmically) this is
+** probably not an immediate problem.
+*/
+/* TODO(shess): Prove that assertion, or extend the merge code to
+** merge tree fashion (like the prefix-searching code does).
+*/
+/* TODO(shess): OptLeavesReader and LeavesReader could probably be
+** merged with little or no loss of performance for LeavesReader.  The
+** merged code would need to handle >MERGE_COUNT segments, and would
+** also need to be able to optionally optimize away deletes.
+*/
+typedef struct OptLeavesReader {
+  /* Segment number, to order readers by age. */
+  int segment;
+  LeavesReader reader;
+} OptLeavesReader;
+
+static int optLeavesReaderAtEnd(OptLeavesReader *pReader){
+  return leavesReaderAtEnd(&pReader->reader);
+}
+static int optLeavesReaderTermBytes(OptLeavesReader *pReader){
+  return leavesReaderTermBytes(&pReader->reader);
+}
+static const char *optLeavesReaderData(OptLeavesReader *pReader){
+  return leavesReaderData(&pReader->reader);
+}
+static int optLeavesReaderDataBytes(OptLeavesReader *pReader){
+  return leavesReaderDataBytes(&pReader->reader);
+}
+static const char *optLeavesReaderTerm(OptLeavesReader *pReader){
+  return leavesReaderTerm(&pReader->reader);
+}
+static int optLeavesReaderStep(fulltext_vtab *v, OptLeavesReader *pReader){
+  return leavesReaderStep(v, &pReader->reader);
+}
+static int optLeavesReaderTermCmp(OptLeavesReader *lr1, OptLeavesReader *lr2){
+  return leavesReaderTermCmp(&lr1->reader, &lr2->reader);
+}
+/* Order by term ascending, segment ascending (oldest to newest), with
+** exhausted readers to the end.
 */
-static int fulltextFindFunction(
-  sqlite3_vtab *pVtab,
-  int nArg,
-  const char *zName,
-  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
-  void **ppArg
-){
-  if( strcmp(zName,"snippet")==0 ){
-    *pxFunc = snippetFunc;
-    return 1;
-  }else if( strcmp(zName,"offsets")==0 ){
-    *pxFunc = snippetOffsetsFunc;
-    return 1;
-  }
-  return 0;
+static int optLeavesReaderCmp(OptLeavesReader *lr1, OptLeavesReader *lr2){
+  int c = optLeavesReaderTermCmp(lr1, lr2);
+  if( c!=0 ) return c;
+  return lr1->segment-lr2->segment;
 }
-
-/*
-** Rename an fts3 table.
+/* Bubble pLr[0] to appropriate place in pLr[1..nLr-1].  Assumes that
+** pLr[1..nLr-1] is already sorted.
 */
-static int fulltextRename(
-  sqlite3_vtab *pVtab,
-  const char *zName
-){
-  fulltext_vtab *p = (fulltext_vtab *)pVtab;
-  int rc = SQLITE_NOMEM;
-  char *zSql = sqlite3_mprintf(
-    "ALTER TABLE %Q.'%q_content'  RENAME TO '%q_content';"
-    "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';"
-    "ALTER TABLE %Q.'%q_segdir'   RENAME TO '%q_segdir';"
-    , p->zDb, p->zName, zName 
-    , p->zDb, p->zName, zName 
-    , p->zDb, p->zName, zName
-  );
-  if( zSql ){
-    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
-    sqlite3_free(zSql);
+static void optLeavesReaderReorder(OptLeavesReader *pLr, int nLr){
+  while( nLr>1 && optLeavesReaderCmp(pLr, pLr+1)>0 ){
+    OptLeavesReader tmp = pLr[0];
+    pLr[0] = pLr[1];
+    pLr[1] = tmp;
+    nLr--;
+    pLr++;
   }
-  return rc;
 }
 
-static const sqlite3_module fts3Module = {
-  /* iVersion      */ 0,
-  /* xCreate       */ fulltextCreate,
-  /* xConnect      */ fulltextConnect,
-  /* xBestIndex    */ fulltextBestIndex,
-  /* xDisconnect   */ fulltextDisconnect,
-  /* xDestroy      */ fulltextDestroy,
-  /* xOpen         */ fulltextOpen,
-  /* xClose        */ fulltextClose,
-  /* xFilter       */ fulltextFilter,
-  /* xNext         */ fulltextNext,
-  /* xEof          */ fulltextEof,
-  /* xColumn       */ fulltextColumn,
-  /* xRowid        */ fulltextRowid,
-  /* xUpdate       */ fulltextUpdate,
-  /* xBegin        */ fulltextBegin,
-  /* xSync         */ fulltextSync,
-  /* xCommit       */ fulltextCommit,
-  /* xRollback     */ fulltextRollback,
-  /* xFindFunction */ fulltextFindFunction,
-  /* xRename */       fulltextRename,
-};
+/* optimize() helper function.  Put the readers in order and iterate
+** through them, merging doclists for matching terms into pWriter.
+** Returns SQLITE_OK on success, or the SQLite error code which
+** prevented success.
+*/
+static int optimizeInternal(fulltext_vtab *v,
+                            OptLeavesReader *readers, int nReaders,
+                            LeafWriter *pWriter){
+  int i, rc = SQLITE_OK;
+  DataBuffer doclist, merged, tmp;
 
-static void hashDestroy(void *p){
-  fts3Hash *pHash = (fts3Hash *)p;
-  sqlite3Fts3HashClear(pHash);
-  sqlite3_free(pHash);
-}
+  /* Order the readers. */
+  i = nReaders;
+  while( i-- > 0 ){
+    optLeavesReaderReorder(&readers[i], nReaders-i);
+  }
 
-/*
-** The fts3 built-in tokenizers - "simple" and "porter" - are implemented
-** in files fts3_tokenizer1.c and fts3_porter.c respectively. The following
-** two forward declarations are for functions declared in these files
-** used to retrieve the respective implementations.
-**
-** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
-** to by the argument to point a the "simple" tokenizer implementation.
-** Function ...PorterTokenizerModule() sets *pModule to point to the
-** porter tokenizer/stemmer implementation.
-*/
-SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
-SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
+  dataBufferInit(&doclist, LEAF_MAX);
+  dataBufferInit(&merged, LEAF_MAX);
 
-SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, fts3Hash *, const char *);
+  /* Exhausted readers bubble to the end, so when the first reader is
+  ** at eof, all are at eof.
+  */
+  while( !optLeavesReaderAtEnd(&readers[0]) ){
 
-/*
-** Initialise the fts3 extension. If this extension is built as part
-** of the sqlite library, then this function is called directly by
-** SQLite. If fts3 is built as a dynamically loadable extension, this
-** function is called by the sqlite3_extension_init() entry point.
-*/
-SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
-  int rc = SQLITE_OK;
-  fts3Hash *pHash = 0;
-  const sqlite3_tokenizer_module *pSimple = 0;
-  const sqlite3_tokenizer_module *pPorter = 0;
-  const sqlite3_tokenizer_module *pIcu = 0;
+    /* Figure out how many readers share the next term. */
+    for(i=1; i<nReaders && !optLeavesReaderAtEnd(&readers[i]); i++){
+      if( 0!=optLeavesReaderTermCmp(&readers[0], &readers[i]) ) break;
+    }
 
-  sqlite3Fts3SimpleTokenizerModule(&pSimple);
-  sqlite3Fts3PorterTokenizerModule(&pPorter);
-#ifdef SQLITE_ENABLE_ICU
-  sqlite3Fts3IcuTokenizerModule(&pIcu);
-#endif
+    /* Special-case for no merge. */
+    if( i==1 ){
+      /* Trim deletions from the doclist. */
+      dataBufferReset(&merged);
+      docListTrim(DL_DEFAULT,
+                  optLeavesReaderData(&readers[0]),
+                  optLeavesReaderDataBytes(&readers[0]),
+                  -1, DL_DEFAULT, &merged);
+    }else{
+      DLReader dlReaders[MERGE_COUNT];
+      int iReader, nReaders;
 
-  /* Allocate and initialise the hash-table used to store tokenizers. */
-  pHash = sqlite3_malloc(sizeof(fts3Hash));
-  if( !pHash ){
+      /* Prime the pipeline with the first reader's doclist.  After
+      ** one pass index 0 will reference the accumulated doclist.
+      */
+      dlrInit(&dlReaders[0], DL_DEFAULT,
+              optLeavesReaderData(&readers[0]),
+              optLeavesReaderDataBytes(&readers[0]));
+      iReader = 1;
+
+      assert( iReader<i );  /* Must execute the loop at least once. */
+      while( iReader<i ){
+        /* Merge 16 inputs per pass. */
+        for( nReaders=1; iReader<i && nReaders<MERGE_COUNT;
+             iReader++, nReaders++ ){
+          dlrInit(&dlReaders[nReaders], DL_DEFAULT,
+                  optLeavesReaderData(&readers[iReader]),
+                  optLeavesReaderDataBytes(&readers[iReader]));
+        }
+
+        /* Merge doclists and swap result into accumulator. */
+        dataBufferReset(&merged);
+        docListMerge(&merged, dlReaders, nReaders);
+        tmp = merged;
+        merged = doclist;
+        doclist = tmp;
+
+        while( nReaders-- > 0 ){
+          dlrDestroy(&dlReaders[nReaders]);
+        }
+
+        /* Accumulated doclist to reader 0 for next pass. */
+        dlrInit(&dlReaders[0], DL_DEFAULT, doclist.pData, doclist.nData);
+      }
+
+      /* Destroy reader that was left in the pipeline. */
+      dlrDestroy(&dlReaders[0]);
+
+      /* Trim deletions from the doclist. */
+      dataBufferReset(&merged);
+      docListTrim(DL_DEFAULT, doclist.pData, doclist.nData,
+                  -1, DL_DEFAULT, &merged);
+    }
+
+    /* Only pass doclists with hits (skip if all hits deleted). */
+    if( merged.nData>0 ){
+      rc = leafWriterStep(v, pWriter,
+                          optLeavesReaderTerm(&readers[0]),
+                          optLeavesReaderTermBytes(&readers[0]),
+                          merged.pData, merged.nData);
+      if( rc!=SQLITE_OK ) goto err;
+    }
+
+    /* Step merged readers to next term and reorder. */
+    while( i-- > 0 ){
+      rc = optLeavesReaderStep(v, &readers[i]);
+      if( rc!=SQLITE_OK ) goto err;
+
+      optLeavesReaderReorder(&readers[i], nReaders-i);
+    }
+  }
+
+ err:
+  dataBufferDestroy(&doclist);
+  dataBufferDestroy(&merged);
+  return rc;
+}
+
+/* Implement optimize() function for FTS3.  optimize(t) merges all
+** segments in the fts index into a single segment.  't' is the magic
+** table-named column.
+*/
+static void optimizeFunc(sqlite3_context *pContext,
+                         int argc, sqlite3_value **argv){
+  fulltext_cursor *pCursor;
+  if( argc>1 ){
+    sqlite3_result_error(pContext, "excess arguments to optimize()",-1);
+  }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
+            sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
+    sqlite3_result_error(pContext, "illegal first argument to optimize",-1);
+  }else{
+    fulltext_vtab *v;
+    int i, rc, iMaxLevel;
+    OptLeavesReader *readers;
+    int nReaders;
+    LeafWriter writer;
+    sqlite3_stmt *s;
+
+    memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
+    v = cursor_vtab(pCursor);
+
+    /* Flush any buffered updates before optimizing. */
+    rc = flushPendingTerms(v);
+    if( rc!=SQLITE_OK ) goto err;
+
+    rc = segdir_count(v, &nReaders, &iMaxLevel);
+    if( rc!=SQLITE_OK ) goto err;
+    if( nReaders==0 || nReaders==1 ){
+      sqlite3_result_text(pContext, "Index already optimal", -1,
+                          SQLITE_STATIC);
+      return;
+    }
+
+    rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
+    if( rc!=SQLITE_OK ) goto err;
+
+    readers = sqlite3_malloc(nReaders*sizeof(readers[0]));
+    if( readers==NULL ) goto err;
+
+    /* Note that there will already be a segment at this position
+    ** until we call segdir_delete() on iMaxLevel.
+    */
+    leafWriterInit(iMaxLevel, 0, &writer);
+
+    i = 0;
+    while( (rc = sqlite3_step(s))==SQLITE_ROW ){
+      sqlite_int64 iStart = sqlite3_column_int64(s, 0);
+      sqlite_int64 iEnd = sqlite3_column_int64(s, 1);
+      const char *pRootData = sqlite3_column_blob(s, 2);
+      int nRootData = sqlite3_column_bytes(s, 2);
+
+      assert( i<nReaders );
+      rc = leavesReaderInit(v, -1, iStart, iEnd, pRootData, nRootData,
+                            &readers[i].reader);
+      if( rc!=SQLITE_OK ) break;
+
+      readers[i].segment = i;
+      i++;
+    }
+
+    /* If we managed to succesfully read them all, optimize them. */
+    if( rc==SQLITE_DONE ){
+      assert( i==nReaders );
+      rc = optimizeInternal(v, readers, nReaders, &writer);
+    }
+
+    while( i-- > 0 ){
+      leavesReaderDestroy(&readers[i].reader);
+    }
+    sqlite3_free(readers);
+
+    /* If we've successfully gotten to here, delete the old segments
+    ** and flush the interior structure of the new segment.
+    */
+    if( rc==SQLITE_OK ){
+      for( i=0; i<=iMaxLevel; i++ ){
+        rc = segdir_delete(v, i);
+        if( rc!=SQLITE_OK ) break;
+      }
+
+      if( rc==SQLITE_OK ) rc = leafWriterFinalize(v, &writer);
+    }
+
+    leafWriterDestroy(&writer);
+
+    if( rc!=SQLITE_OK ) goto err;
+
+    sqlite3_result_text(pContext, "Index optimized", -1, SQLITE_STATIC);
+    return;
+
+    /* TODO(shess): Error-handling needs to be improved along the
+    ** lines of the dump_ functions.
+    */
+ err:
+    {
+      char buf[512];
+      sqlite3_snprintf(sizeof(buf), buf, "Error in optimize: %s",
+                       sqlite3_errmsg(sqlite3_context_db_handle(pContext)));
+      sqlite3_result_error(pContext, buf, -1);
+    }
+  }
+}
+
+#ifdef SQLITE_TEST
+/* Generate an error of the form "<prefix>: <msg>".  If msg is NULL,
+** pull the error from the context's db handle.
+*/
+static void generateError(sqlite3_context *pContext,
+                          const char *prefix, const char *msg){
+  char buf[512];
+  if( msg==NULL ) msg = sqlite3_errmsg(sqlite3_context_db_handle(pContext));
+  sqlite3_snprintf(sizeof(buf), buf, "%s: %s", prefix, msg);
+  sqlite3_result_error(pContext, buf, -1);
+}
+
+/* Helper function to collect the set of terms in the segment into
+** pTerms.  The segment is defined by the leaf nodes between
+** iStartBlockid and iEndBlockid, inclusive, or by the contents of
+** pRootData if iStartBlockid is 0 (in which case the entire segment
+** fit in a leaf).
+*/
+static int collectSegmentTerms(fulltext_vtab *v, sqlite3_stmt *s,
+                               fts3Hash *pTerms){
+  const sqlite_int64 iStartBlockid = sqlite3_column_int64(s, 0);
+  const sqlite_int64 iEndBlockid = sqlite3_column_int64(s, 1);
+  const char *pRootData = sqlite3_column_blob(s, 2);
+  const int nRootData = sqlite3_column_bytes(s, 2);
+  LeavesReader reader;
+  int rc = leavesReaderInit(v, 0, iStartBlockid, iEndBlockid,
+                            pRootData, nRootData, &reader);
+  if( rc!=SQLITE_OK ) return rc;
+
+  while( rc==SQLITE_OK && !leavesReaderAtEnd(&reader) ){
+    const char *pTerm = leavesReaderTerm(&reader);
+    const int nTerm = leavesReaderTermBytes(&reader);
+    void *oldValue = sqlite3Fts3HashFind(pTerms, pTerm, nTerm);
+    void *newValue = (void *)((char *)oldValue+1);
+
+    /* From the comment before sqlite3Fts3HashInsert in fts3_hash.c,
+    ** the data value passed is returned in case of malloc failure.
+    */
+    if( newValue==sqlite3Fts3HashInsert(pTerms, pTerm, nTerm, newValue) ){
+      rc = SQLITE_NOMEM;
+    }else{
+      rc = leavesReaderStep(v, &reader);
+    }
+  }
+
+  leavesReaderDestroy(&reader);
+  return rc;
+}
+
+/* Helper function to build the result string for dump_terms(). */
+static int generateTermsResult(sqlite3_context *pContext, fts3Hash *pTerms){
+  int iTerm, nTerms, nResultBytes, iByte;
+  char *result;
+  TermData *pData;
+  fts3HashElem *e;
+
+  /* Iterate pTerms to generate an array of terms in pData for
+  ** sorting.
+  */
+  nTerms = fts3HashCount(pTerms);
+  assert( nTerms>0 );
+  pData = sqlite3_malloc(nTerms*sizeof(TermData));
+  if( pData==NULL ) return SQLITE_NOMEM;
+
+  nResultBytes = 0;
+  for(iTerm = 0, e = fts3HashFirst(pTerms); e; iTerm++, e = fts3HashNext(e)){
+    nResultBytes += fts3HashKeysize(e)+1;   /* Term plus trailing space */
+    assert( iTerm<nTerms );
+    pData[iTerm].pTerm = fts3HashKey(e);
+    pData[iTerm].nTerm = fts3HashKeysize(e);
+    pData[iTerm].pCollector = fts3HashData(e);  /* unused */
+  }
+  assert( iTerm==nTerms );
+
+  assert( nResultBytes>0 );   /* nTerms>0, nResultsBytes must be, too. */
+  result = sqlite3_malloc(nResultBytes);
+  if( result==NULL ){
+    sqlite3_free(pData);
+    return SQLITE_NOMEM;
+  }
+
+  if( nTerms>1 ) qsort(pData, nTerms, sizeof(*pData), termDataCmp);
+
+  /* Read the terms in order to build the result. */
+  iByte = 0;
+  for(iTerm=0; iTerm<nTerms; ++iTerm){
+    memcpy(result+iByte, pData[iTerm].pTerm, pData[iTerm].nTerm);
+    iByte += pData[iTerm].nTerm;
+    result[iByte++] = ' ';
+  }
+  assert( iByte==nResultBytes );
+  assert( result[nResultBytes-1]==' ' );
+  result[nResultBytes-1] = '\0';
+
+  /* Passes away ownership of result. */
+  sqlite3_result_text(pContext, result, nResultBytes-1, sqlite3_free);
+  sqlite3_free(pData);
+  return SQLITE_OK;
+}
+
+/* Implements dump_terms() for use in inspecting the fts3 index from
+** tests.  TEXT result containing the ordered list of terms joined by
+** spaces.  dump_terms(t, level, idx) dumps the terms for the segment
+** specified by level, idx (in %_segdir), while dump_terms(t) dumps
+** all terms in the index.  In both cases t is the fts table's magic
+** table-named column.
+*/
+static void dumpTermsFunc(
+  sqlite3_context *pContext,
+  int argc, sqlite3_value **argv
+){
+  fulltext_cursor *pCursor;
+  if( argc!=3 && argc!=1 ){
+    generateError(pContext, "dump_terms", "incorrect arguments");
+  }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
+            sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
+    generateError(pContext, "dump_terms", "illegal first argument");
+  }else{
+    fulltext_vtab *v;
+    fts3Hash terms;
+    sqlite3_stmt *s = NULL;
+    int rc;
+
+    memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
+    v = cursor_vtab(pCursor);
+
+    /* If passed only the cursor column, get all segments.  Otherwise
+    ** get the segment described by the following two arguments.
+    */
+    if( argc==1 ){
+      rc = sql_get_statement(v, SEGDIR_SELECT_ALL_STMT, &s);
+    }else{
+      rc = sql_get_statement(v, SEGDIR_SELECT_SEGMENT_STMT, &s);
+      if( rc==SQLITE_OK ){
+        rc = sqlite3_bind_int(s, 1, sqlite3_value_int(argv[1]));
+        if( rc==SQLITE_OK ){
+          rc = sqlite3_bind_int(s, 2, sqlite3_value_int(argv[2]));
+        }
+      }
+    }
+
+    if( rc!=SQLITE_OK ){
+      generateError(pContext, "dump_terms", NULL);
+      return;
+    }
+
+    /* Collect the terms for each segment. */
+    sqlite3Fts3HashInit(&terms, FTS3_HASH_STRING, 1);
+    while( (rc = sqlite3_step(s))==SQLITE_ROW ){
+      rc = collectSegmentTerms(v, s, &terms);
+      if( rc!=SQLITE_OK ) break;
+    }
+
+    if( rc!=SQLITE_DONE ){
+      sqlite3_reset(s);
+      generateError(pContext, "dump_terms", NULL);
+    }else{
+      const int nTerms = fts3HashCount(&terms);
+      if( nTerms>0 ){
+        rc = generateTermsResult(pContext, &terms);
+        if( rc==SQLITE_NOMEM ){
+          generateError(pContext, "dump_terms", "out of memory");
+        }else{
+          assert( rc==SQLITE_OK );
+        }
+      }else if( argc==3 ){
+        /* The specific segment asked for could not be found. */
+        generateError(pContext, "dump_terms", "segment not found");
+      }else{
+        /* No segments found. */
+        /* TODO(shess): It should be impossible to reach this.  This
+        ** case can only happen for an empty table, in which case
+        ** SQLite has no rows to call this function on.
+        */
+        sqlite3_result_null(pContext);
+      }
+    }
+    sqlite3Fts3HashClear(&terms);
+  }
+}
+
+/* Expand the DL_DEFAULT doclist in pData into a text result in
+** pContext.
+*/
+static void createDoclistResult(sqlite3_context *pContext,
+                                const char *pData, int nData){
+  DataBuffer dump;
+  DLReader dlReader;
+
+  assert( pData!=NULL && nData>0 );
+
+  dataBufferInit(&dump, 0);
+  dlrInit(&dlReader, DL_DEFAULT, pData, nData);
+  for( ; !dlrAtEnd(&dlReader); dlrStep(&dlReader) ){
+    char buf[256];
+    PLReader plReader;
+
+    plrInit(&plReader, &dlReader);
+    if( DL_DEFAULT==DL_DOCIDS || plrAtEnd(&plReader) ){
+      sqlite3_snprintf(sizeof(buf), buf, "[%lld] ", dlrDocid(&dlReader));
+      dataBufferAppend(&dump, buf, strlen(buf));
+    }else{
+      int iColumn = plrColumn(&plReader);
+
+      sqlite3_snprintf(sizeof(buf), buf, "[%lld %d[",
+                       dlrDocid(&dlReader), iColumn);
+      dataBufferAppend(&dump, buf, strlen(buf));
+
+      for( ; !plrAtEnd(&plReader); plrStep(&plReader) ){
+        if( plrColumn(&plReader)!=iColumn ){
+          iColumn = plrColumn(&plReader);
+          sqlite3_snprintf(sizeof(buf), buf, "] %d[", iColumn);
+          assert( dump.nData>0 );
+          dump.nData--;                     /* Overwrite trailing space. */
+          assert( dump.pData[dump.nData]==' ');
+          dataBufferAppend(&dump, buf, strlen(buf));
+        }
+        if( DL_DEFAULT==DL_POSITIONS_OFFSETS ){
+          sqlite3_snprintf(sizeof(buf), buf, "%d,%d,%d ",
+                           plrPosition(&plReader),
+                           plrStartOffset(&plReader), plrEndOffset(&plReader));
+        }else if( DL_DEFAULT==DL_POSITIONS ){
+          sqlite3_snprintf(sizeof(buf), buf, "%d ", plrPosition(&plReader));
+        }else{
+          assert( NULL=="Unhandled DL_DEFAULT value");
+        }
+        dataBufferAppend(&dump, buf, strlen(buf));
+      }
+      plrDestroy(&plReader);
+
+      assert( dump.nData>0 );
+      dump.nData--;                     /* Overwrite trailing space. */
+      assert( dump.pData[dump.nData]==' ');
+      dataBufferAppend(&dump, "]] ", 3);
+    }
+  }
+  dlrDestroy(&dlReader);
+
+  assert( dump.nData>0 );
+  dump.nData--;                     /* Overwrite trailing space. */
+  assert( dump.pData[dump.nData]==' ');
+  dump.pData[dump.nData] = '\0';
+  assert( dump.nData>0 );
+
+  /* Passes ownership of dump's buffer to pContext. */
+  sqlite3_result_text(pContext, dump.pData, dump.nData, sqlite3_free);
+  dump.pData = NULL;
+  dump.nData = dump.nCapacity = 0;
+}
+
+/* Implements dump_doclist() for use in inspecting the fts3 index from
+** tests.  TEXT result containing a string representation of the
+** doclist for the indicated term.  dump_doclist(t, term, level, idx)
+** dumps the doclist for term from the segment specified by level, idx
+** (in %_segdir), while dump_doclist(t, term) dumps the logical
+** doclist for the term across all segments.  The per-segment doclist
+** can contain deletions, while the full-index doclist will not
+** (deletions are omitted).
+**
+** Result formats differ with the setting of DL_DEFAULTS.  Examples:
+**
+** DL_DOCIDS: [1] [3] [7]
+** DL_POSITIONS: [1 0[0 4] 1[17]] [3 1[5]]
+** DL_POSITIONS_OFFSETS: [1 0[0,0,3 4,23,26] 1[17,102,105]] [3 1[5,20,23]]
+**
+** In each case the number after the outer '[' is the docid.  In the
+** latter two cases, the number before the inner '[' is the column
+** associated with the values within.  For DL_POSITIONS the numbers
+** within are the positions, for DL_POSITIONS_OFFSETS they are the
+** position, the start offset, and the end offset.
+*/
+static void dumpDoclistFunc(
+  sqlite3_context *pContext,
+  int argc, sqlite3_value **argv
+){
+  fulltext_cursor *pCursor;
+  if( argc!=2 && argc!=4 ){
+    generateError(pContext, "dump_doclist", "incorrect arguments");
+  }else if( sqlite3_value_type(argv[0])!=SQLITE_BLOB ||
+            sqlite3_value_bytes(argv[0])!=sizeof(pCursor) ){
+    generateError(pContext, "dump_doclist", "illegal first argument");
+  }else if( sqlite3_value_text(argv[1])==NULL ||
+            sqlite3_value_text(argv[1])[0]=='\0' ){
+    generateError(pContext, "dump_doclist", "empty second argument");
+  }else{
+    const char *pTerm = (const char *)sqlite3_value_text(argv[1]);
+    const int nTerm = strlen(pTerm);
+    fulltext_vtab *v;
+    int rc;
+    DataBuffer doclist;
+
+    memcpy(&pCursor, sqlite3_value_blob(argv[0]), sizeof(pCursor));
+    v = cursor_vtab(pCursor);
+
+    dataBufferInit(&doclist, 0);
+
+    /* termSelect() yields the same logical doclist that queries are
+    ** run against.
+    */
+    if( argc==2 ){
+      rc = termSelect(v, v->nColumn, pTerm, nTerm, 0, DL_DEFAULT, &doclist);
+    }else{
+      sqlite3_stmt *s = NULL;
+
+      /* Get our specific segment's information. */
+      rc = sql_get_statement(v, SEGDIR_SELECT_SEGMENT_STMT, &s);
+      if( rc==SQLITE_OK ){
+        rc = sqlite3_bind_int(s, 1, sqlite3_value_int(argv[2]));
+        if( rc==SQLITE_OK ){
+          rc = sqlite3_bind_int(s, 2, sqlite3_value_int(argv[3]));
+        }
+      }
+
+      if( rc==SQLITE_OK ){
+        rc = sqlite3_step(s);
+
+        if( rc==SQLITE_DONE ){
+          dataBufferDestroy(&doclist);
+          generateError(pContext, "dump_doclist", "segment not found");
+          return;
+        }
+
+        /* Found a segment, load it into doclist. */
+        if( rc==SQLITE_ROW ){
+          const sqlite_int64 iLeavesEnd = sqlite3_column_int64(s, 1);
+          const char *pData = sqlite3_column_blob(s, 2);
+          const int nData = sqlite3_column_bytes(s, 2);
+
+          /* loadSegment() is used by termSelect() to load each
+          ** segment's data.
+          */
+          rc = loadSegment(v, pData, nData, iLeavesEnd, pTerm, nTerm, 0,
+                           &doclist);
+          if( rc==SQLITE_OK ){
+            rc = sqlite3_step(s);
+
+            /* Should not have more than one matching segment. */
+            if( rc!=SQLITE_DONE ){
+              sqlite3_reset(s);
+              dataBufferDestroy(&doclist);
+              generateError(pContext, "dump_doclist", "invalid segdir");
+              return;
+            }
+            rc = SQLITE_OK;
+          }
+        }
+      }
+
+      sqlite3_reset(s);
+    }
+
+    if( rc==SQLITE_OK ){
+      if( doclist.nData>0 ){
+        createDoclistResult(pContext, doclist.pData, doclist.nData);
+      }else{
+        /* TODO(shess): This can happen if the term is not present, or
+        ** if all instances of the term have been deleted and this is
+        ** an all-index dump.  It may be interesting to distinguish
+        ** these cases.
+        */
+        sqlite3_result_text(pContext, "", 0, SQLITE_STATIC);
+      }
+    }else if( rc==SQLITE_NOMEM ){
+      /* Handle out-of-memory cases specially because if they are
+      ** generated in fts3 code they may not be reflected in the db
+      ** handle.
+      */
+      /* TODO(shess): Handle this more comprehensively.
+      ** sqlite3ErrStr() has what I need, but is internal.
+      */
+      generateError(pContext, "dump_doclist", "out of memory");
+    }else{
+      generateError(pContext, "dump_doclist", NULL);
+    }
+
+    dataBufferDestroy(&doclist);
+  }
+}
+#endif
+
+/*
+** This routine implements the xFindFunction method for the FTS3
+** virtual table.
+*/
+static int fulltextFindFunction(
+  sqlite3_vtab *pVtab,
+  int nArg,
+  const char *zName,
+  void (**pxFunc)(sqlite3_context*,int,sqlite3_value**),
+  void **ppArg
+){
+  if( strcmp(zName,"snippet")==0 ){
+    *pxFunc = snippetFunc;
+    return 1;
+  }else if( strcmp(zName,"offsets")==0 ){
+    *pxFunc = snippetOffsetsFunc;
+    return 1;
+  }else if( strcmp(zName,"optimize")==0 ){
+    *pxFunc = optimizeFunc;
+    return 1;
+#ifdef SQLITE_TEST
+    /* NOTE(shess): These functions are present only for testing
+    ** purposes.  No particular effort is made to optimize their
+    ** execution or how they build their results.
+    */
+  }else if( strcmp(zName,"dump_terms")==0 ){
+    /* fprintf(stderr, "Found dump_terms\n"); */
+    *pxFunc = dumpTermsFunc;
+    return 1;
+  }else if( strcmp(zName,"dump_doclist")==0 ){
+    /* fprintf(stderr, "Found dump_doclist\n"); */
+    *pxFunc = dumpDoclistFunc;
+    return 1;
+#endif
+  }
+  return 0;
+}
+
+/*
+** Rename an fts3 table.
+*/
+static int fulltextRename(
+  sqlite3_vtab *pVtab,
+  const char *zName
+){
+  fulltext_vtab *p = (fulltext_vtab *)pVtab;
+  int rc = SQLITE_NOMEM;
+  char *zSql = sqlite3_mprintf(
+    "ALTER TABLE %Q.'%q_content'  RENAME TO '%q_content';"
+    "ALTER TABLE %Q.'%q_segments' RENAME TO '%q_segments';"
+    "ALTER TABLE %Q.'%q_segdir'   RENAME TO '%q_segdir';"
+    , p->zDb, p->zName, zName 
+    , p->zDb, p->zName, zName 
+    , p->zDb, p->zName, zName
+  );
+  if( zSql ){
+    rc = sqlite3_exec(p->db, zSql, 0, 0, 0);
+    sqlite3_free(zSql);
+  }
+  return rc;
+}
+
+static const sqlite3_module fts3Module = {
+  /* iVersion      */ 0,
+  /* xCreate       */ fulltextCreate,
+  /* xConnect      */ fulltextConnect,
+  /* xBestIndex    */ fulltextBestIndex,
+  /* xDisconnect   */ fulltextDisconnect,
+  /* xDestroy      */ fulltextDestroy,
+  /* xOpen         */ fulltextOpen,
+  /* xClose        */ fulltextClose,
+  /* xFilter       */ fulltextFilter,
+  /* xNext         */ fulltextNext,
+  /* xEof          */ fulltextEof,
+  /* xColumn       */ fulltextColumn,
+  /* xRowid        */ fulltextRowid,
+  /* xUpdate       */ fulltextUpdate,
+  /* xBegin        */ fulltextBegin,
+  /* xSync         */ fulltextSync,
+  /* xCommit       */ fulltextCommit,
+  /* xRollback     */ fulltextRollback,
+  /* xFindFunction */ fulltextFindFunction,
+  /* xRename */       fulltextRename,
+};
+
+static void hashDestroy(void *p){
+  fts3Hash *pHash = (fts3Hash *)p;
+  sqlite3Fts3HashClear(pHash);
+  sqlite3_free(pHash);
+}
+
+/*
+** The fts3 built-in tokenizers - "simple" and "porter" - are implemented
+** in files fts3_tokenizer1.c and fts3_porter.c respectively. The following
+** two forward declarations are for functions declared in these files
+** used to retrieve the respective implementations.
+**
+** Calling sqlite3Fts3SimpleTokenizerModule() sets the value pointed
+** to by the argument to point a the "simple" tokenizer implementation.
+** Function ...PorterTokenizerModule() sets *pModule to point to the
+** porter tokenizer/stemmer implementation.
+*/
+SQLITE_PRIVATE void sqlite3Fts3SimpleTokenizerModule(sqlite3_tokenizer_module const**ppModule);
+SQLITE_PRIVATE void sqlite3Fts3PorterTokenizerModule(sqlite3_tokenizer_module const**ppModule);
+SQLITE_PRIVATE void sqlite3Fts3IcuTokenizerModule(sqlite3_tokenizer_module const**ppModule);
+
+SQLITE_PRIVATE int sqlite3Fts3InitHashTable(sqlite3 *, fts3Hash *, const char *);
+
+/*
+** Initialise the fts3 extension. If this extension is built as part
+** of the sqlite library, then this function is called directly by
+** SQLite. If fts3 is built as a dynamically loadable extension, this
+** function is called by the sqlite3_extension_init() entry point.
+*/
+SQLITE_PRIVATE int sqlite3Fts3Init(sqlite3 *db){
+  int rc = SQLITE_OK;
+  fts3Hash *pHash = 0;
+  const sqlite3_tokenizer_module *pSimple = 0;
+  const sqlite3_tokenizer_module *pPorter = 0;
+  const sqlite3_tokenizer_module *pIcu = 0;
+
+  sqlite3Fts3SimpleTokenizerModule(&pSimple);
+  sqlite3Fts3PorterTokenizerModule(&pPorter);
+#ifdef SQLITE_ENABLE_ICU
+  sqlite3Fts3IcuTokenizerModule(&pIcu);
+#endif
+
+  /* Allocate and initialise the hash-table used to store tokenizers. */
+  pHash = sqlite3_malloc(sizeof(fts3Hash));
+  if( !pHash ){
     rc = SQLITE_NOMEM;
   }else{
     sqlite3Fts3HashInit(pHash, FTS3_HASH_STRING, 1);
@@ -85399,6 +89044,11 @@
    && SQLITE_OK==(rc = sqlite3Fts3InitHashTable(db, pHash, "fts3_tokenizer"))
    && SQLITE_OK==(rc = sqlite3_overload_function(db, "snippet", -1))
    && SQLITE_OK==(rc = sqlite3_overload_function(db, "offsets", -1))
+   && SQLITE_OK==(rc = sqlite3_overload_function(db, "optimize", -1))
+#ifdef SQLITE_TEST
+   && SQLITE_OK==(rc = sqlite3_overload_function(db, "dump_terms", -1))
+   && SQLITE_OK==(rc = sqlite3_overload_function(db, "dump_doclist", -1))
+#endif
   ){
     return sqlite3_create_module_v2(
         db, "fts3", &fts3Module, (void *)pHash, hashDestroy
@@ -87034,3 +90684,2830 @@
 #endif /* !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_FTS3) */
 
 /************** End of fts3_tokenizer1.c *************************************/
+/************** Begin file rtree.c *******************************************/
+/*
+** 2001 September 15
+**
+** The author disclaims copyright to this source code.  In place of
+** a legal notice, here is a blessing:
+**
+**    May you do good and not evil.
+**    May you find forgiveness for yourself and forgive others.
+**    May you share freely, never taking more than you give.
+**
+*************************************************************************
+** This file contains code for implementations of the r-tree and r*-tree
+** algorithms packaged as an SQLite virtual table module.
+**
+** $Id: rtree.c,v 1.7 2008/07/16 14:43:35 drh Exp $
+*/
+
+#if !defined(SQLITE_CORE) || defined(SQLITE_ENABLE_RTREE)
+
+/*
+** This file contains an implementation of a couple of different variants
+** of the r-tree algorithm. See the README file for further details. The 
+** same data-structure is used for all, but the algorithms for insert and
+** delete operations vary. The variants used are selected at compile time 
+** by defining the following symbols:
+*/
+
+/* Either, both or none of the following may be set to activate 
+** r*tree variant algorithms.
+*/
+#define VARIANT_RSTARTREE_CHOOSESUBTREE 0
+#define VARIANT_RSTARTREE_REINSERT      1
+
+/* 
+** Exactly one of the following must be set to 1.
+*/
+#define VARIANT_GUTTMAN_QUADRATIC_SPLIT 0
+#define VARIANT_GUTTMAN_LINEAR_SPLIT    0
+#define VARIANT_RSTARTREE_SPLIT         1
+
+#define VARIANT_GUTTMAN_SPLIT \
+        (VARIANT_GUTTMAN_LINEAR_SPLIT||VARIANT_GUTTMAN_QUADRATIC_SPLIT)
+
+#if VARIANT_GUTTMAN_QUADRATIC_SPLIT
+  #define PickNext QuadraticPickNext
+  #define PickSeeds QuadraticPickSeeds
+  #define AssignCells splitNodeGuttman
+#endif
+#if VARIANT_GUTTMAN_LINEAR_SPLIT
+  #define PickNext LinearPickNext
+  #define PickSeeds LinearPickSeeds
+  #define AssignCells splitNodeGuttman
+#endif
+#if VARIANT_RSTARTREE_SPLIT
+  #define AssignCells splitNodeStartree
+#endif
+
+
+#ifndef SQLITE_CORE
+  #include "sqlite3ext.h"
+  SQLITE_EXTENSION_INIT1
+#else
+  #include "sqlite3.h"
+#endif
+
+
+#ifndef SQLITE_AMALGAMATION
+typedef sqlite3_int64 i64;
+typedef unsigned char u8;
+typedef unsigned int u32;
+#endif
+
+typedef struct Rtree Rtree;
+typedef struct RtreeCursor RtreeCursor;
+typedef struct RtreeNode RtreeNode;
+typedef struct RtreeCell RtreeCell;
+typedef struct RtreeConstraint RtreeConstraint;
+typedef union RtreeCoord RtreeCoord;
+
+/* The rtree may have between 1 and RTREE_MAX_DIMENSIONS dimensions. */
+#define RTREE_MAX_DIMENSIONS 5
+
+/* Size of hash table Rtree.aHash. This hash table is not expected to
+** ever contain very many entries, so a fixed number of buckets is 
+** used.
+*/
+#define HASHSIZE 128
+
+/* 
+** An rtree virtual-table object.
+*/
+struct Rtree {
+  sqlite3_vtab base;
+  sqlite3 *db;                /* Host database connection */
+  int iNodeSize;              /* Size in bytes of each node in the node table */
+  int nDim;                   /* Number of dimensions */
+  int nBytesPerCell;          /* Bytes consumed per cell */
+  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 */ 
+  RtreeNode *aHash[HASHSIZE]; /* Hash table of in-memory nodes. */ 
+  int nBusy;                  /* Current number of users of this structure */
+
+  /* List of nodes removed during a CondenseTree operation. List is
+  ** linked together via the pointer normally used for hash chains -
+  ** RtreeNode.pNext. RtreeNode.iNode stores the depth of the sub-tree 
+  ** headed by the node (leaf nodes have RtreeNode.iNode==0).
+  */
+  RtreeNode *pDeleted;
+  int iReinsertHeight;        /* Height of sub-trees Reinsert() has run on */
+
+  /* Statements to read/write/delete a record from xxx_node */
+  sqlite3_stmt *pReadNode;
+  sqlite3_stmt *pWriteNode;
+  sqlite3_stmt *pDeleteNode;
+
+  /* Statements to read/write/delete a record from xxx_rowid */
+  sqlite3_stmt *pReadRowid;
+  sqlite3_stmt *pWriteRowid;
+  sqlite3_stmt *pDeleteRowid;
+
+  /* Statements to read/write/delete a record from xxx_parent */
+  sqlite3_stmt *pReadParent;
+  sqlite3_stmt *pWriteParent;
+  sqlite3_stmt *pDeleteParent;
+
+  int eCoordType;
+};
+
+/* Possible values for eCoordType: */
+#define RTREE_COORD_REAL32 0
+#define RTREE_COORD_INT32  1
+
+/*
+** The minimum number of cells allowed for a node is a third of the 
+** maximum. In Gutman's notation:
+**
+**     m = M/3
+**
+** If an R*-tree "Reinsert" operation is required, the same number of
+** cells are removed from the overfull node and reinserted into the tree.
+*/
+#define RTREE_MINCELLS(p) ((((p)->iNodeSize-4)/(p)->nBytesPerCell)/3)
+#define RTREE_REINSERT(p) RTREE_MINCELLS(p)
+#define RTREE_MAXCELLS 51
+
+/* 
+** An rtree cursor object.
+*/
+struct RtreeCursor {
+  sqlite3_vtab_cursor base;
+  RtreeNode *pNode;                 /* Node cursor is currently pointing at */
+  int iCell;                        /* Index of current cell in pNode */
+  int iStrategy;                    /* Copy of idxNum search parameter */
+  int nConstraint;                  /* Number of entries in aConstraint */
+  RtreeConstraint *aConstraint;     /* Search constraints. */
+};
+
+union RtreeCoord {
+  float f;
+  int i;
+};
+
+/*
+** The argument is an RtreeCoord. Return the value stored within the RtreeCoord
+** formatted as a double. This macro assumes that local variable pRtree points
+** to the Rtree structure associated with the RtreeCoord.
+*/
+#define DCOORD(coord) (                           \
+  (pRtree->eCoordType==RTREE_COORD_REAL32) ?      \
+    ((double)coord.f) :                           \
+    ((double)coord.i)                             \
+)
+
+/*
+** A search constraint.
+*/
+struct RtreeConstraint {
+  int iCoord;                       /* Index of constrained coordinate */
+  int op;                           /* Constraining operation */
+  double rValue;                    /* Constraint value. */
+};
+
+/* Possible values for RtreeConstraint.op */
+#define RTREE_EQ 0x41
+#define RTREE_LE 0x42
+#define RTREE_LT 0x43
+#define RTREE_GE 0x44
+#define RTREE_GT 0x45
+
+/* 
+** An rtree structure node.
+**
+** Data format (RtreeNode.zData):
+**
+**   1. If the node is the root node (node 1), then the first 2 bytes
+**      of the node contain the tree depth as a big-endian integer.
+**      For non-root nodes, the first 2 bytes are left unused.
+**
+**   2. The next 2 bytes contain the number of entries currently 
+**      stored in the node.
+**
+**   3. The remainder of the node contains the node entries. Each entry
+**      consists of a single 8-byte integer followed by an even number
+**      of 4-byte coordinates. For leaf nodes the integer is the rowid
+**      of a record. For internal nodes it is the node number of a
+**      child page.
+*/
+struct RtreeNode {
+  RtreeNode *pParent;               /* Parent node */
+  i64 iNode;
+  int nRef;
+  int isDirty;
+  u8 *zData;
+  RtreeNode *pNext;                 /* Next node in this hash chain */
+};
+#define NCELL(pNode) readInt16(&(pNode)->zData[2])
+
+/* 
+** Structure to store a deserialized rtree record.
+*/
+struct RtreeCell {
+  i64 iRowid;
+  RtreeCoord aCoord[RTREE_MAX_DIMENSIONS*2];
+};
+
+#define MAX(x,y) ((x) < (y) ? (y) : (x))
+#define MIN(x,y) ((x) > (y) ? (y) : (x))
+
+/*
+** Functions to deserialize a 16 bit integer, 32 bit real number and
+** 64 bit integer. The deserialized value is returned.
+*/
+static int readInt16(u8 *p){
+  return (p[0]<<8) + p[1];
+}
+static void readCoord(u8 *p, RtreeCoord *pCoord){
+  u32 i = (
+    (((u32)p[0]) << 24) + 
+    (((u32)p[1]) << 16) + 
+    (((u32)p[2]) <<  8) + 
+    (((u32)p[3]) <<  0)
+  );
+  *(u32 *)pCoord = i;
+}
+static i64 readInt64(u8 *p){
+  return (
+    (((i64)p[0]) << 56) + 
+    (((i64)p[1]) << 48) + 
+    (((i64)p[2]) << 40) + 
+    (((i64)p[3]) << 32) + 
+    (((i64)p[4]) << 24) + 
+    (((i64)p[5]) << 16) + 
+    (((i64)p[6]) <<  8) + 
+    (((i64)p[7]) <<  0)
+  );
+}
+
+/*
+** Functions to serialize a 16 bit integer, 32 bit real number and
+** 64 bit integer. The value returned is the number of bytes written
+** to the argument buffer (always 2, 4 and 8 respectively).
+*/
+static int writeInt16(u8 *p, int i){
+  p[0] = (i>> 8)&0xFF;
+  p[1] = (i>> 0)&0xFF;
+  return 2;
+}
+static int writeCoord(u8 *p, RtreeCoord *pCoord){
+  u32 i;
+  assert( sizeof(RtreeCoord)==4 );
+  assert( sizeof(u32)==4 );
+  i = *(u32 *)pCoord;
+  p[0] = (i>>24)&0xFF;
+  p[1] = (i>>16)&0xFF;
+  p[2] = (i>> 8)&0xFF;
+  p[3] = (i>> 0)&0xFF;
+  return 4;
+}
+static int writeInt64(u8 *p, i64 i){
+  p[0] = (i>>56)&0xFF;
+  p[1] = (i>>48)&0xFF;
+  p[2] = (i>>40)&0xFF;
+  p[3] = (i>>32)&0xFF;
+  p[4] = (i>>24)&0xFF;
+  p[5] = (i>>16)&0xFF;
+  p[6] = (i>> 8)&0xFF;
+  p[7] = (i>> 0)&0xFF;
+  return 8;
+}
+
+/*
+** Increment the reference count of node p.
+*/
+static void nodeReference(RtreeNode *p){
+  if( p ){
+    p->nRef++;
+  }
+}
+
+/*
+** Clear the content of node p (set all bytes to 0x00).
+*/
+static void nodeZero(Rtree *pRtree, RtreeNode *p){
+  if( p ){
+    memset(&p->zData[2], 0, pRtree->iNodeSize-2);
+    p->isDirty = 1;
+  }
+}
+
+/*
+** Given a node number iNode, return the corresponding key to use
+** in the Rtree.aHash table.
+*/
+static int nodeHash(i64 iNode){
+  return (
+    (iNode>>56) ^ (iNode>>48) ^ (iNode>>40) ^ (iNode>>32) ^ 
+    (iNode>>24) ^ (iNode>>16) ^ (iNode>> 8) ^ (iNode>> 0)
+  ) % HASHSIZE;
+}
+
+/*
+** Search the node hash table for node iNode. If found, return a pointer
+** to it. Otherwise, return 0.
+*/
+static RtreeNode *nodeHashLookup(Rtree *pRtree, i64 iNode){
+  RtreeNode *p;
+  assert( iNode!=0 );
+  for(p=pRtree->aHash[nodeHash(iNode)]; p && p->iNode!=iNode; p=p->pNext);
+  return p;
+}
+
+/*
+** Add node pNode to the node hash table.
+*/
+static void nodeHashInsert(Rtree *pRtree, RtreeNode *pNode){
+  if( pNode ){
+    int iHash;
+    assert( pNode->pNext==0 );
+    iHash = nodeHash(pNode->iNode);
+    pNode->pNext = pRtree->aHash[iHash];
+    pRtree->aHash[iHash] = pNode;
+  }
+}
+
+/*
+** Remove node pNode from the node hash table.
+*/
+static void nodeHashDelete(Rtree *pRtree, RtreeNode *pNode){
+  RtreeNode **pp;
+  if( pNode->iNode!=0 ){
+    pp = &pRtree->aHash[nodeHash(pNode->iNode)];
+    for( ; (*pp)!=pNode; pp = &(*pp)->pNext){ assert(*pp); }
+    *pp = pNode->pNext;
+    pNode->pNext = 0;
+  }
+}
+
+/*
+** Allocate and return new r-tree node. Initially, (RtreeNode.iNode==0),
+** indicating that node has not yet been assigned a node number. It is
+** assigned a node number when nodeWrite() is called to write the
+** node contents out to the database.
+*/
+static RtreeNode *nodeNew(Rtree *pRtree, RtreeNode *pParent, int zero){
+  RtreeNode *pNode;
+  pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
+  if( pNode ){
+    memset(pNode, 0, sizeof(RtreeNode) + (zero?pRtree->iNodeSize:0));
+    pNode->zData = (u8 *)&pNode[1];
+    pNode->nRef = 1;
+    pNode->pParent = pParent;
+    pNode->isDirty = 1;
+    nodeReference(pParent);
+  }
+  return pNode;
+}
+
+/*
+** Obtain a reference to an r-tree node.
+*/
+static int
+nodeAcquire(
+  Rtree *pRtree,             /* R-tree structure */
+  i64 iNode,                 /* Node number to load */
+  RtreeNode *pParent,        /* Either the parent node or NULL */
+  RtreeNode **ppNode         /* OUT: Acquired node */
+){
+  int rc;
+  RtreeNode *pNode;
+
+  /* Check if the requested node is already in the hash table. If so,
+  ** increase its reference count and return it.
+  */
+  if( (pNode = nodeHashLookup(pRtree, iNode)) ){
+    assert( !pParent || !pNode->pParent || pNode->pParent==pParent );
+    if( pParent ){
+      pNode->pParent = pParent;
+    }
+    pNode->nRef++;
+    *ppNode = pNode;
+    return SQLITE_OK;
+  }
+
+  pNode = (RtreeNode *)sqlite3_malloc(sizeof(RtreeNode) + pRtree->iNodeSize);
+  if( !pNode ){
+    *ppNode = 0;
+    return SQLITE_NOMEM;
+  }
+  pNode->pParent = pParent;
+  pNode->zData = (u8 *)&pNode[1];
+  pNode->nRef = 1;
+  pNode->iNode = iNode;
+  pNode->isDirty = 0;
+  pNode->pNext = 0;
+
+  sqlite3_bind_int64(pRtree->pReadNode, 1, iNode);
+  rc = sqlite3_step(pRtree->pReadNode);
+  if( rc==SQLITE_ROW ){
+    const u8 *zBlob = sqlite3_column_blob(pRtree->pReadNode, 0);
+    memcpy(pNode->zData, zBlob, pRtree->iNodeSize);
+    nodeReference(pParent);
+  }else{
+    sqlite3_free(pNode);
+    pNode = 0;
+  }
+
+  *ppNode = pNode;
+  rc = sqlite3_reset(pRtree->pReadNode);
+
+  if( rc==SQLITE_OK && iNode==1 ){
+    pRtree->iDepth = readInt16(pNode->zData);
+  }
+
+  assert( (rc==SQLITE_OK && pNode) || (pNode==0 && rc!=SQLITE_OK) );
+  nodeHashInsert(pRtree, pNode);
+
+  return rc;
+}
+
+/*
+** Overwrite cell iCell of node pNode with the contents of pCell.
+*/
+static void nodeOverwriteCell(
+  Rtree *pRtree, 
+  RtreeNode *pNode,  
+  RtreeCell *pCell, 
+  int iCell
+){
+  int ii;
+  u8 *p = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
+  p += writeInt64(p, pCell->iRowid);
+  for(ii=0; ii<(pRtree->nDim*2); ii++){
+    p += writeCoord(p, &pCell->aCoord[ii]);
+  }
+  pNode->isDirty = 1;
+}
+
+/*
+** Remove cell the cell with index iCell from node pNode.
+*/
+static void nodeDeleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell){
+  u8 *pDst = &pNode->zData[4 + pRtree->nBytesPerCell*iCell];
+  u8 *pSrc = &pDst[pRtree->nBytesPerCell];
+  int nByte = (NCELL(pNode) - iCell - 1) * pRtree->nBytesPerCell;
+  memmove(pDst, pSrc, nByte);
+  writeInt16(&pNode->zData[2], NCELL(pNode)-1);
+  pNode->isDirty = 1;
+}
+
+/*
+** Insert the contents of cell pCell into node pNode. If the insert
+** is successful, return SQLITE_OK.
+**
+** If there is not enough free space in pNode, return SQLITE_FULL.
+*/
+static int
+nodeInsertCell(
+  Rtree *pRtree, 
+  RtreeNode *pNode, 
+  RtreeCell *pCell 
+){
+  int nCell;                    /* Current number of cells in pNode */
+  int nMaxCell;                 /* Maximum number of cells for pNode */
+
+  nMaxCell = (pRtree->iNodeSize-4)/pRtree->nBytesPerCell;
+  nCell = NCELL(pNode);
+
+  assert(nCell<=nMaxCell);
+
+  if( nCell<nMaxCell ){
+    nodeOverwriteCell(pRtree, pNode, pCell, nCell);
+    writeInt16(&pNode->zData[2], nCell+1);
+    pNode->isDirty = 1;
+  }
+
+  return (nCell==nMaxCell);
+}
+
+/*
+** If the node is dirty, write it out to the database.
+*/
+static int
+nodeWrite(Rtree *pRtree, RtreeNode *pNode){
+  int rc = SQLITE_OK;
+  if( pNode->isDirty ){
+    sqlite3_stmt *p = pRtree->pWriteNode;
+    if( pNode->iNode ){
+      sqlite3_bind_int64(p, 1, pNode->iNode);
+    }else{
+      sqlite3_bind_null(p, 1);
+    }
+    sqlite3_bind_blob(p, 2, pNode->zData, pRtree->iNodeSize, SQLITE_STATIC);
+    sqlite3_step(p);
+    pNode->isDirty = 0;
+    rc = sqlite3_reset(p);
+    if( pNode->iNode==0 && rc==SQLITE_OK ){
+      pNode->iNode = sqlite3_last_insert_rowid(pRtree->db);
+      nodeHashInsert(pRtree, pNode);
+    }
+  }
+  return rc;
+}
+
+/*
+** Release a reference to a node. If the node is dirty and the reference
+** count drops to zero, the node data is written to the database.
+*/
+static int
+nodeRelease(Rtree *pRtree, RtreeNode *pNode){
+  int rc = SQLITE_OK;
+  if( pNode ){
+    assert( pNode->nRef>0 );
+    pNode->nRef--;
+    if( pNode->nRef==0 ){
+      if( pNode->iNode==1 ){
+        pRtree->iDepth = -1;
+      }
+      if( pNode->pParent ){
+        rc = nodeRelease(pRtree, pNode->pParent);
+      }
+      if( rc==SQLITE_OK ){
+        rc = nodeWrite(pRtree, pNode);
+      }
+      nodeHashDelete(pRtree, pNode);
+      sqlite3_free(pNode);
+    }
+  }
+  return rc;
+}
+
+/*
+** Return the 64-bit integer value associated with cell iCell of
+** node pNode. If pNode is a leaf node, this is a rowid. If it is
+** an internal node, then the 64-bit integer is a child page number.
+*/
+static i64 nodeGetRowid(
+  Rtree *pRtree, 
+  RtreeNode *pNode, 
+  int iCell
+){
+  assert( iCell<NCELL(pNode) );
+  return readInt64(&pNode->zData[4 + pRtree->nBytesPerCell*iCell]);
+}
+
+/*
+** Return coordinate iCoord from cell iCell in node pNode.
+*/
+static void nodeGetCoord(
+  Rtree *pRtree, 
+  RtreeNode *pNode, 
+  int iCell,
+  int iCoord,
+  RtreeCoord *pCoord           /* Space to write result to */
+){
+  readCoord(&pNode->zData[12 + pRtree->nBytesPerCell*iCell + 4*iCoord], pCoord);
+}
+
+/*
+** Deserialize cell iCell of node pNode. Populate the structure pointed
+** to by pCell with the results.
+*/
+static void nodeGetCell(
+  Rtree *pRtree, 
+  RtreeNode *pNode, 
+  int iCell,
+  RtreeCell *pCell
+){
+  int ii;
+  pCell->iRowid = nodeGetRowid(pRtree, pNode, iCell);
+  for(ii=0; ii<pRtree->nDim*2; ii++){
+    nodeGetCoord(pRtree, pNode, iCell, ii, &pCell->aCoord[ii]);
+  }
+}
+
+
+/* Forward declaration for the function that does the work of
+** the virtual table module xCreate() and xConnect() methods.
+*/
+static int rtreeInit(
+  sqlite3 *, void *, int, const char *const*, sqlite3_vtab **, char **, int, int
+);
+
+/* 
+** Rtree virtual table module xCreate method.
+*/
+static int rtreeCreate(
+  sqlite3 *db,
+  void *pAux,
+  int argc, const char *const*argv,
+  sqlite3_vtab **ppVtab,
+  char **pzErr
+){
+  return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 1, (int)pAux);
+}
+
+/* 
+** Rtree virtual table module xConnect method.
+*/
+static int rtreeConnect(
+  sqlite3 *db,
+  void *pAux,
+  int argc, const char *const*argv,
+  sqlite3_vtab **ppVtab,
+  char **pzErr
+){
+  return rtreeInit(db, pAux, argc, argv, ppVtab, pzErr, 0, (int)pAux);
+}
+
+/*
+** Increment the r-tree reference count.
+*/
+static void rtreeReference(Rtree *pRtree){
+  pRtree->nBusy++;
+}
+
+/*
+** Decrement the r-tree reference count. When the reference count reaches
+** zero the structure is deleted.
+*/
+static void rtreeRelease(Rtree *pRtree){
+  pRtree->nBusy--;
+  if( pRtree->nBusy==0 ){
+    sqlite3_finalize(pRtree->pReadNode);
+    sqlite3_finalize(pRtree->pWriteNode);
+    sqlite3_finalize(pRtree->pDeleteNode);
+    sqlite3_finalize(pRtree->pReadRowid);
+    sqlite3_finalize(pRtree->pWriteRowid);
+    sqlite3_finalize(pRtree->pDeleteRowid);
+    sqlite3_finalize(pRtree->pReadParent);
+    sqlite3_finalize(pRtree->pWriteParent);
+    sqlite3_finalize(pRtree->pDeleteParent);
+    sqlite3_free(pRtree);
+  }
+}
+
+/* 
+** Rtree virtual table module xDisconnect method.
+*/
+static int rtreeDisconnect(sqlite3_vtab *pVtab){
+  rtreeRelease((Rtree *)pVtab);
+  return SQLITE_OK;
+}
+
+/* 
+** Rtree virtual table module xDestroy method.
+*/
+static int rtreeDestroy(sqlite3_vtab *pVtab){
+  Rtree *pRtree = (Rtree *)pVtab;
+  int rc;
+  char *zCreate = sqlite3_mprintf(
+    "DROP TABLE '%q'.'%q_node';"
+    "DROP TABLE '%q'.'%q_rowid';"
+    "DROP TABLE '%q'.'%q_parent';",
+    pRtree->zDb, pRtree->zName, 
+    pRtree->zDb, pRtree->zName,
+    pRtree->zDb, pRtree->zName
+  );
+  if( !zCreate ){
+    rc = SQLITE_NOMEM;
+  }else{
+    rc = sqlite3_exec(pRtree->db, zCreate, 0, 0, 0);
+    sqlite3_free(zCreate);
+  }
+  if( rc==SQLITE_OK ){
+    rtreeRelease(pRtree);
+  }
+
+  return rc;
+}
+
+/* 
+** Rtree virtual table module xOpen method.
+*/
+static int rtreeOpen(sqlite3_vtab *pVTab, sqlite3_vtab_cursor **ppCursor){
+  int rc = SQLITE_NOMEM;
+  RtreeCursor *pCsr;
+
+  pCsr = (RtreeCursor *)sqlite3_malloc(sizeof(RtreeCursor));
+  if( pCsr ){
+    memset(pCsr, 0, sizeof(RtreeCursor));
+    pCsr->base.pVtab = pVTab;
+    rc = SQLITE_OK;
+  }
+  *ppCursor = (sqlite3_vtab_cursor *)pCsr;
+
+  return rc;
+}
+
+/* 
+** Rtree virtual table module xClose method.
+*/
+static int rtreeClose(sqlite3_vtab_cursor *cur){
+  Rtree *pRtree = (Rtree *)(cur->pVtab);
+  int rc;
+  RtreeCursor *pCsr = (RtreeCursor *)cur;
+  sqlite3_free(pCsr->aConstraint);
+  rc = nodeRelease(pRtree, pCsr->pNode);
+  sqlite3_free(pCsr);
+  return rc;
+}
+
+/*
+** Rtree virtual table module xEof method.
+**
+** Return non-zero if the cursor does not currently point to a valid 
+** record (i.e if the scan has finished), or zero otherwise.
+*/
+static int rtreeEof(sqlite3_vtab_cursor *cur){
+  RtreeCursor *pCsr = (RtreeCursor *)cur;
+  return (pCsr->pNode==0);
+}
+
+/* 
+** Cursor pCursor currently points to a cell in a non-leaf page.
+** Return true if the sub-tree headed by the cell is filtered
+** (excluded) by the constraints in the pCursor->aConstraint[] 
+** array, or false otherwise.
+*/
+static int testRtreeCell(Rtree *pRtree, RtreeCursor *pCursor){
+  RtreeCell cell;
+  int ii;
+  int bRes = 0;
+
+  nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
+  for(ii=0; bRes==0 && ii<pCursor->nConstraint; ii++){
+    RtreeConstraint *p = &pCursor->aConstraint[ii];
+    double cell_min = DCOORD(cell.aCoord[(p->iCoord>>1)*2]);
+    double cell_max = DCOORD(cell.aCoord[(p->iCoord>>1)*2+1]);
+
+    assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
+        || p->op==RTREE_GT || p->op==RTREE_EQ
+    );
+
+    switch( p->op ){
+      case RTREE_LE: case RTREE_LT: bRes = p->rValue<cell_min; break;
+      case RTREE_GE: case RTREE_GT: bRes = p->rValue>cell_max; break;
+      case RTREE_EQ: 
+        bRes = (p->rValue>cell_max || p->rValue<cell_min);
+        break;
+    }
+  }
+
+  return bRes;
+}
+
+/* 
+** Return true if the cell that cursor pCursor currently points to
+** would be filtered (excluded) by the constraints in the 
+** pCursor->aConstraint[] array, or false otherwise.
+**
+** This function assumes that the cell is part of a leaf node.
+*/
+static int testRtreeEntry(Rtree *pRtree, RtreeCursor *pCursor){
+  RtreeCell cell;
+  int ii;
+
+  nodeGetCell(pRtree, pCursor->pNode, pCursor->iCell, &cell);
+  for(ii=0; ii<pCursor->nConstraint; ii++){
+    RtreeConstraint *p = &pCursor->aConstraint[ii];
+    double coord = DCOORD(cell.aCoord[p->iCoord]);
+    int res;
+    assert(p->op==RTREE_LE || p->op==RTREE_LT || p->op==RTREE_GE 
+        || p->op==RTREE_GT || p->op==RTREE_EQ
+    );
+    switch( p->op ){
+      case RTREE_LE: res = (coord<=p->rValue); break;
+      case RTREE_LT: res = (coord<p->rValue);  break;
+      case RTREE_GE: res = (coord>=p->rValue); break;
+      case RTREE_GT: res = (coord>p->rValue);  break;
+      case RTREE_EQ: res = (coord==p->rValue); break;
+    }
+
+    if( !res ) return 1;
+  }
+
+  return 0;
+}
+
+/*
+** Cursor pCursor currently points at a node that heads a sub-tree of
+** height iHeight (if iHeight==0, then the node is a leaf). Descend
+** to point to the left-most cell of the sub-tree that matches the 
+** configured constraints.
+*/
+static int descendToCell(
+  Rtree *pRtree, 
+  RtreeCursor *pCursor, 
+  int iHeight,
+  int *pEof                 /* OUT: Set to true if cannot descend */
+){
+  int isEof;
+  int rc;
+  int ii;
+  RtreeNode *pChild;
+  sqlite3_int64 iRowid;
+
+  RtreeNode *pSavedNode = pCursor->pNode;
+  int iSavedCell = pCursor->iCell;
+
+  assert( iHeight>=0 );
+
+  if( iHeight==0 ){
+    isEof = testRtreeEntry(pRtree, pCursor);
+  }else{
+    isEof = testRtreeCell(pRtree, pCursor);
+  }
+  if( isEof || iHeight==0 ){
+    *pEof = isEof;
+    return SQLITE_OK;
+  }
+
+  iRowid = nodeGetRowid(pRtree, pCursor->pNode, pCursor->iCell);
+  rc = nodeAcquire(pRtree, iRowid, pCursor->pNode, &pChild);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+
+  nodeRelease(pRtree, pCursor->pNode);
+  pCursor->pNode = pChild;
+  isEof = 1;
+  for(ii=0; isEof && ii<NCELL(pChild); ii++){
+    pCursor->iCell = ii;
+    rc = descendToCell(pRtree, pCursor, iHeight-1, &isEof);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+  }
+
+  if( isEof ){
+    assert( pCursor->pNode==pChild );
+    nodeReference(pSavedNode);
+    nodeRelease(pRtree, pChild);
+    pCursor->pNode = pSavedNode;
+    pCursor->iCell = iSavedCell;
+  }
+
+  *pEof = isEof;
+  return SQLITE_OK;
+}
+
+/*
+** One of the cells in node pNode is guaranteed to have a 64-bit 
+** integer value equal to iRowid. Return the index of this cell.
+*/
+static int nodeRowidIndex(Rtree *pRtree, RtreeNode *pNode, i64 iRowid){
+  int ii;
+  for(ii=0; nodeGetRowid(pRtree, pNode, ii)!=iRowid; ii++){
+    assert( ii<(NCELL(pNode)-1) );
+  }
+  return ii;
+}
+
+/*
+** Return the index of the cell containing a pointer to node pNode
+** in its parent. If pNode is the root node, return -1.
+*/
+static int nodeParentIndex(Rtree *pRtree, RtreeNode *pNode){
+  RtreeNode *pParent = pNode->pParent;
+  if( pParent ){
+    return nodeRowidIndex(pRtree, pParent, pNode->iNode);
+  }
+  return -1;
+}
+
+/* 
+** Rtree virtual table module xNext method.
+*/
+static int rtreeNext(sqlite3_vtab_cursor *pVtabCursor){
+  Rtree *pRtree = (Rtree *)(pVtabCursor->pVtab);
+  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
+  int rc = SQLITE_OK;
+
+  if( pCsr->iStrategy==1 ){
+    /* This "scan" is a direct lookup by rowid. There is no next entry. */
+    nodeRelease(pRtree, pCsr->pNode);
+    pCsr->pNode = 0;
+  }
+
+  else if( pCsr->pNode ){
+    /* Move to the next entry that matches the configured constraints. */
+    int iHeight = 0;
+    while( pCsr->pNode ){
+      RtreeNode *pNode = pCsr->pNode;
+      int nCell = NCELL(pNode);
+      for(pCsr->iCell++; pCsr->iCell<nCell; pCsr->iCell++){
+        int isEof;
+        rc = descendToCell(pRtree, pCsr, iHeight, &isEof);
+        if( rc!=SQLITE_OK || !isEof ){
+          return rc;
+        }
+      }
+      pCsr->pNode = pNode->pParent;
+      pCsr->iCell = nodeParentIndex(pRtree, pNode);
+      nodeReference(pCsr->pNode);
+      nodeRelease(pRtree, pNode);
+      iHeight++;
+    }
+  }
+
+  return rc;
+}
+
+/* 
+** Rtree virtual table module xRowid method.
+*/
+static int rtreeRowid(sqlite3_vtab_cursor *pVtabCursor, sqlite_int64 *pRowid){
+  Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
+  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
+
+  assert(pCsr->pNode);
+  *pRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
+
+  return SQLITE_OK;
+}
+
+/* 
+** Rtree virtual table module xColumn method.
+*/
+static int rtreeColumn(sqlite3_vtab_cursor *cur, sqlite3_context *ctx, int i){
+  Rtree *pRtree = (Rtree *)cur->pVtab;
+  RtreeCursor *pCsr = (RtreeCursor *)cur;
+
+  if( i==0 ){
+    i64 iRowid = nodeGetRowid(pRtree, pCsr->pNode, pCsr->iCell);
+    sqlite3_result_int64(ctx, iRowid);
+  }else{
+    RtreeCoord c;
+    nodeGetCoord(pRtree, pCsr->pNode, pCsr->iCell, i-1, &c);
+    if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+      sqlite3_result_double(ctx, c.f);
+    }else{
+      assert( pRtree->eCoordType==RTREE_COORD_INT32 );
+      sqlite3_result_int(ctx, c.i);
+    }
+  }
+
+  return SQLITE_OK;
+}
+
+/* 
+** Use nodeAcquire() to obtain the leaf node containing the record with 
+** rowid iRowid. If successful, set *ppLeaf to point to the node and
+** return SQLITE_OK. If there is no such record in the table, set
+** *ppLeaf to 0 and return SQLITE_OK. If an error occurs, set *ppLeaf
+** to zero and return an SQLite error code.
+*/
+static int findLeafNode(Rtree *pRtree, i64 iRowid, RtreeNode **ppLeaf){
+  int rc;
+  *ppLeaf = 0;
+  sqlite3_bind_int64(pRtree->pReadRowid, 1, iRowid);
+  if( sqlite3_step(pRtree->pReadRowid)==SQLITE_ROW ){
+    i64 iNode = sqlite3_column_int64(pRtree->pReadRowid, 0);
+    rc = nodeAcquire(pRtree, iNode, 0, ppLeaf);
+    sqlite3_reset(pRtree->pReadRowid);
+  }else{
+    rc = sqlite3_reset(pRtree->pReadRowid);
+  }
+  return rc;
+}
+
+
+/* 
+** Rtree virtual table module xFilter method.
+*/
+static int rtreeFilter(
+  sqlite3_vtab_cursor *pVtabCursor, 
+  int idxNum, const char *idxStr,
+  int argc, sqlite3_value **argv
+){
+  Rtree *pRtree = (Rtree *)pVtabCursor->pVtab;
+  RtreeCursor *pCsr = (RtreeCursor *)pVtabCursor;
+
+  RtreeNode *pRoot = 0;
+  int ii;
+  int rc = SQLITE_OK;
+
+  rtreeReference(pRtree);
+
+  sqlite3_free(pCsr->aConstraint);
+  pCsr->aConstraint = 0;
+  pCsr->iStrategy = idxNum;
+
+  if( idxNum==1 ){
+    /* Special case - lookup by rowid. */
+    RtreeNode *pLeaf;        /* Leaf on which the required cell resides */
+    i64 iRowid = sqlite3_value_int64(argv[0]);
+    rc = findLeafNode(pRtree, iRowid, &pLeaf);
+    pCsr->pNode = pLeaf; 
+    if( pLeaf && rc==SQLITE_OK ){
+      pCsr->iCell = nodeRowidIndex(pRtree, pLeaf, iRowid);
+    }
+  }else{
+    /* Normal case - r-tree scan. Set up the RtreeCursor.aConstraint array 
+    ** with the configured constraints. 
+    */
+    if( argc>0 ){
+      pCsr->aConstraint = sqlite3_malloc(sizeof(RtreeConstraint)*argc);
+      pCsr->nConstraint = argc;
+      if( !pCsr->aConstraint ){
+        rc = SQLITE_NOMEM;
+      }else{
+        assert( (idxStr==0 && argc==0) || strlen(idxStr)==argc*2 );
+        for(ii=0; ii<argc; ii++){
+          RtreeConstraint *p = &pCsr->aConstraint[ii];
+          p->op = idxStr[ii*2];
+          p->iCoord = idxStr[ii*2+1]-'a';
+          p->rValue = sqlite3_value_double(argv[ii]);
+        }
+      }
+    }
+  
+    if( rc==SQLITE_OK ){
+      pCsr->pNode = 0;
+      rc = nodeAcquire(pRtree, 1, 0, &pRoot);
+    }
+    if( rc==SQLITE_OK ){
+      int isEof = 1;
+      int nCell = NCELL(pRoot);
+      pCsr->pNode = pRoot;
+      for(pCsr->iCell=0; rc==SQLITE_OK && pCsr->iCell<nCell; pCsr->iCell++){
+        assert( pCsr->pNode==pRoot );
+        rc = descendToCell(pRtree, pCsr, pRtree->iDepth, &isEof);
+        if( !isEof ){
+          break;
+        }
+      }
+      if( rc==SQLITE_OK && isEof ){
+        assert( pCsr->pNode==pRoot );
+        nodeRelease(pRtree, pRoot);
+        pCsr->pNode = 0;
+      }
+      assert( rc!=SQLITE_OK || !pCsr->pNode || pCsr->iCell<NCELL(pCsr->pNode) );
+    }
+  }
+
+  rtreeRelease(pRtree);
+  return rc;
+}
+
+/*
+** Rtree virtual table module xBestIndex method. There are three
+** table scan strategies to choose from (in order from most to 
+** least desirable):
+**
+**   idxNum     idxStr        Strategy
+**   ------------------------------------------------
+**     1        Unused        Direct lookup by rowid.
+**     2        See below     R-tree query.
+**     3        Unused        Full table scan.
+**   ------------------------------------------------
+**
+** If strategy 1 or 3 is used, then idxStr is not meaningful. If strategy
+** 2 is used, idxStr is formatted to contain 2 bytes for each 
+** constraint used. The first two bytes of idxStr correspond to 
+** the constraint in sqlite3_index_info.aConstraintUsage[] with
+** (argvIndex==1) etc.
+**
+** The first of each pair of bytes in idxStr identifies the constraint
+** operator as follows:
+**
+**   Operator    Byte Value
+**   ----------------------
+**      =        0x41 ('A')
+**     <=        0x42 ('B')
+**      <        0x43 ('C')
+**     >=        0x44 ('D')
+**      >        0x45 ('E')
+**   ----------------------
+**
+** The second of each pair of bytes identifies the coordinate column
+** to which the constraint applies. The leftmost coordinate column
+** is 'a', the second from the left 'b' etc.
+*/
+static int rtreeBestIndex(sqlite3_vtab *tab, sqlite3_index_info *pIdxInfo){
+  int rc = SQLITE_OK;
+  int ii, cCol;
+
+  int iIdx = 0;
+  char zIdxStr[RTREE_MAX_DIMENSIONS*8+1];
+  memset(zIdxStr, 0, sizeof(zIdxStr));
+
+  assert( pIdxInfo->idxStr==0 );
+  for(ii=0; ii<pIdxInfo->nConstraint; ii++){
+    struct sqlite3_index_constraint *p = &pIdxInfo->aConstraint[ii];
+
+    if( p->usable && p->iColumn==0 && p->op==SQLITE_INDEX_CONSTRAINT_EQ ){
+      /* We have an equality constraint on the rowid. Use strategy 1. */
+      int jj;
+      for(jj=0; jj<ii; jj++){
+        pIdxInfo->aConstraintUsage[jj].argvIndex = 0;
+        pIdxInfo->aConstraintUsage[jj].omit = 0;
+      }
+      pIdxInfo->idxNum = 1;
+      pIdxInfo->aConstraintUsage[ii].argvIndex = 1;
+      pIdxInfo->aConstraintUsage[jj].omit = 1;
+      return SQLITE_OK;
+    }
+
+    if( p->usable && p->iColumn>0 ){
+      u8 op = 0;
+      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_LE: op = RTREE_LE; break;
+        case SQLITE_INDEX_CONSTRAINT_LT: op = RTREE_LT; break;
+        case SQLITE_INDEX_CONSTRAINT_GE: op = RTREE_GE; break;
+      }
+      if( op ){
+        /* Make sure this particular constraint has not been used before.
+        ** If it has been used before, ignore it.
+        **
+        ** A <= or < can be used if there is a prior >= or >.
+        ** A >= or > can be used if there is a prior < or <=.
+        ** A <= or < is disqualified if there is a prior <=, <, or ==.
+        ** A >= or > is disqualified if there is a prior >=, >, or ==.
+        ** A == is disqualifed if there is any prior constraint.
+        */
+        int j, opmsk;
+        static const unsigned char compatible[] = { 0, 0, 1, 1, 2, 2 };
+        assert( compatible[RTREE_EQ & 7]==0 );
+        assert( compatible[RTREE_LT & 7]==1 );
+        assert( compatible[RTREE_LE & 7]==1 );
+        assert( compatible[RTREE_GT & 7]==2 );
+        assert( compatible[RTREE_GE & 7]==2 );
+        cCol = p->iColumn - 1 + 'a';
+        opmsk = compatible[op & 7];
+        for(j=0; j<iIdx; j+=2){
+          if( zIdxStr[j+1]==cCol && (compatible[zIdxStr[j] & 7] & opmsk)!=0 ){
+            op = 0;
+            break;
+          }
+        }
+      }
+      if( op ){
+        assert( iIdx<sizeof(zIdxStr)-1 );
+        zIdxStr[iIdx++] = op;
+        zIdxStr[iIdx++] = cCol;
+        pIdxInfo->aConstraintUsage[ii].argvIndex = (iIdx/2);
+        pIdxInfo->aConstraintUsage[ii].omit = 1;
+      }
+    }
+  }
+
+  pIdxInfo->idxNum = 2;
+  pIdxInfo->needToFreeIdxStr = 1;
+  if( iIdx>0 && 0==(pIdxInfo->idxStr = sqlite3_mprintf("%s", zIdxStr)) ){
+    return SQLITE_NOMEM;
+  }
+  return rc;
+}
+
+/*
+** Return the N-dimensional volumn of the cell stored in *p.
+*/
+static float cellArea(Rtree *pRtree, RtreeCell *p){
+  float area = 1.0;
+  int ii;
+  for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+    area = area * (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
+  }
+  return area;
+}
+
+/*
+** Return the margin length of cell p. The margin length is the sum
+** of the objects size in each dimension.
+*/
+static float cellMargin(Rtree *pRtree, RtreeCell *p){
+  float margin = 0.0;
+  int ii;
+  for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+    margin += (DCOORD(p->aCoord[ii+1]) - DCOORD(p->aCoord[ii]));
+  }
+  return margin;
+}
+
+/*
+** Store the union of cells p1 and p2 in p1.
+*/
+static void cellUnion(Rtree *pRtree, RtreeCell *p1, RtreeCell *p2){
+  int ii;
+  if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+    for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+      p1->aCoord[ii].f = MIN(p1->aCoord[ii].f, p2->aCoord[ii].f);
+      p1->aCoord[ii+1].f = MAX(p1->aCoord[ii+1].f, p2->aCoord[ii+1].f);
+    }
+  }else{
+    for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+      p1->aCoord[ii].i = MIN(p1->aCoord[ii].i, p2->aCoord[ii].i);
+      p1->aCoord[ii+1].i = MAX(p1->aCoord[ii+1].i, p2->aCoord[ii+1].i);
+    }
+  }
+}
+
+/*
+** Return the amount cell p would grow by if it were unioned with pCell.
+*/
+static float cellGrowth(Rtree *pRtree, RtreeCell *p, RtreeCell *pCell){
+  float area;
+  RtreeCell cell;
+  memcpy(&cell, p, sizeof(RtreeCell));
+  area = cellArea(pRtree, &cell);
+  cellUnion(pRtree, &cell, pCell);
+  return (cellArea(pRtree, &cell)-area);
+}
+
+#if VARIANT_RSTARTREE_CHOOSESUBTREE || VARIANT_RSTARTREE_SPLIT
+static float cellOverlap(
+  Rtree *pRtree, 
+  RtreeCell *p, 
+  RtreeCell *aCell, 
+  int nCell, 
+  int iExclude
+){
+  int ii;
+  float overlap = 0.0;
+  for(ii=0; ii<nCell; ii++){
+    if( ii!=iExclude ){
+      int jj;
+      float o = 1.0;
+      for(jj=0; jj<(pRtree->nDim*2); jj+=2){
+        double x1;
+        double x2;
+
+        x1 = MAX(DCOORD(p->aCoord[jj]), DCOORD(aCell[ii].aCoord[jj]));
+        x2 = MIN(DCOORD(p->aCoord[jj+1]), DCOORD(aCell[ii].aCoord[jj+1]));
+
+        if( x2<x1 ){
+          o = 0.0;
+          break;
+        }else{
+          o = o * (x2-x1);
+        }
+      }
+      overlap += o;
+    }
+  }
+  return overlap;
+}
+#endif
+
+#if VARIANT_RSTARTREE_CHOOSESUBTREE
+static float cellOverlapEnlargement(
+  Rtree *pRtree, 
+  RtreeCell *p, 
+  RtreeCell *pInsert, 
+  RtreeCell *aCell, 
+  int nCell, 
+  int iExclude
+){
+  float before;
+  float after;
+  before = cellOverlap(pRtree, p, aCell, nCell, iExclude);
+  cellUnion(pRtree, p, pInsert);
+  after = cellOverlap(pRtree, p, aCell, nCell, iExclude);
+  return after-before;
+}
+#endif
+
+
+/*
+** This function implements the ChooseLeaf algorithm from Gutman[84].
+** ChooseSubTree in r*tree terminology.
+*/
+static int ChooseLeaf(
+  Rtree *pRtree,               /* Rtree table */
+  RtreeCell *pCell,            /* Cell to insert into rtree */
+  int iHeight,                 /* Height of sub-tree rooted at pCell */
+  RtreeNode **ppLeaf           /* OUT: Selected leaf page */
+){
+  int rc;
+  int ii;
+  RtreeNode *pNode;
+  rc = nodeAcquire(pRtree, 1, 0, &pNode);
+
+  for(ii=0; rc==SQLITE_OK && ii<(pRtree->iDepth-iHeight); ii++){
+    int iCell;
+    sqlite3_int64 iBest;
+
+    float fMinGrowth;
+    float fMinArea;
+    float fMinOverlap;
+
+    int nCell = NCELL(pNode);
+    RtreeCell cell;
+    RtreeNode *pChild;
+
+    RtreeCell *aCell = 0;
+
+#if VARIANT_RSTARTREE_CHOOSESUBTREE
+    if( ii==(pRtree->iDepth-1) ){
+      int jj;
+      aCell = sqlite3_malloc(sizeof(RtreeCell)*nCell);
+      if( !aCell ){
+        rc = SQLITE_NOMEM;
+        nodeRelease(pRtree, pNode);
+        pNode = 0;
+        continue;
+      }
+      for(jj=0; jj<nCell; jj++){
+        nodeGetCell(pRtree, pNode, jj, &aCell[jj]);
+      }
+    }
+#endif
+
+    /* 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.
+    */
+    for(iCell=0; iCell<nCell; iCell++){
+      float growth;
+      float area;
+      float overlap = 0.0;
+      nodeGetCell(pRtree, pNode, iCell, &cell);
+      growth = cellGrowth(pRtree, &cell, pCell);
+      area = cellArea(pRtree, &cell);
+#if VARIANT_RSTARTREE_CHOOSESUBTREE
+      if( ii==(pRtree->iDepth-1) ){
+        overlap = cellOverlapEnlargement(pRtree,&cell,pCell,aCell,nCell,iCell);
+      }
+#endif
+      if( (iCell==0) 
+       || (overlap<fMinOverlap) 
+       || (overlap==fMinOverlap && growth<fMinGrowth)
+       || (overlap==fMinOverlap && growth==fMinGrowth && area<fMinArea)
+      ){
+        fMinOverlap = overlap;
+        fMinGrowth = growth;
+        fMinArea = area;
+        iBest = cell.iRowid;
+      }
+    }
+
+    sqlite3_free(aCell);
+    rc = nodeAcquire(pRtree, iBest, pNode, &pChild);
+    nodeRelease(pRtree, pNode);
+    pNode = pChild;
+  }
+
+  *ppLeaf = pNode;
+  return rc;
+}
+
+/*
+** A cell with the same content as pCell has just been inserted into
+** the node pNode. This function updates the bounding box cells in
+** all ancestor elements.
+*/
+static void AdjustTree(
+  Rtree *pRtree,                    /* Rtree table */
+  RtreeNode *pNode,                 /* Adjust ancestry of this node. */
+  RtreeCell *pCell                  /* This cell was just inserted */
+){
+  RtreeNode *p = pNode;
+  while( p->pParent ){
+    RtreeCell cell;
+    RtreeNode *pParent = p->pParent;
+    int iCell = nodeParentIndex(pRtree, p);
+
+    nodeGetCell(pRtree, pParent, iCell, &cell);
+    if( cellGrowth(pRtree, &cell, pCell)>0.0 ){
+      cellUnion(pRtree, &cell, pCell);
+      nodeOverwriteCell(pRtree, pParent, &cell, iCell);
+    }
+ 
+    p = pParent;
+  }
+}
+
+/*
+** Write mapping (iRowid->iNode) to the <rtree>_rowid table.
+*/
+static int rowidWrite(Rtree *pRtree, sqlite3_int64 iRowid, sqlite3_int64 iNode){
+  sqlite3_bind_int64(pRtree->pWriteRowid, 1, iRowid);
+  sqlite3_bind_int64(pRtree->pWriteRowid, 2, iNode);
+  sqlite3_step(pRtree->pWriteRowid);
+  return sqlite3_reset(pRtree->pWriteRowid);
+}
+
+/*
+** Write mapping (iNode->iPar) to the <rtree>_parent table.
+*/
+static int parentWrite(Rtree *pRtree, sqlite3_int64 iNode, sqlite3_int64 iPar){
+  sqlite3_bind_int64(pRtree->pWriteParent, 1, iNode);
+  sqlite3_bind_int64(pRtree->pWriteParent, 2, iPar);
+  sqlite3_step(pRtree->pWriteParent);
+  return sqlite3_reset(pRtree->pWriteParent);
+}
+
+static int rtreeInsertCell(Rtree *, RtreeNode *, RtreeCell *, int);
+
+#if VARIANT_GUTTMAN_LINEAR_SPLIT
+/*
+** Implementation of the linear variant of the PickNext() function from
+** Guttman[84].
+*/
+static RtreeCell *LinearPickNext(
+  Rtree *pRtree,
+  RtreeCell *aCell, 
+  int nCell, 
+  RtreeCell *pLeftBox, 
+  RtreeCell *pRightBox,
+  int *aiUsed
+){
+  int ii;
+  for(ii=0; aiUsed[ii]; ii++);
+  aiUsed[ii] = 1;
+  return &aCell[ii];
+}
+
+/*
+** Implementation of the linear variant of the PickSeeds() function from
+** Guttman[84].
+*/
+static void LinearPickSeeds(
+  Rtree *pRtree,
+  RtreeCell *aCell, 
+  int nCell, 
+  int *piLeftSeed, 
+  int *piRightSeed
+){
+  int i;
+  int iLeftSeed = 0;
+  int iRightSeed = 1;
+  float maxNormalInnerWidth = 0.0;
+
+  /* Pick two "seed" cells from the array of cells. The algorithm used
+  ** here is the LinearPickSeeds algorithm from Gutman[1984]. The 
+  ** indices of the two seed cells in the array are stored in local
+  ** variables iLeftSeek and iRightSeed.
+  */
+  for(i=0; i<pRtree->nDim; i++){
+    float x1 = aCell[0].aCoord[i*2];
+    float x2 = aCell[0].aCoord[i*2+1];
+    float x3 = x1;
+    float x4 = x2;
+    int jj;
+
+    int iCellLeft = 0;
+    int iCellRight = 0;
+
+    for(jj=1; jj<nCell; jj++){
+      float left = aCell[jj].aCoord[i*2];
+      float right = aCell[jj].aCoord[i*2+1];
+
+      if( left<x1 ) x1 = left;
+      if( right>x4 ) x4 = right;
+      if( left>x3 ){
+        x3 = left;
+        iCellRight = jj;
+      }
+      if( right<x2 ){
+        x2 = right;
+        iCellLeft = jj;
+      }
+    }
+
+    if( x4!=x1 ){
+      float normalwidth = (x3 - x2) / (x4 - x1);
+      if( normalwidth>maxNormalInnerWidth ){
+        iLeftSeed = iCellLeft;
+        iRightSeed = iCellRight;
+      }
+    }
+  }
+
+  *piLeftSeed = iLeftSeed;
+  *piRightSeed = iRightSeed;
+}
+#endif /* VARIANT_GUTTMAN_LINEAR_SPLIT */
+
+#if VARIANT_GUTTMAN_QUADRATIC_SPLIT
+/*
+** Implementation of the quadratic variant of the PickNext() function from
+** Guttman[84].
+*/
+static RtreeCell *QuadraticPickNext(
+  Rtree *pRtree,
+  RtreeCell *aCell, 
+  int nCell, 
+  RtreeCell *pLeftBox, 
+  RtreeCell *pRightBox,
+  int *aiUsed
+){
+  #define FABS(a) ((a)<0.0?-1.0*(a):(a))
+
+  int iSelect = -1;
+  float fDiff;
+  int ii;
+  for(ii=0; ii<nCell; ii++){
+    if( aiUsed[ii]==0 ){
+      float left = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
+      float right = cellGrowth(pRtree, pLeftBox, &aCell[ii]);
+      float diff = FABS(right-left);
+      if( iSelect<0 || diff>fDiff ){
+        fDiff = diff;
+        iSelect = ii;
+      }
+    }
+  }
+  aiUsed[iSelect] = 1;
+  return &aCell[iSelect];
+}
+
+/*
+** Implementation of the quadratic variant of the PickSeeds() function from
+** Guttman[84].
+*/
+static void QuadraticPickSeeds(
+  Rtree *pRtree,
+  RtreeCell *aCell, 
+  int nCell, 
+  int *piLeftSeed, 
+  int *piRightSeed
+){
+  int ii;
+  int jj;
+
+  int iLeftSeed = 0;
+  int iRightSeed = 1;
+  float fWaste = 0.0;
+
+  for(ii=0; ii<nCell; ii++){
+    for(jj=ii+1; jj<nCell; jj++){
+      float right = cellArea(pRtree, &aCell[jj]);
+      float growth = cellGrowth(pRtree, &aCell[ii], &aCell[jj]);
+      float waste = growth - right;
+
+      if( waste>fWaste ){
+        iLeftSeed = ii;
+        iRightSeed = jj;
+        fWaste = waste;
+      }
+    }
+  }
+
+  *piLeftSeed = iLeftSeed;
+  *piRightSeed = iRightSeed;
+}
+#endif /* VARIANT_GUTTMAN_QUADRATIC_SPLIT */
+
+/*
+** Arguments aIdx, aDistance and aSpare all point to arrays of size
+** nIdx. The aIdx array contains the set of integers from 0 to 
+** (nIdx-1) in no particular order. This function sorts the values
+** in aIdx according to the indexed values in aDistance. For
+** example, assuming the inputs:
+**
+**   aIdx      = { 0,   1,   2,   3 }
+**   aDistance = { 5.0, 2.0, 7.0, 6.0 }
+**
+** this function sets the aIdx array to contain:
+**
+**   aIdx      = { 0,   1,   2,   3 }
+**
+** The aSpare array is used as temporary working space by the
+** sorting algorithm.
+*/
+static void SortByDistance(
+  int *aIdx, 
+  int nIdx, 
+  float *aDistance, 
+  int *aSpare
+){
+  if( nIdx>1 ){
+    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( iLeft<nLeft || iRight<nRight ){
+      if( iLeft==nLeft ){
+        aIdx[iLeft+iRight] = aRight[iRight];
+        iRight++;
+      }else if( iRight==nRight ){
+        aIdx[iLeft+iRight] = aLeft[iLeft];
+        iLeft++;
+      }else{
+        float fLeft = aDistance[aLeft[iLeft]];
+        float fRight = aDistance[aRight[iRight]];
+        if( fLeft<fRight ){
+          aIdx[iLeft+iRight] = aLeft[iLeft];
+          iLeft++;
+        }else{
+          aIdx[iLeft+iRight] = aRight[iRight];
+          iRight++;
+        }
+      }
+    }
+
+#if 0
+    /* Check that the sort worked */
+    {
+      int jj;
+      for(jj=1; jj<nIdx; jj++){
+        float left = aDistance[aIdx[jj-1]];
+        float right = aDistance[aIdx[jj]];
+        assert( left<=right );
+      }
+    }
+#endif
+  }
+}
+
+/*
+** Arguments aIdx, aCell and aSpare all point to arrays of size
+** nIdx. The aIdx array contains the set of integers from 0 to 
+** (nIdx-1) in no particular order. This function sorts the values
+** in aIdx according to dimension iDim of the cells in aCell. The
+** minimum value of dimension iDim is considered first, the
+** maximum used to break ties.
+**
+** The aSpare array is used as temporary working space by the
+** sorting algorithm.
+*/
+static void SortByDimension(
+  Rtree *pRtree,
+  int *aIdx, 
+  int nIdx, 
+  int iDim, 
+  RtreeCell *aCell, 
+  int *aSpare
+){
+  if( nIdx>1 ){
+
+    int iLeft = 0;
+    int iRight = 0;
+
+    int nLeft = nIdx/2;
+    int nRight = nIdx-nLeft;
+    int *aLeft = aIdx;
+    int *aRight = &aIdx[nLeft];
+
+    SortByDimension(pRtree, aLeft, nLeft, iDim, aCell, aSpare);
+    SortByDimension(pRtree, aRight, nRight, iDim, aCell, aSpare);
+
+    memcpy(aSpare, aLeft, sizeof(int)*nLeft);
+    aLeft = aSpare;
+    while( iLeft<nLeft || iRight<nRight ){
+      double xleft1 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2]);
+      double xleft2 = DCOORD(aCell[aLeft[iLeft]].aCoord[iDim*2+1]);
+      double xright1 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2]);
+      double xright2 = DCOORD(aCell[aRight[iRight]].aCoord[iDim*2+1]);
+      if( (iLeft!=nLeft) && ((iRight==nRight)
+       || (xleft1<xright1)
+       || (xleft1==xright1 && xleft2<xright2)
+      )){
+        aIdx[iLeft+iRight] = aLeft[iLeft];
+        iLeft++;
+      }else{
+        aIdx[iLeft+iRight] = aRight[iRight];
+        iRight++;
+      }
+    }
+
+#if 0
+    /* Check that the sort worked */
+    {
+      int jj;
+      for(jj=1; jj<nIdx; jj++){
+        float xleft1 = aCell[aIdx[jj-1]].aCoord[iDim*2];
+        float xleft2 = aCell[aIdx[jj-1]].aCoord[iDim*2+1];
+        float xright1 = aCell[aIdx[jj]].aCoord[iDim*2];
+        float xright2 = aCell[aIdx[jj]].aCoord[iDim*2+1];
+        assert( xleft1<=xright1 && (xleft1<xright1 || xleft2<=xright2) );
+      }
+    }
+#endif
+  }
+}
+
+#if VARIANT_RSTARTREE_SPLIT
+/*
+** Implementation of the R*-tree variant of SplitNode from Beckman[1990].
+*/
+static int splitNodeStartree(
+  Rtree *pRtree,
+  RtreeCell *aCell,
+  int nCell,
+  RtreeNode *pLeft,
+  RtreeNode *pRight,
+  RtreeCell *pBboxLeft,
+  RtreeCell *pBboxRight
+){
+  int **aaSorted;
+  int *aSpare;
+  int ii;
+
+  int iBestDim;
+  int iBestSplit;
+  float fBestMargin;
+
+  int nByte = (pRtree->nDim+1)*(sizeof(int*)+nCell*sizeof(int));
+
+  aaSorted = (int **)sqlite3_malloc(nByte);
+  if( !aaSorted ){
+    return SQLITE_NOMEM;
+  }
+
+  aSpare = &((int *)&aaSorted[pRtree->nDim])[pRtree->nDim*nCell];
+  memset(aaSorted, 0, nByte);
+  for(ii=0; ii<pRtree->nDim; ii++){
+    int jj;
+    aaSorted[ii] = &((int *)&aaSorted[pRtree->nDim])[ii*nCell];
+    for(jj=0; jj<nCell; jj++){
+      aaSorted[ii][jj] = jj;
+    }
+    SortByDimension(pRtree, aaSorted[ii], nCell, ii, aCell, aSpare);
+  }
+
+  for(ii=0; ii<pRtree->nDim; ii++){
+    float margin = 0.0;
+    float fBestOverlap;
+    float fBestArea;
+    int iBestLeft;
+    int nLeft;
+
+    for(
+      nLeft=RTREE_MINCELLS(pRtree); 
+      nLeft<=(nCell-RTREE_MINCELLS(pRtree)); 
+      nLeft++
+    ){
+      RtreeCell left;
+      RtreeCell right;
+      int kk;
+      float overlap;
+      float area;
+
+      memcpy(&left, &aCell[aaSorted[ii][0]], sizeof(RtreeCell));
+      memcpy(&right, &aCell[aaSorted[ii][nCell-1]], sizeof(RtreeCell));
+      for(kk=1; kk<(nCell-1); kk++){
+        if( kk<nLeft ){
+          cellUnion(pRtree, &left, &aCell[aaSorted[ii][kk]]);
+        }else{
+          cellUnion(pRtree, &right, &aCell[aaSorted[ii][kk]]);
+        }
+      }
+      margin += cellMargin(pRtree, &left);
+      margin += cellMargin(pRtree, &right);
+      overlap = cellOverlap(pRtree, &left, &right, 1, -1);
+      area = cellArea(pRtree, &left) + cellArea(pRtree, &right);
+      if( (nLeft==RTREE_MINCELLS(pRtree))
+       || (overlap<fBestOverlap)
+       || (overlap==fBestOverlap && area<fBestArea)
+      ){
+        iBestLeft = nLeft;
+        fBestOverlap = overlap;
+        fBestArea = area;
+      }
+    }
+
+    if( ii==0 || margin<fBestMargin ){
+      iBestDim = ii;
+      fBestMargin = margin;
+      iBestSplit = iBestLeft;
+    }
+  }
+
+  memcpy(pBboxLeft, &aCell[aaSorted[iBestDim][0]], sizeof(RtreeCell));
+  memcpy(pBboxRight, &aCell[aaSorted[iBestDim][iBestSplit]], sizeof(RtreeCell));
+  for(ii=0; ii<nCell; ii++){
+    RtreeNode *pTarget = (ii<iBestSplit)?pLeft:pRight;
+    RtreeCell *pBbox = (ii<iBestSplit)?pBboxLeft:pBboxRight;
+    RtreeCell *pCell = &aCell[aaSorted[iBestDim][ii]];
+    nodeInsertCell(pRtree, pTarget, pCell);
+    cellUnion(pRtree, pBbox, pCell);
+  }
+
+  sqlite3_free(aaSorted);
+  return SQLITE_OK;
+}
+#endif
+
+#if VARIANT_GUTTMAN_SPLIT
+/*
+** Implementation of the regular R-tree SplitNode from Guttman[1984].
+*/
+static int splitNodeGuttman(
+  Rtree *pRtree,
+  RtreeCell *aCell,
+  int nCell,
+  RtreeNode *pLeft,
+  RtreeNode *pRight,
+  RtreeCell *pBboxLeft,
+  RtreeCell *pBboxRight
+){
+  int iLeftSeed = 0;
+  int iRightSeed = 1;
+  int *aiUsed;
+  int i;
+
+  aiUsed = sqlite3_malloc(sizeof(int)*nCell);
+  memset(aiUsed, 0, sizeof(int)*nCell);
+
+  PickSeeds(pRtree, aCell, nCell, &iLeftSeed, &iRightSeed);
+
+  memcpy(pBboxLeft, &aCell[iLeftSeed], sizeof(RtreeCell));
+  memcpy(pBboxRight, &aCell[iRightSeed], sizeof(RtreeCell));
+  nodeInsertCell(pRtree, pLeft, &aCell[iLeftSeed]);
+  nodeInsertCell(pRtree, pRight, &aCell[iRightSeed]);
+  aiUsed[iLeftSeed] = 1;
+  aiUsed[iRightSeed] = 1;
+
+  for(i=nCell-2; i>0; i--){
+    RtreeCell *pNext;
+    pNext = PickNext(pRtree, aCell, nCell, pBboxLeft, pBboxRight, aiUsed);
+    float diff =  
+      cellGrowth(pRtree, pBboxLeft, pNext) - 
+      cellGrowth(pRtree, pBboxRight, pNext)
+    ;
+    if( (RTREE_MINCELLS(pRtree)-NCELL(pRight)==i)
+     || (diff>0.0 && (RTREE_MINCELLS(pRtree)-NCELL(pLeft)!=i))
+    ){
+      nodeInsertCell(pRtree, pRight, pNext);
+      cellUnion(pRtree, pBboxRight, pNext);
+    }else{
+      nodeInsertCell(pRtree, pLeft, pNext);
+      cellUnion(pRtree, pBboxLeft, pNext);
+    }
+  }
+
+  sqlite3_free(aiUsed);
+  return SQLITE_OK;
+}
+#endif
+
+static int updateMapping(
+  Rtree *pRtree, 
+  i64 iRowid, 
+  RtreeNode *pNode, 
+  int iHeight
+){
+  int (*xSetMapping)(Rtree *, sqlite3_int64, sqlite3_int64);
+  xSetMapping = ((iHeight==0)?rowidWrite:parentWrite);
+  if( iHeight>0 ){
+    RtreeNode *pChild = nodeHashLookup(pRtree, iRowid);
+    if( pChild ){
+      nodeRelease(pRtree, pChild->pParent);
+      nodeReference(pNode);
+      pChild->pParent = pNode;
+    }
+  }
+  return xSetMapping(pRtree, iRowid, pNode->iNode);
+}
+
+static int SplitNode(
+  Rtree *pRtree,
+  RtreeNode *pNode,
+  RtreeCell *pCell,
+  int iHeight
+){
+  int i;
+  int newCellIsRight = 0;
+
+  int rc = SQLITE_OK;
+  int nCell = NCELL(pNode);
+  RtreeCell *aCell;
+  int *aiUsed;
+
+  RtreeNode *pLeft = 0;
+  RtreeNode *pRight = 0;
+
+  RtreeCell leftbbox;
+  RtreeCell rightbbox;
+
+  /* Allocate an array and populate it with a copy of pCell and 
+  ** all cells from node pLeft. Then zero the original node.
+  */
+  aCell = sqlite3_malloc((sizeof(RtreeCell)+sizeof(int))*(nCell+1));
+  if( !aCell ){
+    rc = SQLITE_NOMEM;
+    goto splitnode_out;
+  }
+  aiUsed = (int *)&aCell[nCell+1];
+  memset(aiUsed, 0, sizeof(int)*(nCell+1));
+  for(i=0; i<nCell; i++){
+    nodeGetCell(pRtree, pNode, i, &aCell[i]);
+  }
+  nodeZero(pRtree, pNode);
+  memcpy(&aCell[nCell], pCell, sizeof(RtreeCell));
+  nCell++;
+
+  if( pNode->iNode==1 ){
+    pRight = nodeNew(pRtree, pNode, 1);
+    pLeft = nodeNew(pRtree, pNode, 1);
+    pRtree->iDepth++;
+    pNode->isDirty = 1;
+    writeInt16(pNode->zData, pRtree->iDepth);
+  }else{
+    pLeft = pNode;
+    pRight = nodeNew(pRtree, pLeft->pParent, 1);
+    nodeReference(pLeft);
+  }
+
+  if( !pLeft || !pRight ){
+    rc = SQLITE_NOMEM;
+    goto splitnode_out;
+  }
+
+  memset(pLeft->zData, 0, pRtree->iNodeSize);
+  memset(pRight->zData, 0, pRtree->iNodeSize);
+
+  rc = AssignCells(pRtree, aCell, nCell, pLeft, pRight, &leftbbox, &rightbbox);
+  if( rc!=SQLITE_OK ){
+    goto splitnode_out;
+  }
+
+  /* Ensure both child nodes have node numbers assigned to them. */
+  if( (0==pRight->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pRight)))
+   || (0==pLeft->iNode && SQLITE_OK!=(rc = nodeWrite(pRtree, pLeft)))
+  ){
+    goto splitnode_out;
+  }
+
+  rightbbox.iRowid = pRight->iNode;
+  leftbbox.iRowid = pLeft->iNode;
+
+  if( pNode->iNode==1 ){
+    rc = rtreeInsertCell(pRtree, pLeft->pParent, &leftbbox, iHeight+1);
+    if( rc!=SQLITE_OK ){
+      goto splitnode_out;
+    }
+  }else{
+    RtreeNode *pParent = pLeft->pParent;
+    int iCell = nodeParentIndex(pRtree, pLeft);
+    nodeOverwriteCell(pRtree, pParent, &leftbbox, iCell);
+    AdjustTree(pRtree, pParent, &leftbbox);
+  }
+  if( (rc = rtreeInsertCell(pRtree, pRight->pParent, &rightbbox, iHeight+1)) ){
+    goto splitnode_out;
+  }
+
+  for(i=0; i<NCELL(pRight); i++){
+    i64 iRowid = nodeGetRowid(pRtree, pRight, i);
+    rc = updateMapping(pRtree, iRowid, pRight, iHeight);
+    if( iRowid==pCell->iRowid ){
+      newCellIsRight = 1;
+    }
+    if( rc!=SQLITE_OK ){
+      goto splitnode_out;
+    }
+  }
+  if( pNode->iNode==1 ){
+    for(i=0; i<NCELL(pLeft); i++){
+      i64 iRowid = nodeGetRowid(pRtree, pLeft, i);
+      rc = updateMapping(pRtree, iRowid, pLeft, iHeight);
+      if( rc!=SQLITE_OK ){
+        goto splitnode_out;
+      }
+    }
+  }else if( newCellIsRight==0 ){
+    rc = updateMapping(pRtree, pCell->iRowid, pLeft, iHeight);
+  }
+
+  if( rc==SQLITE_OK ){
+    rc = nodeRelease(pRtree, pRight);
+    pRight = 0;
+  }
+  if( rc==SQLITE_OK ){
+    rc = nodeRelease(pRtree, pLeft);
+    pLeft = 0;
+  }
+
+splitnode_out:
+  nodeRelease(pRtree, pRight);
+  nodeRelease(pRtree, pLeft);
+  sqlite3_free(aCell);
+  return rc;
+}
+
+static int fixLeafParent(Rtree *pRtree, RtreeNode *pLeaf){
+  int rc = SQLITE_OK;
+  if( pLeaf->iNode!=1 && pLeaf->pParent==0 ){
+    sqlite3_bind_int64(pRtree->pReadParent, 1, pLeaf->iNode);
+    if( sqlite3_step(pRtree->pReadParent)==SQLITE_ROW ){
+      i64 iNode = sqlite3_column_int64(pRtree->pReadParent, 0);
+      rc = nodeAcquire(pRtree, iNode, 0, &pLeaf->pParent);
+    }else{
+      rc = SQLITE_ERROR;
+    }
+    sqlite3_reset(pRtree->pReadParent);
+    if( rc==SQLITE_OK ){
+      rc = fixLeafParent(pRtree, pLeaf->pParent);
+    }
+  }
+  return rc;
+}
+
+static int deleteCell(Rtree *, RtreeNode *, int, int);
+
+static int removeNode(Rtree *pRtree, RtreeNode *pNode, int iHeight){
+  int rc;
+  RtreeNode *pParent;
+  int iCell;
+
+  assert( pNode->nRef==1 );
+
+  /* Remove the entry in the parent cell. */
+  iCell = nodeParentIndex(pRtree, pNode);
+  pParent = pNode->pParent;
+  pNode->pParent = 0;
+  if( SQLITE_OK!=(rc = deleteCell(pRtree, pParent, iCell, iHeight+1)) 
+   || SQLITE_OK!=(rc = nodeRelease(pRtree, pParent))
+  ){
+    return rc;
+  }
+
+  /* Remove the xxx_node entry. */
+  sqlite3_bind_int64(pRtree->pDeleteNode, 1, pNode->iNode);
+  sqlite3_step(pRtree->pDeleteNode);
+  if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteNode)) ){
+    return rc;
+  }
+
+  /* Remove the xxx_parent entry. */
+  sqlite3_bind_int64(pRtree->pDeleteParent, 1, pNode->iNode);
+  sqlite3_step(pRtree->pDeleteParent);
+  if( SQLITE_OK!=(rc = sqlite3_reset(pRtree->pDeleteParent)) ){
+    return rc;
+  }
+  
+  /* Remove the node from the in-memory hash table and link it into
+  ** the Rtree.pDeleted list. Its contents will be re-inserted later on.
+  */
+  nodeHashDelete(pRtree, pNode);
+  pNode->iNode = iHeight;
+  pNode->pNext = pRtree->pDeleted;
+  pNode->nRef++;
+  pRtree->pDeleted = pNode;
+
+  return SQLITE_OK;
+}
+
+static void fixBoundingBox(Rtree *pRtree, RtreeNode *pNode){
+  RtreeNode *pParent = pNode->pParent;
+  if( pParent ){
+    int ii; 
+    int nCell = NCELL(pNode);
+    RtreeCell box;                            /* Bounding box for pNode */
+    nodeGetCell(pRtree, pNode, 0, &box);
+    for(ii=1; ii<nCell; ii++){
+      RtreeCell cell;
+      nodeGetCell(pRtree, pNode, ii, &cell);
+      cellUnion(pRtree, &box, &cell);
+    }
+    box.iRowid = pNode->iNode;
+    ii = nodeParentIndex(pRtree, pNode);
+    nodeOverwriteCell(pRtree, pParent, &box, ii);
+    fixBoundingBox(pRtree, pParent);
+  }
+}
+
+/*
+** Delete the cell at index iCell of node pNode. After removing the
+** cell, adjust the r-tree data structure if required.
+*/
+static int deleteCell(Rtree *pRtree, RtreeNode *pNode, int iCell, int iHeight){
+  int rc;
+
+  if( SQLITE_OK!=(rc = fixLeafParent(pRtree, pNode)) ){
+    return rc;
+  }
+
+  /* Remove the cell from the node. This call just moves bytes around
+  ** the in-memory node image, so it cannot fail.
+  */
+  nodeDeleteCell(pRtree, pNode, iCell);
+
+  /* If the node is not the tree root and now has less than the minimum
+  ** number of cells, remove it from the tree. Otherwise, update the
+  ** cell in the parent node so that it tightly contains the updated
+  ** node.
+  */
+  if( pNode->iNode!=1 ){
+    RtreeNode *pParent = pNode->pParent;
+    if( (pParent->iNode!=1 || NCELL(pParent)!=1) 
+     && (NCELL(pNode)<RTREE_MINCELLS(pRtree))
+    ){
+      rc = removeNode(pRtree, pNode, iHeight);
+    }else{
+      fixBoundingBox(pRtree, pNode);
+    }
+  }
+
+  return rc;
+}
+
+static int Reinsert(
+  Rtree *pRtree, 
+  RtreeNode *pNode, 
+  RtreeCell *pCell, 
+  int iHeight
+){
+  int *aOrder;
+  int *aSpare;
+  RtreeCell *aCell;
+  float *aDistance;
+  int nCell;
+  float aCenterCoord[RTREE_MAX_DIMENSIONS];
+  int iDim;
+  int ii;
+  int rc = SQLITE_OK;
+
+  memset(aCenterCoord, 0, sizeof(float)*RTREE_MAX_DIMENSIONS);
+
+  nCell = NCELL(pNode)+1;
+
+  /* Allocate the buffers used by this operation. The allocation is
+  ** relinquished before this function returns.
+  */
+  aCell = (RtreeCell *)sqlite3_malloc(nCell * (
+    sizeof(RtreeCell) +         /* aCell array */
+    sizeof(int)       +         /* aOrder array */
+    sizeof(int)       +         /* aSpare array */
+    sizeof(float)               /* aDistance array */
+  ));
+  if( !aCell ){
+    return SQLITE_NOMEM;
+  }
+  aOrder    = (int *)&aCell[nCell];
+  aSpare    = (int *)&aOrder[nCell];
+  aDistance = (float *)&aSpare[nCell];
+
+  for(ii=0; ii<nCell; ii++){
+    if( ii==(nCell-1) ){
+      memcpy(&aCell[ii], pCell, sizeof(RtreeCell));
+    }else{
+      nodeGetCell(pRtree, pNode, ii, &aCell[ii]);
+    }
+    aOrder[ii] = ii;
+    for(iDim=0; iDim<pRtree->nDim; iDim++){
+      aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2]);
+      aCenterCoord[iDim] += DCOORD(aCell[ii].aCoord[iDim*2+1]);
+    }
+  }
+  for(iDim=0; iDim<pRtree->nDim; iDim++){
+    aCenterCoord[iDim] = aCenterCoord[iDim]/((float)nCell*2.0);
+  }
+
+  for(ii=0; ii<nCell; ii++){
+    aDistance[ii] = 0.0;
+    for(iDim=0; iDim<pRtree->nDim; iDim++){
+      float 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 ){
+    fixBoundingBox(pRtree, pNode);
+  }
+  for(; rc==SQLITE_OK && ii<nCell; ii++){
+    /* Find a node to store this cell in. pNode->iNode 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).
+*/
+static int rtreeInsertCell(
+  Rtree *pRtree,
+  RtreeNode *pNode,
+  RtreeCell *pCell,
+  int iHeight
+){
+  int rc = SQLITE_OK;
+  if( iHeight>0 ){
+    RtreeNode *pChild = nodeHashLookup(pRtree, pCell->iRowid);
+    if( pChild ){
+      nodeRelease(pRtree, pChild->pParent);
+      nodeReference(pNode);
+      pChild->pParent = pNode;
+    }
+  }
+  if( nodeInsertCell(pRtree, pNode, pCell) ){
+#if VARIANT_RSTARTREE_REINSERT
+    if( iHeight<=pRtree->iReinsertHeight || pNode->iNode==1){
+      rc = SplitNode(pRtree, pNode, pCell, iHeight);
+    }else{
+      pRtree->iReinsertHeight = iHeight;
+      rc = Reinsert(pRtree, pNode, pCell, iHeight);
+    }
+#else
+    rc = SplitNode(pRtree, pNode, pCell, iHeight);
+#endif
+  }else{
+    AdjustTree(pRtree, pNode, pCell);
+    if( iHeight==0 ){
+      rc = rowidWrite(pRtree, pCell->iRowid, pNode->iNode);
+    }else{
+      rc = parentWrite(pRtree, pCell->iRowid, pNode->iNode);
+    }
+  }
+  return rc;
+}
+
+static int reinsertNodeContent(Rtree *pRtree, RtreeNode *pNode){
+  int ii;
+  int rc = SQLITE_OK;
+  int nCell = NCELL(pNode);
+
+  for(ii=0; rc==SQLITE_OK && ii<nCell; ii++){
+    RtreeNode *pInsert;
+    RtreeCell cell;
+    nodeGetCell(pRtree, pNode, ii, &cell);
+
+    /* Find a node to store this cell in. pNode->iNode currently contains
+    ** the height of the sub-tree headed by the cell.
+    */
+    rc = ChooseLeaf(pRtree, &cell, pNode->iNode, &pInsert);
+    if( rc==SQLITE_OK ){
+      int rc2;
+      rc = rtreeInsertCell(pRtree, pInsert, &cell, pNode->iNode);
+      rc2 = nodeRelease(pRtree, pInsert);
+      if( rc==SQLITE_OK ){
+        rc = rc2;
+      }
+    }
+  }
+  return rc;
+}
+
+/*
+** Select a currently unused rowid for a new r-tree record.
+*/
+static int newRowid(Rtree *pRtree, i64 *piRowid){
+  int rc;
+  sqlite3_bind_null(pRtree->pWriteRowid, 1);
+  sqlite3_bind_null(pRtree->pWriteRowid, 2);
+  sqlite3_step(pRtree->pWriteRowid);
+  rc = sqlite3_reset(pRtree->pWriteRowid);
+  *piRowid = sqlite3_last_insert_rowid(pRtree->db);
+  return rc;
+}
+
+#ifndef NDEBUG
+static int hashIsEmpty(Rtree *pRtree){
+  int ii;
+  for(ii=0; ii<HASHSIZE; ii++){
+    assert( !pRtree->aHash[ii] );
+  }
+  return 1;
+}
+#endif
+
+/*
+** The xUpdate method for rtree module virtual tables.
+*/
+int rtreeUpdate(
+  sqlite3_vtab *pVtab, 
+  int nData, 
+  sqlite3_value **azData, 
+  sqlite_int64 *pRowid
+){
+  Rtree *pRtree = (Rtree *)pVtab;
+  int rc = SQLITE_OK;
+
+  rtreeReference(pRtree);
+
+  assert(nData>=1);
+  assert(hashIsEmpty(pRtree));
+
+  /* If azData[0] is not an SQL NULL value, it is the rowid of a
+  ** record to delete from the r-tree table. The following block does
+  ** just that.
+  */
+  if( sqlite3_value_type(azData[0])!=SQLITE_NULL ){
+    i64 iDelete;                /* The rowid to delete */
+    RtreeNode *pLeaf;           /* Leaf node containing record iDelete */
+    int iCell;                  /* Index of iDelete cell in pLeaf */
+    RtreeNode *pRoot;
+
+    /* Obtain a reference to the root node to initialise Rtree.iDepth */
+    rc = nodeAcquire(pRtree, 1, 0, &pRoot);
+
+    /* Obtain a reference to the leaf node that contains the entry 
+    ** about to be deleted. 
+    */
+    if( rc==SQLITE_OK ){
+      iDelete = sqlite3_value_int64(azData[0]);
+      rc = findLeafNode(pRtree, iDelete, &pLeaf);
+    }
+
+    /* Delete the cell in question from the leaf node. */
+    if( rc==SQLITE_OK ){
+      int rc2;
+      iCell = nodeRowidIndex(pRtree, pLeaf, iDelete);
+      rc = deleteCell(pRtree, pLeaf, iCell, 0);
+      rc2 = nodeRelease(pRtree, pLeaf);
+      if( rc==SQLITE_OK ){
+        rc = rc2;
+      }
+    }
+
+    /* Delete the corresponding entry in the <rtree>_rowid table. */
+    if( rc==SQLITE_OK ){
+      sqlite3_bind_int64(pRtree->pDeleteRowid, 1, iDelete);
+      sqlite3_step(pRtree->pDeleteRowid);
+      rc = sqlite3_reset(pRtree->pDeleteRowid);
+    }
+
+    /* Check if the root node now has exactly one child. If so, remove
+    ** it, schedule the contents of the child for reinsertion and 
+    ** reduce the tree height by one.
+    **
+    ** This is equivalent to copying the contents of the child into
+    ** the root node (the operation that Gutman's paper says to perform 
+    ** in this scenario).
+    */
+    if( rc==SQLITE_OK && pRtree->iDepth>0 ){
+      if( rc==SQLITE_OK && NCELL(pRoot)==1 ){
+        RtreeNode *pChild;
+        i64 iChild = nodeGetRowid(pRtree, pRoot, 0);
+        rc = nodeAcquire(pRtree, iChild, pRoot, &pChild);
+        if( rc==SQLITE_OK ){
+          rc = removeNode(pRtree, pChild, pRtree->iDepth-1);
+        }
+        if( rc==SQLITE_OK ){
+          pRtree->iDepth--;
+          writeInt16(pRoot->zData, pRtree->iDepth);
+          pRoot->isDirty = 1;
+        }
+      }
+    }
+
+    /* Re-insert the contents of any underfull nodes removed from the tree. */
+    for(pLeaf=pRtree->pDeleted; pLeaf; pLeaf=pRtree->pDeleted){
+      if( rc==SQLITE_OK ){
+        rc = reinsertNodeContent(pRtree, pLeaf);
+      }
+      pRtree->pDeleted = pLeaf->pNext;
+      sqlite3_free(pLeaf);
+    }
+
+    /* Release the reference to the root node. */
+    if( rc==SQLITE_OK ){
+      rc = nodeRelease(pRtree, pRoot);
+    }else{
+      nodeRelease(pRtree, pRoot);
+    }
+  }
+
+  /* If the azData[] array contains more than one element, elements
+  ** (azData[2]..azData[argc-1]) contain a new record to insert into
+  ** the r-tree structure.
+  */
+  if( rc==SQLITE_OK && nData>1 ){
+    /* Insert a new record into the r-tree */
+    RtreeCell cell;
+    int ii;
+    RtreeNode *pLeaf;
+
+    /* Populate the cell.aCoord[] array. The first coordinate is azData[3]. */
+    assert( nData==(pRtree->nDim*2 + 3) );
+    if( pRtree->eCoordType==RTREE_COORD_REAL32 ){
+      for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+        cell.aCoord[ii].f = (float)sqlite3_value_double(azData[ii+3]);
+        cell.aCoord[ii+1].f = (float)sqlite3_value_double(azData[ii+4]);
+        if( cell.aCoord[ii].f>cell.aCoord[ii+1].f ){
+          rc = SQLITE_CONSTRAINT;
+          goto constraint;
+        }
+      }
+    }else{
+      for(ii=0; ii<(pRtree->nDim*2); ii+=2){
+        cell.aCoord[ii].i = sqlite3_value_int(azData[ii+3]);
+        cell.aCoord[ii+1].i = sqlite3_value_int(azData[ii+4]);
+        if( cell.aCoord[ii].i>cell.aCoord[ii+1].i ){
+          rc = SQLITE_CONSTRAINT;
+          goto constraint;
+        }
+      }
+    }
+
+    /* Figure out the rowid of the new row. */
+    if( sqlite3_value_type(azData[2])==SQLITE_NULL ){
+      rc = newRowid(pRtree, &cell.iRowid);
+    }else{
+      cell.iRowid = sqlite3_value_int64(azData[2]);
+      sqlite3_bind_int64(pRtree->pReadRowid, 1, cell.iRowid);
+      if( SQLITE_ROW==sqlite3_step(pRtree->pReadRowid) ){
+        sqlite3_reset(pRtree->pReadRowid);
+        rc = SQLITE_CONSTRAINT;
+        goto constraint;
+      }
+      rc = sqlite3_reset(pRtree->pReadRowid);
+    }
+
+    if( rc==SQLITE_OK ){
+      rc = ChooseLeaf(pRtree, &cell, 0, &pLeaf);
+    }
+    if( rc==SQLITE_OK ){
+      int rc2;
+      pRtree->iReinsertHeight = -1;
+      rc = rtreeInsertCell(pRtree, pLeaf, &cell, 0);
+      rc2 = nodeRelease(pRtree, pLeaf);
+      if( rc==SQLITE_OK ){
+        rc = rc2;
+      }
+    }
+  }
+
+constraint:
+  rtreeRelease(pRtree);
+  return rc;
+}
+
+/*
+** The xRename method for rtree module virtual tables.
+*/
+static int rtreeRename(sqlite3_vtab *pVtab, const char *zNewName){
+  Rtree *pRtree = (Rtree *)pVtab;
+  int rc = SQLITE_NOMEM;
+  char *zSql = sqlite3_mprintf(
+    "ALTER TABLE %Q.'%q_node'   RENAME TO \"%w_node\";"
+    "ALTER TABLE %Q.'%q_parent' RENAME TO \"%w_parent\";"
+    "ALTER TABLE %Q.'%q_rowid'  RENAME TO \"%w_rowid\";"
+    , pRtree->zDb, pRtree->zName, zNewName 
+    , pRtree->zDb, pRtree->zName, zNewName 
+    , pRtree->zDb, pRtree->zName, zNewName
+  );
+  if( zSql ){
+    rc = sqlite3_exec(pRtree->db, zSql, 0, 0, 0);
+    sqlite3_free(zSql);
+  }
+  return rc;
+}
+
+static sqlite3_module rtreeModule = {
+  0,                         /* iVersion */
+  rtreeCreate,                /* xCreate - create a table */
+  rtreeConnect,               /* xConnect - connect to an existing table */
+  rtreeBestIndex,             /* xBestIndex - Determine search strategy */
+  rtreeDisconnect,            /* xDisconnect - Disconnect from a table */
+  rtreeDestroy,               /* xDestroy - Drop a table */
+  rtreeOpen,                  /* xOpen - open a cursor */
+  rtreeClose,                 /* xClose - close a cursor */
+  rtreeFilter,                /* xFilter - configure scan constraints */
+  rtreeNext,                  /* xNext - advance a cursor */
+  rtreeEof,                   /* xEof */
+  rtreeColumn,                /* xColumn - read data */
+  rtreeRowid,                 /* xRowid - read data */
+  rtreeUpdate,                /* xUpdate - write data */
+  0,                          /* xBegin - begin transaction */
+  0,                          /* xSync - sync transaction */
+  0,                          /* xCommit - commit transaction */
+  0,                          /* xRollback - rollback transaction */
+  0,                          /* xFindFunction - function overloading */
+  rtreeRename                 /* xRename - rename the table */
+};
+
+static int rtreeSqlInit(
+  Rtree *pRtree, 
+  sqlite3 *db, 
+  const char *zDb, 
+  const char *zPrefix, 
+  int isCreate
+){
+  int rc = SQLITE_OK;
+
+  #define N_STATEMENT 9
+  static const char *azSql[N_STATEMENT] = {
+    /* Read and write the xxx_node table */
+    "SELECT data FROM '%q'.'%q_node' WHERE nodeno = :1",
+    "INSERT OR REPLACE INTO '%q'.'%q_node' VALUES(:1, :2)",
+    "DELETE FROM '%q'.'%q_node' WHERE nodeno = :1",
+
+    /* Read and write the xxx_rowid table */
+    "SELECT nodeno FROM '%q'.'%q_rowid' WHERE rowid = :1",
+    "INSERT OR REPLACE INTO '%q'.'%q_rowid' VALUES(:1, :2)",
+    "DELETE FROM '%q'.'%q_rowid' WHERE rowid = :1",
+
+    /* Read and write the xxx_parent table */
+    "SELECT parentnode FROM '%q'.'%q_parent' WHERE nodeno = :1",
+    "INSERT OR REPLACE INTO '%q'.'%q_parent' VALUES(:1, :2)",
+    "DELETE FROM '%q'.'%q_parent' WHERE nodeno = :1"
+  };
+  sqlite3_stmt **appStmt[N_STATEMENT];
+  int i;
+
+  pRtree->db = db;
+
+  if( isCreate ){
+    char *zCreate = sqlite3_mprintf(
+"CREATE TABLE \"%w\".\"%w_node\"(nodeno INTEGER PRIMARY KEY, data BLOB);"
+"CREATE TABLE \"%w\".\"%w_rowid\"(rowid INTEGER PRIMARY KEY, nodeno INTEGER);"
+"CREATE TABLE \"%w\".\"%w_parent\"(nodeno INTEGER PRIMARY KEY, parentnode INTEGER);"
+"INSERT INTO '%q'.'%q_node' VALUES(1, zeroblob(%d))",
+      zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, zDb, zPrefix, pRtree->iNodeSize
+    );
+    if( !zCreate ){
+      return SQLITE_NOMEM;
+    }
+    rc = sqlite3_exec(db, zCreate, 0, 0, 0);
+    sqlite3_free(zCreate);
+    if( rc!=SQLITE_OK ){
+      return rc;
+    }
+  }
+
+  appStmt[0] = &pRtree->pReadNode;
+  appStmt[1] = &pRtree->pWriteNode;
+  appStmt[2] = &pRtree->pDeleteNode;
+  appStmt[3] = &pRtree->pReadRowid;
+  appStmt[4] = &pRtree->pWriteRowid;
+  appStmt[5] = &pRtree->pDeleteRowid;
+  appStmt[6] = &pRtree->pReadParent;
+  appStmt[7] = &pRtree->pWriteParent;
+  appStmt[8] = &pRtree->pDeleteParent;
+
+  for(i=0; i<N_STATEMENT && rc==SQLITE_OK; i++){
+    char *zSql = sqlite3_mprintf(azSql[i], zDb, zPrefix);
+    if( zSql ){
+      rc = sqlite3_prepare_v2(db, zSql, -1, appStmt[i], 0); 
+    }else{
+      rc = SQLITE_NOMEM;
+    }
+    sqlite3_free(zSql);
+  }
+
+  return rc;
+}
+
+/*
+** This routine queries database handle db for the page-size used by
+** database zDb. If successful, the page-size in bytes is written to
+** *piPageSize and SQLITE_OK returned. Otherwise, and an SQLite error 
+** code is returned.
+*/
+static int getPageSize(sqlite3 *db, const char *zDb, int *piPageSize){
+  int rc = SQLITE_NOMEM;
+  char *zSql;
+  sqlite3_stmt *pStmt = 0;
+
+  zSql = sqlite3_mprintf("PRAGMA %Q.page_size", zDb);
+  if( !zSql ){
+    return SQLITE_NOMEM;
+  }
+
+  rc = sqlite3_prepare_v2(db, zSql, -1, &pStmt, 0);
+  sqlite3_free(zSql);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+
+  if( SQLITE_ROW==sqlite3_step(pStmt) ){
+    *piPageSize = sqlite3_column_int(pStmt, 0);
+  }
+  return sqlite3_finalize(pStmt);
+}
+
+/* 
+** This function is the implementation of both the xConnect and xCreate
+** methods of the r-tree virtual table.
+**
+**   argv[0]   -> module name
+**   argv[1]   -> database name
+**   argv[2]   -> table name
+**   argv[...] -> column names...
+*/
+static int rtreeInit(
+  sqlite3 *db,                        /* Database connection */
+  void *pAux,                         /* Pointer to head of rtree list */
+  int argc, const char *const*argv,   /* Parameters to CREATE TABLE statement */
+  sqlite3_vtab **ppVtab,              /* OUT: New virtual table */
+  char **pzErr,                       /* OUT: Error message, if any */
+  int isCreate,                       /* True for xCreate, false for xConnect */
+  int eCoordType                      /* One of the RTREE_COORD_* constants */
+){
+  int rc = SQLITE_OK;
+  int iPageSize = 0;
+  Rtree *pRtree;
+  int nDb;              /* Length of string argv[1] */
+  int nName;            /* Length of string argv[2] */
+
+  const char *aErrMsg[] = {
+    0,                                                    /* 0 */
+    "Wrong number of columns for an rtree table",         /* 1 */
+    "Too few columns for an rtree table",                 /* 2 */
+    "Too many columns for an rtree table"                 /* 3 */
+  };
+
+  int iErr = (argc<6) ? 2 : argc>(RTREE_MAX_DIMENSIONS*2+4) ? 3 : argc%2;
+  if( aErrMsg[iErr] ){
+    *pzErr = sqlite3_mprintf("%s", aErrMsg[iErr]);
+    return SQLITE_ERROR;
+  }
+
+  rc = getPageSize(db, argv[1], &iPageSize);
+  if( rc!=SQLITE_OK ){
+    return rc;
+  }
+
+  /* Allocate the sqlite3_vtab structure */
+  nDb = strlen(argv[1]);
+  nName = strlen(argv[2]);
+  pRtree = (Rtree *)sqlite3_malloc(sizeof(Rtree)+nDb+nName+2);
+  if( !pRtree ){
+    return SQLITE_NOMEM;
+  }
+  memset(pRtree, 0, sizeof(Rtree)+nDb+nName+2);
+  pRtree->nBusy = 1;
+  pRtree->base.pModule = &rtreeModule;
+  pRtree->zDb = (char *)&pRtree[1];
+  pRtree->zName = &pRtree->zDb[nDb+1];
+  pRtree->nDim = (argc-4)/2;
+  pRtree->nBytesPerCell = 8 + pRtree->nDim*4*2;
+  pRtree->eCoordType = eCoordType;
+  memcpy(pRtree->zDb, argv[1], nDb);
+  memcpy(pRtree->zName, argv[2], nName);
+
+  /* Figure out the node size to use. By default, use 64 bytes less than
+  ** the database page-size. This ensures that each node is stored on
+  ** a single database page.
+  **
+  ** If the databasd page-size is so large that more than RTREE_MAXCELLS
+  ** entries would fit in a single node, use a smaller node-size.
+  */
+  pRtree->iNodeSize = iPageSize-64;
+  if( (4+pRtree->nBytesPerCell*RTREE_MAXCELLS)<pRtree->iNodeSize ){
+    pRtree->iNodeSize = 4+pRtree->nBytesPerCell*RTREE_MAXCELLS;
+  }
+
+  /* Create/Connect to the underlying relational database schema. If
+  ** that is successful, call sqlite3_declare_vtab() to configure
+  ** the r-tree table schema.
+  */
+  if( (rc = rtreeSqlInit(pRtree, db, argv[1], argv[2], isCreate)) ){
+    *pzErr = sqlite3_mprintf("%s", sqlite3_errmsg(db));
+  }else{
+    char *zSql = sqlite3_mprintf("CREATE TABLE x(%s", argv[3]);
+    char *zTmp;
+    int ii;
+    for(ii=4; zSql && ii<argc; ii++){
+      zTmp = zSql;
+      zSql = sqlite3_mprintf("%s, %s", zTmp, argv[ii]);
+      sqlite3_free(zTmp);
+    }
+    if( zSql ){
+      zTmp = zSql;
+      zSql = sqlite3_mprintf("%s);", zTmp);
+      sqlite3_free(zTmp);
+    }
+    if( !zSql || sqlite3_declare_vtab(db, zSql) ){
+      rc = SQLITE_NOMEM;
+    }
+    sqlite3_free(zSql);
+  }
+
+  if( rc==SQLITE_OK ){
+    *ppVtab = (sqlite3_vtab *)pRtree;
+  }else{
+    rtreeRelease(pRtree);
+  }
+  return rc;
+}
+
+
+/*
+** Implementation of a scalar function that decodes r-tree nodes to
+** human readable strings. This can be used for debugging and analysis.
+**
+** The scalar function takes two arguments, a blob of data containing
+** an r-tree node, and the number of dimensions the r-tree indexes.
+** For a two-dimensional r-tree structure called "rt", to deserialize
+** all nodes, a statement like:
+**
+**   SELECT rtreenode(2, data) FROM rt_node;
+**
+** The human readable string takes the form of a Tcl list with one
+** entry for each cell in the r-tree node. Each entry is itself a
+** list, containing the 8-byte rowid/pageno followed by the 
+** <num-dimension>*2 coordinates.
+*/
+static void rtreenode(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
+  char *zText = 0;
+  RtreeNode node;
+  Rtree tree;
+  int ii;
+
+  memset(&node, 0, sizeof(RtreeNode));
+  memset(&tree, 0, sizeof(Rtree));
+  tree.nDim = sqlite3_value_int(apArg[0]);
+  tree.nBytesPerCell = 8 + 8 * tree.nDim;
+  node.zData = (u8 *)sqlite3_value_blob(apArg[1]);
+
+  for(ii=0; ii<NCELL(&node); ii++){
+    char zCell[512];
+    int nCell = 0;
+    RtreeCell cell;
+    int jj;
+
+    nodeGetCell(&tree, &node, ii, &cell);
+    sqlite3_snprintf(512-nCell,&zCell[nCell],"%d", cell.iRowid);
+    nCell = strlen(zCell);
+    for(jj=0; jj<tree.nDim*2; jj++){
+      sqlite3_snprintf(512-nCell,&zCell[nCell]," %f",(double)cell.aCoord[jj].f);
+      nCell = strlen(zCell);
+    }
+
+    if( zText ){
+      char *zTextNew = sqlite3_mprintf("%s {%s}", zText, zCell);
+      sqlite3_free(zText);
+      zText = zTextNew;
+    }else{
+      zText = sqlite3_mprintf("{%s}", zCell);
+    }
+  }
+  
+  sqlite3_result_text(ctx, zText, -1, sqlite3_free);
+}
+
+static void rtreedepth(sqlite3_context *ctx, int nArg, sqlite3_value **apArg){
+  if( sqlite3_value_type(apArg[0])!=SQLITE_BLOB 
+   || sqlite3_value_bytes(apArg[0])<2
+  ){
+    sqlite3_result_error(ctx, "Invalid argument to rtreedepth()", -1); 
+  }else{
+    u8 *zBlob = (u8 *)sqlite3_value_blob(apArg[0]);
+    sqlite3_result_int(ctx, readInt16(zBlob));
+  }
+}
+
+/*
+** Register the r-tree module with database handle db. This creates the
+** virtual table module "rtree" and the debugging/analysis scalar 
+** function "rtreenode".
+*/
+SQLITE_PRIVATE int sqlite3RtreeInit(sqlite3 *db){
+  int rc = SQLITE_OK;
+
+  if( rc==SQLITE_OK ){
+    int utf8 = SQLITE_UTF8;
+    rc = sqlite3_create_function(db, "rtreenode", 2, utf8, 0, rtreenode, 0, 0);
+  }
+  if( rc==SQLITE_OK ){
+    int utf8 = SQLITE_UTF8;
+    rc = sqlite3_create_function(db, "rtreedepth", 1, utf8, 0,rtreedepth, 0, 0);
+  }
+  if( rc==SQLITE_OK ){
+    void *c = (void *)RTREE_COORD_REAL32;
+    rc = sqlite3_create_module_v2(db, "rtree", &rtreeModule, c, 0);
+  }
+  if( rc==SQLITE_OK ){
+    void *c = (void *)RTREE_COORD_INT32;
+    rc = sqlite3_create_module_v2(db, "rtree_i32", &rtreeModule, c, 0);
+  }
+
+  return rc;
+}
+
+#if !SQLITE_CORE
+SQLITE_API int sqlite3_extension_init(
+  sqlite3 *db,
+  char **pzErrMsg,
+  const sqlite3_api_routines *pApi
+){
+  SQLITE_EXTENSION_INIT2(pApi)
+  return sqlite3RtreeInit(db);
+}
+#endif
+
+#endif
+
+/************** End of rtree.c ***********************************************/

Modified: trunk/libgda/sqlite/sqlite-src/sqlite3.h
==============================================================================
--- trunk/libgda/sqlite/sqlite-src/sqlite3.h	(original)
+++ trunk/libgda/sqlite/sqlite-src/sqlite3.h	Sun Jul 27 19:25:27 2008
@@ -17,7 +17,7 @@
 **
 ** Some of the definitions that are in this file are marked as
 ** "experimental".  Experimental interfaces are normally new
-** features recently added to SQLite.  We do not anticipate changes 
+** features recently added to SQLite.  We do not anticipate changes
 ** to experimental interfaces but reserve to make minor changes if
 ** experience from use "in the wild" suggest such changes are prudent.
 **
@@ -52,8 +52,7 @@
 #endif
 
 /*
-** Make sure these symbols where not defined by some previous header
-** file.
+** Ensure these symbols were not defined by some previous header file.
 */
 #ifdef SQLITE_VERSION
 # undef SQLITE_VERSION
@@ -72,29 +71,28 @@
 ** The "version" of SQLite is a string of the form "X.Y.Z".
 ** The phrase "alpha" or "beta" might be appended after the Z.
 ** The X value is major version number always 3 in SQLite3.
-** The X value only changes when  backwards compatibility is
-** broken and we intend to never break
-** backwards compatibility.  The Y value is the minor version
-** number and only changes when
+** The X value only changes when backwards compatibility is
+** broken and we intend to never break backwards compatibility.
+** The Y value is the minor version number and only changes when
 ** there are major feature enhancements that are forwards compatible
-** but not backwards compatible.  The Z value is release number
-** and is incremented with
-** each release but resets back to 0 when Y is incremented.
+** but not backwards compatible.
+** The Z value is the release number and is incremented with
+** each release but resets back to 0 whenever Y is incremented.
 **
 ** See also: [sqlite3_libversion()] and [sqlite3_libversion_number()].
 **
 ** INVARIANTS:
 **
-** {F10011} The SQLITE_VERSION #define in the sqlite3.h header file
-**          evaluates to a string literal that is the SQLite version
+** {F10011} The SQLITE_VERSION #define in the sqlite3.h header file shall
+**          evaluate to a string literal that is the SQLite version
 **          with which the header file is associated.
 **
-** {F10014} The SQLITE_VERSION_NUMBER #define resolves to an integer
-**          with the value  (X*1000000 + Y*1000 + Z) where X, Y, and
-**          Z are the major version, minor version, and release number.
+** {F10014} The SQLITE_VERSION_NUMBER #define shall resolve to an integer
+**          with the value (X*1000000 + Y*1000 + Z) where X, Y, and Z
+**          are the major version, minor version, and release number.
 */
-#define SQLITE_VERSION         "3.5.9"
-#define SQLITE_VERSION_NUMBER  3005009
+#define SQLITE_VERSION         "3.6.0"
+#define SQLITE_VERSION_NUMBER  3006000
 
 /*
 ** CAPI3REF: Run-Time Library Version Numbers {F10020}
@@ -103,8 +101,8 @@
 ** These features provide the same information as the [SQLITE_VERSION]
 ** and [SQLITE_VERSION_NUMBER] #defines in the header, but are associated
 ** with the library instead of the header file.  Cautious programmers might
-** include a check in their application to verify that 
-** sqlite3_libversion_number() always returns the value 
+** include a check in their application to verify that
+** sqlite3_libversion_number() always returns the value
 ** [SQLITE_VERSION_NUMBER].
 **
 ** The sqlite3_libversion() function returns the same information as is
@@ -114,13 +112,13 @@
 **
 ** INVARIANTS:
 **
-** {F10021} The [sqlite3_libversion_number()] interface returns an integer
-**          equal to [SQLITE_VERSION_NUMBER]. 
+** {F10021} The [sqlite3_libversion_number()] interface shall return
+**          an integer equal to [SQLITE_VERSION_NUMBER].
 **
-** {F10022} The [sqlite3_version] string constant contains the text of the
-**          [SQLITE_VERSION] string. 
+** {F10022} The [sqlite3_version] string constant shall contain
+**          the text of the [SQLITE_VERSION] string.
 **
-** {F10023} The [sqlite3_libversion()] function returns
+** {F10023} The [sqlite3_libversion()] function shall return
 **          a pointer to the [sqlite3_version] string constant.
 */
 SQLITE_EXTERN const char sqlite3_version[];
@@ -131,25 +129,42 @@
 ** CAPI3REF: Test To See If The Library Is Threadsafe {F10100}
 **
 ** SQLite can be compiled with or without mutexes.  When
-** the SQLITE_THREADSAFE C preprocessor macro is true, mutexes
+** the [SQLITE_THREADSAFE] C preprocessor macro is true, mutexes
 ** are enabled and SQLite is threadsafe.  When that macro is false,
 ** the mutexes are omitted.  Without the mutexes, it is not safe
-** to use SQLite from more than one thread.
+** to use SQLite concurrently from more than one thread.
 **
-** There is a measurable performance penalty for enabling mutexes.
+** Enabling mutexes incurs a measurable performance penalty.
 ** So if speed is of utmost importance, it makes sense to disable
 ** the mutexes.  But for maximum safety, mutexes should be enabled.
 ** The default behavior is for mutexes to be enabled.
 **
 ** This interface can be used by a program to make sure that the
 ** version of SQLite that it is linking against was compiled with
-** the desired setting of the SQLITE_THREADSAFE macro.
+** the desired setting of the [SQLITE_THREADSAFE] macro.
+**
+** This interface only reports on the compile-time mutex setting
+** of the [SQLITE_THREADSAFE] flag.  If SQLite is compiled with
+** SQLITE_THREADSAFE=1 then mutexes are enabled by default but
+** can be fully or partially disabled using a call to [sqlite3_config()]
+** with the verbs [SQLITE_CONFIG_SINGLETHREAD], [SQLITE_CONFIG_MULTITHREAD],
+** or [SQLITE_CONFIG_MUTEX].  The return value of this function shows
+** only the default compile-time setting, not any run-time changes
+** to that setting.
 **
 ** INVARIANTS:
 **
-** {F10101} The [sqlite3_threadsafe()] function returns nonzero if
-**          SQLite was compiled with its mutexes enabled or zero
-**          if SQLite was compiled with mutexes disabled.
+** {F10101} The [sqlite3_threadsafe()] function shall return nonzero if
+**          SQLite was compiled with the its mutexes enabled by default
+**          or zero if SQLite was compiled such that mutexes are
+**          permanently disabled.
+**
+** {F10102} The value returned by the [sqlite3_threadsafe()] function
+**          shall not change when mutex setting are modified at
+**          runtime using the [sqlite3_config()] interface and 
+**          especially the [SQLITE_CONFIG_SINGLETHREAD],
+**          [SQLITE_CONFIG_MULTITHREAD], [SQLITE_CONFIG_SERIALIZED],
+**          and [SQLITE_CONFIG_MUTEX] verbs.
 */
 int sqlite3_threadsafe(void);
 
@@ -157,18 +172,17 @@
 ** CAPI3REF: Database Connection Handle {F12000}
 ** KEYWORDS: {database connection} {database connections}
 **
-** Each open SQLite database is represented by pointer to an instance of the
-** opaque structure named "sqlite3".  It is useful to think of an sqlite3
+** Each open SQLite database is represented by a pointer to an instance of
+** the opaque structure named "sqlite3".  It is useful to think of an sqlite3
 ** pointer as an object.  The [sqlite3_open()], [sqlite3_open16()], and
-** [sqlite3_open_v2()] interfaces are its constructors
-** and [sqlite3_close()] is its destructor.  There are many other interfaces
-** (such as [sqlite3_prepare_v2()], [sqlite3_create_function()], and
-** [sqlite3_busy_timeout()] to name but three) that are methods on this
-** object.
+** [sqlite3_open_v2()] interfaces are its constructors, and [sqlite3_close()]
+** is its destructor.  There are many other interfaces (such as
+** [sqlite3_prepare_v2()], [sqlite3_create_function()], and
+** [sqlite3_busy_timeout()] to name but three) that are methods on an
+** sqlite3 object.
 */
 typedef struct sqlite3 sqlite3;
 
-
 /*
 ** CAPI3REF: 64-Bit Integer Types {F10200}
 ** KEYWORDS: sqlite_int64 sqlite_uint64
@@ -176,16 +190,16 @@
 ** Because there is no cross-platform way to specify 64-bit integer types
 ** SQLite includes typedefs for 64-bit signed and unsigned integers.
 **
-** The sqlite3_int64 and sqlite3_uint64 are the preferred type
-** definitions.  The sqlite_int64 and sqlite_uint64 types are
-** supported for backwards compatibility only.
+** The sqlite3_int64 and sqlite3_uint64 are the preferred type definitions.
+** The sqlite_int64 and sqlite_uint64 types are supported for backwards
+** compatibility only.
 **
 ** INVARIANTS:
 **
-** {F10201} The [sqlite_int64] and [sqlite3_int64] types specify a
-**          64-bit signed integer.
+** {F10201} The [sqlite_int64] and [sqlite3_int64] type shall specify
+**          a 64-bit signed integer.
 **
-** {F10202} The [sqlite_uint64] and [sqlite3_uint64] types specify
+** {F10202} The [sqlite_uint64] and [sqlite3_uint64] type shall specify
 **          a 64-bit unsigned integer.
 */
 #ifdef SQLITE_INT64_TYPE
@@ -203,7 +217,7 @@
 
 /*
 ** If compiling for a processor that lacks floating point support,
-** substitute integer for floating-point
+** substitute integer for floating-point.
 */
 #ifdef SQLITE_OMIT_FLOATING_POINT
 # define double sqlite3_int64
@@ -212,41 +226,53 @@
 /*
 ** CAPI3REF: Closing A Database Connection {F12010}
 **
-** This routine is the destructor for the [sqlite3] object.  
+** This routine is the destructor for the [sqlite3] object.
 **
-** Applications should [sqlite3_finalize | finalize] all
-** [prepared statements] and
-** [sqlite3_blob_close | close] all [sqlite3_blob | BLOBs] 
-** associated with the [sqlite3] object prior
-** to attempting to close the [sqlite3] object.
+** Applications should [sqlite3_finalize | finalize] all [prepared statements]
+** and [sqlite3_blob_close | close] all [BLOB handles] associated with
+** the [sqlite3] object prior to attempting to close the object.
+** The [sqlite3_next_stmt()] interface can be used to locate all
+** [prepared statements] associated with a [database connection] if desired.
+** Typical code might look like this:
 **
-** <todo>What happens to pending transactions?  Are they
-** rolled back, or abandoned?</todo>
+** <blockquote><pre>
+** sqlite3_stmt *pStmt;
+** while( (pStmt = sqlite3_next_stmt(db, 0))!=0 ){
+** &nbsp;   sqlite3_finalize(pStmt);
+** }
+** </pre></blockquote>
+**
+** If [sqlite3_close()] is invoked while a transaction is open,
+** the transaction is automatically rolled back.
 **
 ** INVARIANTS:
 **
-** {F12011} The [sqlite3_close()] interface destroys an [sqlite3] object
-**          allocated by a prior call to [sqlite3_open()],
-**          [sqlite3_open16()], or [sqlite3_open_v2()].
+** {F12011} A successful call to [sqlite3_close(C)] shall destroy the
+**          [database connection] object C.
 **
-** {F12012} The [sqlite3_close()] function releases all memory used by the
-**          connection and closes all open files.
+** {F12012} A successful call to [sqlite3_close(C)] shall return SQLITE_OK.
 **
-** {F12013} If the database connection contains
-**          [prepared statements] that have not been
-**          finalized by [sqlite3_finalize()], then [sqlite3_close()]
-**          returns [SQLITE_BUSY] and leaves the connection open.
+** {F12013} A successful call to [sqlite3_close(C)] shall release all
+**          memory and system resources associated with [database connection]
+**          C.
 **
-** {F12014} Giving sqlite3_close() a NULL pointer is a harmless no-op.
+** {F12014} A call to [sqlite3_close(C)] on a [database connection] C that
+**          has one or more open [prepared statements] shall fail with
+**          an [SQLITE_BUSY] error code.
+**
+** {F12015} A call to [sqlite3_close(C)] where C is a NULL pointer shall
+**          return SQLITE_OK.
+**
+** {F12019} When [sqlite3_close(C)] is invoked on a [database connection] C
+**          that has a pending transaction, the transaction shall be
+**          rolled back.
 **
 ** LIMITATIONS:
 **
-** {U12015} The parameter to [sqlite3_close()] must be an [sqlite3] object
-**          pointer previously obtained from [sqlite3_open()] or the 
-**          equivalent, or NULL.
-**
-** {U12016} The parameter to [sqlite3_close()] must not have been previously
-**          closed.
+** {A12016} The C parameter to [sqlite3_close(C)] must be either a NULL
+**          pointer or an [sqlite3] object pointer previously obtained
+**          from [sqlite3_open()], [sqlite3_open16()], or
+**          [sqlite3_open_v2()], and not previously closed.
 */
 int sqlite3_close(sqlite3 *);
 
@@ -260,101 +286,112 @@
 /*
 ** CAPI3REF: One-Step Query Execution Interface {F12100}
 **
-** The sqlite3_exec() interface is a convenient way of running
-** one or more SQL statements without a lot of C code.  The
-** SQL statements are passed in as the second parameter to
-** sqlite3_exec().  The statements are evaluated one by one
-** until either an error or an interrupt is encountered or
-** until they are all done.  The 3rd parameter is an optional
-** callback that is invoked once for each row of any query results
-** produced by the SQL statements.  The 5th parameter tells where
+** The sqlite3_exec() interface is a convenient way of running one or more
+** SQL statements without having to write a lot of C code.  The UTF-8 encoded
+** SQL statements are passed in as the second parameter to sqlite3_exec().
+** The statements are evaluated one by one until either an error or
+** an interrupt is encountered, or until they are all done.  The 3rd parameter
+** is an optional callback that is invoked once for each row of any query
+** results produced by the SQL statements.  The 5th parameter tells where
 ** to write any error messages.
 **
+** The error message passed back through the 5th parameter is held
+** in memory obtained from [sqlite3_malloc()].  To avoid a memory leak,
+** the calling application should call [sqlite3_free()] on any error
+** message returned through the 5th parameter when it has finished using
+** the error message.
+**
+** If the SQL statement in the 2nd parameter is NULL or an empty string
+** or a string containing only whitespace and comments, then no SQL
+** statements are evaluated and the database is not changed.
+**
 ** The sqlite3_exec() interface is implemented in terms of
 ** [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-** The sqlite3_exec() routine does nothing that cannot be done
+** The sqlite3_exec() routine does nothing to the database that cannot be done
 ** by [sqlite3_prepare_v2()], [sqlite3_step()], and [sqlite3_finalize()].
-** The sqlite3_exec() is just a convenient wrapper.
 **
 ** INVARIANTS:
-** 
-** {F12101} The [sqlite3_exec()] interface evaluates zero or more UTF-8
-**          encoded, semicolon-separated, SQL statements in the
-**          zero-terminated string of its 2nd parameter within the
-**          context of the [sqlite3] object given in the 1st parameter.
 **
-** {F12104} The return value of [sqlite3_exec()] is SQLITE_OK if all
-**          SQL statements run successfully.
+** {F12101} A successful invocation of [sqlite3_exec(D,S,C,A,E)]
+**          shall sequentially evaluate all of the UTF-8 encoded,
+**          semicolon-separated SQL statements in the zero-terminated
+**          string S within the context of the [database connection] D.
+**
+** {F12102} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL then
+**          the actions of the interface shall be the same as if the
+**          S parameter were an empty string.
+**
+** {F12104} The return value of [sqlite3_exec()] shall be [SQLITE_OK] if all
+**          SQL statements run successfully and to completion.
 **
-** {F12105} The return value of [sqlite3_exec()] is an appropriate 
-**          non-zero error code if any SQL statement fails.
+** {F12105} The return value of [sqlite3_exec()] shall be an appropriate
+**          non-zero [error code] if any SQL statement fails.
 **
 ** {F12107} If one or more of the SQL statements handed to [sqlite3_exec()]
 **          return results and the 3rd parameter is not NULL, then
-**          the callback function specified by the 3rd parameter is
+**          the callback function specified by the 3rd parameter shall be
 **          invoked once for each row of result.
 **
 ** {F12110} If the callback returns a non-zero value then [sqlite3_exec()]
-**          will aborted the SQL statement it is currently evaluating,
+**          shall abort the SQL statement it is currently evaluating,
 **          skip all subsequent SQL statements, and return [SQLITE_ABORT].
-**          <todo>What happens to *errmsg here?  Does the result code for
-**          sqlite3_errcode() get set?</todo>
 **
-** {F12113} The [sqlite3_exec()] routine will pass its 4th parameter through
+** {F12113} The [sqlite3_exec()] routine shall pass its 4th parameter through
 **          as the 1st parameter of the callback.
 **
-** {F12116} The [sqlite3_exec()] routine sets the 2nd parameter of its
+** {F12116} The [sqlite3_exec()] routine shall set the 2nd parameter of its
 **          callback to be the number of columns in the current row of
 **          result.
 **
-** {F12119} The [sqlite3_exec()] routine sets the 3rd parameter of its 
+** {F12119} The [sqlite3_exec()] routine shall set the 3rd parameter of its
 **          callback to be an array of pointers to strings holding the
 **          values for each column in the current result set row as
 **          obtained from [sqlite3_column_text()].
 **
-** {F12122} The [sqlite3_exec()] routine sets the 4th parameter of its
+** {F12122} The [sqlite3_exec()] routine shall set the 4th parameter of its
 **          callback to be an array of pointers to strings holding the
 **          names of result columns as obtained from [sqlite3_column_name()].
 **
 ** {F12125} If the 3rd parameter to [sqlite3_exec()] is NULL then
-**          [sqlite3_exec()] never invokes a callback.  All query
-**          results are silently discarded.
-**
-** {F12128} If an error occurs while parsing or evaluating any of the SQL
-**          statements handed to [sqlite3_exec()] then [sqlite3_exec()] will
-**          return an [error code] other than [SQLITE_OK].
+**          [sqlite3_exec()] shall silently discard query results.
 **
 ** {F12131} If an error occurs while parsing or evaluating any of the SQL
-**          handed to [sqlite3_exec()] and if the 5th parameter (errmsg)
-**          to [sqlite3_exec()] is not NULL, then an error message is
-**          allocated using the equivalent of [sqlite3_mprintf()] and
-**          *errmsg is made to point to that message.
-**
-** {F12134} The [sqlite3_exec()] routine does not change the value of
-**          *errmsg if errmsg is NULL or if there are no errors.
-**
-** {F12137} The [sqlite3_exec()] function sets the error code and message
-**          accessible via [sqlite3_errcode()], [sqlite3_errmsg()], and
-**          [sqlite3_errmsg16()].
+**          statements in the S parameter of [sqlite3_exec(D,S,C,A,E)] and if
+**          the E parameter is not NULL, then [sqlite3_exec()] shall store
+**          in *E an appropriate error message written into memory obtained
+**          from [sqlite3_malloc()].
+**
+** {F12134} The [sqlite3_exec(D,S,C,A,E)] routine shall set the value of
+**          *E to NULL if E is not NULL and there are no errors.
+**
+** {F12137} The [sqlite3_exec(D,S,C,A,E)] function shall set the [error code]
+**          and message accessible via [sqlite3_errcode()],
+**          [sqlite3_errmsg()], and [sqlite3_errmsg16()].
+**
+** {F12138} If the S parameter to [sqlite3_exec(D,S,C,A,E)] is NULL or an
+**          empty string or contains nothing other than whitespace, comments,
+**          and/or semicolons, then results of [sqlite3_errcode()],
+**          [sqlite3_errmsg()], and [sqlite3_errmsg16()]
+**          shall reset to indicate no errors.
 **
 ** LIMITATIONS:
 **
-** {U12141} The first parameter to [sqlite3_exec()] must be an valid and open
+** {A12141} The first parameter to [sqlite3_exec()] must be an valid and open
 **          [database connection].
 **
-** {U12142} The database connection must not be closed while
+** {A12142} The database connection must not be closed while
 **          [sqlite3_exec()] is running.
-** 
-** {U12143} The calling function is should use [sqlite3_free()] to free
+**
+** {A12143} The calling function should use [sqlite3_free()] to free
 **          the memory that *errmsg is left pointing at once the error
 **          message is no longer needed.
 **
-** {U12145} The SQL statement text in the 2nd parameter to [sqlite3_exec()]
+** {A12145} The SQL statement text in the 2nd parameter to [sqlite3_exec()]
 **          must remain unchanged while [sqlite3_exec()] is running.
 */
 int sqlite3_exec(
   sqlite3*,                                  /* An open database */
-  const char *sql,                           /* SQL to be evaluted */
+  const char *sql,                           /* SQL to be evaluated */
   int (*callback)(void*,int,char**,char**),  /* Callback function */
   void *,                                    /* 1st argument to callback */
   char **errmsg                              /* Error msg written here */
@@ -363,10 +400,13 @@
 /*
 ** CAPI3REF: Result Codes {F10210}
 ** KEYWORDS: SQLITE_OK {error code} {error codes}
+** KEYWORDS: {result code} {result codes}
 **
 ** Many SQLite functions return an integer result code from the set shown
 ** here in order to indicates success or failure.
 **
+** New error codes may be added in future versions of SQLite.
+**
 ** See also: [SQLITE_IOERR_READ | extended result codes]
 */
 #define SQLITE_OK           0   /* Successful result */
@@ -404,18 +444,18 @@
 /*
 ** CAPI3REF: Extended Result Codes {F10220}
 ** KEYWORDS: {extended error code} {extended error codes}
-** KEYWORDS: {extended result codes}
+** KEYWORDS: {extended result code} {extended result codes}
 **
 ** In its default configuration, SQLite API routines return one of 26 integer
-** [SQLITE_OK | result codes].  However, experience has shown that
-** many of these result codes are too course-grained.  They do not provide as
+** [SQLITE_OK | result codes].  However, experience has shown that many of
+** these result codes are too coarse-grained.  They do not provide as
 ** much information about problems as programmers might like.  In an effort to
 ** address this, newer versions of SQLite (version 3.3.8 and later) include
 ** support for additional result codes that provide more detailed information
 ** about errors. The extended result codes are enabled or disabled
-** for each database connection using the [sqlite3_extended_result_codes()]
-** API.
-** 
+** on a per database connection basis using the
+** [sqlite3_extended_result_codes()] API.
+**
 ** Some of the available extended result codes are listed here.
 ** One may expect the number of extended result codes will be expand
 ** over time.  Software that uses extended result codes should expect
@@ -423,32 +463,34 @@
 **
 ** The SQLITE_OK result code will never be extended.  It will always
 ** be exactly zero.
-** 
+**
 ** INVARIANTS:
 **
-** {F10223} The symbolic name for an extended result code always contains
+** {F10223} The symbolic name for an extended result code shall contains
 **          a related primary result code as a prefix.
 **
-** {F10224} Primary result code names contain a single "_" character.
+** {F10224} Primary result code names shall contain a single "_" character.
 **
-** {F10225} Extended result code names contain two or more "_" characters.
+** {F10225} Extended result code names shall contain two or more "_" characters.
 **
-** {F10226} The numeric value of an extended result code contains the
+** {F10226} The numeric value of an extended result code shall contain the
 **          numeric value of its corresponding primary result code in
 **          its least significant 8 bits.
 */
-#define SQLITE_IOERR_READ          (SQLITE_IOERR | (1<<8))
-#define SQLITE_IOERR_SHORT_READ    (SQLITE_IOERR | (2<<8))
-#define SQLITE_IOERR_WRITE         (SQLITE_IOERR | (3<<8))
-#define SQLITE_IOERR_FSYNC         (SQLITE_IOERR | (4<<8))
-#define SQLITE_IOERR_DIR_FSYNC     (SQLITE_IOERR | (5<<8))
-#define SQLITE_IOERR_TRUNCATE      (SQLITE_IOERR | (6<<8))
-#define SQLITE_IOERR_FSTAT         (SQLITE_IOERR | (7<<8))
-#define SQLITE_IOERR_UNLOCK        (SQLITE_IOERR | (8<<8))
-#define SQLITE_IOERR_RDLOCK        (SQLITE_IOERR | (9<<8))
-#define SQLITE_IOERR_DELETE        (SQLITE_IOERR | (10<<8))
-#define SQLITE_IOERR_BLOCKED       (SQLITE_IOERR | (11<<8))
-#define SQLITE_IOERR_NOMEM         (SQLITE_IOERR | (12<<8))
+#define SQLITE_IOERR_READ              (SQLITE_IOERR | (1<<8))
+#define SQLITE_IOERR_SHORT_READ        (SQLITE_IOERR | (2<<8))
+#define SQLITE_IOERR_WRITE             (SQLITE_IOERR | (3<<8))
+#define SQLITE_IOERR_FSYNC             (SQLITE_IOERR | (4<<8))
+#define SQLITE_IOERR_DIR_FSYNC         (SQLITE_IOERR | (5<<8))
+#define SQLITE_IOERR_TRUNCATE          (SQLITE_IOERR | (6<<8))
+#define SQLITE_IOERR_FSTAT             (SQLITE_IOERR | (7<<8))
+#define SQLITE_IOERR_UNLOCK            (SQLITE_IOERR | (8<<8))
+#define SQLITE_IOERR_RDLOCK            (SQLITE_IOERR | (9<<8))
+#define SQLITE_IOERR_DELETE            (SQLITE_IOERR | (10<<8))
+#define SQLITE_IOERR_BLOCKED           (SQLITE_IOERR | (11<<8))
+#define SQLITE_IOERR_NOMEM             (SQLITE_IOERR | (12<<8))
+#define SQLITE_IOERR_ACCESS            (SQLITE_IOERR | (13<<8))
+#define SQLITE_IOERR_CHECKRESERVEDLOCK (SQLITE_IOERR | (14<<8))
 
 /*
 ** CAPI3REF: Flags For File Open Operations {F10230}
@@ -470,6 +512,7 @@
 #define SQLITE_OPEN_TEMP_JOURNAL     0x00001000
 #define SQLITE_OPEN_SUBJOURNAL       0x00002000
 #define SQLITE_OPEN_MASTER_JOURNAL   0x00004000
+#define SQLITE_OPEN_NOMUTEX          0x00008000
 
 /*
 ** CAPI3REF: Device Characteristics {F10240}
@@ -525,15 +568,14 @@
 **
 ** When the SQLITE_SYNC_DATAONLY flag is used, it means that the
 ** sync operation only needs to flush data to mass storage.  Inode
-** information need not be flushed. The SQLITE_SYNC_NORMAL flag means 
-** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means 
+** information need not be flushed. The SQLITE_SYNC_NORMAL flag means
+** to use normal fsync() semantics. The SQLITE_SYNC_FULL flag means
 ** to use Mac OS-X style fullsync instead of fsync().
 */
 #define SQLITE_SYNC_NORMAL        0x00002
 #define SQLITE_SYNC_FULL          0x00003
 #define SQLITE_SYNC_DATAONLY      0x00010
 
-
 /*
 ** CAPI3REF: OS Interface Open File Handle {F11110}
 **
@@ -552,17 +594,18 @@
 /*
 ** CAPI3REF: OS Interface File Virtual Methods Object {F11120}
 **
-** Every file opened by the [sqlite3_vfs] xOpen method contains a pointer to
-** an instance of this object.  This object defines the
-** methods used to perform various operations against the open file.
+** Every file opened by the [sqlite3_vfs] xOpen method populates an
+** [sqlite3_file] object (or, more commonly, a subclass of the
+** [sqlite3_file] object) with a pointer to an instance of this object.
+** This object defines the methods used to perform various operations
+** against the open file represented by the [sqlite3_file] object.
 **
 ** The flags argument to xSync may be one of [SQLITE_SYNC_NORMAL] or
 ** [SQLITE_SYNC_FULL].  The first choice is the normal fsync().
-*  The second choice is an
-** OS-X style fullsync.  The SQLITE_SYNC_DATA flag may be ORed in to
-** indicate that only the data of the file and not its inode needs to be
-** synced.
-** 
+** The second choice is a Mac OS-X style fullsync.  The [SQLITE_SYNC_DATAONLY]
+** flag may be ORed in to indicate that only the data of the file
+** and not its inode needs to be synced.
+**
 ** The integer values to xLock() and xUnlock() are one of
 ** <ul>
 ** <li> [SQLITE_LOCK_NONE],
@@ -571,26 +614,24 @@
 ** <li> [SQLITE_LOCK_PENDING], or
 ** <li> [SQLITE_LOCK_EXCLUSIVE].
 ** </ul>
-** xLock() increases the lock. xUnlock() decreases the lock.  
-** The xCheckReservedLock() method looks
-** to see if any database connection, either in this
-** process or in some other process, is holding an RESERVED,
+** 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
-** if such a lock exists and false if not.
-** 
+** if such a lock exists and false otherwise.
+**
 ** The xFileControl() method is a generic interface that allows custom
 ** VFS implementations to directly control an open file using the
-** [sqlite3_file_control()] interface.  The second "op" argument
-** is an integer opcode.   The third
-** argument is a generic pointer which is intended to be a pointer
-** to a structure that may contain arguments or space in which to
+** [sqlite3_file_control()] interface.  The second "op" argument is an
+** integer opcode.  The third argument is a generic pointer intended to
+** point to a structure that may contain arguments or space in which to
 ** write return values.  Potential uses for xFileControl() might be
 ** functions to enable blocking locks with timeouts, to change the
 ** locking strategy (for example to use dot-file locks), to inquire
 ** about the status of a lock, or to break stale locks.  The SQLite
-** core reserves opcodes less than 100 for its own use. 
+** core reserves all opcodes less than 100 for its own use.
 ** A [SQLITE_FCNTL_LOCKSTATE | list of opcodes] less than 100 is available.
-** Applications that define a custom xFileControl method should use opcodes 
+** Applications that define a custom xFileControl method should use opcodes
 ** greater than 100 to avoid conflicts.
 **
 ** The xSectorSize() method returns the sector size of the
@@ -636,7 +677,7 @@
   int (*xFileSize)(sqlite3_file*, sqlite3_int64 *pSize);
   int (*xLock)(sqlite3_file*, int);
   int (*xUnlock)(sqlite3_file*, int);
-  int (*xCheckReservedLock)(sqlite3_file*);
+  int (*xCheckReservedLock)(sqlite3_file*, int *pResOut);
   int (*xFileControl)(sqlite3_file*, int op, void *pArg);
   int (*xSectorSize)(sqlite3_file*);
   int (*xDeviceCharacteristics)(sqlite3_file*);
@@ -647,7 +688,7 @@
 ** CAPI3REF: Standard File Control Opcodes {F11310}
 **
 ** These integer constants are opcodes for the xFileControl method
-** of the [sqlite3_io_methods] object and to the [sqlite3_file_control()]
+** of the [sqlite3_io_methods] object and for the [sqlite3_file_control()]
 ** interface.
 **
 ** The [SQLITE_FCNTL_LOCKSTATE] opcode is used for debugging.  This
@@ -675,13 +716,16 @@
 /*
 ** CAPI3REF: OS Interface Object {F11140}
 **
-** An instance of this object defines the interface between the
-** SQLite core and the underlying operating system.  The "vfs"
+** An instance of the sqlite3_vfs object defines the interface between
+** the SQLite core and the underlying operating system.  The "vfs"
 ** in the name of the object stands for "virtual file system".
 **
-** The iVersion field is initially 1 but may be larger for future
-** versions of SQLite.  Additional fields may be appended to this
-** object when the iVersion value is increased.
+** The value of the iVersion field is initially 1 but may be larger in
+** future versions of SQLite.  Additional fields may be appended to this
+** object when the iVersion value is increased.  Note that the structure
+** of the sqlite3_vfs object changes in the transaction between
+** SQLite version 3.5.9 and 3.6.0 and yet the iVersion field was not
+** modified.
 **
 ** The szOsFile field is the size of the subclassed [sqlite3_file]
 ** structure used by this VFS.  mxPathname is the maximum length of
@@ -691,9 +735,10 @@
 ** the pNext pointer.  The [sqlite3_vfs_register()]
 ** and [sqlite3_vfs_unregister()] interfaces manage this list
 ** in a thread-safe way.  The [sqlite3_vfs_find()] interface
-** searches the list.
+** searches the list.  Neither the application code nor the VFS
+** implementation should use the pNext pointer.
 **
-** The pNext field is the only field in the sqlite3_vfs 
+** The pNext field is the only field in the sqlite3_vfs
 ** structure that SQLite will ever modify.  SQLite will only access
 ** or modify this field while holding a particular static mutex.
 ** The application should never modify anything within the sqlite3_vfs
@@ -702,23 +747,28 @@
 ** The zName field holds the name of the VFS module.  The name must
 ** be unique across all VFS modules.
 **
-** {F11141} SQLite will guarantee that the zFilename string passed to
-** xOpen() is a full pathname as generated by xFullPathname() and
-** that the string will be valid and unchanged until xClose() is
-** called.  {END} So the [sqlite3_file] can store a pointer to the
+** {F11141} SQLite will guarantee that the zFilename parameter to xOpen
+** is either a NULL pointer or string obtained
+** from xFullPathname().  SQLite further guarantees that
+** the string will be valid and unchanged until xClose() is
+** called. {END}  Becasue of the previous sentense, 
+** the [sqlite3_file] can safely store a pointer to the
 ** filename if it needs to remember the filename for some reason.
+** If the zFilename parameter is xOpen is a NULL pointer then xOpen
+** must invite its own temporary name for the file.  Whenever the 
+** xFilename parameter is NULL it will also be the case that the
+** flags parameter will include [SQLITE_OPEN_DELETEONCLOSE].
 **
 ** {F11142} The flags argument to xOpen() includes all bits set in
 ** the flags argument to [sqlite3_open_v2()].  Or if [sqlite3_open()]
 ** or [sqlite3_open16()] is used, then flags includes at least
 ** [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]. {END}
 ** If xOpen() opens a file read-only then it sets *pOutFlags to
-** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be
-** set.
-** 
+** include [SQLITE_OPEN_READONLY].  Other bits in *pOutFlags may be set.
+**
 ** {F11143} SQLite will also add one of the following flags to the xOpen()
 ** call, depending on the object being opened:
-** 
+**
 ** <ul>
 ** <li>  [SQLITE_OPEN_MAIN_DB]
 ** <li>  [SQLITE_OPEN_MAIN_JOURNAL]
@@ -730,59 +780,56 @@
 ** </ul> {END}
 **
 ** The file I/O implementation can use the object type flags to
-** changes the way it deals with files.  For example, an application
+** change the way it deals with files.  For example, an application
 ** that does not care about crash recovery or rollback might make
 ** the open of a journal file a no-op.  Writes to this journal would
-** also be no-ops, and any attempt to read the journal would return 
-** SQLITE_IOERR.  Or the implementation might recognize that a database 
-** file will be doing page-aligned sector reads and writes in a random 
+** also be no-ops, and any attempt to read the journal would return
+** SQLITE_IOERR.  Or the implementation might recognize that a database
+** file will be doing page-aligned sector reads and writes in a random
 ** order and set up its I/O subsystem accordingly.
-** 
-** SQLite might also add one of the following flags to the xOpen
-** method:
-** 
+**
+** SQLite might also add one of the following flags to the xOpen method:
+**
 ** <ul>
 ** <li> [SQLITE_OPEN_DELETEONCLOSE]
 ** <li> [SQLITE_OPEN_EXCLUSIVE]
 ** </ul>
-** 
+**
 ** {F11145} The [SQLITE_OPEN_DELETEONCLOSE] flag means the file should be
 ** deleted when it is closed.  {F11146} The [SQLITE_OPEN_DELETEONCLOSE]
-** will be set for TEMP  databases, journals and for subjournals. 
+** will be set for TEMP  databases, journals and for subjournals.
+**
 ** {F11147} The [SQLITE_OPEN_EXCLUSIVE] flag means the file should be opened
 ** for exclusive access.  This flag is set for all files except
-** for the main database file. {END}
-** 
-** {F11148} At least szOsFile bytes of memory are allocated by SQLite 
-** to hold the  [sqlite3_file] structure passed as the third 
-** argument to xOpen.  {END}  The xOpen method does not have to
+** for the main database file.
+**
+** {F11148} At least szOsFile bytes of memory are allocated by SQLite
+** to hold the  [sqlite3_file] structure passed as the third
+** argument to xOpen. {END}  The xOpen method does not have to
 ** allocate the structure; it should just fill it in.
-** 
-** {F11149} The flags argument to xAccess() may be [SQLITE_ACCESS_EXISTS] 
-** to test for the existance of a file,
-** or [SQLITE_ACCESS_READWRITE] to test to see
-** if a file is readable and writable, or [SQLITE_ACCESS_READ]
-** to test to see if a file is at least readable.  {END} The file can be a 
+**
+** {F11149} 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. {END}  The file can be a
 ** directory.
-** 
-** {F11150} SQLite will always allocate at least mxPathname+1 bytes for
-** the output buffers for xGetTempname and xFullPathname. {F11151} The exact
-** size of the output buffer is also passed as a parameter to both 
-** methods. {END} If the output buffer is not large enough, SQLITE_CANTOPEN
-** should be returned. As this is handled as a fatal error by SQLite,
-** vfs implementations should endeavor to prevent this by setting 
-** mxPathname to a sufficiently large value.
-** 
+**
+** {F11150} SQLite will always allocate at least mxPathname+1 bytes for the
+** output buffer xFullPathname. {F11151} The exact size of the output buffer
+** is also passed as a parameter to both  methods. {END}  If the output buffer
+** is not large enough, [SQLITE_CANTOPEN] should be returned. Since this is
+** handled as a fatal error by SQLite, vfs implementations should endeavor
+** to prevent this by setting mxPathname to a sufficiently large value.
+**
 ** The xRandomness(), xSleep(), and xCurrentTime() interfaces
 ** are not strictly a part of the filesystem, but they are
 ** included in the VFS structure for completeness.
 ** The xRandomness() function attempts to return nBytes bytes
 ** of good-quality randomness into zOut.  The return value is
-** the actual number of bytes of randomness obtained.  The
-** xSleep() method causes the calling thread to sleep for at
+** the actual number of bytes of randomness obtained.
+** The xSleep() method causes the calling thread to sleep for at
 ** least the number of microseconds given.  The xCurrentTime()
-** method returns a Julian Day Number for the current date and
-** time.
+** method returns a Julian Day Number for the current date and time.
 */
 typedef struct sqlite3_vfs sqlite3_vfs;
 struct sqlite3_vfs {
@@ -795,8 +842,7 @@
   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 (*xGetTempname)(sqlite3_vfs*, int nOut, char *zOut);
+  int (*xAccess)(sqlite3_vfs*, const char *zName, int flags, int *pResOut);
   int (*xFullPathname)(sqlite3_vfs*, const char *zName, int nOut, char *zOut);
   void *(*xDlOpen)(sqlite3_vfs*, const char *zFilename);
   void (*xDlError)(sqlite3_vfs*, int nByte, char *zErrMsg);
@@ -805,6 +851,7 @@
   int (*xRandomness)(sqlite3_vfs*, int nByte, char *zOut);
   int (*xSleep)(sqlite3_vfs*, int microseconds);
   int (*xCurrentTime)(sqlite3_vfs*, double*);
+  int (*xGetLastError)(sqlite3_vfs*, int, char *);
   /* New fields may be appended in figure versions.  The iVersion
   ** value will increment whenever this happens. */
 };
@@ -814,36 +861,319 @@
 **
 ** {F11191} These integer constants can be used as the third parameter to
 ** the xAccess method of an [sqlite3_vfs] object. {END}  They determine
-** what kind of permissions the xAccess method is
-** looking for.  {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method
-** simply checks to see if the file exists. {F11193} With
-** SQLITE_ACCESS_READWRITE, the xAccess method checks to see
-** if the file is both readable and writable.  {F11194} With
-** SQLITE_ACCESS_READ the xAccess method
-** checks to see if the file is readable.
+** what kind of permissions the xAccess method is looking for.
+** {F11192} With SQLITE_ACCESS_EXISTS, the xAccess method
+** simply checks whether the file exists.
+** {F11193} With SQLITE_ACCESS_READWRITE, the xAccess method
+** checks whether the file is both readable and writable.
+** {F11194} With SQLITE_ACCESS_READ, the xAccess method
+** checks whether the file is readable.
 */
 #define SQLITE_ACCESS_EXISTS    0
 #define SQLITE_ACCESS_READWRITE 1
 #define SQLITE_ACCESS_READ      2
 
 /*
+** CAPI3REF: Initialize The SQLite Library {F10130}
+**
+** The sqlite3_initialize() routine initializes the
+** SQLite library.  The sqlite3_shutdown() routine
+** deallocates any resources that were allocated by sqlite3_initialize().
+**
+** A call to sqlite3_initialize() is an "effective" call if it is
+** the first time sqlite3_initialize() is invoked during the lifetime of
+** the process, or if it is the first time sqlite3_initialize() is invoked
+** following a call to sqlite3_shutdown().  Only an effective call
+** of sqlite3_initialize() does any initialization.  All other calls
+** are harmless no-ops.
+**
+** Among other things, sqlite3_initialize() shall invoke
+** sqlite3_os_init().  Similarly, sqlite3_shutdown()
+** shall invoke sqlite3_os_end().
+**
+** The sqlite3_initialize() routine returns SQLITE_OK on success.
+** 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.
+**
+** 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.  For example, [sqlite3_open()]
+** calls sqlite3_initialize() so the SQLite library will be automatically
+** initialized when [sqlite3_open()] is called if it has not be initialized
+** already.  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.  For maximum portability,
+** it is recommended that applications always invoke sqlite3_initialize()
+** directly prior to using any other SQLite interface.  Future releases
+** of SQLite may require this.  In other words, the behavior exhibited
+** when SQLite is compiled with SQLITE_OMIT_AUTOINIT might become the
+** default behavior in some future release of SQLite.
+**
+** The sqlite3_os_init() routine does operating-system specific
+** initialization of the SQLite library.  The sqlite3_os_end()
+** routine undoes the effect of sqlite3_os_init().  Typical tasks
+** performed by these routines include allocation or deallocation
+** of static resources, initialization of global variables,
+** setting up a default [sqlite3_vfs] module, or setting up
+** a default configuration using [sqlite3_config()].
+**
+** The application should never invoke either sqlite3_os_init()
+** or sqlite3_os_end() directly.  The application should only invoke
+** sqlite3_initialize() and sqlite3_shutdown().  The sqlite3_os_init()
+** interface is called automatically by sqlite3_initialize() and
+** sqlite3_os_end() is called by sqlite3_shutdown().  Appropriate
+** implementations for sqlite3_os_init() and sqlite3_os_end()
+** are built into SQLite when it is compiled for unix, windows, or os/2.
+** When built for other platforms (using the SQLITE_OS_OTHER=1 compile-time
+** option) the application must supply a suitable implementation for
+** sqlite3_os_init() and sqlite3_os_end().  An application-supplied
+** implementation of sqlite3_os_init() or sqlite3_os_end()
+** must return SQLITE_OK on success and some other [error code] upon
+** failure.
+*/
+int sqlite3_initialize(void);
+int sqlite3_shutdown(void);
+int sqlite3_os_init(void);
+int sqlite3_os_end(void);
+
+/*
+** CAPI3REF: Configuring The SQLite Library {F10145}
+**
+** The sqlite3_config() interface is used to make global configuration
+** changes to SQLite in order to tune SQLite to the specific needs of
+** the application.  The default configuration is recommended for most
+** applications and so this routine is usually not necessary.  It is
+** provided to support rare applications with unusual needs.
+**
+** The sqlite3_config() interface is not threadsafe.  The application
+** must insure that no other SQLite interfaces are invoked by other
+** threads while sqlite3_config() is running.  Furthermore, sqlite3_config()
+** may only be invoked prior to library initialization using
+** [sqlite3_initialize()] or after shutdown by [sqlite3_shutdown()].
+** 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
+** [SQLITE_CONFIG_SINGLETHREAD | configuration option] that determines
+** what property of SQLite is to be configured.  Subsequent arguments
+** vary depending on the [SQLITE_CONFIG_SINGLETHREAD | 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].
+**
+** The sqlite3_config() interface is considered experimental in that
+** new configuration options may be added in future releases and existing
+** configuration options may be discontinued or modified.
+*/
+int sqlite3_config(int, ...);
+
+/*
+** CAPI3REF: Memory Allocation Routines {F10155}
+**
+** An instance of this object defines the interface between SQLite
+** and low-level memory allocation routines.
+**
+** This object is used in only one place in the SQLite interface.
+** A pointer to an instance of this object is the argument to
+** [sqlite3_config()] when the configuration option is
+** [SQLITE_CONFIG_MALLOC].  By creating an instance of this object
+** and passing it to [sqlite3_config()] during configuration, an
+** application can specify an alternative memory allocation subsystem
+** for SQLite to use for all of its dynamic memory needs.
+**
+** Note that SQLite comes with a built-in memory allocator that is
+** perfectly adequate for the overwhelming majority of applications
+** and that this object is only useful to a tiny minority of applications
+** with specialized memory allocation requirements.  This object is
+** also used during testing of SQLite in order to specify an alternative
+** memory allocator that simulates memory out-of-memory conditions in
+** order to verify that SQLite recovers gracefully from such
+** conditions.
+**
+** The xMalloc, xFree, and xRealloc methods must work like the
+** malloc(), free(), and realloc() functions from the standard library.
+**
+** xSize should return the allocated size of a memory allocation
+** previously obtained from xMalloc or xRealloc.  The allocated size
+** is always at least as big as the requested size but may be larger.
+**
+** The xRoundup method returns what would be the allocated size of
+** a memory allocation given a particular requested size.  Most memory
+** 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.
+**
+** The xInit method initializes the memory allocator.  (For example,
+** it might allocate any require mutexes or initialize internal data
+** structures.  The xShutdown method is invoked (indirectly) by
+** [sqlite3_shutdown()] and should deallocate any resources acquired
+** by xInit.  The pAppData pointer is used as the only parameter to
+** xInit and xShutdown.
+*/
+typedef struct sqlite3_mem_methods sqlite3_mem_methods;
+struct sqlite3_mem_methods {
+  void *(*xMalloc)(int);         /* Memory allocation function */
+  void (*xFree)(void*);          /* Free a prior allocation */
+  void *(*xRealloc)(void*,int);  /* Resize an allocation */
+  int (*xSize)(void*);           /* Return the size of an allocation */
+  int (*xRoundup)(int);          /* Round up request size to allocation size */
+  int (*xInit)(void*);           /* Initialize the memory allocator */
+  void (*xShutdown)(void*);      /* Deinitialize the memory allocator */
+  void *pAppData;                /* Argument to xInit() and xShutdown() */
+};
+
+/*
+** CAPI3REF: Configuration Options {F10160}
+**
+** These constants are the available integer configuration options that
+** can be passed as the first argument to the [sqlite3_config()] interface.
+**
+** 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
+** the call worked.  The [sqlite3_config()] interface will return a
+** non-zero [error code] if a discontinued or unsupported configuration option
+** is invoked.
+**
+** <dl>
+** <dt>SQLITE_CONFIG_SINGLETHREAD</dt>
+** <dd>There are no arguments to this option.  This option disables
+** all mutexing and puts SQLite into a mode where it can only be used
+** by a single thread.</dd>
+**
+** <dt>SQLITE_CONFIG_MULTITHREAD</dt>
+** <dd>There are no arguments to this option.  This option disables
+** mutexing on [database connection] and [prepared statement] objects.
+** The application is responsible for serializing access to
+** [database connections] and [prepared statements].  But other mutexes
+** are enabled so that SQLite will be safe to use in a multi-threaded
+** environment.</dd>
+**
+** <dt>SQLITE_CONFIG_SERIALIZED</dt>
+** <dd>There are no arguments to this option.  This option enables
+** all mutexes including the recursive
+** mutexes on [database connection] and [prepared statement] objects.
+** In this mode (which is the default when SQLite is compiled with
+** [SQLITE_THREADSAFE=1]) the SQLite library will itself serialize access
+** to [database connections] and [prepared statements] so that the
+** application is free to use the same [database connection] or the
+** same [prepared statement] in different threads at the same time.
+**
+** <p>This configuration option merely sets the default mutex 
+** behavior to serialize access to [database connections].  Individual
+** [database connections] can override this setting
+** using the [SQLITE_OPEN_NOMUTEX] flag to [sqlite3_open_v2()].</p></dd>
+**
+** <dt>SQLITE_CONFIG_MALLOC</dt>
+** <dd>This 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.</dd>
+**
+** <dt>SQLITE_CONFIG_GETMALLOC</dt>
+** <dd>This 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.
+** This option can be used to overload the default memory allocation
+** routines with a wrapper that simulations memory allocation failure or
+** tracks memory usage, for example.</dd>
+**
+** <dt>SQLITE_CONFIG_MEMSTATUS</dt>
+** <dd>This option takes single boolean argument which enables or disables
+** the collection of memory allocation statistics.  When disabled, the
+** following SQLite interfaces become non-operational:
+**   <ul>
+**   <li> [sqlite3_memory_used()]
+**   <li> [sqlite3_memory_highwater()]
+**   <li> [sqlite3_soft_heap_limit()]
+**   <li> sqlite3_memory_status()
+**   </ul>
+** </dd>
+**
+** <dt>SQLITE_CONFIG_SCRATCH</dt>
+** <dd>This option specifies a static memory buffer that SQLite can use for
+** scratch memory.  There are three arguments:  A pointer to the memory, the
+** size of each scratch buffer (sz), and the number of buffers (N).  The sz
+** argument must be a multiple of 16. The first
+** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** SQLite will use no more than one scratch buffer at once per thread, so
+** N should be set to the expected maximum number of threads.  The sz
+** parameter should be 6 times the size of the largest database page size.
+** Scratch buffers are used as part of the btree balance operation.  If
+** The btree balancer needs additional memory beyond what is provided by
+** scratch buffers or if no scratch buffer space is specified, then SQLite
+** goes to [sqlite3_malloc()] to obtain the memory it needs.</dd>
+**
+** <dt>SQLITE_CONFIG_PAGECACHE</dt>
+** <dd>This option specifies a static memory buffer that SQLite can use for
+** the database page cache.  There are three arguments: A pointer to the
+** memory, the size of each page buffer (sz), and the number of pages (N).
+** The sz argument must be a power of two between 512 and 32768.  The first
+** argument should point to an allocation of at least (sz+4)*N bytes of memory.
+** SQLite will use the memory provided by the first argument to satisfy its
+** memory needs for the first N pages that it adds to cache.  If additional
+** page cache memory is needed beyond what is provided by this option, then
+** SQLite goes to [sqlite3_malloc()] for the additional storage space.</dd>
+**
+** <dt>SQLITE_CONFIG_HEAP</dt>
+** <dd>This option specifies a static memory buffer that SQLite will use
+** for all of its dynamic memory allocation needs beyond those provided
+** for by [SQLITE_CONFIG_SCRATCH] and [SQLITE_CONFIG_PAGECACHE].
+** There are three arguments: A pointer to the memory, the number of
+** bytes in the memory buffer, and the minimum allocation size.  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].  If the
+** memory pointer is not NULL and either [SQLITE_ENABLE_MEMSYS3] or
+** [SQLITE_ENABLE_MEMSYS5] are defined, then the alternative memory
+** allocator is engaged to handle all of SQLites memory allocation needs.</dd>
+**
+** <dt>SQLITE_CONFIG_MUTEX</dt>
+** <dd>This 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.</dd>
+**
+** <dt>SQLITE_CONFIG_GETMUTEX</dt>
+** <dd>This 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.
+** This option can be used to overload the default mutex allocation
+** routines with a wrapper used to track mutex usage for performance
+** profiling or testing, for example.</dd>
+*/
+#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  /* void*, int sz, int N */
+#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* */
+
+
+/*
 ** CAPI3REF: Enable Or Disable Extended Result Codes {F12200}
 **
 ** The sqlite3_extended_result_codes() routine enables or disables the
-** [SQLITE_IOERR_READ | extended result codes] feature of SQLite.
-** The extended result codes are disabled by default for historical
-** compatibility.
+** [extended result codes] feature of SQLite. The extended result
+** codes are disabled by default for historical compatibility considerations.
 **
 ** INVARIANTS:
 **
-** {F12201} Each new [database connection] has the 
-**          [extended result codes] feature
-**          disabled by default.
+** {F12201} Each new [database connection] shall have the
+**          [extended result codes] feature disabled by default.
 **
-** {F12202} The [sqlite3_extended_result_codes(D,F)] interface will enable
-**          [extended result codes] for the 
-**          [database connection] D if the F parameter
-**          is true, or disable them if F is false.
+** {F12202} The [sqlite3_extended_result_codes(D,F)] interface shall enable
+**          [extended result codes] for the  [database connection] D
+**          if the F parameter is true, or disable them if F is false.
 */
 int sqlite3_extended_result_codes(sqlite3*, int onoff);
 
@@ -858,44 +1188,42 @@
 ** is another alias for the rowid.
 **
 ** This routine returns the rowid of the most recent
-** successful INSERT into the database from the database connection
-** shown in the first argument.  If no successful inserts
-** have ever occurred on this database connection, zero is returned.
-**
-** If an INSERT occurs within a trigger, then the rowid of the
-** inserted row is returned by this routine as long as the trigger
-** is running.  But once the trigger terminates, the value returned
-** by this routine reverts to the last value inserted before the
-** trigger fired.
+** successful INSERT into the database from the [database connection]
+** in the first argument.  If no successful INSERTs
+** have ever occurred on that database connection, zero is returned.
+**
+** If an INSERT occurs within a trigger, then the rowid of the inserted
+** row is returned by this routine as long as the trigger is running.
+** But once the trigger terminates, the value returned by this routine
+** reverts to the last value inserted before the trigger fired.
 **
 ** An INSERT that fails due to a constraint violation is not a
-** successful insert and does not change the value returned by this
+** successful INSERT and does not change the value returned by this
 ** routine.  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.  When INSERT OR REPLACE 
+** routine when their insertion fails.  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. 
+** the return value of this interface.
 **
-** For the purposes of this routine, an insert is considered to
+** For the purposes of this routine, an INSERT is considered to
 ** be successful even if it is subsequently rolled back.
 **
 ** INVARIANTS:
 **
-** {F12221} The [sqlite3_last_insert_rowid()] function returns the
-**          rowid of the most recent successful insert done
-**          on the same database connection and within the same
-**          trigger context, or zero if there have
-**          been no qualifying inserts on that connection.
+** {F12221} The [sqlite3_last_insert_rowid()] function returns the rowid
+**          of the most recent successful INSERT performed on the same
+**          [database connection] and within the same or higher level
+**          trigger context, or zero if there have been no qualifying inserts.
 **
-** {F12223} The [sqlite3_last_insert_rowid()] function returns
+** {F12223} The [sqlite3_last_insert_rowid()] function returns the
 **          same value when called from the same trigger context
 **          immediately before and after a ROLLBACK.
 **
 ** LIMITATIONS:
 **
-** {U12232} If a separate thread does a new insert on the same
+** {A12232} If a separate thread performs a new INSERT on the same
 **          database connection while the [sqlite3_last_insert_rowid()]
 **          function is running and thus changes the last insert rowid,
 **          then the value returned by [sqlite3_last_insert_rowid()] is
@@ -909,9 +1237,9 @@
 **
 ** This function returns the number of database rows that were changed
 ** or inserted or deleted by the most recently completed SQL statement
-** on the connection specified by the first parameter.  Only
-** changes that are directly specified by the INSERT, UPDATE, or
-** DELETE statement are counted.  Auxiliary changes caused by
+** on the [database connection] specified by the first parameter.
+** Only changes that are directly specified by the INSERT, UPDATE,
+** or DELETE statement are counted.  Auxiliary changes caused by
 ** triggers are not counted. Use the [sqlite3_total_changes()] function
 ** to find the total number of changes including changes caused by triggers.
 **
@@ -935,79 +1263,84 @@
 ** most recent INSERT, UPDATE, or DELETE statement within the same
 ** trigger context.
 **
-** So when called from the top level, this function returns the
+** Thus, when called from the top level, this function returns the
 ** number of changes in the most recent INSERT, UPDATE, or DELETE
-** that also occurred at the top level.
-** Within the body of a trigger, the sqlite3_changes() interface
-** can be called to find the number of
+** that also occurred at the top level.  Within the body of a trigger,
+** the sqlite3_changes() interface can be called to find the number of
 ** changes in the most recently completed INSERT, UPDATE, or DELETE
 ** statement within the body of the same trigger.
-** However, the number returned does not include in changes
-** caused by subtriggers since they have their own context.
+** However, the number returned does not include changes
+** caused by subtriggers since those have their own context.
 **
-** SQLite implements the command "DELETE FROM table" without
-** a WHERE clause by dropping and recreating the table.  (This is much
-** faster than going through and deleting individual elements from the
-** table.)  Because of this optimization, the deletions in
-** "DELETE FROM table" are not row changes and will not be counted
-** by the sqlite3_changes() or [sqlite3_total_changes()] functions.
-** To get an accurate count of the number of rows deleted, use
+** SQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table.  (This is much faster than going
+** through and deleting individual elements from the table.)  Because of this
+** optimization, the deletions in "DELETE FROM table" are not row changes and
+** will not be counted by the sqlite3_changes() or [sqlite3_total_changes()]
+** functions, regardless of the number of elements that were originally
+** in the table.  To get an accurate count of the number of rows deleted, use
 ** "DELETE FROM table WHERE 1" instead.
 **
 ** INVARIANTS:
 **
-** {F12241} The [sqlite3_changes()] function returns the number of
+** {F12241} The [sqlite3_changes()] function shall return the number of
 **          row changes caused by the most recent INSERT, UPDATE,
 **          or DELETE statement on the same database connection and
-**          within the same trigger context, or zero if there have
+**          within the same or higher trigger context, or zero if there have
 **          not been any qualifying row changes.
 **
+** {F12243} Statements of the form "DELETE FROM tablename" with no
+**          WHERE clause shall cause subsequent calls to
+**          [sqlite3_changes()] to return zero, regardless of the
+**          number of rows originally in the table.
+**
 ** LIMITATIONS:
 **
-** {U12252} If a separate thread makes changes on the same database connection
+** {A12252} If a separate thread makes changes on the same database connection
 **          while [sqlite3_changes()] is running then the value returned
-**          is unpredictable and unmeaningful.
+**          is unpredictable and not meaningful.
 */
 int sqlite3_changes(sqlite3*);
 
 /*
 ** CAPI3REF: Total Number Of Rows Modified {F12260}
-***
-** This function returns the number of row changes caused
-** by INSERT, UPDATE or DELETE statements since the database handle
-** was opened.  The count includes all changes from all trigger
-** contexts.  But the count does not include changes used to
-** implement REPLACE constraints, do rollbacks or ABORT processing,
-** or DROP table processing.
-** The changes
-** are counted as soon as the statement that makes them is completed 
-** (when the statement handle is passed to [sqlite3_reset()] or 
+**
+** This function returns the number of row changes caused by INSERT,
+** UPDATE or DELETE statements since the [database connection] was opened.
+** The count includes all changes from all trigger contexts.  However,
+** the count does not include changes used to implement REPLACE constraints,
+** do rollbacks or ABORT processing, or DROP table processing.
+** The changes are counted as soon as the statement that makes them is
+** completed (when the statement handle is passed to [sqlite3_reset()] or
 ** [sqlite3_finalize()]).
 **
-** SQLite implements the command "DELETE FROM table" without
-** a WHERE clause by dropping and recreating the table.  (This is much
-** faster than going
-** through and deleting individual elements from the table.)  Because of
-** this optimization, the change count for "DELETE FROM table" will be
-** zero regardless of the number of elements that were originally in the
-** table. To get an accurate count of the number of rows deleted, use
+** SQLite implements the command "DELETE FROM table" without a WHERE clause
+** by dropping and recreating the table.  (This is much faster than going
+** through and deleting individual elements from the table.)  Because of this
+** optimization, the deletions in "DELETE FROM table" are not row changes and
+** will not be counted by the sqlite3_changes() or [sqlite3_total_changes()]
+** functions, regardless of the number of elements that were originally
+** in the table.  To get an accurate count of the number of rows deleted, use
 ** "DELETE FROM table WHERE 1" instead.
 **
 ** See also the [sqlite3_changes()] interface.
 **
 ** INVARIANTS:
-** 
+**
 ** {F12261} The [sqlite3_total_changes()] returns the total number
 **          of row changes caused by INSERT, UPDATE, and/or DELETE
 **          statements on the same [database connection], in any
-**          trigger context, since the database connection was
-**          created.
+**          trigger context, since the database connection was created.
+**
+** {F12263} Statements of the form "DELETE FROM tablename" with no
+**          WHERE clause shall not change the value returned
+**          by [sqlite3_total_changes()].
 **
 ** LIMITATIONS:
 **
-** {U12264} If a separate thread makes changes on the same database connection
-**          while [sqlite3_total_changes()] is running then the value 
-**          returned is unpredictable and unmeaningful.
+** {A12264} 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.
 */
 int sqlite3_total_changes(sqlite3*);
 
@@ -1022,16 +1355,18 @@
 **
 ** 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 not safe to call this routine with a [database connection] that
 ** is closed or might close before sqlite3_interrupt() returns.
 **
-** If an SQL is very nearly finished at the time when sqlite3_interrupt()
-** is called, then it might not have an opportunity to be interrupted.
-** It 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.
+** 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.
+**
 ** A call to sqlite3_interrupt() has no effect on SQL statements
 ** that are started after sqlite3_interrupt() returns.
 **
@@ -1039,15 +1374,14 @@
 **
 ** {F12271} The [sqlite3_interrupt()] interface will force all running
 **          SQL statements associated with the same database connection
-**          to halt after processing at most one additional row of
-**          data.
+**          to halt after processing at most one additional row of data.
 **
 ** {F12272} Any SQL statement that is interrupted by [sqlite3_interrupt()]
 **          will return [SQLITE_INTERRUPT].
 **
 ** LIMITATIONS:
 **
-** {U12279} If the database connection closes while [sqlite3_interrupt()]
+** {A12279} If the database connection closes while [sqlite3_interrupt()]
 **          is running then bad things will likely happen.
 */
 void sqlite3_interrupt(sqlite3*);
@@ -1066,23 +1400,27 @@
 ** independent tokens (they are part of the token in which they are
 ** embedded) and thus do not count as a statement terminator.
 **
-** These routines do not parse the SQL and
-** so will not detect syntactically incorrect SQL.
+** These routines do not parse the SQL statements thus
+** will not detect syntactically incorrect SQL.
 **
 ** INVARIANTS:
 **
-** {F10511} The sqlite3_complete() and sqlite3_complete16() functions
-**          return true (non-zero) if and only if the last
-**          non-whitespace token in their input is a semicolon that
-**          is not in between the BEGIN and END of a CREATE TRIGGER
-**          statement.
+** {F10511} A successful evaluation of [sqlite3_complete()] or
+**          [sqlite3_complete16()] functions shall
+**          return a numeric 1 if and only if the last non-whitespace
+**          token in their input is a semicolon that is not in between
+**          the BEGIN and END of a CREATE TRIGGER statement.
+**
+** {F10512} If a memory allocation error occurs during an invocation
+**          of [sqlite3_complete()] or [sqlite3_complete16()] then the
+**          routine shall return [SQLITE_NOMEM].
 **
 ** LIMITATIONS:
 **
-** {U10512} The input to sqlite3_complete() must be a zero-terminated
+** {A10512} The input to [sqlite3_complete()] must be a zero-terminated
 **          UTF-8 string.
 **
-** {U10513} The input to sqlite3_complete16() must be a zero-terminated
+** {A10513} The input to [sqlite3_complete16()] must be a zero-terminated
 **          UTF-16 string in native byte order.
 */
 int sqlite3_complete(const char *sql);
@@ -1091,29 +1429,27 @@
 /*
 ** CAPI3REF: Register A Callback To Handle SQLITE_BUSY Errors {F12310}
 **
-** This routine identifies a callback function that might be
-** invoked whenever an attempt is made to open a database table 
-** that another thread or process has locked.
-** If the busy callback is NULL, then [SQLITE_BUSY]
-** or [SQLITE_IOERR_BLOCKED]
-** is returned immediately upon encountering the lock.
-** If the busy callback is not NULL, then the
-** callback will be invoked with two arguments.  The
-** first argument to the handler is a copy of the void* pointer which
-** is the third argument to this routine.  The second argument to
-** the handler is the number of times that the busy handler has
-** been invoked for this locking event.   If the
+** This routine sets a callback function that might be invoked whenever
+** an attempt is made to open a database table that another thread
+** or process has locked.
+**
+** If the busy callback is NULL, then [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED]
+** is returned immediately upon encountering the lock. If the busy callback
+** is not NULL, then the callback will be invoked with two arguments.
+**
+** The first argument to the handler is a copy of the void* pointer which
+** is the third argument to sqlite3_busy_handler().  The second argument to
+** the handler callback is the number of times that the busy handler has
+** been invoked for this locking event.  If the
 ** busy callback returns 0, then no additional attempts are made to
 ** access the database and [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED] is returned.
 ** If the callback returns non-zero, then another attempt
 ** is made to open the database for reading and the cycle repeats.
 **
-** 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] or
-** [SQLITE_IOERR_BLOCKED] instead of invoking the
-** busy handler.
+** 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]
+** or [SQLITE_IOERR_BLOCKED] 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
 ** a second process is holding a reserved lock that it is trying
@@ -1138,77 +1474,77 @@
 ** code is promoted from the relatively benign [SQLITE_BUSY] to
 ** the more severe [SQLITE_IOERR_BLOCKED].  This error code promotion
 ** forces an automatic rollback of the changes.  See the
-** <a href="http://www.sqlite.org/cvstrac/wiki?p=CorruptionFollowingBusyError";>
+** <a href="/cvstrac/wiki?p=CorruptionFollowingBusyError">
 ** CorruptionFollowingBusyError</a> wiki page for a discussion of why
 ** this is important.
-**	
-** There can only be a single busy handler defined for each database
-** connection.  Setting a new busy handler clears any previous one. 
-** Note that calling [sqlite3_busy_timeout()] will also set or clear
-** the busy handler.
+**
+** There can only be a single busy handler defined for each
+** [database connection].  Setting a new busy handler clears any
+** previously set handler.  Note that calling [sqlite3_busy_timeout()]
+** will also set or clear the busy handler.
 **
 ** INVARIANTS:
 **
-** {F12311} The [sqlite3_busy_handler()] function replaces the busy handler
-**          callback in the database connection identified by the 1st
-**          parameter with a new busy handler identified by the 2nd and 3rd
-**          parameters.
+** {F12311} The [sqlite3_busy_handler(D,C,A)] function shall replace
+**          busy callback in the [database connection] D with a new
+**          a new busy handler C and application data pointer A.
 **
-** {F12312} The default busy handler for new database connections is NULL.
+** {F12312} Newly created [database connections] shall have a busy
+**          handler of NULL.
 **
-** {F12314} When two or more database connection share a common cache,
+** {F12314} When two or more [database connections] share a
+**          [sqlite3_enable_shared_cache | common cache],
 **          the busy handler for the database connection currently using
-**          the cache is invoked when the cache encounters a lock.
+**          the cache shall be invoked when the cache encounters a lock.
 **
-** {F12316} If a busy handler callback returns zero, then the SQLite
-**          interface that provoked the locking event will return
-**          [SQLITE_BUSY].
+** {F12316} If a busy handler callback returns zero, then the SQLite interface
+**          that provoked the locking event shall return [SQLITE_BUSY].
 **
-** {F12318} SQLite will invokes the busy handler with two argument which
+** {F12318} SQLite shall invokes the busy handler with two arguments which
 **          are a copy of the pointer supplied by the 3rd parameter to
 **          [sqlite3_busy_handler()] and a count of the number of prior
 **          invocations of the busy handler for the same locking event.
 **
 ** LIMITATIONS:
 **
-** {U12319} A busy handler should not call close the database connection
-**          or prepared statement that invoked the busy handler.
+** {A12319} A busy handler must not close the database connection
+**          or [prepared statement] that invoked the busy handler.
 */
 int sqlite3_busy_handler(sqlite3*, int(*)(void*,int), void*);
 
 /*
 ** CAPI3REF: Set A Busy Timeout {F12340}
 **
-** This routine sets a [sqlite3_busy_handler | busy handler]
-** that sleeps for a while when a
-** table is locked.  The handler will sleep multiple times until 
-** at least "ms" milliseconds of sleeping have been done. {F12343} After
-** "ms" milliseconds of sleeping, the handler returns 0 which
-** causes [sqlite3_step()] to return [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
+** This routine sets a [sqlite3_busy_handler | busy handler] that sleeps
+** for a specified amount of time when a table is locked.  The handler
+** will sleep multiple times until at least "ms" milliseconds of sleeping
+** have accumulated. {F12343} After "ms" milliseconds of sleeping,
+** the handler returns 0 which causes [sqlite3_step()] to return
+** [SQLITE_BUSY] or [SQLITE_IOERR_BLOCKED].
 **
 ** Calling this routine with an argument less than or equal to zero
 ** turns off all busy handlers.
 **
-** There can only be a single busy handler for a particular database
-** connection.  If another busy handler was defined  
-** (using [sqlite3_busy_handler()]) prior to calling
+** There can only be a single busy handler for a particular
+** [database connection] any any given moment.  If another busy handler
+** was defined  (using [sqlite3_busy_handler()]) prior to calling
 ** this routine, that other busy handler is cleared.
 **
 ** INVARIANTS:
 **
-** {F12341} The [sqlite3_busy_timeout()] function overrides any prior
+** {F12341} The [sqlite3_busy_timeout()] function shall override any prior
 **          [sqlite3_busy_timeout()] or [sqlite3_busy_handler()] setting
-**          on the same database connection.
+**          on the same [database connection].
 **
 ** {F12343} If the 2nd parameter to [sqlite3_busy_timeout()] is less than
-**          or equal to zero, then the busy handler is cleared so that
+**          or equal to zero, then the busy handler shall be cleared so that
 **          all subsequent locking events immediately return [SQLITE_BUSY].
 **
 ** {F12344} If the 2nd parameter to [sqlite3_busy_timeout()] is a positive
-**          number N, then a busy handler is set that repeatedly calls
-**          the xSleep() method in the VFS interface until either the
-**          lock clears or until the cumulative sleep time reported back
-**          by xSleep() exceeds N milliseconds.
+**          number N, then a busy handler shall be set that repeatedly calls
+**          the xSleep() method in the [sqlite3_vfs | VFS interface] until
+**          either the lock clears or until the cumulative sleep time
+**          reported back by xSleep() exceeds N milliseconds.
 */
 int sqlite3_busy_timeout(sqlite3*, int ms);
 
@@ -1224,16 +1560,14 @@
 ** numbers are obtained separately.  Let N be the number of rows
 ** and M be the number of columns.
 **
-** A result table is an array of pointers to zero-terminated
-** UTF-8 strings.  There are (N+1)*M elements in the array.  
-** The first M pointers point to zero-terminated strings that 
-** contain the names of the columns.
-** The remaining entries all point to query results.  NULL
-** values are give a NULL pointer.  All other values are in
-** their UTF-8 zero-terminated string representation as returned by
-** [sqlite3_column_text()].
+** A result table is an array of pointers to zero-terminated UTF-8 strings.
+** There are (N+1)*M elements in the array.  The first M pointers point
+** to zero-terminated strings that  contain the names of the columns.
+** The remaining entries all point to query results.  NULL values result
+** in NULL pointers.  All other values are in their UTF-8 zero-terminated
+** string representation as returned by [sqlite3_column_text()].
 **
-** A result table might consists of one or more memory allocations.
+** A result table might consist of one or more memory allocations.
 ** It is not safe to pass a result table directly to [sqlite3_free()].
 ** A result table should be deallocated using [sqlite3_free_table()].
 **
@@ -1268,11 +1602,11 @@
 ** string of its 2nd parameter.  It returns a result table to the
 ** pointer given in its 3rd parameter.
 **
-** After the calling function has finished using the result, it should 
-** pass the pointer to the result table to sqlite3_free_table() in order to 
-** release the memory that was malloc-ed.  Because of the way the 
+** After the calling function has finished using the result, it should
+** pass the pointer to the result table to sqlite3_free_table() in order to
+** release the memory that was malloced.  Because of the way the
 ** [sqlite3_malloc()] happens within sqlite3_get_table(), the calling
-** function must not try to call [sqlite3_free()] directly.  Only 
+** function must not try to call [sqlite3_free()] directly.  Only
 ** [sqlite3_free_table()] is able to release the memory properly and safely.
 **
 ** The sqlite3_get_table() interface is implemented as a wrapper around
@@ -1280,38 +1614,48 @@
 ** to any internal data structures of SQLite.  It uses only the public
 ** interface defined here.  As a consequence, errors that occur in the
 ** wrapper layer outside of the internal [sqlite3_exec()] call are not
-** reflected in subsequent calls to [sqlite3_errcode()] or
-** [sqlite3_errmsg()].
+** reflected in subsequent calls to [sqlite3_errcode()] or [sqlite3_errmsg()].
 **
 ** INVARIANTS:
 **
 ** {F12371} If a [sqlite3_get_table()] fails a memory allocation, then
-**          it frees the result table under construction, aborts the
-**          query in process, skips any subsequent queries, sets the
-**          *resultp output pointer to NULL and returns [SQLITE_NOMEM].
-**
-** {F12373} If the ncolumn parameter to [sqlite3_get_table()] is not NULL
-**          then [sqlite3_get_table()] write the number of columns in the
-**          result set of the query into *ncolumn if the query is
-**          successful (if the function returns SQLITE_OK).
-**
-** {F12374} If the nrow parameter to [sqlite3_get_table()] is not NULL
-**          then [sqlite3_get_table()] write the number of rows in the
-**          result set of the query into *nrow if the query is
-**          successful (if the function returns SQLITE_OK).
-**
-** {F12376} The [sqlite3_get_table()] function sets its *ncolumn value
-**          to the number of columns in the result set of the query in the
-**          sql parameter, or to zero if the query in sql has an empty
-**          result set.
+**          it shall free the result table under construction, abort the
+**          query in process, skip any subsequent queries, set the
+**          *pazResult output pointer to NULL and return [SQLITE_NOMEM].
+**
+** {F12373} If the pnColumn parameter to [sqlite3_get_table()] is not NULL
+**          then a successful invocation of [sqlite3_get_table()] shall
+**          write the number of columns in the
+**          result set of the query into *pnColumn.
+**
+** {F12374} If the pnRow parameter to [sqlite3_get_table()] is not NULL
+**          then a successful invocation of [sqlite3_get_table()] shall
+**          writes the number of rows in the
+**          result set of the query into *pnRow.
+**
+** {F12376} A successful invocation of [sqlite3_get_table()] that computes
+**          N rows of result with C columns per row shall make *pazResult
+**          point to an array of pointers to (N+1)*C strings where the first
+**          C strings are column names as obtained from
+**          [sqlite3_column_name()] and the rest are column result values
+**          obtained from [sqlite3_column_text()].
+**
+** {F12379} The values in the pazResult array returned by [sqlite3_get_table()]
+**          shall remain valid until cleared by [sqlite3_free_table()].
+**
+** {F12382} When an error occurs during evaluation of [sqlite3_get_table()]
+**          the function shall set *pazResult to NULL, write an error message
+**          into memory obtained from [sqlite3_malloc()], make
+**          **pzErrmsg point to that error message, and return a
+**          appropriate [error code].
 */
 int sqlite3_get_table(
-  sqlite3*,             /* An open database */
-  const char *sql,      /* SQL to be evaluated */
-  char ***pResult,      /* Results of the query */
-  int *nrow,            /* Number of result rows written here */
-  int *ncolumn,         /* Number of result columns written here */
-  char **errmsg         /* Error msg written here */
+  sqlite3 *db,          /* An open database */
+  const char *zSql,     /* SQL to be evaluated */
+  char ***pazResult,    /* Results of the query */
+  int *pnRow,           /* Number of result rows written here */
+  int *pnColumn,        /* Number of result columns written here */
+  char **pzErrmsg       /* Error msg written here */
 );
 void sqlite3_free_table(char **result);
 
@@ -1324,7 +1668,7 @@
 ** The sqlite3_mprintf() and sqlite3_vmprintf() routines write their
 ** results into memory obtained from [sqlite3_malloc()].
 ** The strings returned by these two routines should be
-** released by [sqlite3_free()].   Both routines return a
+** released by [sqlite3_free()].  Both routines return a
 ** NULL pointer if [sqlite3_malloc()] is unable to allocate enough
 ** memory to hold the resulting string.
 **
@@ -1349,7 +1693,7 @@
 **
 ** These routines all implement some additional formatting
 ** options that are useful for constructing SQL statements.
-** All of the usual printf formatting options apply.  In addition, there
+** All of the usual printf() formatting options apply.  In addition, there
 ** is are "%q", "%Q", and "%z" options.
 **
 ** The %q option works like %s in that it substitutes a null-terminated
@@ -1358,7 +1702,7 @@
 ** character it escapes that character and allows it to be inserted into
 ** the string.
 **
-** For example, so some string variable contains text as follows:
+** For example, assume the string variable zText contains text as follows:
 **
 ** <blockquote><pre>
 **  char *zText = "It's a happy day!";
@@ -1386,14 +1730,13 @@
 **  INSERT INTO table1 VALUES('It's a happy day!');
 ** </pre></blockquote>
 **
-** This second example is an SQL syntax error.  As a general rule you
-** should always use %q instead of %s when inserting text into a string 
-** literal.
+** This second example is an SQL syntax error.  As a general rule you should
+** always use %q instead of %s when inserting text into a string literal.
 **
 ** The %Q option works like %q except it also adds single quotes around
-** the outside of the total string.  Or if the parameter in the argument
-** list is a NULL pointer, %Q substitutes the text "NULL" (without single
-** quotes) in place of the %Q option. {END}  So, for example, one could say:
+** the outside of the total string.  Additionally, if the parameter in the
+** argument list is a NULL pointer, %Q substitutes the text "NULL" (without
+** single quotes) in place of the %Q option.  So, for example, one could say:
 **
 ** <blockquote><pre>
 **  char *zSQL = sqlite3_mprintf("INSERT INTO table VALUES(%Q)", zText);
@@ -1419,12 +1762,11 @@
 **           UTF-8 string into the buffer pointed to by the second parameter
 **           provided that the first parameter is greater than zero.
 **
-** {F17407}  The [sqlite3_snprintf()] interface does not writes slots of
+** {F17407}  The [sqlite3_snprintf()] interface does not write slots of
 **           its output buffer (the second parameter) outside the range
 **           of 0 through N-1 (where N is the first parameter)
 **           regardless of the length of the string
 **           requested by the format specification.
-**   
 */
 char *sqlite3_mprintf(const char*,...);
 char *sqlite3_vmprintf(const char*, va_list);
@@ -1436,7 +1778,7 @@
 ** The SQLite core  uses these three routines for all of its own
 ** internal memory allocation needs. "Core" in the previous sentence
 ** does not include operating-system specific VFS implementation.  The
-** windows VFS uses native malloc and free for some operations.
+** Windows VFS uses native malloc() and free() for some operations.
 **
 ** The sqlite3_malloc() routine returns a pointer to a block
 ** of memory at least N bytes in length, where N is the parameter.
@@ -1465,7 +1807,7 @@
 ** If the second parameter to sqlite3_realloc() is zero or
 ** negative then the behavior is exactly the same as calling
 ** sqlite3_free(P) where P is the first parameter to sqlite3_realloc().
-** Sqlite3_realloc() returns a pointer to a memory allocation
+** sqlite3_realloc() returns a pointer to a memory allocation
 ** of at least N bytes in size or NULL if sufficient memory is unavailable.
 ** 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
@@ -1476,38 +1818,34 @@
 ** The memory returned by sqlite3_malloc() and sqlite3_realloc()
 ** is always aligned to at least an 8 byte boundary. {END}
 **
-** The default implementation
-** of the memory allocation subsystem uses the malloc(), realloc()
-** and free() provided by the standard C library. {F17382} However, if 
-** SQLite is compiled with the following C preprocessor macro
-**
-** <blockquote> SQLITE_MEMORY_SIZE=<i>NNN</i> </blockquote>
-**
-** where <i>NNN</i> is an integer, then SQLite create a static
-** array of at least <i>NNN</i> bytes in size and use that array
-** for all of its dynamic memory allocation needs. {END}  Additional
-** memory allocator options may be added in future releases.
+** The default implementation of the memory allocation subsystem uses
+** the malloc(), realloc() and free() provided by the standard C library.
+** {F17382} However, if SQLite is compiled with the
+** SQLITE_MEMORY_SIZE=<i>NNN</i> C preprocessor macro (where <i>NNN</i>
+** is an integer), then SQLite create a static array of at least
+** <i>NNN</i> bytes in size and uses that array for all of its dynamic
+** memory allocation needs. {END}  Additional memory allocator options
+** may be added in future releases.
 **
 ** In SQLite version 3.5.0 and 3.5.1, it was possible to define
 ** the SQLITE_OMIT_MEMORY_ALLOCATION which would cause the built-in
 ** implementation of these routines to be omitted.  That capability
-** is no longer provided.  Only built-in memory allocators can be
-** used.
+** is no longer provided.  Only built-in memory allocators can be used.
 **
-** The windows OS interface layer calls
+** The Windows OS interface layer calls
 ** the system malloc() and free() directly when converting
 ** filenames between the UTF-8 encoding used by SQLite
-** and whatever filename encoding is used by the particular windows
+** and whatever filename encoding is used by the particular Windows
 ** installation.  Memory allocation errors are detected, but
 ** they are reported back as [SQLITE_CANTOPEN] or
 ** [SQLITE_IOERR] rather than [SQLITE_NOMEM].
 **
 ** INVARIANTS:
 **
-** {F17303}  The [sqlite3_malloc(N)] interface returns either a pointer to 
-**           newly checked-out block of at least N bytes of memory
-**           that is 8-byte aligned, 
-**           or it returns NULL if it is unable to fulfill the request.
+** {F17303}  The [sqlite3_malloc(N)] interface returns either a pointer to
+**           a newly checked-out block of at least N bytes of memory
+**           that is 8-byte aligned, or it returns NULL if it is unable
+**           to fulfill the request.
 **
 ** {F17304}  The [sqlite3_malloc(N)] interface returns a NULL pointer if
 **           N is less than or equal to zero.
@@ -1533,8 +1871,9 @@
 **           that is 8-byte aligned, or a NULL pointer.
 **
 ** {F17321}  When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
-**           copies the first K bytes of content from P into the newly allocated
-**           where K is the lessor of N and the size of the buffer P.
+**           copies the first K bytes of content from P into the newly
+**           allocated block, where K is the lesser of N and the size of
+**           the buffer P.
 **
 ** {F17322}  When [sqlite3_realloc(P,N)] returns a non-NULL pointer, it first
 **           releases the buffer P.
@@ -1544,15 +1883,14 @@
 **
 ** LIMITATIONS:
 **
-** {U17350}  The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
-**           must be either NULL or else a pointer obtained from a prior
-**           invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that has
-**           not been released.
+** {A17350}  The pointer arguments to [sqlite3_free()] and [sqlite3_realloc()]
+**           must be either NULL or else pointers obtained from a prior
+**           invocation of [sqlite3_malloc()] or [sqlite3_realloc()] that have
+**           not yet been released.
 **
-** {U17351}  The application must not read or write any part of 
+** {A17351}  The application must not read or write any part of
 **           a block of memory after it has been released using
 **           [sqlite3_free()] or [sqlite3_realloc()].
-**
 */
 void *sqlite3_malloc(int);
 void *sqlite3_realloc(void*, int);
@@ -1563,28 +1901,27 @@
 **
 ** SQLite provides these two interfaces for reporting on the status
 ** of the [sqlite3_malloc()], [sqlite3_free()], and [sqlite3_realloc()]
-** the memory allocation subsystem included within the SQLite.
+** routines, which form the built-in memory allocation subsystem.
 **
 ** INVARIANTS:
 **
-** {F17371} The [sqlite3_memory_used()] routine returns the
-**          number of bytes of memory currently outstanding 
-**          (malloced but not freed).
+** {F17371} The [sqlite3_memory_used()] routine returns the number of bytes
+**          of memory currently outstanding (malloced but not freed).
 **
 ** {F17373} The [sqlite3_memory_highwater()] routine returns the maximum
-**          value of [sqlite3_memory_used()] 
-**          since the highwater mark was last reset.
+**          value of [sqlite3_memory_used()] since the high-water mark
+**          was last reset.
 **
 ** {F17374} 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.
-** 
-** {F17375} The memory highwater mark is reset to the current value of
+**
+** {F17375} 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.  The value returned
-**          by [sqlite3_memory_highwater(1)] is the highwater mark
+**          by [sqlite3_memory_highwater(1)] is the high-water mark
 **          prior to the reset.
 */
 sqlite3_int64 sqlite3_memory_used(void);
@@ -1597,7 +1934,7 @@
 ** select random ROWIDs when inserting new records into a table that
 ** already uses the largest possible ROWID.  The PRNG is also used for
 ** the build-in random() and randomblob() SQL functions.  This interface allows
-** appliations to access the same PRNG for other purposes.
+** applications to access the same PRNG for other purposes.
 **
 ** A call to this routine stores N bytes of randomness into buffer P.
 **
@@ -1629,9 +1966,9 @@
 ** 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.   If the authorizer callback returns
+** rejected with an error.  If the authorizer callback returns
 ** any value other than [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY]
-** then [sqlite3_prepare_v2()] or equivalent call that triggered
+** then the [sqlite3_prepare_v2()] or equivalent call that triggered
 ** the authorizer will fail with an error message.
 **
 ** When the callback returns [SQLITE_OK], that means the operation
@@ -1646,19 +1983,17 @@
 ** return can be used to deny an untrusted user access to individual
 ** columns of a table.
 **
-** The first parameter to the authorizer callback is a copy of
-** the third parameter to the sqlite3_set_authorizer() interface.
-** The second parameter to the callback is an integer 
-** [SQLITE_COPY | action code] that specifies the particular action
-** to be authorized. The third through sixth
-** parameters to the callback are zero-terminated strings that contain 
-** additional details about the action to be authorized.
+** The first parameter to the authorizer callback is a copy of the third
+** parameter to the sqlite3_set_authorizer() interface. The second parameter
+** to the callback is an integer [SQLITE_COPY | action code] that specifies
+** the particular action to be authorized. The third through sixth parameters
+** to the callback are zero-terminated strings that contain additional
+** details about the action to be authorized.
 **
 ** An authorizer is used when [sqlite3_prepare | preparing]
-** SQL statements from an untrusted
-** source, to ensure that the SQL statements do not try to access data
-** that they are not allowed to see, or that they do not try to
-** execute malicious statements that damage the database.  For
+** SQL statements from an untrusted source, to ensure that the SQL statements
+** do not try to access data they are not allowed to see, or that they do not
+** try to execute malicious statements that damage the database.  For
 ** example, an application may allow a user to enter arbitrary
 ** SQL queries for evaluation by a database.  But the application does
 ** not want the user to be able to make arbitrary changes to the
@@ -1676,7 +2011,7 @@
 ** previous call.  Disable the authorizer by installing a NULL callback.
 ** The authorizer is disabled by default.
 **
-** Note that the authorizer callback is invoked only during 
+** Note that the authorizer callback is invoked only during
 ** [sqlite3_prepare()] or its variants.  Authorization is not
 ** performed during statement evaluation in [sqlite3_step()].
 **
@@ -1686,16 +2021,16 @@
 **          authorizer callback with database connection D.
 **
 ** {F12502} The authorizer callback is invoked as SQL statements are
-**          being compiled
+**          being compiled.
 **
 ** {F12503} If the authorizer callback returns any value other than
-**          [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY] then
+**          [SQLITE_IGNORE], [SQLITE_OK], or [SQLITE_DENY], then
 **          the [sqlite3_prepare_v2()] or equivalent call that caused
 **          the authorizer callback to run shall fail with an
 **          [SQLITE_ERROR] error code and an appropriate error message.
 **
 ** {F12504} When the authorizer callback returns [SQLITE_OK], the operation
-**          described is coded normally.
+**          described is processed normally.
 **
 ** {F12505} When the authorizer callback returns [SQLITE_DENY], the
 **          [sqlite3_prepare_v2()] or equivalent call that caused the
@@ -1705,26 +2040,26 @@
 **
 ** {F12506} If the authorizer code (the 2nd parameter to the authorizer
 **          callback) is [SQLITE_READ] and the authorizer callback returns
-**          [SQLITE_IGNORE] then the prepared statement is constructed to
+**          [SQLITE_IGNORE], then the prepared statement is constructed to
 **          insert a NULL value in place of the table column that would have
 **          been read if [SQLITE_OK] had been returned.
 **
 ** {F12507} If the authorizer code (the 2nd parameter to the authorizer
 **          callback) is anything other than [SQLITE_READ], then
-**          a return of [SQLITE_IGNORE] has the same effect as [SQLITE_DENY]. 
+**          a return of [SQLITE_IGNORE] has the same effect as [SQLITE_DENY].
 **
 ** {F12510} The first parameter to the authorizer callback is a copy of
 **          the third parameter to the [sqlite3_set_authorizer()] interface.
 **
-** {F12511} The second parameter to the callback is an integer 
+** {F12511} The second parameter to the callback is an integer
 **          [SQLITE_COPY | action code] that specifies the particular action
 **          to be authorized.
 **
 ** {F12512} The third through sixth parameters to the callback are
-**          zero-terminated strings that contain 
+**          zero-terminated strings that contain
 **          additional details about the action to be authorized.
 **
-** {F12520} Each call to [sqlite3_set_authorizer()] overrides the
+** {F12520} Each call to [sqlite3_set_authorizer()] overrides
 **          any previously installed authorizer.
 **
 ** {F12521} A NULL authorizer means that no authorization
@@ -1754,31 +2089,31 @@
 ** CAPI3REF: Authorizer Action Codes {F12550}
 **
 ** The [sqlite3_set_authorizer()] interface registers a callback function
-** that is invoked to authorizer certain SQL statement actions.  The
+** that is invoked to authorize certain SQL statement actions.  The
 ** second parameter to the callback is an integer code that specifies
 ** what action is being authorized.  These are the integer action codes that
 ** the authorizer callback may be passed.
 **
-** These action code values signify what kind of operation is to be 
+** These action code values signify what kind of operation is to be
 ** authorized.  The 3rd and 4th parameters to the authorization
 ** callback function will be parameters or NULL depending on which of these
 ** codes is used as the second parameter.  The 5th parameter to the
-** authorizer callback is the name of the database ("main", "temp", 
+** authorizer callback is the name of the database ("main", "temp",
 ** etc.) if applicable.  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 
+** the access attempt or NULL if this access attempt is directly from
 ** top-level SQL code.
 **
 ** INVARIANTS:
 **
-** {F12551} The second parameter to an 
-**          [sqlite3_set_authorizer | authorizer callback is always an integer
+** {F12551} The second parameter to an
+**          [sqlite3_set_authorizer | authorizer callback] is always an integer
 **          [SQLITE_COPY | authorizer code] that specifies what action
 **          is being authorized.
 **
-** {F12552} The 3rd and 4th parameters to the 
-**          [sqlite3_set_authorizer | authorization callback function]
-**          will be parameters or NULL depending on which 
+** {F12552} The 3rd and 4th parameters to the
+**          [sqlite3_set_authorizer | authorization callback]
+**          will be parameters or NULL depending on which
 **          [SQLITE_COPY | authorizer code] is used as the second parameter.
 **
 ** {F12553} The 5th parameter to the
@@ -1788,7 +2123,7 @@
 ** {F12554} The 6th parameter to the
 **          [sqlite3_set_authorizer | 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 
+**          the access attempt or NULL if this access attempt is directly from
 **          top-level SQL code.
 */
 /******************************************* 3rd ************ 4th ***********/
@@ -1835,9 +2170,9 @@
 ** various times when an SQL statement is being run by [sqlite3_step()].
 ** The callback returns a UTF-8 rendering of the SQL statement text
 ** as the statement first begins executing.  Additional callbacks occur
-** as each triggersubprogram is entered.  The callbacks for triggers
+** as each triggered subprogram is entered.  The callbacks for triggers
 ** contain a UTF-8 SQL comment that identifies the trigger.
-** 
+**
 ** The callback function registered by sqlite3_profile() is invoked
 ** as each SQL statement finishes.  The profile callback contains
 ** the original statement text and an estimate of wall-clock time
@@ -1848,7 +2183,7 @@
 **
 ** The trigger reporting feature of the trace callback is considered
 ** experimental and is subject to change or removal in future releases.
-** Future versions of SQLite might also add new trace callback 
+** Future versions of SQLite might also add new trace callback
 ** invocations.
 **
 ** INVARIANTS:
@@ -1866,7 +2201,7 @@
 **          the pointer which was the 3rd argument to [sqlite3_trace()].
 **
 ** {F12285} The second argument to the trace callback is a
-**          zero-terminated UTF8 string containing the original text
+**          zero-terminated UTF-8 string containing the original text
 **          of the SQL statement as it was passed into [sqlite3_prepare_v2()]
 **          or the equivalent, or an SQL comment indicating the beginning
 **          of a trigger subprogram.
@@ -1882,7 +2217,7 @@
 **          the SQL statement as it was processed by [sqlite3_prepare_v2()]
 **          or the equivalent.
 **
-** {F12290} The third parameter to the profile  callback is an estimate
+** {F12290} The third parameter to the profile callback is an estimate
 **          of the number of nanoseconds of wall-clock time required to
 **          run the SQL statement from start to finish.
 */
@@ -1896,37 +2231,37 @@
 ** This routine configures a callback function - the
 ** progress callback - that is invoked periodically during long
 ** running calls to [sqlite3_exec()], [sqlite3_step()] and
-** [sqlite3_get_table()].   An example use for this 
+** [sqlite3_get_table()].  An example use for this
 ** interface is to keep a GUI updated during a large query.
 **
-** If the progress callback returns non-zero, the opertion is
+** If the progress callback returns non-zero, the operation is
 ** interrupted.  This feature can be used to implement a
 ** "Cancel" button on a GUI dialog box.
 **
 ** INVARIANTS:
 **
-** {F12911} The callback function registered by [sqlite3_progress_handler()]
+** {F12911} The callback function registered by sqlite3_progress_handler()
 **          is invoked periodically during long running calls to
 **          [sqlite3_step()].
 **
 ** {F12912} The progress callback is invoked once for every N virtual
-**          machine opcodes, where N is the second argument to 
+**          machine opcodes, where N is the second argument to
 **          the [sqlite3_progress_handler()] call that registered
-**          the callback.  <todo>What if N is less than 1?</todo>
+**          the callback.  If N is less than 1, sqlite3_progress_handler()
+**          acts as if a NULL progress handler had been specified.
 **
 ** {F12913} The progress callback itself is identified by the third
-**          argument to [sqlite3_progress_handler()].
+**          argument to sqlite3_progress_handler().
 **
-** {F12914} The fourth argument [sqlite3_progress_handler()] is a
-***         void pointer passed to the progress callback
+** {F12914} The fourth argument to sqlite3_progress_handler() is a
+**          void pointer passed to the progress callback
 **          function each time it is invoked.
 **
-** {F12915} If a call to [sqlite3_step()] results in fewer than
-**          N opcodes being executed,
-**          then the progress callback is never invoked. {END}
-** 
+** {F12915} If a call to [sqlite3_step()] results in fewer than N opcodes
+**          being executed, then the progress callback is never invoked.
+**
 ** {F12916} Every call to [sqlite3_progress_handler()]
-**          overwrites any previously registere progress handler.
+**          overwrites any previously registered progress handler.
 **
 ** {F12917} If the progress handler callback is NULL then no progress
 **          handler is invoked.
@@ -1939,78 +2274,83 @@
 /*
 ** CAPI3REF: Opening A New Database Connection {F12700}
 **
-** These routines open an SQLite database file whose name
-** is given by the filename argument.
-** 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()].
-** An [sqlite3*] handle is usually returned in *ppDb, even
-** if an error occurs.  The only exception is 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.
-** If the database is opened (and/or created)
-** successfully, then [SQLITE_OK] is returned.  Otherwise an
-** error code is returned.  The
-** [sqlite3_errmsg()] or [sqlite3_errmsg16()]  routines can be used to obtain
+** These routines open an SQLite database file whose name is given by the
+** filename argument. 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(). 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. If the database is opened (and/or created) successfully, then
+** [SQLITE_OK] is returned.  Otherwise an [error code] is returned.  The
+** [sqlite3_errmsg()] or [sqlite3_errmsg16()] routines can be used to obtain
 ** an English language description of the error.
 **
 ** The default encoding for the database will be UTF-8 if
-** [sqlite3_open()] or [sqlite3_open_v2()] is called and
-** UTF-16 in the native byte order if [sqlite3_open16()] is used.
+** sqlite3_open() or sqlite3_open_v2() is called and
+** UTF-16 in the native byte order if sqlite3_open16() is used.
 **
 ** Whether or not an error occurs when it is opened, resources
-** associated with the [sqlite3*] handle should be released by passing it
-** to [sqlite3_close()] when it is no longer required.
+** associated with the [database connection] handle should be released by
+** passing it to [sqlite3_close()] when it is no longer required.
 **
-** The [sqlite3_open_v2()] interface works like [sqlite3_open()] 
-** except that it acccepts two additional parameters for additional control
-** over the new database connection.  The flags parameter can be
-** one of:
+** The sqlite3_open_v2() interface works like sqlite3_open()
+** except that it accepts two additional parameters for additional control
+** over the new database connection.  The flags parameter can take one of
+** the following three values, optionally combined with the 
+** [SQLITE_OPEN_NOMUTEX] flag:
 **
-** <ol>
-** <li>  [SQLITE_OPEN_READONLY]
-** <li>  [SQLITE_OPEN_READWRITE]
-** <li>  [SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]
-** </ol>
+** <dl>
+** <dt>[SQLITE_OPEN_READONLY]</dt>
+** <dd>The database is opened in read-only mode.  If the database does not
+** already exist, an error is returned.</dd>
+**
+** <dt>[SQLITE_OPEN_READWRITE]</dt>
+** <dd>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.</dd>
+**
+** <dt>[SQLITE_OPEN_READWRITE] | [SQLITE_OPEN_CREATE]</dt>
+** <dd>The database is opened for reading and writing, and is creates it if
+** it does not already exist. This is the behavior that is always used for
+** sqlite3_open() and sqlite3_open16().</dd>
+** </dl>
 **
-** The first value opens the database read-only. 
-** If the database does not previously exist, an error is returned.
-** The second option opens
-** the database for reading and writing if possible, or reading only if
-** if the file is write protected.  In either case the database
-** must already exist or an error is returned.  The third option
-** opens the database for reading and writing and creates it if it does
-** not already exist.
-** The third options is behavior that is always used for [sqlite3_open()]
-** and [sqlite3_open16()].
-**
-** If the 3rd parameter to [sqlite3_open_v2()] is not one of the
-** combinations shown above then the behavior is undefined.
-**
-** If the filename is ":memory:", then an private
-** in-memory database is created for the connection.  This in-memory
-** database will vanish when the database connection is closed.  Future
-** version of SQLite might make use of additional special filenames
-** that begin with the ":" character.  It is recommended that 
-** when a database filename really does begin with
-** ":" that you prefix the filename with a pathname like "./" to
-** avoid ambiguity.
+** If the 3rd parameter to sqlite3_open_v2() is not one of the
+** combinations shown above or one of the combinations shown above combined
+** with the [SQLITE_OPEN_NOMUTEX] flag, then the behavior is undefined.
+**
+** If the [SQLITE_OPEN_NOMUTEX] flag is set, then mutexes on the
+** opened [database connection] are disabled and the appliation must
+** insure that access to the [database connection] and its associated
+** [prepared statements] is serialized.  The [SQLITE_OPEN_NOMUTEX] flag
+** is the default behavior is SQLite is configured using the
+** [SQLITE_CONFIG_MULTITHREAD] or [SQLITE_CONFIG_SINGLETHREAD] options
+** to [sqlite3_config()].  The [SQLITE_OPEN_NOMUTEX] flag only makes a
+** difference when SQLite is in its default [SQLITE_CONFIG_SERIALIZED] mode.
+**
+** If the filename is ":memory:", then a private, temporary in-memory database
+** is created for the connection.  This in-memory database will vanish when
+** the database connection is closed.  Future versions of SQLite might
+** make use of additional special filenames that begin with the ":" character.
+** It is recommended that when a database filename actually does begin with
+** a ":" character you should prefix the filename with a pathname such as
+** "./" to avoid ambiguity.
 **
-** If the filename is an empty string, then a private temporary
+** If the filename is an empty string, then a private, temporary
 ** on-disk database will be created.  This private database will be
 ** automatically deleted as soon as the database connection is closed.
 **
 ** 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.  If the
-** fourth parameter is a NULL pointer then the default [sqlite3_vfs]
-** object is used.
+** [sqlite3_vfs] object that defines the operating system interface that
+** the new database connection should use.  If the fourth parameter is
+** a NULL pointer then the default [sqlite3_vfs] object is used.
 **
-** <b>Note to windows users:</b>  The encoding used for the filename argument
-** of [sqlite3_open()] and [sqlite3_open_v2()] must be UTF-8, not whatever
+** <b>Note to Windows users:</b>  The encoding used for the filename argument
+** of sqlite3_open() and sqlite3_open_v2() must be UTF-8, not whatever
 ** codepage is currently defined.  Filenames containing international
 ** characters must be converted to UTF-8 prior to passing them into
-** [sqlite3_open()] or [sqlite3_open_v2()].
+** sqlite3_open() or sqlite3_open_v2().
 **
 ** INVARIANTS:
 **
@@ -2023,7 +2363,7 @@
 **          for [sqlite3_open()] and [sqlite3_open_v2()] and as UTF-16
 **          in the native byte order for [sqlite3_open16()].
 **
-** {F12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()], 
+** {F12703} A successful invocation of [sqlite3_open()], [sqlite3_open16()],
 **          or [sqlite3_open_v2()] writes a pointer to a new
 **          [database connection] into *ppDb.
 **
@@ -2066,14 +2406,18 @@
 **          in sqlite3_open_v2()?</todo>
 **
 ** {F12719} If the filename is NULL or an empty string, then a private,
-**          ephermeral on-disk database will be created.
+**          ephemeral on-disk database will be created.
 **          <todo>Is SQLITE_OPEN_CREATE|SQLITE_OPEN_READWRITE required
 **          in sqlite3_open_v2()?</todo>
 **
-** {F12721} The [database connection] created by 
-**          [sqlite3_open_v2(F,D,G,V)] will use the
-**          [sqlite3_vfs] object identified by the V parameter, or
-**          the default [sqlite3_vfs] object is V is a NULL pointer.
+** {F12721} The [database connection] created by [sqlite3_open_v2(F,D,G,V)]
+**          will use the [sqlite3_vfs] object identified by the V parameter,
+**          or the default [sqlite3_vfs] object if V is a NULL pointer.
+**
+** {F12723} Two [database connections] will share a common cache if both were
+**          opened with the same VFS while [shared cache mode] was enabled and
+**          if both filenames compare equal using memcmp() after having been
+**          processed by the [sqlite3_vfs | xFullPathname] method of the VFS.
 */
 int sqlite3_open(
   const char *filename,   /* Database filename (UTF-8) */
@@ -2093,32 +2437,33 @@
 /*
 ** CAPI3REF: Error Codes And Messages {F12800}
 **
-** The sqlite3_errcode() interface returns the numeric
-** [SQLITE_OK | result code] or [SQLITE_IOERR_READ | extended result code]
-** for the most recent failed sqlite3_* API call associated
-** with [sqlite3] handle 'db'. If a prior API call failed but the
-** most recent API call succeeded, the return value from sqlite3_errcode()
-** is undefined.
+** The sqlite3_errcode() interface returns the numeric [result code] or
+** [extended result code] for the most recent failed sqlite3_* API call
+** associated with a [database connection]. If a prior API call failed
+** but the most recent API call succeeded, the return value from
+** sqlite3_errcode() is undefined.
 **
 ** The sqlite3_errmsg() and sqlite3_errmsg16() return English-language
-** text that describes the error, as either UTF8 or UTF16 respectively.
+** text that describes the error, as either UTF-8 or UTF-16 respectively.
 ** Memory to hold the error message string is managed internally.
-** The application does not need to worry with freeing the result.
+** 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.
 **
+** If an interface fails with SQLITE_MISUSE, that means the interface
+** was invoked incorrectly by the application.  In that case, the
+** error code and message may or may not be set.
+**
 ** INVARIANTS:
 **
 ** {F12801} The [sqlite3_errcode(D)] interface returns the numeric
-**          [SQLITE_OK | result code] or
-**          [SQLITE_IOERR_READ | extended result code]
-**          for the most recently failed interface call associated
-**          with [database connection] D.
+**          [result code] or [extended result code] for the most recently
+**          failed interface call associated with the [database connection] D.
 **
 ** {F12803} The [sqlite3_errmsg(D)] and [sqlite3_errmsg16(D)]
 **          interfaces return English-language text that describes
 **          the error in the mostly recently failed interface call,
-**          encoded as either UTF8 or UTF16 respectively.
+**          encoded as either UTF-8 or UTF-16 respectively.
 **
 ** {F12807} The strings returned by [sqlite3_errmsg()] and [sqlite3_errmsg16()]
 **          are valid until the next SQLite interface call.
@@ -2142,17 +2487,17 @@
 ** CAPI3REF: SQL Statement Object {F13000}
 ** KEYWORDS: {prepared statement} {prepared statements}
 **
-** An instance of this object represent single SQL statements.  This
-** object is variously known as a "prepared statement" or a 
+** An instance of this object represents a single SQL statement.
+** This object is variously known as a "prepared statement" or a
 ** "compiled SQL statement" or simply as a "statement".
-** 
+**
 ** The life of a statement object goes something like this:
 **
 ** <ol>
 ** <li> Create the object using [sqlite3_prepare_v2()] or a related
 **      function.
-** <li> Bind values to host parameters using
-**      [sqlite3_bind_blob | sqlite3_bind_* interfaces].
+** <li> Bind values to [host parameters] using the sqlite3_bind_*()
+**      interfaces.
 ** <li> Run the SQL by calling [sqlite3_step()] one or more times.
 ** <li> Reset the statement using [sqlite3_reset()] then go back
 **      to step 2.  Do this zero or more times.
@@ -2176,7 +2521,7 @@
 **
 ** If the new limit is a negative number, the limit is unchanged.
 ** For the limit category of SQLITE_LIMIT_XYZ there is a hard upper
-** bound set by a compile-time C-preprocess macro named SQLITE_MAX_XYZ.
+** bound set by a compile-time C preprocessor macro named SQLITE_MAX_XYZ.
 ** (The "_LIMIT_" in the name is changed to "_MAX_".)
 ** Attempts to increase a limit above its hard upper bound are
 ** silently truncated to the hard upper limit.
@@ -2185,47 +2530,44 @@
 ** both their own internal database and also databases that are controlled
 ** by untrusted external sources.  An example application might be a
 ** webbrowser that has its own databases for storing history and
-** separate databases controlled by javascript applications downloaded
-** off the internet.  The internal databases can be given the
+** separate databases controlled by JavaScript applications downloaded
+** off the Internet.  The internal databases can be given the
 ** large, default limits.  Databases managed by external sources can
 ** be given much smaller limits designed to prevent a denial of service
-** attach.  Developers might also want to use the [sqlite3_set_authorizer()]
+** attack.  Developers might also want to use the [sqlite3_set_authorizer()]
 ** interface to further control untrusted SQL.  The size of the database
 ** created by an untrusted script can be contained using the
 ** [max_page_count] [PRAGMA].
 **
-** This interface is currently considered experimental and is subject
-** to change or removal without prior notice.
+** New run-time limit categories may be added in future releases.
 **
 ** INVARIANTS:
 **
 ** {F12762} A successful call to [sqlite3_limit(D,C,V)] where V is
-**          positive changes the
-**          limit on the size of construct C in [database connection] D
-**          to the lessor of V and the hard upper bound on the size
-**          of C that is set at compile-time.
+**          positive changes the limit on the size of construct C in the
+**          [database connection] D to the lesser of V and the hard upper
+**          bound on the size of C that is set at compile-time.
 **
 ** {F12766} A successful call to [sqlite3_limit(D,C,V)] where V is negative
-**          leaves the state of [database connection] D unchanged.
+**          leaves the state of the [database connection] D unchanged.
 **
 ** {F12769} A successful call to [sqlite3_limit(D,C,V)] returns the
-**          value of the limit on the size of construct C in
-**          in [database connection] D as it was prior to the call.
+**          value of the limit on the size of construct C in the
+**          [database connection] D as it was prior to the call.
 */
 int sqlite3_limit(sqlite3*, int id, int newVal);
 
 /*
 ** CAPI3REF: Run-Time Limit Categories {F12790}
 ** KEYWORDS: {limit category} {limit categories}
-** 
+**
 ** These constants define various aspects of a [database connection]
 ** that can be limited in size by calls to [sqlite3_limit()].
 ** The meanings of the various limits are as follows:
 **
 ** <dl>
 ** <dt>SQLITE_LIMIT_LENGTH</dt>
-** <dd>The maximum size of any
-** string or blob or table row.<dd>
+** <dd>The maximum size of any string or BLOB or table row.<dd>
 **
 ** <dt>SQLITE_LIMIT_SQL_LENGTH</dt>
 ** <dd>The maximum length of an SQL statement.</dd>
@@ -2273,51 +2615,49 @@
 
 /*
 ** CAPI3REF: Compiling An SQL Statement {F13010}
+** KEYWORDS: {SQL statement compiler}
 **
 ** To execute an SQL query, it must first be compiled into a byte-code
-** program using one of these routines. 
+** program using one of these routines.
+**
+** The first argument, "db", is a [database connection] obtained from a
+** prior call to [sqlite3_open()], [sqlite3_open_v2()] or [sqlite3_open16()].
 **
-** The first argument "db" is an [database connection] 
-** obtained from a prior call to [sqlite3_open()], [sqlite3_open_v2()]
-** or [sqlite3_open16()]. 
-** The second argument "zSql" is the statement to be compiled, encoded
+** The second argument, "zSql", is the statement to be compiled, encoded
 ** as either UTF-8 or UTF-16.  The sqlite3_prepare() and sqlite3_prepare_v2()
-** interfaces uses UTF-8 and sqlite3_prepare16() and sqlite3_prepare16_v2()
-** use UTF-16. {END}
+** interfaces use UTF-8, and sqlite3_prepare16() and sqlite3_prepare16_v2()
+** use UTF-16.
 **
-** If the nByte argument is less
-** than zero, then zSql is read up to the first zero terminator.
-** If nByte is non-negative, then it is the maximum number of 
-** bytes read from zSql.  When nByte is non-negative, the
-** zSql string ends at either the first '\000' or '\u0000' character or 
+** If the nByte argument is less than zero, then zSql is read up to the
+** first zero terminator. If nByte is non-negative, then it is the maximum
+** number of  bytes read from zSql.  When nByte is non-negative, the
+** zSql string ends at either the first '\000' or '\u0000' character or
 ** the nByte-th byte, whichever comes first. If the caller knows
 ** that the supplied string is nul-terminated, then there is a small
-** performance advantage to be had by passing an nByte parameter that 
-** is equal to the number of bytes in the input string <i>including</i> 
-** the nul-terminator bytes.{END}
+** performance advantage to be gained by passing an nByte parameter that
+** is equal to the number of bytes in the input string <i>including</i>
+** the nul-terminator bytes.
 **
 ** *pzTail is made to point to the first byte past the end of the
-** first SQL statement in zSql.  These routines only compiles the first
+** first SQL statement in zSql.  These routines only compile the first
 ** statement in zSql, so *pzTail is left pointing to what remains
 ** uncompiled.
 **
 ** *ppStmt is left pointing to a compiled [prepared statement] that can be
-** executed using [sqlite3_step()].  Or if there is an error, *ppStmt is
-** set to NULL.  If the input text contains no SQL (if the input
-** is and empty string or a comment) then *ppStmt is set to NULL.
-** {U13018} The calling procedure is responsible for deleting the
-** compiled SQL statement
-** using [sqlite3_finalize()] after it has finished with it.
+** executed using [sqlite3_step()].  If there is an error, *ppStmt is set
+** to NULL.  If the input text contains no SQL (if the input is an empty
+** string or a comment) then *ppStmt is set to NULL.
+** {A13018} The calling procedure is responsible for deleting the compiled
+** SQL statement using [sqlite3_finalize()] after it has finished with it.
 **
-** On success, [SQLITE_OK] is returned.  Otherwise an 
-** [error code] is returned.
+** On success, [SQLITE_OK] is returned, otherwise an [error code] is returned.
 **
 ** The sqlite3_prepare_v2() and sqlite3_prepare16_v2() interfaces are
 ** recommended for all new programs. The two older interfaces are retained
 ** for backwards compatibility, but their use is discouraged.
 ** In the "v2" interfaces, the prepared statement
-** that is returned (the [sqlite3_stmt] object) contains a copy of the 
-** original SQL text. {END} This causes the [sqlite3_step()] interface to
+** that is returned (the [sqlite3_stmt] object) contains a copy of the
+** original SQL text. This causes the [sqlite3_step()] interface to
 ** behave a differently in two ways:
 **
 ** <ol>
@@ -2326,22 +2666,19 @@
 ** always used to do, [sqlite3_step()] will automatically recompile the SQL
 ** statement and try to run it again.  If the schema has changed in
 ** a way that makes the statement no longer valid, [sqlite3_step()] will still
-** return [SQLITE_SCHEMA].  But unlike the legacy behavior, 
-** [SQLITE_SCHEMA] is now a fatal error.  Calling
-** [sqlite3_prepare_v2()] again will not make the
+** return [SQLITE_SCHEMA].  But unlike the legacy behavior, [SQLITE_SCHEMA] is
+** now a fatal error.  Calling [sqlite3_prepare_v2()] again will not make the
 ** error go away.  Note: use [sqlite3_errmsg()] to find the text
-** of the parsing error that results in an [SQLITE_SCHEMA] return. {END}
+** of the parsing error that results in an [SQLITE_SCHEMA] return.
 ** </li>
 **
 ** <li>
-** When an error occurs, 
-** [sqlite3_step()] will return one of the detailed 
-** [error codes] or [extended error codes]. 
-** The legacy behavior was that [sqlite3_step()] would only return a generic
-** [SQLITE_ERROR] result code and you would have to make a second call to
-** [sqlite3_reset()] in order to find the underlying cause of the problem.
-** With the "v2" prepare interfaces, the underlying reason for the error is
-** returned immediately.
+** When an error occurs, [sqlite3_step()] will return one of the detailed
+** [error codes] or [extended error codes].  The legacy behavior was that
+** [sqlite3_step()] would only return a generic [SQLITE_ERROR] result code
+** and you would have to make a second call to [sqlite3_reset()] in order
+** to find the underlying cause of the problem. With the "v2" prepare
+** interfaces, the underlying reason for the error is returned immediately.
 ** </li>
 ** </ol>
 **
@@ -2356,11 +2693,11 @@
 **          text in their zSql parameter as UTF-16 in the native byte order.
 **
 ** {F13013} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
-**          and its variants is less than zero, then SQL text is
+**          and its variants is less than zero, the SQL text is
 **          read from zSql is read up to the first zero terminator.
 **
 ** {F13014} If the nByte argument to [sqlite3_prepare_v2(db,zSql,nByte,...)]
-**          and its variants is non-negative, then at most nBytes bytes
+**          and its variants is non-negative, then at most nBytes bytes of
 **          SQL text is read from zSql.
 **
 ** {F13015} In [sqlite3_prepare_v2(db,zSql,N,P,pzTail)] and its variants
@@ -2371,15 +2708,15 @@
 **
 ** {F13016} A successful call to [sqlite3_prepare_v2(db,zSql,N,ppStmt,...)]
 **          or one of its variants writes into *ppStmt a pointer to a new
-**          [prepared statement] or a pointer to NULL
-**          if zSql contains nothing other than whitespace or comments. 
+**          [prepared statement] or a pointer to NULL if zSql contains
+**          nothing other than whitespace or comments.
 **
 ** {F13019} The [sqlite3_prepare_v2()] interface and its variants return
 **          [SQLITE_OK] or an appropriate [error code] upon failure.
 **
 ** {F13021} Before [sqlite3_prepare(db,zSql,nByte,ppStmt,pzTail)] or its
-**          variants returns an error (any value other than [SQLITE_OK])
-**          it first sets *ppStmt to NULL.
+**          variants returns an error (any value other than [SQLITE_OK]),
+**          they first set *ppStmt to NULL.
 */
 int sqlite3_prepare(
   sqlite3 *db,            /* Database handle */
@@ -2413,24 +2750,21 @@
 /*
 ** CAPIREF: Retrieving Statement SQL {F13100}
 **
-** This intereface can be used to retrieve a saved copy of the original
-** SQL text used to create a [prepared statement].
+** This interface can be used to retrieve a saved copy of the original
+** SQL text used to create a [prepared statement] if that statement was
+** compiled using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()].
 **
 ** INVARIANTS:
 **
-** {F13101} If the [prepared statement] passed as 
-**          the an argument to [sqlite3_sql()] was compiled
-**          compiled using either [sqlite3_prepare_v2()] or
-**          [sqlite3_prepare16_v2()],
-**          then [sqlite3_sql()] function returns a pointer to a
-**          zero-terminated string containing a UTF-8 rendering
+** {F13101} If the [prepared statement] passed as the argument to
+**          [sqlite3_sql()] was compiled using either [sqlite3_prepare_v2()] or
+**          [sqlite3_prepare16_v2()], then [sqlite3_sql()] returns
+**          a pointer to a zero-terminated string containing a UTF-8 rendering
 **          of the original SQL statement.
 **
-** {F13102} If the [prepared statement] passed as 
-**          the an argument to [sqlite3_sql()] was compiled
-**          compiled using either [sqlite3_prepare()] or
-**          [sqlite3_prepare16()],
-**          then [sqlite3_sql()] function returns a NULL pointer.
+** {F13102} If the [prepared statement] passed as the argument to
+**          [sqlite3_sql()] was compiled using either [sqlite3_prepare()] or
+**          [sqlite3_prepare16()], then [sqlite3_sql()] returns a NULL pointer.
 **
 ** {F13103} The string returned by [sqlite3_sql(S)] is valid until the
 **          [prepared statement] S is deleted using [sqlite3_finalize(S)].
@@ -2438,58 +2772,65 @@
 const char *sqlite3_sql(sqlite3_stmt *pStmt);
 
 /*
-** CAPI3REF:  Dynamically Typed Value Object  {F15000}
+** CAPI3REF: Dynamically Typed Value Object {F15000}
 ** KEYWORDS: {protected sqlite3_value} {unprotected sqlite3_value}
 **
 ** SQLite uses the sqlite3_value object to represent all values
-** that can be stored in a database table.
-** SQLite uses dynamic typing for the values it stores.  
-** Values stored in sqlite3_value objects can be
-** be integers, floating point values, strings, BLOBs, or NULL.
+** that can be stored in a database table. SQLite uses dynamic typing
+** for the values it stores. Values stored in sqlite3_value objects
+** can be integers, floating point values, strings, BLOBs, or NULL.
 **
 ** An sqlite3_value object may be either "protected" or "unprotected".
 ** Some interfaces require a protected sqlite3_value.  Other interfaces
 ** will accept either a protected or an unprotected sqlite3_value.
-** Every interface that accepts sqlite3_value arguments specifies 
+** Every interface that accepts sqlite3_value arguments specifies
 ** whether or not it requires a protected sqlite3_value.
 **
 ** The terms "protected" and "unprotected" refer to whether or not
 ** a mutex is held.  A internal mutex is held for a protected
 ** 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)
-** then there is no distinction between
-** protected and unprotected sqlite3_value objects and they can be
-** used interchangable.  However, for maximum code portability it
-** is recommended that applications make the distinction between
-** between protected and unprotected sqlite3_value objects even if
-** they are single threaded.
+** (with [SQLITE_THREADSAFE=0] and with [sqlite3_threadsafe()] returning 0)
+** 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,
+** for maximum code portability it is recommended that applications
+** still make the distinction between between protected and unprotected
+** sqlite3_value objects even when not strictly required.
 **
 ** The sqlite3_value objects that are passed as parameters into the
-** implementation of application-defined SQL functions are protected.
+** implementation of [application-defined SQL functions] are protected.
 ** The sqlite3_value object returned by
 ** [sqlite3_column_value()] is unprotected.
 ** Unprotected sqlite3_value objects may only be used with
-** [sqlite3_result_value()] and [sqlite3_bind_value()].  All other
-** interfaces that use sqlite3_value require protected sqlite3_value objects.
+** [sqlite3_result_value()] and [sqlite3_bind_value()].
+** The [sqlite3_value_blob | sqlite3_value_type()] family of
+** interfaces require protected sqlite3_value objects.
 */
 typedef struct Mem sqlite3_value;
 
 /*
-** CAPI3REF:  SQL Function Context Object {F16001}
+** CAPI3REF: SQL Function Context Object {F16001}
 **
 ** The context in which an SQL function executes is stored in an
-** sqlite3_context object.  A pointer to an sqlite3_context
-** object is always first parameter to application-defined SQL functions.
+** sqlite3_context object.  A pointer to an sqlite3_context object
+** is always first parameter to [application-defined SQL functions].
+** The application-defined SQL function implementation will pass this
+** pointer through into calls to [sqlite3_result_int | sqlite3_result()],
+** [sqlite3_aggregate_context()], [sqlite3_user_data()],
+** [sqlite3_context_db_handle()], [sqlite3_get_auxdata()],
+** and/or [sqlite3_set_auxdata()].
 */
 typedef struct sqlite3_context sqlite3_context;
 
 /*
-** CAPI3REF:  Binding Values To Prepared Statements {F13500}
+** CAPI3REF: Binding Values To Prepared Statements {F13500}
+** KEYWORDS: {host parameter} {host parameters} {host parameter name}
+** KEYWORDS: {SQL parameter} {SQL parameters} {parameter binding}
 **
-** In the SQL strings input to [sqlite3_prepare_v2()] and its
-** variants, literals may be replace by a parameter in one
-** of these forms:
+** In the SQL strings input to [sqlite3_prepare_v2()] and its variants,
+** literals may be replaced by a parameter in one of these forms:
 **
 ** <ul>
 ** <li>  ?
@@ -2500,32 +2841,31 @@
 ** </ul>
 **
 ** In the parameter forms shown above NNN is an integer literal,
-** VVV alpha-numeric parameter name.
-** The values of these parameters (also called "host parameter names"
-** or "SQL parameters")
+** and VVV is an alpha-numeric parameter name. The values of these
+** parameters (also called "host parameter names" or "SQL parameters")
 ** can be set using the sqlite3_bind_*() routines defined here.
 **
-** The first argument to the sqlite3_bind_*() routines always
-** is a pointer to the [sqlite3_stmt] object returned from
-** [sqlite3_prepare_v2()] or its variants. The second
-** argument is the index of the parameter to be set. The
-** first parameter has an index of 1.  When the same named
-** parameter is used more than once, second and subsequent
-** occurrences have the same index as the first occurrence. 
+** 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.
+**
+** The second argument is the index of the SQL parameter to be set.
+** The leftmost SQL parameter has an index of 1.  When the same named
+** SQL parameter is used more than once, second and subsequent
+** occurrences have the same index as the first occurrence.
 ** The index for named parameters can be looked up using the
-** [sqlite3_bind_parameter_name()] API if desired.  The index
+** [sqlite3_bind_parameter_index()] API if desired.  The index
 ** for "?NNN" parameters is the value of NNN.
-** The NNN value must be between 1 and the compile-time
-** parameter SQLITE_MAX_VARIABLE_NUMBER (default value: 999).
+** The NNN value must be between 1 and the [sqlite3_limit()]
+** parameter [SQLITE_LIMIT_VARIABLE_NUMBER] (default value: 999).
 **
 ** The third argument is the value to bind to the parameter.
 **
-** 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 <u>bytes</u>
-** in the value, not the number of characters. 
+** 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 <u>bytes</u> in the value, not the number of characters.
 ** If the fourth parameter is negative, the length of the string is
-** number of bytes up to the first zero terminator.
+** the number of bytes up to the first zero terminator.
 **
 ** The fifth argument to sqlite3_bind_blob(), sqlite3_bind_text(), and
 ** sqlite3_bind_text16() is a destructor used to dispose of the BLOB or
@@ -2537,12 +2877,12 @@
 ** the sqlite3_bind_*() routine returns.
 **
 ** The sqlite3_bind_zeroblob() routine binds a BLOB of length N that
-** is filled with zeros.  A zeroblob uses a fixed amount of memory
-** (just an integer to hold it size) while it is being processed.
-** Zeroblobs are intended to serve as place-holders for BLOBs whose
-** content is later written using 
-** [sqlite3_blob_open | increment BLOB I/O] routines. A negative
-** value for the zeroblob results in a zero-length BLOB.
+** is filled with zeroes.  A zeroblob uses a fixed amount of memory
+** (just an integer to hold its size) while it is being processed.
+** Zeroblobs are intended to serve as placeholders for BLOBs whose
+** content is later written using
+** [sqlite3_blob_open | incremental BLOB I/O] routines.
+** A negative value for the zeroblob results in a zero-length BLOB.
 **
 ** The sqlite3_bind_*() routines must be called after
 ** [sqlite3_prepare_v2()] (and its variants) or [sqlite3_reset()] and
@@ -2552,7 +2892,7 @@
 **
 ** These routines return [SQLITE_OK] on success or an error code if
 ** anything goes wrong.  [SQLITE_RANGE] is returned if the parameter
-** index is out of range.  [SQLITE_NOMEM] is returned if malloc fails.
+** index is out of range.  [SQLITE_NOMEM] is returned if malloc() fails.
 ** [SQLITE_MISUSE] might be returned if these routines are called on a
 ** virtual machine that is the wrong state or which has already been finalized.
 ** Detection of misuse is unreliable.  Applications should not depend
@@ -2561,17 +2901,16 @@
 ** panic rather than return SQLITE_MISUSE.
 **
 ** See also: [sqlite3_bind_parameter_count()],
-** [sqlite3_bind_parameter_name()], and
-** [sqlite3_bind_parameter_index()].
+** [sqlite3_bind_parameter_name()], and [sqlite3_bind_parameter_index()].
 **
 ** INVARIANTS:
 **
-** {F13506} The [sqlite3_prepare | SQL statement compiler] recognizes
-**          tokens of the forms "?", "?NNN", "$VVV", ":VVV", and "@VVV"
-**          as SQL parameters, where NNN is any sequence of one or more
-**          digits and where VVV is any sequence of one or more 
-**          alphanumeric characters or "::" optionally followed by
-**          a string containing no spaces and contained within parentheses.
+** {F13506} The [SQL statement compiler] recognizes tokens of the forms
+**          "?", "?NNN", "$VVV", ":VVV", and "@VVV" as SQL parameters,
+**          where NNN is any sequence of one or more digits
+**          and where VVV is any sequence of one or more alphanumeric
+**          characters or "::" optionally followed by a string containing
+**          no spaces and contained within parentheses.
 **
 ** {F13509} The initial value of an SQL parameter is NULL.
 **
@@ -2582,14 +2921,15 @@
 ** {F13515} The index of an "?NNN" SQL parameter is the integer NNN.
 **
 ** {F13518} The index of an ":VVV", "$VVV", or "@VVV" SQL parameter is
-**          the same as the index of leftmost occurances of the same
+**          the same as the index of leftmost occurrences of the same
 **          parameter, or one more than the largest index over all
-**          parameters to the left if this is the first occurrance
+**          parameters to the left if this is the first occurrence
 **          of this parameter, or 1 if this is the leftmost parameter.
 **
-** {F13521} The [sqlite3_prepare | SQL statement compiler] fail with
-**          an [SQLITE_RANGE] error if the index of an SQL parameter
-**          is less than 1 or greater than SQLITE_MAX_VARIABLE_NUMBER.
+** {F13521} The [SQL statement compiler] fails with an [SQLITE_RANGE]
+**          error if the index of an SQL parameter is less than 1
+**          or greater than the compile-time SQLITE_MAX_VARIABLE_NUMBER
+**          parameter.
 **
 ** {F13524} Calls to [sqlite3_bind_text | sqlite3_bind(S,N,V,...)]
 **          associate the value V with all SQL parameters having an
@@ -2604,7 +2944,7 @@
 ** {F13533} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
 **          [sqlite3_bind_text(S,N,V,L,D)], or
 **          [sqlite3_bind_text16(S,N,V,L,D)] SQLite binds the first L
-**          bytes of the blob or string pointed to by V, when L
+**          bytes of the BLOB or string pointed to by V, when L
 **          is non-negative.
 **
 ** {F13536} In calls to [sqlite3_bind_text(S,N,V,L,D)] or
@@ -2621,17 +2961,17 @@
 ** {F13542} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
 **          [sqlite3_bind_text(S,N,V,L,D)], or
 **          [sqlite3_bind_text16(S,N,V,L,D)] when D is the special
-**          constant [SQLITE_TRANSIENT], the routine makes a 
-**          private copy of V value before it returns.
+**          constant [SQLITE_TRANSIENT], the routine makes a
+**          private copy of the value V before it returns.
 **
 ** {F13545} In calls to [sqlite3_bind_blob(S,N,V,L,D)],
 **          [sqlite3_bind_text(S,N,V,L,D)], or
 **          [sqlite3_bind_text16(S,N,V,L,D)] when D is a pointer to
 **          a function, SQLite invokes that function to destroy the
-**          V value after it has finished using the V value.
+**          value V after it has finished using the value V.
 **
 ** {F13548} In calls to [sqlite3_bind_zeroblob(S,N,V,L)] the value bound
-**          is a blob of L bytes, or a zero-length blob if L is negative.
+**          is a BLOB of L bytes, or a zero-length BLOB if L is negative.
 **
 ** {F13551} In calls to [sqlite3_bind_value(S,N,V)] the V argument may
 **          be either a [protected sqlite3_value] object or an
@@ -2650,16 +2990,16 @@
 /*
 ** CAPI3REF: Number Of SQL Parameters {F13600}
 **
-** This routine can be used to find the number of SQL parameters
-** in a prepared statement.  SQL parameters are tokens of the
+** This routine can be used to find the number of [SQL parameters]
+** in a [prepared statement].  SQL parameters are tokens of the
 ** form "?", "?NNN", ":AAA", "$AAA", or "@AAA" that serve as
-** place-holders for values that are [sqlite3_bind_blob | bound]
+** placeholders for values that are [sqlite3_bind_blob | bound]
 ** to the parameters at a later time.
 **
-** This routine actually returns the index of the largest parameter.
-** For all forms except ?NNN, this will correspond to the number of
-** unique parameters.  If parameters of the ?NNN are used, there may
-** be gaps in the list.
+** 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 are used,
+** there may be gaps in the list.
 **
 ** See also: [sqlite3_bind_blob|sqlite3_bind()],
 ** [sqlite3_bind_parameter_name()], and
@@ -2669,8 +3009,7 @@
 **
 ** {F13601} The [sqlite3_bind_parameter_count(S)] interface returns
 **          the largest index of all SQL parameters in the
-**          [prepared statement] S, or 0 if S
-**          contains no SQL parameters.
+**          [prepared statement] S, or 0 if S contains no SQL parameters.
 */
 int sqlite3_bind_parameter_count(sqlite3_stmt*);
 
@@ -2678,19 +3017,20 @@
 ** CAPI3REF: Name Of A Host Parameter {F13620}
 **
 ** This routine returns a pointer to the name of the n-th
-** SQL parameter in a [prepared statement].
+** [SQL parameter] in a [prepared statement].
 ** 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.
-** Parameters of the form "?" without a following integer have no name.
+** Parameters of the form "?" without a following integer have no name
+** and are also referred to as "anonymous parameters".
 **
 ** The first host parameter has an index of 1, not 0.
 **
 ** If the value n is out of range or if the n-th parameter is
 ** nameless, then NULL is returned.  The returned string is
-** always in the UTF-8 encoding even if the named parameter was
+** always in UTF-8 encoding even if the named parameter was
 ** originally specified as UTF-16 in [sqlite3_prepare16()] or
 ** [sqlite3_prepare16_v2()].
 **
@@ -2702,7 +3042,7 @@
 **
 ** {F13621} The [sqlite3_bind_parameter_name(S,N)] interface returns
 **          a UTF-8 rendering of the name of the SQL parameter in
-**          [prepared statement] S having index N, or
+**          the [prepared statement] S having index N, or
 **          NULL if there is no SQL parameter with index N or if the
 **          parameter with index N is an anonymous parameter "?".
 */
@@ -2725,7 +3065,7 @@
 ** INVARIANTS:
 **
 ** {F13641} The [sqlite3_bind_parameter_index(S,N)] interface returns
-**          the index of SQL parameter in [prepared statement]
+**          the index of SQL parameter in the [prepared statement]
 **          S whose name matches the UTF-8 string N, or 0 if there is
 **          no match.
 */
@@ -2734,33 +3074,29 @@
 /*
 ** CAPI3REF: Reset All Bindings On A Prepared Statement {F13660}
 **
-** Contrary to the intuition of many, [sqlite3_reset()] does not
-** reset the [sqlite3_bind_blob | bindings] on a 
-** [prepared statement].  Use this routine to
-** reset all host parameters to NULL.
+** Contrary to the intuition of many, [sqlite3_reset()] does not reset
+** the [sqlite3_bind_blob | bindings] on a [prepared statement].
+** Use this routine to reset all host parameters to NULL.
 **
 ** INVARIANTS:
 **
-** {F13661} The [sqlite3_clear_bindings(S)] interface resets all
-**          SQL parameter bindings in [prepared statement] S
-**          back to NULL.
+** {F13661} The [sqlite3_clear_bindings(S)] interface resets all SQL
+**          parameter bindings in the [prepared statement] S back to NULL.
 */
 int sqlite3_clear_bindings(sqlite3_stmt*);
 
 /*
 ** CAPI3REF: Number Of Columns In A Result Set {F13710}
 **
-** Return the number of columns in the result set returned by the 
-** [prepared statement]. This routine returns 0
-** if pStmt is an SQL statement that does not return data (for 
-** example an UPDATE).
+** Return the number of columns in the result set returned by the
+** [prepared statement]. This routine returns 0 if pStmt is an SQL
+** statement that does not return data (for example an [UPDATE]).
 **
 ** INVARIANTS:
 **
 ** {F13711} The [sqlite3_column_count(S)] interface returns the number of
-**          columns in the result set generated by the
-**          [prepared statement] S, or 0 if S does not generate
-**          a result set.
+**          columns in the result set generated by the [prepared statement] S,
+**          or 0 if S does not generate a result set.
 */
 int sqlite3_column_count(sqlite3_stmt *pStmt);
 
@@ -2768,18 +3104,16 @@
 ** CAPI3REF: Column Names In A Result Set {F13720}
 **
 ** These routines return the name assigned to a particular column
-** in the result set of a SELECT statement.  The sqlite3_column_name()
-** interface returns a pointer to a zero-terminated UTF8 string
+** in the result set of a [SELECT] statement.  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
-** UTF16 string.  The first parameter is the
-** [prepared statement] that implements the SELECT statement.
-** The second parameter is the column number.  The left-most column is
-** number 0.
-**
-** The returned string pointer is valid until either the 
-** [prepared statement] is destroyed by [sqlite3_finalize()]
-** or until the next call sqlite3_column_name() or sqlite3_column_name16()
-** on the same column.
+** UTF-16 string.  The first parameter is the [prepared statement]
+** that implements the [SELECT] statement. The second parameter is the
+** column number.  The leftmost column is number 0.
+**
+** The returned string pointer is valid until either the [prepared statement]
+** is destroyed by [sqlite3_finalize()] or until the next call to
+** sqlite3_column_name() or sqlite3_column_name16() on the same column.
 **
 ** If sqlite3_malloc() fails during the processing of either routine
 ** (for example during a conversion from UTF-8 to UTF-16) then a
@@ -2793,32 +3127,31 @@
 ** INVARIANTS:
 **
 ** {F13721} A successful invocation of the [sqlite3_column_name(S,N)]
-**          interface returns the name
-**          of the Nth column (where 0 is the left-most column) for the
-**          result set of [prepared statement] S as a
-**          zero-terminated UTF-8 string.
+**          interface returns the name of the Nth column (where 0 is
+**          the leftmost column) for the result set of the
+**          [prepared statement] S as a zero-terminated UTF-8 string.
 **
 ** {F13723} A successful invocation of the [sqlite3_column_name16(S,N)]
-**          interface returns the name
-**          of the Nth column (where 0 is the left-most column) for the
-**          result set of [prepared statement] S as a
-**          zero-terminated UTF-16 string in the native byte order.
+**          interface returns the name of the Nth column (where 0 is
+**          the leftmost column) for the result set of the
+**          [prepared statement] S as a zero-terminated UTF-16 string
+**          in the native byte order.
 **
 ** {F13724} The [sqlite3_column_name()] and [sqlite3_column_name16()]
 **          interfaces return a NULL pointer if they are unable to
-**          allocate memory memory to hold there normal return strings.
+**          allocate memory to hold their normal return strings.
 **
 ** {F13725} If the N parameter to [sqlite3_column_name(S,N)] or
 **          [sqlite3_column_name16(S,N)] is out of range, then the
-**          interfaces returns a NULL pointer.
-** 
+**          interfaces return a NULL pointer.
+**
 ** {F13726} The strings returned by [sqlite3_column_name(S,N)] and
 **          [sqlite3_column_name16(S,N)] are valid until the next
 **          call to either routine with the same S and N parameters
 **          or until [sqlite3_finalize(S)] is called.
 **
 ** {F13727} When a result column of a [SELECT] statement contains
-**          an AS clause, the name of that column is the indentifier
+**          an AS clause, the name of that column is the identifier
 **          to the right of the AS keyword.
 */
 const char *sqlite3_column_name(sqlite3_stmt*, int N);
@@ -2828,37 +3161,35 @@
 ** CAPI3REF: Source Of Data In A Query Result {F13740}
 **
 ** These routines provide a means to determine what column of what
-** table in which database a result of a SELECT statement comes from.
+** table in which database a result of a [SELECT] statement comes from.
 ** The name of the database or table or column can be returned as
-** either a UTF8 or UTF16 string.  The _database_ routines return
+** either a UTF-8 or UTF-16 string.  The _database_ routines return
 ** the database name, the _table_ routines return the table name, and
 ** the origin_ routines return the column name.
-** The returned string is valid until
-** the [prepared statement] is destroyed using
-** [sqlite3_finalize()] or until the same information is requested
+** The returned string is valid until the [prepared statement] is destroyed
+** using [sqlite3_finalize()] or until the same information is requested
 ** again in a different encoding.
 **
 ** The names returned are the original un-aliased names of the
 ** database, table, and column.
 **
 ** The first argument to the following calls is a [prepared statement].
-** These functions return information about the Nth column returned by 
+** These functions return information about the Nth column returned by
 ** the statement, where N is the second function argument.
 **
-** 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.  These routine might also return NULL if a memory
-** allocation error occurs.  Otherwise, they return the 
-** name of the attached database, table and column that query result
-** column was extracted from.
+** 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.  These routine might also return NULL if a memory allocation error
+** occurs.  Otherwise, they return the name of the attached database, table
+** and column that query result column was extracted from.
 **
 ** As with all other SQLite APIs, those postfixed with "16" return
 ** UTF-16 encoded strings, the other functions return UTF-8. {END}
 **
-** These APIs are only available if the library was compiled with the 
-** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+** These APIs are only available if the library was compiled with the
+** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
 **
-** {U13751}
+** {A13751}
 ** If two or more threads call one or more of these routines against the same
 ** prepared statement and column at the same time then the results are
 ** undefined.
@@ -2866,62 +3197,53 @@
 ** INVARIANTS:
 **
 ** {F13741} The [sqlite3_column_database_name(S,N)] interface returns either
-**          the UTF-8 zero-terminated name of the database from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-8 zero-terminated name of the database from which the
+**          Nth result column of the [prepared statement] S is extracted,
+**          or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13742} The [sqlite3_column_database_name16(S,N)] interface returns either
-**          the UTF-16 native byte order
-**          zero-terminated name of the database from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-16 native byte order zero-terminated name of the database
+**          from which the Nth result column of the [prepared statement] S is
+**          extracted, or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13743} The [sqlite3_column_table_name(S,N)] interface returns either
-**          the UTF-8 zero-terminated name of the table from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-8 zero-terminated name of the table from which the
+**          Nth result column of the [prepared statement] S is extracted,
+**          or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13744} The [sqlite3_column_table_name16(S,N)] interface returns either
-**          the UTF-16 native byte order
-**          zero-terminated name of the table from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-16 native byte order zero-terminated name of the table
+**          from which the Nth result column of the [prepared statement] S is
+**          extracted, or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13745} The [sqlite3_column_origin_name(S,N)] interface returns either
-**          the UTF-8 zero-terminated name of the table column from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
-**          to store the name.
-**          
+**          the UTF-8 zero-terminated name of the table column from which the
+**          Nth result column of the [prepared statement] S is extracted,
+**          or NULL if the Nth column of S is a general expression
+**          or if unable to allocate memory to store the name.
+**
 ** {F13746} The [sqlite3_column_origin_name16(S,N)] interface returns either
-**          the UTF-16 native byte order
-**          zero-terminated name of the table column from which the 
-**          Nth result column of [prepared statement] S 
-**          is extracted, or NULL if the the Nth column of S is a
-**          general expression or if unable to allocate memory
+**          the UTF-16 native byte order zero-terminated name of the table
+**          column from which the Nth result column of the
+**          [prepared statement] S is extracted, or NULL if the Nth column
+**          of S is a general expression or if unable to allocate memory
 **          to store the name.
-**          
+**
 ** {F13748} The return values from
-**          [sqlite3_column_database_name|column metadata interfaces]
-**          are valid
-**          for the lifetime of the [prepared statement]
+**          [sqlite3_column_database_name | column metadata interfaces]
+**          are valid for the lifetime of the [prepared statement]
 **          or until the encoding is changed by another metadata
 **          interface call for the same prepared statement and column.
 **
 ** LIMITATIONS:
 **
-** {U13751} If two or more threads call one or more
-**          [sqlite3_column_database_name|column metadata interfaces]
-**          the same [prepared statement] and result column
+** {A13751} If two or more threads call one or more
+**          [sqlite3_column_database_name | column metadata interfaces]
+**          for the same [prepared statement] and result column
 **          at the same time then the results are undefined.
 */
 const char *sqlite3_column_database_name(sqlite3_stmt*,int);
@@ -2934,24 +3256,24 @@
 /*
 ** CAPI3REF: Declared Datatype Of A Query Result {F13760}
 **
-** 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
+** 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.  If the Nth column of the result set is an
 ** expression or subquery, then a NULL pointer is returned.
-** The returned string is always UTF-8 encoded.  {END} 
-** For example, in the database schema:
+** The returned string is always UTF-8 encoded. {END}
+**
+** For example, given the database schema:
 **
 ** CREATE TABLE t1(c1 VARIANT);
 **
-** And the following statement compiled:
+** and the following statement to be compiled:
 **
 ** SELECT c1 + 1, c1 FROM t1;
 **
-** Then 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).
+** 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).
 **
 ** SQLite uses dynamic run-time typing.  So just because a column
 ** is declared to contain a particular type does not mean that the
@@ -2962,11 +3284,10 @@
 **
 ** INVARIANTS:
 **
-** {F13761}  A successful call to [sqlite3_column_decltype(S,N)]
-**           returns a zero-terminated UTF-8 string containing the
-**           the declared datatype of the table column that appears
-**           as the Nth column (numbered from 0) of the result set to the
-**           [prepared statement] S.
+** {F13761}  A successful call to [sqlite3_column_decltype(S,N)] returns a
+**           zero-terminated UTF-8 string containing the declared datatype
+**           of the table column that appears as the Nth column (numbered
+**           from 0) of the result set to the [prepared statement] S.
 **
 ** {F13762}  A successful call to [sqlite3_column_decltype16(S,N)]
 **           returns a zero-terminated UTF-16 native byte order string
@@ -2975,9 +3296,9 @@
 **           [prepared statement] S.
 **
 ** {F13763}  If N is less than 0 or N is greater than or equal to
-**           the number of columns in [prepared statement] S
+**           the number of columns in the [prepared statement] S,
 **           or if the Nth column of S is an expression or subquery rather
-**           than a table column or if a memory allocation failure
+**           than a table column, or if a memory allocation failure
 **           occurs during encoding conversions, then
 **           calls to [sqlite3_column_decltype(S,N)] or
 **           [sqlite3_column_decltype16(S,N)] return NULL.
@@ -2985,32 +3306,30 @@
 const char *sqlite3_column_decltype(sqlite3_stmt*,int);
 const void *sqlite3_column_decltype16(sqlite3_stmt*,int);
 
-/* 
-** CAPI3REF:  Evaluate An SQL Statement {F13200}
+/*
+** CAPI3REF: Evaluate An SQL Statement {F13200}
 **
-** After an [prepared statement] has been prepared with a call
-** to either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or to one of
-** the legacy interfaces [sqlite3_prepare()] or [sqlite3_prepare16()],
-** then this function must be called one or more times to evaluate the 
-** statement.
+** After a [prepared statement] has been prepared using either
+** [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] or one of the legacy
+** interfaces [sqlite3_prepare()] or [sqlite3_prepare16()], this function
+** must be called one or more times to evaluate the statement.
 **
-** The details of the behavior of this sqlite3_step() interface depend
+** The details of the behavior of the sqlite3_step() interface depend
 ** on whether the statement was prepared using the newer "v2" interface
 ** [sqlite3_prepare_v2()] and [sqlite3_prepare16_v2()] or the older legacy
 ** interface [sqlite3_prepare()] and [sqlite3_prepare16()].  The use of the
 ** new "v2" interface is recommended for new applications but the legacy
 ** interface will continue to be supported.
 **
-** In the legacy interface, the return value will be either [SQLITE_BUSY], 
+** In the legacy interface, the return value will be either [SQLITE_BUSY],
 ** [SQLITE_DONE], [SQLITE_ROW], [SQLITE_ERROR], or [SQLITE_MISUSE].
-** With the "v2" interface, any of the other [SQLITE_OK | result code]
-** or [SQLITE_IOERR_READ | extended result code] might be returned as
-** well.
+** With the "v2" interface, any of the other [result codes] or
+** [extended result codes] might be returned as well.
 **
 ** [SQLITE_BUSY] means that the database engine was unable to acquire the
-** database locks it needs to do its job.  If the statement is a COMMIT
+** database locks it needs to do its job.  If the statement is a [COMMIT]
 ** or occurs outside of an explicit transaction, then you can retry the
-** statement.  If the statement is not a COMMIT and occurs within a
+** statement.  If the statement is not a [COMMIT] and occurs within a
 ** explicit transaction then you should rollback the transaction before
 ** continuing.
 **
@@ -3019,16 +3338,15 @@
 ** machine without first calling [sqlite3_reset()] to reset the virtual
 ** machine back to its initial state.
 **
-** 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. The values may be accessed using
-** the [sqlite3_column_int | column access functions].
+** 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. The values may be accessed using the [column access functions].
 ** sqlite3_step() is called again to retrieve the next row of data.
-** 
+**
 ** [SQLITE_ERROR] means that a run-time error (such as a constraint
 ** violation) has occurred.  sqlite3_step() should not be called again on
 ** the VM. More information may be found by calling [sqlite3_errmsg()].
-** With the legacy interface, a more specific error code (example:
+** 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].  In the "v2" interface,
@@ -3036,50 +3354,47 @@
 **
 ** [SQLITE_MISUSE] means that the this routine was called inappropriately.
 ** Perhaps it was called on a [prepared statement] that has
-** already been [sqlite3_finalize | finalized] or on one that had 
+** already been [sqlite3_finalize | finalized] or on one that had
 ** previously returned [SQLITE_ERROR] or [SQLITE_DONE].  Or it could
 ** be the case that the same database connection is being used by two or
 ** more threads at the same moment in time.
 **
-** <b>Goofy Interface Alert:</b>
-** In the legacy interface, 
-** the sqlite3_step() API always returns a generic error code,
-** [SQLITE_ERROR], following any error other than [SQLITE_BUSY]
-** and [SQLITE_MISUSE].  You must call [sqlite3_reset()] or
-** [sqlite3_finalize()] in order to find one of the specific
-** [error codes] that better describes the error.
+** <b>Goofy Interface Alert:</b> In the legacy interface, the sqlite3_step()
+** API always returns a generic error code, [SQLITE_ERROR], following any
+** error other than [SQLITE_BUSY] and [SQLITE_MISUSE].  You must call
+** [sqlite3_reset()] or [sqlite3_finalize()] in order to find one of the
+** specific [error codes] that better describes the error.
 ** We admit that this is a goofy design.  The problem has been fixed
 ** with the "v2" interface.  If you prepare all of your SQL statements
 ** using either [sqlite3_prepare_v2()] or [sqlite3_prepare16_v2()] instead
-** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()], then the 
-** more specific [error codes] are returned directly
+** of the legacy [sqlite3_prepare()] and [sqlite3_prepare16()] interfaces,
+** then the more specific [error codes] are returned directly
 ** by sqlite3_step().  The use of the "v2" interface is recommended.
 **
 ** INVARIANTS:
 **
-** {F13202}  If [prepared statement] S is ready to be
-**           run, then [sqlite3_step(S)] advances that prepared statement
-**           until to completion or until it is ready to return another
-**           row of the result set or an interrupt or run-time error occurs.
-**
-** {F15304}  When a call to [sqlite3_step(S)] causes the 
-**           [prepared statement] S to run to completion,
-**           the function returns [SQLITE_DONE].
-**
-** {F15306}  When a call to [sqlite3_step(S)] stops because it is ready
-**           to return another row of the result set, it returns
-**           [SQLITE_ROW].
+** {F13202}  If the [prepared statement] S is ready to be run, then
+**           [sqlite3_step(S)] advances that prepared statement until
+**           completion or until it is ready to return another row of the
+**           result set, or until an [sqlite3_interrupt | interrupt]
+**           or a run-time error occurs.
+**
+** {F15304}  When a call to [sqlite3_step(S)] causes the [prepared statement]
+**           S to run to completion, the function returns [SQLITE_DONE].
+**
+** {F15306}  When a call to [sqlite3_step(S)] stops because it is ready to
+**           return another row of the result set, it returns [SQLITE_ROW].
 **
 ** {F15308}  If a call to [sqlite3_step(S)] encounters an
-**           [sqlite3_interrupt|interrupt] or a run-time error,
-**           it returns an appropraite error code that is not one of
+**           [sqlite3_interrupt | interrupt] or a run-time error,
+**           it returns an appropriate error code that is not one of
 **           [SQLITE_OK], [SQLITE_ROW], or [SQLITE_DONE].
 **
-** {F15310}  If an [sqlite3_interrupt|interrupt] or run-time error
+** {F15310}  If an [sqlite3_interrupt | interrupt] or a run-time error
 **           occurs during a call to [sqlite3_step(S)]
 **           for a [prepared statement] S created using
 **           legacy interfaces [sqlite3_prepare()] or
-**           [sqlite3_prepare16()] then the function returns either
+**           [sqlite3_prepare16()], then the function returns either
 **           [SQLITE_ERROR], [SQLITE_BUSY], or [SQLITE_MISUSE].
 */
 int sqlite3_step(sqlite3_stmt*);
@@ -3087,21 +3402,19 @@
 /*
 ** CAPI3REF: Number of columns in a result set {F13770}
 **
-** Return the number of values in the current row of the result set.
+** Returns the number of values in the current row of the result set.
 **
 ** INVARIANTS:
 **
-** {F13771}  After a call to [sqlite3_step(S)] that returns
-**           [SQLITE_ROW], the [sqlite3_data_count(S)] routine
-**           will return the same value as the
-**           [sqlite3_column_count(S)] function.
+** {F13771}  After a call to [sqlite3_step(S)] that returns [SQLITE_ROW],
+**           the [sqlite3_data_count(S)] routine will return the same value
+**           as the [sqlite3_column_count(S)] function.
 **
 ** {F13772}  After [sqlite3_step(S)] has returned any value other than
-**           [SQLITE_ROW] or before [sqlite3_step(S)] has been 
-**           called on the [prepared statement] for
-**           the first time since it was [sqlite3_prepare|prepared]
-**           or [sqlite3_reset|reset], the [sqlite3_data_count(S)]
-**           routine returns zero.
+**           [SQLITE_ROW] or before [sqlite3_step(S)] has been called on the
+**           [prepared statement] for the first time since it was
+**           [sqlite3_prepare | prepared] or [sqlite3_reset | reset],
+**           the [sqlite3_data_count(S)] routine returns zero.
 */
 int sqlite3_data_count(sqlite3_stmt *pStmt);
 
@@ -3109,7 +3422,7 @@
 ** CAPI3REF: Fundamental Datatypes {F10265}
 ** KEYWORDS: SQLITE_TEXT
 **
-** {F10266}Every value in SQLite has one of five fundamental datatypes:
+** {F10266} Every value in SQLite has one of five fundamental datatypes:
 **
 ** <ul>
 ** <li> 64-bit signed integer
@@ -3123,7 +3436,7 @@
 **
 ** Note that the SQLITE_TEXT constant was also used in SQLite version 2
 ** for a completely different meaning.  Software that links against both
-** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT not
+** SQLite version 2 and SQLite version 3 should use SQLITE3_TEXT, not
 ** SQLITE_TEXT.
 */
 #define SQLITE_INTEGER  1
@@ -3138,33 +3451,31 @@
 #define SQLITE3_TEXT     3
 
 /*
-** CAPI3REF: Results Values From A Query {F13800}
+** CAPI3REF: Result Values From A Query {F13800}
+** KEYWORDS: {column access functions}
 **
 ** These routines form the "result set query" interface.
 **
-** These routines return information about
-** a single column of the current result row of a query.  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.  The left-most column of the result set
-** has an index of 0.
+** These routines return information about a single column of the current
+** result row of a query.  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.  The leftmost column of the result set has the index 0.
 **
-** If the SQL statement is not currently point to a valid row, or if the
-** the column index is out of range, the result is undefined. 
+** If the SQL statement does not currently point to a valid row, or if the
+** column index is out of range, the result is undefined.
 ** These routines may only be called when the most recent call to
 ** [sqlite3_step()] has returned [SQLITE_ROW] and neither
-** [sqlite3_reset()] nor [sqlite3_finalize()] has been call subsequently.
+** [sqlite3_reset()] nor [sqlite3_finalize()] have been called subsequently.
 ** If any of these routines are called after [sqlite3_reset()] or
 ** [sqlite3_finalize()] or after [sqlite3_step()] has returned
 ** something other than [SQLITE_ROW], the results are undefined.
 ** If [sqlite3_step()] or [sqlite3_reset()] or [sqlite3_finalize()]
 ** are called from a different thread while any of these routines
-** are pending, then the results are undefined.  
+** are pending, then the results are undefined.
 **
-** The sqlite3_column_type() routine returns 
+** The sqlite3_column_type() routine returns the
 ** [SQLITE_INTEGER | datatype code] for the initial data type
 ** of the result column.  The returned value is one of [SQLITE_INTEGER],
 ** [SQLITE_FLOAT], [SQLITE_TEXT], [SQLITE_BLOB], or [SQLITE_NULL].  The value
@@ -3174,7 +3485,7 @@
 ** versions of SQLite may change the behavior of sqlite3_column_type()
 ** following a type conversion.
 **
-** If the result is a BLOB or UTF-8 string then the sqlite3_column_bytes() 
+** 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.
 ** 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.
@@ -3187,11 +3498,11 @@
 **
 ** Strings returned by sqlite3_column_text() and sqlite3_column_text16(),
 ** even empty strings, are always zero terminated.  The return
-** value from sqlite3_column_blob() for a zero-length blob is an arbitrary
+** value from sqlite3_column_blob() for a zero-length BLOB is an arbitrary
 ** pointer, possibly even a NULL pointer.
 **
 ** The sqlite3_column_bytes16() routine is similar to sqlite3_column_bytes()
-** but leaves the result in UTF-16 in native byte order instead of UTF-8.  
+** but leaves the result in UTF-16 in native byte order instead of UTF-8.
 ** The zero terminator is not included in this count.
 **
 ** The object returned by [sqlite3_column_value()] is an
@@ -3199,15 +3510,14 @@
 ** may only be used with [sqlite3_bind_value()] and [sqlite3_result_value()].
 ** If the [unprotected sqlite3_value] object returned by
 ** [sqlite3_column_value()] is used in any other way, including calls
-** to routines like 
-** [sqlite3_value_int()], [sqlite3_value_text()], or [sqlite3_value_bytes()],
-** then the behavior is undefined.
+** to routines like [sqlite3_value_int()], [sqlite3_value_text()],
+** or [sqlite3_value_bytes()], then the behavior is undefined.
 **
 ** These routines attempt to convert the value where appropriate.  For
 ** example, if the internal representation is FLOAT and a text result
-** is requested, [sqlite3_snprintf()] is used internally to do the conversion
-** automatically.  The following table details the conversions that
-** are applied:
+** is requested, [sqlite3_snprintf()] is used internally to perform the
+** conversion automatically.  The following table details the conversions
+** that are applied:
 **
 ** <blockquote>
 ** <table border="1">
@@ -3219,7 +3529,7 @@
 ** <tr><td>  NULL    <td>   BLOB    <td> Result is NULL pointer
 ** <tr><td> INTEGER  <td>  FLOAT    <td> Convert from integer to float
 ** <tr><td> INTEGER  <td>   TEXT    <td> ASCII rendering of the integer
-** <tr><td> INTEGER  <td>   BLOB    <td> Same as for INTEGER->TEXT
+** <tr><td> INTEGER  <td>   BLOB    <td> Same as INTEGER->TEXT
 ** <tr><td>  FLOAT   <td> INTEGER   <td> Convert from float to integer
 ** <tr><td>  FLOAT   <td>   TEXT    <td> ASCII rendering of the float
 ** <tr><td>  FLOAT   <td>   BLOB    <td> Same as FLOAT->TEXT
@@ -3234,57 +3544,56 @@
 **
 ** The table above makes reference to standard C library functions atoi()
 ** and atof().  SQLite does not really use these functions.  It has its
-** on equavalent internal routines.  The atoi() and atof() names are
+** own equivalent internal routines.  The atoi() and atof() names are
 ** used in the table for brevity and because they are familiar to most
 ** C programmers.
 **
 ** Note that when type conversions occur, pointers returned by prior
 ** calls to sqlite3_column_blob(), sqlite3_column_text(), and/or
-** sqlite3_column_text16() may be invalidated. 
+** sqlite3_column_text16() may be invalidated.
 ** Type conversions and pointer invalidations might occur
 ** in the following cases:
 **
 ** <ul>
-** <li><p>  The initial content is a BLOB and sqlite3_column_text() 
-**          or sqlite3_column_text16() is called.  A zero-terminator might
-**          need to be added to the string.</p></li>
-**
-** <li><p>  The initial content is UTF-8 text and sqlite3_column_bytes16() or
-**          sqlite3_column_text16() is called.  The content must be converted
-**          to UTF-16.</p></li>
-**
-** <li><p>  The initial content is UTF-16 text and sqlite3_column_bytes() or
-**          sqlite3_column_text() is called.  The content must be converted
-**          to UTF-8.</p></li>
+** <li> The initial content is a BLOB and sqlite3_column_text() or
+**      sqlite3_column_text16() is called.  A zero-terminator might
+**      need to be added to the string.</li>
+** <li> The initial content is UTF-8 text and sqlite3_column_bytes16() or
+**      sqlite3_column_text16() is called.  The content must be converted
+**      to UTF-16.</li>
+** <li> The initial content is UTF-16 text and sqlite3_column_bytes() or
+**      sqlite3_column_text() is called.  The content must be converted
+**      to UTF-8.</li>
 ** </ul>
 **
 ** 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 points to will have been modified.  Other kinds
-** of conversion are done in place when it is possible, but sometime it is
-** not possible and in those cases prior pointers are invalidated.  
+** of conversion are done in place when it is possible, but sometimes they
+** are not possible and in those cases prior pointers are invalidated.
 **
 ** The safest and easiest to remember policy is to invoke these routines
 ** in one of the following ways:
 **
-**  <ul>
+** <ul>
 **  <li>sqlite3_column_text() followed by sqlite3_column_bytes()</li>
 **  <li>sqlite3_column_blob() followed by sqlite3_column_bytes()</li>
 **  <li>sqlite3_column_text16() followed by sqlite3_column_bytes16()</li>
-**  </ul>
+** </ul>
 **
-** In other words, you should call sqlite3_column_text(), sqlite3_column_blob(),
-** or sqlite3_column_text16() first to force the result into the desired
-** format, then invoke sqlite3_column_bytes() or sqlite3_column_bytes16() to
-** find the size of the result.  Do not mix call to sqlite3_column_text() or
-** sqlite3_column_blob() with calls to sqlite3_column_bytes16().  And do not
-** mix calls to sqlite3_column_text16() with calls to sqlite3_column_bytes().
+** In other words, you should call sqlite3_column_text(),
+** sqlite3_column_blob(), or sqlite3_column_text16() first to force the result
+** into the desired format, then invoke sqlite3_column_bytes() or
+** sqlite3_column_bytes16() to find the size of the result.  Do not mix calls
+** to sqlite3_column_text() or sqlite3_column_blob() with calls to
+** sqlite3_column_bytes16(), and do not mix calls to sqlite3_column_text16()
+** with calls to sqlite3_column_bytes().
 **
 ** 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.  The memory space used to hold strings
-** and blobs is freed automatically.  Do <b>not</b> pass the pointers returned
-** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into 
+** and BLOBs is freed automatically.  Do <b>not</b> pass the pointers returned
+** [sqlite3_column_blob()], [sqlite3_column_text()], etc. into
 ** [sqlite3_free()].
 **
 ** If a memory allocation error occurs during the evaluation of any
@@ -3297,11 +3606,11 @@
 **
 ** {F13803} The [sqlite3_column_blob(S,N)] interface converts the
 **          Nth column in the current row of the result set for
-**          [prepared statement] S into a blob and then returns a
+**          the [prepared statement] S into a BLOB and then returns a
 **          pointer to the converted value.
 **
 ** {F13806} The [sqlite3_column_bytes(S,N)] interface returns the
-**          number of bytes in the blob or string (exclusive of the
+**          number of bytes in the BLOB or string (exclusive of the
 **          zero terminator on the string) that was returned by the
 **          most recent call to [sqlite3_column_blob(S,N)] or
 **          [sqlite3_column_text(S,N)].
@@ -3312,41 +3621,41 @@
 **          most recent call to [sqlite3_column_text16(S,N)].
 **
 ** {F13812} The [sqlite3_column_double(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a floating point value and
 **          returns a copy of that value.
 **
 ** {F13815} The [sqlite3_column_int(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a 64-bit signed integer and
 **          returns the lower 32 bits of that integer.
 **
 ** {F13818} The [sqlite3_column_int64(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a 64-bit signed integer and
 **          returns a copy of that integer.
 **
 ** {F13821} The [sqlite3_column_text(S,N)] interface converts the
 **          Nth column in the current row of the result set for
-**          [prepared statement] S into a zero-terminated UTF-8 
+**          the [prepared statement] S into a zero-terminated UTF-8
 **          string and returns a pointer to that string.
 **
 ** {F13824} The [sqlite3_column_text16(S,N)] interface converts the
-**          Nth column in the current row of the result set for
+**          Nth column in the current row of the result set for the
 **          [prepared statement] S into a zero-terminated 2-byte
-**          aligned UTF-16 native byte order
-**          string and returns a pointer to that string.
+**          aligned UTF-16 native byte order string and returns
+**          a pointer to that string.
 **
 ** {F13827} The [sqlite3_column_type(S,N)] interface returns
 **          one of [SQLITE_NULL], [SQLITE_INTEGER], [SQLITE_FLOAT],
 **          [SQLITE_TEXT], or [SQLITE_BLOB] as appropriate for
 **          the Nth column in the current row of the result set for
-**          [prepared statement] S.
+**          the [prepared statement] S.
 **
 ** {F13830} The [sqlite3_column_value(S,N)] interface returns a
 **          pointer to an [unprotected sqlite3_value] object for the
 **          Nth column in the current row of the result set for
-**          [prepared statement] S.
+**          the [prepared statement] S.
 */
 const void *sqlite3_column_blob(sqlite3_stmt*, int iCol);
 int sqlite3_column_bytes(sqlite3_stmt*, int iCol);
@@ -3362,19 +3671,17 @@
 /*
 ** CAPI3REF: Destroy A Prepared Statement Object {F13300}
 **
-** The sqlite3_finalize() function is called to delete a 
-** [prepared statement]. If the statement was
-** executed successfully, or not executed at all, then SQLITE_OK is returned.
-** If execution of the statement failed then an 
-** [error code] or [extended error code]
-** is returned. 
+** The sqlite3_finalize() function is called to delete a [prepared statement].
+** If the statement was executed successfully or not executed at all, then
+** SQLITE_OK is returned. If execution of the statement failed then an
+** [error code] or [extended error code] is returned.
 **
 ** This routine can be called at any point during the execution of the
-** [prepared statement].  If the virtual machine has not 
+** [prepared statement].  If the virtual machine has not
 ** completed execution when this routine is called, that is like
-** encountering an error or an interrupt.  (See [sqlite3_interrupt()].) 
-** Incomplete updates may be rolled back and transactions cancelled,  
-** depending on the circumstances, and the 
+** encountering an error or an [sqlite3_interrupt | interrupt].
+** Incomplete updates may be rolled back and transactions canceled,
+** depending on the circumstances, and the
 ** [error code] returned will be [SQLITE_ABORT].
 **
 ** INVARIANTS:
@@ -3392,9 +3699,8 @@
 /*
 ** CAPI3REF: Reset A Prepared Statement Object {F13330}
 **
-** The sqlite3_reset() function is called to reset a 
-** [prepared statement] object.
-** back to its initial state, ready to be re-executed.
+** The sqlite3_reset() function is called to reset a [prepared statement]
+** object back to its initial state, ready to be re-executed.
 ** Any SQL statement variables that had values bound to them using
 ** the [sqlite3_bind_blob | sqlite3_bind_*() API] retain their values.
 ** Use [sqlite3_clear_bindings()] to reset the bindings.
@@ -3402,48 +3708,49 @@
 ** {F11332} The [sqlite3_reset(S)] interface resets the [prepared statement] S
 **          back to the beginning of its program.
 **
-** {F11334} If the most recent call to [sqlite3_step(S)] for 
+** {F11334} 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].
 **
-** {F11336} If the most recent call to [sqlite3_step(S)] for
+** {F11336} 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].
 **
 ** {F11338} The [sqlite3_reset(S)] interface does not change the values
-**          of any [sqlite3_bind_blob|bindings] on [prepared statement] S.
+**          of any [sqlite3_bind_blob|bindings] on the [prepared statement] S.
 */
 int sqlite3_reset(sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Create Or Redefine SQL Functions {F16100}
-** KEYWORDS: {function creation routines} 
-**
-** These two 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
-** difference only between the two is that the second parameter, the
-** name of the (scalar) function or aggregate, is encoded in UTF-8 for
-** sqlite3_create_function() and UTF-16 for sqlite3_create_function16().
+** KEYWORDS: {function creation routines}
+** KEYWORDS: {application-defined SQL function}
+** KEYWORDS: {application-defined SQL functions}
+**
+** These two 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 difference between the
+** two is that the second parameter, the name of the (scalar) function or
+** aggregate, is encoded in UTF-8 for sqlite3_create_function() and UTF-16
+** for sqlite3_create_function16().
 **
 ** The first parameter is the [database connection] to which the SQL
-** function is to be added.  If a single
-** program uses more than one [database connection] internally, then SQL
-** functions must be added individually to each [database connection].
-**
-** 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, exclusive of the 
-** zero-terminator.  Note that the name length limit is in bytes, not
+** function is to be added.  If a single program uses more than one database
+** connection internally, then SQL functions must be added individually to
+** each database connection.
+**
+** 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, exclusive of
+** the zero-terminator.  Note that the name length limit is in bytes, not
 ** characters.  Any attempt to create a function with a longer name
-** will result in an SQLITE_ERROR error.
+** will result in [SQLITE_ERROR] being returned.
 **
 ** The third parameter is the number of arguments that the SQL function or
 ** aggregate takes. If this parameter is negative, then the SQL function or
 ** aggregate may take any number of arguments.
 **
-** The fourth parameter, eTextRep, specifies what 
+** The fourth parameter, eTextRep, specifies what
 ** [SQLITE_UTF8 | text encoding] this SQL function prefers for
 ** its parameters.  Any SQL function implementation should be able to work
 ** work with UTF-8, UTF-16le, or UTF-16be.  But some implementations may be
@@ -3452,26 +3759,23 @@
 ** times with the same function but with different values of eTextRep.
 ** When multiple implementations of the same function are available, SQLite
 ** will pick the one that involves the least amount of data conversion.
-** If there is only a single implementation which does not care what
-** text encoding is used, then the fourth argument should be
-** [SQLITE_ANY].
-**
-** The fifth parameter is an arbitrary pointer.  The implementation
-** of the function can gain access to this pointer using
-** [sqlite3_user_data()].
+** If there is only a single implementation which does not care what text
+** encoding is used, then the fourth argument should be [SQLITE_ANY].
+**
+** The fifth parameter is an arbitrary pointer.  The implementation of the
+** function can gain access to this pointer using [sqlite3_user_data()].
 **
 ** The seventh, eighth and ninth parameters, xFunc, xStep and xFinal, are
-** pointers to C-language functions that implement the SQL
-** function or aggregate. A scalar SQL function requires an implementation of
-** the xFunc callback only, NULL pointers should be passed as the xStep
-** and xFinal parameters. An aggregate SQL function requires an implementation
-** of xStep and xFinal and NULL should be passed for xFunc. To delete an
-** existing SQL function or aggregate, pass NULL for all three function
-** callback.
+** pointers to C-language functions that implement the SQL function or
+** aggregate. A scalar SQL function requires an implementation of the xFunc
+** callback only, NULL pointers should be passed as the xStep and xFinal
+** parameters. An aggregate SQL function requires an implementation of xStep
+** and xFinal and NULL should be passed for xFunc. To delete an existing
+** SQL function or aggregate, pass NULL for all three function callbacks.
 **
 ** It is permitted to register multiple implementations of the same
 ** functions with the same name but with either differing numbers of
-** arguments or differing perferred text encodings.  SQLite will use
+** arguments or differing preferred text encodings.  SQLite will use
 ** the implementation most closely matches the way in which the
 ** SQL function is used.
 **
@@ -3479,15 +3783,14 @@
 **
 ** {F16103} The [sqlite3_create_function16()] interface behaves exactly
 **          like [sqlite3_create_function()] in every way except that it
-**          interprets the zFunctionName argument as
-**          zero-terminated UTF-16 native byte order instead of as a
-**          zero-terminated UTF-8.
+**          interprets the zFunctionName argument as zero-terminated UTF-16
+**          native byte order instead of as zero-terminated UTF-8.
 **
 ** {F16106} A successful invocation of
 **          the [sqlite3_create_function(D,X,N,E,...)] interface registers
-**          or replaces callback functions in [database connection] D
+**          or replaces callback functions in the [database connection] D
 **          used to implement the SQL function named X with N parameters
-**          and having a perferred text encoding of E.
+**          and having a preferred text encoding of E.
 **
 ** {F16109} A successful call to [sqlite3_create_function(D,X,N,E,P,F,S,L)]
 **          replaces the P, F, S, and L values from any prior calls with
@@ -3531,7 +3834,7 @@
 **          database encoding is preferred.
 **
 ** {F16139} For an aggregate SQL function created using
-**          [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finializer
+**          [sqlite3_create_function(D,X,N,E,P,0,S,L)] the finalizer
 **          function L will always be invoked exactly once if the
 **          step function S is called one or more times.
 **
@@ -3610,42 +3913,40 @@
 ** Any attempt to use these routines on an [unprotected sqlite3_value]
 ** object results in undefined behavior.
 **
-** These routines work just like the corresponding 
-** [sqlite3_column_blob | sqlite3_column_* routines] except that 
-** these routines take a single [protected sqlite3_value] object pointer
-** instead of an [sqlite3_stmt*] pointer and an integer column number.
+** 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.
 **
-** The sqlite3_value_text16() interface extracts a UTF16 string
+** The sqlite3_value_text16() interface extracts a UTF-16 string
 ** in the native byte-order of the host machine.  The
 ** sqlite3_value_text16be() and sqlite3_value_text16le() interfaces
-** extract UTF16 strings as big-endian and little-endian respectively.
+** extract UTF-16 strings as big-endian and little-endian respectively.
 **
 ** 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 done.  Otherwise no conversion occurs.  The 
-** [SQLITE_INTEGER | datatype] after conversion is returned.
+** words, if the value is a string that looks like a number)
+** then the conversion is performed.  Otherwise no conversion occurs.
+** The [SQLITE_INTEGER | datatype] after conversion is returned.
 **
-** Please pay particular attention to the fact that the pointer that
-** is returned from [sqlite3_value_blob()], [sqlite3_value_text()], or
+** Please pay particular attention to the fact that the pointer returned
+** from [sqlite3_value_blob()], [sqlite3_value_text()], or
 ** [sqlite3_value_text16()] can be invalidated by a subsequent call to
 ** [sqlite3_value_bytes()], [sqlite3_value_bytes16()], [sqlite3_value_text()],
-** or [sqlite3_value_text16()].  
+** or [sqlite3_value_text16()].
 **
 ** These routines must be called from the same thread as
 ** the SQL function that supplied the [sqlite3_value*] parameters.
 **
-**
 ** INVARIANTS:
 **
 ** {F15103} The [sqlite3_value_blob(V)] interface converts the
-**          [protected sqlite3_value] object V into a blob and then returns a
-**          pointer to the converted value.
+**          [protected sqlite3_value] object V into a BLOB and then
+**          returns a pointer to the converted value.
 **
 ** {F15106} The [sqlite3_value_bytes(V)] interface returns the
-**          number of bytes in the blob or string (exclusive of the
+**          number of bytes in the BLOB or string (exclusive of the
 **          zero terminator on the string) that was returned by the
 **          most recent call to [sqlite3_value_blob(V)] or
 **          [sqlite3_value_text(V)].
@@ -3669,7 +3970,7 @@
 **          returns a copy of that integer.
 **
 ** {F15121} The [sqlite3_value_text(V)] interface converts the
-**          [protected sqlite3_value] object V into a zero-terminated UTF-8 
+**          [protected sqlite3_value] object V into a zero-terminated UTF-8
 **          string and returns a pointer to that string.
 **
 ** {F15124} The [sqlite3_value_text16(V)] interface converts the
@@ -3697,8 +3998,8 @@
 **          a floating point value if it can do so without loss of
 **          information, and returns one of [SQLITE_NULL],
 **          [SQLITE_INTEGER], [SQLITE_FLOAT], [SQLITE_TEXT], or
-**          [SQLITE_BLOB] as appropriate for
-**          the [protected sqlite3_value] object V after the conversion attempt.
+**          [SQLITE_BLOB] as appropriate for the
+**          [protected sqlite3_value] object V after the conversion attempt.
 */
 const void *sqlite3_value_blob(sqlite3_value*);
 int sqlite3_value_bytes(sqlite3_value*);
@@ -3717,22 +4018,21 @@
 ** CAPI3REF: Obtain Aggregate Function Context {F16210}
 **
 ** The implementation of aggregate SQL functions use this routine to allocate
-** a structure for storing their state.  
-** The first time the sqlite3_aggregate_context() routine is
-** is called for a particular aggregate, SQLite allocates nBytes of memory
-** zeros that memory, and returns a pointer to it.
-** On second and subsequent calls to sqlite3_aggregate_context()
-** for the same aggregate function index, the same buffer is returned.
-** The implementation
-** of the aggregate can use the returned buffer to accumulate data.
+** a structure for storing their state.
+**
+** The first time the sqlite3_aggregate_context() routine is called for a
+** particular aggregate, SQLite allocates nBytes of memory, zeroes out that
+** memory, and returns a pointer to it. On second and subsequent calls to
+** sqlite3_aggregate_context() for the same aggregate function index,
+** the same buffer is returned. The implementation of the aggregate can use
+** the returned buffer to accumulate data.
 **
 ** SQLite automatically frees the allocated buffer when the aggregate
 ** query concludes.
 **
-** The first parameter should be a copy of the 
-** [sqlite3_context | SQL function context] that is the first
-** parameter to the callback routine that implements the aggregate
-** function.
+** The first parameter should be a copy of the
+** [sqlite3_context | SQL function context] that is the first parameter
+** to the callback routine that implements the aggregate function.
 **
 ** This routine must be called from the same thread in which
 ** the aggregate SQL function is running.
@@ -3741,9 +4041,8 @@
 **
 ** {F16211} The first invocation of [sqlite3_aggregate_context(C,N)] for
 **          a particular instance of an aggregate function (for a particular
-**          context C) causes SQLite to allocation N bytes of memory,
-**          zero that memory, and return a pointer to the allocationed
-**          memory.
+**          context C) causes SQLite to allocate N bytes of memory,
+**          zero that memory, and return a pointer to the allocated memory.
 **
 ** {F16213} If a memory allocation error occurs during
 **          [sqlite3_aggregate_context(C,N)] then the function returns 0.
@@ -3765,7 +4064,7 @@
 **
 ** The sqlite3_user_data() interface returns a copy of
 ** the pointer that was the pUserData parameter (the 5th parameter)
-** of the the [sqlite3_create_function()]
+** of the [sqlite3_create_function()]
 ** and [sqlite3_create_function16()] routines that originally
 ** registered the application defined function. {END}
 **
@@ -3777,8 +4076,7 @@
 ** {F16243} The [sqlite3_user_data(C)] interface returns a copy of the
 **          P pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
 **          or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
-**          registered the SQL function associated with 
-**          [sqlite3_context] C.
+**          registered the SQL function associated with [sqlite3_context] C.
 */
 void *sqlite3_user_data(sqlite3_context*);
 
@@ -3787,7 +4085,7 @@
 **
 ** The sqlite3_context_db_handle() interface returns a copy of
 ** the pointer to the [database connection] (the 1st parameter)
-** of the the [sqlite3_create_function()]
+** of the [sqlite3_create_function()]
 ** and [sqlite3_create_function16()] routines that originally
 ** registered the application defined function.
 **
@@ -3796,8 +4094,7 @@
 ** {F16253} The [sqlite3_context_db_handle(C)] interface returns a copy of the
 **          D pointer from the [sqlite3_create_function(D,X,N,E,P,F,S,L)]
 **          or [sqlite3_create_function16(D,X,N,E,P,F,S,L)] call that
-**          registered the SQL function associated with 
-**          [sqlite3_context] C.
+**          registered the SQL function associated with [sqlite3_context] C.
 */
 sqlite3 *sqlite3_context_db_handle(sqlite3_context*);
 
@@ -3805,40 +4102,38 @@
 ** CAPI3REF: Function Auxiliary Data {F16270}
 **
 ** The following two functions may be used by scalar SQL functions to
-** associate meta-data with argument values. If the same value is passed 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 meta-data may be preserved. This may
+** some circumstances the associated metadata may be preserved. This may
 ** be used, for example, to add a regular-expression matching scalar
 ** function. The compiled version of the regular expression is stored as
-** meta-data associated with the SQL value passed as the regular expression
+** metadata associated with the SQL value passed as the regular expression
 ** pattern.  The compiled regular expression can be reused on multiple
 ** invocations of the same function so that the original pattern string
 ** does not need to be recompiled on each invocation.
 **
-** The sqlite3_get_auxdata() interface returns a pointer to the meta-data
+** The sqlite3_get_auxdata() interface returns a pointer to the metadata
 ** associated by the sqlite3_set_auxdata() function with the Nth argument
-** value to the application-defined function.
-** If no meta-data has been ever been set for the Nth
-** argument of the function, or if the cooresponding function parameter
-** has changed since the meta-data was set, then sqlite3_get_auxdata()
-** returns a NULL pointer.
+** value to the application-defined function. If no metadata has been ever
+** been set for the Nth argument of the function, or if the corresponding
+** function parameter has changed since the meta-data was set,
+** then sqlite3_get_auxdata() returns a NULL pointer.
 **
-** The sqlite3_set_auxdata() interface saves the meta-data
-** pointed to by its 3rd parameter as the meta-data for the N-th
+** The sqlite3_set_auxdata() interface saves the metadata
+** pointed to by its 3rd parameter as the metadata for the N-th
 ** argument of the application-defined function.  Subsequent
 ** calls to sqlite3_get_auxdata() might return this data, if it has
-** not been destroyed. 
-** If it is not NULL, SQLite will invoke the destructor 
+** not been destroyed.
+** If it is not NULL, SQLite will invoke the destructor
 ** function given by the 4th parameter to sqlite3_set_auxdata() on
-** the meta-data when the corresponding function parameter changes
+** the metadata when the corresponding function parameter changes
 ** or when the SQL statement completes, whichever comes first.
 **
-** SQLite is free to call the destructor and drop meta-data on
-** any parameter of any function at any time.  The only guarantee
-** is that the destructor will be called before the metadata is
-** dropped.
+** SQLite is free to call the destructor and drop metadata on any
+** parameter of any function at any time.  The only guarantee is that
+** the destructor will be called before the metadata is dropped.
 **
-** In practice, meta-data is preserved between function calls for
+** In practice, metadata is preserved between function calls for
 ** expressions that are constant at compile time. This includes literal
 ** values and SQL variables.
 **
@@ -3853,8 +4148,7 @@
 **          with that parameter.
 **
 ** {F16274} The [sqlite3_set_auxdata(C,N,P,D)] interface assigns a metadata
-**          pointer P to the Nth parameter of the SQL function with context
-**          C.
+**          pointer P to the Nth parameter of the SQL function with context C.
 **
 ** {F16276} SQLite will invoke the destructor D with a single argument
 **          which is the metadata pointer P following a call to
@@ -3879,10 +4173,10 @@
 /*
 ** CAPI3REF: Constants Defining Special Destructor Behavior {F10280}
 **
-** These are special value for the destructor that is passed in as the
+** These are special values for the destructor that is passed in as the
 ** final argument to routines like [sqlite3_result_blob()].  If the destructor
 ** argument is SQLITE_STATIC, it means that the content pointer is constant
-** and will never change.  It does not need to be destroyed.  The 
+** and will never change.  It does not need to be destroyed.  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.
@@ -3902,23 +4196,21 @@
 ** [sqlite3_create_function()] and [sqlite3_create_function16()]
 ** for additional information.
 **
-** These functions work very much like the 
-** [sqlite3_bind_blob | sqlite3_bind_*] family of functions used
-** to bind values to host parameters in prepared statements.
-** Refer to the
-** [sqlite3_bind_blob | sqlite3_bind_* documentation] for
-** additional information.
+** These functions work very much like the [parameter binding] family of
+** functions used to bind values to host parameters in prepared statements.
+** Refer to the [SQL parameter] documentation for additional information.
 **
 ** The sqlite3_result_blob() interface sets the result from
-** an application defined function to be the BLOB whose content is pointed
+** 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. 
-** The sqlite3_result_zeroblob() inerfaces set the result of
-** the application defined function to be a BLOB containing all zero
+** third parameter.
+**
+** The sqlite3_result_zeroblob() interfaces set the result of
+** the application-defined function to be a BLOB containing all zero
 ** bytes and N bytes in size, where N is the value of the 2nd parameter.
 **
 ** The sqlite3_result_double() interface sets the result from
-** an application defined function to be a floating point value specified
+** an application-defined function to be a floating point value specified
 ** by its 2nd argument.
 **
 ** The sqlite3_result_error() and sqlite3_result_error16() functions
@@ -3926,8 +4218,8 @@
 ** 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.  SQLite interprets the error
-** message string from sqlite3_result_error() as UTF8. SQLite
-** interprets the string from sqlite3_result_error16() as UTF16 in native
+** message string from sqlite3_result_error() as UTF-8. SQLite
+** interprets the string from sqlite3_result_error16() as UTF-16 in native
 ** byte order.  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.
@@ -3935,7 +4227,7 @@
 ** sqlite3_result_error16() is non-negative then SQLite takes that many
 ** bytes (not characters) from the 2nd parameter as the error message.
 ** The sqlite3_result_error() and sqlite3_result_error16()
-** routines make a copy private copy of the error message text before
+** routines make a private copy of the error message text before
 ** they return.  Hence, the calling function can deallocate or
 ** modify the text after they return without harm.
 ** The sqlite3_result_error_code() function changes the error code
@@ -3943,11 +4235,11 @@
 ** the error code is SQLITE_ERROR.  A subsequent call to sqlite3_result_error()
 ** or sqlite3_result_error16() resets the error code to SQLITE_ERROR.
 **
-** The sqlite3_result_toobig() interface causes SQLite
-** to throw an error indicating that a string or BLOB is to long
-** to represent.  The sqlite3_result_nomem() interface
-** causes SQLite to throw an exception indicating that the a
-** memory allocation failed.
+** The sqlite3_result_toobig() interface causes SQLite to throw an error
+** indicating that a string or BLOB is to long to represent.
+**
+** The sqlite3_result_nomem() interface causes SQLite to throw an error
+** indicating that a memory allocation failed.
 **
 ** The sqlite3_result_int() interface sets the return value
 ** of the application-defined function to be the 32-bit signed integer
@@ -3959,7 +4251,7 @@
 ** The sqlite3_result_null() interface sets the return value
 ** of the application-defined function to be NULL.
 **
-** The sqlite3_result_text(), sqlite3_result_text16(), 
+** 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,
@@ -3967,7 +4259,7 @@
 ** SQLite takes the text result from the application from
 ** the 2nd parameter of the sqlite3_result_text* interfaces.
 ** If the 3rd parameter to the sqlite3_result_text* interfaces
-** is negative, then SQLite takes result text from the 2nd parameter 
+** 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
@@ -3975,13 +4267,12 @@
 ** function result.
 ** 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.
-** If the 4th parameter to the sqlite3_result_text* interfaces
-** or sqlite3_result_blob is the special constant SQLITE_STATIC, then
-** SQLite assumes that the text or blob result is constant space and
-** does not copy the space or call a destructor when it has
+** function as the destructor on the text or BLOB result when it has
 ** finished using that result.
+** If the 4th parameter to the sqlite3_result_text* interfaces or
+** 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 it or call a destructor when it has finished using that result.
 ** 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
@@ -3991,14 +4282,14 @@
 ** the application-defined function to be a copy the
 ** [unprotected sqlite3_value] object specified by the 2nd parameter.  The
 ** sqlite3_result_value() interface makes a copy of the [sqlite3_value]
-** so that [sqlite3_value] specified in the parameter may change or
+** so that the [sqlite3_value] specified in the parameter may change or
 ** be deallocated after sqlite3_result_value() returns without harm.
 ** 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.
 **
-** If these routines are called from within the different thread 
-** than the one containing the application-defined function that recieved
+** If these routines are called from within the different thread
+** than the one containing the application-defined function that received
 ** the [sqlite3_context] pointer, the results are undefined.
 **
 ** INVARIANTS:
@@ -4006,7 +4297,7 @@
 ** {F16403} The default return value from any SQL function is NULL.
 **
 ** {F16406} The [sqlite3_result_blob(C,V,N,D)] interface changes the
-**          return value of function C to be a blob that is N bytes
+**          return value of function C to be a BLOB that is N bytes
 **          in length and with content pointed to by V.
 **
 ** {F16409} The [sqlite3_result_double(C,V)] interface changes the
@@ -4014,12 +4305,12 @@
 **
 ** {F16412} The [sqlite3_result_error(C,V,N)] interface changes the return
 **          value of function C to be an exception with error code
-**          [SQLITE_ERROR] and a UTF8 error message copied from V up to the
+**          [SQLITE_ERROR] and a UTF-8 error message copied from V up to the
 **          first zero byte or until N bytes are read if N is positive.
 **
 ** {F16415} The [sqlite3_result_error16(C,V,N)] interface changes the return
 **          value of function C to be an exception with error code
-**          [SQLITE_ERROR] and a UTF16 native byte order error message
+**          [SQLITE_ERROR] and a UTF-16 native byte order error message
 **          copied from V up to the first zero terminator or until N bytes
 **          are read if N is positive.
 **
@@ -4045,31 +4336,31 @@
 **          return value of function C to be NULL.
 **
 ** {F16436} The [sqlite3_result_text(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF8 string
+**          return value of function C to be the UTF-8 string
 **          V up to the first zero if N is negative
 **          or the first N bytes of V if N is non-negative.
 **
 ** {F16439} The [sqlite3_result_text16(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF16 native byte order
-**          string V up to the first zero if N is
-**          negative or the first N bytes of V if N is non-negative.
+**          return value of function C to be the UTF-16 native byte order
+**          string V up to the first zero if N is negative
+**          or the first N bytes of V if N is non-negative.
 **
 ** {F16442} The [sqlite3_result_text16be(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF16 big-endian
-**          string V up to the first zero if N is
-**          is negative or the first N bytes or V if N is non-negative.
+**          return value of function C to be the UTF-16 big-endian
+**          string V up to the first zero if N is negative
+**          or the first N bytes or V if N is non-negative.
 **
 ** {F16445} The [sqlite3_result_text16le(C,V,N,D)] interface changes the
-**          return value of function C to be the UTF16 little-endian
-**          string V up to the first zero if N is
-**          negative or the first N bytes of V if N is non-negative.
+**          return value of function C to be the UTF-16 little-endian
+**          string V up to the first zero if N is negative
+**          or the first N bytes of V if N is non-negative.
 **
 ** {F16448} The [sqlite3_result_value(C,V)] interface changes the
-**          return value of function C to be [unprotected sqlite3_value]
+**          return value of function C to be the [unprotected sqlite3_value]
 **          object V.
 **
 ** {F16451} The [sqlite3_result_zeroblob(C,N)] interface changes the
-**          return value of function C to be an N-byte blob of all zeros.
+**          return value of function C to be an N-byte BLOB of all zeros.
 **
 ** {F16454} The [sqlite3_result_error()] and [sqlite3_result_error16()]
 **          interfaces make a copy of their error message strings before
@@ -4093,7 +4384,7 @@
 **          [sqlite3_result_text(C,V,N,D)], [sqlite3_result_text16(C,V,N,D)],
 **          [sqlite3_result_text16be(C,V,N,D)], or
 **          [sqlite3_result_text16le(C,V,N,D)] is some value other than
-**          the constants [SQLITE_STATIC] and [SQLITE_TRANSIENT] then 
+**          the constants [SQLITE_STATIC] and [SQLITE_TRANSIENT] then
 **          SQLite will invoke the destructor D with V as its only argument
 **          when it has finished with the V value.
 */
@@ -4118,7 +4409,7 @@
 ** CAPI3REF: Define New Collating Sequences {F16600}
 **
 ** These functions are used to add new collation sequences to the
-** [sqlite3*] handle specified as the first argument. 
+** [database connection] specified as the first argument.
 **
 ** The name of the new collation sequence is specified as a UTF-8 string
 ** for sqlite3_create_collation() and sqlite3_create_collation_v2()
@@ -4128,42 +4419,40 @@
 ** The third argument may be one of the constants [SQLITE_UTF8],
 ** [SQLITE_UTF16LE] or [SQLITE_UTF16BE], indicating that the user-supplied
 ** routine expects to be passed pointers to strings encoded using UTF-8,
-** UTF-16 little-endian or UTF-16 big-endian respectively. The
+** UTF-16 little-endian, or UTF-16 big-endian, respectively. The
 ** third argument might also be [SQLITE_UTF16_ALIGNED] to indicate that
 ** the routine expects pointers to 16-bit word aligned strings
-** of UTF16 in the native byte order of the host computer.
+** of UTF-16 in the native byte order of the host computer.
 **
 ** A pointer to the user supplied routine must be passed as the fifth
 ** argument.  If it is NULL, this is the same as deleting the collation
 ** sequence (so that SQLite cannot call it anymore).
-** Each time the application
-** supplied function is invoked, it is passed a copy of the void* passed as
-** the fourth argument to sqlite3_create_collation() or
-** sqlite3_create_collation16() as its first parameter.
+** Each time the application supplied function is invoked, it is passed
+** as its first parameter a copy of the void* passed as the fourth argument
+** to sqlite3_create_collation() or sqlite3_create_collation16().
 **
 ** The remaining arguments to the application-supplied routine are two strings,
 ** each represented by a (length, data) pair and encoded in the encoding
 ** that was passed as the third argument when the collation sequence was
-** registered. {END} The application defined collation routine should
-** return negative, zero or positive if
-** the first string is less than, equal to, or greater than the second
-** string. i.e. (STRING1 - STRING2).
+** registered. {END}  The application defined collation routine should
+** return negative, zero or positive if the first string is less than,
+** equal to, or greater than the second string. i.e. (STRING1 - STRING2).
 **
 ** The sqlite3_create_collation_v2() works like sqlite3_create_collation()
-** excapt that it takes an extra argument which is a destructor for
+** except that it takes an extra argument which is a destructor for
 ** the collation.  The destructor is called when the collation is
 ** destroyed and is passed a copy of the fourth parameter void* pointer
 ** of the sqlite3_create_collation_v2().
-** Collations are destroyed when
-** they are overridden by later calls to the collation creation functions
-** or when the [sqlite3*] database handle is closed using [sqlite3_close()].
+** Collations are destroyed when they are overridden by later calls to the
+** collation creation functions or when the [database connection] is closed
+** using [sqlite3_close()].
 **
 ** INVARIANTS:
 **
 ** {F16603} A successful call to the
 **          [sqlite3_create_collation_v2(B,X,E,P,F,D)] interface
 **          registers function F as the comparison function used to
-**          implement collation X on [database connection] B for
+**          implement collation X on the [database connection] B for
 **          databases having encoding E.
 **
 ** {F16604} SQLite understands the X parameter to
@@ -4175,7 +4464,7 @@
 **          with the same values for B, X, and E, override prior values
 **          of P, F, and D.
 **
-** {F16609} The destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
+** {F16609} If the destructor D in [sqlite3_create_collation_v2(B,X,E,P,F,D)]
 **          is not NULL then it is called with argument P when the
 **          collating function is dropped by SQLite.
 **
@@ -4194,8 +4483,8 @@
 **
 ** {F16624} Following a [sqlite3_create_collation_v2(B,X,E,P,F,D)],
 **          SQLite uses the comparison function F for all text comparison
-**          operations on [database connection] B on text values that
-**          use the collating sequence name X.
+**          operations on the [database connection] B on text values that
+**          use the collating sequence named X.
 **
 ** {F16627} The [sqlite3_create_collation16(B,X,E,P,F)] works the same
 **          as [sqlite3_create_collation(B,X,E,P,F)] except that the
@@ -4224,7 +4513,7 @@
 );
 int sqlite3_create_collation16(
   sqlite3*, 
-  const char *zName, 
+  const void *zName,
   int eTextRep, 
   void*,
   int(*xCompare)(void*,int,const void*,int,const void*)
@@ -4235,22 +4524,21 @@
 **
 ** To avoid having to register all collation sequences before a database
 ** can be used, a single callback function may be registered with the
-** database handle to be called whenever an undefined collation sequence is
-** required.
+** [database connection] to be called whenever an undefined collation
+** sequence is required.
 **
 ** 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. {F16703} If sqlite3_collation_needed16() is used, the names
-** are passed as UTF-16 in machine native byte order. A call to either
-** function replaces any existing callback.
+** encoded in UTF-8. {F16703} If sqlite3_collation_needed16() is used,
+** the names are passed as UTF-16 in machine native byte order.
+** A call to either function replaces any existing callback.
 **
 ** 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
-** handle.  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
+** 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.
 **
 ** The callback function should register the desired collation using
@@ -4275,8 +4563,6 @@
 **          was registered using [sqlite3_collation_needed()] and
 **          is in UTF-16 native byte order if the callback was
 **          registered using [sqlite3_collation_needed16()].
-**
-** 
 */
 int sqlite3_collation_needed(
   sqlite3*, 
@@ -4315,15 +4601,14 @@
 );
 
 /*
-** CAPI3REF:  Suspend Execution For A Short Time {F10530}
+** CAPI3REF: Suspend Execution For A Short Time {F10530}
 **
-** The sqlite3_sleep() function
-** causes the current thread to suspend execution
+** The sqlite3_sleep() function causes the current thread to suspend execution
 ** for at least a number of milliseconds specified in its parameter.
 **
-** If the operating system does not support sleep requests with 
-** millisecond time resolution, then the time will be rounded up to 
-** the nearest second. The number of milliseconds of sleep actually 
+** If the operating system does not support sleep requests with
+** millisecond time resolution, then the time will be rounded up to
+** the nearest second. The number of milliseconds of sleep actually
 ** requested from the operating system is returned.
 **
 ** SQLite implements this interface by calling the xSleep()
@@ -4343,15 +4628,15 @@
 int sqlite3_sleep(int);
 
 /*
-** CAPI3REF:  Name Of The Folder Holding Temporary Files {F10310}
+** CAPI3REF: Name Of The Folder Holding Temporary Files {F10310}
 **
 ** If this global variable is made to point to a string which is
-** the name of a folder (a.ka. directory), then all temporary files
+** the name of a folder (a.k.a. directory), then all temporary files
 ** created by SQLite will be placed in that directory.  If this variable
-** is NULL pointer, then SQLite does a search for an appropriate temporary
-** file directory.
+** is a NULL pointer, then SQLite performs a search for an appropriate
+** temporary file directory.
 **
-** It is not safe to modify this variable once a database connection
+** It is not safe to modify this variable once a [database connection]
 ** has been opened.  It is intended that this variable be set once
 ** as part of process initialization and before any SQLite interface
 ** routines have been call and remain unchanged thereafter.
@@ -4359,19 +4644,20 @@
 SQLITE_EXTERN char *sqlite3_temp_directory;
 
 /*
-** CAPI3REF:  Test To See If The Database Is In Auto-Commit Mode {F12930}
+** CAPI3REF: Test To See If The Database Is In Auto-Commit Mode {F12930}
+** KEYWORDS: {autocommit mode}
 **
-** The sqlite3_get_autocommit() interfaces returns non-zero or
+** The sqlite3_get_autocommit() interface returns non-zero or
 ** zero if the given database connection is or is not in autocommit mode,
-** respectively.   Autocommit mode is on
-** by default.  Autocommit mode is disabled by a [BEGIN] statement.
-** Autocommit mode is reenabled by a [COMMIT] or [ROLLBACK].
+** respectively.  Autocommit mode is on by default.
+** Autocommit mode is disabled by a [BEGIN] statement.
+** Autocommit mode is re-enabled by a [COMMIT] or [ROLLBACK].
 **
 ** If certain kinds of errors occur on a statement within a multi-statement
-** transactions (errors including [SQLITE_FULL], [SQLITE_IOERR], 
+** transaction (errors including [SQLITE_FULL], [SQLITE_IOERR],
 ** [SQLITE_NOMEM], [SQLITE_BUSY], and [SQLITE_INTERRUPT]) then the
 ** transaction might be rolled back automatically.  The only way to
-** find out if SQLite automatically rolled back the transaction after
+** find out whether SQLite automatically rolled back the transaction after
 ** an error is to use this function.
 **
 ** INVARIANTS:
@@ -4386,35 +4672,62 @@
 **
 ** {F12934} Autocommit mode is enabled by a successful [COMMIT] or [ROLLBACK]
 **          statement.
-** 
 **
 ** LIMITATIONS:
-***
-** {U12936} If another thread changes the autocommit status of the database
+**
+** {A12936} If another thread changes the autocommit status of the database
 **          connection while this routine is running, then the return value
 **          is undefined.
 */
 int sqlite3_get_autocommit(sqlite3*);
 
 /*
-** CAPI3REF:  Find The Database Handle Of A Prepared Statement {F13120}
+** CAPI3REF: Find The Database Handle Of A Prepared Statement {F13120}
 **
-** The sqlite3_db_handle interface
-** returns the [sqlite3*] database handle to which a
-** [prepared statement] belongs.
-** The database handle returned by sqlite3_db_handle
-** is the same database handle that was
-** the first argument to the [sqlite3_prepare_v2()] or its variants
-** that was used to create the statement in the first place.
+** The sqlite3_db_handle interface returns the [database connection] handle
+** to which a [prepared statement] belongs.  The database handle returned by
+** sqlite3_db_handle is the same database handle 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.
 **
 ** INVARIANTS:
 **
 ** {F13123} The [sqlite3_db_handle(S)] interface returns a pointer
-**          to the [database connection] associated with
+**          to the [database connection] associated with the
 **          [prepared statement] S.
 */
 sqlite3 *sqlite3_db_handle(sqlite3_stmt*);
 
+/*
+** CAPI3REF: Find the next prepared statement {F13140}
+**
+** This interface returns a pointer to the next [prepared statement] after
+** pStmt associated with the [database connection] pDb.  If pStmt is NULL
+** then this interface returns a pointer to the first prepared statement
+** associated with the database connection pDb.  If no prepared statement
+** satisfies the conditions of this routine, it returns NULL.
+**
+** INVARIANTS:
+**
+** {F13143} If D is a [database connection] that holds one or more
+**          unfinalized [prepared statements] and S is a NULL pointer,
+**          then [sqlite3_next_stmt(D, S)] routine shall return a pointer
+**          to one of the prepared statements associated with D.
+**
+** {F13146} If D is a [database connection] that holds no unfinalized
+**          [prepared statements] and S is a NULL pointer, then
+**          [sqlite3_next_stmt(D, S)] routine shall return a NULL pointer.
+**
+** {F13149} If S is a [prepared statement] in the [database connection] D
+**          and S is not the last prepared statement in D, then
+**          [sqlite3_next_stmt(D, S)] routine shall return a pointer
+**          to the next prepared statement in D after S.
+**
+** {F13152} If S is the last [prepared statement] in the
+**          [database connection] D then the [sqlite3_next_stmt(D, S)]
+**          routine shall return a NULL pointer.
+*/
+sqlite3_stmt *sqlite3_next_stmt(sqlite3 *pDb, sqlite3_stmt *pStmt);
 
 /*
 ** CAPI3REF: Commit And Rollback Notification Callbacks {F12950}
@@ -4427,16 +4740,16 @@
 ** function to be invoked whenever a transaction is committed.
 ** Any callback set by a previous call to sqlite3_commit_hook()
 ** for the same database connection is overridden.
-** The pArg argument is passed through
-** to the callback.  If the callback on a commit hook function 
-** returns non-zero, then the commit is converted into a rollback.
+** The pArg argument is passed through to the callback.
+** If the callback on a commit hook function returns non-zero,
+** then the commit is converted into a rollback.
 **
 ** If another function was previously registered, its
 ** pArg value is returned.  Otherwise NULL is returned.
 **
 ** Registering a NULL function disables the callback.
 **
-** For the purposes of this API, a transaction is said to have been 
+** 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.
 ** The rollback callback is not invoked if a transaction is
@@ -4445,24 +4758,21 @@
 ** rolled back because a commit callback returned non-zero.
 ** <todo> Check on this </todo>
 **
-** These are experimental interfaces and are subject to change.
-**
 ** INVARIANTS:
 **
 ** {F12951} The [sqlite3_commit_hook(D,F,P)] interface registers the
 **          callback function F to be invoked with argument P whenever
-**          a transaction commits on [database connection] D.
+**          a transaction commits on the [database connection] D.
 **
-** {F12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P
-**          argument from the previous call with the same 
-**          [database connection ] D , or NULL on the first call
-**          for a particular [database connection] D.
+** {F12952} The [sqlite3_commit_hook(D,F,P)] interface returns the P argument
+**          from the previous call with the same [database connection] D,
+**          or NULL on the first call for a particular database connection D.
 **
 ** {F12953} Each call to [sqlite3_commit_hook()] overwrites the callback
 **          registered by prior calls.
 **
 ** {F12954} If the F argument to [sqlite3_commit_hook(D,F,P)] is NULL
-**          then the commit hook callback is cancelled and no callback
+**          then the commit hook callback is canceled and no callback
 **          is invoked when a transaction commits.
 **
 ** {F12955} If the commit callback returns non-zero then the commit is
@@ -4470,18 +4780,18 @@
 **
 ** {F12961} The [sqlite3_rollback_hook(D,F,P)] interface registers the
 **          callback function F to be invoked with argument P whenever
-**          a transaction rolls back on [database connection] D.
+**          a transaction rolls back on the [database connection] D.
 **
 ** {F12962} The [sqlite3_rollback_hook(D,F,P)] interface returns the P
-**          argument from the previous call with the same 
-**          [database connection ] D , or NULL on the first call
-**          for a particular [database connection] D.
+**          argument from the previous call with the same
+**          [database connection] D, or NULL on the first call
+**          for a particular database connection D.
 **
 ** {F12963} Each call to [sqlite3_rollback_hook()] overwrites the callback
 **          registered by prior calls.
 **
 ** {F12964} If the F argument to [sqlite3_rollback_hook(D,F,P)] is NULL
-**          then the rollback hook callback is cancelled and no callback
+**          then the rollback hook callback is canceled and no callback
 **          is invoked when a transaction rolls back.
 */
 void *sqlite3_commit_hook(sqlite3*, int(*)(void*), void*);
@@ -4490,26 +4800,23 @@
 /*
 ** CAPI3REF: Data Change Notification Callbacks {F12970}
 **
-** 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.
-** Any callback set by a previous call to this function for the same 
-** database connection is overridden.
-**
-** The second argument is a pointer to the function to invoke when a 
-** row is updated, inserted or deleted. 
-** The first argument to the callback is
-** a copy of the third argument to sqlite3_update_hook().
-** 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.
-** The third and 
-** fourth arguments to the callback contain pointers to the database and 
-** table name containing the affected row.
-** The final callback parameter is 
-** the rowid of the row.
-** In the case of an update, this is the rowid after 
-** the update takes place.
+** 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.
+** Any callback set by a previous call to this function
+** for the same database connection is overridden.
+**
+** The second argument is a pointer to the function to invoke when a
+** row is updated, inserted or deleted.
+** The first argument to the callback is a copy of the third argument
+** to sqlite3_update_hook().
+** 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.
+** The third and fourth arguments to the callback contain pointers to the
+** database and table name containing the affected row.
+** The final callback parameter is the rowid of the row. In the case of
+** an update, this is the rowid after the update takes place.
 **
 ** The update hook is not invoked when internal system tables are
 ** modified (i.e. sqlite_master and sqlite_sequence).
@@ -4519,10 +4826,10 @@
 **
 ** INVARIANTS:
 **
-** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes callback
+** {F12971} The [sqlite3_update_hook(D,F,P)] interface causes the callback
 **          function F to be invoked with first parameter P whenever
 **          a table row is modified, inserted, or deleted on
-**          [database connection] D.
+**          the [database connection] D.
 **
 ** {F12973} The [sqlite3_update_hook(D,F,P)] interface returns the value
 **          of P for the previous call on the same [database connection] D,
@@ -4537,7 +4844,7 @@
 ** {F12979} The update hook callback is not invoked when internal system
 **          tables such as sqlite_master and sqlite_sequence are modified.
 **
-** {F12981} The second parameter to the update callback 
+** {F12981} The second parameter to the update callback
 **          is one of [SQLITE_INSERT], [SQLITE_DELETE] or [SQLITE_UPDATE],
 **          depending on the operation that caused the callback to be invoked.
 **
@@ -4555,37 +4862,36 @@
 );
 
 /*
-** CAPI3REF:  Enable Or Disable Shared Pager Cache {F10330}
+** CAPI3REF: Enable Or Disable Shared Pager Cache {F10330}
+** KEYWORDS: {shared cache} {shared cache mode}
 **
 ** 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.
-**
-** Cache sharing is enabled and disabled
-** for an entire process. {END} This is a change as of SQLite version 3.5.0.
-** In prior versions of SQLite, sharing was
-** enabled or disabled for each thread separately.
+** and schema data structures between [database connection | connections]
+** to the same database. Sharing is enabled if the argument is true
+** and disabled if the argument is false.
+**
+** Cache sharing is enabled and disabled for an entire process. {END}
+** This is a change as of SQLite version 3.5.0. In prior versions of SQLite,
+** sharing was enabled or disabled for each thread separately.
 **
 ** 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 use the sharing mode
 ** that was in effect at the time they were opened.
 **
-** Virtual tables cannot be used with a shared cache.   When shared
+** Virtual tables cannot be used with a shared cache.  When shared
 ** cache is enabled, the [sqlite3_create_module()] API used to register
 ** virtual tables will always return an error.
 **
-** This routine returns [SQLITE_OK] if shared cache was
-** enabled or disabled successfully.  An [error code]
-** is returned otherwise.
+** This routine returns [SQLITE_OK] if shared cache was enabled or disabled
+** successfully.  An [error code] is returned otherwise.
 **
 ** Shared cache is disabled by default. But this might change in
 ** future releases of SQLite.  Applications that care about shared
 ** cache setting should set it explicitly.
 **
 ** INVARIANTS:
-** 
+**
 ** {F10331} A successful invocation of [sqlite3_enable_shared_cache(B)]
 **          will enable or disable shared cache mode for any subsequently
 **          created [database connection] in the same process.
@@ -4601,21 +4907,20 @@
 int sqlite3_enable_shared_cache(int);
 
 /*
-** CAPI3REF:  Attempt To Free Heap Memory {F17340}
+** CAPI3REF: Attempt To Free Heap Memory {F17340}
 **
-** The sqlite3_release_memory() interface attempts to
-** free N bytes of heap memory by deallocating non-essential memory
-** allocations held by the database labrary. {END}  Memory used
-** to cache database pages to improve performance is an example of
-** non-essential memory.  Sqlite3_release_memory() returns
-** the number of bytes actually freed, which might be more or less
-** than the amount requested.
+** The sqlite3_release_memory() interface attempts to free N bytes
+** of heap memory by deallocating non-essential memory allocations
+** held by the database library. {END}  Memory used to cache database
+** pages to improve performance is an example of non-essential memory.
+** sqlite3_release_memory() returns the number of bytes actually freed,
+** which might be more or less than the amount requested.
 **
 ** INVARIANTS:
 **
 ** {F17341} The [sqlite3_release_memory(N)] interface attempts to
 **          free N bytes of heap memory by deallocating non-essential
-**          memory allocations held by the database labrary.
+**          memory allocations held by the database library.
 **
 ** {F16342} The [sqlite3_release_memory(N)] returns the number
 **          of bytes actually freed, which might be more or less
@@ -4624,27 +4929,25 @@
 int sqlite3_release_memory(int);
 
 /*
-** CAPI3REF:  Impose A Limit On Heap Size {F17350}
+** CAPI3REF: Impose A Limit On Heap Size {F17350}
 **
-** The sqlite3_soft_heap_limit() interface
-** places a "soft" limit on the amount of heap memory that may be allocated
-** by SQLite. If an internal allocation is requested 
-** that would exceed the soft heap limit, [sqlite3_release_memory()] is
-** invoked one or more times to free up some space before the allocation
-** is made.
-**
-** The limit is called "soft", because if
-** [sqlite3_release_memory()] cannot
-** free sufficient memory to prevent the limit from being exceeded,
+** The sqlite3_soft_heap_limit() interface places a "soft" limit
+** on the amount of heap memory that may be allocated by SQLite.
+** If an internal allocation is requested that would exceed the
+** soft heap limit, [sqlite3_release_memory()] is invoked one or
+** more times to free up some space before the allocation is performed.
+**
+** The limit is called "soft", because if [sqlite3_release_memory()]
+** cannot free sufficient memory to prevent the limit from being exceeded,
 ** the memory is allocated anyway and the current operation proceeds.
 **
 ** A negative or zero value for N means that there is no soft heap limit and
 ** [sqlite3_release_memory()] will only be called when memory is exhausted.
 ** The default value for the soft heap limit is zero.
 **
-** SQLite makes a best effort to honor the soft heap limit.  
-** But if the soft heap limit cannot honored, execution will
-** continue without error or notification.  This is why the limit is 
+** SQLite makes a best effort to honor the soft heap limit.
+** But if the soft heap limit cannot be honored, execution will
+** continue without error or notification.  This is why the limit is
 ** called a "soft" limit.  It is advisory only.
 **
 ** Prior to SQLite version 3.5.0, this routine only constrained the memory
@@ -4686,52 +4989,50 @@
 void sqlite3_soft_heap_limit(int);
 
 /*
-** CAPI3REF:  Extract Metadata About A Column Of A Table {F12850}
+** CAPI3REF: Extract Metadata About A Column Of A Table {F12850}
 **
-** This routine
-** returns meta-data about a specific column of a specific database
-** table accessible using the connection handle passed as the first function 
-** argument.
+** This routine returns metadata about a specific column of a specific
+** database table accessible using the [database connection] handle
+** passed as the first function argument.
 **
-** The column is identified by the second, third and fourth parameters to 
+** The column is identified by the second, third and fourth parameters to
 ** this function. The second parameter is either the name of the database
 ** (i.e. "main", "temp" or an attached database) containing the specified
 ** table or NULL. If it is NULL, then all attached databases are searched
-** for the table using the same algorithm as the database engine uses to 
+** for the table using the same algorithm used by the database engine to
 ** resolve unqualified table references.
 **
-** The third and fourth parameters to this function are the table and column 
-** name of the desired column, respectively. Neither of these parameters 
+** The third and fourth parameters to this function are the table and column
+** name of the desired column, respectively. Neither of these parameters
 ** may be NULL.
 **
-** Meta information is returned by writing to the memory locations passed as
-** the 5th and subsequent parameters to this function. Any of these 
-** arguments may be NULL, in which case the corresponding element of meta 
-** information is ommitted.
-**
-** <pre>
-** Parameter     Output Type      Description
-** -----------------------------------
+** Metadata is returned by writing to the memory locations passed as the 5th
+** and subsequent parameters to this function. Any of these arguments may be
+** NULL, in which case the corresponding element of metadata is omitted.
 **
-**   5th         const char*      Data type
-**   6th         const char*      Name of the default collation sequence 
-**   7th         int              True if the column has a NOT NULL constraint
-**   8th         int              True if the column is part of the PRIMARY KEY
-**   9th         int              True if the column is AUTOINCREMENT
-** </pre>
+** <blockquote>
+** <table border="1">
+** <tr><th> Parameter <th> Output<br>Type <th>  Description
 **
+** <tr><td> 5th <td> const char* <td> Data type
+** <tr><td> 6th <td> const char* <td> Name of default collation sequence
+** <tr><td> 7th <td> int         <td> True if column has a NOT NULL constraint
+** <tr><td> 8th <td> int         <td> True if column is part of the PRIMARY KEY
+** <tr><td> 9th <td> int         <td> True if column is AUTOINCREMENT
+** </table>
+** </blockquote>
 **
-** The memory pointed to by the character pointers returned for the 
-** declaration type and collation sequence is valid only until the next 
-** call to any sqlite API function.
+** The memory pointed to by the character pointers returned for the
+** declaration type and collation sequence is valid only until the next
+** call to any SQLite API function.
 **
-** If the specified table is actually a view, then an error is returned.
+** If the specified table is actually a view, an [error code] is returned.
 **
-** If the specified column is "rowid", "oid" or "_rowid_" and an 
-** INTEGER PRIMARY KEY column has been explicitly declared, then the output 
+** If the specified column is "rowid", "oid" or "_rowid_" 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
-** explicitly declared IPK column, then the output parameters are set as 
-** follows:
+** explicitly declared INTEGER PRIMARY KEY column, then the output
+** parameters are set as follows:
 **
 ** <pre>
 **     data type: "INTEGER"
@@ -4743,11 +5044,11 @@
 **
 ** This function may load one or more schemas from database files. If an
 ** error occurs during this process, or if the requested table or column
-** cannot be found, an SQLITE error code is returned and an error message
-** left in the database handle (to be retrieved using sqlite3_errmsg()).
+** cannot be found, an [error code] is returned and an error message left
+** in the [database connection] (to be retrieved using sqlite3_errmsg()).
 **
 ** This API is only available if the library was compiled with the
-** SQLITE_ENABLE_COLUMN_METADATA preprocessor symbol defined.
+** [SQLITE_ENABLE_COLUMN_METADATA] C-preprocessor symbol defined.
 */
 int sqlite3_table_column_metadata(
   sqlite3 *db,                /* Connection handle */
@@ -4764,25 +5065,28 @@
 /*
 ** CAPI3REF: Load An Extension {F12600}
 **
-** {F12601} The sqlite3_load_extension() interface
-** attempts to load an SQLite extension library contained in the file
-** zFile. {F12602} The entry point is zProc. {F12603} zProc may be 0
-** in which case the name of the entry point defaults
-** to "sqlite3_extension_init".
-**
-** {F12604} The sqlite3_load_extension() interface shall
-** return [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
-**
-** {F12605}
-** 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()].
-** {END}  The calling function should free this memory
-** by calling [sqlite3_free()].
-**
-** {F12606}
-** Extension loading must be enabled using [sqlite3_enable_load_extension()]
-** prior to calling this API or an error will be returned.
+** This interface loads an SQLite extension library from the named file.
+**
+** {F12601} The sqlite3_load_extension() interface attempts to load an
+**          SQLite extension library contained in the file zFile.
+**
+** {F12602} The entry point is zProc.
+**
+** {F12603} zProc may be 0, in which case the name of the entry point
+**          defaults to "sqlite3_extension_init".
+**
+** {F12604} The sqlite3_load_extension() interface shall return
+**          [SQLITE_OK] on success and [SQLITE_ERROR] if something goes wrong.
+**
+** {F12605} 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()]. {END}  The calling function
+**          should free this memory by calling [sqlite3_free()].
+**
+** {F12606} Extension loading must be enabled using
+**          [sqlite3_enable_load_extension()] prior to calling this API,
+**          otherwise an error will be returned.
 */
 int sqlite3_load_extension(
   sqlite3 *db,          /* Load the extension into this database connection */
@@ -4792,65 +5096,64 @@
 );
 
 /*
-** CAPI3REF:  Enable Or Disable Extension Loading {F12620}
+** CAPI3REF: Enable Or Disable Extension Loading {F12620}
 **
 ** 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.  {F12622} It is off by default. {END} See ticket #1863.
-**
-** {F12621} 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. {END}
+** extension loading while evaluating user-entered SQL, the following API
+** is provided to turn the [sqlite3_load_extension()] mechanism on and off.
+**
+** Extension loading is off by default. See ticket #1863.
+**
+** {F12621} 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.
+**
+** {F12622} Extension loading is off by default.
 */
 int sqlite3_enable_load_extension(sqlite3 *db, int onoff);
 
 /*
 ** CAPI3REF: Make Arrangements To Automatically Load An Extension {F12640}
 **
-** {F12641} This function
-** registers an extension entry point that is automatically invoked
-** whenever a new database connection is opened using
-** [sqlite3_open()], [sqlite3_open16()], or [sqlite3_open_v2()]. {END}
-**
 ** This API can be invoked at program startup in order to register
 ** one or more statically linked extensions that will be available
-** to all new database connections.
+** to all new [database connections]. {END}
 **
-** {F12642} Duplicate extensions are detected so calling this routine multiple
-** times with the same extension is harmless.
+** This routine stores a pointer to the extension in an array that is
+** obtained from [sqlite3_malloc()].  If you run a memory leak checker
+** on your program and it reports a leak because of this array, invoke
+** [sqlite3_reset_auto_extension()] prior to shutdown to free the memory.
+**
+** {F12641} This function registers an extension entry point that is
+**          automatically invoked whenever a new [database connection]
+**          is opened using [sqlite3_open()], [sqlite3_open16()],
+**          or [sqlite3_open_v2()].
 **
-** {F12643} This routine stores a pointer to the extension in an array
-** that is obtained from sqlite_malloc(). {END} If you run a memory leak
-** checker on your program and it reports a leak because of this
-** array, then invoke [sqlite3_reset_auto_extension()] prior
-** to shutdown to free the memory.
+** {F12642} Duplicate extensions are detected so calling this routine
+**          multiple times with the same extension is harmless.
 **
-** {F12644} Automatic extensions apply across all threads. {END}
+** {F12643} This routine stores a pointer to the extension in an array
+**          that is obtained from [sqlite3_malloc()].
 **
-** This interface is experimental and is subject to change or
-** removal in future releases of SQLite.
+** {F12644} Automatic extensions apply across all threads.
 */
 int sqlite3_auto_extension(void *xEntryPoint);
 
-
 /*
 ** CAPI3REF: Reset Automatic Extension Loading {F12660}
 **
-** {F12661} This function disables all previously registered
-** automatic extensions. {END}  This
-** routine undoes the effect of all prior [sqlite3_auto_extension()]
-** calls.
+** This function disables all previously registered automatic
+** extensions. {END}  It undoes the effect of all prior
+** [sqlite3_auto_extension()] calls.
 **
-** {F12662} This call disabled automatic extensions in all threads. {END}
+** {F12661} This function disables all previously registered
+**          automatic extensions.
 **
-** This interface is experimental and is subject to change or
-** removal in future releases of SQLite.
+** {F12662} This function disables automatic extensions in all threads.
 */
 void sqlite3_reset_auto_extension(void);
 
-
 /*
 ****** EXPERIMENTAL - subject to change without notice **************
 **
@@ -4858,7 +5161,7 @@
 ** to be experimental.  The interface might change in incompatible ways.
 ** If this is a problem for you, do not use the interface at this time.
 **
-** When the virtual-table mechanism stablizes, we will declare the
+** When the virtual-table mechanism stabilizes, we will declare the
 ** interface fixed, support it indefinitely, and remove this comment.
 */
 
@@ -4877,6 +5180,9 @@
 ** A module is a class of virtual tables.  Each module is defined
 ** by an instance of the following structure.  This structure consists
 ** mostly of methods for the module.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_module {
   int iVersion;
@@ -4919,14 +5225,12 @@
 ** inputs to xBestIndex and are read-only.  xBestIndex inserts its
 ** results into the **Outputs** fields.
 **
-** The aConstraint[] array records WHERE clause constraints of the
-** form:
+** The aConstraint[] array records WHERE clause constraints of the form:
 **
-**         column OP expr
+** <pre>column OP expr</pre>
 **
-** Where OP is =, &lt;, &lt;=, &gt;, or &gt;=.  
-** The particular operator is stored
-** in aConstraint[].op.  The index of the column is stored in 
+** where OP is =, &lt;, &lt;=, &gt;, or &gt;=.  The particular operator is
+** stored in aConstraint[].op.  The index of the column is stored in
 ** aConstraint[].iColumn.  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.
@@ -4958,6 +5262,9 @@
 ** particular lookup.  A full scan of a table with N entries should have
 ** a cost of N.  A binary search of a table of N entries should have a
 ** cost of approximately log(N).
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_index_info {
   /* Inputs */
@@ -4995,10 +5302,13 @@
 /*
 ** CAPI3REF: Register A Virtual Table Implementation {F18200}
 **
-** This routine is used to register a new module name with an SQLite
-** connection.  Module names must be registered before creating new
-** virtual tables on the module, or before using preexisting virtual
-** tables of the module.
+** This routine is used to register a new module name with a
+** [database connection].  Module names must be registered before
+** creating new virtual tables on the module, or before using
+** preexisting virtual tables of the module.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 int sqlite3_create_module(
   sqlite3 *db,               /* SQLite connection to register module with */
@@ -5010,7 +5320,7 @@
 /*
 ** CAPI3REF: Register A Virtual Table Implementation {F18210}
 **
-** This routine is identical to the sqlite3_create_module() method above,
+** This routine is identical to the [sqlite3_create_module()] method above,
 ** except that it allows a destructor function to be specified. It is
 ** even more experimental than the rest of the virtual tables API.
 */
@@ -5028,19 +5338,22 @@
 **
 ** Every module implementation uses a subclass of the following structure
 ** to describe a particular instance of the module.  Each subclass will
-** be tailored to the specific needs of the module implementation.   The
-** purpose of this superclass is to define certain fields that are common
-** to all module implementations.
+** be tailored to the specific needs of the module implementation.
+** The purpose of this superclass is to define certain fields that are
+** common to all module implementations.
 **
 ** Virtual tables methods can set an error message by assigning a
-** string obtained from sqlite3_mprintf() to zErrMsg.  The method should
-** take care that any prior string is freed by a call to sqlite3_free()
+** string obtained from [sqlite3_mprintf()] to zErrMsg.  The method should
+** take care that any prior string is freed by a call to [sqlite3_free()]
 ** prior to assigning a new string to zErrMsg.  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.  Note
 ** that sqlite3_mprintf() and sqlite3_free() are used on the zErrMsg field
 ** since virtual tables are commonly implemented in loadable extensions which
 ** do not have access to sqlite3MPrintf() or sqlite3Free().
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_vtab {
   const sqlite3_module *pModule;  /* The module for this virtual table */
@@ -5061,6 +5374,9 @@
 **
 ** This superclass exists in order to define fields of the cursor that
 ** are common to all implementations.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 struct sqlite3_vtab_cursor {
   sqlite3_vtab *pVtab;      /* Virtual table of this cursor */
@@ -5073,6 +5389,9 @@
 ** The xCreate and xConnect methods of a module use the following API
 ** to declare the format (the names and datatypes of the columns) of
 ** the virtual tables they implement.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
 */
 int sqlite3_declare_vtab(sqlite3*, const char *zCreateTable);
 
@@ -5088,7 +5407,7 @@
 ** before this API is called, a new function is created.  The implementation
 ** of the new function always causes an exception to be thrown.  So
 ** the new function is not good for anything by itself.  Its only
-** purpose is to be a place-holder function that can be overloaded
+** purpose is to be a placeholder function that can be overloaded
 ** by virtual tables.
 **
 ** This API should be considered part of the virtual table interface,
@@ -5110,67 +5429,82 @@
 
 /*
 ** CAPI3REF: A Handle To An Open BLOB {F17800}
+** KEYWORDS: {BLOB handle} {BLOB handles}
 **
 ** An instance of this object represents an open BLOB on which
-** incremental I/O can be preformed.
-** Objects of this type are created by
-** [sqlite3_blob_open()] and destroyed by [sqlite3_blob_close()].
+** [sqlite3_blob_open | incremental BLOB I/O] can be performed.
+** Objects of this type are created by [sqlite3_blob_open()]
+** and destroyed by [sqlite3_blob_close()].
 ** 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.
+** 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.
 */
 typedef struct sqlite3_blob sqlite3_blob;
 
 /*
 ** CAPI3REF: Open A BLOB For Incremental I/O {F17810}
 **
-** This interfaces opens a handle to the blob located
+** This interfaces opens a [BLOB handle | 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:
+** in other words, the same BLOB that would be selected by:
 **
 ** <pre>
 **     SELECT zColumn FROM zDb.zTable WHERE rowid = iRow;
 ** </pre> {END}
 **
-** If the flags parameter is non-zero, the blob is opened for 
-** read and write access. If it is zero, the blob is opened for read 
-** access.
+** If the flags parameter is non-zero, the the BLOB is opened for read
+** and write access. If it is zero, the BLOB is opened for read access.
 **
 ** Note that the database name is not the filename that contains
 ** the database but rather the symbolic name of the database that
 ** is assigned when the database is connected using [ATTACH].
-** For the main database file, the database name is "main".  For
-** TEMP tables, the database name is "temp".
+** For the main database file, the database name is "main".
+** For TEMP tables, the database name is "temp".
 **
-** On success, [SQLITE_OK] is returned and the new 
-** [sqlite3_blob | blob handle] is written to *ppBlob. 
-** Otherwise an error code is returned and 
-** any value written to *ppBlob should not be used by the caller.
-** This function sets the database-handle error code and message
+** On success, [SQLITE_OK] is returned and the new [BLOB handle] is written
+** to *ppBlob. Otherwise an [error code] is returned and any value written
+** to *ppBlob should not be used by the caller.
+** This function sets the [database connection] error code and message
 ** accessible via [sqlite3_errcode()] and [sqlite3_errmsg()].
-** 
+**
+** 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.
+** Calls to [sqlite3_blob_read()] and [sqlite3_blob_write()] for
+** a expired BLOB handle fail with an return code of [SQLITE_ABORT].
+** Changes written into a BLOB prior to the BLOB expiring are not
+** rollback by the expiration of the BLOB.  Such changes will eventually
+** commit if the transaction continues to completion.
+**
 ** INVARIANTS:
 **
 ** {F17813} A successful invocation of the [sqlite3_blob_open(D,B,T,C,R,F,P)]
-**          interface opens an [sqlite3_blob] object P on the blob
-**          in column C of table T in database B on [database connection] D.
-**
-** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] starts
-**          a new transaction on [database connection] D if that connection
-**          is not already in a transaction.
-**
-** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface opens the blob
-**          for read and write access if and only if the F parameter
-**          is non-zero.
+**          interface shall open an [sqlite3_blob] object P on the BLOB
+**          in column C of the table T in the database B on
+**          the [database connection] D.
+**
+** {F17814} A successful invocation of [sqlite3_blob_open(D,...)] shall start
+**          a new transaction on the [database connection] D if that
+**          connection is not already in a transaction.
+**
+** {F17816} The [sqlite3_blob_open(D,B,T,C,R,F,P)] interface shall open
+**          the BLOB for read and write access if and only if the F
+**          parameter is non-zero.
 **
-** {F17819} The [sqlite3_blob_open()] interface returns [SQLITE_OK] on 
+** {F17819} The [sqlite3_blob_open()] interface shall return [SQLITE_OK] on
 **          success and an appropriate [error code] on failure.
 **
 ** {F17821} If an error occurs during evaluation of [sqlite3_blob_open(D,...)]
 **          then subsequent calls to [sqlite3_errcode(D)],
-**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return
-**          information approprate for that error.
+**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
+**          information appropriate for that error.
+**
+** {F17824} If any column in the row that a [sqlite3_blob] has open is
+**          changed by a separate [UPDATE] or [DELETE] statement or by
+**          an [ON CONFLICT] side effect, then the [sqlite3_blob] shall
+**          be marked as invalid.
 */
 int sqlite3_blob_open(
   sqlite3*,
@@ -5183,15 +5517,16 @@
 );
 
 /*
-** CAPI3REF:  Close A BLOB Handle {F17830}
+** CAPI3REF: Close A BLOB Handle {F17830}
 **
-** Close an open [sqlite3_blob | blob handle].
+** Closes an open [BLOB handle].
 **
 ** Closing a BLOB shall cause the current transaction to commit
 ** if there are no other BLOBs, no pending prepared statements, and the
-** database connection is in autocommit mode.
+** database connection is in [autocommit mode].
 ** If any writes were made to the BLOB, they might be held in cache
 ** until the close operation if they will fit. {END}
+**
 ** Closing the BLOB often forces the changes
 ** out to disk and so if any I/O errors occur, they will likely occur
 ** at the time when the BLOB is closed.  {F17833} Any errors that occur during
@@ -5202,29 +5537,26 @@
 **
 ** INVARIANTS:
 **
-** {F17833} The [sqlite3_blob_close(P)] interface closes an
-**          [sqlite3_blob] object P previously opened using
-**          [sqlite3_blob_open()].
+** {F17833} The [sqlite3_blob_close(P)] interface closes an [sqlite3_blob]
+**          object P previously opened using [sqlite3_blob_open()].
 **
 ** {F17836} Closing an [sqlite3_blob] object using
 **          [sqlite3_blob_close()] shall cause the current transaction to
 **          commit if there are no other open [sqlite3_blob] objects
 **          or [prepared statements] on the same [database connection] and
-**          the [database connection] is in
-**          [sqlite3_get_autocommit | autocommit mode].
+**          the database connection is in [autocommit mode].
 **
-** {F17839} The [sqlite3_blob_close(P)] interfaces closes the 
+** {F17839} The [sqlite3_blob_close(P)] interfaces shall close the
 **          [sqlite3_blob] object P unconditionally, even if
 **          [sqlite3_blob_close(P)] returns something other than [SQLITE_OK].
-**          
 */
 int sqlite3_blob_close(sqlite3_blob *);
 
 /*
-** CAPI3REF:  Return The Size Of An Open BLOB {F17840}
+** CAPI3REF: Return The Size Of An Open BLOB {F17840}
 **
-** Return the size in bytes of the blob accessible via the open 
-** [sqlite3_blob] object in its only argument.
+** Returns the size in bytes of the BLOB accessible via the open
+** []BLOB handle] in its only argument.
 **
 ** INVARIANTS:
 **
@@ -5235,106 +5567,126 @@
 int sqlite3_blob_bytes(sqlite3_blob *);
 
 /*
-** CAPI3REF:  Read Data From A BLOB Incrementally {F17850}
+** CAPI3REF: Read Data From A BLOB Incrementally {F17850}
 **
-** This function is used to read data from an open 
-** [sqlite3_blob | blob-handle] into a caller supplied buffer.
-** N bytes of data are copied into buffer
-** Z from the open blob, starting at offset iOffset.
+** 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.
 **
-** If offset iOffset is less than N bytes from the end of the blob, 
+** If offset iOffset is less than N bytes from the end of the BLOB,
 ** [SQLITE_ERROR] is returned and no data is read.  If N or iOffset is
-** less than zero [SQLITE_ERROR] is returned and no data is read.
+** less than zero, [SQLITE_ERROR] is returned and no data is read.
 **
-** On success, SQLITE_OK is returned. Otherwise, an 
-** [error code] or an [extended error code] is returned.
+** An attempt to read from an expired [BLOB handle] fails with an
+** error code of [SQLITE_ABORT].
+**
+** On success, SQLITE_OK is returned.
+** Otherwise, an [error code] or an [extended error code] is returned.
 **
 ** INVARIANTS:
 **
-** {F17853} The [sqlite3_blob_read(P,Z,N,X)] interface reads N bytes
-**          beginning at offset X from
-**          the blob that [sqlite3_blob] object P refers to
-**          and writes those N bytes into buffer Z.
+** {F17853} A successful invocation of [sqlite3_blob_read(P,Z,N,X)] 
+**          shall reads N bytes of data out of the BLOB referenced by
+**          [BLOB handle] P beginning at offset X and store those bytes
+**          into buffer Z.
 **
-** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the blob
-**          is less than N+X bytes, then the function returns [SQLITE_ERROR]
-**          and nothing is read from the blob.
+** {F17856} In [sqlite3_blob_read(P,Z,N,X)] if the size of the BLOB
+**          is less than N+X bytes, then the function shall leave the
+**          Z buffer unchanged and return [SQLITE_ERROR].
 **
 ** {F17859} In [sqlite3_blob_read(P,Z,N,X)] if X or N is less than zero
-**          then the function returns [SQLITE_ERROR]
-**          and nothing is read from the blob.
+**          then the function shall leave the Z buffer unchanged
+**          and return [SQLITE_ERROR].
+**
+** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface shall return [SQLITE_OK]
+**          if N bytes are successfully read into buffer Z.
 **
-** {F17862} The [sqlite3_blob_read(P,Z,N,X)] interface returns [SQLITE_OK]
-**          if N bytes where successfully read into buffer Z.
+** {F17863} If the [BLOB handle] P is expired and X and N are within bounds
+**          then [sqlite3_blob_read(P,Z,N,X)] shall leave the Z buffer
+**          unchanged and return [SQLITE_ABORT].
 **
 ** {F17865} If the requested read could not be completed,
-**          the [sqlite3_blob_read(P,Z,N,X)] interface returns an
+**          the [sqlite3_blob_read(P,Z,N,X)] interface shall return an
 **          appropriate [error code] or [extended error code].
 **
 ** {F17868} If an error occurs during evaluation of [sqlite3_blob_read(P,...)]
 **          then subsequent calls to [sqlite3_errcode(D)],
-**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return
-**          information approprate for that error, where D is the
-**          database handle that was used to open blob handle P.
+**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
+**          information appropriate for that error, where D is the
+**          [database connection] that was used to open the [BLOB handle] P.
 */
 int sqlite3_blob_read(sqlite3_blob *, void *Z, int N, int iOffset);
 
 /*
-** CAPI3REF:  Write Data Into A BLOB Incrementally {F17870}
+** CAPI3REF: Write Data Into A BLOB Incrementally {F17870}
 **
-** This function is used to write data into an open 
-** [sqlite3_blob | blob-handle] from a user supplied buffer.
-** n bytes of data are copied from the buffer
-** pointed to by z into the open blob, starting at offset iOffset.
-**
-** If the [sqlite3_blob | 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].
-**
-** 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.  If n is
+** 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.
+**
+** 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].
+**
+** 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.  If N is
 ** less than zero [SQLITE_ERROR] is returned and no data is written.
 **
-** On success, SQLITE_OK is returned. Otherwise, an 
-** [error code] or an [extended error code] is returned.
+** An attempt to write to an expired [BLOB handle] fails with an
+** error code of [SQLITE_ABORT].  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.
+**
+** On success, SQLITE_OK is returned.
+** Otherwise, an  [error code] or an [extended error code] is returned.
 **
 ** INVARIANTS:
 **
-** {F17873} The [sqlite3_blob_write(P,Z,N,X)] interface writes N bytes
-**          from buffer Z into
-**          the blob that [sqlite3_blob] object P refers to
-**          beginning at an offset of X into the blob.
+** {F17873} A successful invocation of [sqlite3_blob_write(P,Z,N,X)]
+**          shall write N bytes of data from buffer Z into the BLOB 
+**          referenced by [BLOB handle] P beginning at offset X into
+**          the BLOB.
 **
-** {F17875} The [sqlite3_blob_write(P,Z,N,X)] interface returns
-**          [SQLITE_READONLY] if the [sqlite3_blob] object P was
-**          [sqlite3_blob_open | opened] for reading only.
+** {F17874} In the absence of other overridding changes, the changes
+**          written to a BLOB by [sqlite3_blob_write()] shall
+**          remain in effect after the associated [BLOB handle] expires.
 **
-** {F17876} In [sqlite3_blob_write(P,Z,N,X)] if the size of the blob
-**          is less than N+X bytes, then the function returns [SQLITE_ERROR]
-**          and nothing is written into the blob.
+** {F17875} If the [BLOB handle] P was opened for reading only then
+**          an invocation of [sqlite3_blob_write(P,Z,N,X)] shall leave
+**          the referenced BLOB unchanged and return [SQLITE_READONLY].
 **
-** {F17879} In [sqlite3_blob_write(P,Z,N,X)] if X or N is less than zero
-**          then the function returns [SQLITE_ERROR]
-**          and nothing is written into the blob.
+** {F17876} If the size of the BLOB referenced by [BLOB handle] P is
+**          less than N+X bytes then [sqlite3_blob_write(P,Z,N,X)] shall
+**          leave the BLOB unchanged and return [SQLITE_ERROR].
 **
-** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface returns [SQLITE_OK]
-**          if N bytes where successfully written into blob.
+** {F17877} If the [BLOB handle] P is expired and X and N are within bounds
+**          then [sqlite3_blob_read(P,Z,N,X)] shall leave the BLOB
+**          unchanged and return [SQLITE_ABORT].
+**
+** {F17879} If X or N are less than zero then [sqlite3_blob_write(P,Z,N,X)]
+**          shall leave the BLOB referenced by [BLOB handle] P unchanged
+**          and return [SQLITE_ERROR].
+**
+** {F17882} The [sqlite3_blob_write(P,Z,N,X)] interface shall return
+**          [SQLITE_OK] if N bytes where successfully written into the BLOB.
 **
 ** {F17885} If the requested write could not be completed,
-**          the [sqlite3_blob_write(P,Z,N,X)] interface returns an
+**          the [sqlite3_blob_write(P,Z,N,X)] interface shall return an
 **          appropriate [error code] or [extended error code].
 **
 ** {F17888} If an error occurs during evaluation of [sqlite3_blob_write(D,...)]
 **          then subsequent calls to [sqlite3_errcode(D)],
-**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] will return
-**          information approprate for that error.
+**          [sqlite3_errmsg(D)], and [sqlite3_errmsg16(D)] shall return
+**          information appropriate for that error.
 */
 int sqlite3_blob_write(sqlite3_blob *, const void *z, int n, int iOffset);
 
 /*
-** CAPI3REF:  Virtual File System Objects {F11200}
+** CAPI3REF: Virtual File System Objects {F11200}
 **
 ** A virtual filesystem (VFS) is an [sqlite3_vfs] object
 ** that SQLite uses to interact
@@ -5343,12 +5695,11 @@
 ** New VFSes can be registered and existing VFSes can be unregistered.
 ** The following interfaces are provided.
 **
-** The sqlite3_vfs_find() interface returns a pointer to 
-** a VFS given its name.  Names are case sensitive.
+** The sqlite3_vfs_find() interface returns a pointer to a VFS given its name.
+** Names are case sensitive.
 ** Names are zero-terminated UTF-8 strings.
-** If there is no match, a NULL
-** pointer is returned.  If zVfsName is NULL then the default 
-** VFS is returned. 
+** If there is no match, a NULL pointer is returned.
+** If zVfsName is NULL then the default VFS is returned.
 **
 ** New VFSes are registered with sqlite3_vfs_register().
 ** Each new VFS becomes the default VFS if the makeDflt flag is set.
@@ -5358,7 +5709,7 @@
 ** same name are registered, the behavior is undefined.  If a
 ** VFS is registered with a name that is NULL or an empty string,
 ** then the behavior is undefined.
-** 
+**
 ** 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.
@@ -5372,7 +5723,7 @@
 **
 ** {F11206} If the N parameter to [sqlite3_vfs_find(N)] is NULL then
 **          the function returns a pointer to the default [sqlite3_vfs]
-**          object if there is one, or NULL if there is no default 
+**          object if there is one, or NULL if there is no default
 **          [sqlite3_vfs] object.
 **
 ** {F11209} The [sqlite3_vfs_register(P,F)] interface registers the
@@ -5382,9 +5733,8 @@
 ** {F11212} Using the [sqlite3_vfs_register(P,F)] interface to register
 **          the same [sqlite3_vfs] object multiple times is a harmless no-op.
 **
-** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the
-**          the [sqlite3_vfs] object P the default [sqlite3_vfs] object
-**          if F is non-zero.
+** {F11215} The [sqlite3_vfs_register(P,F)] interface makes the [sqlite3_vfs]
+**          object P the default [sqlite3_vfs] object if F is non-zero.
 **
 ** {F11218} The [sqlite3_vfs_unregister(P)] interface unregisters the
 **          [sqlite3_vfs] object P so that it is no longer returned by
@@ -5398,11 +5748,11 @@
 ** CAPI3REF: Mutexes {F17000}
 **
 ** The SQLite core uses these routines for thread
-** synchronization.  Though they are intended for internal
+** synchronization. Though they are intended for internal
 ** use by SQLite, code that links against SQLite is
 ** permitted to use any of these routines.
 **
-** The SQLite source code contains multiple implementations 
+** The SQLite source code contains multiple implementations
 ** of these mutex routines.  An appropriate implementation
 ** is selected automatically at compile-time.  The following
 ** implementations are available in the SQLite core:
@@ -5414,20 +5764,19 @@
 ** <li>   SQLITE_MUTEX_NOOP
 ** </ul>
 **
-** The SQLITE_MUTEX_NOOP implementation is a set of routines 
-** that does no real locking and is appropriate for use in 
+** The SQLITE_MUTEX_NOOP implementation is a set of routines
+** that does no real locking and is appropriate for use in
 ** a single-threaded application.  The SQLITE_MUTEX_OS2,
 ** SQLITE_MUTEX_PTHREAD, and SQLITE_MUTEX_W32 implementations
-** are appropriate for use on os/2, unix, and windows.
-** 
+** are appropriate for use on OS/2, Unix, and Windows.
+**
 ** If SQLite is compiled with the SQLITE_MUTEX_APPDEF preprocessor
 ** macro defined (with "-DSQLITE_MUTEX_APPDEF=1"), then no mutex
-** implementation is included with the library.  The
-** mutex interface routines defined here become external
-** references in the SQLite library for which implementations
-** must be provided by the application.  This facility allows an
-** application that links against SQLite to provide its own mutex
-** implementation without having to modify the SQLite core.
+** implementation is included with the library. In this case the
+** application must supply a custom mutex implementation using the
+** [SQLITE_CONFIG_MUTEX] option of the sqlite3_config() function
+** before calling sqlite3_initialize() or any other public sqlite3_
+** function that calls sqlite3_initialize().
 **
 ** {F17011} The sqlite3_mutex_alloc() routine allocates a new
 ** mutex and returns a pointer to it. {F17012} If it returns NULL
@@ -5444,7 +5793,7 @@
 ** <li>  SQLITE_MUTEX_STATIC_PRNG
 ** <li>  SQLITE_MUTEX_STATIC_LRU
 ** <li>  SQLITE_MUTEX_STATIC_LRU2
-** </ul> {END}
+** </ul>
 **
 ** {F17015} The first two constants cause sqlite3_mutex_alloc() to create
 ** a new mutex.  The new mutex is recursive when SQLITE_MUTEX_RECURSIVE
@@ -5466,41 +5815,45 @@
 **
 ** {F17018} 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.  {F17034} But for the static 
+** returns a different mutex on every call.  {F17034} But for the static
 ** mutex types, the same mutex is returned on every call that has
-** the same type number. {END}
+** the same type number.
 **
 ** {F17019} The sqlite3_mutex_free() routine deallocates a previously
 ** allocated dynamic mutex. {F17020} SQLite is careful to deallocate every
-** dynamic mutex that it allocates. {U17021} The dynamic mutexes must not be in 
-** use when they are deallocated. {U17022} Attempting to deallocate a static
+** dynamic mutex that it allocates. {A17021} The dynamic mutexes must not be in
+** use when they are deallocated. {A17022} Attempting to deallocate a static
 ** mutex results in undefined behavior. {F17023} SQLite never deallocates
 ** a static mutex. {END}
 **
 ** The sqlite3_mutex_enter() and sqlite3_mutex_try() routines attempt
 ** to enter a mutex. {F17024} If another thread is already within the mutex,
 ** sqlite3_mutex_enter() will block and sqlite3_mutex_try() will return
-** SQLITE_BUSY. {F17025}  The sqlite3_mutex_try() interface returns SQLITE_OK
+** SQLITE_BUSY. {F17025}  The sqlite3_mutex_try() interface returns [SQLITE_OK]
 ** upon successful entry.  {F17026} Mutexes created using
 ** SQLITE_MUTEX_RECURSIVE can be entered multiple times by the same thread.
 ** {F17027} In such cases the,
 ** mutex must be exited an equal number of times before another thread
-** can enter.  {U17028} If the same thread tries to enter any other
+** can enter.  {A17028} If the same thread tries to enter any other
 ** kind of mutex more than once, the behavior is undefined.
 ** {F17029} SQLite will never exhibit
-** such behavior in its own use of mutexes. {END}
+** such behavior in its own use of mutexes.
 **
-** Some systems (ex: windows95) do not the operation implemented by
-** sqlite3_mutex_try().  On those systems, sqlite3_mutex_try() will
-** always return SQLITE_BUSY.  {F17030} The SQLite core only ever uses
-** sqlite3_mutex_try() as an optimization so this is acceptable behavior. {END}
+** 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.  {F17030} The SQLite core only ever uses
+** sqlite3_mutex_try() as an optimization so this is acceptable behavior.
 **
 ** {F17031} The sqlite3_mutex_leave() routine exits a mutex that was
-** previously entered by the same thread.  {U17032} The behavior
+** previously entered by the same thread.  {A17032} The behavior
 ** is undefined if the mutex is not currently entered by the
 ** calling thread or is not currently allocated.  {F17033} SQLite will
 ** never do either. {END}
 **
+** 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()].
 */
 sqlite3_mutex *sqlite3_mutex_alloc(int);
@@ -5510,26 +5863,87 @@
 void sqlite3_mutex_leave(sqlite3_mutex*);
 
 /*
-** CAPI3REF: Mutex Verifcation Routines {F17080}
+** CAPI3REF: Mutex Methods Object {F17120}
+**
+** An instance of this structure defines the low-level routines
+** used to allocate and use mutexes.
+**
+** Usually, the default mutex implementations provided by SQLite are
+** sufficient, however the user has the option of substituting a custom
+** implementation for specialized deployments or systems for which SQLite
+** does not provide a suitable implementation. In this case, the user
+** creates and populates an instance of this structure to pass
+** to sqlite3_config() along with the [SQLITE_CONFIG_MUTEX] option.
+** Additionally, an instance of this structure can be used as an
+** output variable when querying the system for the current mutex
+** implementation, using the [SQLITE_CONFIG_GETMUTEX] option.
+**
+** The xMutexInit method defined by this structure is invoked as
+** part of system initialization by the sqlite3_initialize() function.
+** {F17001} The xMutexInit routine shall be called by SQLite once for each
+** effective call to [sqlite3_initialize()].
+**
+** The xMutexEnd method defined by this structure is invoked as
+** part of system shutdown by the sqlite3_shutdown() function. The
+** implementation of this method is expected to release all outstanding
+** resources obtained by the mutex methods implementation, especially
+** those obtained by the xMutexInit method. {F17003} The xMutexEnd()
+** interface shall be invoked once for each call to [sqlite3_shutdown()].
+**
+** The remaining seven methods defined by this structure (xMutexAlloc,
+** xMutexFree, xMutexEnter, xMutexTry, xMutexLeave, xMutexHeld and
+** xMutexNotheld) implement the following interfaces (respectively):
+**
+** <ul>
+**   <li>  [sqlite3_mutex_alloc()] </li>
+**   <li>  [sqlite3_mutex_free()] </li>
+**   <li>  [sqlite3_mutex_enter()] </li>
+**   <li>  [sqlite3_mutex_try()] </li>
+**   <li>  [sqlite3_mutex_leave()] </li>
+**   <li>  [sqlite3_mutex_held()] </li>
+**   <li>  [sqlite3_mutex_notheld()] </li>
+** </ul>
+**
+** The only difference is that the public sqlite3_XXX functions enumerated
+** above silently ignore any invocations that pass a NULL pointer instead
+** of a valid mutex handle. The implementations of the methods defined
+** by this structure are not required to handle this case, the results
+** of passing a NULL pointer instead of a valid mutex handle are undefined
+** (i.e. it is acceptable to provide an implementation that segfaults if
+** it is passed a NULL pointer).
+*/
+typedef struct sqlite3_mutex_methods sqlite3_mutex_methods;
+struct sqlite3_mutex_methods {
+  int (*xMutexInit)(void);
+  int (*xMutexEnd)(void);
+  sqlite3_mutex *(*xMutexAlloc)(int);
+  void (*xMutexFree)(sqlite3_mutex *);
+  void (*xMutexEnter)(sqlite3_mutex *);
+  int (*xMutexTry)(sqlite3_mutex *);
+  void (*xMutexLeave)(sqlite3_mutex *);
+  int (*xMutexHeld)(sqlite3_mutex *);
+  int (*xMutexNotheld)(sqlite3_mutex *);
+};
+
+/*
+** CAPI3REF: Mutex Verification Routines {F17080}
 **
 ** The sqlite3_mutex_held() and sqlite3_mutex_notheld() routines
 ** are intended for use inside assert() statements. {F17081} The SQLite core
 ** never uses these routines except inside an assert() and applications
 ** are advised to follow the lead of the core.  {F17082} The core only
 ** provides implementations for these routines when it is compiled
-** with the SQLITE_DEBUG flag.  {U17087} External mutex implementations
+** with the SQLITE_DEBUG flag.  {A17087} External mutex implementations
 ** are only required to provide these routines if SQLITE_DEBUG is
 ** defined and if NDEBUG is not defined.
 **
 ** {F17083} These routines should return true if the mutex in their argument
-** is held or not held, respectively, by the calling thread. {END}
+** is held or not held, respectively, by the calling thread.
 **
 ** {X17084} The implementation is not required to provided versions of these
-** routines that actually work.
-** If the implementation does not provide working
-** versions of these routines, it should at least provide stubs
-** that always return true so that one does not get spurious
-** assertion failures. {END}
+** routines that actually work. If the implementation does not provide working
+** versions of these routines, it should at least provide stubs that always
+** return true so that one does not get spurious assertion failures.
 **
 ** {F17085} If the argument to sqlite3_mutex_held() is a NULL pointer then
 ** the routine should return 1.  {END} This seems counter-intuitive since
@@ -5537,7 +5951,7 @@
 ** the reason the mutex does not exist is because the build is not
 ** using mutexes.  And we do not want the assert() containing the
 ** call to sqlite3_mutex_held() to fail, so a non-zero return is
-** the appropriate thing to do.  {F17086} The sqlite3_mutex_notheld() 
+** the appropriate thing to do.  {F17086} The sqlite3_mutex_notheld()
 ** interface should also return 1 when given a NULL pointer.
 */
 int sqlite3_mutex_held(sqlite3_mutex*);
@@ -5547,7 +5961,7 @@
 ** CAPI3REF: Mutex Types {F17001}
 **
 ** {F17002} The [sqlite3_mutex_alloc()] interface takes a single argument
-** which is one of these integer constants. {END}
+** which is one of these integer constants.
 */
 #define SQLITE_MUTEX_FAST             0
 #define SQLITE_MUTEX_RECURSIVE        1
@@ -5575,8 +5989,8 @@
 ** {F11306} If the second parameter (zDbName) does not match the name of any
 ** open database file, then SQLITE_ERROR is returned. {F11307} This error
 ** code is not remembered and will not be recalled by [sqlite3_errcode()]
-** or [sqlite3_errmsg()]. {U11308} The underlying xFileControl method might
-** also return SQLITE_ERROR.  {U11309} There is no way to distinguish between
+** or [sqlite3_errmsg()]. {A11308} The underlying xFileControl method might
+** also return SQLITE_ERROR.  {A11309} There is no way to distinguish between
 ** an incorrect zDbName and an SQLITE_ERROR return from the underlying
 ** xFileControl method. {END}
 **
@@ -5589,7 +6003,7 @@
 **
 ** The sqlite3_test_control() interface is used to read out internal
 ** state of SQLite and to inject faults into SQLite for testing
-** purposes.  The first parameter a operation code that determines
+** purposes.  The first parameter is an operation code that determines
 ** the number, meaning, and operation of all subsequent parameters.
 **
 ** This interface is not for use by applications.  It exists solely
@@ -5609,19 +6023,106 @@
 ** These constants are the valid operation code parameters used
 ** as the first argument to [sqlite3_test_control()].
 **
-** These parameters and their meansing are subject to change
+** These parameters and their meanings are subject to change
 ** without notice.  These values are for testing purposes only.
 ** Applications should not use any of these parameters or the
 ** [sqlite3_test_control()] interface.
 */
-#define SQLITE_TESTCTRL_FAULT_CONFIG             1
-#define SQLITE_TESTCTRL_FAULT_FAILURES           2
-#define SQLITE_TESTCTRL_FAULT_BENIGN_FAILURES    3
-#define SQLITE_TESTCTRL_FAULT_PENDING            4
 #define SQLITE_TESTCTRL_PRNG_SAVE                5
 #define SQLITE_TESTCTRL_PRNG_RESTORE             6
 #define SQLITE_TESTCTRL_PRNG_RESET               7
 #define SQLITE_TESTCTRL_BITVEC_TEST              8
+#define SQLITE_TESTCTRL_FAULT_INSTALL            9
+#define SQLITE_TESTCTRL_BENIGN_MALLOC_HOOKS     10
+
+/*
+** CAPI3REF: SQLite Runtime Status {F17200}
+**
+** This interface is used to retrieve runtime status information
+** about the preformance of SQLite, and optionally to reset various
+** highwater marks.  The first argument is an integer code for
+** the specific parameter to measure.  Recognized integer codes
+** are of the form [SQLITE_STATUS_MEMORY_USED | SQLITE_STATUS_...].
+** The current value of the parameter is returned into *pCurrent.
+** The highest recorded value is returned in *pHighwater.  If the
+** resetFlag is true, then the highest record value is reset after
+** *pHighwater is written. Some parameters do not record the highest
+** value.  For those parameters
+** nothing is written into *pHighwater and the resetFlag is ignored.
+** Other parameters record only the highwater mark and not the current
+** value.  For these latter parameters nothing is written into *pCurrent.
+**
+** This routine returns SQLITE_OK on success and a non-zero
+** [error code] on failure.
+**
+** This routine is threadsafe but is not atomic.  This routine can
+** called while other threads are running the same or different SQLite
+** interfaces.  However the values returned in *pCurrent and
+** *pHighwater reflect the status of SQLite at different points in time
+** and it is possible that another thread might change the parameter
+** in between the times when *pCurrent and *pHighwater are written.
+**
+** This interface is experimental and is subject to change or
+** removal in future releases of SQLite.
+*/
+int sqlite3_status(int op, int *pCurrent, int *pHighwater, int resetFlag);
+
+/*
+** CAPI3REF: Status Parameters {F17250}
+**
+** These integer constants designate various run-time status parameters
+** that can be returned by [sqlite3_status()].
+**
+** <dl>
+** <dt>SQLITE_STATUS_MEMORY_USED</dt>
+** <dd>This parameter is the current amount of memory checked out
+** using [sqlite3_malloc()], either directly or indirectly.  The
+** figure includes calls made to [sqlite3_malloc()] by the application
+** and internal memory usage by the SQLite library.  Scratch memory
+** controlled by [SQLITE_CONFIG_SCRATCH] and auxiliary page-cache
+** 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].</dd>
+**
+** <dt>SQLITE_STATUS_PAGECACHE_USED</dt>
+** <dd>This parameter returns the number of pages used out of the
+** page cache buffer configured using [SQLITE_CONFIG_PAGECACHE].  The
+** value returned is in pages, not in bytes.</dd>
+**
+** <dt>SQLITE_STATUS_PAGECACHE_OVERFLOW</dt>
+** <dd>This parameter returns the number of bytes of page cache
+** allocation which could not be statisfied by the [SQLITE_CONFIG_PAGECACHE]
+** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+**
+** <dt>SQLITE_STATUS_SCRATCH_USED</dt>
+** <dd>This parameter returns the number of allocations used out of the
+** scratch allocation lookaside buffer configured using
+** [SQLITE_CONFIG_SCRATCH].  The value returned is in allocations, not
+** in bytes.  Since a single thread may only have one allocation
+** outstanding at time, this parameter also reports the number of threads
+** using scratch memory at the same time.</dd>
+**
+** <dt>SQLITE_STATUS_SCRATCH_OVERFLOW</dt>
+** <dd>This parameter returns the number of bytes of scratch memory
+** allocation which could not be statisfied by the [SQLITE_CONFIG_SCRATCH]
+** buffer and where forced to overflow to [sqlite3_malloc()].</dd>
+**
+** <dt>SQLITE_STATUS_MALLOC_SIZE</dt>
+** <dd>This parameter records the largest memory allocation request
+** handed to [sqlite3_malloc()] or [sqlite3_realloc()] (or their
+** internal equivalents).  The value of interest is return in the
+** *pHighwater parameter to [sqlite3_status()].  The value written
+** into the *pCurrent parameter is undefined.</dd>
+** </dl>
+**
+** New status parameters may be added from time to time.
+*/
+#define SQLITE_STATUS_MEMORY_USED          0
+#define SQLITE_STATUS_PAGECACHE_USED       1
+#define SQLITE_STATUS_PAGECACHE_OVERFLOW   2
+#define SQLITE_STATUS_SCRATCH_USED         3
+#define SQLITE_STATUS_SCRATCH_OVERFLOW     4
+#define SQLITE_STATUS_MALLOC_SIZE          5
 
 
 /*

Modified: trunk/libgda/sqlite/utils.c
==============================================================================
--- trunk/libgda/sqlite/utils.c	(original)
+++ trunk/libgda/sqlite/utils.c	Sun Jul 27 19:25:27 2008
@@ -29,50 +29,6 @@
 #include <libgda/gda-connection-private.h>
 #include "gda-sqlite-recordset.h"
 
-/* 
- * copied from SQLite's sources to determine column affinity 
- */
-#define SQLITE_AFF_TEXT     'a'
-#define SQLITE_AFF_NONE     'b'
-#define SQLITE_AFF_NUMERIC  'c'
-#define SQLITE_AFF_INTEGER  'd'
-#define SQLITE_AFF_REAL     'e'
-static char get_affinity (const gchar *type)
-{
-	guint32 h = 0;
-	char aff = SQLITE_AFF_NUMERIC;
-	const unsigned char *ptr = (unsigned char *) type;
-	
-	while( *ptr ){
-		h = (h<<8) + g_ascii_tolower(*ptr);
-		ptr++;
-		if( h==(('c'<<24)+('h'<<16)+('a'<<8)+'r') ){             /* CHAR */
-			aff = SQLITE_AFF_TEXT;
-		}else if( h==(('c'<<24)+('l'<<16)+('o'<<8)+'b') ){       /* CLOB */
-			aff = SQLITE_AFF_TEXT;
-		}else if( h==(('t'<<24)+('e'<<16)+('x'<<8)+'t') ){       /* TEXT */
-			aff = SQLITE_AFF_TEXT;
-		}else if( h==(('b'<<24)+('l'<<16)+('o'<<8)+'b')          /* BLOB */
-			  && (aff==SQLITE_AFF_NUMERIC || aff==SQLITE_AFF_REAL) ){
-			aff = SQLITE_AFF_NONE;
-		}else if( h==(('r'<<24)+('e'<<16)+('a'<<8)+'l')          /* REAL */
-			  && aff==SQLITE_AFF_NUMERIC ){
-			aff = SQLITE_AFF_REAL;
-		}else if( h==(('f'<<24)+('l'<<16)+('o'<<8)+'a')          /* FLOA */
-			  && aff==SQLITE_AFF_NUMERIC ){
-			aff = SQLITE_AFF_REAL;
-		}else if( h==(('d'<<24)+('o'<<16)+('u'<<8)+'b')          /* DOUB */
-			  && aff==SQLITE_AFF_NUMERIC ){
-			aff = SQLITE_AFF_REAL;
-		}else if( (h&0x00FFFFFF)==(('i'<<16)+('n'<<8)+'t') ){    /* INT */
-			aff = SQLITE_AFF_INTEGER;
-			break;
-		}
-	}
-	
-	return aff;
-}
-
 static guint
 nocase_str_hash (gconstpointer v)
 {
@@ -90,15 +46,13 @@
 }
 
 void
-_gda_sqlite_update_types_hash (SqliteConnectionData *cdata)
+_gda_sqlite_compute_types_hash (SqliteConnectionData *cdata)
 {
 	GHashTable *types;
-	gint status;
-	sqlite3_stmt *tables_stmt = NULL;
-
 	types = cdata->types;
 	if (!types) {
-		types = g_hash_table_new_full (nocase_str_hash, nocase_str_equal, g_free, NULL); /* key= type name, value= gda type */
+		types = g_hash_table_new_full (nocase_str_hash, nocase_str_equal, g_free, NULL); 
+		/* key= type name, value= gda type */
 		cdata->types = types;
 	}
 	
@@ -111,52 +65,26 @@
 	g_hash_table_insert (types, g_strdup ("text"), GINT_TO_POINTER (G_TYPE_STRING));
 	g_hash_table_insert (types, g_strdup ("string"), GINT_TO_POINTER (G_TYPE_STRING));
 	g_hash_table_insert (types, g_strdup ("blob"), GINT_TO_POINTER (GDA_TYPE_BINARY));
+}
 
-	/* HACK: force SQLite to reparse the schema and thus discover new tables if necessary */
-	status = sqlite3_prepare_v2 (cdata->connection, "SELECT 1 FROM sqlite_master LIMIT 1", -1, &tables_stmt, NULL);
-	if (status == SQLITE_OK)
-		sqlite3_step (tables_stmt);
-	if (tables_stmt)
-		sqlite3_finalize (tables_stmt);
-
-	/* build a list of tables */
-	status = sqlite3_prepare_v2 (cdata->connection, "SELECT name "
-				     " FROM (SELECT * FROM sqlite_master UNION ALL "
-				     "       SELECT * FROM sqlite_temp_master) "
-				     " WHERE name not like 'sqlite_%%'", -1, &tables_stmt, NULL);
-	if ((status != SQLITE_OK) || !tables_stmt)
-		return;
-	for (status = sqlite3_step (tables_stmt); status == SQLITE_ROW; status = sqlite3_step (tables_stmt)) {
-		gchar *sql;
-		sqlite3_stmt *fields_stmt;
-		gint fields_status;
-
-		sql = g_strdup_printf ("PRAGMA table_info('%s');", sqlite3_column_text (tables_stmt, 0));
-		fields_status = sqlite3_prepare_v2 (cdata->connection, sql, -1, &fields_stmt, NULL);
-		g_free (sql);
-		if ((fields_status != SQLITE_OK) || !fields_stmt)
-			break;
-		
-		for (fields_status = sqlite3_step (fields_stmt); fields_status == SQLITE_ROW; 
-		     fields_status = sqlite3_step (fields_stmt)) {
-			const gchar *typname = (gchar *) sqlite3_column_text (fields_stmt, 2);
-			if (typname && !g_hash_table_lookup (types, typname)) {
-				GType type;
-				switch (get_affinity (typname)) {
-				case SQLITE_AFF_INTEGER:
-					type = G_TYPE_INT;
-					break;
-				case SQLITE_AFF_REAL:
-					type = G_TYPE_DOUBLE;
-					break;
-				default:
-					type = G_TYPE_STRING;
-					break;
-				}
-				g_hash_table_insert (types, g_strdup (typname), GINT_TO_POINTER (type));
-			}
-		}
-		sqlite3_finalize (fields_stmt);
+GType
+_gda_sqlite_compute_g_type (int sqlite_type)
+{
+	switch (sqlite_type) {
+	case SQLITE_INTEGER:
+		return G_TYPE_INT;
+	case SQLITE_FLOAT:
+		return G_TYPE_DOUBLE;
+	case 0:
+	case SQLITE_TEXT:
+		return G_TYPE_STRING;
+	case SQLITE_BLOB:
+		return GDA_TYPE_BINARY;
+	case SQLITE_NULL:
+		return GDA_TYPE_NULL;
+	default:
+		g_warning ("Unknown SQLite internal data type %d", sqlite_type);
+		return G_TYPE_STRING;
 	}
-	sqlite3_finalize (tables_stmt);
 }
+

Modified: trunk/libgda/sqlite/virtual/gda-vconnection-data-model.c
==============================================================================
--- trunk/libgda/sqlite/virtual/gda-vconnection-data-model.c	(original)
+++ trunk/libgda/sqlite/virtual/gda-vconnection-data-model.c	Sun Jul 27 19:25:27 2008
@@ -384,7 +384,11 @@
  * @func: a #GdaVConnectionDataModelFunc function pointer
  * @data: data to pass to @cunc calls
  *
- * Call @func for each #GdaDataModel represented as a table in @cnc.
+ * Call @func for each table in @cnc. 
+ *
+ * Warning: @func will be called for any table present in @cnc even if no data
+ * model represents the contents of the table (which means the 1st argument of @func
+ * may be %NULL)
  */
 void
 gda_vconnection_data_model_foreach (GdaVconnectionDataModel *cnc, 
@@ -401,8 +405,7 @@
 	while (list) {
 		GdaVConnectionTableData *td = (GdaVConnectionTableData*) list->data;
 		next = list->next;
-		if (td->spec->data_model)
-			func (td->spec->data_model, td->table_name, data);
+		func (td->spec->data_model, td->table_name, data);
 		list = next;
 	}
 }

Modified: trunk/libgda/sqlite/virtual/gda-vprovider-data-model.c
==============================================================================
--- trunk/libgda/sqlite/virtual/gda-vprovider-data-model.c	(original)
+++ trunk/libgda/sqlite/virtual/gda-vprovider-data-model.c	Sun Jul 27 19:25:27 2008
@@ -412,6 +412,7 @@
 	for (i = 0; i < ncols; i++) {
 		GdaColumn *column;
 		const gchar *name, *type;
+		GType gtype;
 		gchar *newcolname;
 
 		if (i != 0)
@@ -434,38 +435,32 @@
 		else
 			newcolname = g_strdup (name);
 
-		type = g_type_name (gda_column_get_g_type (column));
+		gtype = gda_column_get_g_type (column);
+		type = g_type_name (gtype);
 		if (!type) {
 			*pzErr = sqlite3_mprintf (_("Can't get data model's column type or type for column %d"), i);
 			g_string_free (sql, TRUE);
 			return SQLITE_ERROR;
 		}
-		else if (!strcmp (type, "GdaBlob") || !strcmp (type, "GdaBinary"))
+		else if ((gtype == GDA_TYPE_BLOB) || (gtype == GDA_TYPE_BINARY))
 			type = "blob";
-		else if (!strcmp (type, "gchararray"))
+		else if (gtype == G_TYPE_STRING)
 			type = "text";
-		else if (!strncmp (type, "gint", 4))
+		else if ((gtype == G_TYPE_INT) || (gtype == G_TYPE_UINT) || 
+			 (gtype == G_TYPE_INT64) || (gtype == G_TYPE_UINT64) ||
+			 (gtype == GDA_TYPE_SHORT) || (gtype == GDA_TYPE_USHORT) ||
+			 (gtype == G_TYPE_LONG) || (gtype == G_TYPE_ULONG))
 			type = "integer";
-		else if (!strcmp (type, "gdouble"))
+		else if ((gtype == G_TYPE_DOUBLE) || (gtype == G_TYPE_FLOAT))
 			type = "real";
-		else if (!strcmp (type, "gfloat"))
-			type = "real";
-		else {
-			/* use the declared GType */
-			type = g_type_name (gda_column_get_g_type (column));
-			if (!strcmp (type, "GdaBlob") || !strcmp (type, "GdaBinary"))
-				type = "blob";
-			else if (!strcmp (type, "gchararray"))
-				type = "text";
-			else if (!strncmp (type, "gint", 4))
-				type = "integer";
-			else if (!strcmp (type, "gdouble"))
-				type = "real";
-			else if (!strcmp (type, "gfloat"))
-				type = "real";
-			else
-				type = "text";
-		}
+		else if (gtype == G_TYPE_DATE)
+			type = "date";
+		else if (gtype == GDA_TYPE_TIME)
+			type = "time";
+		else if (gtype == GDA_TYPE_TIMESTAMP)
+			type = "timestamp";
+		else 
+			type = "text";
 
 		g_string_append (sql, newcolname);
 		g_free (newcolname);

Modified: trunk/po/POTFILES.in
==============================================================================
--- trunk/po/POTFILES.in	(original)
+++ trunk/po/POTFILES.in	Sun Jul 27 19:25:27 2008
@@ -67,8 +67,6 @@
 providers/mdb/gda-mdb-provider.c
 providers/mdb/libmain.c
 providers/mdb/mdb_specs_dsn.xml.in
-providers/firebird/firebird_specs_create_table.xml.in
-providers/firebird/gda-firebird-ddl.c
 providers/mysql/gda-mysql-ddl.c
 providers/mysql/gda-mysql-meta.c
 providers/mysql/gda-mysql-provider.c

Modified: trunk/po/POTFILES.skip
==============================================================================
--- trunk/po/POTFILES.skip	(original)
+++ trunk/po/POTFILES.skip	Sun Jul 27 19:25:27 2008
@@ -2,8 +2,10 @@
 libgda/sqlite/sql-parser.c/lemon.c
 libgda/sqlite/sql-parser.c/lempar.c
 libgda/sqlite/sqlite-src/sqlite3.c
+providers/firebird/firebird_specs_create_table.xml.in
 providers/firebird/firebird_specs_dsn.xml.in
 providers/firebird/gda-firebird-blob-op.c
+providers/firebird/gda-firebird-ddl.c
 providers/firebird/gda-firebird-provider.c
 providers/firebird/gda-firebird-recordset.c
 providers/firebird/libmain.c

Modified: trunk/providers/mdb/gda-mdb-provider.c
==============================================================================
--- trunk/providers/mdb/gda-mdb-provider.c	(original)
+++ trunk/providers/mdb/gda-mdb-provider.c	Sun Jul 27 19:25:27 2008
@@ -89,6 +89,7 @@
 static void
 gda_mdb_provider_init (GdaMdbProvider *myprv, GdaMdbProviderClass *klass)
 {
+	mdb_set_date_fmt ("%Y-%m-%d %H:%M:%S");
 }
 
 static void
@@ -231,9 +232,11 @@
 
 	/* look for parameters */
 	dirname = gda_quark_list_find (params, "DB_DIR");
+	if (!dirname)
+		dirname= "."; /* default to current directory */
 	dbname = gda_quark_list_find (params, "DB_NAME");
 	
-	if (!dirname || !dbname) {
+	if (!dbname) {
                 const gchar *str;
 
                 str = gda_quark_list_find (params, "FILENAME");
@@ -245,6 +248,7 @@
                 else {
                         gint len = strlen (str);
 			gint elen = strlen (FILE_EXTENSION);
+			dirname = NULL;
 
 			if (g_str_has_suffix (str, FILE_EXTENSION)) {
                                 gchar *ptr;
@@ -401,7 +405,8 @@
 		gda_column_set_name (gda_col, tmp);
 		g_free (tmp);
 		gda_column_set_g_type (gda_col, gda_mdb_type_to_gda (mdb_col->col_type));
-		tmp = sanitize_name (g_strdup (mdb_get_coltype_string (spec->cdata->mdb->default_backend, mdb_col->col_type)));
+		tmp = sanitize_name (g_strdup (mdb_get_coltype_string (spec->cdata->mdb->default_backend, 
+								       mdb_col->col_type)));
 		gda_column_set_dbms_type (gda_col, tmp);
 		g_free (tmp);
                 gda_column_set_defined_size (gda_col, mdb_col->col_size);
@@ -427,7 +432,7 @@
 	mdb_rewind_table (mdb_table);
 
 	/* prepare data model */
-	g_print ("New data model for table %p\n", mdb_table);
+	/*g_print ("New data model for MDB table %p\n", mdb_table);*/
 	model = gda_data_model_array_new (mdb_table->num_cols);
 	
 	/* prepare column types */
@@ -464,8 +469,10 @@
 		gda_column_set_dbms_type (gda_col, tmp);
 		g_free (tmp);
                 gda_column_set_g_type (gda_col, coltypes [c]);
-		/*g_print ("col: %s (%s/%s)\n", gda_column_get_name (gda_col), gda_column_get_dbms_type (gda_col),
-		  g_type_name (coltypes [c]));*/
+#ifdef GDA_DEBUG_NO
+		g_print ("col: %s (%s/%s)\n", gda_column_get_name (gda_col), gda_column_get_dbms_type (gda_col),
+			 g_type_name (coltypes [c]));
+#endif
         }
 
 	/* read data */
@@ -493,7 +500,8 @@
 #endif
 			}
 			else
-				gda_value_set_from_string ((tmpval = gda_value_new (coltypes [c])), bound_values[c], coltypes [c]);
+				gda_value_set_from_string ((tmpval = gda_value_new (coltypes [c])), bound_values[c], 
+							   coltypes [c]);
                         value_list = g_list_append (value_list, tmpval);
 		}
 

Modified: trunk/providers/postgres/gda-postgres-meta.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-meta.c	(original)
+++ trunk/providers/postgres/gda-postgres-meta.c	Sun Jul 27 19:25:27 2008
@@ -57,6 +57,8 @@
 	I_STMT_REF_CONSTRAINTS_ALL,
 	I_STMT_KEY_COLUMN_USAGE,
 	I_STMT_KEY_COLUMN_USAGE_ALL,
+	I_STMT_CHECK_COLUMN_USAGE,
+	I_STMT_CHECK_COLUMN_USAGE_ALL,
 	I_STMT_UDT,
 	I_STMT_UDT_ALL,
 	I_STMT_UDT_COLUMNS,
@@ -72,7 +74,16 @@
 	I_STMT_EL_TYPES_COL,
 	I_STMT_EL_TYPES_DOM,
 	I_STMT_EL_TYPES_UDT,
-	I_STMT_EL_TYPES_ALL
+	I_STMT_EL_TYPES_ROUT_PAR,
+	I_STMT_EL_TYPES_ROUT_COL,
+	I_STMT_EL_TYPES_ALL,
+	I_STMT_ROUTINES_ALL,
+	I_STMT_ROUTINES,
+	I_STMT_ROUTINES_ONE,
+	I_STMT_ROUTINE_PAR_ALL,
+	I_STMT_ROUTINE_PAR,
+	I_STMT_ROUTINE_COL_ALL,
+	I_STMT_ROUTINE_COL
 } InternalStatementItem;
 
 
@@ -120,10 +131,12 @@
 	"SELECT current_database(), nc.nspname, c.relname, a.attname, a.attnum, pg_get_expr(ad.adbin, ad.adrelid), CASE WHEN a.attnotnull OR t.typtype = 'd' AND t.typnotnull THEN FALSE ELSE TRUE END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN NULL ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum ELSE NULL END, 'gchararray', information_schema._pg_char_max_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_char_octet_length(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), information_schema._pg_numeric_scale(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t
 .*)), information_schema._pg_datetime_precision(information_schema._pg_truetypid(a.*, t.*), information_schema._pg_truetypmod(a.*, t.*)), NULL, NULL, NULL, NULL, NULL, NULL, CASE WHEN pg_get_expr(ad.adbin, ad.adrelid) LIKE 'nextval(%' THEN 'AUTO_INCREMENT' ELSE NULL END, CASE WHEN c.relkind = 'r' THEN TRUE ELSE FALSE END, pg_catalog.col_description(c.oid, a.attnum), CAST (t.oid AS int8) FROM pg_attribute a LEFT JOIN pg_attrdef ad ON a.attrelid = ad.adrelid AND a.attnum = ad.adnum, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typtype = 'd' AND t.typbasetype = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r', 'v'])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_tab
 le_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text))",
 
 	/* I_STMT_TABLES_CONSTRAINTS */
-	"SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints WHERE table_catalog = ##cat::string AND table_schema = ##schema::string AND table_name = ##name::string",
+	"SELECT current_database()::information_schema.sql_identifier AS constraint_catalog, nc.nspname::information_schema.sql_identifier AS constraint_schema, c.conname::information_schema.sql_identifier AS constraint_name, current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, CASE c.contype WHEN 'c'::\"char\" THEN 'CHECK'::text WHEN 'f'::\"char\" THEN 'FOREIGN KEY'::text WHEN 'p'::\"char\" THEN 'PRIMARY KEY'::text WHEN 'u'::\"char\" THEN 'UNIQUE'::text ELSE NULL::text END::information_schema.character_data AS constraint_type, CASE c.contype WHEN 'c'::\"char\" THEN c.consrc ELSE NULL END, CASE WHEN c.condeferrable THEN TRUE ELSE FALSE END AS is_deferrable, CASE WHEN c.condeferred THEN TRUE ELSE FALSE END AS initially_deferred FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r WHERE nc.oid = c.connamespace AND nr.oid = r.relna
 mespace AND c.conrelid = r.oid AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text)) AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string "
+	"UNION SELECT current_database()::information_schema.sql_identifier AS constraint_catalog, nr.nspname::information_schema.sql_identifier AS constraint_schema, (((((nr.oid::text || '_'::text) || r.oid::text) || '_'::text) || a.attnum::text) || '_not_null'::text)::information_schema.sql_identifier AS constraint_name, current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, 'CHECK'::character varying::information_schema.character_data AS constraint_type, a.attname || ' IS NOT NULL', FALSE AS is_deferrable, FALSE AS initially_deferred FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'SELECT'::
 text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text)) AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string",
 
 	/* I_STMT_TABLES_CONSTRAINTS_ALL */
-	"SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints",
+	"SELECT current_database()::information_schema.sql_identifier AS constraint_catalog, nc.nspname::information_schema.sql_identifier AS constraint_schema, c.conname::information_schema.sql_identifier AS constraint_name, current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, CASE c.contype WHEN 'c'::\"char\" THEN 'CHECK'::text WHEN 'f'::\"char\" THEN 'FOREIGN KEY'::text WHEN 'p'::\"char\" THEN 'PRIMARY KEY'::text WHEN 'u'::\"char\" THEN 'UNIQUE'::text ELSE NULL::text END::information_schema.character_data AS constraint_type, CASE c.contype WHEN 'c'::\"char\" THEN c.consrc ELSE NULL END, CASE WHEN c.condeferrable THEN TRUE ELSE FALSE END AS is_deferrable, CASE WHEN c.condeferred THEN TRUE ELSE FALSE END AS initially_deferred FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r WHERE nc.oid = c.connamespace AND nr.oid = r.relna
 mespace AND c.conrelid = r.oid AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text)) "
+	"UNION SELECT current_database()::information_schema.sql_identifier AS constraint_catalog, nr.nspname::information_schema.sql_identifier AS constraint_schema, (((((nr.oid::text || '_'::text) || r.oid::text) || '_'::text) || a.attnum::text) || '_not_null'::text)::information_schema.sql_identifier AS constraint_name, current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, 'CHECK'::character varying::information_schema.character_data AS constraint_type, a.attname || ' IS NOT NULL', FALSE AS is_deferrable, FALSE AS initially_deferred FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'SELECT'::
 text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text))",
 
 	/* I_STMT_TABLES_CONSTRAINT_NAMED */
 	"SELECT constraint_catalog, constraint_schema, constraint_name, table_catalog, table_schema, table_name, constraint_type, NULL, CASE WHEN is_deferrable = 'YES' THEN TRUE ELSE FALSE END, CASE WHEN initially_deferred = 'YES' THEN TRUE ELSE FALSE END FROM information_schema.table_constraints WHERE table_catalog = ##cat::string AND table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string",
@@ -140,6 +153,14 @@
 	/* I_STMT_KEY_COLUMN_USAGE_ALL */
 	"SELECT table_catalog, table_schema, table_name, constraint_name, column_name, ordinal_position FROM information_schema.key_column_usage",
 
+	/* I_STMT_CHECK_COLUMN_USAGE */
+	"SELECT current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, c.conname::information_schema.sql_identifier AS constraint_name,a.attname FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r, pg_attribute a, (SELECT sc.oid, information_schema._pg_expandarray (sc.conkey) as x FROM pg_constraint sc WHERE sc.contype = 'c') ss WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text)) AND c.contype = 'c' AND ss.oid = c.oid AND a.attrelid = r.oid AND a.attnum = (s
 s.x).x AND current_database() = ##cat::string AND nr.nspname = ##schema::string AND r.relname = ##name::string AND c.conname = ##name2::string "
+	"UNION SELECT current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, (((((nr.oid::text || '_'::text) || r.oid::text) || '_'::text) || a.attnum::text) || '_not_null'::text)::information_schema.sql_identifier AS constraint_name, a.attname FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'SELECT'::text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text)) AND current_database() = ##cat::string AND nr.nspname = 
 ##schema::string AND r.relname = ##name::string AND (((((nr.oid::text || '_'::text) || r.oid::text) || '_'::text) || a.attnum::text) || '_not_null'::text) = ##name2::string",
+
+	/* I_STMT_CHECK_COLUMN_USAGE_ALL */
+	"SELECT current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, c.conname::information_schema.sql_identifier AS constraint_name,a.attname FROM pg_namespace nc, pg_namespace nr, pg_constraint c, pg_class r, pg_attribute a, (SELECT sc.oid, information_schema._pg_expandarray (sc.conkey) as x FROM pg_constraint sc WHERE sc.contype = 'c') ss WHERE nc.oid = c.connamespace AND nr.oid = r.relnamespace AND c.conrelid = r.oid AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text)) AND c.contype = 'c' AND ss.oid = c.oid AND a.attrelid = r.oid AND a.attnum = (s
 s.x).x "
+	"UNION SELECT current_database()::information_schema.sql_identifier AS table_catalog, nr.nspname::information_schema.sql_identifier AS table_schema, r.relname::information_schema.sql_identifier AS table_name, (((((nr.oid::text || '_'::text) || r.oid::text) || '_'::text) || a.attnum::text) || '_not_null'::text)::information_schema.sql_identifier AS constraint_name, a.attname FROM pg_namespace nr, pg_class r, pg_attribute a WHERE nr.oid = r.relnamespace AND r.oid = a.attrelid AND a.attnotnull AND a.attnum > 0 AND NOT a.attisdropped AND r.relkind = 'r'::\"char\" AND NOT pg_is_other_temp_schema(nr.oid) AND (pg_has_role(r.relowner, 'USAGE'::text) OR has_table_privilege(r.oid, 'SELECT'::text) OR has_table_privilege(r.oid, 'INSERT'::text) OR has_table_privilege(r.oid, 'UPDATE'::text) OR has_table_privilege(r.oid, 'DELETE'::text) OR has_table_privilege(r.oid, 'REFERENCES'::text) OR has_table_privilege(r.oid, 'TRIGGER'::text))",
+
 	/* I_STMT_UDT */
 	"SELECT pg_catalog.current_database() as cat, n.nspname, t.typname, 'gchararray', pg_catalog.obj_description(t.oid), CASE WHEN pg_catalog.pg_type_is_visible(t.oid) IS TRUE THEN t.typname ELSE coalesce (n.nspname || '.', '') || t.typname END, coalesce (n.nspname || '.', '') || t.typname, CASE WHEN t.typname ~ '^_' THEN TRUE WHEN t.typname in ('any', 'anyarray', 'anyelement', 'cid', 'cstring', 'int2vector', 'internal', 'language_handler', 'oidvector', 'opaque', 'record', 'refcursor', 'regclass', 'regoper', 'regoperator', 'regproc', 'regprocedure', 'regtype', 'SET', 'smgr', 'tid', 'trigger', 'unknown', 'void', 'xid', 'oid', 'aclitem') THEN TRUE ELSE FALSE END, o.rolname FROM pg_catalog.pg_type t, pg_catalog.pg_user u, pg_catalog.pg_namespace n , pg_authid o WHERE t.typowner=u.usesysid AND n.oid = t.typnamespace AND pg_catalog.pg_type_is_visible(t.oid) AND (t.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = t.typrelid)) AND o.oid=t.typowner AND
  pg_catalog.current_database = ##cat::string AND n.nspname = ##schema::string",
 
@@ -185,10 +206,40 @@
 	/* I_STMT_EL_TYPES_UDT */
 	"SELECT 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum, pg_catalog.current_database(), n.nspname, udt.typname, 'UDT_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type udt INNER JOIN pg_namespace n ON (udt.typnamespace=n.oid) INNER JOIN pg_attribute a ON (a.attrelid=udt.typrelid) INNER JOIN pg_type t ON (a.atttypid=t.oid) INNER JOIN pg_namespace nt ON (t.typnamespace = nt.oid), pg_type bt, pg_namespace nbt where udt.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = udt.typrelid) AND t.typelem = bt.oid AND bt.typnamespace = nbt.oid AND t.typlen = -1 AND 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum = ##name::string",
 
+	/* I_STMT_EL_TYPES_ROUT_PAR */
+	"SELECT 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), 'ROUTINE_PAR', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type t, pg_type bt, pg_namespace nbt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss WHERE t.oid = (ss.x).x AND bt.oid= t.typelem AND bt.typnamespace = nbt.oid AND t.typelem <> 0::oid AND t.typlen = -1 AND 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n = ##name::string", 
+
+	/* I_STMT_EL_TYPES_ROUT_COL */
+	"SELECT 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), 'ROUTINE_COL', CASE WHEN at.typelem <> 0::oid AND at.typlen = -1 THEN 'array_spec' ELSE coalesce (ant.nspname || '.', '') || at.typname END, CASE WHEN at.typelem <> 0::oid AND at.typlen = -1 THEN 'ARR' || at.typelem ELSE NULL END, NULL, NULL FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss, pg_type at, pg_namespace ant WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND at.oid = t.typelem AND at.typnamespace = ant.oid AND (ss.pro
 argmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b') AND 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n = ##name::string",
+
 	/* I_STMT_EL_TYPES_ALL */
 	"SELECT 'UDT' || current_database() || '.' || n.nspname || '.' || udt.typname || '.' || a.attnum, pg_catalog.current_database(), n.nspname, udt.typname, 'UDT_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type udt INNER JOIN pg_namespace n ON (udt.typnamespace=n.oid) INNER JOIN pg_attribute a ON (a.attrelid=udt.typrelid) INNER JOIN pg_type t ON (a.atttypid=t.oid) INNER JOIN pg_namespace nt ON (t.typnamespace = nt.oid), pg_type bt, pg_namespace nbt where udt.typrelid != 0 AND (SELECT c.relkind = 'c' FROM pg_catalog.pg_class c WHERE c.oid = udt.typrelid) AND t.typelem = bt.oid AND bt.typnamespace = nbt.oid AND t.typlen = -1 "
 	"UNION SELECT 'DOM' || current_database() || '.' || nt.nspname || '.' || t.typname, current_database(), nt.nspname, t.typname, 'DOMAIN', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type t, pg_namespace nt, pg_type bt, pg_namespace nbt WHERE t.typnamespace = nt.oid AND t.typelem = bt.oid AND bt.typnamespace = nbt.oid AND t.typtype = 'd' AND t.typlen = -1 "
-	"UNION SELECT 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum, current_database(), nc.nspname, c.relname, 'TABLE_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_attribute a, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typelem = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r'::\"char\", 'v'::\"char\"])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text)) AND t.typelem <> 0::oid AND t.typlen = -1"
+	"UNION SELECT 'COL' || current_database() || '.' || nc.nspname || '.' || c.relname || '.' || a.attnum, current_database(), nc.nspname, c.relname, 'TABLE_COL', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_attribute a, pg_class c, pg_namespace nc, pg_type t JOIN pg_namespace nt ON t.typnamespace = nt.oid LEFT JOIN (pg_type bt JOIN pg_namespace nbt ON bt.typnamespace = nbt.oid) ON t.typelem = bt.oid WHERE a.attrelid = c.oid AND a.atttypid = t.oid AND nc.oid = c.relnamespace AND NOT pg_is_other_temp_schema(nc.oid) AND a.attnum > 0 AND NOT a.attisdropped AND (c.relkind = ANY (ARRAY['r'::\"char\", 'v'::\"char\"])) AND (pg_has_role(c.relowner, 'USAGE'::text) OR has_table_privilege(c.oid, 'SELECT'::text) OR has_table_privilege(c.oid, 'INSERT'::text) OR has_table_privilege(c.oid, 'UPDATE'::text) OR has_table_privilege(c.oid, 'REFERENCES'::text)) AND t.typelem <> 0::oid AND t.typlen = -1 "
+	"UNION SELECT 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), 'ROUTINE_PAR', coalesce (nbt.nspname || '.', '') || bt.typname, NULL, NULL, NULL FROM pg_type t, pg_type bt, pg_namespace nbt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss WHERE t.oid = (ss.x).x AND bt.oid= t.typelem AND bt.typnamespace = nbt.oid AND t.typelem <> 0::oid AND t.typlen = -1 "
+	"UNION SELECT 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n, current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), 'ROUTINE_COL', CASE WHEN at.typelem <> 0::oid AND at.typlen = -1 THEN 'array_spec' ELSE coalesce (ant.nspname || '.', '') || at.typname END, CASE WHEN at.typelem <> 0::oid AND at.typlen = -1 THEN 'ARR' || at.typelem ELSE NULL END, NULL, NULL FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss, pg_type at, pg_namespace ant WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND at.oid = t.typelem AND at.typnamespace = ant.oid AND (
 ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b')",
+
+	/* I_STMT_ROUTINES_ALL */
+	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_schema.c
 haracter_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.proowner",
+
+	/* I_STMT_ROUTINES */
+	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_schema.c
 haracter_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE current_database()::information_schema.sql_identifier = ##cat::string AND n.nspname::information_schema.sql_identifier = ##schema::string AND n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.proowner",
+
+	/* I_STMT_ROUTINES_ONE */
+	"SELECT current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier, current_database()::information_schema.sql_identifier, n.nspname::information_schema.sql_identifier, p.proname::information_schema.sql_identifier, CASE WHEN p.proisagg THEN 'AGGREGATE' ELSE 'FUNCTION' END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || n.nspname || '.' || p.proname || '.' || p.oid ELSE coalesce (nt.nspname || '.', '') || t.typname END AS rettype, p.proretset, p.pronargs, CASE WHEN l.lanname = 'sql'::name THEN 'SQL'::text ELSE 'EXTERNAL'::text END, CASE WHEN pg_has_role(p.proowner, 'USAGE'::text) THEN p.prosrc ELSE NULL::text END, CASE WHEN l.lanname = 'c'::name THEN p.prosrc ELSE NULL::text END, upper(l.lanname::text)::information_schema.character_data AS external_language, 'GENERAL'::character varying::information_schema.c
 haracter_data AS parameter_style, CASE WHEN p.provolatile = 'i' THEN TRUE ELSE FALSE END, 'MODIFIES'::character varying::information_schema.character_data AS sql_data_access, CASE WHEN p.proisstrict THEN TRUE ELSE FALSE END, pg_catalog.obj_description(p.oid), CASE WHEN pg_catalog.pg_function_is_visible(p.oid) IS TRUE THEN p.proname ELSE coalesce (n.nspname || '.', '') || p.proname END, coalesce (n.nspname || '.', '') || p.proname, o.rolname FROM pg_namespace n, pg_proc p, pg_language l, pg_type t, pg_namespace nt, pg_authid o WHERE current_database()::information_schema.sql_identifier = ##cat::string AND n.nspname::information_schema.sql_identifier = ##schema::string AND ((p.proname::text || '_'::text) || p.oid::text)::information_schema.sql_identifier = ##name::string AND n.oid = p.pronamespace AND p.prolang = l.oid AND p.prorettype = t.oid AND t.typnamespace = nt.oid AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text)) AND o.oid=p.
 proowner",
+
+	/* I_STMT_ROUTINE_PAR_ALL */
+	"SELECT current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), (ss.x).n, CASE WHEN ss.proargmodes IS NULL THEN 'IN'::text WHEN ss.proargmodes[(ss.x).n] = 'i' THEN 'IN' WHEN ss.proargmodes[(ss.x).n] = 'o' THEN 'OUT' WHEN ss.proargmodes[(ss.x).n] = 'b' THEN 'INOUT' ELSE NULL::text END, NULLIF(ss.proargnames[(ss.x).n], ''), CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::
 text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid",
+
+	/* I_STMT_ROUTINE_PAR */
+	"SELECT current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), (ss.x).n, CASE WHEN ss.proargmodes IS NULL THEN 'IN'::text WHEN ss.proargmodes[(ss.x).n] = 'i' THEN 'IN' WHEN ss.proargmodes[(ss.x).n] = 'o' THEN 'OUT' WHEN ss.proargmodes[(ss.x).n] = 'b' THEN 'INOUT' ELSE NULL::text END, NULLIF(ss.proargnames[(ss.x).n], ''), CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUP' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::
 text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND current_database() = ##cat::string AND ss.n_nspname = ##schema::string AND ((ss.proname::text || '_'::text) || ss.p_oid::text) = ##name::string",
+
+	/* I_STMT_ROUTINE_COL_ALL */
+	"SELECT current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), NULLIF(ss.proargnames[(ss.x).n], ''), (ss.x).n, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND (ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b') ORDER BY 1, 2, 3, 4, 5",
+
+	/* I_STMT_ROUTINE_COL */
+	"SELECT current_database(), ss.n_nspname, ((ss.proname::text || '_'::text) || ss.p_oid::text), NULLIF(ss.proargnames[(ss.x).n], ''), (ss.x).n, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'array_spec' ELSE coalesce (nt.nspname || '.', '') || t.typname END, CASE WHEN t.typelem <> 0::oid AND t.typlen = -1 THEN 'ROUC' || current_database() || '.' || ss.n_nspname || '.' || ((ss.proname::text || '_'::text) || ss.p_oid::text) || '.' || (ss.x).n ELSE NULL END FROM pg_type t, pg_namespace nt, ( SELECT n.nspname AS n_nspname, p.proname, p.oid AS p_oid, p.proargnames, p.proargmodes, information_schema._pg_expandarray(COALESCE(p.proallargtypes, p.proargtypes::oid[])) AS x FROM pg_namespace n, pg_proc p WHERE n.oid = p.pronamespace AND (pg_has_role(p.proowner, 'USAGE'::text) OR has_function_privilege(p.oid, 'EXECUTE'::text))) ss WHERE t.oid = (ss.x).x AND t.typnamespace = nt.oid AND (ss.proargmodes[(ss.x).n] = 'o' OR ss.proargmodes[(ss.x).n] = 'b') AND current_database() = ##ca
 t::string AND ss.n_nspname = ##schema::string AND ((ss.proname::text || '_'::text) || ss.p_oid::text) = ##name::string ORDER BY 1, 2, 3, 4, 5"
+
 };
 
 /*
@@ -513,6 +564,12 @@
 	else if (*cstr == 'U')
 		model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_EL_TYPES_UDT], i_set, 
 								 error);
+	else if (!strcmp (cstr, "ROUTINE_PAR"))
+		model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_EL_TYPES_ROUT_PAR], i_set, 
+								 error);
+	else if (!strcmp (cstr, "ROUTINE_COL"))
+		model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_EL_TYPES_ROUT_COL], i_set, 
+								 error);
 	else
 		TO_IMPLEMENT;
 	
@@ -1028,8 +1085,17 @@
 _gda_postgres_meta__check_columns (GdaServerProvider *prov, GdaConnection *cnc, 
 				   GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+	GdaDataModel *model;
+	gboolean retval;
+
+	model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_CHECK_COLUMN_USAGE_ALL], NULL, 
+							 error);
+	if (!model)
+		return FALSE;
+	retval = gda_meta_store_modify_with_context (store, context, model, error);
+	g_object_unref (model);
+		
+	return retval;
 }
 
 gboolean
@@ -1038,8 +1104,28 @@
 				  const GValue *table_catalog, const GValue *table_schema, 
 				  const GValue *table_name, const GValue *constraint_name)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+	GdaDataModel *model;
+	gboolean retval = TRUE;
+
+	gda_holder_set_value (gda_set_get_holder (i_set, "cat"), table_catalog);
+	gda_holder_set_value (gda_set_get_holder (i_set, "schema"), table_schema);
+	gda_holder_set_value (gda_set_get_holder (i_set, "name"), table_name);
+	gda_holder_set_value (gda_set_get_holder (i_set, "name2"), constraint_name);
+	model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_CHECK_COLUMN_USAGE], i_set, 
+							 error);
+	if (!model)
+		return FALSE;
+
+
+	/* modify meta store */
+	if (retval)
+		retval = gda_meta_store_modify (store, context->table_name, model, 
+						"table_schema = ##schema::string AND table_name = ##name::string AND constraint_name = ##name2::string", 
+						error, 
+						"schema", table_schema, "name", table_name, "name2", constraint_name, NULL);
+	g_object_unref (model);
+
+	return retval;	
 }
 
 gboolean
@@ -1108,8 +1194,28 @@
 _gda_postgres_meta__routines (GdaServerProvider *prov, GdaConnection *cnc, 
 			      GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+	GdaDataModel *model;
+	gboolean retval;
+
+	/* check correct postgres server version */
+	PostgresConnectionData *cdata;
+	cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+	if (cdata->version_float < 8.2) {
+		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
+			     _("PostgreSQL version 8.2.0 at least is required"));
+		return FALSE;
+	}
+
+	model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ROUTINES_ALL], NULL, 
+							 error);
+	if (!model)
+		return FALSE;
+	retval = gda_meta_store_modify_with_context (store, context, model, error);
+	g_object_unref (model);
+		
+	return retval;
 }
 
 gboolean
@@ -1118,16 +1224,91 @@
 			     const GValue *routine_catalog, const GValue *routine_schema, 
 			     const GValue *routine_name_n)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+	GdaDataModel *model;
+	gboolean retval = TRUE;
+
+	/* check correct postgres server version */
+	PostgresConnectionData *cdata;
+	cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+	if (cdata->version_float < 8.2) {
+		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
+			     _("PostgreSQL version 8.2.0 at least is required"));
+		return FALSE;
+	}
+
+	gda_holder_set_value (gda_set_get_holder (i_set, "cat"), routine_catalog);
+	gda_holder_set_value (gda_set_get_holder (i_set, "schema"), routine_schema);
+	if (routine_name_n) {
+		gda_holder_set_value (gda_set_get_holder (i_set, "name"), routine_name_n);
+		model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ROUTINES_ONE], i_set, 
+								 error);
+	}
+	else 
+		model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ROUTINES], i_set, 
+								 error);
+
+	if (!model)
+		return FALSE;
+	retval = gda_meta_store_modify_with_context (store, context, model, error);
+	g_object_unref (model);
+		
+	return retval;
 }
 
 gboolean
 _gda_postgres_meta__routine_col (GdaServerProvider *prov, GdaConnection *cnc, 
 				 GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+	GdaDataModel *model, *proxy;
+	gint ordinal_pos, i, nrows;
+	const GValue *spname = NULL;
+	gboolean retval;
+
+	/* check correct postgres server version */
+	PostgresConnectionData *cdata;
+	cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+	if (cdata->version_float < 8.2) {
+		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
+			     _("PostgreSQL version 8.2.0 at least is required"));
+		return FALSE;
+	}
+
+	model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ROUTINE_COL_ALL], NULL, 
+							 error);
+	if (!model)
+		return FALSE;
+
+	/* use a proxy to customize @model */
+	proxy = (GdaDataModel*) gda_data_proxy_new (model);
+	gda_data_proxy_set_sample_size ((GdaDataProxy*) proxy, 0);
+	nrows = gda_data_model_get_n_rows (model);
+	for (i = 0; i < nrows; i++) {
+		const GValue *cvalue;
+		GValue *v;
+
+		cvalue = gda_data_model_get_value_at (model, 2, i);
+		if (!spname || gda_value_compare (spname, cvalue))
+			/* reinit ordinal position */
+			ordinal_pos = 1;
+		spname = cvalue;
+
+		g_value_set_int ((v = gda_value_new (G_TYPE_INT)), ordinal_pos++);
+		retval = gda_data_model_set_value_at (proxy, 4, i, v, error);
+		gda_value_free (v);
+		if (!retval)
+			break;
+	}
+
+	if (retval)
+		retval = gda_meta_store_modify_with_context (store, context, proxy, error);
+	g_object_unref (model);
+	g_object_unref (proxy);
+		
+	return retval;
 }
 
 gboolean
@@ -1136,16 +1317,86 @@
 				const GValue *rout_catalog, const GValue *rout_schema, 
 				const GValue *rout_name)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+GdaDataModel *model, *proxy;
+	gint ordinal_pos, i, nrows;
+	const GValue *spname = NULL;
+	gboolean retval;
+
+	/* check correct postgres server version */
+	PostgresConnectionData *cdata;
+	cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+	if (cdata->version_float < 8.2) {
+		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
+			     _("PostgreSQL version 8.2.0 at least is required"));
+		return FALSE;
+	}
+
+	gda_holder_set_value (gda_set_get_holder (i_set, "cat"), rout_catalog);
+	gda_holder_set_value (gda_set_get_holder (i_set, "schema"), rout_schema);
+	gda_holder_set_value (gda_set_get_holder (i_set, "name"), rout_name);
+
+	model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ROUTINE_COL], i_set, 
+							 error);
+	if (!model)
+		return FALSE;
+
+	/* use a proxy to customize @model */
+	proxy = (GdaDataModel*) gda_data_proxy_new (model);
+	gda_data_proxy_set_sample_size ((GdaDataProxy*) proxy, 0);
+	nrows = gda_data_model_get_n_rows (model);
+	for (i = 0; i < nrows; i++) {
+		const GValue *cvalue;
+		GValue *v;
+
+		cvalue = gda_data_model_get_value_at (model, 2, i);
+		if (!spname || gda_value_compare (spname, cvalue))
+			/* reinit ordinal position */
+			ordinal_pos = 1;
+		spname = cvalue;
+
+		g_value_set_int ((v = gda_value_new (G_TYPE_INT)), ordinal_pos++);
+		retval = gda_data_model_set_value_at (proxy, 4, i, v, error);
+		gda_value_free (v);
+		if (!retval)
+			break;
+	}
+
+	if (retval)
+		retval = gda_meta_store_modify_with_context (store, context, proxy, error);
+	g_object_unref (model);
+	g_object_unref (proxy);
+		
+	return retval;
 }
 
 gboolean
 _gda_postgres_meta__routine_par (GdaServerProvider *prov, GdaConnection *cnc, 
 				 GdaMetaStore *store, GdaMetaContext *context, GError **error)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+	GdaDataModel *model;
+	gboolean retval;
+
+	/* check correct postgres server version */
+	PostgresConnectionData *cdata;
+	cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+	if (cdata->version_float < 8.2) {
+		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
+			     _("PostgreSQL version 8.2.0 at least is required"));
+		return FALSE;
+	}
+
+	model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ROUTINE_PAR_ALL], NULL, 
+							 error);
+	if (!model)
+		return FALSE;
+	retval = gda_meta_store_modify_with_context (store, context, model, error);
+	g_object_unref (model);
+		
+	return retval;
 }
 
 gboolean
@@ -1154,6 +1405,30 @@
 				const GValue *rout_catalog, const GValue *rout_schema, 
 				const GValue *rout_name)
 {
-	TO_IMPLEMENT;
-	return TRUE;
+	GdaDataModel *model;
+	gboolean retval = TRUE;
+
+	/* check correct postgres server version */
+	PostgresConnectionData *cdata;
+	cdata = (PostgresConnectionData*) gda_connection_internal_get_provider_data (cnc);
+	if (!cdata)
+		return FALSE;
+	if (cdata->version_float < 8.2) {
+		g_set_error (error, GDA_SERVER_PROVIDER_ERROR, GDA_SERVER_PROVIDER_SERVER_VERSION_ERROR,
+			     _("PostgreSQL version 8.2.0 at least is required"));
+		return FALSE;
+	}
+
+	gda_holder_set_value (gda_set_get_holder (i_set, "cat"), rout_catalog);
+	gda_holder_set_value (gda_set_get_holder (i_set, "schema"), rout_schema);
+	gda_holder_set_value (gda_set_get_holder (i_set, "name"), rout_name);
+
+	model = gda_connection_statement_execute_select (cnc, internal_stmt[I_STMT_ROUTINE_PAR], i_set, 
+							 error);
+	if (!model)
+		return FALSE;
+	retval = gda_meta_store_modify_with_context (store, context, model, error);
+	g_object_unref (model);
+		
+	return retval;
 }

Modified: trunk/providers/postgres/gda-postgres-provider.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-provider.c	(original)
+++ trunk/providers/postgres/gda-postgres-provider.c	Sun Jul 27 19:25:27 2008
@@ -116,7 +116,7 @@
 								     GdaStatement *stmt, GdaSet *params,
 								     GdaStatementModelUsage model_usage, 
 								     GType *col_types, GdaSet **last_inserted_row, 
-								     guint *task_id, GdaServerProviderAsyncCallback async_cb, 
+								     guint *task_id, GdaServerProviderExecCallback async_cb, 
 								     gpointer cb_data, GError **error);
 
 /* distributed transactions */
@@ -147,7 +147,7 @@
  * TO_ADD: any prepared statement to be used internally by the provider should be
  *         declared here, as constants and as SQL statements
  */
-GdaStatement **internal_stmt;
+static GdaStatement **internal_stmt;
 
 typedef enum {
 	I_STMT_BEGIN,
@@ -159,7 +159,7 @@
 	I_STMT_XA_RECOVER
 } InternalStatementItem;
 
-gchar *internal_sql[] = {
+static gchar *internal_sql[] = {
 	"BEGIN",
 	"COMMIT",
 	"ROLLBACK",
@@ -1895,7 +1895,7 @@
 					 GdaStatementModelUsage model_usage, 
 					 GType *col_types, GdaSet **last_inserted_row, 
 					 guint *task_id, 
-					 GdaServerProviderAsyncCallback async_cb, gpointer cb_data, GError **error)
+					 GdaServerProviderExecCallback async_cb, gpointer cb_data, GError **error)
 {
 	GdaPostgresPStmt *ps;
 	PostgresConnectionData *cdata;

Modified: trunk/providers/postgres/gda-postgres-recordset.c
==============================================================================
--- trunk/providers/postgres/gda-postgres-recordset.c	(original)
+++ trunk/providers/postgres/gda-postgres-recordset.c	Sun Jul 27 19:25:27 2008
@@ -60,8 +60,6 @@
 
 /* static helper functions */
 static void make_point (GdaGeometricPoint *point, const gchar *value);
-static void make_time (GdaTime *timegda, const gchar *value);
-static void make_timestamp (GdaTimestamp *timestamp, const gchar *value);
 static void set_value (GdaConnection *cnc, GValue *value, GType type, const gchar *thevalue, gint length);
 
 static void     set_prow_with_pg_res (GdaPostgresRecordset *imodel, GdaPRow *prow, gint pg_res_rownum);
@@ -608,72 +606,6 @@
 	point->y = atof (value);
 }
 
-/* Makes a GdaTime from a string like "12:30:15+01" */
-static void
-make_time (GdaTime *timegda, const gchar *value)
-{
-	timegda->hour = atoi (value);
-	value += 3;
-	timegda->minute = atoi (value);
-	value += 3;
-	timegda->second = atoi (value);
-	value += 2;
-	if (*value)
-		timegda->timezone = atoi (value);
-	else
-		timegda->timezone = GDA_TIMEZONE_INVALID;
-}
-
-/* Makes a GdaTimestamp from a string like "2003-12-13 13:12:01.12+01" */
-static void
-make_timestamp (GdaTimestamp *timestamp, const gchar *value)
-{
-	timestamp->year = atoi (value);
-	value += 5;
-	timestamp->month = atoi (value);
-	value += 3;
-	timestamp->day = atoi (value);
-	value += 3;
-	timestamp->hour = atoi (value);
-	value += 3;
-	timestamp->minute = atoi (value);
-	value += 3;
-	timestamp->second = atoi (value);
-	value += 2;
-	if (*value != '.') {
-		timestamp->fraction = 0;
-	} else {
-		gint ndigits = 0;
-		gint64 fraction;
-
-		value++;
-		fraction = atol (value);
-		while (*value && *value != '+') {
-			value++;
-			ndigits++;
-		}
-
-		while (ndigits < 3) {
-			fraction *= 10;
-			ndigits++;
-		}
-
-		while (fraction > 0 && ndigits > 3) {
-			fraction /= 10;
-			ndigits--;
-		}
-		
-		timestamp->fraction = fraction;
-	}
-
-	if (*value != '+') {
-		timestamp->timezone = 0;
-	} else {
-		value++;
-		timestamp->timezone = atol (value) * 60 * 60;
-	}
-}
-
 static void
 set_value (GdaConnection *cnc, GValue *value, GType type,
 	   const gchar *thevalue, gint length)
@@ -713,15 +645,11 @@
 		g_free (numeric.number);
 	}
 	else if (type == G_TYPE_DATE) {
-		GDate *gdate;
-		gdate = g_date_new ();
-		g_date_set_parse (gdate, thevalue);
-		if (!g_date_valid (gdate)) {
-			g_warning (_("Could not parse date '%s', assuming 01/01/0001"), thevalue);
-			g_date_clear (gdate, 1);
-			g_date_set_dmy (gdate, 1, 1, 1);
-		}
-		g_value_take_boxed (value, gdate);
+		GDate date;
+		if (!gda_parse_iso8601_date (&date, thevalue)) 
+			g_warning (_("Invalid date '%s' (date format should be YYYY-MM-DD)"), thevalue);
+		else
+			g_value_set_boxed (value, &date);
 	}
 	else if (type == GDA_TYPE_GEOMETRIC_POINT) {
 		GdaGeometricPoint point;
@@ -730,13 +658,18 @@
 	}
 	else if (type == GDA_TYPE_TIMESTAMP) {
 		GdaTimestamp timestamp;
-		make_timestamp (&timestamp, thevalue);
-		gda_value_set_timestamp (value, &timestamp);
+		if (! gda_parse_iso8601_timestamp (&timestamp, thevalue))
+			g_warning (_("Invalid timestamp '%s' (format should be YYYY-MM-DD HH:MM:SS[.ms])"), 
+				   thevalue);
+		else
+			gda_value_set_timestamp (value, &timestamp);
 	}
 	else if (type == GDA_TYPE_TIME) {
 		GdaTime timegda;
-		make_time (&timegda, thevalue);
-		gda_value_set_time (value, &timegda);
+		if (!gda_parse_iso8601_time (&timegda, thevalue)) 
+			g_warning (_("Invalid time '%s' (time format should be HH:MM:SS[.ms])"), thevalue);
+		else
+			gda_value_set_time (value, &timegda);
 	}
 	else if (type == GDA_TYPE_BINARY) {
 		/*

Modified: trunk/providers/skel-implementation/capi/gda-capi-provider.c
==============================================================================
--- trunk/providers/skel-implementation/capi/gda-capi-provider.c	(original)
+++ trunk/providers/skel-implementation/capi/gda-capi-provider.c	Sun Jul 27 19:25:27 2008
@@ -109,7 +109,7 @@
 								 GdaStatement *stmt, GdaSet *params,
 								 GdaStatementModelUsage model_usage, 
 								 GType *col_types, GdaSet **last_inserted_row, 
-								 guint *task_id, GdaServerProviderAsyncCallback async_cb, 
+								 guint *task_id, GdaServerProviderExecCallback async_cb, 
 								 gpointer cb_data, GError **error);
 
 /* distributed transactions */
@@ -140,13 +140,13 @@
  * TO_ADD: any prepared statement to be used internally by the provider should be
  *         declared here, as constants and as SQL statements
  */
-GdaStatement **internal_stmt;
+static GdaStatement **internal_stmt;
 
 typedef enum {
 	INTERNAL_STMT1
 } InternalStatementItem;
 
-gchar *internal_sql[] = {
+static gchar *internal_sql[] = {
 	"SQL for INTERNAL_STMT1"
 };
 
@@ -946,7 +946,7 @@
 				     GdaStatementModelUsage model_usage, 
 				     GType *col_types, GdaSet **last_inserted_row, 
 				     guint *task_id, 
-				     GdaServerProviderAsyncCallback async_cb, gpointer cb_data, GError **error)
+				     GdaServerProviderExecCallback async_cb, gpointer cb_data, GError **error)
 {
 	GdaCapiPStmt *ps;
 	CapiConnectionData *cdata;

Modified: trunk/tests/Makefile.am
==============================================================================
--- trunk/tests/Makefile.am	(original)
+++ trunk/tests/Makefile.am	Sun Jul 27 19:25:27 2008
@@ -14,7 +14,9 @@
 
 libgda_test_4_0_la_SOURCES = \
         $(test_headers) \
-        gda-ddl-creator.c
+        gda-ddl-creator.c \
+	test-cnc-utils.h \
+	test-cnc-utils.c
 
 libgda_test_4_0_la_LDFLAGS = -version-info $(GDA_CURRENT):$(GDA_REVISION):$(GDA_AGE) $(NO_UNDEFINED)
 libgda_test_4_0_la_LIBADD = \

Modified: trunk/tests/data-models/check_model_copy.c
==============================================================================
--- trunk/tests/data-models/check_model_copy.c	(original)
+++ trunk/tests/data-models/check_model_copy.c	Sun Jul 27 19:25:27 2008
@@ -92,6 +92,21 @@
 	gboolean retval = TRUE;
 	GError *error = NULL;
 
+	/* make sure we only test data model dumps */
+	xmlDocPtr doc;
+	xmlNodePtr root;
+	doc = xmlParseFile (filename);
+	if (!doc) 
+		/* abort the test */
+		return TRUE;
+	root = xmlDocGetRootElement (doc);
+	if (strcmp (root->name, "gda_array")) {
+		/* abort the test */
+		xmlFreeDoc (doc);
+		return TRUE;
+	}
+	xmlFreeDoc (doc);
+
 	import = gda_data_model_import_new_file (filename, TRUE, NULL);
 
 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {

Modified: trunk/tests/data-models/check_model_import.c
==============================================================================
--- trunk/tests/data-models/check_model_import.c	(original)
+++ trunk/tests/data-models/check_model_import.c	Sun Jul 27 19:25:27 2008
@@ -20,8 +20,6 @@
 
 	gda_init ();
 
-	
-
 	if (argc == 2) {
 		if (g_str_has_suffix (argv[1], ".xml")) {
 			g_print ("Tested: %s\n", argv[1]);
@@ -91,6 +89,21 @@
 	gboolean retval = TRUE;
 	gchar *export, *contents;
 
+	/* make sure we only test data model dumps */
+	xmlDocPtr doc;
+	xmlNodePtr root;
+	doc = xmlParseFile (filename);
+	if (!doc) 
+		/* abort the test */
+		return TRUE;
+	root = xmlDocGetRootElement (doc);
+	if (strcmp (root->name, "gda_array")) {
+		/* abort the test */
+		xmlFreeDoc (doc);
+		return TRUE;
+	}
+	xmlFreeDoc (doc);
+
 	import = gda_data_model_import_new_file (filename, TRUE, NULL);
 
 	if ((errors = gda_data_model_import_get_errors (GDA_DATA_MODEL_IMPORT (import)))) {

Modified: trunk/tests/gda-ddl-creator.c
==============================================================================
--- trunk/tests/gda-ddl-creator.c	(original)
+++ trunk/tests/gda-ddl-creator.c	Sun Jul 27 19:25:27 2008
@@ -72,7 +72,7 @@
 
 struct _GdaDDLCreatorPrivate {
 	GdaConnection *cnc;
-	GdaMetaStruct *mstruct;
+	GdaMetaStruct *d_mstruct;
 
 	GHashTable    *provider_specifics; /* key = a ProviderSpecificKey , value = a ProviderSpecificValue */
 	GValue *catalog;
@@ -201,7 +201,7 @@
 {
 	creator->priv = g_new0 (GdaDDLCreatorPrivate, 1);
 	creator->priv->cnc = NULL;
-	creator->priv->mstruct = (GdaMetaStruct*) g_object_new (GDA_TYPE_META_STRUCT, NULL);
+	creator->priv->d_mstruct = NULL;
 	creator->priv->provider_specifics = g_hash_table_new_full (ProviderSpecific_hash, ProviderSpecific_equal,
 								   (GDestroyNotify) ProviderSpecific_key_free,
 								   (GDestroyNotify) ProviderSpecific_value_free);
@@ -211,34 +211,6 @@
 	creator->priv->quoted_schema = NULL;
 }
 
-
-/**
- * gda_ddl_creator_new_with_file
- * @xml_spec_file: a file name
- * @error: a place to store errors, or %NULL
- *
- * Create a new #GdaDDLCreator object using @xml_spec_file as the description
- * of the database objects
- *
- * Returns: the newly created object, or %NULL if an error occurred
- */
-GdaDDLCreator *
-gda_ddl_creator_new_with_file (const gchar *xml_spec_file, GError **error) 
-{
-	GdaDDLCreator *creator;
-	
-	g_return_val_if_fail (xml_spec_file && *xml_spec_file, NULL);
-	creator = (GdaDDLCreator *) g_object_new (GDA_TYPE_DDL_CREATOR, NULL);
-	
-	if (!gda_meta_struct_load_from_xml_file (creator->priv->mstruct, NULL, NULL, xml_spec_file, error) ||
-	    !load_customization (creator, xml_spec_file, error)) {
-		g_object_unref (creator);
-		creator = NULL;
-	}
-
-	return creator;
-}
-
 static void
 gda_ddl_creator_dispose (GObject *object) 
 {
@@ -260,9 +232,9 @@
 			creator->priv->cnc = NULL;
 		}
 
-		if (creator->priv->mstruct) {
-			g_object_unref (creator->priv->mstruct);
-			creator->priv->mstruct = NULL;
+		if (creator->priv->d_mstruct) {
+			g_object_unref (creator->priv->d_mstruct);
+			creator->priv->d_mstruct = NULL;
 		}
 	}
 	
@@ -371,6 +343,49 @@
 	}
 }
 
+/**
+ * gda_ddl_creator_new
+ * Create a new #GdaDDLCreator object
+ *
+ * Returns: the newly created object
+ */
+GdaDDLCreator *
+gda_ddl_creator_new (void) 
+{
+	return (GdaDDLCreator *) g_object_new (GDA_TYPE_DDL_CREATOR, NULL);
+}
+
+/**
+ * gda_ddl_creator_set_dest_from_file
+ * @ddlc: a #GdaDDLCreator object
+ * @xml_spec_file: a file name
+ * @error: a place to store errors, or %NULL
+ *
+ * Sets the destination structure
+ *
+ * Returns: TRUE if no error occurred
+ */
+gboolean
+gda_ddl_creator_set_dest_from_file (GdaDDLCreator *ddlc, const gchar *xml_spec_file, GError **error)
+{
+	g_return_val_if_fail (GDA_IS_DDL_CREATOR (ddlc), FALSE);
+	g_return_val_if_fail (xml_spec_file && *xml_spec_file, FALSE);
+
+	if (ddlc->priv->d_mstruct)
+		g_object_unref (ddlc->priv->d_mstruct);
+
+	ddlc->priv->d_mstruct = (GdaMetaStruct*) g_object_new (GDA_TYPE_META_STRUCT, NULL);
+
+	if (!gda_meta_struct_load_from_xml_file (ddlc->priv->d_mstruct, NULL, NULL, xml_spec_file, error) ||
+	    !load_customization (ddlc, xml_spec_file, error)) {
+		g_object_unref (ddlc->priv->d_mstruct);
+		ddlc->priv->d_mstruct = NULL;
+		return FALSE;
+	}
+	else
+		return TRUE;
+}
+
 static gboolean
 load_customization (GdaDDLCreator *ddlc, const gchar *xml_spec_file, GError **error)
 {
@@ -409,11 +424,10 @@
 				}
 
 				xmlNodePtr rnode;
-				gboolean pname_used = FALSE;
 				for (rnode = snode->children; rnode; rnode = rnode->next) {
 					if (!strcmp ((gchar *) rnode->name, "replace") ||
 					    !strcmp ((gchar *) rnode->name, "ignore")) {
-						xmlChar *context;
+						xmlChar *context, *tmp;
 						context = xmlGetProp (rnode, BAD_CAST "context");
 						if (!context) {
 							g_warning ("<%s> section ignored because no context specified",
@@ -422,18 +436,25 @@
 						}
 						ProviderSpecificKey *key = g_new0 (ProviderSpecificKey, 1);
 						ProviderSpecificValue *val = g_new0 (ProviderSpecificValue, 1);
-						key->prov = (gchar *) pname; 
-						pname_used = TRUE;
-						key->path = (gchar *) context;
-						key->expr = (gchar *) xmlGetProp (rnode, BAD_CAST "expr");
-						val->repl = (gchar *) xmlGetProp (rnode, BAD_CAST "replace_with");
+						key->prov = g_strdup ((gchar *) pname);
+						key->path = g_strdup ((gchar *) context);
+						xmlFree (context);
+						tmp = xmlGetProp (rnode, BAD_CAST "expr");
+						if (tmp) {
+							key->expr = g_strdup ((gchar *) tmp);
+							xmlFree (tmp);
+						}
+						tmp = xmlGetProp (rnode, BAD_CAST "replace_with");
+						if (tmp) {
+							val->repl = g_strdup ((gchar *) tmp);
+							xmlFree (tmp);
+						}
 						g_hash_table_insert (ddlc->priv->provider_specifics, key, val);
 						/*g_print ("RULE: %s, %s, %s => %s\n", key->prov,
 						  key->path, key->expr, val->repl);*/
 					}
 				}
-				if (!pname_used)
-					xmlFree (pname);
+				xmlFree (pname);
 			}
 		}
 	}
@@ -524,6 +545,9 @@
 		if (! gda_server_operation_set_value_at (op, "FALSE", error,
 							 "/FIELDS_A/@COLUMN_AUTOINC/%d", index))
 			goto onerror;
+		if (! gda_server_operation_set_value_at (op, "FALSE", error,
+							 "/FIELDS_A/@COLUMN_UNIQUE/%d", index))
+			goto onerror;
 		repl = provider_specific_match (ddlc->priv->provider_specifics, prov, "dummy", "/FIELDS_A/@COLUMN_PKEY");
 		if (repl) {
 			if (! gda_server_operation_set_value_at (op, tcol->pkey ? "TRUE" : "FALSE", error,
@@ -556,7 +580,8 @@
 		}
 	}
 
-	if (0) {
+#ifdef GDA_DEBUG_NO
+	{
 		xmlNodePtr node;
 		xmlBufferPtr buffer;
 		node = gda_server_operation_save_data_to_xml (op, NULL);
@@ -566,6 +591,7 @@
 		xmlBufferDump (stdout, buffer);
 		xmlBufferFree (buffer);
 	}
+#endif
 
 	return op;
  onerror:
@@ -610,7 +636,7 @@
 }
 
 /**
- * gda_ddl_creator_get_sql_for_create_objects
+ * gda_ddl_creator_get_sql
  * @ddlc: a #GdaDDLCreator object
  * @error: a place to store errors, or %NULL
  *
@@ -619,7 +645,7 @@
  * Returns: a new string if no error occurred, or %NULL
  */
 gchar *
-gda_ddl_creator_get_sql_for_create_objects (GdaDDLCreator *ddlc, GError **error)
+gda_ddl_creator_get_sql (GdaDDLCreator *ddlc, GError **error)
 {
 	GString *string;
 	gchar *sql;
@@ -634,7 +660,7 @@
 	/* render operations to SQL */
 	GdaServerProvider *prov = gda_connection_get_provider_obj (ddlc->priv->cnc);
 	GSList *objlist, *list;
-	objlist = gda_meta_struct_get_all_db_objects (ddlc->priv->mstruct);
+	objlist = gda_meta_struct_get_all_db_objects (ddlc->priv->d_mstruct);
 
 	string = g_string_new ("");
 	for (list = objlist; list; list = list->next) {
@@ -667,14 +693,14 @@
 }
 
 /**
- * gda_ddl_creator_create_objects
+ * gda_ddl_creator_execute
  * @ddlc: a #GdaDDLCreator object
  * @error: a place to store errors, or %NULL
  *
  * 
  */
 gboolean
-gda_ddl_creator_create_objects (GdaDDLCreator *ddlc, GError **error)
+gda_ddl_creator_execute (GdaDDLCreator *ddlc, GError **error)
 {
 	g_return_val_if_fail (GDA_IS_DDL_CREATOR (ddlc), FALSE);
 	g_return_val_if_fail (ddlc->priv, FALSE);
@@ -683,6 +709,11 @@
 			     _("No connection specified"));
 		return FALSE;
 	}
+	if (!ddlc->priv->d_mstruct) {
+		g_set_error (error, GDA_DDL_CREATOR_ERROR, GDA_DDL_CREATOR_NO_CONNECTION_ERROR,
+			     _("No destination database objects specified"));
+		return FALSE;
+	}
 
 	/* begin transaction */
 	if (!gda_connection_begin_transaction (ddlc->priv->cnc, NULL, GDA_TRANSACTION_ISOLATION_UNKNOWN,
@@ -692,7 +723,7 @@
 	/* execute operations */
 	GdaServerProvider *prov = gda_connection_get_provider_obj (ddlc->priv->cnc);
 	GSList *objlist, *list;
-	objlist = gda_meta_struct_get_all_db_objects (ddlc->priv->mstruct);
+	objlist = gda_meta_struct_get_all_db_objects (ddlc->priv->d_mstruct);
 	for (list = objlist; list; list = list->next) {
 		GdaServerOperation *op;
 		op = prepare_dbo_server_operation (ddlc, prov, NULL, GDA_META_DB_OBJECT (list->data), error);
@@ -717,20 +748,3 @@
 	return FALSE;
 }
 
-/**
- * gda_ddl_creator_delete_objects
- */
-gboolean
-gda_ddl_creator_delete_objects (GdaDDLCreator *ddlc, GError **error)
-{
-	g_return_val_if_fail (GDA_IS_DDL_CREATOR (ddlc), FALSE);
-	g_return_val_if_fail (ddlc->priv, FALSE);
-	if (!ddlc->priv->cnc) {
-		g_set_error (error, GDA_DDL_CREATOR_ERROR, GDA_DDL_CREATOR_NO_CONNECTION_ERROR,
-			     _("No connection specified"));
-		return FALSE;
-	}
-
-	TO_IMPLEMENT;
-	return FALSE;
-}

Modified: trunk/tests/gda-ddl-creator.h
==============================================================================
--- trunk/tests/gda-ddl-creator.h	(original)
+++ trunk/tests/gda-ddl-creator.h	Sun Jul 27 19:25:27 2008
@@ -47,17 +47,6 @@
 	GDA_DDL_CREATOR_INCORRECT_SCHEMA_ERROR,
 	GDA_DDL_CREATOR_NO_CONNECTION_ERROR,
 	GDA_DDL_CREATOR_INTERNAL_ERROR, 
-
-	GDA_DDL_CREATOR_UNSUPPORTED_PROVIDER_ERROR,
-	GDA_DDL_CREATOR_DDL_CONTEXT_ERROR,
-	GDA_DDL_CREATOR_MODIFY_CONTENTS_ERROR,
-	GDA_DDL_CREATOR_EXTRACT_SQL_ERROR,
-	GDA_DDL_CREATOR_ATTRIBUTE_NOT_FOUND_ERROR,
-	GDA_DDL_CREATOR_ATTRIBUTE_ERROR,
-	GDA_DDL_CREATOR_SCHEMA_OBJECT_NOT_FOUND_ERROR,
-	GDA_DDL_CREATOR_SCHEMA_OBJECT_CONFLICT_ERROR,
-	GDA_DDL_CREATOR_SCHEMA_OBJECT_DESCR_ERROR,
-	GDA_DDL_CREATOR_TRANSACTION_ALREADY_STARTED_ERROR
 } GdaDDLCreatorError;
 
 
@@ -75,21 +64,17 @@
 };
 
 GType             gda_ddl_creator_get_type             (void) G_GNUC_CONST;
-GdaDDLCreator    *gda_ddl_creator_new_with_file        (const gchar *xml_spec_file, GError **error);
-
-void              gda_ddl_creator_set_connection       (GdaDDLCreator *ddlc, GdaConnection *cnc);
-gchar            *gda_ddl_creator_get_sql_for_create_objects (GdaDDLCreator *ddlc, GError **error);
+GdaDDLCreator    *gda_ddl_creator_new                  (void);
 
-/* must use a transaction, fails if it cannot start one */
-gboolean          gda_ddl_creator_create_objects       (GdaDDLCreator *ddlc, GError **error);
-gboolean          gda_ddl_creator_delete_objects       (GdaDDLCreator *ddlc, GError **error);
+gboolean          gda_ddl_creator_set_dest_from_file   (GdaDDLCreator *ddlc, const gchar *xml_spec_file, 
+							GError **error);
+//gboolean          gda_ddl_creator_set_dest_from_meta   (GdaDDLCreator *ddlc, GdaMetaStruct *struct, GError **error);
 
+void              gda_ddl_creator_set_connection       (GdaDDLCreator *ddlc, GdaConnection *cnc);
 
-/* ideas:
-GdaDDLCreator    *gda_ddl_creator_new_with_meta_struct (GdaMetaStruct *mstruct);
 
-gboolean          gda_ddl_creator_update_objects       (GdaDDLCreator ddlc, GError **error);
-*/
+gchar            *gda_ddl_creator_get_sql              (GdaDDLCreator *ddlc, GError **error);
+gboolean          gda_ddl_creator_execute              (GdaDDLCreator *ddlc, GError **error);
 
 G_END_DECLS
 

Modified: trunk/tests/multi-threading/Makefile.am
==============================================================================
--- trunk/tests/multi-threading/Makefile.am	(original)
+++ trunk/tests/multi-threading/Makefile.am	Sun Jul 27 19:25:27 2008
@@ -3,7 +3,8 @@
 	-I$(top_srcdir)/libgda \
 	-I$(top_builddir) \
 	$(LIBGDA_CFLAGS) \
-	-DROOT_DIR=\""$(top_srcdir)"\"
+	-DROOT_DIR=\""$(top_srcdir)"\" \
+	-DTOP_BUILD_DIR=\""$(top_builddir)"\"
 
 TESTS = check_mutex check_parser check_cnc_lock
 check_PROGRAMS = check_mutex check_parser check_cnc_lock
@@ -23,4 +24,6 @@
 	$(top_builddir)/libgda/libgda-4.0.la \
 	$(LIBGDA_LIBS)
 
+EXTRA_DIST = testdb.sql
+
 DISTCLEANFILES = testdb.db

Modified: trunk/tests/multi-threading/check_cnc_lock.c
==============================================================================
--- trunk/tests/multi-threading/check_cnc_lock.c	(original)
+++ trunk/tests/multi-threading/check_cnc_lock.c	Sun Jul 27 19:25:27 2008
@@ -26,6 +26,10 @@
 	gchar *fname;
 	GError *error = NULL;
 
+	/* set up test environment */
+        g_setenv ("GDA_TOP_BUILD_DIR", TOP_BUILD_DIR, 0);
+	g_setenv ("GDA_TOP_SRC_DIR", ROOT_DIR, 0);
+
 	g_type_init ();
 	gda_init ();
 

Modified: trunk/tests/providers/Makefile.am
==============================================================================
--- trunk/tests/providers/Makefile.am	(original)
+++ trunk/tests/providers/Makefile.am	Sun Jul 27 19:25:27 2008
@@ -91,54 +91,63 @@
 check_bdb_CFLAGS = 
 check_bdb_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_ibmdb2_SOURCES = $(common_sources) check_ibmdb2.c
 check_ibmdb2_CFLAGS = 
 check_ibmdb2_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_firebird_SOURCES = $(common_sources) check_firebird.c
 check_firebird_CFLAGS = 
 check_firebird_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_mdb_SOURCES = $(common_sources) check_mdb.c
 check_mdb_CFLAGS = 
 check_mdb_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_mysql_SOURCES = $(common_sources) check_mysql.c
 check_mysql_CFLAGS = 
 check_mysql_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_msql_SOURCES = $(common_sources) check_msql.c
 check_msql_CFLAGS = 
 check_msql_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_odbc_SOURCES = $(common_sources) check_odbc.c
 check_odbc_CFLAGS = 
 check_odbc_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_oracle_SOURCES = $(common_sources) check_oracle.c
 check_oracle_CFLAGS = 
 check_oracle_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_postgres_SOURCES = $(common_sources) check_postgres.c
 check_postgres_CFLAGS = 
 check_postgres_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_sybase_SOURCES = $(common_sources) check_sybase.c
@@ -151,18 +160,21 @@
 check_freetds_CFLAGS = 
 check_freetds_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_xbase_SOURCES = $(common_sources) check_xbase.c
 check_xbase_CFLAGS = 
 check_xbase_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 check_ldap_SOURCES = $(common_sources) check_ldap.c
 check_ldap_CFLAGS = 
 check_ldap_LDADD =  \
 	$(top_builddir)/libgda/libgda-4.0.la \
+	$(top_builddir)/tests/libgda-test-4.0.la \
 	$(LIBGDA_LIBS)
 
 EXTRA_DIST = \

Modified: trunk/tests/providers/TYPES_SCHEMA_PostgreSQL.xml
==============================================================================
--- trunk/tests/providers/TYPES_SCHEMA_PostgreSQL.xml	(original)
+++ trunk/tests/providers/TYPES_SCHEMA_PostgreSQL.xml	Sun Jul 27 19:25:27 2008
@@ -1,275 +1,212 @@
 <?xml version="1.0"?>
 <gda_array id="EXPORT" name="Exported Data">
-  <gda_array_field id="FI0" name="Type" title="Type" gdatype="gchararray" nullok="TRUE"/>
-  <gda_array_field id="FI1" name="Owner" title="Owner" gdatype="gchararray" nullok="TRUE"/>
-  <gda_array_field id="FI2" name="Comments" title="Comments" gdatype="gchararray" nullok="TRUE"/>
-  <gda_array_field id="FI3" name="GDA type" title="GDA type" gdatype="gulong" nullok="TRUE"/>
-  <gda_array_field id="FI4" name="Synonyms" title="Synonyms" gdatype="gchararray" nullok="TRUE"/>
+  <gda_array_field id="FI0" name="short_type_name" title="short_type_name" gdatype="gchararray" size="-1" scale="-1"/>
+  <gda_array_field id="FI1" name="gtype" title="gtype" gdatype="gchararray" size="-1" scale="-1"/>
+  <gda_array_field id="FI2" name="comments" title="comments" gdatype="gchararray" size="-1" scale="-1" nullok="TRUE"/>
+  <gda_array_field id="FI3" name="synonyms" title="synonyms" gdatype="null" size="-1" scale="-1" nullok="TRUE"/>
   <gda_array_data>
     <gda_array_row>
       <gda_value>abstime</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gint</gda_value>
       <gda_value>absolute, limited-range date and time (Unix system time)</gda_value>
-      <gda_value>24</gda_value>
-      <gda_value isnull="t"/>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>aclitem</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value>access control list</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>bit</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>fixed-length bit string</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>bool</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gboolean</gda_value>
       <gda_value>boolean, 'true'/'false'</gda_value>
-      <gda_value>20</gda_value>
-      <gda_value>boolean</gda_value>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>box</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value>geometric box '(lower left,upper right)'</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>bpchar</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>char(length), blank-padded string, fixed storage length</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>bytea</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GdaBinary</gda_value>
       <gda_value>variable-length string, binary values escaped</gda_value>
-      <gda_value>164376752</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>char</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>single character</gda_value>
-      <gda_value>64</gda_value>
-      <gda_value>character</gda_value>
+      <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>cidr</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>network IP address/netmask, network address</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>circle</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>geometric circle '(center,radius)'</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>date</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GDate</gda_value>
       <gda_value>ANSI SQL date</gda_value>
-      <gda_value>164376624</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>float4</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gfloat</gda_value>
       <gda_value>single-precision floating point number, 4-byte storage</gda_value>
-      <gda_value>56</gda_value>
-      <gda_value>real</gda_value>
+      <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>float8</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gdouble</gda_value>
       <gda_value>double-precision floating point number, 8-byte storage</gda_value>
-      <gda_value>60</gda_value>
-      <gda_value>double precision</gda_value>
+      <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>inet</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>IP address/netmask, host address, netmask optional</gda_value>
-      <gda_value>64</gda_value>
+      <gda_value isnull="t"/>
+    </gda_array_row>
+    <gda_array_row>
+      <gda_value>information_schema.cardinal_number</gda_value>
+      <gda_value>gchararray</gda_value>
+      <gda_value isnull="t"/>
+      <gda_value isnull="t"/>
+    </gda_array_row>
+    <gda_array_row>
+      <gda_value>information_schema.character_data</gda_value>
+      <gda_value>gchararray</gda_value>
+      <gda_value isnull="t"/>
+      <gda_value isnull="t"/>
+    </gda_array_row>
+    <gda_array_row>
+      <gda_value>information_schema.sql_identifier</gda_value>
+      <gda_value>gchararray</gda_value>
+      <gda_value isnull="t"/>
+      <gda_value isnull="t"/>
+    </gda_array_row>
+    <gda_array_row>
+      <gda_value>information_schema.time_stamp</gda_value>
+      <gda_value>gchararray</gda_value>
+      <gda_value isnull="t"/>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>int2</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GdaShort</gda_value>
       <gda_value>-32 thousand to 32 thousand, 2-byte storage</gda_value>
-      <gda_value>164374840</gda_value>
-      <gda_value>smallint</gda_value>
+      <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>int4</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gint</gda_value>
       <gda_value>-2 billion to 2 billion integer, 4-byte storage</gda_value>
-      <gda_value>24</gda_value>
-      <gda_value>int,integer</gda_value>
+      <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>int8</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gint64</gda_value>
       <gda_value>~18 digit integer, 8-byte storage</gda_value>
-      <gda_value>40</gda_value>
-      <gda_value>bigint</gda_value>
+      <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>interval</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>@ &lt;number&gt; &lt;units&gt;, time interval</gda_value>
-      <gda_value>64</gda_value>
-      <gda_value isnull="t"/>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>line</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value>geometric line (not implemented)'</gda_value>
-      <gda_value>64</gda_value>
-      <gda_value isnull="t"/>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>lseg</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value>geometric line segment '(pt1,pt2)'</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>macaddr</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>XX:XX:XX:XX:XX:XX, MAC address</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>money</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>monetary amounts, $d,ddd.cc</gda_value>
-      <gda_value>64</gda_value>
-      <gda_value isnull="t"/>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>name</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value>63-character type for storing system identifiers</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>numeric</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GdaNumeric</gda_value>
       <gda_value>numeric(precision, decimal), arbitrary precision number</gda_value>
-      <gda_value>164374928</gda_value>
-      <gda_value>decimal</gda_value>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>oid</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value>object identifier(oid), maximum 4 billion</gda_value>
-      <gda_value>164372672</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>path</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>geometric path '(pt1,...)'</gda_value>
-      <gda_value>64</gda_value>
-      <gda_value isnull="t"/>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>point</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value>geometric point '(x, y)'</gda_value>
-      <gda_value>164376896</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>polygon</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>geometric polygon '(pt1,...)'</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>reltime</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>relative, limited-range time interval (Unix delta time)</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>text</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>variable-length string, no limit specified</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>time</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GdaTime</gda_value>
       <gda_value>hh:mm:ss, ANSI SQL time</gda_value>
-      <gda_value>164374496</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>timestamp</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GdaTimestamp</gda_value>
       <gda_value>date and time</gda_value>
-      <gda_value>164379336</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>timestamptz</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GdaTimestamp</gda_value>
       <gda_value>date and time with time zone</gda_value>
-      <gda_value>164379336</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>timetz</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>GdaTime</gda_value>
       <gda_value>hh:mm:ss, ANSI SQL time</gda_value>
-      <gda_value>164374496</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>tinterval</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>(abstime,abstime), time interval</gda_value>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>varbit</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>variable-length bit string</gda_value>
-      <gda_value>64</gda_value>
-      <gda_value>bit varying</gda_value>
+      <gda_value isnull="t"/>
     </gda_array_row>
     <gda_array_row>
       <gda_value>varchar</gda_value>
-      <gda_value>postgres</gda_value>
+      <gda_value>gchararray</gda_value>
       <gda_value>varchar(length), non-blank-padded string, variable storage length</gda_value>
-      <gda_value>64</gda_value>
-      <gda_value>character varying</gda_value>
-    </gda_array_row>
-    <gda_array_row>
-      <gda_value>year</gda_value>
-      <gda_value>postgres</gda_value>
-      <gda_value/>
-      <gda_value>64</gda_value>
       <gda_value isnull="t"/>
     </gda_array_row>
   </gda_array_data>

Modified: trunk/tests/providers/check_mysql.c
==============================================================================
--- trunk/tests/providers/check_mysql.c	(original)
+++ trunk/tests/providers/check_mysql.c	Sun Jul 27 19:25:27 2008
@@ -27,7 +27,6 @@
 	number_failed = prov_test_common_setup ();
 
 	if (cnc) {
-		number_failed += prov_test_common_create_tables_sql ();
 		number_failed += prov_test_common_check_meta ();
 		number_failed += prov_test_common_clean ();
 	}

Modified: trunk/tests/providers/check_oracle.c
==============================================================================
--- trunk/tests/providers/check_oracle.c	(original)
+++ trunk/tests/providers/check_oracle.c	Sun Jul 27 19:25:27 2008
@@ -27,7 +27,6 @@
 	number_failed = prov_test_common_setup ();
 
 	if (cnc) {
-		number_failed += prov_test_common_create_tables_sql ();
 		number_failed += prov_test_common_check_meta ();
 		number_failed += prov_test_common_clean ();
 	}

Modified: trunk/tests/providers/check_postgres.c
==============================================================================
--- trunk/tests/providers/check_postgres.c	(original)
+++ trunk/tests/providers/check_postgres.c	Sun Jul 27 19:25:27 2008
@@ -29,7 +29,6 @@
 	number_failed = prov_test_common_setup ();
 
 	if (cnc) {
-		number_failed += prov_test_common_create_tables_sql ();
 		number_failed += prov_test_common_check_meta ();
 		number_failed += prov_test_common_load_data ();
 		number_failed += prov_test_common_check_cursor_models ();

Modified: trunk/tests/providers/check_sqlite.c
==============================================================================
--- trunk/tests/providers/check_sqlite.c	(original)
+++ trunk/tests/providers/check_sqlite.c	Sun Jul 27 19:25:27 2008
@@ -29,7 +29,6 @@
 	number_failed = prov_test_common_setup ();
 
 	if (cnc) {
-		number_failed += prov_test_common_create_tables_sql ();
 		number_failed += prov_test_common_check_meta ();
 		number_failed += prov_test_common_load_data ();
 		number_failed += prov_test_common_check_cursor_models ();

Modified: trunk/tests/providers/gda_check_db.mdb
==============================================================================
Binary files. No diff available.

Modified: trunk/tests/providers/prov-test-common.c
==============================================================================
--- trunk/tests/providers/prov-test-common.c	(original)
+++ trunk/tests/providers/prov-test-common.c	Sun Jul 27 19:25:27 2008
@@ -3,6 +3,7 @@
 #include "prov-test-common.h"
 #include "prov-test-util.h"
 #include <sql-parser/gda-sql-statement.h>
+#include "../test-cnc-utils.h"
 
 #define CHECK_EXTRA_INFO
 /*#undef CHECK_EXTRA_INFO*/
@@ -10,7 +11,6 @@
 GdaProviderInfo *pinfo;
 GdaConnection   *cnc;
 gboolean         params_provided;
-gboolean         db_created;
 gboolean         fork_tests = TRUE;
 
 /*
@@ -23,9 +23,36 @@
 prov_test_common_setup ()
 {
 	int number_failed = 0;
-	cnc = prov_test_setup_connection (pinfo, &params_provided, &db_created);
-	if (params_provided)
-		fail_if (!cnc, "Could not setup connection");
+	GError *error = NULL;
+	cnc = test_cnc_setup_connection (pinfo->id, "testcheckdb", &error);
+	if (!cnc) {
+		if (error) {
+			if (error->domain != 0) {
+				gchar *str = g_strdup_printf ("Could not setup connection: %s", 
+							      error->message ? error->message : "No detail");
+				fail (str);
+				g_free (str);
+				number_failed++;
+			}
+			else
+				g_print ("==> %s\n", error->message ? error->message : "No detail");
+			g_error_free (error);
+		}
+	}
+	else {
+		gchar *file;
+		file = g_build_filename (CHECK_SQL_FILES, "tests", "providers", "prov_dbstruct.xml", NULL);
+		if (!test_cnc_setup_db_structure (cnc, file, &error)) {
+			gchar *str = g_strdup_printf ("Could not setup database structure: %s", 
+						      error && error->message ? error->message : "No detail");
+			fail (str);
+			g_free (str);
+			if (error)
+				g_error_free (error);
+			number_failed++;
+		}
+		g_free (file);
+	}
 	return number_failed;
 }
 
@@ -40,22 +67,7 @@
 {
 	int number_failed = 0;
 
-	if (!prov_test_clean_connection (cnc, db_created))
-		number_failed++;
-
-	return number_failed;	
-}
-
-/*
- *
- * CREATE_TABLES_SQL
- *
- */
-int
-prov_test_common_create_tables_sql ()
-{
-	int number_failed = 0;
-	if (!prov_test_create_tables_sql (cnc))
+	if (!test_cnc_clean_connection (cnc, NULL))
 		number_failed++;
 
 	return number_failed;	
@@ -171,6 +183,7 @@
 		if (strcmp (tmp, dump1[i])) {
 #ifdef CHECK_EXTRA_INFO
 			g_warning ("Meta data has changed after update for table %s\n", (gchar*) list->data);
+			g_print ("===\n%s\n===\n%s\n===\n", tmp, dump1[i]);
 #endif
 			number_failed++;
 			g_free (tmp);

Modified: trunk/tests/providers/prov-test-common.h
==============================================================================
--- trunk/tests/providers/prov-test-common.h	(original)
+++ trunk/tests/providers/prov-test-common.h	Sun Jul 27 19:25:27 2008
@@ -11,7 +11,6 @@
 #define fail_unless(x,y) if (!(x)) g_warning (y)
 
 int prov_test_common_setup ();
-int prov_test_common_create_tables_sql ();
 int prov_test_common_load_data ();
 int prov_test_common_check_meta ();
 int prov_test_common_check_cursor_models ();

Modified: trunk/tests/providers/prov-test-util.c
==============================================================================
--- trunk/tests/providers/prov-test-util.c	(original)
+++ trunk/tests/providers/prov-test-util.c	Sun Jul 27 19:25:27 2008
@@ -10,7 +10,7 @@
 /*#undef CHECK_EXTRA_INFO*/
 
 #define DB_NAME "gda_check_db"
-#define CREATE_FILES 1
+#define CREATE_FILES 0
 GdaSqlParser *parser = NULL;
 
 /*
@@ -103,307 +103,6 @@
 }
 
 /*
- *
- * Connection SETUP
- *
- */
-typedef struct {
-	gchar        *db_name;
-	GdaQuarkList *ql;
-	GString      *string;
-} Data1;
-
-static void 
-db_create_quark_foreach_func (gchar *name, gchar *value, GdaServerOperation *op)
-{
-	gda_server_operation_set_value_at (op, value, NULL, "/SERVER_CNX_P/%s", name);
-}
-
-static void 
-cnc_quark_foreach_func (gchar *name, gchar *value, Data1 *data)
-{
-	if (data->db_name && !strcmp (name, "DB_NAME"))
-		return;
-
-	if (data->ql) {
-		if (!gda_quark_list_find (data->ql, name)) {
-			if (*(data->string->str) != 0)
-				g_string_append_c (data->string, ';');
-			g_string_append_printf (data->string, "%s=%s", name, value);
-		}
-	}
-	else {
-		if (*(data->string->str) != 0)
-			g_string_append_c (data->string, ';');
-		g_string_append_printf (data->string, "%s=%s", name, value);
-	}
-}
-
-static gchar *
-prov_name_upcase (const gchar *prov_name)
-{
-	gchar *str, *ptr;
-
-	str = g_ascii_strup (prov_name, -1);
-	for (ptr = str; *ptr; ptr++) {
-		if (! g_ascii_isalnum (*ptr))
-			*ptr = '_';
-	}
-
-	return str;
-}
-
-GdaConnection *
-prov_test_setup_connection (GdaProviderInfo *prov_info, gboolean *params_provided, gboolean *db_created)
-{
-	GdaConnection *cnc = NULL;
-	gchar *str, *upname;
-	const gchar *db_params, *cnc_params;
-	GError *error = NULL;
-	gchar *db_name = NULL;
-
-	GdaQuarkList *db_quark_list = NULL, *cnc_quark_list = NULL;
-
-	g_assert (prov_info);
-
-	upname = prov_name_upcase (prov_info->id);
-	str = g_strdup_printf ("%s_DBCREATE_PARAMS", upname);
-	db_params = getenv (str);
-	g_free (str);
-	if (db_params) {
-		GdaServerOperation *op;
-
-		db_name = DB_NAME;
-		db_quark_list = gda_quark_list_new_from_string (db_params);
-		op = gda_prepare_drop_database (prov_info->id, db_name, NULL);
-		gda_quark_list_foreach (db_quark_list, (GHFunc) db_create_quark_foreach_func, op);
-		gda_perform_create_database (op, NULL);
-		g_object_unref (op);
-
-		op = gda_prepare_create_database (prov_info->id, db_name, NULL);
-		gda_quark_list_foreach (db_quark_list, (GHFunc) db_create_quark_foreach_func, op);
-		if (!gda_perform_create_database (op, &error)) {
-#ifdef CHECK_EXTRA_INFO
-			g_warning ("Could not create the '%s' database (provider %s): %s", db_name,
-				   prov_info->id, error && error->message ? error->message : "No detail");
-#endif
-			g_error_free (error);
-			error = NULL;
-			goto out;
-		}
-	}
-
-	str = g_strdup_printf ("%s_CNC_PARAMS", upname);
-	cnc_params = getenv (str);
-	g_free (str);
-	if (cnc_params) 
-		cnc_quark_list = gda_quark_list_new_from_string (cnc_params);
-	
-	if (db_quark_list || cnc_quark_list) {
-		Data1 data;
-
-		data.string = g_string_new ("");
-		data.db_name = db_name;
-		data.ql = NULL;
-
-		if (db_quark_list) 
-			gda_quark_list_foreach (db_quark_list, (GHFunc) cnc_quark_foreach_func, &data);
-		data.ql = db_quark_list;
-		if (cnc_quark_list)
-			gda_quark_list_foreach (cnc_quark_list, (GHFunc) cnc_quark_foreach_func, &data);
-		if (db_name) {
-			if (*(data.string->str) != 0)
-				g_string_append_c (data.string, ';');
-			g_string_append_printf (data.string, "DB_NAME=%s", db_name);
-		}
-		g_print ("Open connection string: %s\n", data.string->str);
-
-		/***/
-		gchar *auth_string = NULL;
-
-		GSList *current = prov_info->auth_params->holders;
-		while (current) {
-			GdaHolder *holder = (GdaHolder *) current->data;
-
-			const gchar *id = gda_holder_get_id (holder);
-			const gchar *env = NULL;
-			if (g_strrstr (id, "USER") != NULL) {
-				str = g_strdup_printf ("%s_USER", upname);
-				env = getenv (str);
-				g_free (str);
-			} else if (g_strrstr (id, "PASS") != NULL) {
-				str = g_strdup_printf ("%s_PASS", upname);
-				env = getenv (str);
-				g_free (str);
-			}
-
-			if (env) {
-				str = g_strdup_printf ("%s=%s;", id, env);
-
-				gchar *tmp = auth_string;
-				auth_string = g_strconcat (auth_string, str, NULL);
-				g_free (str);
-				g_free (tmp);
-			}
-
-			current = g_slist_next (current);
-		}
-
-		cnc = gda_connection_open_from_string (prov_info->id, data.string->str, auth_string,
- 						       GDA_CONNECTION_OPTIONS_NONE, &error);
-		g_free (auth_string);
-		if (!cnc && error) {
-#ifdef CHECK_EXTRA_INFO
-			g_warning ("Could not open connection to %s (provider %s): %s",
-				   cnc_params, prov_info->id, error->message ? error->message : "No detail");
-#endif
-			g_error_free (error);
-			error = NULL;
-		}
-		g_string_free (data.string, TRUE);
-	}
-
-	if (db_quark_list)
-		gda_quark_list_free (db_quark_list);
-	if (cnc_quark_list)
-		gda_quark_list_free (cnc_quark_list);
-
- out:
-	*db_created = db_name ? TRUE : FALSE;
-
-	if (db_params || cnc_params)
-		*params_provided = TRUE;
-	else {
-		g_print ("Connection parameters not specified, test not executed (define %s_CNC_PARAMS or %s_DBCREATE_PARAMS to create a test DB)\n", upname, upname);
-		*params_provided = FALSE;
-	}
-	g_free (upname);
-
-	return cnc;
-}
-
-
-/*
- *
- * Connection CLEAN
- *
- */
-static void 
-db_drop_quark_foreach_func (gchar *name, gchar *value, GdaServerOperation *op)
-{
-	gda_server_operation_set_value_at (op, value, NULL, "/SERVER_CNX_P/%s", name);
-	gda_server_operation_set_value_at (op, value, NULL, "/DB_DESC_P/%s", name);
-}
-
-gboolean
-prov_test_clean_connection (GdaConnection *cnc, gboolean destroy_db)
-{
-	gchar *prov_id;
-	gboolean retval = TRUE;
-	gchar *str, *upname;
-
-	prov_id = g_strdup (gda_connection_get_provider_name (cnc));
-	gda_connection_close (cnc);
-	g_object_unref (cnc);
-
-	upname = prov_name_upcase (prov_id);
-	str = g_strdup_printf ("%s_DONT_REMOVE_DB", upname);
-	if (getenv (str))
-		destroy_db = FALSE;
-	g_free (str);
-
-	if (destroy_db) {
-		GdaServerOperation *op;
-		GError *error = NULL;
-		
-		const gchar *db_params;
-		GdaQuarkList *db_quark_list = NULL;
-
-#ifdef CHECK_EXTRA_INFO
-		g_print ("Waiting a bit for the server to register the disconnection...\n");
-#endif
-		sleep (1);
-		str = g_strdup_printf ("%s_DBCREATE_PARAMS", upname);
-		db_params = getenv (str);
-		g_free (str);
-		g_assert (db_params);
-
-		op = gda_prepare_drop_database (prov_id, DB_NAME, NULL);
-		db_quark_list = gda_quark_list_new_from_string (db_params);
-		gda_quark_list_foreach (db_quark_list, (GHFunc) db_drop_quark_foreach_func, op);
-		gda_quark_list_free (db_quark_list);
-
-		if (!gda_perform_drop_database (op, &error)) {
-#ifdef CHECK_EXTRA_INFO
-			g_warning ("Could not drop the '%s' database (provider %s): %s", DB_NAME,
-				   prov_id, error && error->message ? error->message : "No detail");
-#endif
-			g_error_free (error);
-			error = NULL;
-			retval = FALSE;
-		}
-	}
-	g_free (upname);
-
-	g_free (prov_id);
-
-	return retval;
-}
-
-/*
- *
- * Create tables SQL
- *
- */
-gboolean
-prov_test_create_tables_sql (GdaConnection *cnc)
-{
-	const gchar *prov_id;
-	gchar *tmp, *filename;
-	gboolean retval = TRUE;
-	GError *error = NULL;
-	const GSList *list;
-
-	prov_id = gda_connection_get_provider_name (cnc);
-
-	tmp = g_strdup_printf ("%s_create_tables.sql", prov_id);
-	filename = g_build_filename (CHECK_SQL_FILES, "tests", "providers", tmp, NULL);
-	g_free (tmp);
-
-	if (!parser) 
-		parser = gda_sql_parser_new ();
-
-	GdaBatch *batch;
-	batch = gda_sql_parser_parse_file_as_batch (parser, filename, &error);
-	if (!batch) {
-#ifdef CHECK_EXTRA_INFO
-                g_warning ("Could not parser file '%s': %s", filename,
-			   error && error->message ? error->message : "No detail");
-#endif
-		g_error_free (error);
-		error = NULL;
-		g_free (filename);
-		return FALSE;
-	}
-
-	for (list = gda_batch_get_statements (batch); list; list = list->next) {
-		if (gda_connection_statement_execute_non_select (cnc, GDA_STATEMENT (list->data),
-								 NULL, NULL, &error) == -1) {
-#ifdef CHECK_EXTRA_INFO
-			g_warning ("Could execute statement: %s",
-				   error && error->message ? error->message : "No detail");
-			g_error_free (error);
-#endif
-			retval = FALSE;
-			break;
-		}
-	}
-
-	g_object_unref (batch);
-	return retval;
-}
-
-/*
  * 
  * Check data types' schema
  *
@@ -617,6 +316,15 @@
 		return FALSE;
 	}
 
+	{
+		gchar *csv;
+		csv = gda_data_model_export_to_string (imodel, GDA_DATA_MODEL_IO_TEXT_SEPARATED,
+						       NULL, 0, NULL, 0, NULL);
+		tmp = g_strdup_printf ("CSV_DATA_%s.csv", table);
+		g_file_set_contents (tmp, csv, -1, NULL);
+		g_free (tmp);
+	}
+
 	/* create INSERT GdaStatement */
 	GdaStatement *insert;
 	GdaSqlStatement *sqlst;
@@ -662,6 +370,8 @@
 	g_object_set (G_OBJECT (insert), "structure", sqlst, NULL);
 	gda_sql_statement_free (sqlst);
 
+	/*g_print ("SQL: %s\n", gda_statement_to_sql (insert, NULL, NULL));*/
+
 	/* execute the INSERT statement */
 	GdaSet *set;
 	if (! gda_statement_get_parameters (insert, &set, &error)) {

Modified: trunk/tests/providers/prov-test-util.h
==============================================================================
--- trunk/tests/providers/prov-test-util.h	(original)
+++ trunk/tests/providers/prov-test-util.h	Sun Jul 27 19:25:27 2008
@@ -5,19 +5,7 @@
 #include <glib.h>
 #include <libgda/libgda.h>
 
-/*
- * Uses env variables to
- *    - create a DB if env. variable <upper_case_provider_name>_DBCREATE_PARAMS exists
- *    - open a connection if env. variable <upper_case_provider_name>_CNC_PARAMS exists
- *
- * If for the @prov_info, those env. variables don't exist, then @params_provided is set to FALSE
- */
-GdaConnection *prov_test_setup_connection (GdaProviderInfo *prov_info, gboolean *params_provided, gboolean *db_created);
-gboolean       prov_test_clean_connection (GdaConnection *cnc, gboolean destroy_db);
-gboolean       prov_test_create_tables_sql (GdaConnection *cnc);
-
 gboolean       prov_test_check_types_schema (GdaConnection *cnc);
-
 gboolean       prov_test_load_data (GdaConnection *cnc, const gchar *table);
 gboolean       prov_test_check_table_cursor_model (GdaConnection *cnc, const gchar *table);
 

Added: trunk/tests/providers/prov_dbstruct.xml
==============================================================================
--- (empty file)
+++ trunk/tests/providers/prov_dbstruct.xml	Sun Jul 27 19:25:27 2008
@@ -0,0 +1,120 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+   Tests databases schema
+-->
+
+
+<schema>
+  <!-- provider specific information 
+       use <replace> to replace something with something else (context can only be "/FIELDS_A/@COLUMN_TYPE" at the moment)
+       use <ignore> to ignore some parts (context can only be "/FKEY_S" or "/FIELDS_A/@COLUMN_PKEY" at the moment)
+       use <symbol> to define a symbolic value
+    -->
+  <specifics>
+    <provider name="PostgreSQL">
+      <replace context="/FIELDS_A/@COLUMN_TYPE" expr="string" replace_with="varchar"/>
+      <replace context="/FIELDS_A/@COLUMN_TYPE" expr="gint" replace_with="int"/>
+      <symbol name="now">now()</symbol>
+    </provider>
+
+    <provider name="MySQL">
+      <replace context="/FIELDS_A/@COLUMN_TYPE" expr="string" replace_with="text"/>
+      <replace context="/FIELDS_A/@COLUMN_TYPE" expr="gint" replace_with="int"/>
+      <ignore context="/FKEY_S"/>
+      <ignore context="/FIELDS_A/@COLUMN_PKEY"/>
+      <symbol name="now">CURRENT_TIMESTAMP</symbol>
+    </provider>
+
+    <provider name="SQLite">
+      <replace context="/FIELDS_A/@COLUMN_TYPE" expr="gint" replace_with="int"/>
+      <symbol name="now">CURRENT_TIMESTAMP</symbol>
+    </provider>
+  </specifics>
+
+  <!-- actor table -->
+  <table name="actor"> <!-- possibly also schema attribute -->
+    <column name="actor_id" type="gint" pkey="TRUE" autoinc="TRUE"/>
+    <column name="first_name"/>
+    <column name="last_name"/>
+    <column name="last_update" type="timestamp">
+      <extra context="COLUMN_DEFAULT" symbol="now"></extra>
+    </column>
+  </table>
+
+  <!-- film table -->
+  <table name="film">
+    <column name="film_id" type="gint" pkey="TRUE" autoinc="TRUE"/>
+    <column name="title"/>
+    <column name="description"/>
+    <column name="release_year" type="gint"/>
+    <column name="language_id" type="gint"/>
+    <column name="original_language_id" type="gint" nullok="TRUE"/>
+    <column name="rental_duration" type="smallint">
+      <extra context="COLUMN_DEFAULT">3</extra>
+    </column>
+    <column name="rental_rate" type="numeric(4,2)">
+      <extra context="COLUMN_DEFAULT">4.99</extra>
+    </column>
+    <column name="length" type="smallint"/>
+    <column name="replacement_cost" type="numeric(5,2)">
+      <extra context="COLUMN_DEFAULT">19.99</extra>
+    </column>
+    <column name="rating" nullok="TRUE">
+      <extra context="COLUMN_DEFAULT">G</extra>
+    </column>
+    <column name="last_update" type="timestamp">
+      <extra context="COLUMN_DEFAULT" symbol="now"></extra>
+    </column>
+    <column name="special_features" type="string"/>
+
+    <check>((((rating = 'G') OR (rating = 'PG')) OR (rating = 'PG-13')) OR (rating = 'R')) OR (rating = 'NC-17')</check>
+
+    <fkey ref_table="language">
+      <part column="language_id" ref_column="language_id"/>
+    </fkey>
+
+    <fkey ref_table="language">
+      <part column="original_language_id" ref_column="language_id"/>
+    </fkey>
+  </table>
+
+  <!-- film_actor table -->
+  <table name="film_actor">
+    <column name="actor_id" type="gint"/>
+    <column name="film_id" type="gint"/>
+    <column name="last_update" type="timestamp">
+      <default symbolic="now"/>
+    </column>
+
+    <fkey ref_table="actor">
+      <part column="actor_id" ref_column="actor_id"/>
+    </fkey>
+
+    <fkey ref_table="film">
+      <part column="film_id" ref_column="film_id"/>
+    </fkey>
+  </table>
+
+  <!-- language table -->
+  <table name="language">
+    <column name="language_id" type="gint" pkey="TRUE" autoinc="TRUE"/>
+    <column name="name"/>
+    <column name="last_update" type="timestamp">
+      <extra context="COLUMN_DEFAULT" symbol="now"></extra>
+    </column>
+  </table>
+
+  <!-- dummy table -->
+  <table name="dummy">
+    <column name="name"/>
+    <unique>
+      <column name="name"/>
+    </unique>
+  </table>
+
+  <!-- films_ordered view -->
+  <view name="films_ordered" descr="Ordered list of films">
+    <definition>SELECT * FROM films ORDER BY last_update</definition>
+  </view>
+
+</schema>

Added: trunk/tests/test-cnc-utils.c
==============================================================================
--- (empty file)
+++ trunk/tests/test-cnc-utils.c	Sun Jul 27 19:25:27 2008
@@ -0,0 +1,323 @@
+#include <stdlib.h>
+#include <string.h>
+#include "test-cnc-utils.h"
+#include "gda-ddl-creator.h"
+#include <libgda/gda-server-provider-extra.h>
+#include <libgda/sql-parser/gda-sql-parser.h>
+#include <libgda/sql-parser/gda-sql-statement.h>
+#include <unistd.h>
+
+#define CHECK_EXTRA_INFO
+/*#undef CHECK_EXTRA_INFO*/
+
+#define CREATE_FILES 1
+
+/*
+ *
+ * Connection SETUP
+ *
+ */
+typedef struct {
+	GdaQuarkList *ql;
+	GString      *string;
+	gchar        *requested_db_name;
+} Data1;
+
+static void 
+db_create_quark_foreach_func (gchar *name, gchar *value, GdaServerOperation *op)
+{
+	gda_server_operation_set_value_at (op, value, NULL, "/SERVER_CNX_P/%s", name);
+}
+
+static void 
+cnc_quark_foreach_func (gchar *name, gchar *value, Data1 *data)
+{
+	if (!strcmp (name, "DB_NAME")) {
+		data->requested_db_name = g_strdup (value);
+		return;
+	}
+
+	if (data->ql) {
+		if (!gda_quark_list_find (data->ql, name)) {
+			if (*(data->string->str) != 0)
+				g_string_append_c (data->string, ';');
+			g_string_append_printf (data->string, "%s=%s", name, value);
+		}
+	}
+	else {
+		if (*(data->string->str) != 0)
+			g_string_append_c (data->string, ';');
+		g_string_append_printf (data->string, "%s=%s", name, value);
+	}
+}
+
+static gchar *
+prov_name_upcase (const gchar *prov_name)
+{
+	gchar *str, *ptr;
+
+	str = g_ascii_strup (prov_name, -1);
+	for (ptr = str; *ptr; ptr++) {
+		if (! g_ascii_isalnum (*ptr))
+			*ptr = '_';
+	}
+
+	return str;
+}
+
+/*
+ * Set up a connection.
+ *
+ * Optionnally the database can be created if the <upper_case_provider_name>_DBCREATE_PARAMS 
+ * environment variable exists. Examples are:
+ *     MYSQL_DBCREATE_PARAMS "HOST=localhost"
+ *     POSTGRESQL_DBCREATE_PARAMS "HOST=localhost;PORT=5432"
+ *     SQLITE_DBCREATE_PARAMS "DB_DIR=."
+ *     BERKELEY_DB_CNC_PARAMS "DB_NAME=gda_check_bdb.db"
+ *
+ * The connection is opened if the <upper_case_provider_name>_CNC_PARAMS environment variable exists.
+ * For example:
+ *     MSACCESS_CNC_PARAMS "DB_DIR=/home/me/libgda/tests/providers;DB_NAME=gda_check_db"
+ *     ORACLE_CNC_PARAMS TNSNAME=//127.0.0.1
+ *
+ *
+ * If the <upper_case_provider_name>_DBCREATE_PARAMS is supplied, then its contents can be used
+ * to complement the <upper_case_provider_name>_CNC_PARAMS.
+ *
+ * Returns: a GdaConnection if no error occurred
+ */
+GdaConnection *
+test_cnc_setup_connection (const gchar *provider, const gchar *dbname, GError **error)
+{
+	GdaConnection *cnc = NULL;
+	gchar *str, *upname;
+	const gchar *db_params, *cnc_params;
+	GdaProviderInfo *prov_info;
+	GdaQuarkList *db_quark_list = NULL, *cnc_quark_list = NULL;
+	gboolean db_created = FALSE;
+
+	g_return_val_if_fail (dbname && *dbname, NULL);
+
+	prov_info = gda_config_get_provider_info (provider);
+	if (!prov_info) {
+		g_set_error (error, 0, 0,
+			     "Provider '%s' not found", provider);
+		return NULL;
+	}
+
+	/* create database if requested */
+	upname = prov_name_upcase (prov_info->id);
+	str = g_strdup_printf ("%s_DBCREATE_PARAMS", upname);
+	db_params = getenv (str);
+	g_free (str);
+	if (db_params) {
+		GdaServerOperation *op;
+
+		db_quark_list = gda_quark_list_new_from_string (db_params);
+		op = gda_prepare_drop_database (prov_info->id, dbname, NULL);
+		gda_quark_list_foreach (db_quark_list, (GHFunc) db_create_quark_foreach_func, op);
+		gda_perform_create_database (op, NULL);
+		g_object_unref (op);
+
+		op = gda_prepare_create_database (prov_info->id, dbname, NULL);
+		gda_quark_list_foreach (db_quark_list, (GHFunc) db_create_quark_foreach_func, op);
+		if (!gda_perform_create_database (op, error)) 
+			goto out;
+		db_created = TRUE;
+	}
+
+	/* open connection to database */
+	str = g_strdup_printf ("%s_CNC_PARAMS", upname);
+	cnc_params = getenv (str);
+	g_free (str);
+	if (cnc_params) 
+		cnc_quark_list = gda_quark_list_new_from_string (cnc_params);
+	
+	if (db_quark_list || cnc_quark_list) {
+		Data1 data;
+
+		data.string = g_string_new ("");
+		data.ql = NULL;
+		data.requested_db_name = NULL;
+
+		if (db_quark_list) 
+			gda_quark_list_foreach (db_quark_list, (GHFunc) cnc_quark_foreach_func, &data);
+		data.ql = db_quark_list;
+		if (cnc_quark_list)
+			gda_quark_list_foreach (cnc_quark_list, (GHFunc) cnc_quark_foreach_func, &data);
+
+		if (*(data.string->str) != 0)
+			g_string_append_c (data.string, ';');
+		g_string_append_printf (data.string, "DB_NAME=%s", 
+					data.requested_db_name ? data.requested_db_name : dbname);
+		g_print ("Open connection string: %s\n", data.string->str);
+
+		gchar *auth_string = NULL;
+		GSList *current = prov_info->auth_params->holders;
+		while (current) {
+			GdaHolder *holder = (GdaHolder *) current->data;
+
+			const gchar *id = gda_holder_get_id (holder);
+			const gchar *env = NULL;
+			if (g_strrstr (id, "USER") != NULL) {
+				str = g_strdup_printf ("%s_USER", upname);
+				env = getenv (str);
+				g_free (str);
+			} else if (g_strrstr (id, "PASS") != NULL) {
+				str = g_strdup_printf ("%s_PASS", upname);
+				env = getenv (str);
+				g_free (str);
+			}
+
+			if (env) {
+				str = g_strdup_printf ("%s=%s;", id, env);
+
+				gchar *tmp = auth_string;
+				auth_string = g_strconcat (auth_string, str, NULL);
+				g_free (str);
+				g_free (tmp);
+			}
+
+			current = g_slist_next (current);
+		}
+
+		cnc = gda_connection_open_from_string (prov_info->id, data.string->str, auth_string,
+ 						       GDA_CONNECTION_OPTIONS_NONE, error);
+		g_free (auth_string);
+		g_string_free (data.string, TRUE);
+	}
+
+	if (db_quark_list)
+		gda_quark_list_free (db_quark_list);
+	if (cnc_quark_list)
+		gda_quark_list_free (cnc_quark_list);
+
+ out:
+	if (!db_params && !cnc_params) 
+		g_set_error (error, 0, 0,
+			     "Connection parameters not specified, test not executed (define %s_CNC_PARAMS or %s_DBCREATE_PARAMS to create a test DB)\n", upname, upname);
+	g_free (upname);
+
+	if (cnc) {
+		g_object_set_data_full (G_OBJECT (cnc), "dbname", g_strdup (dbname), g_free);
+		g_object_set_data (G_OBJECT (cnc), "db_created", GINT_TO_POINTER (db_created));
+		g_print ("Connection now set up (%s)\n", db_created ? "database created" : "reusing database");
+	}
+
+	return cnc;
+}
+
+/*
+ * Creates the structure of the database pointed by @cnc, as specified in @schema_file
+ *
+ */
+gboolean
+test_cnc_setup_db_structure (GdaConnection *cnc, const gchar *schema_file, GError **error)
+{
+	GdaDDLCreator *ddl;
+	g_return_val_if_fail (GDA_IS_CONNECTION (cnc), FALSE);
+	
+	ddl = gda_ddl_creator_new ();
+        if (!gda_ddl_creator_set_dest_from_file (ddl, schema_file, error)) {
+		g_object_unref (ddl);
+		return FALSE;
+        }
+
+	gda_ddl_creator_set_connection (ddl, cnc);
+	if (!gda_ddl_creator_execute (ddl, error)) {
+		g_object_unref (ddl);
+		return FALSE;
+        }
+
+        g_object_unref (ddl);
+	return TRUE;
+}
+
+/*
+ *
+ * Connection CLEAN
+ *
+ */
+static void 
+db_drop_quark_foreach_func (gchar *name, gchar *value, GdaServerOperation *op)
+{
+	gda_server_operation_set_value_at (op, value, NULL, "/SERVER_CNX_P/%s", name);
+	gda_server_operation_set_value_at (op, value, NULL, "/DB_DESC_P/%s", name);
+}
+
+/*
+ * Cleans up a connection.
+ *
+ * If @destroy_db is TRUE, then the database is destroyed, except if <upper_case_provider_name>_DONT_REMOVE_DB
+ * is set.
+ *
+ * WARNING: the @cnc connection destroyed closed by this function
+ */
+gboolean
+test_cnc_clean_connection (GdaConnection *cnc, GError **error)
+{
+	gchar *prov_id;
+	gboolean retval = TRUE;
+	gchar *str, *upname;
+	gboolean destroy_db;
+
+	prov_id = g_strdup (gda_connection_get_provider_name (cnc));
+
+	upname = prov_name_upcase (prov_id);
+	str = g_strdup_printf ("%s_DONT_REMOVE_DB", upname);
+	if (getenv (str))
+		destroy_db = FALSE;
+	else
+		destroy_db = GPOINTER_TO_INT (g_object_get_data (G_OBJECT (cnc), "db_created"));
+	g_free (str);
+
+	if (destroy_db) {
+		GdaServerOperation *op;
+		gchar *dbname;
+		
+		const gchar *db_params;
+		GdaQuarkList *db_quark_list = NULL;
+
+		dbname = (gchar *) g_object_get_data (G_OBJECT (cnc), "dbname");
+		g_assert (dbname);
+		dbname = g_strdup (dbname);
+		
+		gda_connection_close (cnc);
+		g_object_unref (cnc);
+
+#ifdef CHECK_EXTRA_INFO
+		g_print ("Waiting a bit for the server to register the disconnection...\n");
+#endif
+		sleep (1);
+		str = g_strdup_printf ("%s_DBCREATE_PARAMS", upname);
+		db_params = getenv (str);
+		g_free (str);
+		g_assert (db_params);
+
+		op = gda_prepare_drop_database (prov_id, dbname, NULL);
+		g_free (dbname);
+		db_quark_list = gda_quark_list_new_from_string (db_params);
+		gda_quark_list_foreach (db_quark_list, (GHFunc) db_drop_quark_foreach_func, op);
+		gda_quark_list_free (db_quark_list);
+
+		if (!gda_perform_drop_database (op, error)) 
+			retval = FALSE;
+		g_object_unref (op);
+	}
+	else {
+		TO_IMPLEMENT;
+		gda_connection_close (cnc);
+		g_object_unref (cnc);
+	}
+	g_free (upname);
+	g_free (prov_id);
+
+	return retval;
+}
+
+gboolean
+test_cnc_setup_db_contents (GdaConnection *cnc, const gchar *data_file, GError **error)
+{
+	TO_IMPLEMENT;
+	return FALSE;
+}

Added: trunk/tests/test-cnc-utils.h
==============================================================================
--- (empty file)
+++ trunk/tests/test-cnc-utils.h	Sun Jul 27 19:25:27 2008
@@ -0,0 +1,13 @@
+#ifndef __TEST_CNC_UTIL_H__
+#define __TEST_CNC_UTIL_H__
+
+#include <string.h>
+#include <glib.h>
+#include <libgda/libgda.h>
+
+GdaConnection *test_cnc_setup_connection (const gchar *provider, const gchar *dbname, GError **error);
+gboolean       test_cnc_setup_db_structure (GdaConnection *cnc, const gchar *schema_file, GError **error);
+gboolean       test_cnc_setup_db_contents (GdaConnection *cnc, const gchar *data_file, GError **error);
+gboolean       test_cnc_clean_connection (GdaConnection *cnc, GError **error);
+
+#endif

Modified: trunk/tests/test-ddl-creator.c
==============================================================================
--- trunk/tests/test-ddl-creator.c	(original)
+++ trunk/tests/test-ddl-creator.c	Sun Jul 27 19:25:27 2008
@@ -32,8 +32,8 @@
 
 	gda_init ();
 	
-	ddl = gda_ddl_creator_new_with_file ("dbstruct.xml", &error);
-	if (!ddl) {
+	ddl = gda_ddl_creator_new ();
+	if (!gda_ddl_creator_set_dest_from_file (ddl, "dbstruct.xml", &error)) {
 		g_print ("Error creating GdaDDLCreator: %s\n", error && error->message ? error->message : "No detail");
 		g_error_free (error);
 		return EXIT_FAILURE;
@@ -50,7 +50,7 @@
 	g_object_unref (cnc);
 
 	/* get SQL */
-	str = gda_ddl_creator_get_sql_for_create_objects (ddl, &error);
+	str = gda_ddl_creator_get_sql (ddl, &error);
 	if (!str) {
 		g_print ("Error getting SQL: %s\n", error && error->message ? error->message : "No detail");
 		g_error_free (error);
@@ -60,7 +60,7 @@
 	g_free (str);
 
 	/* execute */
-	if (!gda_ddl_creator_create_objects (ddl, &error)) {
+	if (!gda_ddl_creator_execute (ddl, &error)) {
 		g_print ("Error creating database objects: %s\n", error && error->message ? error->message : "No detail");
 		g_error_free (error);
 		return EXIT_FAILURE;

Modified: trunk/tools/gda-sql.c
==============================================================================
--- trunk/tools/gda-sql.c	(original)
+++ trunk/tools/gda-sql.c	Sun Jul 27 19:25:27 2008
@@ -60,7 +60,7 @@
 gchar *outfile = NULL;
 
 static GOptionEntry entries[] = {
-        { "no-password-ask", 'p', 0, G_OPTION_ARG_NONE, &ask_pass, "Don't ast for a password when it is empty", NULL },
+        { "no-password-ask", 'p', 0, G_OPTION_ARG_NONE, &ask_pass, "Don't ask for a password when it is empty", NULL },
 
         { "output-file", 'o', 0, G_OPTION_ARG_STRING, &outfile, "Output file", "output file"},
         { "command", 'C', 0, G_OPTION_ARG_STRING, &single_command, "Run only single command (SQL or internal) and exit", "command" },
@@ -96,6 +96,10 @@
 	gchar         *name;
 	GdaConnection *cnc;
 	GdaSqlParser  *parser;
+	GString       *query_buffer;
+
+	GdaThreader   *threader;
+	guint          meta_job_id;
 } ConnectionSetting;
 
 /* structure to hold program's data */
@@ -110,7 +114,6 @@
 	OutputFormat output_format;
 
 	GString *partial_command;
-	GString *query_buffer;
 
 	GHashTable *parameters; /* key = name, value = G_TYPE_STRING GdaParameter */
 } MainData;
@@ -126,6 +129,7 @@
 static void     output_string (MainData *data, const gchar *str);
 static ConnectionSetting *open_connection (MainData *data, const gchar *cnc_name, const gchar *cnc_string,
 					   GError **error);
+static void connection_settings_free (ConnectionSetting *cs);
 static GdaDataModel *list_all_dsn (MainData *data);
 static GdaDataModel *list_all_providers (MainData *data);
 
@@ -142,7 +146,6 @@
 	GError *error = NULL;
 	MainData *data;
 	int exit_status = EXIT_SUCCESS;
-	GSList *list;
 	prompt = g_string_new ("");
 
 	context = g_option_context_new (_("[DSN|connection string]..."));        
@@ -299,9 +302,11 @@
 				FILE *to_stream;
 
 				if ((*data->partial_command->str != '\\') && (*data->partial_command->str != '.')) {
-					if (!data->query_buffer)
-						data->query_buffer = g_string_new ("");
-					g_string_assign (data->query_buffer, data->partial_command->str);
+					if (data->current) {
+						if (!data->current->query_buffer)
+							data->current->query_buffer = g_string_new ("");
+						g_string_assign (data->current->query_buffer, data->partial_command->str);
+					}
 				}
 
 				if (data && data->output_stream)
@@ -339,15 +344,7 @@
 	
 	/* cleanups */
  cleanup:
-	for (list = data->settings; list; list = list->next) {
-		ConnectionSetting *cs = (ConnectionSetting*) list->data;
-		if (cs->cnc)
-			g_object_unref (cs->cnc);
-		if (cs->parser)
-			g_object_unref (cs->parser);
-		g_free (cs->name);
-		g_free (cs);
-	}
+	g_slist_foreach (data->settings, (GFunc) connection_settings_free, NULL);
 	set_input_file (data, NULL, NULL); 
 	set_output_file (data, NULL, NULL); 
 
@@ -866,6 +863,18 @@
 	return cs;
 }
 
+typedef struct {
+	MainData *data;
+	ConnectionSetting *cs;
+	gboolean cannot_lock;
+	gboolean result;
+	GError   *error;
+} MetaUpdateData;
+
+static gpointer thread_start_update_meta_store (MetaUpdateData *data);
+static void thread_ok_cb_update_meta_store (GdaThreader *threader, guint job, MetaUpdateData *data);
+static void thread_cancelled_cb_update_meta_store (GdaThreader *threader, guint job, MetaUpdateData *data);
+
 /*
  * Open a connection
  */
@@ -961,6 +970,9 @@
 		cncindex++;
 		cs->parser = gda_connection_create_parser (newcnc);
 		cs->cnc = newcnc;
+		cs->query_buffer = NULL;
+		cs->threader = NULL;
+		cs->meta_job_id = 0;
 
 		data->settings = g_slist_append (data->settings, cs);
 		data->current = cs;
@@ -987,21 +999,26 @@
 		g_object_set (G_OBJECT (cs->cnc), "meta-store", store, NULL);
 		if (update_store) {
 			GError *lerror = NULL;
-			if (!data->output_stream) {
-				g_print (_("\tGetting database schema information, "
-					   "this may take some time... "));
-				fflush (stdout);
-			}
-			if (!gda_connection_update_meta_store (cs->cnc, NULL, &lerror)) {
+			MetaUpdateData *thdata;
+			
+			cs->threader = (GdaThreader*) gda_threader_new ();
+			thdata = g_new0 (MetaUpdateData, 1);
+			thdata->data = data;
+			thdata->cs = cs;
+			thdata->cannot_lock = FALSE;
+			cs->meta_job_id = gda_threader_start_thread (cs->threader, 
+								     (GThreadFunc) thread_start_update_meta_store,
+								     thdata,
+								     (GdaThreaderFunc) thread_ok_cb_update_meta_store,
+								     (GdaThreaderFunc) thread_cancelled_cb_update_meta_store, 
+								     &lerror);
+			if (cs->meta_job_id == 0) {
 				if (!data->output_stream) 
-					g_print (_("error: %s\n"), 
+					g_print (_("Error getting meta data in background: %s\n"), 
 						 lerror && lerror->message ? lerror->message : _("No detail"));
 				if (lerror)
 					g_error_free (lerror);
 			}
-			else
-				if (!data->output_stream) 
-					g_print (_("Done.\n"));
 		}
 
 		g_object_unref (store);
@@ -1010,6 +1027,77 @@
 	return cs;
 }
 
+static gpointer
+thread_start_update_meta_store (MetaUpdateData *data)
+{
+	/* test if the connection can be locked, which means that multiple threads can access it at the same time.
+	 * If that is not possible, then quit the thread while positionning data->cannot_lock to TRUE so the
+	 * meta data update can be done while back in the main thread */
+	if (gda_lockable_trylock (GDA_LOCKABLE (data->cs->cnc))) {
+		gda_lockable_unlock (GDA_LOCKABLE (data->cs->cnc));
+		data->result = gda_connection_update_meta_store (data->cs->cnc, NULL, &(data->error));
+	}
+	else
+		data->cannot_lock = TRUE;
+	return NULL;
+}
+
+static void
+thread_ok_cb_update_meta_store (GdaThreader *threader, guint job, MetaUpdateData *data)
+{
+	data->cs->meta_job_id = 0;
+	if (data->cannot_lock) {
+		if (!data->data->output_stream) {
+			GError *lerror = NULL;
+			g_print (_("Getting database schema information for connection '%s', this may take some time... "),
+				 data->cs->name);
+			fflush (stdout);
+			if (!gda_connection_update_meta_store (data->cs->cnc, NULL, &lerror)) {
+				if (!data->data->output_stream) 
+					g_print (_("error: %s\n"), 
+						 lerror && lerror->message ? lerror->message : _("No detail"));
+				if (lerror)
+					g_error_free (lerror);
+			}
+			else
+				if (!data->data->output_stream) 
+					g_print (_("Done.\n"));
+		}
+	}
+	if (data->error)
+		g_error_free (data->error);
+
+	g_free (data);
+}
+
+static void
+thread_cancelled_cb_update_meta_store (GdaThreader *threader, guint job, MetaUpdateData *data)
+{
+	data->cs->meta_job_id = 0;
+	if (data->error)
+		g_error_free (data->error);
+	g_free (data);
+}
+
+/* free the connection settings */
+static void
+connection_settings_free (ConnectionSetting *cs)
+{
+	g_free (cs->name);
+	if (cs->cnc)
+		g_object_unref (cs->cnc);
+	if (cs->parser)
+		g_object_unref (cs->parser);
+	if (cs->query_buffer)
+		g_string_free (cs->query_buffer, TRUE);
+	if (cs->threader) {
+		if (cs->meta_job_id)
+			gda_threader_cancel (cs->threader, cs->meta_job_id);
+		g_object_unref (cs->threader);
+	}
+	g_free (cs);
+}
+
 /* 
  * Dumps the data model contents onto @data->output
  */
@@ -1792,6 +1880,9 @@
 					ncs->cnc = gda_meta_store_get_internal_connection (store);
 					g_object_ref (ncs->cnc);
 					ncs->parser = gda_connection_create_parser (ncs->cnc);
+					ncs->query_buffer = NULL;
+					ncs->threader = NULL;
+					ncs->meta_job_id = 0;
 					
 					data->settings = g_slist_append (data->settings, ncs);
 					data->current = ncs;
@@ -1862,14 +1953,14 @@
 			gda_value_free (value);
 			
 			prov = gda_connection_get_provider_obj (cs->cnc);
-			if (GDA_IS_VIRTUAL_PROVIDER (prov))
+			if (GDA_IS_VPROVIDER_HUB (prov))
 				value = gda_value_new_from_string ("", G_TYPE_STRING);
 			else
 				value = gda_value_new_from_string (gda_connection_get_provider_name (cs->cnc), G_TYPE_STRING);
 			gda_data_model_set_value_at (model, 1, row, value, NULL);
 			gda_value_free (value);
 
-			if (GDA_IS_VIRTUAL_PROVIDER (prov)) {
+			if (GDA_IS_VPROVIDER_HUB (prov)) {
 				GString *string = g_string_new ("");
 				gda_vconnection_hub_foreach (GDA_VCONNECTION_HUB (cs->cnc), 
 							     (GdaVConnectionHubFunc) vconnection_hub_foreach_cb, string);
@@ -1934,10 +2025,7 @@
 		data->current = g_slist_nth_data (data->settings, pos + 1);
 
 	data->settings = g_slist_remove (data->settings, cs);
-	g_object_unref (cs->cnc);
-	g_object_unref (cs->parser);
-	g_free (cs->name);
-	g_free (cs);
+	connection_settings_free (cs);
 
 	GdaInternalCommandResult *res;
 	
@@ -2009,6 +2097,9 @@
 	cs->name = g_strdup (args[0]);
 	cs->cnc = virtual;
 	cs->parser = gda_connection_create_parser (virtual);
+	cs->query_buffer = NULL;
+	cs->threader = NULL;
+	cs->meta_job_id = 0;
 
 	data->settings = g_slist_append (data->settings, cs);
 	data->current = cs;
@@ -2120,8 +2211,13 @@
 	gint systemres;
 	GdaInternalCommandResult *res = NULL;
 
-	if (!data->query_buffer) 
-		data->query_buffer = g_string_new ("");
+	if (!data->current) {
+		g_set_error (error, 0, 0, _("No connection opened"));
+		goto end_of_command;
+	}
+
+	if (!data->current->query_buffer) 
+		data->current->query_buffer = g_string_new ("");
 
 	if (args[0] && *args[0])
 		filename = (gchar *) args[0];
@@ -2131,7 +2227,8 @@
 		fd = g_file_open_tmp (NULL, &filename, error);
 		if (fd < 0)
 			goto end_of_command;
-		if (write (fd, data->query_buffer->str, data->query_buffer->len) != data->query_buffer->len) {
+		if (write (fd, data->current->query_buffer->str, 
+			   data->current->query_buffer->len) != data->current->query_buffer->len) {
 			g_set_error (error, 0, 0,
 				     _("Could not write to temporary file '%s': %s"),
 				     filename, strerror (errno));
@@ -2183,7 +2280,7 @@
 			
 			if (!g_file_get_contents (filename, &str, NULL, error))
 				goto end_of_command;
-			g_string_assign (data->query_buffer, str);
+			g_string_assign (data->current->query_buffer, str);
 			g_free (str);
 		}
 	}
@@ -2208,10 +2305,15 @@
 {
 	GdaInternalCommandResult *res = NULL;
 
-	if (!data->query_buffer) 
-		data->query_buffer = g_string_new ("");
+	if (!data->current) {
+		g_set_error (error, 0, 0, _("No connection opened"));
+		return NULL;
+	}
+
+	if (!data->current->query_buffer) 
+		data->current->query_buffer = g_string_new ("");
 	else 
-		g_string_assign (data->query_buffer, "");
+		g_string_assign (data->current->query_buffer, "");
 
 	if (args[0]) {
 		const gchar *filename = NULL;
@@ -2221,7 +2323,7 @@
 		if (!g_file_get_contents (filename, &str, NULL, error))
 			return NULL;
 
-		g_string_assign (data->query_buffer, str);
+		g_string_assign (data->current->query_buffer, str);
 		g_free (str);
 	}
 	
@@ -2237,11 +2339,16 @@
 {
 	GdaInternalCommandResult *res = NULL;
 
-	if (!data->query_buffer) 
-		data->query_buffer = g_string_new ("");
+	if (!data->current) {
+		g_set_error (error, 0, 0, _("No connection opened"));
+		return NULL;
+	}
+
+	if (!data->current->query_buffer) 
+		data->current->query_buffer = g_string_new ("");
 	res = g_new0 (GdaInternalCommandResult, 1);
 	res->type = GDA_INTERNAL_COMMAND_RESULT_TXT;
-	res->u.txt = g_string_new (data->query_buffer->str);
+	res->u.txt = g_string_new (data->current->query_buffer->str);
 
 	return res;
 }
@@ -2252,10 +2359,15 @@
 {
 	GdaInternalCommandResult *res = NULL;
 
-	if (!data->query_buffer) 
-		data->query_buffer = g_string_new ("");
-	if (*data->query_buffer->str != 0)
-		res = command_execute (data, data->query_buffer->str, error);
+	if (!data->current) {
+		g_set_error (error, 0, 0, _("No connection opened"));
+		return NULL;
+	}
+
+	if (!data->current->query_buffer) 
+		data->current->query_buffer = g_string_new ("");
+	if (*data->current->query_buffer->str != 0)
+		res = command_execute (data, data->current->query_buffer->str, error);
 	else {
 		res = g_new0 (GdaInternalCommandResult, 1);
 		res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;
@@ -2269,13 +2381,19 @@
 			    GError **error, MainData *data)
 {
 	GdaInternalCommandResult *res = NULL;
-	if (!data->query_buffer) 
-		data->query_buffer = g_string_new ("");
+
+	if (!data->current) {
+		g_set_error (error, 0, 0, _("No connection opened"));
+		return NULL;
+	}
+
+	if (!data->current->query_buffer) 
+		data->current->query_buffer = g_string_new ("");
 	if (!args[0]) 
 		g_set_error (error, 0, 0, 
 			     _("Missing FILE to write to"));
 	else {
-		if (g_file_set_contents (args[0], data->query_buffer->str, -1, error)) {
+		if (g_file_set_contents (args[0], data->current->query_buffer->str, -1, error)) {
 			res = g_new0 (GdaInternalCommandResult, 1);
 			res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;
 		}
@@ -2298,17 +2416,20 @@
 {
 	GdaInternalCommandResult *res = NULL;
 
-	g_assert (data->current);
+	if (!data->current) {
+		g_set_error (error, 0, 0, _("No connection opened"));
+		return NULL;
+	}
 
-	if (!data->query_buffer) 
-		data->query_buffer = g_string_new ("");
-	if (*data->query_buffer->str != 0) {
+	if (!data->current->query_buffer) 
+		data->current->query_buffer = g_string_new ("");
+	if (*data->current->query_buffer->str != 0) {
 		GdaStatement *stmt;
 		gchar *qname;
 
 		/* check SQL validity */
 		const gchar *remain = NULL;
-		stmt = gda_sql_parser_parse_string (data->current->parser, data->query_buffer->str, &remain, error);
+		stmt = gda_sql_parser_parse_string (data->current->parser, data->current->query_buffer->str, &remain, error);
 		if (!stmt)
 			return NULL;
 		g_object_unref (stmt);
@@ -2331,7 +2452,7 @@
 			}
 		}
 
-		TO_IMPLEMENT; /* add data->query_buffer->str as a new query in data->current->cnc's meta store */
+		TO_IMPLEMENT; /* add data->current->query_buffer->str as a new query in data->current->cnc's meta store */
 		g_free (qname);
 		res = g_new0 (GdaInternalCommandResult, 1);
 		res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;
@@ -2349,8 +2470,13 @@
 {
 	GdaInternalCommandResult *res = NULL;
 
-	if (!data->query_buffer) 
-		data->query_buffer = g_string_new ("");
+	if (!data->current) {
+		g_set_error (error, 0, 0, _("No connection opened"));
+		return NULL;
+	}
+
+	if (!data->current->query_buffer) 
+		data->current->query_buffer = g_string_new ("");
 
 	if (args[0] && *args[0]) {
 		GdaStatement *stmt = find_statement_in_connection_meta_store (data->current->cnc, args[0]);
@@ -2361,7 +2487,7 @@
 			if (!str)
 				return NULL;
 
-			g_string_assign (data->query_buffer, str);
+			g_string_assign (data->current->query_buffer, str);
 			g_free (str);
 			res = g_new0 (GdaInternalCommandResult, 1);
 			res->type = GDA_INTERNAL_COMMAND_RESULT_EMPTY;



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]